Programmer’s Guide
Initialization
After reset, the initialization of the I2C HWIP primarily consists of four steps:
- Timing parameter initialization
- FIFO reset and configuration
- Interrupt configuration
- Enable I2C Controller 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 requiresTHIGH
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:
- 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)
- 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
.
- 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
andTIMING0.TLOW
will be taken care of in a later step.
- 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 $$
- Store T_R and T_F in their corresponding registers:
TIMING1.T_R
andTIMING1.T_F
. - 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} $$
- 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 $$
- Let
PERIOD = max(MINPERIOD, USERPERIOD)
. - Each SCL cycle will now be at least
PERIOD
clock cycles in duration, divided between four segments:T_R
,THIGH
,T_F
, andTLOW
.- In other words:
PERIOD = T_R + THIGH + T_F + TLOW
. - With
T_R
andT_F
already established, the remaining integer parametersTHIGH
andTLOW
are to be divided among the remaining clock cycles inPERIOD
: $$ \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} $$
- In other words:
- 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 controller 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.
Parameter | Spec. Min. (ns) | Reg. Val. | Phys. Val (ns) | Comment |
---|---|---|---|---|
TIMING0.THIGH | 260 | 120 | 360 | Chosen to satisfy SCL Period Minimum |
TIMING0.TLOW | 500 | 167 | 501 | Spec. tLOW Minimum |
TIMING1.T_F | 20ns * (VDD/5.5V) | 7 | 21 | Signal slew-rate should be controlled |
TIMING1.T_R | 0 | 40 | 120 | Based on pull-up resistance, line capacitance |
SCL Period | 1000 | N/A | 1002 | Constraint on THIGH+TLOW+T_R+T_F |
TIMING2.THD_STA | 260 | 87 | 261 | Spec. Minimum |
TIMING2.TSU_STA | 260 | 87 | 261 | Spec. Minimum |
TIMING3.THD_DAT | 0 | 0 | 0 | Spec. Minimum |
TIMING3.TSU_DAT | 260 | 87 | 261 | Spec. Minimum |
TIMING4.T_BUF | 500 | 167 | 501 | Spec. Minimum |
TIMING4.T_STO | 260 | 87 | 161 | Spec. 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.
Parameter | Spec. Min. (ns) | Reg. Val. | Phys. Val (ns) | Comment |
---|---|---|---|---|
TIMING0.THIGH | 260 | 87 | 261 | Spec. tHIGH Minimum |
TIMING0.TLOW | 500 | 167 | 501 | Spec. tLOW Minimum |
TIMING1.T_F | 20ns * (VDD/5.5V) | 7 | 21 | Signal slew-rate should be controlled |
TIMING1.T_R | 0 | 134 | 402 | Atypically high line capacitance |
SCL Period | 1000 | N/A | 395 | Forced longer than minimum by long T_R |
Writing n
bytes to a device:
- Address the device for writing by writing to:
FDATA.START
= 1;FDATA.FBYTE
= <7-bit address + write bit>.
- Fill the TX_FIFO by writing to
FDATA.FBYTE
n
-1 times. - Send last byte with the stop bit by writing to:
FDATA.STOP
= 1;FDATA.FBYTE
=.
Reading n
bytes from a device:
- Address the device for reading by writing to:
FDATA.START
= 1;FDATA.FBYTE
= <7-bit address + read bit>.
- 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 asFIFO_CTRL.FMTILVL
is set to 1).
- If
- If
INTR_STATE.nak
bit is 1, then go back to step 1, else proceed. - Issue a read transaction by writing to.
FDATA.READ
= 1;FDATA.STOP
= 1;FDATA.FBYTE
= <n
>.
- Wait for the read transaction to finish by checking:
STATUS.FMTEMPTY
bit is 1.
- Retrieve the data from the FIFO by reading
RDATA
n
times.