aboutsummaryrefslogtreecommitdiff
path: root/libraries/Wire/utility/twi.c
diff options
context:
space:
mode:
authorDavid A. Mellis <d.mellis@arduino.cc>2008-06-21 23:16:27 +0000
committerDavid A. Mellis <d.mellis@arduino.cc>2008-06-21 23:16:27 +0000
commit79904311bb35ca52b51650f834683606e31882c2 (patch)
tree06c39698c080a079a3967dadacb59467ee76133d /libraries/Wire/utility/twi.c
parent75d1f5053c3460484973d6de1d0d7ec9d9a6516d (diff)
Wire library patch to provide better error handling.
Diffstat (limited to 'libraries/Wire/utility/twi.c')
-rw-r--r--libraries/Wire/utility/twi.c36
1 files changed, 31 insertions, 5 deletions
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;
}