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.

i2c NACK problem

Other Parts Discussed in Thread: AM4379

Hi,

I'm using Starterware v02.01.00.01 on AM4379, and communicating over i2c using the i2c_utils from the examples.

I have found that NACKs are not handled correctly. In fact I can send bytes to any (non-existant) i2c device address and the I2CUtilsWrite() function will return S_PASS (rather than the expected E_I2C_NAK_ERR).

Looking inside I2cUtilsTransceive() I see the following:

/*transmit byte of data*/
I2CPutTxData(instObj->baseAddr, dataByte);

/*Check for status*/
devStatus = I2CIntrRawStatus(instObj->baseAddr);

/*check nack status*/
if (devStatus & I2C_INTR_NO_ACK)
{
    status = E_I2C_NAK_ERR;
    break;
}

My feeling is that this can't work, as it takes some time for a NACK to be realised, and the code checks for the NACK status right after writing the data register. However an attempt to fix this by inserting the following after the transmit doesn't help:

do
{
devStatus = I2CIntrRawStatus(instObj->baseAddr);
} while (!((I2C_INTR_REG_ACESS_RDY & devStatus) || (I2C_INTR_NO_ACK & devStatus) || (I2C_INTR_TX_READY & devStatus)));

In fact, even if the loop is changed to wait ONLY for a NACK (and when a NACK is clearly seen on the logic analyser) the NACK bit in the status register is not set.

Has anyone else experienced this and found a solution?

Thanks, Kieran.

  • Hi Kieran,

    Will need to dig into this a bit and get back to you.

    Lali
  • Hi Kieran,

    Do you notice the same problem with the NACK bit not being set with the AM437x Processor SDK RTOS I2C example?

    Its located under:

    C:\ti\pdk_am437x_1_0_0\packages\MyExampleProjects\I2C_Test_idkAM437x_armTestProject

    This seems to be handled by I2C_transfer() located under:

    C:\ti\pdk_am437x_1_0_0\packages\ti\drv\i2c\src\I2C_drv.c

    If you are new to Processor SDK, please post back here for assistance in building the example projects in the package.

    Lali

  • Hi Lalindra,

    Thanks for your reply. I will try the Processor SDK I2C example and see if this exhibits the same problem.

    Thanks, Kieran.
  • Hi again,

    I can confirm that the Processor SDK example I2C_Test_idkAM437x_armTestProject does seem to handle the NACK properly. (At least, writing to an invalid i2c address results in an error as expected).

    However, I'm not sure that this code is readily useable in our project, as it depends on the TI-RTOS kernel (it uses TI-RTOS mutexes, runs in a TI-RTOS task, and hooks into the TI-RTOS interrupt handlers.) Our application is based on Starterware and doesn't use TI-RTOS.

    What is the status regarding support for Starterware at the moment? Could we hope for assistance with fixing the Starterware I2C driver, or are we expected to migrate to using TI-RTOS?

    Thanks, Kieran.
  • I since discovered I2C_osal.h, which would suggest that the Processor SDK I2C driver should be able to operate with any RTOS by providing the required semaphore and interrupt hooks. I'll try that, thanks.
  • Just to report back that after implementing the OSAL wrappers HwIP_, Semaphore_ and Utils_ (for FreeRTOS in our case), the Processor SDK I2C driver works great.

    I hadn't realised previously that the drivers are OS agnostic, good to know.

    I did have to make one small changes to the driver, the interrupt priority for the i2c interrupt seems to be hardcoded to 0x20 in I2C_v1.c. This was incompatible with our application, maybe a future release of the driver could have the priority customisable through a passed in parameter?

    Thanks, Kieran.

  • Kieran,

    Glad that you got it working, and thanks for posting an update.
    Appreciate the feedback as well. I will pass on your recommendation to the development team.

    Lali