LP-MSPM0G3507: DriverLib - I2C Peripheral Error Handling

Part Number: LP-MSPM0G3507
Other Parts Discussed in Thread: MSPM0G3507

Tool/software:

Hello,

I am trying to familiarize myself with the I2C peripheral within DriverLib. I am using the following example program to help me out: i2c_controller_rw_multibyte_fifo_poll_LP_MSPM0G3507_nortos_gcc

The example seems straight forward and not too complex to understand, but there were some questions that I had regarding the behavior of the code when a failure is present.

When I was testing the code, I forgot to set the correct I2C slave address for the device I am interfacing with. Because of this, I noticed the software got stuck in the for loop which waits for the RX FIFO to fill with the data expected from the slave node (see picture below).

This is problematic for my use case as this is technically now an infinite loop and will starve the rest of the program - not good. It seems like this can be mitigated by checking the ACK status of the target slave device before moving forward with reading the data.

With that being said, 

  • Is there a way to check if the sensor NACKs during the write part of the read transaction? This way you can safely prevent the software from trying to read from something that is not there. I looked through the DriverLib documentation and did not find anything.
  • The DriverLib doesn't seem to provide any feedback regarding the status of each transaction. Are there any functions that can be called to get this information?

Another thing, the example program uses this while loop to ensure the I2C peripheral is not busy before moving onto the next step. In what situations can the software get stuck here and what are the solutions to this. 

And finally, when reading from a sensor, is there a certain delay that should happen between the write and read transaction?

Thank you for your help! It is greatly appreciated.

  • Hi Adan,

    This is problematic for my use case as this is technically now an infinite loop and will starve the rest of the program - not good.

    This is because this demo is used with a fixed data length, so that before the "for" loop end, there should always has the data in the RXFIFO, otherwise there represent the transmission (read) is not finish.

    Normally, to avoid this we need to use the the interrupt example project, maybe you can refer to it.

    Another thing, the example program uses this while loop to ensure the I2C peripheral is not busy before moving onto the next step. In what situations can the software get stuck here and what are the solutions to this. 

    Please check the I2C bus status, sometimes the I2C bus is stuck (SCL forced low by slave) will make the I2C keep in BUSY status.

    B.R.

    Sal

  • Sal,

    Sorry for the late reply.

    Normally, to avoid this we need to use the the interrupt example project, maybe you can refer to it.

    So you're saying the only way to get feedback from the I2C bus is through the use of interrupts? There is no other way?

    Please check the I2C bus status, sometimes the I2C bus is stuck (SCL forced low by slave) will make the I2C keep in BUSY status.

    In this situation, would a should there be a timeout within the while loop?

    Adan

  • The Examples are made (deliberately) simple, in the interest of showing the most important steps.

    For this example, I suggest you add something resembling this to the loops (both Rx and Tx):

        if ((DL_I2C_getControllerStatus(I2C_INST) & DL_I2C_CONTROLLER_STATUS_ERROR))
           break;  // We won't progress any further

    The ERR bit in almost every case means NACK. In all cases it means your transaction has ended.

    In the Tx+ERR case you should probably clear the TX FIFO.

    [Edit: Minor clarification]

  • Hi Adan,

    So you're saying the only way to get feedback from the I2C bus is through the use of interrupts? There is no other way?

    Interrupt is a convenient way as it can break the while loop easily and do not need poll the status to check. Use polling method to check its bus stauts also works.

    As recommended by Bruce, the ERROR bit can be used to check the NACK condition (slave address NACK or TX data NACK). the BUSY bit can be used to check bus status. 

    In this situation, would a should there be a timeout within the while loop?

    You can use below function to detect if there has an SCL timeout:

    Or, use a generic timer and read the SCL/SDA time if it keep LOW for a certain time, trigger a timeout. We support read SDA/SCL status by I2C register.

    B.R.

    Sal