Search code examples
arduinoi2catmegaslave

I2C Slave Transmitter NACK (aka variable length reply)


Is an I2C slave when transmitting to a master allowed to NACK?

It seems from the spec (2.1) there is no way for a slave to realistically send a NACK to a master while transmitting, i.e. sending data from the slave to the master. I have scoured the net and can't find any help either way here.

Why? I am implementing an I2C master device in AVR Atmega8. I want to cover all use cases. I have a user who has noted that when an I2C slave device sends a NACK when in SLA+R mode, the master ignores it.

As far as I am aware, the master device that has initiated SLA+R is the only party allowed to NACK a packet. The slave must keep sending packets on the master clock. However, a snippet in the Arduino wire library implies that the slave can send NACK to a master. https://github.com/arduino/Arduino/blob/master/libraries/Wire/utility/twi.c#L503

  1. What should happen if the slave wants to send 2 packets but the master clocks for 3
  2. Can the slave send a NACK in slave transmitter mode?
  3. Is there any other way to indicate to the master there is no more data?

Solution

  • You are correct, there is no way for slave to send NACK. I2C is meant to make cheap slave devices, and to put as much/all logic into the master. So, in majority of cases, master should know how long the packet will be. If the data is really variable, you have to create a higher level protocol, and transmit the packet length as part of the header. E.g. DDC transmits packet size in the 3rd byte, and master should use this info.

    1. Implementation dependent and mostly undetermined. Subsequent bytes might be copies of the last valid byte, constant value e.g. FF, or anything else.

    2. No.

    3. As I said earlier, a higher level protocol. E.g. a) Simple, single Size message, max 256 payload: Start - Address - Size - Bytes... - Stop b) Multiple sub packets, unlimited payload: Start - Address - Size - Bytes... - Size - Bytes... - Stop

    Please note, that using any of the higher level protocols requires that logic for determining length of the message is embedded into the masters I2C functions. This means that most commonly provided routines like read(adr, buffer, size), which issue start, read then stop, cannot be used, as they read exactly "size" number of bytes.