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/utility/twi.c | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) (limited to 'libraries/Wire/utility/twi.c') 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; } -- cgit v1.2.3-18-g5258