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.

CCS/TM4C1294NCZAD: I2C Hanging Issue

Part Number: TM4C1294NCZAD

Tool/software: Code Composer Studio

Good afternoon,

I'm using the I2C Bus of the Tiva to communicate with a bunch of different plug-in sensor modules on my board.  It's working great.  The problem I'm having is that on some occasions, one of the sensors could be missing (unplugged).  When this happens, my code gets stuck in the I2C routine.  Can anyone suggest a proper way to escape and return 0 or FF in this situation?  I'd prefer to avoid using a timer.  Is there a flag that I could check for to see that the slave didn't respond?

Thanks!

uint32_t I2C3Receive1(uint32_t slave_addr, uint8_t reg)
{

//specify that we are writing (a register address) to the
//slave device
I2CMasterSlaveAddrSet(I2C3_BASE, slave_addr, false);

//specify register to be read
I2CMasterDataPut(I2C3_BASE, reg);

//send control byte and register address byte to slave device
I2CMasterControl(I2C3_BASE, I2C_MASTER_CMD_BURST_SEND_START);

//wait for MCU to finish transaction
while(!I2CMasterBusy(I2C3_BASE));
while(I2CMasterBusy(I2C3_BASE));

//specify that we are going to read from slave device
I2CMasterSlaveAddrSet(I2C3_BASE, slave_addr, true);

//send control byte and read from the register we
//specified
I2CMasterControl(I2C3_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);

//wait for MCU to finish transaction
while(!I2CMasterBusy(I2C3_BASE));
while(I2CMasterBusy(I2C3_BASE));

//return data pulled from the specified register
return I2CMasterDataGet(I2C3_BASE);
}

  • Sorry about the post.  Forgot to include the code tag.

    uint32_t I2C3Receive1(uint32_t slave_addr, uint8_t reg)
    {
    
        //specify that we are writing (a register address) to the
        //slave device
        I2CMasterSlaveAddrSet(I2C3_BASE, slave_addr, false);
    
        //specify register to be read
        I2CMasterDataPut(I2C3_BASE, reg);
    
        //send control byte and register address byte to slave device
        I2CMasterControl(I2C3_BASE, I2C_MASTER_CMD_BURST_SEND_START);
    
        //wait for MCU to finish transaction
        while(!I2CMasterBusy(I2C3_BASE));
        while(I2CMasterBusy(I2C3_BASE));
    
        //specify that we are going to read from slave device
        I2CMasterSlaveAddrSet(I2C3_BASE, slave_addr, true);
    
        //send control byte and read from the register we
        //specified
        I2CMasterControl(I2C3_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);
    
        //wait for MCU to finish transaction
        while(!I2CMasterBusy(I2C3_BASE));
        while(I2CMasterBusy(I2C3_BASE));
    
        //return data pulled from the specified register
        return I2CMasterDataGet(I2C3_BASE);
    }

  • You advise that your code fails when an I2C sensor has been removed. And such IS a valid concern. Yet - unmentioned is the case when you generate an "improper I2C address" (or one which is "glitched" via a noise burst) - what happens then?

    Should not you seek a solution to (both) issues?      Is it not likely that such "broader solution" proves a superior solution?

    Firm/I do not use TivaWare - have you searched for an I2C function - which may accommodate - (both) needs?      (there's no indication that you've done such...)

  • An incorrect address should have the exact same response as a missing sensor. A glitched sensor, on the other hand, could be a much larger problem because it could potentially hold clk or data low. Planning for that possibility requires a different approach (power cycle the sensor, in most cases).
  • I added to my (earlier) posting - is it true that your "search" of the I2C API reveals "No such Failed address" function?
  • Hi Benjamin,
    Your code should check for acknowledgement and error flags in your master I2C. If the addressed slave is unplugged then it will not acknowledge the command from the master during the address and data cycles.

    Note that even with the I2C slave still on the bus it is possible that the master does not detect acknowledgement from the slave for various reasons as noted by cb1. For example, the SDA high or low voltage level does not reach the slave's input thresholds or the slave interpreted a noise spike as an SCL cycle. Make sure you have adequate series resistors in this case if the I2C bus can be accessed from an external connector. cb1 may have other recommendations.
  • Benjamin Bawkon said:
    It's working great.  ....  The problem I'm having is...

    Somehow - "working great" - so quickly followed by "problem I'm having" - registers as "inconsistent!"

    Poster's code reveals that such "working great" occurs (only) under the "most favorable & forgiving" conditions.        (thus - "great" proves an "over-statement" - hope/dream - does it not?)

    Should you (really) desire to gain improved & more robust performance - should you not "Check for Errors?"      There is "no/zero" error checking - revealed anywhere - w/in your code!      Such was "hinted at" earlier - received only an (argumentative/thankless) response - in return.

    As suggested earlier - the newest API includes, "I2C error testing/checking."     A "reasonable" summary follows:

    And here is presented relevant detail - which expands - yet may not (fully) meet "all user" expectations:

    May we note that this poster's "use case" is rare, (plug/unplug) various I2C sensors.      Far more prevalent would be, "Multiple I2C devices installed (permanently) upon the (same) pcb.      (I2C is - after all - "short range" communication)       To conserve power - and reduce I2C bus loading - many/most of those I2C devices may be placed in "standby" - or even "powered down."      And - this creates the (larger) need to determine, "Who is (or remains) still on the I2C bus?"

    In the past - under StellarisWare 9453 - we devised such a scheme - enabling us to "log & know" which "I2C" devices were, "Up & Operational."     We could then enable other devices - when needed - and this selectivity (only those devices "required" were enabled) reduced bus loading and insured that, "all devices w/in the board's "I2C inventory" could be recognized & verified...

    It is believed that the detail provided herein - with the possible addition of some added "groundwork" - enables users to (actually) realize, "working great!"