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: I2C recover from busy status

Part Number: TM4C1294NCPDT

Hello e2e,

Here our customer is using TM4C1294 as I2C master in product, they found an issue about i2c recover from busy status, the issue detail is below.

TM4C1294 I2C master communicate with a MCU I2C slave device, sometimes the MCU slave data is not ready, the I2C bus goes busy, TM4C1294 use I2CMasterBusBusy API checks the status and reply with busy, in this condition, the SCL is low, TM4C1294 Reg I2CMCS and I2CMBMON show the bus is busy, later the slave MCU data is ready, but TM4C1294 is still in busy status, later TM4C1294 send STOP command with I2C_MASTER_CMD_BURST_SEND_ERROR_STOP, but TM4C1294 I2CMasterBusBusy still shows the bus is busy.

in order to repeat the issue easily, customer tried to set a break point in slave MCU i2c interrupt, once TM4C1294 I2C send command to slave, the slave MCU will halt in I2C interrupt, and I2C bus goes busy, SCL will be low, then repeat the process yellow background marked above, the bus can not recover, in this condition, customer continue run slave mcu and remove the i2c interrupt break point, but the i2c bus still can not be recovered.

the only way to recover i2c bus is that customer have to re-initialized TM4C1294 I2C module so far, customer want to know that what should they do in this condition to recover the I2C bus without re-initialized TM4C1294 I2C module.

thanks in advance.

