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.

TM4C1294NCPDT: Odd I2C Error Occurring

Part Number: TM4C1294NCPDT

I have Tiva firmware that is periodically (every ~200ms) reading a few different devices on a single I2C Bus.  We often see the SCL and SDA lines on the bus remain high despite the fact that the Tiva firmware continues executing the code that does the I2C reads.  A scope screenshot is shown below of when the SCL and SDA transition from working fine to staying high indefinitely.

What's odd about this is that the I2C peripheral is configured as open drain, we're using pullup resistors on the SCL and SDA lines yet we never see either of the lines go low despite, as mentioned, that the firmware continues doing the periodic I2C reads calling TivaWare functions like I2CMasterSlaveAddrSet, I2CMasterDataPut, I2CMasterSlaveAddrSet, I2CMasterControl and I2CMasterDataGet.

After we see the SCL and SDA remain high indefinitely, I've examined the I2C channel's I2CMCS register (see second image below) and see some very conflicting states.  For example, the bus is both busy and idle at the same time.

Additionally, we've added the ability to trigger some "reset logic" on demand.  This reset logic will disable the I2C peripheral, change the SDA and SCL pins to GPIO and attempt to reset the I2C bus according to Analog Devices AN-686 application note (basically a bit bang reset to free the bus) and then switch back to I2C.  This works, but usually just a second or two later it will return to the previous state where both SCL and SDA lines remain high indefinitely.

Any thoughts anyone might have on this issue would be appreciated.

  • We often see the SCL and SDA lines on the bus remain high despite the fact that the Tiva firmware continues executing the code that does the I2C reads.  A scope screenshot is shown below of when the SCL and SDA transition from working fine to staying high indefinitely.

    Hi Terence,

      Just to make sure we are on the same page, can you answer a few questions?

      - What speed are you running the I2C at? 100k or higher like 400k?

      - If you currently run at higher speed, does it make a difference running at 100k?

      - On which I2C device do you see the bus stuck? Is it always after accessing a specific slave or it is random?

      - If the bus is always stuck after reading a specific slave then can you take that slave out for a moment. Can you repeat the same issue again on other devices and vice versa?

      - Can you repeat the same issue on another of your custom board?

      - Can you repeat the same issue on a LaunchPad?

      - If you examine closely on the scope, do you see any glitch on the clock?

    What's odd about this is that the I2C peripheral is configured as open drain, we're using pullup resistors on the SCL and SDA lines yet we never see either of the lines go low despite, as mentioned, that the firmware continues doing the periodic I2C reads calling TivaWare functions like I2CMasterSlaveAddrSet, I2CMasterDataPut, I2CMasterSlaveAddrSet, I2CMasterControl and I2CMasterDataGet.

      - I want to make sure you use the GPIOPinTypeI2CSCL() and GPIOPinTypeI2C() for the SCL and SDA  pins and not something of your own. Below is an example. 

    MAP_GPIOPinTypeI2CSCL(GPIO_PORTD_BASE, GPIO_PIN_0);
    MAP_GPIOPinTypeI2C(GPIO_PORTD_BASE, GPIO_PIN_1);

      - What is the pullup resistor value you use?

    Additionally, we've added the ability to trigger some "reset logic" on demand.  This reset logic will disable the I2C peripheral, change the SDA and SCL pins to GPIO and attempt to reset the I2C bus according to Analog Devices AN-686 application note (basically a bit bang reset to free the bus) and then switch back to I2C.  This works, but usually just a second or two later it will return to the previous state where both SCL and SDA lines remain high indefinitely.

    Bit-bang the bus to restore/resynchronize both the master and slaves is the only way I'm aware to be reliable. Once the master and slaves lost synchronization, just resetting the I2C master is not enough because the slave does not know the master is reset and it is still in a state waiting for the next clock to arrive. The only way is to bit-bang the bus to force both sides into the same state without doing a cold power cycle. 

  • Hi Charles, thanks for the response.  I regret to inform you that it seems this was a hardware issue.  Our electrical engineering team looked into this with greater detail and apparently found issues with some cable shielding.  Fixing this has resolved the I2C communication issues.

    I really appreciate your thorough and timely response.  Apologies for the false alarm.

  • Hi Terence,

      Glad your problem is resolved.