NodeLoop

I3C Bus Explained: A Modern Sensor Bus (and the Successor to I2C)

I3C keeps the simplicity of a 2-wire bus, but adds modern features (higher speed, lower power, dynamic addressing, and in-band interrupts) that make sensor-heavy designs easier to scale.

Erratum
Updated
  • Before this date the guide drew fixed pull-up resistors on both SCL and SDA and said pull-ups were required "even on an I3C-only bus", pointing to the I2C pull-up calculator. On I3C, SCL is driven push-pull by the controller only, and the SDA pull-up for open-drain phases is a structure the controller manages (often internal), together with high-keepers. The schematic, table and FAQ were corrected.
  • Legacy I2C devices may share an I3C bus only with a 50 ns spike filter and without clock stretching; this condition was missing. The dynamic address assignment section now describes ENTDAA, SETDASA and SETAASA.

Sources: MIPI Alliance, I3C frequently asked questions (pull-up structures, legacy I2C devices, ENTDAA).

If you have ever designed a board with "just one more sensor" and hit a wall with address conflicts, interrupt pin count, or I2C rise-time limits, I3C is the bus that tries to fix those pain points while staying familiar. I3C (Improved Inter-Integrated Circuit) is a 2-wire, multi-drop serial bus standardized by the MIPI Alliance, and it is widely positioned as the modern successor to I2C for sensors and small peripherals.

This guide is a practical, engineering-first introduction: what I3C is, what it changes electrically, how it discovers devices with Dynamic Address Assignment (DAA), what Common Command Codes (CCC) do, and how features like In-Band Interrupts (IBI) reduce wiring complexity.

Scope note: I3C is a spec family with multiple modes and optional features. The details vary by controller, target device, and "I3C vs I3C Basic" compliance level. This page focuses on the core concepts you need to evaluate I3C in real designs.

I3C vs I2C: What Actually Changes

I3C looks like I2C on the schematic (SCL + SDA), but it modernizes both the electrical behavior and the protocol. Here is the high-level comparison that matters in practice:

If you want a deep refresher on the classic bus (START/STOP, ACK/NACK, pull-ups, timing), see the I2C Communication Guide.

Topic I2C I3C
Wires SCL + SDA (open-drain) SCL is driven push-pull by the controller only. SDA is open-drain during START / address arbitration and legacy I2C transfers, push-pull for I3C data.
Speed ceiling Limited by RC rise time, bus capacitance, and pull-ups Higher typical data rates thanks to push-pull signaling; optional high-data-rate modes exist
Addressing Mostly static addresses; conflicts require straps/muxes Dynamic addressing (DAA) is a first-class feature; less need for address pins
Interrupts Extra GPIO interrupt lines are common In-Band Interrupt (IBI): targets can request attention over SDA
Configuration Mostly vendor-defined registers Common Command Codes (CCC) provide standardized discovery/config commands
Legacy compatibility N/A Designed to allow I2C devices on the same bus (with practical constraints)

Wiring & Electrical Layer: Why I3C Is Faster (and Lower Power)

I2C is fundamentally open-drain: devices only pull the line low, and pull-up resistors bring it high. That is simple and safe, but it also makes edges slow as bus capacitance grows. I3C keeps open-drain behavior where it needs to (especially for compatibility), then switches to push-pull signaling for most I3C traffic.

  • Pull-ups are a controller function: SCL is always driven by the active controller. During the open-drain phases (after START, address arbitration, legacy I2C transfers) the controller enables an open-drain class pull-up on SDA, and weak "high-keepers" hold the lines when nobody drives them. Many controllers integrate and switch these structures; whether an external resistor is needed, and its value, comes from the controller datasheet, not from an I2C pull-up calculation.
  • Push-pull changes everything: when the bus is driven actively high and low, you are less dependent on RC rise time. This is why I3C can reach higher data rates and reduce static pull-up current.
  • Be careful with level shifters: many "I2C level shifters" rely on open-drain behavior and will break (or degrade) push-pull signaling. Mixed-voltage I3C typically requires an I3C-capable translator or a system-level architecture that avoids translating the bus.
  • No clock stretching: I3C targets must not hold SCL low, and a legacy I2C device can only share an I3C bus if it never stretches the clock, has a 50 ns spike filter and runs in Fast-mode or Fast-mode Plus. The controller then slows down only for transfers addressed to that device.
I3C bus (with optional legacy I2C devices) VCC I3C Controller (MCU / SoC) SCL SDA pull-up* Sensor (I3C) Sensor (I3C) Legacy I2C Device (EEPROM)
SCL is push-pull from the controller, so it has no pull-up resistor. *The SDA pull-up is enabled by the controller only during open-drain phases and is often integrated; check the controller datasheet for any external part. A legacy I2C device on the bus must have a 50 ns spike filter and must not stretch the clock.

I3C Terminology (Controller, Target, and Friends)

You will see slightly different naming than legacy I2C documentation:

  • Controller: the device that initiates transfers and manages the bus (roughly "I2C master").
  • Target: a device that responds to transfers (roughly "I2C slave").
  • Multi-controller: some I3C systems allow more than one controller, with standardized mechanisms for more advanced arbitration/hand-off. Many embedded systems stick to a single controller.

I3C vs "I3C Basic"

In the wild, you will encounter three compatibility buckets:

  • I2C-only: legacy devices that never speak I3C.
  • I3C Basic: a widely implemented subset meant to make adoption easier while retaining the key ideas (dynamic addressing, CCC, event support depending on device).
  • Full I3C: devices/controllers that implement a broader set of optional features and modes.

For engineering decisions, the important part is not the label, but the feature checklist: DAA support, CCC coverage, IBI capability, and which speed modes are actually implemented.

Dynamic Addressing (DAA): How I3C Avoids Address Conflicts

On I2C, devices typically ship with a fixed 7-bit address (sometimes with 1-2 strap pins). If you need two identical sensors with the same address, you end up adding an I2C multiplexer or extra GPIOs. I3C solves this with Dynamic Address Assignment (DAA):

  1. The controller broadcasts the ENTDAA command (a Common Command Code).
  2. Every target without a dynamic address answers at once with its 48-bit Provisional ID followed by its BCR and DCR bytes, in open-drain mode. Because a 0 wins on an open-drain line, the target with the lowest value wins the arbitration; the others drop out.
  3. The controller sends the winner a 7-bit dynamic address, which the target acknowledges, then repeats ENTDAA until no target answers.
  4. Alternatives: SETDASA gives a dynamic address to a target whose I2C static address is already known, and SETAASA (I3C v1.1 and later) tells targets to use their static address as dynamic address. Normal traffic then uses the dynamic addresses, so two identical sensors are no longer a conflict.
Practical firmware takeaway: you typically run an "enumeration" sequence at boot (DAA), store the assigned addresses, then interact with targets much like you would on I2C (read/write registers), but with I3C-specific extras available.

Common Command Codes (CCC): Standardized Control & Discovery

One of the most "bus-level" differences is that I3C defines a set of standardized commands called Common Command Codes. CCCs let a controller discover devices, configure bus behavior, and enable/disable events in a uniform way.

CCC type What it means When you use it
Broadcast CCC Targets react without being individually addressed. Reset dynamic addresses, start dynamic address assignment, enable events globally, etc.
Directed CCC Applies to a specific target (or a set of targets). Query capabilities, configure limits, enable IBI for one device, etc.

Even if your application "just reads registers", CCCs matter because they define how the bus boots and how it stays manageable as you add more devices.

Events: In-Band Interrupt (IBI), Hot-Join, and More

A classic I2C pattern is "poll every sensor" or "wire a dedicated interrupt pin per sensor". I3C introduces bus-native event mechanisms so that targets can request service without extra GPIOs.

  • In-Band Interrupt (IBI): a target requests attention on the bus; the controller can then service the device and optionally read a small payload. This is a big deal when you have many sensors and few GPIOs.
  • Hot-Join: a newly connected target can request to be discovered and addressed without a full system reset (useful in modular designs).
  • Multi-controller concepts: I3C supports multi-controller topologies (more advanced designs), but most embedded systems use a single controller in practice.

