diff options
Diffstat (limited to 'libraries/Wire/utility')
-rw-r--r-- | libraries/Wire/utility/twi.c | 63 |
1 files changed, 34 insertions, 29 deletions
diff --git a/libraries/Wire/utility/twi.c b/libraries/Wire/utility/twi.c index 82a25c0..2ad2a71 100644 --- a/libraries/Wire/utility/twi.c +++ b/libraries/Wire/utility/twi.c @@ -87,9 +87,9 @@ void twi_init(void) It is 72 for a 16mhz Wiring board with 100kHz TWI */ // enable twi module, acks, and twi interrupt - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA); + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA); - // allocate buffers + // allocate buffers twi_masterBuffer = (uint8_t*) calloc(TWI_BUFFER_LENGTH, sizeof(uint8_t)); twi_txBuffer = (uint8_t*) calloc(TWI_BUFFER_LENGTH, sizeof(uint8_t)); twi_rxBuffer = (uint8_t*) calloc(TWI_BUFFER_LENGTH, sizeof(uint8_t)); @@ -135,29 +135,34 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length) // initialize buffer iteration vars twi_masterBufferIndex = 0; - twi_masterBufferLength = length; + twi_masterBufferLength = length-1; // This is not intuitive, read on... + // On receive, the previously configured ACK/NACK setting is transmitted in + // response to the received byte before the interrupt is signalled. + // Therefor we must actually set NACK when the _next_ to last byte is + // received, causing that NACK to be sent in response to receiving the last + // expected byte of data. // build sla+w, slave device address + w bit twi_slarw = TW_READ; - twi_slarw |= address << 1; + twi_slarw |= address << 1; // send start condition - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); - // wait for read operation to complete - while(TWI_MRX == twi_state){ - continue; - } + // wait for read operation to complete + while(TWI_MRX == twi_state){ + continue; + } if (twi_masterBufferIndex < length) - length = twi_masterBufferIndex; + length = twi_masterBufferIndex; // copy twi buffer to data for(i = 0; i < length; ++i){ data[i] = twi_masterBuffer[i]; } - return length; + return length; } /* @@ -202,24 +207,24 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait // build sla+w, slave device address + w bit twi_slarw = TW_WRITE; - twi_slarw |= address << 1; + twi_slarw |= address << 1; // send start condition - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); - // wait for write operation to complete - while(wait && (TWI_MTX == twi_state)){ - continue; - } - - 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 + // wait for write operation to complete + while(wait && (TWI_MTX == twi_state)){ + continue; + } + + 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 } /* @@ -285,9 +290,9 @@ void twi_attachSlaveTxEvent( void (*function)(void) ) */ void twi_reply(uint8_t ack) { - // transmit master read ready signal, with or without ack - if(ack){ - TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA); + // transmit master read ready signal, with or without ack + if(ack){ + TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA); }else{ TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT); } |