Go Down

Topic: Bug in Wire library (Read 374 times) previous topic - next topic

BenF

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: [Select]
   // 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: [Select]
   // 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;

Go Up