From 065459c18fb36c3266463ba86a41506f23a20b52 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Sun, 21 Dec 2014 20:57:08 -0500 Subject: [PATCH 1/9] Implement transmit buffering with interrupts for USART devices --- .../arduino/sam/cores/arduino/USARTClass.cpp | 38 +++++++++++++++---- .../arduino/sam/cores/arduino/USARTClass.h | 3 +- .../sam/variants/arduino_due_x/variant.cpp | 9 +++-- 3 files changed, 39 insertions(+), 11 deletions(-) diff --git a/hardware/arduino/sam/cores/arduino/USARTClass.cpp b/hardware/arduino/sam/cores/arduino/USARTClass.cpp index d950c50c9..44f92be5a 100644 --- a/hardware/arduino/sam/cores/arduino/USARTClass.cpp +++ b/hardware/arduino/sam/cores/arduino/USARTClass.cpp @@ -23,15 +23,17 @@ // Constructors //////////////////////////////////////////////////////////////// -USARTClass::USARTClass( Usart* pUsart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer ) +USARTClass::USARTClass( Usart* pUsart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer, volatile RingBuffer* pTx_buffer ) { - _rx_buffer = pRx_buffer ; + _rx_buffer = pRx_buffer; + _tx_buffer = pTx_buffer; _pUsart=pUsart ; _dwIrq=dwIrq ; _dwId=dwId ; } + // Public Methods ////////////////////////////////////////////////////////////// void USARTClass::begin( const uint32_t dwBaudRate ) @@ -73,6 +75,8 @@ void USARTClass::end( void ) // clear any received data _rx_buffer->_iHead = _rx_buffer->_iTail ; + while (_tx_buffer->_iHead != _tx_buffer->_iTail); //wait for transmit data to be sent + // Disable UART interrupt in NVIC NVIC_DisableIRQ( _dwIrq ) ; @@ -115,12 +119,21 @@ void USARTClass::flush( void ) size_t USARTClass::write( const uint8_t uc_data ) { - // Check if the transmitter is ready - while ((_pUsart->US_CSR & US_CSR_TXRDY) != US_CSR_TXRDY) - ; + if ((_pUsart->US_CSR & US_CSR_TXRDY) != US_CSR_TXRDY) //is the hardware currently busy? + { + //if busy we buffer + unsigned int l = (_tx_buffer->_iHead + 1) % SERIAL_BUFFER_SIZE; + while (_tx_buffer->_iTail == l); //spin locks if we're about to overwrite the buffer. This continues once the data is sent - // Send character - _pUsart->US_THR = uc_data ; + _tx_buffer->_aucBuffer[_tx_buffer->_iHead] = uc_data; + _tx_buffer->_iHead = l; + _pUsart->US_IER = US_IER_TXRDY; //make sure TX interrupt is enabled + } + else + { + // Send character + _pUsart->US_THR = uc_data ; + } return 1; } @@ -132,6 +145,17 @@ void USARTClass::IrqHandler( void ) if ((status & US_CSR_RXRDY) == US_CSR_RXRDY) _rx_buffer->store_char( _pUsart->US_RHR ) ; + //Do we need to keep sending data? + if ((status & US_CSR_TXRDY) == US_CSR_TXRDY) + { + _pUsart->US_THR = _tx_buffer->_aucBuffer[_tx_buffer->_iTail]; + _tx_buffer->_iTail = (unsigned int)(_tx_buffer->_iTail + 1) % SERIAL_BUFFER_SIZE; + if (_tx_buffer->_iTail == _tx_buffer->_iHead) //if this is true we have no more data to transmit + { + _pUsart->US_IDR = US_IDR_TXRDY; //mask off transmit interrupt so we don't get it anymore + } + } + // Acknowledge errors if ((status & US_CSR_OVRE) == US_CSR_OVRE || (status & US_CSR_FRAME) == US_CSR_FRAME) diff --git a/hardware/arduino/sam/cores/arduino/USARTClass.h b/hardware/arduino/sam/cores/arduino/USARTClass.h index 9082cc6c2..9d820c982 100644 --- a/hardware/arduino/sam/cores/arduino/USARTClass.h +++ b/hardware/arduino/sam/cores/arduino/USARTClass.h @@ -60,6 +60,7 @@ class USARTClass : public HardwareSerial { protected: RingBuffer *_rx_buffer ; + volatile RingBuffer *_tx_buffer; protected: Usart* _pUsart ; @@ -67,7 +68,7 @@ class USARTClass : public HardwareSerial uint32_t _dwId ; public: - USARTClass( Usart* pUsart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer ) ; + USARTClass( Usart* pUsart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer, volatile RingBuffer* pTx_buffer ) ; void begin( const uint32_t dwBaudRate ) ; void begin( const uint32_t dwBaudRate , const uint32_t config ) ; diff --git a/hardware/arduino/sam/variants/arduino_due_x/variant.cpp b/hardware/arduino/sam/variants/arduino_due_x/variant.cpp index ac066898d..f4ccc0c12 100644 --- a/hardware/arduino/sam/variants/arduino_due_x/variant.cpp +++ b/hardware/arduino/sam/variants/arduino_due_x/variant.cpp @@ -317,14 +317,17 @@ void UART_Handler(void) RingBuffer rx_buffer2; RingBuffer rx_buffer3; RingBuffer rx_buffer4; +volatile RingBuffer tx_buffer2; +volatile RingBuffer tx_buffer3; +volatile RingBuffer tx_buffer4; -USARTClass Serial1(USART0, USART0_IRQn, ID_USART0, &rx_buffer2); +USARTClass Serial1(USART0, USART0_IRQn, ID_USART0, &rx_buffer2, &tx_buffer2); void serialEvent1() __attribute__((weak)); void serialEvent1() { } -USARTClass Serial2(USART1, USART1_IRQn, ID_USART1, &rx_buffer3); +USARTClass Serial2(USART1, USART1_IRQn, ID_USART1, &rx_buffer3, &tx_buffer3); void serialEvent2() __attribute__((weak)); void serialEvent2() { } -USARTClass Serial3(USART3, USART3_IRQn, ID_USART3, &rx_buffer4); +USARTClass Serial3(USART3, USART3_IRQn, ID_USART3, &rx_buffer4, &tx_buffer4); void serialEvent3() __attribute__((weak)); void serialEvent3() { } From 4eb05c303b5a9771309bd754a5f04292a25b5d1f Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Tue, 23 Dec 2014 22:36:35 -0500 Subject: [PATCH 2/9] Change RingBuffer to have buffer size of 128 and also set its members volatile since they are all accessed and modified in interrupt handlers. --- hardware/arduino/sam/cores/arduino/RingBuffer.cpp | 2 +- hardware/arduino/sam/cores/arduino/RingBuffer.h | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/hardware/arduino/sam/cores/arduino/RingBuffer.cpp b/hardware/arduino/sam/cores/arduino/RingBuffer.cpp index f0b3ed1df..d9931c977 100644 --- a/hardware/arduino/sam/cores/arduino/RingBuffer.cpp +++ b/hardware/arduino/sam/cores/arduino/RingBuffer.cpp @@ -21,7 +21,7 @@ RingBuffer::RingBuffer( void ) { - memset( _aucBuffer, 0, SERIAL_BUFFER_SIZE ) ; + memset( (void *)_aucBuffer, 0, SERIAL_BUFFER_SIZE ) ; _iHead=0 ; _iTail=0 ; } diff --git a/hardware/arduino/sam/cores/arduino/RingBuffer.h b/hardware/arduino/sam/cores/arduino/RingBuffer.h index 28309df45..1a5861b0b 100644 --- a/hardware/arduino/sam/cores/arduino/RingBuffer.h +++ b/hardware/arduino/sam/cores/arduino/RingBuffer.h @@ -25,14 +25,14 @@ // using a ring buffer (I think), in which head is the index of the location // to which to write the next incoming character and tail is the index of the // location from which to read. -#define SERIAL_BUFFER_SIZE 64 +#define SERIAL_BUFFER_SIZE 128 class RingBuffer { public: - uint8_t _aucBuffer[SERIAL_BUFFER_SIZE] ; - int _iHead ; - int _iTail ; + volatile uint8_t _aucBuffer[SERIAL_BUFFER_SIZE] ; + volatile int _iHead ; + volatile int _iTail ; public: RingBuffer( void ) ; From bb341c6d922ee65cd5d5e4489a02e81e2a063168 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Tue, 23 Dec 2014 22:37:58 -0500 Subject: [PATCH 3/9] Modifications to make serial transmit interrupt work more reliably. Also, added the availableForWrite function. --- .../arduino/sam/cores/arduino/USARTClass.cpp | 32 +++++++++++++------ .../arduino/sam/cores/arduino/USARTClass.h | 7 ++-- .../sam/variants/arduino_due_x/variant.cpp | 6 ++-- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/hardware/arduino/sam/cores/arduino/USARTClass.cpp b/hardware/arduino/sam/cores/arduino/USARTClass.cpp index 44f92be5a..ce2c28a5c 100644 --- a/hardware/arduino/sam/cores/arduino/USARTClass.cpp +++ b/hardware/arduino/sam/cores/arduino/USARTClass.cpp @@ -23,7 +23,7 @@ // Constructors //////////////////////////////////////////////////////////////// -USARTClass::USARTClass( Usart* pUsart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer, volatile RingBuffer* pTx_buffer ) +USARTClass::USARTClass( Usart* pUsart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer, RingBuffer* pTx_buffer ) { _rx_buffer = pRx_buffer; _tx_buffer = pTx_buffer; @@ -33,7 +33,6 @@ USARTClass::USARTClass( Usart* pUsart, IRQn_Type dwIrq, uint32_t dwId, RingBuffe _dwId=dwId ; } - // Public Methods ////////////////////////////////////////////////////////////// void USARTClass::begin( const uint32_t dwBaudRate ) @@ -66,6 +65,10 @@ void USARTClass::begin( const uint32_t dwBaudRate, const uint32_t config ) // Enable UART interrupt in NVIC NVIC_EnableIRQ( _dwIrq ) ; + //make sure both ring buffers are initialized back to empty. + _rx_buffer->_iHead = _rx_buffer->_iTail = 0; + _tx_buffer->_iHead = _tx_buffer->_iTail = 0; + // Enable receiver and transmitter _pUsart->US_CR = US_CR_RXEN | US_CR_TXEN ; } @@ -91,6 +94,14 @@ int USARTClass::available( void ) return (uint32_t)(SERIAL_BUFFER_SIZE + _rx_buffer->_iHead - _rx_buffer->_iTail) % SERIAL_BUFFER_SIZE ; } +int USARTClass::availableForWrite(void) +{ + int head = _tx_buffer->_iHead; + int tail = _tx_buffer->_iTail; + if (head >= tail) return SERIAL_BUFFER_SIZE - 1 - head + tail; + return tail - head - 1; +} + int USARTClass::peek( void ) { if ( _rx_buffer->_iHead == _rx_buffer->_iTail ) @@ -142,17 +153,20 @@ void USARTClass::IrqHandler( void ) uint32_t status = _pUsart->US_CSR; // Did we receive data ? - if ((status & US_CSR_RXRDY) == US_CSR_RXRDY) - _rx_buffer->store_char( _pUsart->US_RHR ) ; - + if ((status & US_CSR_RXRDY) == US_CSR_RXRDY) + { + _rx_buffer->store_char(_pUsart->US_RHR); + } //Do we need to keep sending data? if ((status & US_CSR_TXRDY) == US_CSR_TXRDY) { - _pUsart->US_THR = _tx_buffer->_aucBuffer[_tx_buffer->_iTail]; - _tx_buffer->_iTail = (unsigned int)(_tx_buffer->_iTail + 1) % SERIAL_BUFFER_SIZE; - if (_tx_buffer->_iTail == _tx_buffer->_iHead) //if this is true we have no more data to transmit + if (_tx_buffer->_iTail != _tx_buffer->_iHead) { //just in case + _pUsart->US_THR = _tx_buffer->_aucBuffer[_tx_buffer->_iTail]; + _tx_buffer->_iTail = (unsigned int)(_tx_buffer->_iTail + 1) % SERIAL_BUFFER_SIZE; + } + else { - _pUsart->US_IDR = US_IDR_TXRDY; //mask off transmit interrupt so we don't get it anymore + _pUsart->US_IDR = US_IDR_TXRDY; //mask off transmit interrupt so we don't get it anymore } } diff --git a/hardware/arduino/sam/cores/arduino/USARTClass.h b/hardware/arduino/sam/cores/arduino/USARTClass.h index 9d820c982..fcce9fd12 100644 --- a/hardware/arduino/sam/cores/arduino/USARTClass.h +++ b/hardware/arduino/sam/cores/arduino/USARTClass.h @@ -59,8 +59,8 @@ class USARTClass : public HardwareSerial { protected: - RingBuffer *_rx_buffer ; - volatile RingBuffer *_tx_buffer; + RingBuffer *_rx_buffer; + RingBuffer *_tx_buffer; protected: Usart* _pUsart ; @@ -68,12 +68,13 @@ class USARTClass : public HardwareSerial uint32_t _dwId ; public: - USARTClass( Usart* pUsart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer, volatile RingBuffer* pTx_buffer ) ; + USARTClass( Usart* pUsart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer, RingBuffer* pTx_buffer ) ; void begin( const uint32_t dwBaudRate ) ; void begin( const uint32_t dwBaudRate , const uint32_t config ) ; void end( void ) ; int available( void ) ; + int availableForWrite(void); int peek( void ) ; int read( void ) ; void flush( void ) ; diff --git a/hardware/arduino/sam/variants/arduino_due_x/variant.cpp b/hardware/arduino/sam/variants/arduino_due_x/variant.cpp index f4ccc0c12..f746fdf44 100644 --- a/hardware/arduino/sam/variants/arduino_due_x/variant.cpp +++ b/hardware/arduino/sam/variants/arduino_due_x/variant.cpp @@ -317,9 +317,9 @@ void UART_Handler(void) RingBuffer rx_buffer2; RingBuffer rx_buffer3; RingBuffer rx_buffer4; -volatile RingBuffer tx_buffer2; -volatile RingBuffer tx_buffer3; -volatile RingBuffer tx_buffer4; +RingBuffer tx_buffer2; +RingBuffer tx_buffer3; +RingBuffer tx_buffer4; USARTClass Serial1(USART0, USART0_IRQn, ID_USART0, &rx_buffer2, &tx_buffer2); void serialEvent1() __attribute__((weak)); From 2fedb00552e45aaca1623789138d223690244f43 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Wed, 24 Dec 2014 10:20:37 -0500 Subject: [PATCH 4/9] Switch all of the transmit interrupt code to UARTClass. Also, turn USARTClass into a stub because it did nothing differently from the UART code anyway. Now all serial ports use transmit interrupts. --- .../arduino/sam/cores/arduino/UARTClass.cpp | 58 +++++++- .../arduino/sam/cores/arduino/UARTClass.h | 5 +- .../arduino/sam/cores/arduino/USARTClass.cpp | 132 +----------------- .../arduino/sam/cores/arduino/USARTClass.h | 14 +- .../sam/variants/arduino_due_x/variant.cpp | 3 +- 5 files changed, 66 insertions(+), 146 deletions(-) diff --git a/hardware/arduino/sam/cores/arduino/UARTClass.cpp b/hardware/arduino/sam/cores/arduino/UARTClass.cpp index 16188b128..99e7219b5 100644 --- a/hardware/arduino/sam/cores/arduino/UARTClass.cpp +++ b/hardware/arduino/sam/cores/arduino/UARTClass.cpp @@ -23,9 +23,10 @@ // Constructors //////////////////////////////////////////////////////////////// -UARTClass::UARTClass( Uart* pUart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer ) +UARTClass::UARTClass( Uart *pUart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer *pRx_buffer, RingBuffer *pTx_buffer ) { _rx_buffer = pRx_buffer ; + _tx_buffer = pTx_buffer; _pUart=pUart ; _dwIrq=dwIrq ; @@ -34,7 +35,14 @@ UARTClass::UARTClass( Uart* pUart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* p // Public Methods ////////////////////////////////////////////////////////////// + + void UARTClass::begin( const uint32_t dwBaudRate ) +{ + begin( dwBaudRate, UART_MR_PAR_NO | UART_MR_CHMODE_NORMAL ); +} + +void UARTClass::begin( const uint32_t dwBaudRate, const uint32_t config ) { // Configure PMC pmc_enable_periph_clk( _dwId ) ; @@ -46,7 +54,7 @@ void UARTClass::begin( const uint32_t dwBaudRate ) _pUart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RXDIS | UART_CR_TXDIS ; // Configure mode - _pUart->UART_MR = UART_MR_PAR_NO | UART_MR_CHMODE_NORMAL ; + _pUart->UART_MR = config ; // Configure baudrate (asynchronous, no oversampling) _pUart->UART_BRGR = (SystemCoreClock / dwBaudRate) >> 4 ; @@ -58,6 +66,10 @@ void UARTClass::begin( const uint32_t dwBaudRate ) // Enable UART interrupt in NVIC NVIC_EnableIRQ(_dwIrq); + //make sure both ring buffers are initialized back to empty. + _rx_buffer->_iHead = _rx_buffer->_iTail = 0; + _tx_buffer->_iHead = _tx_buffer->_iTail = 0; + // Enable receiver and transmitter _pUart->UART_CR = UART_CR_RXEN | UART_CR_TXEN ; } @@ -67,6 +79,8 @@ void UARTClass::end( void ) // clear any received data _rx_buffer->_iHead = _rx_buffer->_iTail ; + while (_tx_buffer->_iHead != _tx_buffer->_iTail); //wait for transmit data to be sent + // Disable UART interrupt in NVIC NVIC_DisableIRQ( _dwIrq ) ; @@ -81,6 +95,14 @@ int UARTClass::available( void ) return (uint32_t)(SERIAL_BUFFER_SIZE + _rx_buffer->_iHead - _rx_buffer->_iTail) % SERIAL_BUFFER_SIZE ; } +int UARTClass::availableForWrite(void) +{ + int head = _tx_buffer->_iHead; + int tail = _tx_buffer->_iTail; + if (head >= tail) return SERIAL_BUFFER_SIZE - 1 - head + tail; + return tail - head - 1; +} + int UARTClass::peek( void ) { if ( _rx_buffer->_iHead == _rx_buffer->_iTail ) @@ -109,12 +131,21 @@ void UARTClass::flush( void ) size_t UARTClass::write( const uint8_t uc_data ) { - // Check if the transmitter is ready - while ((_pUart->UART_SR & UART_SR_TXRDY) != UART_SR_TXRDY) - ; + if ((_pUart->UART_SR & UART_SR_TXRDY) != UART_SR_TXRDY) //is the hardware currently busy? + { + //if busy we buffer + unsigned int l = (_tx_buffer->_iHead + 1) % SERIAL_BUFFER_SIZE; + while (_tx_buffer->_iTail == l); //spin locks if we're about to overwrite the buffer. This continues once the data is sent - // Send character - _pUart->UART_THR = uc_data; + _tx_buffer->_aucBuffer[_tx_buffer->_iHead] = uc_data; + _tx_buffer->_iHead = l; + _pUart->UART_IER = UART_IER_TXRDY; //make sure TX interrupt is enabled + } + else + { + // Send character + _pUart->UART_THR = uc_data ; + } return 1; } @@ -126,6 +157,19 @@ void UARTClass::IrqHandler( void ) if ((status & UART_SR_RXRDY) == UART_SR_RXRDY) _rx_buffer->store_char(_pUart->UART_RHR); + //Do we need to keep sending data? + if ((status & UART_SR_TXRDY) == UART_SR_TXRDY) + { + if (_tx_buffer->_iTail != _tx_buffer->_iHead) { //just in case + _pUart->UART_THR = _tx_buffer->_aucBuffer[_tx_buffer->_iTail]; + _tx_buffer->_iTail = (unsigned int)(_tx_buffer->_iTail + 1) % SERIAL_BUFFER_SIZE; + } + else + { + _pUart->UART_IDR = UART_IDR_TXRDY; //mask off transmit interrupt so we don't get it anymore + } + } + // Acknowledge errors if ((status & UART_SR_OVRE) == UART_SR_OVRE || (status & UART_SR_FRAME) == UART_SR_FRAME) diff --git a/hardware/arduino/sam/cores/arduino/UARTClass.h b/hardware/arduino/sam/cores/arduino/UARTClass.h index 5836f2e62..6c513374f 100644 --- a/hardware/arduino/sam/cores/arduino/UARTClass.h +++ b/hardware/arduino/sam/cores/arduino/UARTClass.h @@ -29,6 +29,7 @@ class UARTClass : public HardwareSerial { protected: RingBuffer *_rx_buffer ; + RingBuffer *_tx_buffer; protected: Uart* _pUart ; @@ -36,11 +37,13 @@ class UARTClass : public HardwareSerial uint32_t _dwId ; public: - UARTClass( Uart* pUart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer ) ; + UARTClass( Uart* pUart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer, RingBuffer* pTx_buffer) ; void begin( const uint32_t dwBaudRate ) ; + void begin( const uint32_t dwBaudRate , const uint32_t config ) ; void end( void ) ; int available( void ) ; + int availableForWrite(void); int peek( void ) ; int read( void ) ; void flush( void ) ; diff --git a/hardware/arduino/sam/cores/arduino/USARTClass.cpp b/hardware/arduino/sam/cores/arduino/USARTClass.cpp index ce2c28a5c..310e5680b 100644 --- a/hardware/arduino/sam/cores/arduino/USARTClass.cpp +++ b/hardware/arduino/sam/cores/arduino/USARTClass.cpp @@ -23,14 +23,10 @@ // Constructors //////////////////////////////////////////////////////////////// -USARTClass::USARTClass( Usart* pUsart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer, RingBuffer* pTx_buffer ) +USARTClass::USARTClass( Usart* pUsart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer, RingBuffer* pTx_buffer ) : UARTClass((Uart*)pUsart, dwIrq, dwId, pRx_buffer, pTx_buffer) { - _rx_buffer = pRx_buffer; - _tx_buffer = pTx_buffer; - _pUsart=pUsart ; - _dwIrq=dwIrq ; - _dwId=dwId ; + _pUsart=pUsart ; //In case anyone needs USART specific functionality in the future } // Public Methods ////////////////////////////////////////////////////////////// @@ -42,140 +38,26 @@ void USARTClass::begin( const uint32_t dwBaudRate ) void USARTClass::begin( const uint32_t dwBaudRate, const uint32_t config ) { - // Configure PMC - pmc_enable_periph_clk( _dwId ) ; - - // Disable PDC channel - _pUsart->US_PTCR = US_PTCR_RXTDIS | US_PTCR_TXTDIS ; - - // Reset and disable receiver and transmitter - _pUsart->US_CR = US_CR_RSTRX | US_CR_RSTTX | US_CR_RXDIS | US_CR_TXDIS ; - - // Configure mode - _pUsart->US_MR = config; - - - // Configure baudrate, asynchronous no oversampling - _pUsart->US_BRGR = (SystemCoreClock / dwBaudRate) / 16 ; - - // Configure interrupts - _pUsart->US_IDR = 0xFFFFFFFF; - _pUsart->US_IER = US_IER_RXRDY | US_IER_OVRE | US_IER_FRAME; - - // Enable UART interrupt in NVIC - NVIC_EnableIRQ( _dwIrq ) ; - - //make sure both ring buffers are initialized back to empty. - _rx_buffer->_iHead = _rx_buffer->_iTail = 0; - _tx_buffer->_iHead = _tx_buffer->_iTail = 0; - - // Enable receiver and transmitter - _pUsart->US_CR = US_CR_RXEN | US_CR_TXEN ; + UARTClass::begin(dwBaudRate, config); } void USARTClass::end( void ) { - // clear any received data - _rx_buffer->_iHead = _rx_buffer->_iTail ; - - while (_tx_buffer->_iHead != _tx_buffer->_iTail); //wait for transmit data to be sent - - // Disable UART interrupt in NVIC - NVIC_DisableIRQ( _dwIrq ) ; - - // Wait for any outstanding data to be sent - flush(); - - pmc_disable_periph_clk( _dwId ) ; -} - -int USARTClass::available( void ) -{ - return (uint32_t)(SERIAL_BUFFER_SIZE + _rx_buffer->_iHead - _rx_buffer->_iTail) % SERIAL_BUFFER_SIZE ; -} - -int USARTClass::availableForWrite(void) -{ - int head = _tx_buffer->_iHead; - int tail = _tx_buffer->_iTail; - if (head >= tail) return SERIAL_BUFFER_SIZE - 1 - head + tail; - return tail - head - 1; -} - -int USARTClass::peek( void ) -{ - if ( _rx_buffer->_iHead == _rx_buffer->_iTail ) - return -1 ; - - return _rx_buffer->_aucBuffer[_rx_buffer->_iTail] ; -} - -int USARTClass::read( void ) -{ - // if the head isn't ahead of the tail, we don't have any characters - if ( _rx_buffer->_iHead == _rx_buffer->_iTail ) - return -1 ; - - uint8_t uc = _rx_buffer->_aucBuffer[_rx_buffer->_iTail] ; - _rx_buffer->_iTail = (unsigned int)(_rx_buffer->_iTail + 1) % SERIAL_BUFFER_SIZE ; - return uc ; + UARTClass::end(); } void USARTClass::flush( void ) { - // Wait for transmission to complete - while ((_pUsart->US_CSR & US_CSR_TXRDY) != US_CSR_TXRDY) - ; + UARTClass::flush(); } size_t USARTClass::write( const uint8_t uc_data ) { - if ((_pUsart->US_CSR & US_CSR_TXRDY) != US_CSR_TXRDY) //is the hardware currently busy? - { - //if busy we buffer - unsigned int l = (_tx_buffer->_iHead + 1) % SERIAL_BUFFER_SIZE; - while (_tx_buffer->_iTail == l); //spin locks if we're about to overwrite the buffer. This continues once the data is sent - - _tx_buffer->_aucBuffer[_tx_buffer->_iHead] = uc_data; - _tx_buffer->_iHead = l; - _pUsart->US_IER = US_IER_TXRDY; //make sure TX interrupt is enabled - } - else - { - // Send character - _pUsart->US_THR = uc_data ; - } - return 1; + return UARTClass::write(uc_data); } void USARTClass::IrqHandler( void ) { - uint32_t status = _pUsart->US_CSR; - - // Did we receive data ? - if ((status & US_CSR_RXRDY) == US_CSR_RXRDY) - { - _rx_buffer->store_char(_pUsart->US_RHR); - } - //Do we need to keep sending data? - if ((status & US_CSR_TXRDY) == US_CSR_TXRDY) - { - if (_tx_buffer->_iTail != _tx_buffer->_iHead) { //just in case - _pUsart->US_THR = _tx_buffer->_aucBuffer[_tx_buffer->_iTail]; - _tx_buffer->_iTail = (unsigned int)(_tx_buffer->_iTail + 1) % SERIAL_BUFFER_SIZE; - } - else - { - _pUsart->US_IDR = US_IDR_TXRDY; //mask off transmit interrupt so we don't get it anymore - } - } - - // Acknowledge errors - if ((status & US_CSR_OVRE) == US_CSR_OVRE || - (status & US_CSR_FRAME) == US_CSR_FRAME) - { - // TODO: error reporting outside ISR - _pUsart->US_CR |= US_CR_RSTSTA; - } + UARTClass::IrqHandler(); } diff --git a/hardware/arduino/sam/cores/arduino/USARTClass.h b/hardware/arduino/sam/cores/arduino/USARTClass.h index fcce9fd12..53fee41d8 100644 --- a/hardware/arduino/sam/cores/arduino/USARTClass.h +++ b/hardware/arduino/sam/cores/arduino/USARTClass.h @@ -19,7 +19,7 @@ #ifndef _USART_CLASS_ #define _USART_CLASS_ -#include "HardwareSerial.h" +#include "UARTClass.h" #include "RingBuffer.h" // Includes Atmel CMSIS @@ -56,16 +56,10 @@ #define SERIAL_7O2 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_7_BIT | US_MR_PAR_ODD | US_MR_NBSTOP_2_BIT | US_MR_CHMODE_NORMAL) #define SERIAL_8O2 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_8_BIT | US_MR_PAR_ODD | US_MR_NBSTOP_2_BIT | US_MR_CHMODE_NORMAL) -class USARTClass : public HardwareSerial +class USARTClass : public UARTClass { - protected: - RingBuffer *_rx_buffer; - RingBuffer *_tx_buffer; - protected: Usart* _pUsart ; - IRQn_Type _dwIrq ; - uint32_t _dwId ; public: USARTClass( Usart* pUsart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer, RingBuffer* pTx_buffer ) ; @@ -73,10 +67,6 @@ class USARTClass : public HardwareSerial void begin( const uint32_t dwBaudRate ) ; void begin( const uint32_t dwBaudRate , const uint32_t config ) ; void end( void ) ; - int available( void ) ; - int availableForWrite(void); - int peek( void ) ; - int read( void ) ; void flush( void ) ; size_t write( const uint8_t c ) ; diff --git a/hardware/arduino/sam/variants/arduino_due_x/variant.cpp b/hardware/arduino/sam/variants/arduino_due_x/variant.cpp index f746fdf44..4cbe0df80 100644 --- a/hardware/arduino/sam/variants/arduino_due_x/variant.cpp +++ b/hardware/arduino/sam/variants/arduino_due_x/variant.cpp @@ -299,8 +299,9 @@ extern const PinDescription g_APinDescription[]= * UART objects */ RingBuffer rx_buffer1; +RingBuffer tx_buffer1; -UARTClass Serial(UART, UART_IRQn, ID_UART, &rx_buffer1); +UARTClass Serial(UART, UART_IRQn, ID_UART, &rx_buffer1, &tx_buffer1); void serialEvent() __attribute__((weak)); void serialEvent() { } From eff20deb27ccde721d78dbade8b57787479d6c91 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Wed, 24 Dec 2014 10:36:40 -0500 Subject: [PATCH 5/9] Add ability to set interrupt priority for UART/USARTs. --- hardware/arduino/sam/cores/arduino/UARTClass.cpp | 10 ++++++++++ hardware/arduino/sam/cores/arduino/UARTClass.h | 2 ++ 2 files changed, 12 insertions(+) diff --git a/hardware/arduino/sam/cores/arduino/UARTClass.cpp b/hardware/arduino/sam/cores/arduino/UARTClass.cpp index 99e7219b5..6ff9d932f 100644 --- a/hardware/arduino/sam/cores/arduino/UARTClass.cpp +++ b/hardware/arduino/sam/cores/arduino/UARTClass.cpp @@ -90,6 +90,16 @@ void UARTClass::end( void ) pmc_disable_periph_clk( _dwId ) ; } +void UARTClass::setInterruptPriority(uint32_t priority) +{ + NVIC_SetPriority(_dwIrq, priority & 0x0F); +} + +uint32_t UARTClass::getInterruptPriority() +{ + return NVIC_GetPriority(_dwIrq); +} + int UARTClass::available( void ) { return (uint32_t)(SERIAL_BUFFER_SIZE + _rx_buffer->_iHead - _rx_buffer->_iTail) % SERIAL_BUFFER_SIZE ; diff --git a/hardware/arduino/sam/cores/arduino/UARTClass.h b/hardware/arduino/sam/cores/arduino/UARTClass.h index 6c513374f..b60fae3d0 100644 --- a/hardware/arduino/sam/cores/arduino/UARTClass.h +++ b/hardware/arduino/sam/cores/arduino/UARTClass.h @@ -48,6 +48,8 @@ class UARTClass : public HardwareSerial int read( void ) ; void flush( void ) ; size_t write( const uint8_t c ) ; + void setInterruptPriority(uint32_t priority); + uint32_t getInterruptPriority(); void IrqHandler( void ) ; From 76280e87789c96f1c3ba8e283410fefbec3209f7 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Wed, 31 Dec 2014 08:42:26 -0500 Subject: [PATCH 6/9] Correct an issue where write could send data out of order. --- hardware/arduino/sam/cores/arduino/UARTClass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hardware/arduino/sam/cores/arduino/UARTClass.cpp b/hardware/arduino/sam/cores/arduino/UARTClass.cpp index 6ff9d932f..b6a0629da 100644 --- a/hardware/arduino/sam/cores/arduino/UARTClass.cpp +++ b/hardware/arduino/sam/cores/arduino/UARTClass.cpp @@ -141,7 +141,7 @@ void UARTClass::flush( void ) size_t UARTClass::write( const uint8_t uc_data ) { - if ((_pUart->UART_SR & UART_SR_TXRDY) != UART_SR_TXRDY) //is the hardware currently busy? + if (((_pUart->UART_SR & UART_SR_TXRDY) != UART_SR_TXRDY) | (_tx_buffer->_iTail != _tx_buffer->_iHead)) //is the hardware currently busy? { //if busy we buffer unsigned int l = (_tx_buffer->_iHead + 1) % SERIAL_BUFFER_SIZE; From cabfd8ed21d43eab067bace33302d47067473e46 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Sun, 4 Jan 2015 13:37:28 -0500 Subject: [PATCH 7/9] Fixed flush so that it actually is sure to flush all outstanding data. --- hardware/arduino/sam/cores/arduino/UARTClass.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/hardware/arduino/sam/cores/arduino/UARTClass.cpp b/hardware/arduino/sam/cores/arduino/UARTClass.cpp index b6a0629da..0dc74fa2f 100644 --- a/hardware/arduino/sam/cores/arduino/UARTClass.cpp +++ b/hardware/arduino/sam/cores/arduino/UARTClass.cpp @@ -79,14 +79,12 @@ void UARTClass::end( void ) // clear any received data _rx_buffer->_iHead = _rx_buffer->_iTail ; - while (_tx_buffer->_iHead != _tx_buffer->_iTail); //wait for transmit data to be sent + // Wait for any outstanding data to be sent + flush(); // Disable UART interrupt in NVIC NVIC_DisableIRQ( _dwIrq ) ; - // Wait for any outstanding data to be sent - flush(); - pmc_disable_periph_clk( _dwId ) ; } @@ -134,6 +132,7 @@ int UARTClass::read( void ) void UARTClass::flush( void ) { + while (_tx_buffer->_iHead != _tx_buffer->_iTail); //wait for transmit data to be sent // Wait for transmission to complete while ((_pUart->UART_SR & UART_SR_TXRDY) != UART_SR_TXRDY) ; From 16d836108ff9d33336b9318492515f1a683df447 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 29 Dec 2014 17:27:43 +0100 Subject: [PATCH 8/9] sam: fix code format and indent in UART/USART class --- .../arduino/sam/cores/arduino/UARTClass.cpp | 102 +++++++++--------- .../arduino/sam/cores/arduino/UARTClass.h | 42 ++++---- .../arduino/sam/cores/arduino/USARTClass.cpp | 19 ++-- .../arduino/sam/cores/arduino/USARTClass.h | 22 ++-- 4 files changed, 94 insertions(+), 91 deletions(-) diff --git a/hardware/arduino/sam/cores/arduino/UARTClass.cpp b/hardware/arduino/sam/cores/arduino/UARTClass.cpp index 0dc74fa2f..22ec20abb 100644 --- a/hardware/arduino/sam/cores/arduino/UARTClass.cpp +++ b/hardware/arduino/sam/cores/arduino/UARTClass.cpp @@ -25,39 +25,37 @@ UARTClass::UARTClass( Uart *pUart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer *pRx_buffer, RingBuffer *pTx_buffer ) { - _rx_buffer = pRx_buffer ; + _rx_buffer = pRx_buffer; _tx_buffer = pTx_buffer; - _pUart=pUart ; - _dwIrq=dwIrq ; - _dwId=dwId ; + _pUart=pUart; + _dwIrq=dwIrq; + _dwId=dwId; } // Public Methods ////////////////////////////////////////////////////////////// - - void UARTClass::begin( const uint32_t dwBaudRate ) { - begin( dwBaudRate, UART_MR_PAR_NO | UART_MR_CHMODE_NORMAL ); + begin( dwBaudRate, UART_MR_PAR_NO | UART_MR_CHMODE_NORMAL ); } void UARTClass::begin( const uint32_t dwBaudRate, const uint32_t config ) { // Configure PMC - pmc_enable_periph_clk( _dwId ) ; + pmc_enable_periph_clk( _dwId ); // Disable PDC channel - _pUart->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS ; + _pUart->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS; // Reset and disable receiver and transmitter - _pUart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RXDIS | UART_CR_TXDIS ; + _pUart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RXDIS | UART_CR_TXDIS; // Configure mode - _pUart->UART_MR = config ; + _pUart->UART_MR = config; // Configure baudrate (asynchronous, no oversampling) - _pUart->UART_BRGR = (SystemCoreClock / dwBaudRate) >> 4 ; + _pUart->UART_BRGR = (SystemCoreClock / dwBaudRate) >> 4; // Configure interrupts _pUart->UART_IDR = 0xFFFFFFFF; @@ -66,41 +64,41 @@ void UARTClass::begin( const uint32_t dwBaudRate, const uint32_t config ) // Enable UART interrupt in NVIC NVIC_EnableIRQ(_dwIrq); - //make sure both ring buffers are initialized back to empty. + // Make sure both ring buffers are initialized back to empty. _rx_buffer->_iHead = _rx_buffer->_iTail = 0; _tx_buffer->_iHead = _tx_buffer->_iTail = 0; // Enable receiver and transmitter - _pUart->UART_CR = UART_CR_RXEN | UART_CR_TXEN ; + _pUart->UART_CR = UART_CR_RXEN | UART_CR_TXEN; } void UARTClass::end( void ) { - // clear any received data - _rx_buffer->_iHead = _rx_buffer->_iTail ; + // Clear any received data + _rx_buffer->_iHead = _rx_buffer->_iTail; // Wait for any outstanding data to be sent flush(); // Disable UART interrupt in NVIC - NVIC_DisableIRQ( _dwIrq ) ; + NVIC_DisableIRQ( _dwIrq ); - pmc_disable_periph_clk( _dwId ) ; + pmc_disable_periph_clk( _dwId ); } void UARTClass::setInterruptPriority(uint32_t priority) { - NVIC_SetPriority(_dwIrq, priority & 0x0F); + NVIC_SetPriority(_dwIrq, priority & 0x0F); } uint32_t UARTClass::getInterruptPriority() { - return NVIC_GetPriority(_dwIrq); + return NVIC_GetPriority(_dwIrq); } int UARTClass::available( void ) { - return (uint32_t)(SERIAL_BUFFER_SIZE + _rx_buffer->_iHead - _rx_buffer->_iTail) % SERIAL_BUFFER_SIZE ; + return (uint32_t)(SERIAL_BUFFER_SIZE + _rx_buffer->_iHead - _rx_buffer->_iTail) % SERIAL_BUFFER_SIZE; } int UARTClass::availableForWrite(void) @@ -114,20 +112,20 @@ int UARTClass::availableForWrite(void) int UARTClass::peek( void ) { if ( _rx_buffer->_iHead == _rx_buffer->_iTail ) - return -1 ; + return -1; - return _rx_buffer->_aucBuffer[_rx_buffer->_iTail] ; + return _rx_buffer->_aucBuffer[_rx_buffer->_iTail]; } int UARTClass::read( void ) { // if the head isn't ahead of the tail, we don't have any characters if ( _rx_buffer->_iHead == _rx_buffer->_iTail ) - return -1 ; + return -1; - uint8_t uc = _rx_buffer->_aucBuffer[_rx_buffer->_iTail] ; - _rx_buffer->_iTail = (unsigned int)(_rx_buffer->_iTail + 1) % SERIAL_BUFFER_SIZE ; - return uc ; + uint8_t uc = _rx_buffer->_aucBuffer[_rx_buffer->_iTail]; + _rx_buffer->_iTail = (unsigned int)(_rx_buffer->_iTail + 1) % SERIAL_BUFFER_SIZE; + return uc; } void UARTClass::flush( void ) @@ -135,25 +133,29 @@ void UARTClass::flush( void ) while (_tx_buffer->_iHead != _tx_buffer->_iTail); //wait for transmit data to be sent // Wait for transmission to complete while ((_pUart->UART_SR & UART_SR_TXRDY) != UART_SR_TXRDY) - ; + ; } size_t UARTClass::write( const uint8_t uc_data ) { - if (((_pUart->UART_SR & UART_SR_TXRDY) != UART_SR_TXRDY) | (_tx_buffer->_iTail != _tx_buffer->_iHead)) //is the hardware currently busy? + // Is the hardware currently busy? + if (((_pUart->UART_SR & UART_SR_TXRDY) != UART_SR_TXRDY) | + (_tx_buffer->_iTail != _tx_buffer->_iHead)) { - //if busy we buffer - unsigned int l = (_tx_buffer->_iHead + 1) % SERIAL_BUFFER_SIZE; - while (_tx_buffer->_iTail == l); //spin locks if we're about to overwrite the buffer. This continues once the data is sent + // If busy we buffer + unsigned int l = (_tx_buffer->_iHead + 1) % SERIAL_BUFFER_SIZE; + while (_tx_buffer->_iTail == l) + ; // Spin locks if we're about to overwrite the buffer. This continues once the data is sent - _tx_buffer->_aucBuffer[_tx_buffer->_iHead] = uc_data; - _tx_buffer->_iHead = l; - _pUart->UART_IER = UART_IER_TXRDY; //make sure TX interrupt is enabled + _tx_buffer->_aucBuffer[_tx_buffer->_iHead] = uc_data; + _tx_buffer->_iHead = l; + // Make sure TX interrupt is enabled + _pUart->UART_IER = UART_IER_TXRDY; } else { - // Send character - _pUart->UART_THR = uc_data ; + // Bypass buffering and send character directly + _pUart->UART_THR = uc_data; } return 1; } @@ -162,28 +164,28 @@ void UARTClass::IrqHandler( void ) { uint32_t status = _pUart->UART_SR; - // Did we receive data ? + // Did we receive data? if ((status & UART_SR_RXRDY) == UART_SR_RXRDY) _rx_buffer->store_char(_pUart->UART_RHR); - //Do we need to keep sending data? + // Do we need to keep sending data? if ((status & UART_SR_TXRDY) == UART_SR_TXRDY) { - if (_tx_buffer->_iTail != _tx_buffer->_iHead) { //just in case - _pUart->UART_THR = _tx_buffer->_aucBuffer[_tx_buffer->_iTail]; - _tx_buffer->_iTail = (unsigned int)(_tx_buffer->_iTail + 1) % SERIAL_BUFFER_SIZE; - } - else - { - _pUart->UART_IDR = UART_IDR_TXRDY; //mask off transmit interrupt so we don't get it anymore - } + if (_tx_buffer->_iTail != _tx_buffer->_iHead) { + _pUart->UART_THR = _tx_buffer->_aucBuffer[_tx_buffer->_iTail]; + _tx_buffer->_iTail = (unsigned int)(_tx_buffer->_iTail + 1) % SERIAL_BUFFER_SIZE; + } + else + { + // Mask off transmit interrupt so we don't get it anymore + _pUart->UART_IDR = UART_IDR_TXRDY; + } } // Acknowledge errors - if ((status & UART_SR_OVRE) == UART_SR_OVRE || - (status & UART_SR_FRAME) == UART_SR_FRAME) + if ((status & UART_SR_OVRE) == UART_SR_OVRE || (status & UART_SR_FRAME) == UART_SR_FRAME) { - // TODO: error reporting outside ISR + // TODO: error reporting outside ISR _pUart->UART_CR |= UART_CR_RSTSTA; } } diff --git a/hardware/arduino/sam/cores/arduino/UARTClass.h b/hardware/arduino/sam/cores/arduino/UARTClass.h index b60fae3d0..7cb5ba7f1 100644 --- a/hardware/arduino/sam/cores/arduino/UARTClass.h +++ b/hardware/arduino/sam/cores/arduino/UARTClass.h @@ -28,36 +28,36 @@ class UARTClass : public HardwareSerial { protected: - RingBuffer *_rx_buffer ; - RingBuffer *_tx_buffer; + RingBuffer *_rx_buffer; + RingBuffer *_tx_buffer; protected: - Uart* _pUart ; - IRQn_Type _dwIrq ; - uint32_t _dwId ; + Uart* _pUart; + IRQn_Type _dwIrq; + uint32_t _dwId; public: - UARTClass( Uart* pUart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer, RingBuffer* pTx_buffer) ; + UARTClass(Uart* pUart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer, RingBuffer* pTx_buffer); - void begin( const uint32_t dwBaudRate ) ; - void begin( const uint32_t dwBaudRate , const uint32_t config ) ; - void end( void ) ; - int available( void ) ; - int availableForWrite(void); - int peek( void ) ; - int read( void ) ; - void flush( void ) ; - size_t write( const uint8_t c ) ; - void setInterruptPriority(uint32_t priority); - uint32_t getInterruptPriority(); + void begin(const uint32_t dwBaudRate); + void begin(const uint32_t dwBaudRate, const uint32_t config); + void end(void); + int available(void); + int availableForWrite(void); + int peek(void); + int read(void); + void flush(void); + size_t write(const uint8_t c); + void setInterruptPriority(uint32_t priority); + uint32_t getInterruptPriority(); - void IrqHandler( void ) ; + void IrqHandler( void ); #if defined __GNUC__ /* GCC CS3 */ - using Print::write ; // pull in write(str) and write(buf, size) from Print + using Print::write; // pull in write(str) and write(buf, size) from Print #elif defined __ICCARM__ /* IAR Ewarm 5.41+ */ -// virtual void write( const char *str ) ; -// virtual void write( const uint8_t *buffer, size_t size ) ; +// virtual void write( const char *str ); +// virtual void write( const uint8_t *buffer, size_t size ); #endif operator bool() { return true; }; // UART always active diff --git a/hardware/arduino/sam/cores/arduino/USARTClass.cpp b/hardware/arduino/sam/cores/arduino/USARTClass.cpp index 310e5680b..1f901626d 100644 --- a/hardware/arduino/sam/cores/arduino/USARTClass.cpp +++ b/hardware/arduino/sam/cores/arduino/USARTClass.cpp @@ -23,41 +23,42 @@ // Constructors //////////////////////////////////////////////////////////////// -USARTClass::USARTClass( Usart* pUsart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer, RingBuffer* pTx_buffer ) : UARTClass((Uart*)pUsart, dwIrq, dwId, pRx_buffer, pTx_buffer) +USARTClass::USARTClass( Usart* pUsart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer, RingBuffer* pTx_buffer ) + : UARTClass((Uart*)pUsart, dwIrq, dwId, pRx_buffer, pTx_buffer) { - - _pUsart=pUsart ; //In case anyone needs USART specific functionality in the future + // In case anyone needs USART specific functionality in the future + _pUsart=pUsart; } // Public Methods ////////////////////////////////////////////////////////////// void USARTClass::begin( const uint32_t dwBaudRate ) { - begin( dwBaudRate, SERIAL_8N1 ); + begin( dwBaudRate, SERIAL_8N1 ); } void USARTClass::begin( const uint32_t dwBaudRate, const uint32_t config ) { - UARTClass::begin(dwBaudRate, config); + UARTClass::begin(dwBaudRate, config); } void USARTClass::end( void ) { - UARTClass::end(); + UARTClass::end(); } void USARTClass::flush( void ) { - UARTClass::flush(); + UARTClass::flush(); } size_t USARTClass::write( const uint8_t uc_data ) { - return UARTClass::write(uc_data); + return UARTClass::write(uc_data); } void USARTClass::IrqHandler( void ) { - UARTClass::IrqHandler(); + UARTClass::IrqHandler(); } diff --git a/hardware/arduino/sam/cores/arduino/USARTClass.h b/hardware/arduino/sam/cores/arduino/USARTClass.h index 53fee41d8..3ac4cceef 100644 --- a/hardware/arduino/sam/cores/arduino/USARTClass.h +++ b/hardware/arduino/sam/cores/arduino/USARTClass.h @@ -59,24 +59,24 @@ class USARTClass : public UARTClass { protected: - Usart* _pUsart ; + Usart* _pUsart; public: - USARTClass( Usart* pUsart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer, RingBuffer* pTx_buffer ) ; + USARTClass( Usart* pUsart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer, RingBuffer* pTx_buffer ); - void begin( const uint32_t dwBaudRate ) ; - void begin( const uint32_t dwBaudRate , const uint32_t config ) ; - void end( void ) ; - void flush( void ) ; - size_t write( const uint8_t c ) ; + void begin( const uint32_t dwBaudRate ); + void begin( const uint32_t dwBaudRate , const uint32_t config ); + void end( void ); + void flush( void ); + size_t write( const uint8_t c ); - void IrqHandler( void ) ; + void IrqHandler( void ); #if defined __GNUC__ /* GCC CS3 */ - using Print::write ; // pull in write(str) and write(buf, size) from Print + using Print::write; // pull in write(str) and write(buf, size) from Print #elif defined __ICCARM__ /* IAR Ewarm 5.41+ */ -// virtual void write( const char *str ) ; -// virtual void write( const uint8_t *buffer, size_t size ) ; +// virtual void write( const char *str ); +// virtual void write( const uint8_t *buffer, size_t size ); #endif operator bool() { return true; }; // USART always active From 37ea166e1999e57eee6835786d3310c7ef8f2ec3 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 29 Dec 2014 17:57:41 +0100 Subject: [PATCH 9/9] sam: refined UART/USART class inheritance Let Usart inherit all methods from Uart. --- .../arduino/sam/cores/arduino/UARTClass.h | 11 +++----- .../arduino/sam/cores/arduino/USARTClass.cpp | 25 ------------------- .../arduino/sam/cores/arduino/USARTClass.h | 16 +----------- 3 files changed, 4 insertions(+), 48 deletions(-) diff --git a/hardware/arduino/sam/cores/arduino/UARTClass.h b/hardware/arduino/sam/cores/arduino/UARTClass.h index 7cb5ba7f1..1bc223d80 100644 --- a/hardware/arduino/sam/cores/arduino/UARTClass.h +++ b/hardware/arduino/sam/cores/arduino/UARTClass.h @@ -48,17 +48,12 @@ class UARTClass : public HardwareSerial int read(void); void flush(void); size_t write(const uint8_t c); + using Print::write; // pull in write(str) and write(buf, size) from Print + void setInterruptPriority(uint32_t priority); uint32_t getInterruptPriority(); - void IrqHandler( void ); - -#if defined __GNUC__ /* GCC CS3 */ - using Print::write; // pull in write(str) and write(buf, size) from Print -#elif defined __ICCARM__ /* IAR Ewarm 5.41+ */ -// virtual void write( const char *str ); -// virtual void write( const uint8_t *buffer, size_t size ); -#endif + void IrqHandler(void); operator bool() { return true; }; // UART always active }; diff --git a/hardware/arduino/sam/cores/arduino/USARTClass.cpp b/hardware/arduino/sam/cores/arduino/USARTClass.cpp index 1f901626d..9fcfa30a6 100644 --- a/hardware/arduino/sam/cores/arduino/USARTClass.cpp +++ b/hardware/arduino/sam/cores/arduino/USARTClass.cpp @@ -32,33 +32,8 @@ USARTClass::USARTClass( Usart* pUsart, IRQn_Type dwIrq, uint32_t dwId, RingBuffe // Public Methods ////////////////////////////////////////////////////////////// -void USARTClass::begin( const uint32_t dwBaudRate ) -{ - begin( dwBaudRate, SERIAL_8N1 ); -} - void USARTClass::begin( const uint32_t dwBaudRate, const uint32_t config ) { UARTClass::begin(dwBaudRate, config); } -void USARTClass::end( void ) -{ - UARTClass::end(); -} - -void USARTClass::flush( void ) -{ - UARTClass::flush(); -} - -size_t USARTClass::write( const uint8_t uc_data ) -{ - return UARTClass::write(uc_data); -} - -void USARTClass::IrqHandler( void ) -{ - UARTClass::IrqHandler(); -} - diff --git a/hardware/arduino/sam/cores/arduino/USARTClass.h b/hardware/arduino/sam/cores/arduino/USARTClass.h index 3ac4cceef..235f54910 100644 --- a/hardware/arduino/sam/cores/arduino/USARTClass.h +++ b/hardware/arduino/sam/cores/arduino/USARTClass.h @@ -64,22 +64,8 @@ class USARTClass : public UARTClass public: USARTClass( Usart* pUsart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer, RingBuffer* pTx_buffer ); - void begin( const uint32_t dwBaudRate ); void begin( const uint32_t dwBaudRate , const uint32_t config ); - void end( void ); - void flush( void ); - size_t write( const uint8_t c ); - - void IrqHandler( void ); - -#if defined __GNUC__ /* GCC CS3 */ - using Print::write; // pull in write(str) and write(buf, size) from Print -#elif defined __ICCARM__ /* IAR Ewarm 5.41+ */ -// virtual void write( const char *str ); -// virtual void write( const uint8_t *buffer, size_t size ); -#endif - - operator bool() { return true; }; // USART always active + using UARTClass::begin; // Needed only for polymorphic methods }; #endif // _USART_CLASS_