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));