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.

RTOS/CC2652R: Error when using IOID_0 as I2C data line

Part Number: CC2652R
Other Parts Discussed in Thread: LAUNCHXL-CC26X2R1

Tool/software: TI-RTOS

Hi I was using I2C with TIRTOS on my launchpad and everything was fine. I could read and write with it. For that I had the default I2C maping which is IOID_4 for clock and IOID_5 for data.

However, for my board, I mapped IOID_0 as data and IOID_3 as clock. Everything else is the same in the code but with this configuration, I can only open the I2C once and if I close it next time I open it when I use I2C_transfer() it returns false indicating an error.

If I swap IOID_0  and IOID_3 it -> IOID_0  as clock and IOID_3 as data I get no error, everything works fine.

Any thoughts on how to fix this?

Here is the code. I call Init once and every time I want to write or read something I call i2c_comm

void i2c_init(void)
{
    /* Call driver init function */
    I2C_init();
    /* Create I2C for usage */
    I2C_Params_init(&i2cParams);
}

// Param: 1 - Buffer to be sent, 2 - Buffer to store data collected, 3 - number of bytes to be sent 4 - number of bytes to be received, 5 - i2c slave address.

bool i2c_comm(uint8_t *tx_buffer, uint8_t *rx_buffer, size_t tx_count, size_t rx_count, uint8_t i2c_address)
{
    i2c = I2C_open(Board_I2C, &i2cParams);
    if (i2c == NULL)
    {
        status = I2C_ERROR;
    }

    i2cParams.bitRate = I2C_400kHz;
    i2cTransaction.slaveAddress = i2c_address;
    i2cTransaction.writeBuf = tx_buffer;
    i2cTransaction.writeCount = tx_count;
    i2cTransaction.readBuf = rx_buffer;
    i2cTransaction.readCount = rx_count;

    if (I2C_transfer(i2c, &i2cTransaction))
    {
        status = I2C_OK;
    }
    else
    {
        status = I2C_ERROR;
    }
    I2C_close(i2c);
    return status;
}

  • Hi Lucas,

    Which example are you basing your findings from?  Are you using the LAUNCHXL-CC26X2R1 or a custom PCB?  Have you disconnected the TXD jumper since it is connected to DIO3?  Any oscilloscope or logic analyzer screenshots of the I2C communication lines?

    Regards,
    Ryan

  • Hi Ryan,

    My project was based on the this exemple:
    ti\simplelink_cc26x2_sdk_2_10_00_44\examples\rtos\CC26X2R1_LAUNCHXL\thread\temp_sensor

    I am using both a launchpad and a custom PCB. In both cases I have the same problem.
    Right now I am debuging TI`s i2c driver and what I found is that whenever I use IOID_0 as data and after I have opened and closed the peripheral once, next time I try to read or write data, this function: I2CMasterBusBusy(hwAttrs->baseAddr)
    returns me that the bus is busy. However I from the osciloscope I can see that the data pin is on high and therefore it could not be busy.
  • I have disconected the jumper from TXD.
    On the osciloscope in the first time the peripherral is opned and data ins tranmitted a normal transmission is seen. However for the second time the peripheral is opened, no activity is seen on the osciloscope. Both clock and data lines stay on 3.3v
  • One more thing, when debugging TI`s I2C driver I was able to see that the MSTAT register actually is showing that the bus is busy, even though there is only one device in the bus, the data line in the scope is high and this only happens when IOID_0 is used as data, if I use another pin that does not happen.

  • Can you share your CC26X2R1_LAUNCHXL.c/.h files, the external pullup resistances used, and the I2C device you are communicating with?

    Thanks,
    Ryan
  • Hi Ryan,

    I sent the requested information to chris.lande@ti.com
    He is suppose to redirect them to you.
  • Your board files have been analyzed and everything looks good.

    Has this issue been resolved?
  • Hi AB,

    No. It does not work if I use IOID_0 as data line. However if I use it as clock line it works.
    (I clicked on this resolved my issue by mistake)
  • Hi Lucas,

    This is a known issue with the I2C driver from SDK version 2.1 and earlier. This should have been resolved in the never versions.

    In short what is happening is that when you call I2C_close, the IOs are released and returned to their "default" configuration as defined in the "BoardGpioInitTable" table. In your version of the driver, the IOs are released before the I2C Master module is disabled. The consequence of this is that if the SDA pin is released to a state that is not "I2C Idle", the I2C hardware could detect a faulty START condition and get stuck in busy state.

    This is most likely why you see it working with IO3 and not IO0, as IO3 in our default board files (assuming you have not changed this) is defaulting to be a pin with a configured as a HIGH output pin (it is commonly used as the UART TX pin). IO0 however do not have a defined "default" configuration and thus it can return to floating/low when the driver releases it (which would look like a START condition).

    Unfortunately, there is not way to reset the I2C module during open, which means this busy state can not be cleared if set during I2C_close. The module would have to be power-cycled in order to get reset properly.
  • Hi M-W,

    According to what you`ve explained, if I set the DIO0 to HIGH output on the BoardGpioInitTable should fix the problem right? That however did not work for me.
    I had to substitute my current drivers lib by the one in the newest SDK to fix the problem.
    Is there a way of fixing it without having to use the newest SDK`s driver?
  • Hi Lucas,

    Yes, you would have to set it to be a HIGH output, note that this is not a 100% solution to the problem. The best is to do what you did and use the latest version instead as this re-orders the PIN_close and I2C Master disable calls in the I2C driver to mitigate the issue, this is a less glitch sensitive solution.

    If you do not want to move to the latest SDK, I would suggest you simply migrate the I2C driver patches to your SDK. You should be able to copy the I2CCC26XX.c file from the new SDK over to the old and then add it directly to your project. When you have the source in your CCS project, it will override the driverlib version.