Programmer’s Guide


After reset, the initialization of the I2C HWIP primarily consists of four steps:

  1. Timing parameter initialization
  2. FIFO reset and configuration
  3. Interrupt configuration
  4. Enable I2C Host or Target functionality

Timing Parameter Tuning Algorithm

Of the four initialization steps, the timing parameter initialization is the most involved. With so many timing parameters, it is essential to have dedicated device interface functions (DIFs) to determine appropriate values for the 10 timing parameters.

The values of these parameters will depend primarily on three bus details:

  • The speed mode of the slowest device on the bus: Standard-mode (100 kbaud), Fast-mode (400 kbaud) or Fast-mode Plus (1 Mbaud).
  • The input clock period, tclk in ns.
  • The expected signal rise time, tr, in ns.
    • This is not a firmware-controlled parameter. Rather, it is a function of the capacitance and physical design of the bus. The specification provides detailed guidelines on how to manage capacitance in an I2C system:
    • Section 5.2 of the I2C specification indicates that Fast-mode Plus devices may operate at reduced clock speeds if the bus capacitance drives signal rise times (tr) outside the nominal 120ns limit. Excess capacitance can also be compensated for by reducing the size of the bus pullup resistor, so long as the total open-drain current does not exceed 20mA for Fast-mode Plus devices (as described in section 7.1 of the I2C specification). However the specification places a hard limit on rise times capping them at 1000ns.
    • If there are Standard- or Fast-mode target devices on the bus, the specified open-drain current limit is reduced to 3mA (section 7.1), thus further restricting the minimum value of the pull-up resistor.
    • In Fast-mode bus designs, where the total line capacitance exceeds 200pF, the specification recommends replacing the pull-up resistor with an active current source, supplying 3mA or less (section 5.1). Regardless of the physical construction of the bus, the rise time (tr) is a system dependent, parameter that needs to be made known to firmware for I2C initialization.
  • The expected fall time, tf, in ns.
    • Like tr, this parameter is not firmware controlled rather it is a function of the SCL driver, which in a strictly compliant device is expected to manage the slew-rate for the falling edge of the SDA and SCL signals, through proper design of the SCL output buffer.
    • See table 10 of the I2C specification for more details.
  • (optional) The desired SCL cycle period, tSCL,user in ns.
    • By default the device should operate at the maximum frequency for that mode. However, If the system developer wishes to operate at slower than the mode-specific maximum, a larger than minimum period could be allowed as an additional functional parameter when calculating the timing parameters.

Additional Constraints

  • To guarantee clock stretching works correctly in Controller-Mode, there is a requirement of THIGH >= 4. This constraint derives from the fact that there is a latency between the Controller FSM driving the bus and observing the effect of driving the bus. The implementation requires THIGH to be at least this large to guarantee that if the Target stretches the clock, we can observe it in time, and react accordingly.

Based on the inputs, the timing parameters may be chosen using the following algorithm:

  1. The physical timing parameters tHD,STA, tSU,STA, tHD.DAT, tSU,DAT, tBUF, and tSTO, tHIGH, and tLOW all have minimum allowed values which depend on the choice of speed mode (Standard-mode, Fast-mode or Fast-mode Plus). Using the speed mode input, look up the appropriate minimum value (in ns) for each parameter (i.e. tHD,STA,min, tSU,STA,min, etc)
  2. For each of these eight parameters, obtain an integer minimum by dividing the physical minimum parameter by the clock period and rounding up to the next highest integer: $$ \textrm{THIGH_MIN}=\max(\lceil{t_{HIGH,min}/t_{clk}}\rceil,4) $$ $$ \textrm{TLOW_MIN}=\lceil{t_{LOW,min}/t_{clk}}\rceil $$ $$ \textrm{THD_STA_MIN}= \lceil{t_{HD,STA,min}/t_{clk}}\rceil $$ $$ \textrm{TSU_STA_MIN}= \lceil{t_{SU,STA,min}/t_{clk}}\rceil $$ $$ \textrm{THD_DAT_MIN}= \lceil{t_{HD,DAT,min}/t_{clk}}\rceil $$ $$ \textrm{TSU_DAT_MIN}= \lceil{t_{HD,DAT,min}/t_{clk}}\rceil $$ $$ \textrm{T_BUF_MIN}= \lceil{t_{BUF,min}/t_{clk}}\rceil $$ $$ \textrm{T_STO_MIN}= \lceil{t_{STO,min}/t_{clk}}\rceil $$

