Hi,
I am currently implementing a small I2C slave that shall demonstrate I2C communication to students who implement the master part and communicate with the slave (in loopback mode, but I have currently set it up with external pull ups for debugging). To that end I would like the implementation to behave as nice as possible regarding error detection/propagation, i.e. I want to NACK whenever the master is not behaving as intended whenever possible. My slave implements a typical register-based device, i.e. the master needs to address the slave via I2C and then write a register address before it can eventually read or write to that register of the slave.
It basically works but I would like to return more NACKs than I currently do. However, there are some situations where my slave code stalls the master instead of NACKing and making it abort the transaction, which I don't understand. For example, when I am serving a I2C_SLAVE_ACT_TREQ in a I2C_SLAVE_INT_DATA interrupt I would like to NACK this request instead of returning data (an then NACK which I think works). To that end, I tried to execute I2CSlaveACKValueSet(..., 0) instead of I2CSlaveDataPut(). However, when I do so the transaction (as shown by a logic analyzer) comes to a hold after the addressing byte is sent by the master and an ACK by the slave - mind you, although I tried to NACK. I presume the stall is due to clock stretching by the slave but I am not sure. I wonder if what I try is possible at all with the TM4C1294NCPDT slave at all. Basically, I would like to know at which instants calling I2CSlaveACKValueSet() has an effect because neither the MCU datasheet nor TivaWare documentation go even near that amount of details.