CC2340R5: How to recover from an I2C error

Part Number: CC2340R5

Tool/software:

Hello. My name is Mori.

I encountered an I2C error and tried the following steps to recover, but communication was not possible at step ⑩.
Resetting the CPU allowed I2C communication to resume.
I thought that I2C_close → I2C_open would be sufficient as a recovery method when an I2C error occurs, but
is there anything else I'm missing?
Thank you for your response.

① I2C_transfer
② I2C error
③ I2C_close
④ GPIO_resetConfig(SCL)
⑤ GPIO_resetConfig(SDA)
⑥ Sleep
⑦ Wakeup
⑧ I2C_open
⑩ I2C_transfer

  • Sorry.
    I forgot to mention that.
    I executed GPIO_setConfig after waking up.
    I2C communication failed in step 11.

    ① I2C_transfer
    ② I2C error
    ③ I2C_close
    ④ GPIO_resetConfig(SCL)
    ⑤ GPIO_resetConfig(SDA)
    ⑥ Sleep
    ⑦ Wakeup
    ⑧ GPIO_setConfig(SCL)
    ⑨ GPIO_setConfig(SDA)
    ⑩ I2C_open
    ⑪ I2C_transfer

  • Hello mori.oq

    I hope you are doing well. I created a similar code to what you provided above (minus the GPIO_reset/setConfig); however, my code did not display the same behavior as what you explained above (*as I2C still worked). 

    #include <ti/drivers/I2C.h>
    // Define name for an index of an I2C bus
    #define SENSORS 0
    // Define the target address of device on the SENSORS bus
    #define OPT_ADDR 0x47
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        uint8_t writeBuffer[3];
        uint8_t readBuffer[3];
        // One-time init of I2C driver
        I2C_init();
        // initialize optional I2C bus parameters
        I2C_Params params;
        I2C_Params_init(&params);
        params.bitRate = I2C_400kHz;
        // Open I2C bus for usage
        I2C_Handle i2cHandle = I2C_open(SENSORS, &params);
        // Initialize target address of transaction
        I2C_Transaction transaction = {0};
        transaction.targetAddress = OPT_ADDR;
        // Read from I2C target device
        transaction.readBuf = readBuffer;
        transaction.readCount = sizeof(readBuffer);
        transaction.writeCount = 0;
        I2C_transfer(i2cHandle, &transaction);
        // Write to I2C target device
        transaction.writeBuf = writeBuffer;
        transaction.writeCount = sizeof(writeBuffer);
        transaction.readCount = 0;
        I2C_transferTimeout(i2cHandle, &transaction, 5000);
        // Close I2C
        I2C_close(i2cHandle);
        sleep(1);
        I2C_open(SENSORS, &params);
        // Read from I2C target device
        transaction.readBuf = readBuffer;
        transaction.readCount = sizeof(readBuffer);
        transaction.writeCount = 0;
        I2C_transfer(i2cHandle, &transaction);
        // Write to I2C target device
        transaction.writeBuf = writeBuffer;
        transaction.writeCount = sizeof(writeBuffer);
        transaction.readCount = 0;
        I2C_transferTimeout(i2cHandle, &transaction, 5000);
        // Close I2C
        I2C_close(i2cHandle);
        return 0;
    }

    Thanks,
    Alex F

  • Thank you for your reply.
    Have you implemented "② I2C error"?

  • Hello Mori.oq,

    Looks like my code did not do the same error in step 2 currently, thanks for pointing that out. Can you read the state of the status of the i2c transaction at step 11? (IE transaction.status = #)

    Also which SDK version is this in.

    Thanks,
    Alex F

  • Thank you for your reply.
    transaction.status is -5 (I2C_STATUS_ADDR_NACK).
    The SDK version is 8.40.00.61.

  • Additional information:
    I placed a metal object on pin 38 (PA5/SCL) of the CC2345R5 to cause an I2C error.
    I removed the metal object immediately after the error occurred.