From 2b1bebc58107876c18378c894dd5b473a9edcf4f Mon Sep 17 00:00:00 2001 From: techpaul Date: Mon, 18 Jan 2016 01:09:55 +0000 Subject: [PATCH 1/3] Compiler Warning UARTClass.cpp and RingBuffer.h correction --- hardware/arduino/sam/cores/arduino/RingBuffer.h | 2 +- hardware/arduino/sam/cores/arduino/UARTClass.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hardware/arduino/sam/cores/arduino/RingBuffer.h b/hardware/arduino/sam/cores/arduino/RingBuffer.h index 1a5861b0b4c..6041430ea47 100644 --- a/hardware/arduino/sam/cores/arduino/RingBuffer.h +++ b/hardware/arduino/sam/cores/arduino/RingBuffer.h @@ -22,7 +22,7 @@ #include // Define constants and variables for buffering incoming serial data. We're -// using a ring buffer (I think), in which head is the index of the location +// using a ring buffer, 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 128 diff --git a/hardware/arduino/sam/cores/arduino/UARTClass.cpp b/hardware/arduino/sam/cores/arduino/UARTClass.cpp index ed1cb26870b..36de13586ce 100644 --- a/hardware/arduino/sam/cores/arduino/UARTClass.cpp +++ b/hardware/arduino/sam/cores/arduino/UARTClass.cpp @@ -149,12 +149,12 @@ size_t UARTClass::write( const uint8_t uc_data ) (_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) + int nextWrite = (_tx_buffer->_iHead + 1) % SERIAL_BUFFER_SIZE; + while (_tx_buffer->_iTail == nextWrite) ; // 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; + _tx_buffer->_iHead = nextWrite; // Make sure TX interrupt is enabled _pUart->UART_IER = UART_IER_TXRDY; } From e831ce9f13d7dda685c4aa88349d0346dfc5ff3e Mon Sep 17 00:00:00 2001 From: techpaul Date: Mon, 18 Jan 2016 01:17:44 +0000 Subject: [PATCH 2/3] Correct Compiler Warning UARTClass.cpp and Comment in RingBuffer.h --- .../arduino/sam/cores/arduino/RingBuffer.h~ | 42 ++++ .../arduino/sam/cores/arduino/UARTClass.cpp~ | 198 ++++++++++++++++++ 2 files changed, 240 insertions(+) create mode 100644 hardware/arduino/sam/cores/arduino/RingBuffer.h~ create mode 100644 hardware/arduino/sam/cores/arduino/UARTClass.cpp~ diff --git a/hardware/arduino/sam/cores/arduino/RingBuffer.h~ b/hardware/arduino/sam/cores/arduino/RingBuffer.h~ new file mode 100644 index 00000000000..1a5861b0b4c --- /dev/null +++ b/hardware/arduino/sam/cores/arduino/RingBuffer.h~ @@ -0,0 +1,42 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _RING_BUFFER_ +#define _RING_BUFFER_ + +#include + +// Define constants and variables for buffering incoming serial data. We're +// 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 128 + +class RingBuffer +{ + public: + volatile uint8_t _aucBuffer[SERIAL_BUFFER_SIZE] ; + volatile int _iHead ; + volatile int _iTail ; + + public: + RingBuffer( void ) ; + void store_char( uint8_t c ) ; +} ; + +#endif /* _RING_BUFFER_ */ diff --git a/hardware/arduino/sam/cores/arduino/UARTClass.cpp~ b/hardware/arduino/sam/cores/arduino/UARTClass.cpp~ new file mode 100644 index 00000000000..ed1cb26870b --- /dev/null +++ b/hardware/arduino/sam/cores/arduino/UARTClass.cpp~ @@ -0,0 +1,198 @@ +/* + Copyright (c) 2011 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include +#include +#include "UARTClass.h" + +// Constructors //////////////////////////////////////////////////////////////// + +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; + _dwId=dwId; +} + +// Public Methods ////////////////////////////////////////////////////////////// + +void UARTClass::begin(const uint32_t dwBaudRate) +{ + begin(dwBaudRate, Mode_8N1); +} + +void UARTClass::begin(const uint32_t dwBaudRate, const UARTModes config) +{ + uint32_t modeReg = static_cast(config) & 0x00000E00; + init(dwBaudRate, modeReg | UART_MR_CHMODE_NORMAL); +} + +void UARTClass::init(const uint32_t dwBaudRate, const uint32_t modeReg) +{ + // Configure PMC + pmc_enable_periph_clk( _dwId ); + + // Disable PDC channel + _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; + + // Configure mode + _pUart->UART_MR = modeReg; + + // 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); + + // 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; +} + +void UARTClass::end( void ) +{ + // 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 ); + + 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; +} + +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 ) + return -1; + + 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; + + 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 transmit data to be sent + // Wait for transmission to complete + while ((_pUart->UART_SR & UART_SR_TXEMPTY) != UART_SR_TXEMPTY) + ; +} + +size_t UARTClass::write( const uint8_t uc_data ) +{ + // 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 + + _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 + { + // Bypass buffering and send character directly + _pUart->UART_THR = uc_data; + } + return 1; +} + +void UARTClass::IrqHandler( void ) +{ + 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); + + // Do we need to keep sending data? + if ((status & UART_SR_TXRDY) == UART_SR_TXRDY) + { + 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) + { + // TODO: error reporting outside ISR + _pUart->UART_CR |= UART_CR_RSTSTA; + } +} + From 660d38d0c8424b88a752c405a8cf9618e27d6d25 Mon Sep 17 00:00:00 2001 From: techpaul Date: Mon, 18 Jan 2016 14:26:20 +0000 Subject: [PATCH 3/3] Delete erroneous temporary files --- .../arduino/sam/cores/arduino/RingBuffer.h~ | 42 ---- .../arduino/sam/cores/arduino/UARTClass.cpp~ | 198 ------------------ 2 files changed, 240 deletions(-) delete mode 100644 hardware/arduino/sam/cores/arduino/RingBuffer.h~ delete mode 100644 hardware/arduino/sam/cores/arduino/UARTClass.cpp~ diff --git a/hardware/arduino/sam/cores/arduino/RingBuffer.h~ b/hardware/arduino/sam/cores/arduino/RingBuffer.h~ deleted file mode 100644 index 1a5861b0b4c..00000000000 --- a/hardware/arduino/sam/cores/arduino/RingBuffer.h~ +++ /dev/null @@ -1,42 +0,0 @@ -/* - Copyright (c) 2011 Arduino. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _RING_BUFFER_ -#define _RING_BUFFER_ - -#include - -// Define constants and variables for buffering incoming serial data. We're -// 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 128 - -class RingBuffer -{ - public: - volatile uint8_t _aucBuffer[SERIAL_BUFFER_SIZE] ; - volatile int _iHead ; - volatile int _iTail ; - - public: - RingBuffer( void ) ; - void store_char( uint8_t c ) ; -} ; - -#endif /* _RING_BUFFER_ */ diff --git a/hardware/arduino/sam/cores/arduino/UARTClass.cpp~ b/hardware/arduino/sam/cores/arduino/UARTClass.cpp~ deleted file mode 100644 index ed1cb26870b..00000000000 --- a/hardware/arduino/sam/cores/arduino/UARTClass.cpp~ +++ /dev/null @@ -1,198 +0,0 @@ -/* - Copyright (c) 2011 Arduino. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include "UARTClass.h" - -// Constructors //////////////////////////////////////////////////////////////// - -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; - _dwId=dwId; -} - -// Public Methods ////////////////////////////////////////////////////////////// - -void UARTClass::begin(const uint32_t dwBaudRate) -{ - begin(dwBaudRate, Mode_8N1); -} - -void UARTClass::begin(const uint32_t dwBaudRate, const UARTModes config) -{ - uint32_t modeReg = static_cast(config) & 0x00000E00; - init(dwBaudRate, modeReg | UART_MR_CHMODE_NORMAL); -} - -void UARTClass::init(const uint32_t dwBaudRate, const uint32_t modeReg) -{ - // Configure PMC - pmc_enable_periph_clk( _dwId ); - - // Disable PDC channel - _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; - - // Configure mode - _pUart->UART_MR = modeReg; - - // 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); - - // 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; -} - -void UARTClass::end( void ) -{ - // 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 ); - - 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; -} - -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 ) - return -1; - - 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; - - 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 transmit data to be sent - // Wait for transmission to complete - while ((_pUart->UART_SR & UART_SR_TXEMPTY) != UART_SR_TXEMPTY) - ; -} - -size_t UARTClass::write( const uint8_t uc_data ) -{ - // 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 - - _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 - { - // Bypass buffering and send character directly - _pUart->UART_THR = uc_data; - } - return 1; -} - -void UARTClass::IrqHandler( void ) -{ - 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); - - // Do we need to keep sending data? - if ((status & UART_SR_TXRDY) == UART_SR_TXRDY) - { - 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) - { - // TODO: error reporting outside ISR - _pUart->UART_CR |= UART_CR_RSTSTA; - } -} -