From c8ec267d0bb16b53359d5eb932784bbd62213caf Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 23 Nov 2011 23:15:13 +0100 Subject: [PATCH] Bugfix UARTClass --- hardware/sam/cores/sam/UARTClass.cpp | 96 +++++++++---------- hardware/sam/cores/sam/UARTClass.h | 3 +- hardware/sam/variants/arduino_due/variant.cpp | 13 +-- 3 files changed, 50 insertions(+), 62 deletions(-) diff --git a/hardware/sam/cores/sam/UARTClass.cpp b/hardware/sam/cores/sam/UARTClass.cpp index 76a60d3b3..2ef23a7e1 100644 --- a/hardware/sam/cores/sam/UARTClass.cpp +++ b/hardware/sam/cores/sam/UARTClass.cpp @@ -23,10 +23,9 @@ // Constructors //////////////////////////////////////////////////////////////// -UARTClass::UARTClass( Uart* pUart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer, RingBuffer* pTx_buffer ) +UARTClass::UARTClass( Uart* pUart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer ) { _rx_buffer = pRx_buffer ; - _tx_buffer = pTx_buffer ; _pUart=pUart ; _dwIrq=dwIrq ; @@ -37,42 +36,43 @@ UARTClass::UARTClass( Uart* pUart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* p void UARTClass::begin( const uint32_t dwBaudRate ) { - /* Configure PMC */ + // Configure PMC PMC_EnablePeripheral( _dwId ) ; - /* Reset and disable receiver & transmitter */ - _pUart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RXDIS | UART_CR_TXDIS ; - - /* Configure mode */ - _pUart->UART_MR = UART_MR_PAR_NO ; - - /* Configure baudrate */ - /* Asynchronous, no oversampling */ - _pUart->UART_BRGR = (SystemCoreClock / dwBaudRate) >> 4 ; - - /* Disable PDC channel */ + // Disable PDC channel _pUart->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS ; - /* Configure the ENDRX interrupt */ - _pUart->UART_IER=UART_IER_ENDRX ; + // Reset and disable receiver and transmitter + _pUart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RXDIS | UART_CR_TXDIS ; - /* Enable UART interrupt in NVIC */ -// NVIC_EnableIRQ( _dwIrq ) ; + // Configure mode + _pUart->UART_MR = UART_MR_PAR_NO | UART_MR_CHMODE_NORMAL ; - /* Enable receiver and transmitter */ + // Configure baudrate (asynchronous, no oversampling) + _pUart->UART_BRGR = (SystemCoreClock / dwBaudRate) >> 4 ; + + // Configure interrupts + _pUart->UART_IDR = 0xFFFFFFFF; + _pUart->UART_IER = UART_IER_RXRDY | UART_IER_OVRE | UART_IER_FRAME; + + // Enable UART interrupt in NVIC + NVIC_EnableIRQ(_dwIrq); + + // Enable receiver and transmitter _pUart->UART_CR = UART_CR_RXEN | UART_CR_TXEN ; } void UARTClass::end( void ) { - // wait for transmission of outgoing data - //while ( _tx_buffer->_iHead != _tx_buffer->_iTail ) - //{ - //} - // clear any received data _rx_buffer->_iHead = _rx_buffer->_iTail ; + // Disable UART interrupt in NVIC + NVIC_DisableIRQ( _dwIrq ) ; + + // Wait for any outstanding data to be sent + flush(); + PMC_DisablePeripheral( _dwId ) ; } @@ -84,55 +84,53 @@ int UARTClass::available( void ) int UARTClass::peek( void ) { if ( _rx_buffer->_iHead == _rx_buffer->_iTail ) - { return -1 ; - } - else - { - 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 ; - } - else - { - 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 ) { - //while ( _tx_buffer->_iHead != _tx_buffer->_iTail ) - //{ - //} + // Wait for transmission to complete + while ((_pUart->UART_SR & UART_SR_TXRDY) != UART_SR_TXRDY) + ; } void UARTClass::write( const uint8_t uc_data ) { - /* Check if the transmitter is ready */ - while ( (_pUart->UART_SR & UART_SR_TXRDY) != UART_SR_TXRDY ) + // Check if the transmitter is ready + while ((_pUart->UART_SR & UART_SR_TXRDY) != UART_SR_TXRDY) ; - /* Send character */ - _pUart->UART_THR = uc_data ; + // Send character + _pUart->UART_THR = uc_data; } void UARTClass::IrqHandler( void ) { - /* Did we receive data ? */ - if ( (_pUart->UART_IER & UART_IER_ENDRX) == UART_IER_ENDRX ) + uint32_t status = _pUart->UART_SR; + + // Did we receive data ? + if ((status & UART_SR_RXRDY) == UART_SR_RXRDY) + _rx_buffer->store_char(_pUart->UART_RHR); + + // Acknowledge errors + if ((status & UART_SR_OVRE) == UART_SR_OVRE || + (status & UART_SR_FRAME) == UART_SR_FRAME) { - _rx_buffer->store_char( _pUart->UART_RHR ) ; + // TODO: error reporting outside ISR + _pUart->UART_CR |= UART_CR_RSTSTA; } } diff --git a/hardware/sam/cores/sam/UARTClass.h b/hardware/sam/cores/sam/UARTClass.h index f4d459a2b..0ce9d714c 100644 --- a/hardware/sam/cores/sam/UARTClass.h +++ b/hardware/sam/cores/sam/UARTClass.h @@ -25,7 +25,6 @@ class UARTClass : public HardwareSerial { protected: RingBuffer *_rx_buffer ; - RingBuffer *_tx_buffer ; protected: Uart* _pUart ; @@ -33,7 +32,7 @@ class UARTClass : public HardwareSerial 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 ) ; void begin( const uint32_t dwBaudRate ) ; void end( void ) ; diff --git a/hardware/sam/variants/arduino_due/variant.cpp b/hardware/sam/variants/arduino_due/variant.cpp index 4ad038eee..e1133db3e 100644 --- a/hardware/sam/variants/arduino_due/variant.cpp +++ b/hardware/sam/variants/arduino_due/variant.cpp @@ -265,24 +265,15 @@ extern const PinDescription g_APinDescription[]= * UART objects */ RingBuffer rx_buffer1 ; -RingBuffer tx_buffer1 ; -UARTClass Serial( UART, UART_IRQn, ID_UART, &rx_buffer1, &tx_buffer1 ) ; - -#ifdef __cplusplus -extern "C" { -#endif +UARTClass Serial( UART, UART_IRQn, ID_UART, &rx_buffer1 ) ; // IT handlers -extern void UART_IrqHandler( void ) +void UART_IrqHandler(void) { Serial.IrqHandler() ; } -#ifdef __cplusplus -} -#endif - // ---------------------------------------------------------------------------- /* * USART objects