From 79904311bb35ca52b51650f834683606e31882c2 Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Sat, 21 Jun 2008 23:16:27 +0000 Subject: Wire library patch to provide better error handling. --- libraries/Wire/Wire.cpp | 17 ++++++++++------- libraries/Wire/Wire.h | 6 +++--- libraries/Wire/utility/twi.c | 36 +++++++++++++++++++++++++++++++----- libraries/Wire/utility/twi.h | 12 ++++++------ 4 files changed, 50 insertions(+), 21 deletions(-) (limited to 'libraries') diff --git a/libraries/Wire/Wire.cpp b/libraries/Wire/Wire.cpp index 73369b3..0ee3012 100755 --- a/libraries/Wire/Wire.cpp +++ b/libraries/Wire/Wire.cpp @@ -77,22 +77,24 @@ void TwoWire::begin(int address) begin((uint8_t)address); } -void TwoWire::requestFrom(uint8_t address, uint8_t quantity) +uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity) { // clamp to buffer length if(quantity > BUFFER_LENGTH){ quantity = BUFFER_LENGTH; } // perform blocking read into buffer - twi_readFrom(address, rxBuffer, quantity); + uint8_t read = twi_readFrom(address, rxBuffer, quantity); // set rx buffer iterator vars rxBufferIndex = 0; - rxBufferLength = quantity; + rxBufferLength = read; + + return read; } -void TwoWire::requestFrom(int address, int quantity) +uint8_t TwoWire::requestFrom(int address, int quantity) { - requestFrom((uint8_t)address, (uint8_t)quantity); + return requestFrom((uint8_t)address, (uint8_t)quantity); } void TwoWire::beginTransmission(uint8_t address) @@ -111,15 +113,16 @@ void TwoWire::beginTransmission(int address) beginTransmission((uint8_t)address); } -void TwoWire::endTransmission(void) +uint8_t TwoWire::endTransmission(void) { // transmit buffer (blocking) - twi_writeTo(txAddress, txBuffer, txBufferLength, 1); + int8_t ret = twi_writeTo(txAddress, txBuffer, txBufferLength, 1); // reset tx buffer iterator vars txBufferIndex = 0; txBufferLength = 0; // indicate that we are done transmitting transmitting = 0; + return ret; } // must be called in: diff --git a/libraries/Wire/Wire.h b/libraries/Wire/Wire.h index 9c91b9b..9e849d5 100755 --- a/libraries/Wire/Wire.h +++ b/libraries/Wire/Wire.h @@ -48,9 +48,9 @@ class TwoWire void begin(int); void beginTransmission(uint8_t); void beginTransmission(int); - void endTransmission(void); - void requestFrom(uint8_t, uint8_t); - void requestFrom(int, int); + uint8_t endTransmission(void); + uint8_t requestFrom(uint8_t, uint8_t); + uint8_t requestFrom(int, int); void send(uint8_t); void send(uint8_t*, uint8_t); void send(int); diff --git a/libraries/Wire/utility/twi.c b/libraries/Wire/utility/twi.c index 563b41b..3e5489f 100644 --- a/libraries/Wire/utility/twi.c +++ b/libraries/Wire/utility/twi.c @@ -51,6 +51,8 @@ static volatile uint8_t twi_txBufferLength; static uint8_t* twi_rxBuffer; static volatile uint8_t twi_rxBufferIndex; +static volatile uint8_t twi_error; + /* * Function twi_init * Desc readys twi pins and sets twi bitrate @@ -112,7 +114,7 @@ void twi_setAddress(uint8_t address) * Input address: 7bit i2c device address * data: pointer to byte array * length: number of bytes to read into array - * Output byte: 0 ok, 1 length too long for buffer + * Output number of bytes read */ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length) { @@ -120,7 +122,7 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length) // ensure data will fit into buffer if(TWI_BUFFER_LENGTH < length){ - return 1; + return 0; } // wait until twi is ready, become master receiver @@ -128,6 +130,8 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length) continue; } twi_state = TWI_MRX; + // reset error state (0xFF.. no error occured) + twi_error = 0xFF; // initialize buffer iteration vars twi_masterBufferIndex = 0; @@ -145,12 +149,15 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length) continue; } + if (twi_masterBufferIndex < length) + length = twi_masterBufferIndex; + // copy twi buffer to data for(i = 0; i < length; ++i){ data[i] = twi_masterBuffer[i]; } - return 0; + return length; } /* @@ -161,7 +168,11 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length) * data: pointer to byte array * length: number of bytes in array * wait: boolean indicating to wait for write or not - * Output byte: 0 ok, 1 length too long for buffer + * Output 0 .. success + * 1 .. length to long for buffer + * 2 .. address send, NACK received + * 3 .. data send, NACK received + * 4 .. other twi error (lost bus arbitration, bus error, ..) */ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait) { @@ -177,6 +188,8 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait continue; } twi_state = TWI_MTX; + // reset error state (0xFF.. no error occured) + twi_error = 0xFF; // initialize buffer iteration vars twi_masterBufferIndex = 0; @@ -199,7 +212,14 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait continue; } - return 0; + if (twi_error == 0xFF) + return 0; // success + else if (twi_error == TW_MT_SLA_NACK) + return 2; // error: address send, nack received + else if (twi_error == TW_MT_DATA_NACK) + return 3; // error: data send, nack received + else + return 4; // other twi error } /* @@ -333,10 +353,15 @@ SIGNAL(SIG_2WIRE_SERIAL) } break; case TW_MT_SLA_NACK: // address sent, nack received + twi_error = TW_MT_SLA_NACK; + twi_stop(); + break; case TW_MT_DATA_NACK: // data sent, nack received + twi_error = TW_MT_DATA_NACK; twi_stop(); break; case TW_MT_ARB_LOST: // lost bus arbitration + twi_error = TW_MT_ARB_LOST; twi_releaseBus(); break; @@ -441,6 +466,7 @@ SIGNAL(SIG_2WIRE_SERIAL) case TW_NO_INFO: // no state information break; case TW_BUS_ERROR: // bus error, illegal stop/start + twi_error = TW_BUS_ERROR; twi_stop(); break; } diff --git a/libraries/Wire/utility/twi.h b/libraries/Wire/utility/twi.h index 7ccbf5c..1258d8d 100755 --- a/libraries/Wire/utility/twi.h +++ b/libraries/Wire/utility/twi.h @@ -17,18 +17,18 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef twi_h -#define twi_h +#ifndef twi_h +#define twi_h #include //#define ATMEGA8 - #ifndef CPU_FREQ + #ifndef CPU_FREQ #define CPU_FREQ 16000000L #endif - #ifndef TWI_FREQ + #ifndef TWI_FREQ #define TWI_FREQ 100000L #endif @@ -51,7 +51,7 @@ void twi_attachSlaveTxEvent( void (*)(void) ); void twi_reply(uint8_t); void twi_stop(void); - void twi_releaseBus(void); - + void twi_releaseBus(void); + #endif -- cgit v1.2.3-18-g5258