From e079baa18daaa21ded7c3ea49fc82bd6f5a0fc5b Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 6 Apr 2014 20:25:31 +0100 Subject: [PATCH] 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 cbf46db90..9ba314f44 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