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.

LP-MSPM0G3507: I2C_CMD_RECOVER_BUS not work

Part Number: LP-MSPM0G3507

Tool/software:

Hi,

  SDK: mspm0_sdk_2_02_00_05

  OS: freeRTOS

  using I2C_control to send I2C_CMD_RECOVER_BUS command will return -2 (I2C_STATUS_UNDEFINEDCMD)

  It seems like TI SDK not support this command so far, is there another way to reset I2C bus?

Thanks.

  • Hi,

      As above, one of the I2C devices use the general call address 0x00.

      The scenario is when the device (slave address = 0x00) removed (hot plug), polling I2C to read 0x00 will cause I2C_transfer stuck.

      Why i2c_transfer will stuck on this operation?

      

    Thanks.

  • Hello Roi,

    I will help you on this issue tomorrow morning.

    Best Regards,

    Janz Bai

  • Hi Janz,

      Thanks, if any further information needs to be provided please let me know.

  • Hi, 

    The scenario is when the device (slave address = 0x00) removed (hot plug), polling I2C to read 0x00 will cause I2C_transfer stuck.

    Can you please help me to check where we stuck in I2C_transfer.

    Also, can you help me to observe the I2C hardware line signal via such as logic analyzer?

    I want to see what happened on I2C line (SCL and SDA), and where CPU is stuck.

    Also, provide me the detailed steps that can trigger this issue you have met.

    Regards,

    Helic

  • Hi Helic,

      Vendor just feedback us to read 0x00 is not a standard operation, should use 10bit address to read. Thus, there is no issue for

      general call address 0x00 on I2C bus to cause I2C_transfer stuck.

      But we still want to know how to do I2C BUS recovery (I2C_CMD_RECOVER_BUS) on freeRTOS when I2C_transfer stuck.

      It's because MCU has connected to 5 devices on one I2C BUS, and when we do stress testing (read/write data) on those I2C devices,

      somehow I2C clock pin stay in LOW permanently, and stuck in I2C_transfer as shown in below.

      

      

                if (xSemaphoreTake(I2cMutex, 20 / portTICK_PERIOD_MS) == pdTRUE) {
                    Status = I2C_transferTimeout(I2c, &I2cTransaction, 10 / portTICK_PERIOD_MS);
                    xSemaphoreGive(I2cMutex);
                } else
                    _printf("I2cReadReg busy!\r\n");
    

    Thanks.

  • Hi, 

      somehow I2C clock pin stay in LOW permanently, and stuck in I2C_transfer as shown in below.

    Make sure that M0 cause this clock low.

    how to do I2C BUS recovery (I2C_CMD_RECOVER_BUS) on freeRTOS when I2C_transfer stuck.

    You can reset I2C to try to recover the I2C bus.

    prvSetupHardware() - SYSCFG_DL_init() - SYSCFG_DL_initPower(); (Only I2C is need to reset.)

    And then call I2C_init(); and some other I2C init and config steps (I2C_Params_init) in freertos.

    Regares,

    Helic

  • Hi Helic,

      While I2C clock pin stay in LOW permanently,  following prvSetupHardware() I2C reset flow as show in below I2cBusRecover(),

      I2C clock pin will reset to high --> OK

      Then, read the I2C device again, I2C clock pin stay in LOW again, and stuck at I2C_transferTimeout(). --> FAIL

      seems like I2C_init() did not recover after reset I2C flow?

      

    void I2cBusRecover(void)
    {
        I2C_Params i2cParams;
     
        I2C_close(I2c);
     
        DL_I2C_reset(I2C_INST);
        DL_I2C_enablePower(I2C_INST);
        I2C_init();
     
        /* Create I2C for usage */
        I2C_Params_init(&i2cParams);
        i2cParams.bitRate = I2C_100kHz;
        I2c = I2C_open(CONFIG_I2C_TMP, &i2cParams);
        if (I2c == NULL) {
            LOG("Error Initializing I2C");
        }
        LOG("OK");
    }

    Thanks.

  • Hi, 

      seems like I2C_init() did not recover after reset I2C flow?
      I2C clock pin will reset to high --> OK

    This shows that M0 can reset the state of I2C.

    However, communicating with the slave device again puts M0 I2C into an abnormal state or let SDA and SCL in Low status again.

    Maybe this is cause by I2C slave I think...

    Also, It's better to add the 16 CPU clock delay after [DL_I2C_enablePower(I2C_INST);].

    Regards,

    Helic

  • Hi Helic,

      Not work by adding 16 CPU clock delay.

      I also try to use I2C_setClockTimeout() for recovering, but there returns I2C_STATUS_UNDEFINEDCMD.

      Is this command supported on G3507 platform?

     

    * I2C_setClockTimeout()

    *  The count is used to force a
    *  timeout if an I2C target holds the clock line low for longer than the
    *  @p timeout duration. An #I2C_STATUS_CLOCK_TIMEOUT status indicates a
    *  timeout event occured.

    Thanks.