YAN

  • Hi Yan,

      How long did the slave hold the SCL low? When you said the master is stuck in the busy status, does it matter how long the duration the SCL is held low? In another word, if the SCL is held low for a short period of time, will the master continue and not stuck in the busy? 

      Did you try the CLTO (Clock Low Timout)? I will suggest for a proper I2C setup, you always enable this feature. You don't want the slave to hold the bus forever. You should provide a mechanism for the master and the bus to free up after a programmable timeout period. Once the bus timeouts, you will issue a STOP condition to recover the bus. Please see below excerpt from the datasheet. 

    18.3.1.6 Clock Low Timeout (CLTO)
    The I2C slave can extend the transaction by pulling the clock low periodically to create a slow bit
    transfer rate. The I2C module has a 12-bit programmable counter that is used to track how long the
    clock has been held low. The upper 8 bits of the count value are software programmable through
    the I2C Master Clock Low Timeout Count (I2CMCLKOCNT) register. The lower four bits are not
    user visible and are 0x0. The CNTL value programmed in the I2CMCLKOCNT register has to be
    greater than 0x01. The application can program the eight most significant bits of the counter to
    reflect the acceptable cumulative low period in transaction. The count is loaded at the START
    condition and counts down on each falling edge of the internal bus clock of the Master. Note that
    the internal bus clock generated for this counter keeps running at the programmed I2C speed even
    if SCL is held low on the bus. Upon reaching terminal count, the master state machine forces ABORT
    on the bus by issuing a STOP condition at the instance of SCL and SDA release.


    As an example, if an I2C module was operating at 100 kHz speed, programming the I2CMCLKOCNT
    register to 0xDA would translate to the value 0xDA0 since the lower four bits are set to 0x0. This
    would translate to a decimal value of 3488 clocks or a cumulative clock low period of 34.88 ms at
    100 kHz.


    The CLKRIS bit in the I2C Master Raw Interrupt Status (I2CMRIS) register is set when the clock
    timeout period is reached, allowing the master to start corrective action to resolve the remote slave
    state. In addition, the CLKTO bit in the I2C Master Control/Status (I2CMCS) register is set; this bit
    is cleared when a STOP condition is sent or during the I2C master reset. The status of the raw SDA
    and SCL signals are readable by software through the SDA and SCL bits in the I2C Master Bus
    Monitor (I2CMBMON) register to help determine the state of the remote slave.


    In the event of a CLTO condition, application software must choose how it intends to attempt bus
    recovery. Most applications may attempt to manually toggle the I2C pins to force the slave to let go
    of the clock signal (a common solution is to attempt to force a STOP on the bus). If a CLTO is
    detected before the end of a burst transfer, and the bus is successfully recovered by the master,
    the master hardware attempts to finish the pending burst operation. Depending on the state of the

    slave after bus recovery, the actual behavior on the bus varies. If the slave resumes in a state where
    it can acknowledge the master (essentially, where it was before the bus hang), it continues where
    it left off. However, if the slave resumes in a reset state (or if a forced STOP by the master causes
    the slave to enter the idle state), it may ignore the master's attempt to complete the burst operation
    and NAK the first data byte that the master sends or requests.


    Since the behavior of slaves cannot always be predicted, it is suggested that the application software
    always write the STOP bit in the I2C Master Configuration (I2CMCR) register during the CLTO
    interrupt service routine. This limits the amount of data the master attempts to send or receive upon
    bus recovery to a single byte, and after the single byte is on the wire, the master issues a STOP.
    An alternative solution is to have the application software reset the I2C peripheral before attempting
    to manually recover the bus. This solution allows the I2C master hardware to be returned to a known
    good (and idle) state before attempting to recover a stuck bus and prevents any unwanted data
    from appearing on the wire.


    Note: The Master Clock Low Timeout counter counts for the entire time SCL is held Low
    continuously. If SCL is deasserted at any point, the Master Clock Low Timeout Counter is
    reloaded with the value in the I2CMCLKOCNT register and begins counting down from this
    value.

  • Hi Charles,

    Thank you for this detailed & helpful analysis - sure to prove useful to many here.

    Young staff wants to add that this useful "CLTO" capability exists w/in the TM4C123 family as well.   (some here (moi) had doubts)

    We do have (some) reservations regarding the utility of:   (a true copy follows:)

    An alternative solution is to have the application software reset the I2C peripheral before attempting
    to manually recover the bus. This solution allows the I2C master hardware to be returned to a known
    good (and idle) state before attempting to recover a stuck bus and prevents any unwanted data
    from appearing on the wire.

    • Have the App's software "reset" the I2C peripheral

    Our group finds that the majority of such I2C peripherals do not provide a "dedicated reset pin."   Thus - "generating a sufficient length SCL pulse train" and/or "issuing an I2C STOP command" may be attempted.   However - not always do these succeed!   Our group thus recommends that the general I2C design implementation include the means for the I2C Master (MCU) to provide individual/controlled "power" to (each) I2C slave.   (Many slaves may be powered by the MCU's GPIO alone - a small FET supplies even additional, controllable "slave power.")    This insures that the I2C Slave may be reset.

    • A complication exists when the I2C Slave is an MCU

    It proves "Not always desirable" to reset an MCU.    (Data fetched & ready is subject to loss, the slave MCU requires "time to fully re-initialize & recover from the reset etc.")    Instead - my group has discovered that providing a "dedicated signal line" (GPIO) between the MCU Master & MCU Slave - enables the Master to "Command the Slave MCU to "Reset or otherwise restore its I2C peripheral to the proper, "Ready State."

    It should be additionally noted that I2C signal traces should be, "Short, direct, & avoid proximity to noise sources and high speed data signalling.".   Careful/thoughtful "distribution of multiple I2C Slaves" (i.e. Slaves placed as "Spokes w/in a wheel" (equidistant from the Master) rather than "daisy chained" - which places the "most distant devices at high risk for disturbance.")

  • Hi cb1,

      Thank you for your invaluable insights and system level experience sharing with the community. I like your idea to use the GPIO as a means to reset a slave MCU I2C device. The slave MCU can specifically just reset its I2C instead of the entire device based on the GPIO input provided the slave MCU is not pin constrained. 

  • Hi again Charles,

    Thank you - it is hoped that "our experience & justification of our recommendations" works much to the "benefit of others!"    (If it is possible to make a mistake (staff here) ... OK - I've made them all.)    [noted as "staff edit!"]

    Note too that many/most I2C Slave devices may be "powered down" - w/out disturbing the I2C bus - providing (some) power savings.   (And possibly - rendering the I2C bus "improved" - thru "reduction in number of active devices!")    Staff has repeatedly verified this finding - although "every case" proves (somewhat) different.

    "He who does not study history is condemned to repeat it!"   

  • Hello Charles and cb,

    Really thanks for your invaluable suggestion and quickly support on this, i will discuss with customer and have a further debug, will reply you once there are something new.

    thanks.

    YAN

  • Hi Yan,

      Do you have any updates on the status?

  • Hi Charles,

    No update from customer so far, i will keep on tracking, and update the status once there is something new, thanks.

    YAN

  • HI Yan,

      Ok. please write back when you have updates.