AM5706: I2C Bus Issue

Part Number: AM5706
Other Parts Discussed in Thread: PCA9306

Dear Team,

We are using AM5706BCBDJA device in our Processor Board. This problem is regarding the I2C bus issue. We are using all 5 I2C buses as masters, connecting them to different slave cards. Each Master has many slaves connected. We are using bare metal software I2c driver given by TI. All I2C except I2C2 and 5 buses we use for reading some house keeping activities which works consistently as they are used rarely.

Whereas, we use I2C5 and I2C2 continuously for LM6586 cross point switching. This LM6586 connects to Processor through PCA9306 level translator (3.3V to 5V). There are 3 devices (LM6586) connected after PCA9306 and 2 I2C expanders (PCA9555PW,118) & one Temp sensor (MAX1668MEE+) before translator.

We are facing I2C issues very frequently with these 2 buses from Processor. Some times write transaction goes through but whereas read transaction does not get initiated from Processor itself. We get F0 from Processor when probed instead of given address. We have 00 or 01 or 02 address but we are not able to understand how F0 is coming out. We do read transaction to confirm whether write went through properly or not. sometimes it is working after we give more I2C timeout time, do bus close and open, but in major problem is there. Even with pull-ups value reduction, severity improves but still problem exist. Now pullup value is 2.35K (2 4.7k's used on each side)

We needed help in understanding this issue. In which scenario F0 comes out of Processor? We are not able to doubt slaves or hardware or pull-ups as Master itself is not sending right data out? Is there anything that we are missing here which slaves or hardware can cause issue? I have given part numbers of all devices on path above.

I2C bus hardware configuration and pin mapping is given below.

 

Regards,

Erfan

  • Hello Abdul,

    Can you please share what SW you are using as stated: 

    We are using bare metal software I2c driver given by TI.

    As well as SDK version and any error logs available?

    Best,

    Josue

  • Dear Josue,

    We are using SDK - 9.3.0.00012 version with Code Composer Studio. Attached I2C driver files files for review.

    ADE_TVCSU_I2C.h

    ADE_TVSCU_ATS_I2C.c
    /*
     * ADE_TVCSU_ARINC_I2C.c
     *
     *  Created on: 06 Nov 2023
     *      Author: Jigyansu.J
     */
    
    #include "Headers/ADE_TVCSU_HEADERS.h"
    
    
    I2C_Params i2cParams;
    I2C_Handle handle = NULL;
    I2C_Transaction i2cTransaction;
    
    
    void ADE_Tvcsu_i2c_init()
    {
    
        /* Initialize parameters */
        I2C_Params_init(&i2cParams);
    
        /* Open I2C instance */
        handle = I2C_open(ADE_I2C_INSTANCE , &i2cParams);
    
    }
    
    int I2C_Hub__Read(int i2c_no , uint16_t hub_address , uint16_t hub_ch_no , uint16_t slave_address,uint16_t slave_offset)
    {
    
        I2C_Params i2cParams;
        I2C_Handle handle = NULL;
        I2C_Transaction i2cTransaction;
    
        i2cParams.bitRate= 0;
    
        bool status;
        char txBuf[8] = {0x0};
        char rxBuf[8] = {0x0};
    
    
        /* Initialize parameters */
        I2C_Params_init(&i2cParams);
    
        /* Open I2C instance */
        handle = I2C_open(i2c_no , &i2cParams);
    
        txBuf[0] = (char)((uint32_t) hub_ch_no);
    
        /* Configure common parameters with I2C transaction */
        i2cTransaction.targetAddress =  hub_address;
        i2cTransaction.writeBuf = (uint8_t *)&txBuf[0];
        i2cTransaction.writeCount = 1;
        i2cTransaction.readBuf = NULL;
        i2cTransaction.readCount = 0;
        i2cTransaction.timeout   = I2C_TRANSACTION_TIMEOUT;
    
        status = I2C_transfer(handle, &i2cTransaction);
        if (status == false)
        {
            I2C_close(handle);
            I2C_log("\nERROR: I2C_transfer failed");
            return -1;
        }
    
        memset(rxBuf,0,8);
    
        txBuf[0] = (char)((uint32_t) slave_offset);
    
        i2cTransaction.targetAddress = slave_address ;
        i2cTransaction.writeBuf = (uint8_t *)&txBuf[0];
        i2cTransaction.writeCount = 1;
        i2cTransaction.readBuf = (uint8_t *)&rxBuf[0];
        i2cTransaction.readCount = 1;
        i2cTransaction.timeout   = I2C_TRANSACTION_TIMEOUT;
        status = I2C_transfer(handle, &i2cTransaction);
        if (status == false)
        {
            I2C_close(handle);
            I2C_log("\nERROR: I2C_transfer failed");
            return -1;
        }
        else
        {
            for(int k = 0 ; k < 1 ; k++)
            {
    //            I2C_log("0x%x ",rxBuf[k]);
            }
        }
        I2C_close(handle);
        return rxBuf[0];
    }
    
    
    int I2C_Hub_Write(int i2c_no , uint16_t hub_address , uint16_t hub_ch_no , uint16_t slave_address,uint16_t slave_offset,uint16_t data)
    {
        I2C_Params i2cParams;
        I2C_Handle handle = NULL;
        I2C_Transaction i2cTransaction;
    
        i2cParams.bitRate= 0;
    
        bool status;
        char txBuf[8] = {0x0};
        char rxBuf[8] = {0x0};
    
        /* Initialize parameters */
        I2C_Params_init(&i2cParams);
    
        /* Open I2C instance */
        handle = I2C_open(i2c_no , &i2cParams);
    
        txBuf[0] = (char)((uint32_t) hub_ch_no);
    
        /* Configure common parameters with I2C transaction */
        i2cTransaction.targetAddress = hub_address;
        i2cTransaction.writeBuf = (uint8_t *)&txBuf[0];
        i2cTransaction.writeCount = 1;
    
        i2cTransaction.readBuf      = NULL;
        i2cTransaction.readCount    = 0;
        i2cTransaction.timeout      = I2C_TRANSACTION_TIMEOUT;
    
        status = I2C_transfer(handle, &i2cTransaction);
        if (status == false)
        {
            I2C_close(handle);
            I2C_log("\nERROR: I2C_transfer failed in HUB configuration\r\n");
            return -1;
        }
        memset(rxBuf,0,8);
    
        /* Get board version */
        txBuf[0] = (char)((uint32_t) slave_offset);
        txBuf[1] = (char)((uint32_t) data);
    
        i2cTransaction.targetAddress = slave_address;
        i2cTransaction.writeBuf = (uint8_t *)&txBuf[0];
        i2cTransaction.writeCount = 2;
        i2cTransaction.readBuf = NULL;
        i2cTransaction.readCount = 0;
        i2cTransaction.timeout   = I2C_TRANSACTION_TIMEOUT;
        status = I2C_transfer(handle, &i2cTransaction);
    
      //  for(int i=0;i<9999999;i++);
    
        if (status == false)
        {
            I2C_close(handle);
            I2C_log("\nERROR: I2C_transfer failed in slave write\r\n");
            return -1;
        }
        else
        {
            I2C_log("#");
        }
        I2C_close(handle);
        return 0;
    }
    
    
    int I2C_Write(int i2c_no , uint16_t slave_address,uint16_t slave_offset,uint16_t data)
    {
        I2C_Params i2cParams;
        I2C_Handle handle = NULL;
        I2C_Transaction i2cTransaction;
    
        i2cParams.bitRate= 0;
    
        bool status;
        char txBuf[8] = {0x0};
        char rxBuf[8] = {0x0};
    
        /* Initialize parameters */
        I2C_Params_init(&i2cParams);
    
        /* Open I2C instance */
        handle = I2C_open(i2c_no , &i2cParams);
    
        txBuf[0] = (char)((uint32_t) slave_offset);
        txBuf[1] = (char)((uint32_t) data);
    
        /* Configure common parameters with I2C transaction */
        i2cTransaction.targetAddress = slave_address;
        i2cTransaction.writeBuf = (uint8_t *)&txBuf[0];
        i2cTransaction.writeCount = 2;          //1
        i2cTransaction.readBuf = NULL;
        i2cTransaction.readCount = 0;
        i2cTransaction.timeout   = I2C_TRANSACTION_TIMEOUT;
    
        status = I2C_transfer(handle, &i2cTransaction);
      //  for(int i=0;i<9999999;i++);
        if (status == false)
        {
            I2C_close(handle);
            I2C_log("\nERROR: I2C_transfer failed");
            return -1;
        }
        memset(rxBuf,0,8);
    
        I2C_log("#");
    
        I2C_close(handle);
        return 0;
    }
    
    int I2C__Read(int i2c_no , uint16_t slave_address,uint16_t slave_offset)
    {
    
        I2C_Params i2cParams;
        I2C_Handle handle = NULL;
        I2C_Transaction i2cTransaction;
    
        i2cParams.bitRate= 0;
    
        bool status;
        char txBuf[8] = {0x0};
        char rxBuf[8] = {0x0};
    
        /* Initialize parameters */
        I2C_Params_init(&i2cParams);
    
        /* Open I2C instance */
        handle = I2C_open(i2c_no , &i2cParams);
    
        txBuf[0] = (char)((uint32_t) slave_offset);
    
        /* Configure common parameters with I2C transaction */
        i2cTransaction.targetAddress =  slave_address;
        i2cTransaction.writeBuf = (uint8_t *)&txBuf[0];
        i2cTransaction.writeCount = 1;
        i2cTransaction.readBuf = (uint8_t *)&rxBuf[0];;
        i2cTransaction.readCount = 1;
        i2cTransaction.timeout   = I2C_TRANSACTION_TIMEOUT;
    
        status = I2C_transfer(handle, &i2cTransaction);
        if (status == false)
        {
            I2C_close(handle);
            I2C_log("\nERROR: I2C_transfer failed");
            return -1;
        }
    #if 1
        for(int k = 0 ; k < 1 ; k++)  //(i2cTransaction.readCount)
        {
            //        I2C_log("0x%x ",rxBuf[k]);
        }
    #endif
        I2C_close(handle);
        return rxBuf[0];
    }
    
    
    

  • processor_sdk_rtos_am57xx_08_01_00_09 is used

  • Hi Request you to provide update

  • Hi,

    Apology for delay in response on this.

    Can you please help with the following details:

    1) Does write always work fine?

    Some times write transaction goes through but whereas read transaction does not get initiated from Processor itself. We get F0 from Processor when probed instead of given address. We have 00 or 01 or 02 address but we are not able to understand how F0 is coming out

    What is the rate of failure in this case and are you recovering from the failure? Do you have to restart the system or does it recover by itself?

    Would it be possible for you to share the waveform in both working and non working cases?

    Also, do you see this issue with PCA9306 itself always or this issue is with other slave as well

    Regards,
    Parth

  • Dear Parth,

    we did little more debug and below are our observations.

    1. What is the rate of failure in this case and are you recovering from the failure? Do you have to restart the system or does it recover by itself?

    As we are closing the I2C handler during problem and opening. Problem gets hidden but it takes more time for transaction. 

    2. Would it be possible for you to share the waveform in both working and non working cases?

    Correct waveform comes out when transaction goes through but during failure scenario, nothing comes out sometimes or wrong address comes out for read/write. No issues with voltage levels during failure and no failure.

    3. We see issues without PCA9306 also with other slaves like I2C expanders

    4. We tried reading the I2C data & address registers during the failure and see that registers itself were not getting updated sometimes with the right value and sometimes those data register (0x4807 C09C) value is 0x02 or 0x82 which is not correct value.

  • Hi,

    . We tried reading the I2C data & address registers during the failure and see that registers itself were not getting updated sometimes with the right value and sometimes those data register (0x4807 C09C) value is 0x02 or 0x82 which is not correct value.

    Could you please share your block diagram?

    Regards,

    Karthik