2. MIPI CSI-2 接口协议:物理层、协议层与 Lane 速率计算
MIPI CSI-2,说白了就是摄像头和处理器之间的「普通话」。没有它,Sensor 再牛,数据也传不过去。我刚开始调图像的时候,总觉得协议是协议,驱动是驱动,各管各的。后来被一个「花屏」问题折腾了两周,才发现是 Lane 速率算错了。嗯,从那以后,我再也不敢小看这个接口了。
这一章,我们就把 CSI-2 拆开揉碎。从物理层的 D-PHY 和 C-PHY,到协议层的长包短包,再到虚拟通道和速率计算,一条线捋清楚。
2.1 物理层:D-PHY 与 C-PHY
物理层负责把 0 和 1 变成电信号,在线上跑。MIPI 联盟定义了两套物理层标准:D-PHY 和 C-PHY。目前绝大多数 Sensor 用的还是 D-PHY,但 C-PHY 在高端手机上越来越常见。
2.1.1 D-PHY:差分信号,简单可靠
D-PHY 用一对差分线(Dp/Dn)传输一个 Lane。差分信号抗干扰能力强,这是它的核心优势。每个 Lane 包含两条线:正极(Dp)和负极(Dn)。信号通过两者的电压差来表示。
D-PHY 有两种工作模式:高速模式(HS)和低功耗模式(LP)。
- HS 模式:差分信号,电压摆幅约 200mV,速率可达 80 Mbps 到 4.5 Gbps(D-PHY v2.5)。用于传输图像数据。
- LP 模式:单端信号,电压摆幅约 1.2V,速率约 10 Mbps。用于传输控制指令(比如唤醒、休眠)。
2.1.2 C-PHY:三线传输,带宽翻倍
C-PHY 用三根线(A/B/C)组成一个 Lane。它不靠差分,而是靠三线之间的电压关系来编码。每个符号可以传输 2.28 bit 数据,带宽利用率比 D-PHY 高。
简单对比一下:
| 特性 | D-PHY | C-PHY |
|---|---|---|
| 每 Lane 线数 | 2(Dp/Dn) | 3(A/B/C) |
| 信号方式 | 差分 | 三线电压关系 |
| 每符号比特 | 1 bit | 2.28 bit |
| 典型速率 | 2.5 Gbps/Lane | 5.7 Gbps/Lane(等效) |
| 应用场景 | 主流 Sensor | 高端手机、高帧率 |
我个人习惯,在项目初期先确认平台支持哪种 PHY。有些 SoC 只支持 D-PHY,强行上 C-PHY 的 Sensor 就得加桥接芯片,成本和功耗都上去了。
2.2 协议层:长包与短包
物理层把比特流送过来,协议层负责「解读」这些比特。CSI-2 协议层定义了两种包:短包(Short Packet)和长包(Long Packet)。
2.2.1 短包:控制信息
短包只有 32 位,不包含数据负载。它用来传递控制信息,比如帧开始(FS)、帧结束(FE)、行开始(LS)、行结束(LE)。
短包的结构很简单:
- 数据标识符(DI):8 位,包含虚拟通道 ID 和数据类型。
- 数据值(Data Value):16 位,具体控制信息。
- ECC:8 位,纠错码。
2.2.2 长包:图像数据
长包包含数据负载,也就是我们真正关心的像素数据。它的结构分为三部分:
- 包首(Packet Header):32 位,包含 DI、字计数(WC)、ECC。
- 数据负载(Data Payload):可变长度,存放像素数据。
- 包尾(Packet Footer):16 位 CRC,校验数据完整性。
这里有个容易踩的坑:字计数(WC) 的单位是字节,不是像素。比如一个 1920×1080 的 RAW10 图像,每像素 10 位,需要 5 个字节存 4 个像素。WC 应该是 (1920×1080×10) / 8 = 2,592,000 字节。我曾经见过有人直接写 1920×1080,结果接收端解析出来的图像全是乱的。
2.3 虚拟通道:多路复用
虚拟通道(Virtual Channel,VC)允许在同一个 CSI-2 链路上传输多路数据流。每个数据包都带有 VC ID(0~3),接收端根据 VC ID 把数据分发到不同的处理模块。
举个例子:一个双摄模组,主摄和副摄共用同一个 CSI-2 接口。主摄的数据包打上 VC=0,副摄打上 VC=1。接收端根据 VC ID 分别处理,互不干扰。
虚拟通道的配置通常在 Sensor 的寄存器里完成。我建议在驱动初始化时,明确设置每个 VC 的数据类型和格式,避免混淆。
| VC ID | 数据类型 | 分辨率 | 帧率 |
|---|---|---|---|
| 0 | RAW10 | 1920×1080 | 30 fps |
| 1 | YUV422 8-bit | 640×480 | 30 fps |
| 2 | RAW10 | 1280×720 | 60 fps |
| 3 | 未使用 | - | - |
2.4 Lane 速率计算与调试
这是调试中最常碰到的环节。Lane 速率算不对,图像要么出不来,要么全是噪点。
2.4.1 计算公式
Lane 速率(Mbps)的计算公式如下:
Lane Rate = (Width × Height × Frame Rate × Bits per Pixel) / (Number of Lanes × 2)
为什么要除以 2?因为 D-PHY 是 DDR(双倍数据率),每个时钟周期传输 2 位数据。
举个例子:
- 分辨率:1920×1080
- 帧率:30 fps
- 位深:10 bit
- Lane 数:4
计算过程:
Lane Rate = (1920 × 1080 × 30 × 10) / (4 × 2)
= 622,080,000 / 8
= 77,760,000 bps
= 777.6 Mbps
所以,每条 Lane 需要跑 777.6 Mbps。实际选择时,我会留 10%~20% 的余量,比如选 900 Mbps 或 1 Gbps。
2.4.2 调试步骤
调试 Lane 速率时,我一般按这个顺序来:
- 确认 Sensor 支持的速率范围:查 Datasheet,找到 PLL 配置表。
- 计算理论速率:用上面的公式算一遍。
- 配置 PLL:在 Sensor 驱动中设置分频系数,使输出速率接近理论值。
- 用示波器测量:抓 HS 模式下的眼图,看信号质量。
- 调整驱动强度:如果眼图不好,调整 Sensor 的输出驱动强度或 SoC 的接收端均衡。
2.5 知识结构图
下面这张图把 CSI-2 的核心层次和关键要素串起来了。你可以把它当作调试时的「地图」。
2.6 调试实战:一个真实案例
我记得有一次,客户反馈一款 13M Sensor 在 4 Lane 下跑 30fps 时,图像上半部分正常,下半部分全是条纹。
排查过程:
- 先看速率:计算理论速率是 1.2 Gbps/Lane,Sensor 配置的是 1.5 Gbps。余量够,排除速率不足。
- 再看眼图:用示波器抓 Lane 0 的眼图,发现眼张开度只有 40%,明显偏小。
- 调整驱动强度:把 Sensor 的输出驱动强度从 100% 降到 80%,眼图张开度提升到 65%。
- 验证:重新抓图,图像正常。
这个案例说明,速率算对了,不代表信号质量没问题。眼图是最终的「照妖镜」。