Pages: [1]   Go Down
Author Topic: Bug in Wire library  (Read 348 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Edison Member
*
Karma: 3
Posts: 1001
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The code below is from the "twi.c" Master Receiver routine. When data nack has been sent, no more data should be added to the master buffer. As written it will lead to a buffer overrun error if a master requests 32 bytes.

    case TW_MR_DATA_NACK: // data received, nack sent
      // put final byte into buffer
      twi_masterBuffer[twi_masterBufferIndex++] = TWDR;

Code:
   // Master Receiver
    case TW_MR_DATA_ACK: // data received, ack sent
      // put byte into buffer
      twi_masterBuffer[twi_masterBufferIndex++] = TWDR;
    case TW_MR_SLA_ACK:  // address sent, ack received
      // ack if more bytes are expected, otherwise nack
      if(twi_masterBufferIndex < twi_masterBufferLength){
        twi_reply(1);
      }else{
        twi_reply(0);
      }
      break;
    case TW_MR_DATA_NACK: // data received, nack sent
      // put final byte into buffer
      twi_masterBuffer[twi_masterBufferIndex++] = TWDR;
    case TW_MR_SLA_NACK: // address sent, nack received
      twi_stop();
      break;

Also I suggest a test is added in the data ack section to avoid overruns in case illegit acks are received.

With corrections applied, code should then look as follows:

Code:
   // Master Receiver
    case TW_MR_DATA_ACK: // data received, ack sent
      // put byte into buffer
      if(twi_masterBufferIndex < twi_masterBufferLength){
            twi_masterBuffer[twi_masterBufferIndex++] = TWDR;
        }
    case TW_MR_SLA_ACK:  // address sent, ack received
      // ack if more bytes are expected, otherwise nack
      if(twi_masterBufferIndex < twi_masterBufferLength){
        twi_reply(1);
      }else{
        twi_reply(0);
      }
      break;
    case TW_MR_DATA_NACK: // data received, nack sent
    case TW_MR_SLA_NACK: // address sent, nack received
      twi_stop();
      break;
Logged

Pages: [1]   Go Up
Jump to: