34.6.2.4 I2C Host Operation

The I2C Host is byte-oriented and interrupt based. The number of interrupts generated is kept at a minimum by automatic handling of most events. The software driver complexity and code size are reduced by auto-triggering of operations, and a special smart mode, which can be enabled by the Smart Mode Enable bit in the Control A register (CTRLA.SMEN).

The I2C Host has two interrupt strategies.

When SCL Stretch Mode (CTRLA.SCLSM) is '0', SCL is stretched before or after the acknowledge bit . In this mode the I2C Host operates according to the following figure. The circles labeled "Mn" (M1, M2..) indicate the nodes the bus logic can jump to, based on software or hardware interaction.

This diagram is used as reference for the description of the I2C Host operation throughout the document.

Figure 34-4. I2C Host Behavioral Diagram (SCLSM=0)

In the second strategy (CTRLA.SCLSM=1), interrupts only occur after the ACK bit, as shown in the following figure. This strategy can be used when it is not necessary to check DATA before acknowledging.

Note: I2C High-speed (Hs) mode requires CTRLA.SCLSM=1.
Figure 34-5.  I2C Host Behavioral Diagram (SCLSM=1)

Host Clock Generation

The SERCOM peripheral supports several I2C bi-directional modes:
  • Standard mode (Sm) up to 100kHz
  • Fast mode (Fm) up to 400kHz
  • Fast mode Plus (Fm+) up to 1MHz
  • High-speed mode (Hs) up to 3.4MHz
The Host clock configuration for Sm, Fm, and Fm+ are described in Clock Generation (Standard-Mode, Fast-Mode, and Fast-Mode Plus) . For Hs, refer to Host Clock Generation (High-Speed Mode) .

Clock Generation (Standard-Mode, Fast-Mode, and Fast-Mode Plus)

In I2C Sm, Fm, and Fm+ mode, the Host clock (SCL) frequency is determined as described in this section:

The low (TLOW) and high (THIGH) times are determined by the Baud Rate register (BAUD), while the rise (TRISE) and fall (TFALL) times are determined by the bus topology. Because of the wired-AND logic of the bus, TFALL will be considered as part of TLOW. Likewise, TRISE will be in a state between TLOW and THIGH until a high state has been detected.

Figure 34-6. SCL Timing
The following parameters are timed using the SCL low time period TLOW. This comes from the Host Baud Rate Low bit group in the Baud Rate register (BAUD.BAUDLOW). When BAUD.BAUDLOW=0, or the Host Baud Rate bit group in the Baud Rate register (BAUD.BAUD) determines it.
  • TLOW – Low period of SCL clock
  • TSU;STO – Set-up time for stop condition
  • TBUF – Bus free time between stop and start conditions
  • THD;STA – Hold time (repeated) start condition
  • TSU;STA – Set-up time for repeated start condition
  • THIGH is timed using the SCL high time count from BAUD.BAUD
  • TRISE is determined by the bus impedance; for internal pull-ups. Refer to the Electric Characteristics
  • TFALL is determined by the open-drain current limit and bus impedance; can typically be regarded as zero. Refer to the Electric Characteristics for details.

The SCL frequency is given by:

f SCL = 1 T LOW + T HIGH + T RISE

When BAUD.BAUDLOW is zero, the BAUD.BAUD value is used to time both SCL high and SCL low. In this case the following formula will give the SCL frequency:

f SCL = f GCLK 10 + 2 B A U D + f GCLK T RISE GUID-BBC2C9B1-8E97-4094-8770-1CF1E10F9F36

When BAUD.BAUDLOW is non-zero, the following formula determines the SCL frequency:

f SCL = f GCLK 10 + B A U D + B A U D L O W + f GCLK T RISE

The following formulas can determine the SCL TLOW and THIGH times:

T LOW = B A U D L O W + 5 f GCLK

T HIGH = B A U D + 5 f GCLK

Note: The I2C standard Fm+ (Fast-mode plus) requires a nominal high to low SCL ratio of 1:2, and BAUD should be set accordingly. At a minimum, BAUD.BAUD and/or BAUD.BAUDLOW must be non-zero.
Startup Timing The minimum time between SDA transition and SCL rising edge is 6 APB cycles when the DATA register is written in smart mode. If a greater startup time is required due to long rise times, the time between DATA write and IF clear must be controlled by software.
Note: When timing is controlled by user, the Smart Mode cannot be enabled.

References:

Electric Characterstics

Host Clock Generation (High-Speed Mode)

For I2C Hs transfers, there is no SCL synchronization. Instead, the SCL frequency is determined by the GCLK_SERCOMx_CORE frequency (fGCLK) and the High-Speed Baud setting in the Baud register (BAUD.HSBAUD). When BAUD.HSBAUDLOW=0, the HSBAUD value will determine both SCL high and SCL low. In this case the following formula determines the SCL frequency.

f SCL = f GCLK 2 + 2 H S B A U D

When HSBAUDLOW is non-zero, the following formula determines the SCL frequency.

f SCL = f GCLK 2 + H S B A U D + H S B A U D L O W

Note: The I2C standard Hs (High-speed) requires a nominal high to low SCL ratio of 1:2, and HSBAUD should be set accordingly. At a minimum, BAUD.HSBAUD and/or BAUD.HSBAUDLOW must be non-zero.

Transmitting Address Packets

The I2C Host starts a bus transaction by writing the I2C Client address to ADDR.ADDR and the direction bit, as described in Principle of Operation. If the bus is busy, the I2C Host will wait until the bus becomes idle before continuing the operation. When the bus is idle, the I2C Host will issue a start condition on the bus. The I2C Host will then transmit an address packet using the address written to ADDR.ADDR. After the address packet has been transmitted by the I2C Host, one of four cases will arise according to arbitration and transfer direction.

Case 1: Arbitration lost or bus error during address packet transmission

If arbitration was lost during transmission of the address packet, the Host on Bus bit in the Interrupt Flag Status and Clear register (INTFLAG.MB) and the Arbitration Lost bit in the Status register (STATUS.ARBLOST) are both set. Serial data output to SDA is disabled, and the SCL is released, which disables clock stretching. In effect the I2C Host is no longer allowed to execute any operation on the bus until the bus is idle again. A bus error will behave similarly to the arbitration lost condition. In this case, the MB interrupt flag and Host Bus Error bit in the Status register (STATUS.BUSERR) are both set in addition to STATUS.ARBLOST.

The Host Received Not Acknowledge bit in the Status register (STATUS.RXNACK) will always contain the last successfully received acknowledge or not acknowledge indication.

In this case, software will typically inform the application code of the condition and then clear the interrupt flag before exiting the interrupt routine. No other flags have to be cleared at this moment, because all flags will be cleared automatically the next time the ADDR.ADDR register is written.

Case 2: Address packet transmit complete – No ACK received

If there is no I2C Client device responding to the address packet, then the INTFLAG.MB interrupt flag and STATUS.RXNACK will be set. The clock hold is active at this point, preventing further activity on the bus.

The missing ACK response can indicate that the I2C Client is busy with other tasks or sleeping. Therefore, it is not able to respond. In this event, the next step can be either issuing a stop condition (recommended) or resending the address packet by a repeated start condition. When using SMBus logic, the Client must ACK the address. If there is no response, it means that the Client is not available on the bus.

Case 3: Address packet transmit complete – Write packet, Host on Bus set

If the I2C Host receives an acknowledge response from the I2C Client, INTFLAG.MB will be set and STATUS.RXNACK will be cleared. The clock hold is active at this point, preventing further activity on the bus.

In this case, the software implementation becomes highly protocol dependent. Three possible actions can enable the I2C operation to continue:
  • Initiate a data transmit operation by writing the data byte to be transmitted into DATA.DATA.
  • Transmit a new address packet by writing ADDR.ADDR. A repeated start condition will automatically be inserted before the address packet.
  • Issue a stop condition, consequently terminating the transaction.

Case 4: Address packet transmit complete – Read packet, Client on Bus set

If the I2C Host receives an ACK from the I2C Client, the I2C Host proceeds to receive the next byte of data from the I2C Client. When the first data byte is received, the Client on Bus bit in the Interrupt Flag register (INTFLAG.SB) will be set and STATUS.RXNACK will be cleared. The clock hold is active at this point, preventing further activity on the bus.

In this case, the software implementation becomes highly protocol dependent. Three possible actions can enable the I2C operation to continue:
  • Let the I2C Host continue to read data by acknowledging the data received. ACK can be sent by software, or automatically in smart mode.
  • Transmit a new address packet.
  • Terminate the transaction by issuing a stop condition.
