This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

RM48 I2C Response to Slave address NACK

Hi,

We had what we thought was a stable I2C driver subsystem until we encountered an issue today during testing.


Our driver roughly follows:

  1. Setup for the transaction (data length, slave addx, etc)
  2. Set the start condition on the bus
  3. Wait for the TX buffer to be empty (It already should be)
  4. Send the slave address
  5. Wait for Tx buffer empty (it should go empty after sending slave addx)
  6. Check ACK/NACK status
  7. Go on and send any other data ...
  8. Set stop condition and cleanup

We intentionally addressed an I2C slave with the wrong address, and found that after sending the slave address and watching the slave NACK (Technically not ACK) we find that TXRDY in the status register is 0 (still contains data). On the bus analyzer we see our false address, and a NACK but, but the RM4 does not bring the SCL line high.

Page 1308 of SPNU503B, TXDRY bit states that the bit is set to 1 (empty) when data has been copied from DXR register to shift register.

Is there some issue that would prevent the TXRDY bit from becoming 1 (empty) if there is a NACK on the bus during slave addressing phase?

Thanks

Stomp!

  • Hello,

    You do need to configure the I2C module on the RM48x so that it can ignore any NACK while in master-transmitter mode. The I2C module can be placed in the ignore NACK mode by setting the IGNACK bit in the I2CEMDR register. This mode allows an I2C module that is configured as a master transmitter to ignore a NACK from a slave device that is not capable of generating a proper ACK signal.

    Regards,
    Sunil
  • Hi,
    Thanks for the response.
    We already have an option for ignoring the NACK, this works.

    Our problem is: For example if the slave device was damaged or faulty our system must be able to gracefully recover.

    Currently can you please advise why the TXRDY bit would not be set to 1 if the slave addressing phase does not ACK.

    Thanks
    Stomp!
  • Hi Stomp,

    I suggest you to review the I2C code I posted here: 

    The i2cMasterWriteSync function is able to deal with not responding slaves (NACK). If I remember right, the key to deal with this are the following lines of code:

                if ((i2c->STR & I2C_NACK) == I2C_NACK)
                {
                    /* NACK detected during transmision
                     *
                     * According to I2C Spec the reason could be:
                     * 1. No receiver is present on the bus with the transmitted address so there is no device to respond with an acknowledge.
                     * 2. The receiver is unable to receive or transmit because it is performing some real-time function and is not ready to start communication with the master.
                     * 3. During the transfer, the receiver gets data or commands that it does not understand.
                     * 4. During the transfer, the receiver cannot receive any more data bytes.
                     */
    
                    i2c->MDR |= I2C_STOP_COND; /* Send stop condition so SCL isn't held low */
    
                    /* Wait for Busy Bit to go Low --> The bus is free and stop was send */
                    while((i2c->STR & I2C_BUSBUSY) == I2C_BUSBUSY);
    
                    i2c->STR = I2C_SCD | I2C_TX | I2C_NACK; /* Clear SCD, NACK and set TXRDY flag to indicate that a new transfer is possible. */
    
                    g_Struct.eMode = I2C_IDLE;
    
                    return 4ul;
                }

    Best Regards,
    Christian

  • Hi Christian,

    Sorry for the delay in responding.

    We still have the situation where the above code does not work during slave addressing. In that the i2c->STR I2C_NACK flag (bit 1) is never set by the I2C hardware if the slave addressing failed.

    On table 27-2, bit 1 we have:
    "This bit is NOT set by no-ack after Start Byte"

    I think this means the I2C module has no way of determining if the slave addressing was an ACK or NACK.

    Can you confirm that what we are seeing is correct?

    Thanks
    Stomp!.
  • Hi Stomp,

    I'm not a hundred percent sure what you mean with "addressed an I2C slave with the wrong address".
    For me this is equal to addressing a not connected slave, or using an address which isn't used in the I2C network.

    When I do this with my code I see the following signals on the bus:

    You can see, I try to write to an slave (address 0x10) which doesn't respond (NACK), RM46 sends a stop condition and the bus goes to idle.

    My code catches the situation of a not responding slave.

    However, you are right with that the NACK doesn't get set after the start byte ("This bit is NOT set by no-acknowledgement after Start byte.").
    Instead it gets set after trying to send the first data byte, but you can see the data byte is never placed on the bus.

    So for me the code I posted in the other thread works under this condition.

    The program sequence should look like:

    • Setup to write

    • Trigger Start condition
      • Start and Address are on the bus
    • Wait for TX or ARDY

    • Write first data byte into DXR
    • Wait for TX or ARDY

    • Check for NACK
      • If NACK than send stop, clear flags and exit
      • if ACK than first data byte was on the bus

    • Write second data byte into DXR
    • Wait for TX or ARDY

    • Check for NACK
      • If NACK than send stop, clear flags and exit
      • if ACK than second data byte was on the bus
    • ...

    However, checking for a NACK after the start bit and address, as I did in my code, shouldn't hurt.

    Best Regards,
    Christian

  • Hi Christian,
    Thanks for your very detailed answer.
    We have modified our driver not to look for an ACK/NACK after the slave addressing phase and wait until after the first byte of data is sent to check to see if a slave is responding.

    Cheers
    Stomp!