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.

I2C timing questions

Two questions about I2C in Tiva:

1) If I set START / RUN / STOP bits in I2CMCS, and then read I2CMCS in the next CPU instruction, the BUSY bits are not set yet. Experimentally, it appears that a delay of 4 cycles (at 40MHz) is necessary before the BUSY bits are visible. Is this delay documented anywhere? Is it frequency-specific? I looked at the data sheet fairly carefully, but didn't see it mentioned anywhere. The I2C flow charts specifically do not show this delay.

2) When I2C is configured to run at 400KHz, I see more like 375-380KHz clock frequency with a logic analyzer. Why the difference? I am 100% confident I am configuring the bit rate correctly.

Thanks.

  • Andrew G said:
    I am 100% confident I am configuring the bit rate correctly.

    Always beware when client, boss, wife or financial advisor expresses, "100% confidence."

    Your confidence would be less, "called to question" if you provided your set-up/config I2C code block. 

    Is it wise to "turn your back" on skilled/experienced/focused expertise - as this vendor provides, here?

    And - we use many versions of ARM Cortex MCUs - find some frequency deviation (as you note) pretty much "par for the course" (among multiple vendors - especially @ newer/higher I2C speeds) although 100% confidence "never" intrudes upon our self-analysis...

  • I2C frequency is set as

    I2C_MTPR_R = (clock_frequency / (20 * bit_rate)) - 1;

    This value comes out to 4 @ 40MHz to get 400KHz bit rate. If this is off by one, then I would see 30% higher or lower bit rate. Instead I see only a ~5% difference from what is expected.

    I am actually more interested in the answer to my first question. There appears to be a critical I2C timing constraint that is not mentioned anywhere in the documentation, although I may be wrong.
  • Andrew G said:
    I2C frequency is set as

    I2C_MTPR_R = (clock_frequency / (20 * bit_rate)) - 1;  

    That's helpful - although we (still) must rely upon (100% confidence) that "clock_frequency" has been correctly determined.

    Note that newer devices here suffer some variation in how/where, "system clock" may be determined.  (Get function is errata plagued...)

    Vendor is best qualified to respond to question one - perhaps my probe better enables (and eases) his response...

  • Hello Andrew,

    1. The delay is expected as from the time the command is issued to the time the state machine starts making the transition for I2C Transaction there is a delay.
    2. The second behavior is due to the fact that I2C is drive low and pull high. Thus based on the pull resistor value and the bus load, the rise time of the clock is affected. The dividers work correctly, but due to the rise time of the I2C SCL, the master assumes it to be clock stretching and restarts the count. If you try using HS mode then you will see that the SCL frequency comes correct as in HS mode the SCL is drive high and low instead of Pull Up, after the preamble phase.


    Regards
    Amit
  • Hi Amit,

    We find that a great explanation - thank you.

    That said - what really is the value of "uber correct" timing forced upon an I2C bus?

    Beauty of the original I2C schema was collision avoidance - and acceptance of (reasonably) broad timing tolerances.    As you (now) note - such timing is often held "hostage" by bus-loading & response of other devices - resident upon (even) a 400KHz I2C bus...

  • Hello cb1,

    Since the I2C Master has to adjust as per the external slave ablity to clock stretch, it must not mean that it should not have a finite counter for counting SCL high and low period. That is why the specific point about HS mode.

    Regards
    Amit
  • Good that - but was not poster's interest focused upon 400KHz - and that's not (yet) HS mode? As stated - we've seen multiple ARM MCUs (many makers) and yours are "far from alone" in "NOT locking down" @ 400KHz. (and we still - don't see what's the "big deal!")

  • Thank you Amit. Regarding the delay, how many cycles should one wait before checking the BUSY bits and where is that documented?
  • Hello Andrew,

    It is not documented as we suggest either use of Interrupt or Complement polling where we first wait for the controller to be busy and then wait for it to be "un"busy.

    while(!I2CMasterBusy(x));
    while(I2CMasterBusy(x));

    Regards
    Amit
  • The problem with what you suggested is that if you somehow miss the master being busy (e.g. due to an unrelated interrupt), you could get stuck forever in the first line

    It would be better if you could put an upper bound on the number of cycles before the BUSY bits are set. Then I could just insert the right number of nops in my code.

    Please consider documenting this delay. As is, the I2C flow charts in the data sheet are wrong.
  • Hello Andrew,

    Yes that is true, but the same is applicable for the I2CMasterBusy, i.e. if the interrupt remains longer then we could still get stuck in the loop. The right approach would be to use interrupt.

    Regards
    Amit
  • That's not true.

    while (I2CMasterBusy()) {}

    only blocks as long as an I2C operation is in progress. An interrupt will not cause it to get stuck.

    Asking again if it's possible to get an upper bound on the number of cycles between a modification to the I2C_MCS register and the setting of the BUSY bits. This is an important timing parameter that should be documented.

    If I2C can only be used via interrupts, please state so in the datasheet.

  • Hello Andrew

    My apologies, yes you are right.

    The Upper Bound cannot be placed as the System Clock Frequency is a programmable parameter, so it would end up being done on each and every divider setting v/s every baud rate (do note that customers use other than 100K, 400K and 1M). That is why recommend using Interrupt mechanism. Now why the data sheet still has the Busy polling mechanism is to keep it in line with legacy software from LM3S device when using StellarisWare or TivaWare.

    Regards
    Amit
  • Thank you for clarification.

    Are there state machine delays in other Tiva peripherals, such as UART and SPI, and should communication with those peripherals also be interrupt-driven? As an example, is the following UART code not valid

    *UART_DR_R = c;
    while ((*UART_FR_R & UART_FR_BUSY) != 0) {}

    because the BUSY state can be missed in the while loop?

  • Hello Andrew

    It would need to be investigated. Also I tried looking for the device, but there was no information if it is a TM4C123 or a TM4C129 device?

    Regards
    Amit
  • It is a TM4C123. It would be good if these state machine delays could be characterized and documented for other TI microcontrollers as well.