Note: An ACK or NACK will be automatically transmitted if smart mode is enabled. The Acknowledge Action bit in the Control B register (CTRLB.ACKACT) determines whether ACK or NACK should be sent.

Transmitting Data Packets

When an address packet with direction Host Write (see Figure 34-2) was transmitted successfully , INTFLAG.MB will be set. The I2C Host will start transmitting data via the I2C bus by writing to DATA.DATA, and monitor continuously for packet collisions. I

If a collision is detected, the I2C Host will lose arbitration and STATUS.ARBLOST will be set. If the transmit was successful, the I2C Host will receive an ACK bit from the I2C Client, and STATUS.RXNACK will be cleared. INTFLAG.MB will be set in both cases, regardless of arbitration outcome.

It is recommended to read STATUS.ARBLOST and handle the arbitration lost condition in the beginning of the I2C Host on Bus interrupt. This can be done as there is no difference between handling address and data packet arbitration.

STATUS.RXNACK must be checked for each data packet transmitted before the next data packet transmission can commence. The I2C Host is not allowed to continue transmitting data packets if a NACK is received from the I2C Client.

Receiving Data Packets (SCLSM=0)

When INTFLAG.SB is set, the I2C Host will already have received one data packet. The I2C Host must respond by sending either an ACK or NACK. Sending a NACK may be unsuccessful when arbitration is lost during the transmission. In this case, a lost arbitration will prevent setting INTFLAG.SB. Instead, INTFLAG.MB will indicate a change in arbitration. Handling of lost arbitration is the same as for data bit transmission.

Receiving Data Packets (SCLSM=1)

When INTFLAG.SB is set, the I2C Host will already have received one data packet and transmitted an ACK or NACK, depending on CTRLB.ACKACT. At this point, CTRLB.ACKACT must be set to the correct value for the next ACK bit, and the transaction can continue by reading DATA and issuing a command if not in the smart mode.

High-Speed Mode

High-speed transfers are a multi-step process, see the following figure.

First, a Host code (0b00001nnn, where 'nnn' is a unique Host code) is transmitted in Full-speed mode, followed by a NACK since no Client should acknowledge. Arbitration is performed only during the Full-speed Host Code phase. The Host code is transmitted by writing the Host code to the address register (ADDR.ADDR) and writing the high-speed bit (ADDR.HS) to '0'.

After the Host code and NACK have been transmitted, the Host write interrupt will be asserted. In the meanwhile, the Client address can be written to the ADDR.ADDR register together with ADDR.HS=1. Now in High-speed mode, the Host will generate a repeated start, followed by the Client address with RW-direction. The bus will remain in High-speed mode until a stop is generated. If a repeated start is desired, the ADDR.HS bit must again be written to '1', along with the new address ADDR.ADDR to be transmitted.

Figure 34-7. High Speed Transfer

Transmitting in High-speed mode requires the I2C Host to be configured in High-speed mode (CTRLA.SPEED=0x2) and the SCL clock stretch mode (CTRLA.SCLSM) bit set to '1'.

10-Bit Addressing

When 10-bit addressing is enabled by the Ten Bit Addressing Enable bit in the Address register (ADDR.TENBITEN=1) and the Address bit field ADDR.ADDR is written, the two address bytes will be transmitted, see the following figure. The addressed Client acknowledges the two address bytes, and the transaction continues. Regardless of whether the transaction is a read or write, the Host must start by sending the 10-bit address with the direction bit (ADDR.ADDR[0]) being zero.

If the Host receives a NACK after the first byte, the write interrupt flag will be raised and the STATUS.RXNACK bit will be set. If the first byte is acknowledged by one or more Clients, then the Host will proceed to transmit the second address byte and the Host will first see the write interrupt flag after the second byte is transmitted. If the transaction direction is read-from-Client, the 10-bit address transmission must be followed by a repeated start and the first 7 bits of the address with the read/write bit equal to '1'.

Figure 34-8. 10-bit Address Transmission for a Read Transaction
This implies the following procedure for a 10-bit read operation:
  1. Write the 10-bit address to ADDR.ADDR[10:1]. ADDR.TENBITEN must be '1', the direction bit (ADDR.ADDR[0]) must be '0' (can be written simultaneously with ADDR).
  2. Once the Host on Bus interrupt is asserted, Write ADDR[7:0] register to '11110 address[9:8] 1'. ADDR.TENBITEN must be cleared (can be written simultaneously with ADDR).
  3. Proceed to transmit data.