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/TM4C129XKCZAD: TM4C129 I2C handle when unconnected

Part Number: TM4C129XKCZAD
Other Parts Discussed in Thread: TM4C1294NCPDT

Tool/software: Code Composer Studio

Hi,

I am working on TM4C129X dev board to which I have interface an Power sequencer Ucd via I2C

My aim was to check whether the interface is thru for which I try to read the device ID and manf ID of chipset. In normal I am able to communicate with the Ucd chipset Via I2C.

When I unconnect the chip from I2C I face two issues

here is the code i work on

/***************************/

    I2CMasterSlaveAddrSet(I2C1_BASE, UCD_I2Caddr , false);//  write ucd addr
    I2CMasterDataPut(I2C1_BASE, ui8Command); // put Command to I2C1
    I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_START); // Send
    while(!I2CMasterBusy(I2C1_BASE));
    while(I2CMasterBusy(I2C1_BASE));  // check for I2C master busy hence wait
    if( I2CMasterErr(I2C1_BASE) != I2C_MASTER_ERR_NONE)
    {
    return false;
   }

/***********************/

Issue 1: when I2C pins are floating ie. when there are no pull-ups

I observe that the code hangs on statement

""while(I2CMasterBusy(I2C1_BASE));  // check for I2C master busy hence wait""

What to do about it??

Issue 2: when I2C disconnected from Ucd but has pullups

I2CMasterErr(I2C1_BASE) doesnot result in an error!!

but

""I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_START); // Send""

On scope i could observe only 9 clock cycle where as in actual case there should be 18 cycles (ADDR && Command"")

Is such a scenario how to determine error in the interface if any ??

