4、MIPI DSI协议:DSI命令模式与视频模式、DSI数据包格式(长包/短包)、DSI虚拟通道

MIPI DSI 协议,说白了就是屏幕和主控之间的“对话规则”。你想想看,一块显示屏要刷新画面,主控得把像素数据送过去。怎么送?什么时候送?送错了怎么办?这些都由 DSI 协议来管。

我个人习惯把 DSI 协议拆成三个维度来理解:传输模式(命令 vs 视频)、数据打包方式(长包 vs 短包)、通道复用(虚拟通道)。这三个维度搞清楚了,驱动移植时遇到的大部分问题都能找到根因。

4.1 命令模式 vs 视频模式:两种“说话”方式

DSI 定义了两种操作模式,区别在于谁控制刷新节奏。

特性 命令模式 视频模式
刷新控制方 主控发送命令,屏幕内部驱动 IC 自行刷新 主控实时发送像素流,屏幕被动接收
是否需要帧缓冲 屏幕端通常自带 GRAM(显存) 屏幕端无显存,必须持续接收数据
典型应用 小尺寸屏(手表、IoT 设备) 大尺寸屏(手机、平板、车载)
功耗 低(可局部刷新、进入休眠) 高(必须持续传输)
实现复杂度 驱动端需要管理命令队列 驱动端需要精确时序同步

命令模式:主控发一条“写像素”命令,屏幕 IC 自己把数据存到内部 GRAM 里,然后按自己的节奏刷新。我在做智能手表驱动时遇到过一个问题——屏幕刷新率只有 30Hz,但主控发命令的速度远高于这个频率。结果呢?GRAM 写太快,屏幕读太慢,画面撕裂。解决办法是在命令之间插入 DCS Read 命令查询 TE(Tearing Effect)信号,等屏幕准备好再发下一帧。

视频模式:主控必须按行同步(HSYNC)和帧同步(VSYNC)的节奏,把像素数据一字节不差地送过去。屏幕没有缓存,你送慢了它就黑屏,送快了它就花屏。嗯,这里要注意:视频模式下 DSI 时钟必须和像素时钟严格匹配,差 1% 都不行。

关键判断依据:如果你的屏幕规格书里提到“GRAM”或“Frame Memory”,那多半是命令模式。如果只提“HSYNC/VSYNC/DE”时序参数,那就是视频模式。

4.2 DSI 数据包格式:长包与短包

DSI 协议里,所有数据都打包传输。包分两种:短包和长包。区别很简单——短包只有 4 字节,长包可以很长(最长 65541 字节)。

4.2.1 短包(Short Packet)

短包固定 4 字节:

字节 0: 数据标识符(DI, Data Identifier)
  - bit[7:6]: 虚拟通道号(VC)
  - bit[5:0]: 数据类型(DT)
字节 1: 数据低字节(Data Low)
字节 2: 数据高字节(Data High)
字节 3: 校验和(ECC, Error Correction Code)

短包用来干什么?发命令、读寄存器、设置参数。比如你想让屏幕进入休眠模式,发一个短包,数据类型设为 DCS Short Write,数据字节填 0x10(Sleep In 命令)。

我曾经踩过一个坑:ECC 校验位算错了。DSI 控制器硬件会自动计算 ECC,但如果你用 GPIO 模拟 DSI(有些低端 MCU 这么干),ECC 必须自己算。算错一个 bit,接收端直接丢弃包,屏幕没反应。我当时查了三天,最后用逻辑分析仪抓波形才发现 ECC 不对。

4.2.2 长包(Long Packet)

长包结构稍微复杂一点:

+----------------+----------------+------------------+------------------+----------------+
| 包首(4字节)   | 数据负载        | 校验和(2字节)    | 包尾              |
| DI + WC(2字节) + ECC | (0~65541字节) | (Checksum)       | (停止状态)        |
+----------------+----------------+------------------+------------------+----------------+

其中:

  • DI:数据标识符,同短包
  • WC(Word Count):数据负载的字节数,2 字节
  • ECC:对包首 3 字节做校验
  • 数据负载:真正的像素数据或命令参数
  • Checksum:对数据负载做 16 位 CRC

长包用来传输大量数据,比如一帧图像、一块颜色查找表(LUT)。我建议你在驱动初始化时,用长包一次性把屏幕的初始化序列(Initial Code)发过去,比一条条发短包快得多。

实用技巧:长包的 Checksum 是可选的。如果你的 DSI 控制器硬件不支持自动计算 CRC,可以把 Checksum 设为 0x0000,接收端会忽略校验。但注意——这只适用于调试阶段,量产时一定要开校验。

4.3 DSI 虚拟通道:一条总线,多个设备

虚拟通道(Virtual Channel, VC)是 DSI 协议里一个很巧妙的设计。它允许在同一条物理 DSI 总线上,同时传输多个不同设备的数据。

VC 号占用 DI 字节的最高 2 个 bit,所以取值范围是 0~3,一共 4 个虚拟通道。

VC 号 典型用途 示例
VC0 主显示屏 手机主屏
VC1 副显示屏 折叠屏的副屏
VC2 触控数据 内嵌触控的显示面板
VC3 调试/诊断 工厂测试模式

你想想看,如果一块屏幕同时要显示画面、接收触控数据、还要跑诊断命令,没有虚拟通道的话,你得拉三条物理 DSI 总线。有了 VC,一条总线就够了,接收端根据 VC 号把数据分发给不同的处理单元。

我在做双屏手机驱动时用过 VC。主屏用 VC0,副屏用 VC1,两个屏幕共用同一组 DSI 时钟和数据线。驱动里只需要在发送每个包之前设置好 VC 号,硬件自动把数据路由到对应的屏幕。嗯,这里有个坑:两个屏幕的时序参数可能不一样,切换 VC 时要注意重新配置 DSI 控制器的时序寄存器。

注意:虚拟通道只是逻辑上的复用,物理层仍然是同一组差分线。如果两个 VC 的数据速率加起来超过了 DSI 总线的最大带宽,就会出现丢包。我建议你在设计阶段就估算好总带宽,留出 20% 的余量。

4.4 三种模式的关系与选择

命令模式/视频模式、长包/短包、虚拟通道,这三者不是互斥的,而是可以组合使用的。比如:

  • 视频模式下,像素数据用长包传输,配置命令用短包传输
  • 命令模式下,写 GRAM 用长包,读状态用短包
  • 虚拟通道可以在任何模式下使用

我一般这样选型:

  • 低功耗、小尺寸 → 命令模式 + 短包为主 + VC0
  • 高刷新率、大尺寸 → 视频模式 + 长包为主 + VC0~VC1
  • 多设备复用 → 任意模式 + 合理分配 VC 号
DSI 协议核心概念关系图 DSI 协议 传输模式 数据包格式 虚拟通道 命令模式 视频模式 短包 长包 VC0~VC3 关键说明: • 命令模式:主控发命令,屏幕自带 GRAM,适合低功耗小尺寸 • 视频模式:主控实时发像素流,屏幕无缓存,适合高刷大尺寸 • 短包:4 字节固定长度,用于命令/读寄存器 • 长包:可变长度(最长 65541 字节),用于像素/批量数据 • 虚拟通道:一条物理总线复用 4 个逻辑通道(VC0~VC3)

最后说一句:DSI 协议看起来复杂,但实际驱动开发中,你只需要关注三件事——选对模式(看屏幕规格书)、打包正确(长包短包别搞混)、VC 别冲突(多设备时分配好)。剩下的,DSI 控制器硬件和驱动框架会帮你处理大部分细节。