4. CSI-2 数据包格式:长包与短包结构
MIPI CSI-2 协议在 D-PHY 物理层之上定义了分层的数据包传输机制。所有图像数据、控制信息与错误检测均通过两种基本包结构完成:短包 (Short Packet) 和 长包 (Long Packet)。理解这两种包的格式是设计 CSI-2 接收端 DMA 控制器的前提。
4.1 短包 (Short Packet) 结构
短包用于传输帧同步、行同步以及事件触发等控制信息。其长度固定为 4 字节,不携带图像数据负载。
| 字段 | 位宽 (bits) | 描述 |
|---|---|---|
| Data ID | 8 | 虚拟通道标识 (VC, [7:6]) + 数据类型 (DT, [5:0]) |
| Word Count (WC) | 16 | 短包数据字段(通常用于传递帧号或行号) |
| ECC | 8 | 前 24 位的纠错码,支持单比特纠错与双比特检测 |
设计要点: 短包中的 Word Count 字段在帧开始包 (FS) 中通常为帧号,在行开始包 (LS) 中为行号。接收端 DMA 控制器应解析此字段以重建帧同步信号。
短包传输流程:
- 发送端通过 D-PHY 发送 SoT (Start of Transmission) 序列。
- 连续发送 4 字节短包数据:Data ID → WC (低字节) → WC (高字节) → ECC。
- 发送 EoT (End of Transmission) 序列。
- 接收端 ECC 模块校验前 3 字节,若检测到单比特错误则自动纠正。
4.2 长包 (Long Packet) 结构
长包用于传输像素数据、嵌入式数据块等负载。其结构包含包头 (Packet Header, PH)、数据负载 (Payload) 和包尾 (Packet Footer, PF)。
| 字段 | 位宽 (bits) | 描述 |
|---|---|---|
| Packet Header (PH) | 32 | Data ID (8 bits) + Word Count (16 bits) + ECC (8 bits) |
| Payload | 可变 | 像素数据或嵌入式数据,长度由 Word Count 指定 (0~65535 字节) |
| Packet Footer (PF) | 16 | CRC-16 校验码,覆盖整个 Payload |
关键约束: 长包的数据负载长度必须为偶数个字节。若原始数据为奇数,发送端需在末尾填充一个额外字节(通常为 0x00),但 Word Count 仍记录原始数据长度。接收端 DMA 需根据数据类型判断是否需要丢弃填充字节。
4.3 包头 (Header) 与包尾 (Footer) 字段解析
4.3.1 Data ID 字段
Data ID 是包头的第一个字节,由高 2 位的虚拟通道标识 (Virtual Channel, VC) 和低 6 位的数据类型 (Data Type, DT) 组成。
- VC[1:0]:支持最多 4 个虚拟通道 (VC0~VC3),用于在同一物理链路上复用多路摄像头数据流。
- DT[5:0]:定义负载数据的格式与内容,常见值包括:
0x00:帧开始 (Frame Start, FS)0x01:帧结束 (Frame End, FE)0x02:行开始 (Line Start, LS)0x03:行结束 (Line End, LE)0x1E:嵌入式 8 位数据 (Embedded 8-bit Data)0x2A~0x2F:YUV 420 格式0x30~0x37:RGB 格式0x40~0x4F:RAW 格式 (RAW6/RAW7/RAW8/RAW10/RAW12/RAW14/RAW16/RAW20)
4.3.2 Word Count (WC) 字段
对于长包,WC 表示数据负载的字节数(不包括包头和包尾)。对于短包,WC 用于传递控制信息(如帧号或行号)。
DMA 设计提示: 接收端 DMA 控制器必须从包头中提取 WC 值,以确定本次传输需要从 FIFO 中读取多少字节到系统内存。WC 值为 0 表示空负载长包,通常用于同步或测试目的。
4.3.3 ECC (Error Correction Code) 字段
ECC 是包头中的最后一个字节,采用汉明码 (Hamming Code) 对前 24 位(Data ID + WC)进行保护。
- 纠错能力:单比特错误纠正 (SEC),双比特错误检测 (DED)。
- 生成多项式:基于 (24, 16) 汉明码扩展,增加一个全局偶校验位。
- 硬件实现:在 FPGA 中通常使用组合逻辑实现 ECC 校验矩阵,延迟仅 1~2 个时钟周期。
// ECC 校验伪代码 (Verilog 风格)
// 输入: data_id[7:0], wc[15:0]
// 输出: ecc_expected[7:0]
assign ecc_expected[0] = data_id[0] ^ data_id[1] ^ data_id[3] ^ data_id[4] ^ wc[0] ^ wc[2] ^ wc[4] ^ wc[6] ^ wc[8] ^ wc[10] ^ wc[12] ^ wc[14];
assign ecc_expected[1] = data_id[0] ^ data_id[2] ^ data_id[3] ^ data_id[5] ^ wc[1] ^ wc[2] ^ wc[5] ^ wc[6] ^ wc[9] ^ wc[10] ^ wc[13] ^ wc[14];
// ... 其余位类似
assign ecc_expected[6] = ^(data_id ^ wc[15:0]); // 全局偶校验
assign ecc_expected[7] = 1'b0; // 保留位
4.3.4 CRC (Cyclic Redundancy Check) 字段
包尾的 CRC-16 校验码覆盖整个数据负载区域,用于检测传输过程中的比特错误。
| 参数 | 值 |
|---|---|
| 多项式 | x^16 + x^12 + x^5 + 1 (0x1021) |
| 初始值 | 0x0000 |
| 输入反转 | 否 |
| 输出反转 | 否 |
| 输出异或 | 0x0000 |
工程陷阱: 某些传感器厂商实现的 CRC 可能采用不同的初始值或反转配置。在集成第三方 IP 时,务必通过数据手册确认 CRC 参数,否则可能导致校验失败。
4.4 ECC 与 CRC 校验的协同工作
在 CSI-2 接收链路中,ECC 和 CRC 分别保护不同的数据区域,形成分层错误检测机制:
- ECC:保护包头 (PH) 的 3 个字节,确保 WC 值正确解析。若 ECC 校验失败且无法纠正,接收端应丢弃整个长包。
- CRC:保护数据负载 (Payload),确保像素数据完整性。CRC 错误通常触发重传请求或错误标记。
硬件优化建议: 在 FPGA 实现中,ECC 校验和 CRC 校验可以流水线并行处理。当 ECC 正在校验包头时,CRC 引擎可以开始计算前导数据的校验值,从而减少整体延迟。对于高速应用(如 4-lane 2.5 Gbps),建议使用 CRC 查找表 (LUT) 或并行 CRC 实现以满足时序要求。