I3C 协议栈:命令、数据、响应、仲裁
如果你做过 I2C 项目,再看 I3C 协议栈,第一感觉就是——它还是那个熟悉的两线制框架,但里子已经彻底重构了。我个人习惯把 I3C 协议栈拆成四个核心环节:命令、数据、响应、仲裁。这四个环节环环相扣,你在 PCB 布线时遇到的大部分信号完整性问题,都能从这里面找到根因。
1. 命令阶段:CCC 与私有命令
I3C 的命令分两大类:通用命令代码(CCC) 和 私有命令。CCC 是协议规定的广播或定向指令,比如动态地址分配(ENTDAA)、设置 IBI 使能等。私有命令则是主设备和特定从设备之间的“私聊”。
命令的发送格式,说白了就是一个 8 位地址 + 读/写位 + ACK 位。但跟 I2C 有个巨大区别:I3C 的地址是 7 位,而且从设备地址可以在运行时动态改。这也是“动态地址分配”能玩起来的基础。
| 命令类型 | 地址域 | 数据方向 | 典型场景 |
|---|---|---|---|
| CCC 广播 | 7’h7E | 写 | ENTDAA、RSTDAA |
| CCC 定向 | 目标从地址 | 写 / 读 | SETDASA、GETACCCR |
| 私有命令 | 目标从地址 | 写 / 读 | 传感器数据读取、寄存器配置 |
2. 数据阶段:SDR 与 HDR 的取舍
数据阶段是协议栈的“体力活”。I3C 支持两种数据传输模式:单倍数据率(SDR) 和 高倍数据率(HDR)。SDR 向后兼容 I2C 传统模式,每个 SCL 时钟传 1 位;HDR 则能在一个时钟内传 2 位甚至更多。
你可能会问:“那我全部用 HDR 不就好了?” 没那么简单。HDR 对布线要求高得多。我做过一个项目,为了赶速度把相机模块配成 HDR 模式,结果信号在 10cm 的 PCB 走线上就跑飞了。波形上冲下冲明显,数据校验总是出错。最后老老实实切回 SDR,虽然带宽降了一半,但稳如老狗。
3. 响应阶段:ACK/NACK 的黄金法则
命令和数据发出去之后,从设备必须给个回应——这就是响应阶段。每个字节传输结束后,接收方在第 9 个 SCL 时钟周期拉低 SDA 表示 ACK,保持高则表示 NACK。
I3C 有个巧妙的设计:NACK 不仅仅是“我不认”,它还能携带状态信息。比如从设备忙,就 NACK 主设备的后续读写;主设备在 CCC 过程中发现没有设备响应,也会 NACK 并结束本次传输。
- 收到 ACK → 继续传下一个字节
- 收到 NACK → 主设备发 STOP 或重复 START
- 广播命令的 NACK 处理:任何从设备都可以 NACK 来拒绝广播
我在调试一块温度传感器时,发现主设备读温度值总是读到 0xFF。示波器一看,从设备在第 9 时钟拉了 NACK,主设备没正确处理,直接把上一帧的残余数据当有效数据用了。那是我第一次意识到:NACK 后的收尾时序必须严格按协议走,否则数据会“串味”。
4. 仲裁阶段:谁抢到总线谁说话
仲裁是 I3C 协议栈里最有趣的部分。I2C 的仲裁是基于“线与”逻辑,谁拉低 SDA 谁赢。I3C 保留了这套机制,但增加了 主设备之间的主动仲裁。比如两个主设备同时想发命令,它们会在 START 之后的地址阶段角逐——地址更低的一方会获胜(因为 SDA 是开漏,拉低优先)。
但注意:I3C 的仲裁 只发生在 SDR 模式。HDR 模式下不允许多主争抢,必须由当前主设备主动交出控制权。这个细节很多人不知道,结果在 HDR 总线上一接两个主设备,直接就死锁了。
5. 协议栈与布线的映射关系
学完这四个环节,你在画 PCB 时就要带着“场景”去布。比如:
- 命令阶段:地址位的上升/下降时间要匹配 I3C 的时序容限(通常 SCL 频率 12.5MHz 时,tr/tf ≤ 20ns)。我的做法是在 SCL 和 SDA 上各串一个 22Ω 电阻,既能限流又能抑制过冲。
- 数据阶段:HDR 模式要求走线阻抗控制在 50Ω ± 10%,差分对?不,I3C 是单端线,但你要把 SCL 和 SDA 的走线长度控制在 ±5% 以内。否则数据建立时间会出问题。
- 响应阶段:从设备拉低 SDA 给出 ACK 的时刻,正是总线电平最低、噪声最敏感的时间点。旁边有 DC-DC 的话,容易把 ACK 误判成 NACK。我吃过这个亏,后来把 I3C 总线跟电源层用 GND 隔了一个完整的地平面。
- 仲裁阶段:多主系统的 PCB 上,每个主设备的 SDA 脚要加独立的上拉电阻(通常 2.2kΩ 左右),否则仲裁时主设备之间的拉电流会打架,导致信号畸变。