4、MIPI CSI-2协议详解:D-PHY、速率计算与包格式
MIPI CSI-2,说白了就是摄像头和处理器之间的“普通话”。你传感器采集到的原始数据,得通过它才能规规矩矩地传给 ISP。我刚开始调摄像头时,总觉得这层协议太抽象,直到拿着示波器去抓波形,才真正明白它到底在干什么。
这一章,咱们就把 CSI-2 的物理层、速率、模式切换、包结构这些硬骨头啃下来。嗯,都是实战中绕不开的东西。
4.1 D-PHY 物理层:差分信号与 Lane 结构
CSI-2 的物理层用的是 D-PHY。它靠差分信号传输,就是一对线(Dp/Dn)传一个信号。好处很明显——抗干扰能力强,速率也能跑得高。
一个 D-PHY 链路包含三部分:
- Clock Lane:时钟通道,必须得有,给数据做同步。
- Data Lane:数据通道,可以 1 条、2 条、4 条,甚至更多。
- LP(Low Power)与 HS(High Speed)模式:同一组线,两种玩法。
我在项目中遇到过一个问题:某款 sensor 在 4-lane 模式下死活出图不稳定,后来发现是 PCB 走线没等长,导致 lane 之间 skew 太大。所以 layout 阶段,D-PHY 的差分对一定要等长、包地、远离时钟源。
4.2 Lane 速率计算:从 PCLK 到 Bit Rate
很多工程师搞不清 sensor 的输出速率到底怎么算。我习惯用一个公式:
Bit Rate per Lane = (PCLK × Bits per Pixel × Frame Width × Frame Height × Frame Rate) / Number of Lanes
举个例子:一个 1080p 的 sensor,30fps,10bit RAW,PCLK 是 74.25MHz,用 4-lane 输出。
Bit Rate = (74.25 × 10 × 1920 × 1080 × 30) / 4
≈ 1.15 Gbps/lane
这个值必须在 D-PHY 的规范范围内。D-PHY v1.2 单 lane 最高能到 2.5 Gbps,v2.0 能到 4.5 Gbps。你算出来如果超了,就得加 lane 或者降帧率。
| D-PHY 版本 | 单 Lane 最大速率 | 典型应用 |
|---|---|---|
| v1.1 | 1.0 Gbps | 老款 sensor,VGA/720p |
| v1.2 | 2.5 Gbps | 主流 1080p/4K sensor |
| v2.0 | 4.5 Gbps | 高端 8K/多摄模组 |
4.3 LP/HS 模式切换:总线状态机
D-PHY 的物理层有两种工作模式:
- LP 模式:低功耗,低速,用于控制指令和总线初始化。
- HS 模式:高速,用于传输图像数据。
模式切换靠的是总线状态机。D-PHY 定义了 4 种 LP 状态:
- LP-00:Dp=0, Dn=0,总线空闲
- LP-01:Dp=0, Dn=1,HS 请求
- LP-10:Dp=1, Dn=0,HS 准备
- LP-11:Dp=1, Dn=1,停止状态
从 LP 切到 HS 的流程是这样的:
- 总线处于 LP-11(停止)
- 发送 LP-01(HS 请求)
- 发送 LP-00(桥接状态)
- 进入 HS 模式,开始传数据
- 传完后发 LP-11 回到停止
这个切换过程大概需要 100ns 左右。你想想看,如果每帧数据都要切一次,这个开销其实不小。所以 sensor 一般会在一帧内连续传多个包,减少切换次数。
4.4 长包与短包格式:Packet 结构拆解
CSI-2 的数据传输以包为单位。包分两种:
- 短包(Short Packet):只有包头,没有数据体。用于帧同步、行同步等控制。
- 长包(Long Packet):有包头、数据体、包尾。用于传输图像数据。
咱们先看短包格式:
| Data ID (1B) | Word Count (2B) | ECC (1B) |
| 0x2A | 0x0001 | 0xXX |
Data ID 的高 2 位是 Virtual Channel,低 6 位是数据类型。比如 0x2A 表示帧起始(Frame Start)。
长包格式稍微复杂一点:
| Data ID (1B) | Word Count (2B) | ECC (1B) | Data (N Bytes) | CRC (2B) |
| 0x2B | 0x0A00 | 0xXX | [像素数据...] | 0xXXXX |
Word Count 表示数据体的字节数。注意,它是 16 位的,所以单包最大能传 65535 字节。如果一行的像素数超过这个值,就得拆成多个包。
我在调 4K sensor 时就遇到过这个问题——一行 4096 个像素,每个像素 10bit,算下来一行 5120 字节,一个包装不下。解决方案是把一行拆成两个包,或者用 4-lane 交错传输。
4.5 ECC 与 CRC 校验:数据完整性保障
高速传输中,数据出错是难免的。CSI-2 用了两种校验机制:
- ECC(Error Correction Code):用于保护包头,能纠正 1bit 错误,检测 2bit 错误。
- CRC(Cyclic Redundancy Check):用于保护数据体,只能检测错误,不能纠正。
ECC 的计算方式是基于汉明码的。我一般不会手算,但得知道它的原理:
ECC[0] = DataID[0] ^ DataID[1] ^ DataID[3] ^ DataID[4] ^ WC[0] ^ WC[1] ^ WC[3] ^ WC[4]
ECC[1] = DataID[0] ^ DataID[2] ^ DataID[3] ^ DataID[5] ^ WC[0] ^ WC[2] ^ WC[3] ^ WC[5]
ECC[2] = DataID[1] ^ DataID[2] ^ DataID[3] ^ WC[1] ^ WC[2] ^ WC[3]
ECC[3] = DataID[4] ^ DataID[5] ^ WC[4] ^ WC[5]
ECC[4] = DataID[0] ^ DataID[1] ^ DataID[2] ^ DataID[3] ^ DataID[4] ^ DataID[5] ^ WC[0] ^ WC[1] ^ WC[2] ^ WC[3] ^ WC[4] ^ WC[5]
ECC[5] = ECC[0] ^ ECC[1] ^ ECC[2] ^ ECC[3] ^ ECC[4] ^ DataID[0] ^ DataID[1] ^ DataID[2] ^ DataID[3] ^ DataID[4] ^ DataID[5] ^ WC[0] ^ WC[1] ^ WC[2] ^ WC[3] ^ WC[4] ^ WC[5]
CRC 用的是 CRC-16-CCITT 多项式:x^16 + x^12 + x^5 + 1。接收端会重新计算 CRC,跟包尾的 CRC 比对,不一致就说明数据出错了。
4.6 Virtual Channel:多路复用
Virtual Channel(VC)是 CSI-2 的一个很实用的特性。它允许在同一个物理链路上传输多路数据流。比如双摄模组,两个 sensor 可以共用同一组 D-PHY lane。
VC 的编号是 0~3,共 4 个通道。它在 Data ID 的高 2 位里编码:
| VC 编号 | Data ID 高 2 位 | 示例 |
|---|---|---|
| VC0 | 00 | 主摄 |
| VC1 | 01 | 广角 |
| VC2 | 10 | 深度 |
| VC3 | 11 | 预留 |
接收端(比如 ISP)会根据 VC 编号把数据分发到不同的处理通道。这样,一条 MIPI 总线就能同时传多路图像,省掉了额外的硬件接口。
我调过一个双摄模组,两个 sensor 共用 4-lane,每个 sensor 分 2-lane。配置时要注意:两个 sensor 的帧率必须同步,否则 VC 数据会乱掉。解决方案是用同一个 MCLK 和 XSHUTDOWN 信号来控制两个 sensor。