What should be the right way to do this ??

 

  • I don't believe the I2C interface was designed to be connected and disconnected like USB. Is the TM4C1294 the only master on the bus? If so, you can call I2CMasterLineStateGet() to check that the pull-ups are attached.
  • Note too - as you & I have (often) advised - the use of (proper) external Pull-Up resistors is - at all times - mandatory. Floating the "I2C" pins of any I2C based device deviates from "best practice" - is not "normal" nor ever recommended!
  • My aim is to test the hardware so that I could identify possible faults!! so I am simulating various scenarios....what abt 2nd issue ?? Wont a nack error should occur??
  • Hello Rakesh,

    I think you should seek to understand how I2C works if you want to try such tests. For example this app note is a good general place to start: www.ti.com/.../slva704.pdf

    Note in Section 2.3: "Each byte of data (including the address byte) is followed by one ACK bit from the receiver." - This means when you disconnect your slave, after sending the address byte your master cannot receive the ACK bit and thus hangs.

    If you want to test the hardware, you should get a logic state analyzer and debug the I2C pins with both devices attached and monitor the communication between them.

    Also once you understand the basics, here is an app note specifically for TM4C: http://www.ti.com/lit/pdf/spma073

  • Indeterminate logic states prove (rarely) your friend. Your read of the "older, more official" I2C spec (thus far silent) is also recommended.
  • Hi,

    This is the point I was trying to raise.....Pls understand that i am able to establish communication with the receiver/ exchange data and program it via I2C. My aim is to create a code to test the interface (POST sort) to ensure that the interface is functional .... So I was trying to perform simulated scenario for error conditions that may occur....so in case of error I can report problem with I2C interface to hardware testing team....

    Issue 2 : when receiver is not present or Addr does not match or I2C lines broken

    If I try to perform I2C cycle with no receiver then in the following code

    /***************************/

        I2CMasterSlaveAddrSet(I2C1_BASE, UCD_I2Caddr , false);//  write ucd addr
        I2CMasterDataPut(I2C1_BASE, ui8Command); // put Command to I2C1
        I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_START); // Send
        while(!I2CMasterBusy(I2C1_BASE));
        while(I2CMasterBusy(I2C1_BASE));  // check for I2C master busy hence wait
        if( I2CMasterErr(I2C1_BASE) != I2C_MASTER_ERR_NONE)
        {
        return false;
       }

    /***********************/

    I was expecting

     I2CMasterErr() will return an error and I can exit from the code with a false .... which i could use to detect a fault in the I2C....In this case code does not return false....

      if( I2CMasterErr(I2C1_BASE) != I2C_MASTER_ERR_NONE)
        {
        return false;
       }

    I2CMasterErr(I2C1_BASE) returns I2C_MASTER_ERR_NONE......

    meaning that there was a proper ack for (addr & data)....No ack without receiver!!

    where actual scenario should have resulted in an I2C_MASTER_ERR_ADDR_ACK....

    I probed I2C interface with a scope , uC has issued only addr and doesnot spit out data meaning there was no ack for addr...

    What could be the reason for this??...

  • Rakesh Muralidharan said:
    I probed I2C interface with a scope , uC has issued only addr and doesnot spit out data

    As you claim that (necessary) "I2C pull-ups" have been removed/defeated - how is it possible for the µC to issue, "logically correct level" slave address?     That's an inconsistency - is it not?

    You should recall that the API includes very simple functions which, "Monitor I2C Line State" - is not that an infinitely faster/easier method to detect "failed or missing" (yet necessary) pull-up resistors?

  • ""Issue 2: when I2C disconnected from Ucd but has pullups""

    Pls forget the pullup issue....In 2nd case I have replugged pullups but there is no receiver....

  • Once again - "detail-lite!" Much depends upon the "timing" of said pull-up removal - and re-insertion - such detail (nowhere) disclosed...

    It is usual that (some) subtlety must be employed when "removing & inserting" such (necessary) components - while the device remains (it is assumed) "under power."    Again - such is undescribed...   "Heavy handed" pull-up "insertion/removal" have been seen to "lock up or latch" the slave - or (even) confuse the MCU!     All such possibilities must be examined, resolved - then properly implemented...

    Note too - if such testing is to continue when your slave devices are "present & powered" - how do you justify  "no receiver (slave) present" - at this time?     Is it not possible that the slave - itself - may react to your test - and may (further) complicate - even confound - your testing.    Such testing MUST be much more methodical - note your latest post, "Plz forget the pullup issue" - issued AFTER a serious description weakness of your process was identified.     (a valid µC emitted address was claimed - absent any pull-ups - and now should be "forgotten!"     Such does NOT illustrate great planning or confidence in the test design and execution - does it?)     My sense is that you "have the capability to devise such test" - yet are "too rushed now" to devise a systematic and logically valid - slave inclusive test...

    Further -  "testing" with an "absent receiver" WAS covered under the original (official/guiding) I2C spec issued by Philips.    (later arriving "adopters" of I2C (i.e. here) may have deviated from that spec - adding to your challenge...)

  • I presume i should hav started two separate threads addressing each issue independently...this would hav avoided confusion....

    Both the test were carried out seperately without any dependecy on one over the other....

    Now that i explicitly state this let us focus on 2nd issue of receiver not present....

  • With (more properly) "Slave" absent (will not ALWAYS be a receiver)  - both I2C signal lines should "line test" High - due to the presence of pull-up resistors.    During past tests my firm devised for testing (a faster, ARM MCU) we verified that the (expected) "voltage level resulted" when each I2C pin was independently, "driven low."       (this achieved via a "spare set" of GPIO - config'ed as "open drain" - able to effectively "pull-down.")       Note too that a buffered version of each I2C signal line was routed to the MCU's ADC - that voltage measure confirming that the pull-up R's were (both) "present & proper."

    Minus any slave - you should be able to test for "undue line capacitance" - or the shorting of either I2C signal line to supply or ground.

    And a, "free MCU GPIO pair" - may "connect" to the Slave's I2C pcb (signal footprint pins) - and thus confirm that the "pcb's signal path" is (itself) intact  & correct.     Those GPIO must then (restore) to "inputs" - so as not to impede "normal" I2C operations.

    Firm/I did this years past - for far larger client.   (as they continue to engage us - such test appears to have met their expectations...)

    [edit] 08:31 - I further recall that we employed a 2nd mini MCU - attached to a small "bed of nails" (connecting to the client's "I2C" bus) - which operated in conjunction w/client's board mounted MCU - to enable more detailed testing than that afforded by the client's (single) board mounted, ARM MCU.    (i.e. apparently "your" condition - as well...)

    Perhaps a "Verified Answer" may (now) be awarded?     (time/effort -> detail ... devoted in your behalf...)

  • For issue 1 when pull up not present

    ""If so, you can call I2CMasterLineStateGet() to check that the pull-ups are attached.""

    As Tiva  is the only master .....i tried this on board with with I2CMasterLineStateGet() with partial success...

    //*******************//

    bool
    I2C_Test_Pullup(uint32_t ui32Base)
    {
        bool lbool_Status;
        uint32_t ltest;
        ltest = I2CMasterLineStateGet(ui32Base);
        if (ltest  == 0x00000003)
            {
            lbool_Status = true;
            }
        else
            {lbool_Status = false;

            }
        return lbool_Status;
    }

    /**********/

    In my case  didn't work for clk pullup present and and data pull up absent(foating) ... I2CMasterLineStateGet(ui32Base) return 0x00000003...

     ""During past tests my firm devised for testing (a faster, ARM MCU) we verified that the (expected) "voltage level resulted" when each I2C pin was independently, "driven low."       (this achieved via a "spare set" of GPIO - configured as "open drain" - able to effectively "pull-down.")""

    From the above info I tried

    I2C pull up resistance value 2.2K .Before initializing the I2C .

    1. initialized i2c clk and data GPIOs as input

    2. configured weak pull down

    3. read the GPIO values and check for fault

    4. Disable GPIO peripheral

    /********************/

    bool
    I2C_Test_Pullup(void)
    {
        bool lbool_status;
        uint32_t luint32_GpioRead;
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
        while(!(SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOG)));
        /*
         * Enable weak pull down to bring
         */

        GPIOPinTypeGPIOInput(GPIO_PORTG_BASE, GPIO_PIN_1|GPIO_PIN_0);
        GPIOPadConfigSet(GPIO_PORTG_BASE,GPIO_PIN_1|GPIO_PIN_0,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPD);
        SysCtlDelay(5);  // delay
        /*
         *
         */
        luint32_GpioRead = GPIOPinRead (GPIO_PORTG_BASE,GPIO_PIN_1|GPIO_PIN_0);

        if (luint32_GpioRead == 3)
        {
            lbool_status = true;
        }
        else
        {
            lbool_status = false;
        }

        SysCtlPeripheralDisable(SYSCTL_PERIPH_GPIOG);
        SysCtlDelay(5);  // delay
        return lbool_status;

    }

    this seems to provide consistent result .... configure GPIO peripheral  & later  reconfigure GPIO impact is yet to be checked!!

     

  • ""Note in Section 2.3: "Each byte of data (including the address byte) is followed by one ACK bit from the receiver." - This means when you disconnect your slave, after sending the address byte your master cannot receive the ACK bit and thus hangs.""

    I agree that the way i tried to put-forth the information has created confusion......

    When slave not present the uC does NOT hang ... it executes without indicating nack error....My understanding is that Master will generate an nack error  if slave doesnot provide acknowledgement.....

    /***************************/

        I2CMasterSlaveAddrSet(I2C1_BASE, UCD_I2Caddr , false);//  write ucd addr
        I2CMasterDataPut(I2C1_BASE, ui8Command); // put Command to I2C1
        I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_START); // Send
        while(!I2CMasterBusy(I2C1_BASE));
        while(I2CMasterBusy(I2C1_BASE));  // check for I2C master busy hence wait
        if( I2CMasterErr(I2C1_BASE) != I2C_MASTER_ERR_NONE)
        {
        return false;
       }

    /***********************/

    I was expecting the following statement will  return an error but it didnt happen. there was no ""return false;"" uC started executing statements following

    if( I2CMasterErr(I2C1_BASE) != I2C_MASTER_ERR_NONE)
        {
        return false;
       }

  • Thank you - do note that your "sharpened focus" has enabled (better) response - and (hopefully) will "carry thru" to other aspects of your work...

    That "back to back" (first NOT Busy - then Busy) is (highly) unconventional (an "add-on") unique to your device (claimed a "fix") yet may cause the vulnerability you note.      IIRC the (simpler) "4C123" made, "No such, unconventional/kludged SW demand - and enabled "NAK" testing...

    Following the guidelines & suggestions provided herein (has) improved your I2C Test capability - "fixing" vendor's MCU is "outside" our interest/capability...

    [edit] As the higher speed operation of this MCU (still far below that of competing others) has been said to,  "have caused the kludged "back to back test" - perhaps your "I2C Testing" can be performed at "Reduced System Clock Speeds" - which may enable "kludge elimination" - and enable your NAK to "shine thru!"      (maybe)      (so deserves the banned "LIKE" - another kludged horror!)

  • Hi,

    Below thread has reference to the error with

    ""There is a known errata with using I2CMasterErr() -- it tries to get the status from I2CMCS but the tm4c1294ncpdt at least will reset the ADRACK and DATACK bits when BUSY gets reset, so you need to read from I2CMRIS. ""

    So I created a new error function

    /*********/

    int

    I2C_Error_check(uint32_t ui32Base)

    {

           uint32_t ui32Err;

           //

           // Get the raw error state

           //

           ui32Err = HWREG(ui32Base + I2C_O_MRIS);

           //

           // Check for errors.

           //

           if(ui32Err & (I2C_MRIS_NACKRIS))

           {

               return(I2C_MASTER_ERR_ADDR_ACK);

           }

           else

           {

               return(I2C_MASTER_ERR_NONE);

           }

    }

    /*****************/

    So my original code looks like

    /*****************************/

        I2CMasterSlaveAddrSet(I2C1_BASE, UCD_I2Caddr , false);//  write ucd addr
        I2CMasterDataPut(I2C1_BASE, ui8Command); // put Command to I2C1
        I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_START); // Send
        while(!I2CMasterBusy(I2C1_BASE))
        while(I2CMasterBusy(I2C1_BASE));  // check for I2C master busy hence wait
        if( I2C_Error_check(I2C1_BASE) != I2C_MASTER_ERR_NONE)
        {
            return false;
        }

    /**************************/

    this seems to work for the time being......

  • Good for you - ALWAYS the "most recent" errata must be "searched for, found, & followed."

    It is noted that MCUs of others - operating 50%+ faster - have "escaped" such "back to back" (unconventional/add-on) i2C Busy checks...

    You are "silent" as regards the ability to, "Check the integrity of the I2C signal path to the Slave(s)."     It is recalled that client found that most useful - if that path is "flawed" - ALL of your tests have been compromised - have they not?