不知道你是不是也经常卡在这种局面上:手里有一块屏,点亮了却显示异常,怀疑是初始化寄存器没配对;或者想确认刷新率算对没有,可是规格书写的时序和驱动源码完全对不上。排这类显示问题,绕不开的就是MIPI-DSI总线。这篇教程,我想扎扎实实写一次用逻辑分析仪抓取并解析MIPI-DSI信号的全过程,重点放在HS/LP模式波形分析上,让你看完就能自己动手复现一遍。
先说清楚这东西能干什么。逻辑分析仪不是示波器,它不看模拟电压,只采数字电平。但DSI总线的LP模式本来就是单端1.2V的数字信号,逻辑分析仪完全可以直接抓、直接解码;HS模式虽然是小信号差分,逻辑分析仪照样能用来测时序边界和传输包络。所以我平时的调试策略是:逻辑分析仪负责协议层和时序验证,示波器负责物理层波形质量。这篇文章主要讲前者,适合嵌入式驱动工程师、硬件工程师、以及正在调显示面板的底层开发者参考。
1. 开始之前:先搞懂DSI总线与逻辑分析仪的能力边界
1.1 DSI总线:一对时钟加几条数据lane
MIPI-DSI是MIPI联盟定义的显示器串行接口,叫Display Serial Interface。现在的手机屏、平板屏、车载屏、工业屏,绝大多数SoC和面板之间走的就是这条总线。你可以把它理解成一条专用的“像素高速公路”,主机端(SoC/AP)往面板端发送像素数据和寄存器配置命令,逻辑分析仪需要在这条高速公路上“搭桥取样”。
它由两部分组成:物理层用D-PHY,协议层用DSI协议。物理线路上至少有一条时钟lane(CLKP/CLKN)和一条数据lane(D0P/D0N),最多支持四条数据lane。数据是源同步的,也就是说时钟lane和数据lane一起从主机端发出来,接收端靠时钟lane来对齐数据。这也是为什么用逻辑分析仪抓DSI时,最好把时钟lane也一起接上——它不光帮你对齐,还能帮你判断数据lane上的信号是不是合法。
D-PHY还有一个很特别的地方:每条lane是成对的差分线,但它的工作模式分为单端低摆幅的LP模式和差分小摆幅的HS模式,两种模式之间通过特定的状态转换序列来切换。这决定了逻辑分析仪能在什么程度上一探究竟。
1.2 HS/LP两种模式:为什么逻辑分析仪只能“看到”一半
先讲LP模式。LP就是Low Power,低功耗模式,单端信号,典型高电平1.2V,低电平0V,通信速率很低,通常不超过10Mbps。LP模式下,Dp和Dn两条线上各自用0/1组合出一个状态机,共有四种状态:LP-00、LP-01、LP-10、LP-11。总线空闲时处于LP-11,也叫Stop态。面板初始化时大量控制命令、读寄存器、屏幕唤醒指令都走LP模式。
再讲HS模式。HS就是High Speed,高速模式,这条lane会切换到差分驱动方式,典型差分摆幅只有200mV左右,速率动辄几百Mbps到数Gbps。HS模式下,Dp和Dn两条线的电平不再是普通的0/1逻辑,而是一对差分小信号——这正是问题所在。
逻辑分析仪的输入级是数字比较器,内部有一个阈值电压,高于阈值判1,低于阈值判0。普通逻辑分析仪能很好地处理0~1.2V、0~1.8V、0~3.3V这类单端数字信号,所以LP模式对它来说毫无压力。但HS模式的200mV差分摆幅,共模电压大约在150mV到250mV,这个幅度和绝对电压都远低于常见逻辑分析仪的判定阈值,采样结果基本是一堆随机跳变或者卡在一个固定电平上。你说它抓不到HS吗?也不全是。HS数据区域会让逻辑分析仪看到一段“高频毛刺带”,但这段毛刺带里包含什么数据,普通逻辑分析仪是解不出来的。
这里就是整篇教程的关键认知:逻辑分析仪能直接解析LP模式,对HS模式只能看到“有没有在跑、跑了多久、什么时候开始什么时候结束”。真正要解析HS里的像素数据内容,需要专业DSI协议分析仪或者配合差分探头转单端信号示波器。
1.3 逻辑分析仪的定位:不是协议分析仪,但够用
既然HS数据解不了,逻辑分析仪在DSI调试里到底有什么用?我自己的答案是三个场景。
第一个场景是初始化命令分析。屏上电以后,SoC会通过LP模式发送一大堆寄存器配置命令。绝大多数时候,屏幕显示不正常都是初始化初始化序列不对。用逻辑分析仪把LP模式命令抓下来,解码成字节,跟驱动源码里的初始化数组一对比,马上就能看出哪里漏发、哪里发错。
第二个场景是显示时序验证。视频模式下,SoC会周期性发送VSync、HSync、像素流等时序包。虽然是高速信号,但这些时序包的周期性很强,逻辑分析仪只要能识别出HS突发区域,就能通过时间差算出帧率、行周期、刷新率。我经常用这个方法反过来验证驱动的timing参数。
第三个场景是总线状态检查。开机时序里,哪条lane没起来、时钟和数据的进入序列对不对、总线是不是卡在某个状态出不来,这些都能通过LP状态机一目了然。
所以结论很明确:不要期待逻辑分析仪把HS像素数据解出来,把它定位成一个附带协议解码能力的时序分析工具,很多问题就能迎刃而解。
2. 工具准备与探针连接
2.1 逻辑分析仪选型:采样率和通道数怎么定
选逻辑分析仪只看两件事:采样率和通道数。
先说采样率。LP模式最大10Mbps,按奈奎斯特也才20MS/s,但实际抓D-PHY状态切换的时候,进入序列和退出序列都只有几十纳秒的时间窗口,加上D-PHY规范里很多边沿和毛刺都讲究一个先后顺序,我建议至少用50MS/s来抓LP模式,100MS/s更好。如果还想分析HS区域的出现位置和burst时长,就需要200MS/s以上的采样率,因为HS的同步序列可能有几百Mbps的翻转频率,采样率太低根本看不到翻转,只会看到一段平滑的中间电平。
再说通道数。最省事的方案是八通道。四路信号固定为CLKP、CLKN、D0P、D0N,剩下四路可以接D1P/D1N甚至复位、背光、使能等外部信号做触发参考。如果只想着重看初始化命令,四通道勉强也够,把D0P和D0N挂上,再挂一根CLKP做时钟参考,剩下一个通道留空都行。但考虑到以后要抓多条lane,一步到位选8通道比较实用。
市面上常见的几类工具:
- Saleae系列及其兼容版:软件生态成熟,逻辑分析仪官网下载的软件界面友好,解码器丰富,但注意市面上的兼容版鱼龙混杂,采样率和带宽经常虚标,有条件优先选正版。
- DSLogic Plus:开源硬件,配合PulseView/DSView使用,支持阈值调节,这是抓1.2V LP信号很关键的功能。
- Kingst等国产设备:性价比高,部分型号自带浏览器端软件,用起来也顺。
我记得网上经常有人讨论“逻辑分析仪怎么分析I2C数据”,那个需求其实十几块钱的普通逻辑分析仪就能搞定,但DSI的需求明显更高:你要考虑采样率上限、阈值可调范围、通道数、触发深度。这几个参数直接决定你能不能看到HS包络、能不能正确解析LP命令。
2.2 接线方案:挂哪根线、怎么接地、线越短越好
接线是整个实操里最枯燥但最影响成败的部分。先说物理位置。大多数嵌入式主板上,MIPI-DSI信号都是从SoC出来直接进FPC连接器或者板对板连接器。FPC座子的引脚间距很小,直接夹探头容易碰短路,我建议优先在主板上找串阻测试点。DSI信号线上一般会有串联电阻,比如22欧姆、33欧姆,位置在SoC和连接器之间,没有铺地平面遮挡的情况下,用逻辑分析仪的探针直接点在电阻两端,取电阻靠近连接器那一端。
接线顺序:
- 先把逻辑分析仪的地线和被测板的系统地连在一起,必须是同一根地,别接到外壳铁皮上。
- 接CLKP、CLKN,再接D0P、D0N。
- 如果要用外部触发,把复位信号或者背光使能信号接到空闲通道。
- 检查所有探针与被测点稳定接触,避免虚接。
线的长度是另一个坑。杜邦线又长又乱,很容易引入串扰和高频噪声。抓LP低速率信号倒是没什么压力,但一旦探针长度超过15厘米又同时挂着高速信号,就可能看到一个“带毛刺”的状态。我的习惯是:能用逻辑分析仪自带排线就绝不飞线,如果没有排线,用示波器探头上面的地弹簧针加短线焊到测试点上。
还有一点容易被忽略:逻辑分析仪的采样地和被测板地之间如果存在地环路,会引入工频干扰,导致采样结果里出现无规律的窄脉冲。这个在连接USB供电的逻辑分析仪和电池供电的开发板时尤其明显。解决办法是把逻辑分析仪的USB线换成一个带磁环的,或者把被测板改成电池/隔离电源供电。
2.3 输入阈值:1.2V逻辑电平最容易踩的坑
如果说接线是体力活,那设置输入阈值才是真正的技术活。很多朋友第一次抓DSI,抓出来的波形全是低电平,或者全是高电平,第一反应是信号没出来,其实多半是阈值设错了。
LP模式的信号是单端1.2V,意味着高电平是1.2V,低电平是0V。常见逻辑分析仪的输入阈值默认是1.5V甚至2.5V,对1.2V信号来说,1.2V低于阈值,会被判定成0,结果整条波形都是平的。
所以抓DSI之前,先把逻辑分析仪的输入阈值改成0.5V到0.6V之间。PulseView里能在Device配置界面调阈值,DSView也能在采集前设置。如果用的是不支持调阈值的设备,还有一条土办法:找一个小板子做一个电平转换,把1.2V信号抬到3.3V,再接逻辑分析仪。但这样会引入额外延迟和抖动,只适合慢速LP模式,不建议用在HS包络测量里。
3. 实操:抓取DSI初始化序列和HS/Timing包络
3.1 典型场景一:抓LP模式下的初始化命令
正常一块面板的上电流程大致是:供电稳定 — 复位释放 — 初始化命令发送 — 打开显示。初始化命令走DSI的LP模式,命令内容以DSI短包或长包形式在D0 lane上发送。这个阶段的信号非常规整,正好适合逻辑分析仪。
具体的操作流程,我按自己的习惯列一遍:
- 接好采样线:CLKP、CLKN、D0P、D0N,外加一个外部触发通道接LCD_RESET引脚。
- 打开PulseView,选择采样率,100MS/s,采样深度设到100M点以上,保证能覆盖整个上电过程。
- 设置触发方式。我习惯于用外部通道的上升沿触发,触发电平选LCD_RESET从低到高的那个瞬间。这样按键复位、重新上电,逻辑分析仪能捕捉到从复位释放之后的所有DSI通信。
- 启动采样,然后给开发板上电或者执行一次软复位。
- 采样完成后,查看波形。
这个场景有两点要注意。第一,初始化命令往往集中在复位释放后的几十毫秒到几百毫秒内,采样深度不够的话,数据还在缓冲区,但前面一大半都是无用的空闲状态。解决方案是把触发位置放在波形窗口的5%到10%处,之后的大部分采样空间留给后面的通信。第二,面板复位不只是给一个脉冲那么简单,复位前后还需要满足一定的电源时序,如果波形里完全没有LP动作,优先查是不是面板根本没退出复位。
3.2 触发策略:如何精准抓到开机那一瞬
触发策略决定你花多少时间在“等待一次有效采样”上。如果每次都手工点停止再翻找波形,效率太低,而且很容易错过开机瞬间的那几帧初始化命令。
我最常用的触发方案有三种,按可靠性排序:
第一种是外部硬件触发。把逻辑分析仪的一个通道接到面板的复位引脚或者背光使能引脚,设置上升沿触发。这一招最稳,因为无论SoC初始化脚本怎么改,硬复位信号始终存在,而且复位动作一定发生在初始化命令之前。
第二种是总线状态触发。一些逻辑分析仪软件支持在某个通道上设置特定的码型触发,比如CLK通道高电平时,D0P从1跳到0。这个对调试阶段很有用,能直接定位到特定命令发送的位置。但配置起来稍微麻烦,需要了解D-PHY的状态切换点。
第三种是使用预触发和长时间连续采样。把采样率降低一些,比如20MS/s,然后把采样深度拉满,先点“开始采样”,再手动执行一次上电,最后停止采样。相当于录了一段很长的“监控录像”,后来慢慢翻。
老实说,我日常用得最多的是外部触发加预触发组合。外部触发定位复位脚,预触发深度设到20%,这样能看到复位之前的电源状态和总线空闲状态,方便分析完整的上电时序。
3.3 波形查看与导出:PulseView/DSView操作要点
抓完数据之后,大部分时间花在查看波形和分析上。
PulseView是开源社区非常常用的逻辑分析仪软件,它有个Protocol Decoder面板,可以加载各种协议解码器。你要先去Decoder列表里找有没有现成的DSI或者D-PHY相关解码器。如果当前安装的版本带这个解码器,直接在D0P、D0N、CLKP几个信号上映射好,解码结果会自动以十六进制数据行的形式显示在波形下方。如果找不到DSI解码器,也不用着急,本文第5节会给一套手工解析和脚本解析的思路。
另一个常用软件是DSLogic配套的DSView,它的界面风格和Saleae比较接近,同样支持协议解码、CSV导出。无论是PulseView还是DSView,导出数据时都建议选择CSV格式,把时间戳和通道电平都导出来,后续写脚本分析会方便很多。
4. HS/LP模式波形逐段拆解
4.1 LP模式波形:状态组合、停止态与总线转向
现在来看关键内容:波形怎么看。
如果你把CLKP、CLKN、D0P、D0N四路信号同时展开,第一个直观感受是大部分时间四条线都停在1.2V高电平,也就是LP-11状态。这是D-PHY的正常空闲态,叫Stop态。所有通信都从Stop态开始,通信结束也回到Stop态。
LP模式下,D0P和D0N的组合状态决定了当前总线处于什么状态:
- LP-00:两条线都是低电平,代表总线进入了某种低电平保持状态,在HS进入序列末尾、退出序列开头经常出现。
- LP-01:D0P低、D0N高,代表进入HS之前的准备状态之一。
- LP-10:D0P高、D0N低,HS退出序列中回Jump到LP-10再到LP-11。
- LP-11:两条线都高,Stop态,总线空闲。
如果你抓到的是一段初始化命令,你会看到总线先从LP-11切到LP-01或者LP-00,然后出现一系列高低电平变化,最后又回到LP-11。这一连串变化里,有用命令内容就藏在这些高低电平组合中。DSI把D0P和D0N上的逻辑电平直接作为数据位来传输,所以只要在PulseView里把两个通道并列显示,一眼就能看出这段LP数据传输的节奏。
这里分享一个我踩过的坑:很多SoC在主机端初始化之前,先回发一两个总线转向(BTA)请求,用于读取Panel的状态寄存器。BTA期间,总线控制权会从主机转给面板,波形上表现为D0N和D0P出现特定顺序的状态跳变。如果抓到的命令和你期望的初始化数组对不上,可能不是命令发错了,而是总线中间转向了,别忘了把转向部分考虑进去。
4.2 HS模式波形:从进入序列到退出序列
HS模式通常出现在视频模式的数据传输阶段,但在命令模式下面板也可能用HS发命令。HS burst在逻辑分析仪上长什么样,我总结成三个阶段。
第一阶段是HS进入序列。波形会从LP-11变成LP-01,再变成LP-00,紧接着两条lane开始进入高速翻转区间。这一段是D-PHY规范非常明确的转换序列,逻辑分析仪虽然解不了后面的HS数据,但能看到这个序列本身是否完整。如果进入序列里有某一步缺失,说明主机端的HS lane启动逻辑有问题。
第二阶段是HS数据传输区。在这个区域里,CLKP通道上能看到方波一样的时钟翻转,频率很高;D0P和D0N通道则是一堆看起来像随机翻转的毛刺带。很多第一次上手的朋友看到这里就慌了,以为是测量问题。其实这一段就是HS差分信号经逻辑分析仪阈值一通切之后产生的“伪随机”表现。它虽然不能还原出数据位,但能反映出HS传输持续了多久、时钟频率大致多少、两条数据lane是不是在同时翻转。
第三阶段是HS退出序列。数据翻转停止,两条lane都回到低电平,进入LP-00,经历LP-10,最后回到LP-11停止态。这个退出序列同样重要,如果总线卡在LP-00或者LP-10出不来,说明退出时序不对,后面再发命令就容易错乱。
要测量HS burst的时长,直接把光标从HS进入序列的最后一个LP-00过后,拖到退出序列第一个LP-00之前,看时间差就行。我习惯在HS区域里连续测三次,取平均值,可以反推出大概的行周期和刷新率。
4.3 DSI包结构:从波形到字节流
波形层面的眼动图会了,就该把它对应到DSI协议包了。DSI包里分两种,短包和长包。
短包固定4字节:1字节的数据标识(DI),2字节的负载数据,1字节的ECC校验码。DI里的高2位是虚拟通道号VC,低6位是数据类型DT。常见的DT值比如0x05是Generic Short Write 0参数,0x15是Generic Short Write 1参数,0x29是Generic Read命令。
长包的结构复杂一点:头部6字节,包含DI、2字节的字计数WC和1字节ECC;然后是WC乘以2字节的数据负载;最后还有2字节的CRC16校验。像素流数据就是用长包传输的,比如RGB888像素流对应的DT是0x21。
逻辑分析仪在LP模式下抓到的原始字节流,要按这个包结构去切分。如果你在波形上看到,D0P/D0N上先出现一个字节,又出现两个字节,然后是ECC,这就是一个短包;如果看到前面有6个字节头,中间一大片数据,尾部两个字节CRC,就是长包。把这些包按顺序列出来,就得到了一条完整的DSI命令序列。
5. 解析命令内容与显示时序
5.1 手工解析一帧DSI包(附ECC/CRC说明)
假设你在波形里连续抓到这么一组原始字节:39 00 04 6D 02 00 00 00 00 00 FF FF。
第一个字节0x39就是DI,低6位0x39=0b111001,对应的DT是Generic Long Write。接着是WC,两名字节0x0400,按小端序读就是0x0004,表示后面有8字节数据(4个16位字)。然后是ECC字节0x6D,它由前面三个字节(VC+DT+WC)计算得出。
数据部分就是接下来的8个字节:02 00 00 00 00 00 FF FF,这是实际写入面板寄存器的内容。最后两个字节FF FF是CRC16,用多项式0x1021对前面的数据和包头计算得到。
手工解析最痛苦的就是算ECC和CRC。ECC是汉明码变体,8位覆盖24位信息,手工算起来很容易错,我一般直接找个在线MIPI DSI ECC工具算。CRC16相对好一些,Python里用binascii.crc_hqx(data, 0xFFFF)就能搞定。不过说实话,手工解析的场景多半是在应急分析,日常还是建议用脚本。
5.2 用脚本批量解析:PulseView导出CSV+Python
当你抓到的命令不止一条,而是一整个初始化序列时,手工解析效率太低。我的做法是先让PulseView把波形导出成CSV,每一行包含时间戳和各个通道的电平,然后用Python脚本去恢复LP模式的数据位流。
这里只讲核心思路,不贴完整代码。第一步,从CSV里找D0P和D0N的状态切换点。第二步,根据D-PHY的LP编码规则,把状态切换解释成0和1的bit序列。第三步,把bit序列按字节组织成byte流。第四步,按5.1节的DSI包结构切分成短包/长包,输出十六进制数组。
脚本实现的时候有几个容易踩的坑:
- CSV导出时电平是0/1的数字,别把它当成模拟电压看。
- D-PHY的LP编码和普通UART的起始位/停止位不一样,别套用串口解析逻辑。
- 如果捕获的lane数不止D0,还要处理lane合并,不同lane上是交替分布的数据字节,需要按lane数做拆位重组。
我平时会把初始化数组和抓到的命令做一次diff,输出多出、缺失、顺序不对的命令,这样排查驱动问题基本能一步到位。
5.3 验证解析结果:刷新率、寄存器配置对不对
解析出命令以后,验证工作同样重要。这里分享两个我常用的验证思路。
验证寄存器配置,把初始化数组里的关键参数,比如像素格式、分辨率、时序参数,跟面板数据手册对照。这一步主要靠经验和数据手册,逻辑分析仪只是帮你确认“主机端到底发了什么”,不能代替你判断“发得对不对”。
验证刷新率,在视频模式下抓一段波形,测量VSync事件包和HSync事件包出现的时间间隔。比如你在波形里识别到两次VSync包之间是16.67ms,那帧率就是60Hz。如果配置的刷新率是60Hz,这个测量值能直接验证驱动配置有没有问题。这个方法我在低分辨率屏幕调试时特别好用,因为HS数据内容不解码完全不影响时序测量。
6. 常见问题与排错实录
6.1 波形没变化/全高/全低的排查
抓到波形后最怕的是整条总线纹丝不动,全高或全低。我的排查顺序一般是这样的:
先确认逻辑分析仪阈值是否正确。前面说了,1.2V信号如果阈值设成1.5V以上,保证全判成低。把阈值调到0.5V到0.6V再看一遍。第二个排查点是地线。逻辑分析仪的地线没接好,所有通道都会在固定电平上飘。第三个排查点是物理接触。探针点在FPC座子上,稍微动一下就虚接,波形变成翻乱码。这时候可以用手轻轻压一压排线,如果波形立刻变化,那就是接触问题。
如果这些都排除了,才开始怀疑DSI信号本身。把逻辑分析仪换回示波器,先看D0P上有没有真正的1.2V高电平、有没有LP状态切换。有时候SoC根本没启动DSI,或者面板压根没上电,信号自然不会出现在线上。
6.2 HS区域抓不好的原因
HS区域出现“毛刺带”是正常的,真正的异常是连毛刺带都看不到。这种情况先检查采样率,如果只有20MS/s,而HS速率是400Mbps,那你看到的就是一条“半高电平”,完全看不出翻转。把采样率提高到200MS/s甚至更高,正常情况下能看到CLKP上连续翻转、数据lane上乱跳。
还有一种情况是阈值问题。HS信号共模电压只有200mV左右,如果逻辑分析仪阈值调到0.5V,那么HS区域也可能被整体识别成0。想看到HS区域的“翻转迹象”,可以把阈值尽量调低,有些设备最低能到0.3V左右,配合高采样率可以看到HS期间的微弱翻转。但再次强调,这不是标准的HS测量方式,只能做包络观测,真要评估HS物理层,还是上示波器搭配差分探头。
6.3 工具边界误区:什么是逻辑分析仪解决不了的
最后说一个认知误区。逻辑分析仪是数字逻辑分析工具,解决不了所有物理层问题。它不能测模拟波形,不能测信号眼图,更不能评估SI和EMI。有人拿逻辑分析仪去测MOS管的栅极驱动波形,或者去看电源纹波,这本质上就是工具选错了。这些模拟信号的波形分析必须用示波器配合合适的探头,跟逻辑分析仪是两个世界。
回到DSI场景,逻辑分析仪的边界也很清晰:LP模式命令解析、HS burst时序、总线状态转移、初始化时序比对,这些是它的主场;HS物理层电平质量、差分信号眼图、信号完整性测试,这些要交给专业示波器和DSI协议分析仪。把工具放在合适的位置,效率自然就上来了。
6.4 常见问题速查表
| 现象 | 可能原因 | 解决办法 |
|---|---|---|
| 所有通道全低 | 输入阈值过高,1.2V信号判为0 | 阈值改到0.5V~0.6V |
| 所有通道全高 | 地线虚接,共模电压抬高 | 检查逻辑分析仪地线连接 |
| 波形乱变、不稳定 | 探针虚接、线太长 | 换短线、用探针弹簧头固定 |
| LP模式抓不到命令 | 触发点设错,命令已经发完 | 用复位信号做外部触发 |
| HS区域看不到翻转 | 采样率太低、阈值太高 | 采样率提到200MS/s以上 |
| 解出来的命令和源码对不上 | 漏了BTA总线转向或lane没合并 | 检查是否有总线转向、按lane数重组数据 |
再列一个我从实践中总结的操作习惯:每次抓DSI波形前,先把阈值、采样率、触发通道三个参数写在调试日志里,方便复现问题。这个习惯帮我少走了很多弯路,也方便把同一份波形发给同事复现分析。最后再说个小技巧,如果手头只有四通道的逻辑分析仪,优先挂D0P、D0N、CLKP和复位信号,比挂上其他辅助线更实用。因为D0 lane承载了绝大多数初始化命令,CLKP提供时钟参考,复位信号提供触发,这个组合已经覆盖了80%的调试场景。