Note that T_HD_DAT_MIN must be at least 1, and T_HD_STA_MIN and T_BUF_MIN must be greater than T_HD_DAT_MIN.

  1. Input the integer timing parameters, THD_STA_MIN, TSU_STA_MIN, THD_DAT_MIN, TSU_DAT_MIN, T_BUF_MIN and T_STO_MIN into their corresponding registers (TIMING2.THD_STA, TIMING2.TSU_STA, TIMING3.THD_DAT, TIMING3.TSU_DAT, TIMING4.T_BUF, TIMING4.T_STO)
    • This step allows the firmware to manage SDA signal delays to ensure that the SDA outputs are compliant with the specification.
    • The registers TIMING0.THIGH and TIMING0.TLOW will be taken care of in a later step.
  2. Take the given values for tf and tr and convert them to integer counts as well: $$ \textrm{T_R}= \lceil{t_{r}/t_{clk}}\rceil $$ $$ \textrm{T_F}= \lceil{t_{f}/t_{clk}}\rceil $$
  3. Store T_R and T_F in their corresponding registers: TIMING1.T_R and TIMING1.T_F.
  4. Based on the input speed mode, look up the maximum permissible SCL frequency (fSCL,max)and calculate the minimum permissible SCL period: $$ t_{SCL,min}= 1/f_{SCL,max} $$
  5. As with each of the other physical parameters convert tSCL,min and, if provided, the tSCL,user to integers, MINPERIOD and USERPERIOD.. $$ MINPERIOD = \lceil{t_{SCL,min}/t_{clk}}\rceil $$ $$ USERPERIOD = \lceil{t_{SCL,user}/t_{clk}}\rceil $$
  7. Each SCL cycle will now be at least PERIOD clock cycles in duration, divided between four segments: T_R, THIGH, T_F, and TLOW.
    • In other words: PERIOD = T_R + THIGH + T_F + TLOW.
    • With T_R and T_F already established, the remaining integer parameters THIGH and TLOW are to be divided among the remaining clock cycles in PERIOD: $$ \textrm{THIGH}+\textrm{TLOW} \ge\textrm{PERIOD}-\textrm{T_F}-\textrm{T_R} $$
    • Since tHIGH and tLOW both have minimum allowable values, which depends on the mode, high values of tr or tf may force an increase in the total SCL period, slowing down the data transit rate.
    • The balance between tHIGH and tLOW can be manipulated in a variety of different ways (depending on the desired SCL duty cycle).
    • It is, for instance, perfectly acceptable to simply set TLOW to the minimum possible value: $$ \textrm{TIMING0.TLOW}=\textrm{TLOW_MIN} $$
  8. THIGH is then set to satisfy both constraints in the desired SCL period and in the minimum permissible values for tHIGH: $$ \textrm{TIMING0.THIGH}=\max(\textrm{PERIOD}-\textrm{T_R} - \textrm{TIMING0.TLOW} -\textrm{T_F}, \textrm{THIGH_MIN}) $$

We are aware of two issues with timing calculations. First, the fall time (T_F) is counted twice in host mode as is tracked in issue #18958. Second, the high time (THIGH) is 3 cycles longer when no clock stretching is detected as tracked in issue #18962. Due to these two discrepancies and the tendency of the above equations to create an underestimate of the eventual clock frequency, we recommend that the internal clock is driven at least 50x higher than the line speed.

Timing parameter examples

The following tables show a couple of examples for calculating timing register parameters for Fast-mode Plus devices. Both examples assume a desired datarate of 1 Mbaud (the bus maximum) for an SCL period of 1 us, and an internal device clock period of 3 ns.

ParameterSpec. Min. (ns)Reg. Val.Phys. Val (ns)Comment
TIMING0.THIGH260120360Chosen to satisfy SCL Period Minimum
TIMING0.TLOW500167501Spec. tLOW Minimum
TIMING1.T_F20ns * (VDD/5.5V)721Signal slew-rate should be controlled
TIMING1.T_R040120Based on pull-up resistance, line capacitance
SCL Period1000N/A1002Constraint on THIGH+TLOW+T_R+T_F
TIMING2.THD_STA26087261Spec. Minimum
TIMING2.TSU_STA26087261Spec. Minimum
TIMING3.THD_DAT000Spec. Minimum
TIMING3.TSU_DAT26087261Spec. Minimum
TIMING4.T_BUF500167501Spec. Minimum
TIMING4.T_STO26087161Spec. Minimum

This next example shows how the first SCL timing registers: TIMING0 and TIMING1 are altered in a high-capacitance Fast-mode Plus bus, where the physical value of tr driven to an atypical value of 400ns. As in the previous example the integer register values are determined based on a system clock period, tclk, of 3ns. All other parameters in registers TIMING2, TIMING3, TIMING4 are unchanged from the previous example.

ParameterSpec. Min. (ns)Reg. Val.Phys. Val (ns)Comment
TIMING0.THIGH26087261Spec. tHIGH Minimum
TIMING0.TLOW500167501Spec. tLOW Minimum
TIMING1.T_F20ns * (VDD/5.5V)721Signal slew-rate should be controlled
TIMING1.T_R0134402Atypically high line capacitance
SCL Period1000N/A395Forced longer than minimum by long T_R

Writing n bytes to a device:

  1. Address the device for writing by writing to:
    • FDATA.START = 1;
    • FDATA.FBYTE = <7-bit address + write bit>.
  2. Fill the TX_FIFO by writing to FDATA.FBYTE n-1 times.
  3. Send last byte with the stop bit by writing to:
    • FDATA.STOP = 1;
    • FDATA.FBYTE = .

Reading n bytes from a device:

  1. Address the device for reading by writing to:
    • FDATA.START = 1;
    • FDATA.FBYTE = <7-bit address + read bit>.
  2. Wait the write transaction to finish by either checking:
    • If STATUS.FMTEMPTY bit is 1.
    • Or if INTR_STATE.fmt_threshold bit is 1 ( as long as FIFO_CTRL.FMTILVL is set to 1).
  3. If INTR_STATE.nak bit is 1, then go back to step 1, else proceed.
  4. Issue a read transaction by writing to.
    • FDATA.READ = 1;
    • FDATA.STOP = 1;
    • FDATA.FBYTE = <n>.
  5. Wait for the read transaction to finish by checking:
    • STATUS.FMTEMPTY bit is 1.
  6. Retrieve the data from the FIFO by reading RDATA n times.

Device Interface Functions (DIFs)