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。用于传输控制指令(比如唤醒、休眠)。
我的经验:调试时,如果发现 Sensor 无法进入 HS 模式,先别急着查寄存器。用示波器看 LP→HS 的切换时序,很多问题出在「准备时间」不够。我曾经遇到过一款 Sensor,它的 LP-11 状态维持时间比标准短了 50 ns,导致接收端无法正确识别。

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 位,纠错码。
关键点:短包没有 CRC,只有 ECC。ECC 能纠正 1 位错误,检测 2 位错误。如果 ECC 校验失败,接收端会丢弃这个包。

2.2.2 长包:图像数据

长包包含数据负载,也就是我们真正关心的像素数据。它的结构分为三部分:

  1. 包首(Packet Header):32 位,包含 DI、字计数(WC)、ECC。
  2. 数据负载(Data Payload):可变长度,存放像素数据。
  3. 包尾(Packet Footer):16 位 CRC,校验数据完整性。

这里有个容易踩的坑:字计数(WC) 的单位是字节,不是像素。比如一个 1920×1080 的 RAW10 图像,每像素 10 位,需要 5 个字节存 4 个像素。WC 应该是 (1920×1080×10) / 8 = 2,592,000 字节。我曾经见过有人直接写 1920×1080,结果接收端解析出来的图像全是乱的。

避坑指南:我曾经调试一个 4K 30fps 的 Sensor,发现图像偶尔出现「撕裂」。抓包分析后发现,长包的 CRC 校验失败率高达 5%。最后定位到是 PCB 走线太长,信号质量下降。解决办法是降低 Lane 速率,或者增加 Lane 数量。

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 速率时,我一般按这个顺序来:

  1. 确认 Sensor 支持的速率范围:查 Datasheet,找到 PLL 配置表。
  2. 计算理论速率:用上面的公式算一遍。
  3. 配置 PLL:在 Sensor 驱动中设置分频系数,使输出速率接近理论值。
  4. 用示波器测量:抓 HS 模式下的眼图,看信号质量。
  5. 调整驱动强度:如果眼图不好,调整 Sensor 的输出驱动强度或 SoC 的接收端均衡。
我的习惯:调试时,先用最低速率(比如 200 Mbps)验证链路通不通。通了之后,再逐步提高速率。这样能快速定位是「链路问题」还是「速率问题」。

2.5 知识结构图

下面这张图把 CSI-2 的核心层次和关键要素串起来了。你可以把它当作调试时的「地图」。

MIPI CSI-2 协议栈 应用层(图像数据) 协议层 长包(数据) | 短包(控制) | 虚拟通道(VC 0~3) 物理层 D-PHY(差分) | C-PHY(三线) | HS/LP 模式 电气层(信号/时序) 调试关键:Lane 速率计算 → PLL 配置 → 眼图测量 → 驱动强度调整 常见问题:花屏(速率不足)、撕裂(CRC 错误)、无图(LP→HS 切换失败)

2.6 调试实战:一个真实案例

我记得有一次,客户反馈一款 13M Sensor 在 4 Lane 下跑 30fps 时,图像上半部分正常,下半部分全是条纹。

排查过程:

  1. 先看速率:计算理论速率是 1.2 Gbps/Lane,Sensor 配置的是 1.5 Gbps。余量够,排除速率不足。
  2. 再看眼图:用示波器抓 Lane 0 的眼图,发现眼张开度只有 40%,明显偏小。
  3. 调整驱动强度:把 Sensor 的输出驱动强度从 100% 降到 80%,眼图张开度提升到 65%。
  4. 验证:重新抓图,图像正常。

这个案例说明,速率算对了,不代表信号质量没问题。眼图是最终的「照妖镜」。

警告:不要盲目提高驱动强度。驱动强度太大,会导致信号过冲,反而恶化眼图。我一般从 80% 开始试,逐步调整。