Signal pins I3C uses the same two signal pins as I²C, referred to as
SCL (serial clock) and
SDA (serial data). The primary difference is that I²C operates them as
open-drain outputs at all times, so its speed is limited by the resultant slow signal
rise time. I3C uses open-drain mode when necessary for compatibility, but switches to
push-pull outputs whenever possible, and includes protocol changes to make it possible more often than in I²C. • SCL is a conventional digital
clock signal, driven with a push-pull output by the current bus controller during data transfers. (
Clock stretching, a rarely used I²C feature, is not supported.) In transactions involving I²C target devices, this clock signal generally has a
duty cycle of approximately 50%, but when communicating with known I3C targets, the bus controller may switch to a higher frequency and/or alter the duty cycle so the SCL high period is limited to at most 40 ns. • SDA carries the serial data stream, which may be driven by either controller or target, but is driven at a rate determined by the controller's SCL signal. For compatibility with the I²C protocol, each transaction begins with SDA operating as an open-drain output, which limits the transmission speed. For messages addressed to an I3C target, the SDA driver mode switches to push-pull after the first few bits in the transaction, allowing the clock to be further increased up to 12.5 MHz. This medium-speed feature is called single data rate (SDR) mode. Generally, SDA is changed just after the falling edge of SCL, and the resultant value is received on the following rising edge. When the controller hands SDA over to the target, it likewise does so on the falling edge of SCL. However, when an I3C target is handing back control of SDA to the controller (e.g. after acknowledging its address before a write), it releases SDA on the
rising edge of SCL, and the
controller is responsible for holding the received value (re-driving a copy of the target's bit) for the duration of SCL high. Because the controller drives SCL, it will see the rising edge first, so there will be a brief period of overlap when both are driving SDA, but as they are both driving the same value, no
bus contention occurs.
Framing All communications in I²C and I3C requires
framing for synchronization. Within a frame, changes on the SDA line should always occur while SCL is in the low state, so that SDA can be considered stable on the low-to-high transition of SCL. Violations of this general rule are used for framing (at least in legacy and standard data rate modes). Between data frames, the bus controller holds SCL high, in effect stopping the clock, and SDA drivers are in a high-impedance state, permitting a pull-up resistor to float it to high. A high-to-low transition of SDA while SCL is high is known as a START symbol, and signals the beginning a new data frame. A low-to-high transition on SDA while SCL is high is the STOP symbol, ending a data frame. A START without a preceding STOP, called a "repeated START", may be used to end one message and begin another within a single bus transaction. In I²C, the START symbol is usually generated by a bus controller, but in I3C, even target devices may pull SDA low to indicate they want to start a frame. This is used to implement some advanced I3C features, such as in-band interrupts, multi-controller support, and hot-joins. After the start, the bus controller restarts the clock by driving SCL, and begins the bus arbitration process.
Bus arbitration At the start of a frame, several devices may contend for use of the bus, and the bus arbitration process serves to select which device obtains control of the SDA line. In both I²C and I3C, bus arbitration is done with the SDA line in open-drain mode, which allows devices transmitting a binary 0 (low) to override devices transmitting a binary 1. Contending devices monitor the SDA line while driving it in open-drain mode. Whenever a device detects a low condition (0 bit) on SDA while transmitting a high (1 bit), it has lost arbitration and must cease contending until the next transaction begins. Each transaction begins with the target address, and the implementation gives priority to lower-numbered target addresses. The difference is that I²C has no limit on how long arbitration can last (in the rare but legal situation of several devices contending to send a message to the same device, the contention will not be detected until after the address byte). I3C, however, guarantees that arbitration will be complete no later than the end of the first byte. This allows push-pull drivers and faster clock rates to be used the great majority of the time. This is done in several ways: • I3C supports multiple controllers, but they are not symmetrical; one is the current controller and responsible for generating the clock. Other devices sending a message on the bus (in-band interrupts or secondary controllers wishing use of the bus) must arbitrate using their own address before sending any other data. Thus, no two legal bus messages share the same first byte
except if the controller and another device are simultaneously communicating with each other. • I3C, like I²C, allows multiple messages per transaction separated with "repeated START" symbols. Arbitration is per-transaction, so these subsequent messages are never subject to arbitration. • Most I3C controller transactions begin with the reserved address 0x7E(11111102). As this has a lower priority than any I3C device, once it has passed arbitration, the controller knows that no other device is contending for the bus. • As a special case, if I3C devices are assigned low addresses (I3C supports dynamic, controller-controlled address assignment), then as soon as the 0x7E address has won arbitration for enough leading bits to distinguish it from any assigned address, the controller knows that arbitration is complete and it may switch to push-pull operation on SDA. If all assigned addresses are less than 0x40, this is after the first bit. If all addresses are less than 0x60, this is after the second bit, and so on. • In the case described above wherein the current controller begins a transaction with the address of a device which is itself contending for use of the bus, both will transmit their address bytes successfully. However, each will expect the other to acknowledge the address (by pulling SDA low) for the following acknowledge bit. Consequently, neither will, and both will observe the lack of acknowledgement. In this case, the message is not sent, but the controller wins arbitration: it may send a repeated start, followed by a retry which will be successful.
Common command codes A write addressed to the reserved address 0x7E is used to perform a number of special operations in I3C. All I3C devices must receive and interpret writes to this address in addition to their individual addresses. First of all, a write consisting of just the address byte and no data bytes has no effect on I3C targets, but may be used to simplify I3C arbitration. As described above, this prefix may speed up arbitration (if the controller supports the optimization of switching to push-pull mid-byte), and it simplifies the controller by avoiding a slightly tricky arbitration case. If the write is followed by a data byte, the byte encodes a "common command code", a standardized I3C operation. Command codes 0–0x7F are broadcast commands addressed to all I3C targets. They may be followed by additional, command-specific parameters. Command codes 0x80–0xFE are direct commands addressed to individual targets. These are followed by a series of repeated STARTs and writes or reads to specific targets. While a direct command is in effect, per-target writes or reads convey command-specific parameters. This operation is in lieu of target's normal response to an I3C message. One direct command may be followed by multiple per-target messages, each preceded by a repeated START. This special mode ends at the end of the transaction (STOP symbol) or the next message addressed to 0x7E. Some command codes exist in both broadcast and direct forms. For example, the commands to enable or disable in-band interrupts may be sent to individual targets or broadcast to all. Commands to get parameters from a target (for example the GETHDRCAP command to ask a device which high-data-rate modes it supports) only exist in direct form. == Device classes ==