From d8d6d62853a5308c21b95dad4bdd64e358e857cc Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 6 Apr 2014 20:25:31 +0100 Subject: [PATCH 1/3] Fix for Due Wire library Fix reading and use of TWI status register. Also, update endTransmission to be compatible with original & give more useful return. --- hardware/arduino/sam/libraries/Wire/Wire.cpp | 56 ++++++++++++++------ 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/hardware/arduino/sam/libraries/Wire/Wire.cpp b/hardware/arduino/sam/libraries/Wire/Wire.cpp index cbf46db9010..9ba314f44ea 100644 --- a/hardware/arduino/sam/libraries/Wire/Wire.cpp +++ b/hardware/arduino/sam/libraries/Wire/Wire.cpp @@ -29,9 +29,13 @@ static inline bool TWI_FailedAcknowledge(Twi *pTwi) { } static inline bool TWI_WaitTransferComplete(Twi *_twi, uint32_t _timeout) { - while (!TWI_TransferComplete(_twi)) { - if (TWI_FailedAcknowledge(_twi)) + uint32_t _status_reg = 0; + while ((_status_reg & TWI_SR_TXCOMP) != TWI_SR_TXCOMP) { + _status_reg = TWI_GetStatus(_twi); + + if (_status_reg & TWI_SR_NACK) return false; + if (--_timeout == 0) return false; } @@ -39,22 +43,32 @@ static inline bool TWI_WaitTransferComplete(Twi *_twi, uint32_t _timeout) { } static inline bool TWI_WaitByteSent(Twi *_twi, uint32_t _timeout) { - while (!TWI_ByteSent(_twi)) { - if (TWI_FailedAcknowledge(_twi)) + uint32_t _status_reg = 0; + while ((_status_reg & TWI_SR_TXRDY) != TWI_SR_TXRDY) { + _status_reg = TWI_GetStatus(_twi); + + if (_status_reg & TWI_SR_NACK) return false; + if (--_timeout == 0) return false; } + return true; } static inline bool TWI_WaitByteReceived(Twi *_twi, uint32_t _timeout) { - while (!TWI_ByteReceived(_twi)) { - if (TWI_FailedAcknowledge(_twi)) + uint32_t _status_reg = 0; + while ((_status_reg & TWI_SR_RXRDY) != TWI_SR_RXRDY) { + _status_reg = TWI_GetStatus(_twi); + + if (_status_reg & TWI_SR_NACK) return false; + if (--_timeout == 0) return false; } + return true; } @@ -175,22 +189,30 @@ void TwoWire::beginTransmission(int address) { // devices will behave oddly if they do not see a STOP. // uint8_t TwoWire::endTransmission(uint8_t sendStop) { + uint8_t error = 0; // transmit buffer (blocking) TWI_StartWrite(twi, txAddress, 0, 0, txBuffer[0]); - TWI_WaitByteSent(twi, XMIT_TIMEOUT); - int sent = 1; - while (sent < txBufferLength) { - TWI_WriteByte(twi, txBuffer[sent++]); - TWI_WaitByteSent(twi, XMIT_TIMEOUT); + if (!TWI_WaitByteSent(twi, XMIT_TIMEOUT)) + error = 2; // error, got NACK on address transmit + + if (error == 0) { + uint16_t sent = 1; + while (sent < txBufferLength) { + TWI_WriteByte(twi, txBuffer[sent++]); + if (!TWI_WaitByteSent(twi, XMIT_TIMEOUT)) + error = 3; // error, got NACK during data transmmit + } + } + + if (error == 0) { + TWI_Stop(twi); + if (!TWI_WaitTransferComplete(twi, XMIT_TIMEOUT)) + error = 4; // error, finishing up } - TWI_Stop( twi); - TWI_WaitTransferComplete(twi, XMIT_TIMEOUT); - - // empty buffer - txBufferLength = 0; + txBufferLength = 0; // empty buffer status = MASTER_IDLE; - return sent; + return error; } // This provides backwards compatibility with the original From 05ca9e125447343feca2c9b8f42c2a2e94a7b7ea Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 7 Apr 2014 18:29:41 +0100 Subject: [PATCH 2/3] Add config options to due Serial1, 2, and 3 Adds ability to set length, parity and stop bit configuration to hardware serial ports using USART module (Serial1, Serial2, and Serial 3) on Due to allow compatibility with avr devices. --- .../arduino/sam/cores/arduino/USARTClass.cpp | 9 ++++-- .../arduino/sam/cores/arduino/USARTClass.h | 32 +++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/hardware/arduino/sam/cores/arduino/USARTClass.cpp b/hardware/arduino/sam/cores/arduino/USARTClass.cpp index 6531c4c5b4b..d950c50c9af 100644 --- a/hardware/arduino/sam/cores/arduino/USARTClass.cpp +++ b/hardware/arduino/sam/cores/arduino/USARTClass.cpp @@ -35,6 +35,11 @@ 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 ) { // Configure PMC pmc_enable_periph_clk( _dwId ) ; @@ -46,8 +51,8 @@ void USARTClass::begin( const uint32_t dwBaudRate ) _pUsart->US_CR = US_CR_RSTRX | US_CR_RSTTX | US_CR_RXDIS | US_CR_TXDIS ; // Configure mode - _pUsart->US_MR = US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_8_BIT | US_MR_PAR_NO | - US_MR_NBSTOP_1_BIT | US_MR_CHMODE_NORMAL; + _pUsart->US_MR = config; + // Configure baudrate, asynchronous no oversampling _pUsart->US_BRGR = (SystemCoreClock / dwBaudRate) / 16 ; diff --git a/hardware/arduino/sam/cores/arduino/USARTClass.h b/hardware/arduino/sam/cores/arduino/USARTClass.h index deb74a71d29..d5d7ff963d5 100644 --- a/hardware/arduino/sam/cores/arduino/USARTClass.h +++ b/hardware/arduino/sam/cores/arduino/USARTClass.h @@ -25,6 +25,37 @@ // Includes Atmel CMSIS #include +// Define config for Serial.begin(baud, config); +#define SERIAL_5N1 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_5_BIT | US_MR_PAR_NO | US_MR_NBSTOP_1_BIT | US_MR_CHMODE_NORMAL) +#define SERIAL_6N1 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_6_BIT | US_MR_PAR_NO | US_MR_NBSTOP_1_BIT | US_MR_CHMODE_NORMAL) +#define SERIAL_7N1 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_7_BIT | US_MR_PAR_NO | US_MR_NBSTOP_1_BIT | US_MR_CHMODE_NORMAL) +#define SERIAL_8N1 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_8_BIT | US_MR_PAR_NO | US_MR_NBSTOP_1_BIT | US_MR_CHMODE_NORMAL) + +#define SERIAL_5N2 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_5_BIT | US_MR_PAR_NO | US_MR_NBSTOP_2_BIT | US_MR_CHMODE_NORMAL) +#define SERIAL_6N2 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_6_BIT | US_MR_PAR_NO | US_MR_NBSTOP_2_BIT | US_MR_CHMODE_NORMAL) +#define SERIAL_7N2 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_7_BIT | US_MR_PAR_NO | US_MR_NBSTOP_2_BIT | US_MR_CHMODE_NORMAL) +#define SERIAL_8N2 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_8_BIT | US_MR_PAR_NO | US_MR_NBSTOP_2_BIT | US_MR_CHMODE_NORMAL) + +#define SERIAL_5E1 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_5_BIT | US_MR_PAR_EVEN | US_MR_NBSTOP_1_BIT | US_MR_CHMODE_NORMAL) +#define SERIAL_6E1 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_6_BIT | US_MR_PAR_EVEN | US_MR_NBSTOP_1_BIT | US_MR_CHMODE_NORMAL) +#define SERIAL_7E1 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_7_BIT | US_MR_PAR_EVEN | US_MR_NBSTOP_1_BIT | US_MR_CHMODE_NORMAL) +#define SERIAL_8E1 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_8_BIT | US_MR_PAR_EVEN | US_MR_NBSTOP_1_BIT | US_MR_CHMODE_NORMAL) + +#define SERIAL_5E2 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_5_BIT | US_MR_PAR_EVEN | US_MR_NBSTOP_2_BIT | US_MR_CHMODE_NORMAL) +#define SERIAL_6E2 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_6_BIT | US_MR_PAR_EVEN | US_MR_NBSTOP_2_BIT | US_MR_CHMODE_NORMAL) +#define SERIAL_7E2 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_7_BIT | US_MR_PAR_EVEN | US_MR_NBSTOP_2_BIT | US_MR_CHMODE_NORMAL) +#define SERIAL_8E2 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_8_BIT | US_MR_PAR_EVEN | US_MR_NBSTOP_2_BIT | US_MR_CHMODE_NORMAL) + +#define SERIAL_5O1 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_5_BIT | US_MR_PAR_ODD | US_MR_NBSTOP_1_BIT | US_MR_CHMODE_NORMAL) +#define SERIAL_6O1 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_6_BIT | US_MR_PAR_ODD | US_MR_NBSTOP_1_BIT | US_MR_CHMODE_NORMAL) +#define SERIAL_7O1 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_7_BIT | US_MR_PAR_ODD | US_MR_NBSTOP_1_BIT | US_MR_CHMODE_NORMAL) +#define SERIAL_8O1 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_8_BIT | US_MR_PAR_ODD | US_MR_NBSTOP_1_BIT | US_MR_CHMODE_NORMAL) + +#define SERIAL_5O2 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_5_BIT | US_MR_PAR_ODD | US_MR_NBSTOP_2_BIT | US_MR_CHMODE_NORMAL) +#define SERIAL_6O2 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_6_BIT | US_MR_PAR_ODD | US_MR_NBSTOP_2_BIT | US_MR_CHMODE_NORMAL) +#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 { protected: @@ -39,6 +70,7 @@ class USARTClass : public HardwareSerial USARTClass( Usart* pUsart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer ) ; void begin( const uint32_t dwBaudRate ) ; + void begin( const uint32_t dwBaudRate , const uint32_t config ) ; void end( void ) ; int available( void ) ; int peek( void ) ; From 63f0ca06a8af7a223aacca8b9f93f65c1d90ec2b Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 7 Apr 2014 21:23:03 +0100 Subject: [PATCH 3/3] Revert "Add config options to due Serial1, 2, and 3" This reverts commit 05ca9e125447343feca2c9b8f42c2a2e94a7b7ea. --- .../arduino/sam/cores/arduino/USARTClass.cpp | 9 ++---- .../arduino/sam/cores/arduino/USARTClass.h | 32 ------------------- 2 files changed, 2 insertions(+), 39 deletions(-) diff --git a/hardware/arduino/sam/cores/arduino/USARTClass.cpp b/hardware/arduino/sam/cores/arduino/USARTClass.cpp index d950c50c9af..6531c4c5b4b 100644 --- a/hardware/arduino/sam/cores/arduino/USARTClass.cpp +++ b/hardware/arduino/sam/cores/arduino/USARTClass.cpp @@ -35,11 +35,6 @@ 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 ) { // Configure PMC pmc_enable_periph_clk( _dwId ) ; @@ -51,8 +46,8 @@ void USARTClass::begin( const uint32_t dwBaudRate, const uint32_t config ) _pUsart->US_CR = US_CR_RSTRX | US_CR_RSTTX | US_CR_RXDIS | US_CR_TXDIS ; // Configure mode - _pUsart->US_MR = config; - + _pUsart->US_MR = US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_8_BIT | US_MR_PAR_NO | + US_MR_NBSTOP_1_BIT | US_MR_CHMODE_NORMAL; // Configure baudrate, asynchronous no oversampling _pUsart->US_BRGR = (SystemCoreClock / dwBaudRate) / 16 ; diff --git a/hardware/arduino/sam/cores/arduino/USARTClass.h b/hardware/arduino/sam/cores/arduino/USARTClass.h index d5d7ff963d5..deb74a71d29 100644 --- a/hardware/arduino/sam/cores/arduino/USARTClass.h +++ b/hardware/arduino/sam/cores/arduino/USARTClass.h @@ -25,37 +25,6 @@ // Includes Atmel CMSIS #include -// Define config for Serial.begin(baud, config); -#define SERIAL_5N1 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_5_BIT | US_MR_PAR_NO | US_MR_NBSTOP_1_BIT | US_MR_CHMODE_NORMAL) -#define SERIAL_6N1 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_6_BIT | US_MR_PAR_NO | US_MR_NBSTOP_1_BIT | US_MR_CHMODE_NORMAL) -#define SERIAL_7N1 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_7_BIT | US_MR_PAR_NO | US_MR_NBSTOP_1_BIT | US_MR_CHMODE_NORMAL) -#define SERIAL_8N1 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_8_BIT | US_MR_PAR_NO | US_MR_NBSTOP_1_BIT | US_MR_CHMODE_NORMAL) - -#define SERIAL_5N2 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_5_BIT | US_MR_PAR_NO | US_MR_NBSTOP_2_BIT | US_MR_CHMODE_NORMAL) -#define SERIAL_6N2 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_6_BIT | US_MR_PAR_NO | US_MR_NBSTOP_2_BIT | US_MR_CHMODE_NORMAL) -#define SERIAL_7N2 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_7_BIT | US_MR_PAR_NO | US_MR_NBSTOP_2_BIT | US_MR_CHMODE_NORMAL) -#define SERIAL_8N2 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_8_BIT | US_MR_PAR_NO | US_MR_NBSTOP_2_BIT | US_MR_CHMODE_NORMAL) - -#define SERIAL_5E1 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_5_BIT | US_MR_PAR_EVEN | US_MR_NBSTOP_1_BIT | US_MR_CHMODE_NORMAL) -#define SERIAL_6E1 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_6_BIT | US_MR_PAR_EVEN | US_MR_NBSTOP_1_BIT | US_MR_CHMODE_NORMAL) -#define SERIAL_7E1 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_7_BIT | US_MR_PAR_EVEN | US_MR_NBSTOP_1_BIT | US_MR_CHMODE_NORMAL) -#define SERIAL_8E1 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_8_BIT | US_MR_PAR_EVEN | US_MR_NBSTOP_1_BIT | US_MR_CHMODE_NORMAL) - -#define SERIAL_5E2 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_5_BIT | US_MR_PAR_EVEN | US_MR_NBSTOP_2_BIT | US_MR_CHMODE_NORMAL) -#define SERIAL_6E2 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_6_BIT | US_MR_PAR_EVEN | US_MR_NBSTOP_2_BIT | US_MR_CHMODE_NORMAL) -#define SERIAL_7E2 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_7_BIT | US_MR_PAR_EVEN | US_MR_NBSTOP_2_BIT | US_MR_CHMODE_NORMAL) -#define SERIAL_8E2 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_8_BIT | US_MR_PAR_EVEN | US_MR_NBSTOP_2_BIT | US_MR_CHMODE_NORMAL) - -#define SERIAL_5O1 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_5_BIT | US_MR_PAR_ODD | US_MR_NBSTOP_1_BIT | US_MR_CHMODE_NORMAL) -#define SERIAL_6O1 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_6_BIT | US_MR_PAR_ODD | US_MR_NBSTOP_1_BIT | US_MR_CHMODE_NORMAL) -#define SERIAL_7O1 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_7_BIT | US_MR_PAR_ODD | US_MR_NBSTOP_1_BIT | US_MR_CHMODE_NORMAL) -#define SERIAL_8O1 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_8_BIT | US_MR_PAR_ODD | US_MR_NBSTOP_1_BIT | US_MR_CHMODE_NORMAL) - -#define SERIAL_5O2 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_5_BIT | US_MR_PAR_ODD | US_MR_NBSTOP_2_BIT | US_MR_CHMODE_NORMAL) -#define SERIAL_6O2 (US_MR_USART_MODE_NORMAL | US_MR_USCLKS_MCK | US_MR_CHRL_6_BIT | US_MR_PAR_ODD | US_MR_NBSTOP_2_BIT | US_MR_CHMODE_NORMAL) -#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 { protected: @@ -70,7 +39,6 @@ class USARTClass : public HardwareSerial USARTClass( Usart* pUsart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer* pRx_buffer ) ; void begin( const uint32_t dwBaudRate ) ; - void begin( const uint32_t dwBaudRate , const uint32_t config ) ; void end( void ) ; int available( void ) ; int peek( void ) ;