Speed & Bandwidth: What to Expect

You will see "I3C is much faster than I2C" everywhere. The useful engineering framing is:

  • SDR (single data rate) transfers use push-pull signaling and run at up to 12.5 MHz SCL: 12.5 Mbit/s raw, about 11 Mbit/s of data once the T-bits are counted.
  • Byte transfers are not "8 clocks per byte": in SDR, data is commonly followed by an extra T-bit (similar in spirit to an ACK/NACK bit, but I3C-specific). A useful rule of thumb is "about 9 bits on the wire per 8-bit byte", before you even count command/address overhead.
  • Optional HDR modes exist for higher throughput, but the real-world number depends on which HDR mode is supported by both the controller and the target, and on your traffic pattern (many short register reads vs. longer bursts).
  • Effective throughput is workload-dependent: bus arbitration, command overhead, and "many small register reads" can dominate. I3C helps, but it does not magically turn a shared 2-wire bus into a point-to-point high-speed link.

Hardware Design Checklist (What Engineers Actually Get Wrong)

  • Assuming any I2C level shifter works: a common failure mode is putting a MOSFET-based bidirectional I2C level shifter on an I3C bus, then wondering why the bus is unstable at higher rates.
  • Copying an I2C pull-up design: fixed pull-ups sized for a fast I2C bus fight the controller's push-pull drivers and its own pull-up structures. Start from the controller datasheet; add external parts only where it asks for them.
  • Legacy devices without a 50 ns spike filter: I3C traffic looks like glitches to them and can corrupt their state. Check the I2C devices before putting them on an I3C bus.
  • Ignoring bus topology: stubs and long branches increase capacitance and reflections. Keep the bus short and "linear" when you care about speed.
  • Mixing legacy I2C devices without a plan: mixed-bus operation is supported, but it can restrict which I3C features you can use and may change electrical/timing assumptions.
  • No recovery strategy: define how your firmware handles a stuck bus, a misbehaving device, or a hot-join event. Treat enumeration and error recovery as first-class logic, not an afterthought.

Migration Strategy: From I2C to I3C

If you are already shipping products on I2C, I3C adoption usually happens incrementally:

  • Start with the controller: verify your MCU/SoC actually has an I3C controller (not just "fast I2C").
  • Pick one I3C-capable target: add a single I3C sensor on an otherwise familiar bus and validate enumeration (DAA), drivers, and bus monitoring.
  • Keep legacy devices where it makes sense: EEPROMs and simple peripherals are often still fine on I2C. Use I3C where its features remove real system cost.
  • Refactor interrupt wiring: if you adopt IBI, you can often delete multiple GPIOs, simplify routing, and reduce connector pin count.

FAQ (Engineers Ask These First)

Can I put I2C and I3C devices on the same bus?

Yes, that is a core I3C design goal. In practice, your controller must manage compatibility constraints (timing, signaling, and which features are safe to use) when legacy I2C devices are present.

Do I still need pull-up resistors?

Not in the I2C sense. SCL is driven push-pull by the controller and needs no pull-up. SDA needs a pull-up during open-drain phases, but that is a structure the controller enables and disables (often internal). Read your controller datasheet to see whether it expects an external resistor and which value; do not size it with an I2C rise-time calculation.

Can I debug I3C with an I2C logic analyzer?

Sometimes you can see the electrical activity, but decoding is usually incomplete: I3C uses additional protocol features and signaling behavior that basic I2C decoders do not understand. For serious debugging, use an analyzer or software stack that explicitly supports I3C.

References & Further Reading

  • MIPI Alliance: I3C and I3C Basic specifications and overview material.
  • MCU/SoC reference manuals: look for the "I3C controller" peripheral chapter, especially enumeration (DAA), CCC support, and IBI handling.
  • Sensor datasheets: confirm whether a device supports I3C, I3C Basic, or I2C-only operation, and what features (IBI, dynamic addressing) are actually implemented.

Related resources