Bug in twi.c

If I understand you correct, you suggest that the absence of $A0 in the NACK path on figure 21-16 should be taken literally.

Do you have any test/trace to show that this is the case or a reference in the Atmel datasheet text to support this (other sources)?

Also consider the following:

    case TW_SR_DATA_ACK:       // data received, returned ack
    case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack
      // if there is still room in the rx buffer
      if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){
        // put byte in buffer and ack
        twi_rxBuffer[twi_rxBufferIndex++] = TWDR;
        twi_reply(1);
      }else{
        // otherwise nack
        twi_reply(0);
      }
      break;

In the fragment above, the else case will set up for NACK to be returned provided that master actually sends another byte (one byte is already lost in this case even though it has been acknowledged).

Next step would be for master to send another byte (in which case TW_SR_DATA_NACK will be called) or the master may send a stop condition. Have you considered both of these scenarios?