多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

MIPI LP RX 调试实战:从屏幕不亮到链路建立的关键技术

MIPI LP RX 调试实战:从屏幕不亮到链路建立的关键技术 1. 从一个“调不通”的屏说起MIPI LP RX 到底在解决什么问题如果你做过嵌入式显示或者摄像头相关的项目大概率遇到过这种场景硬件上电主控和屏幕之间的高速数据通道HS看起来已经跑起来了示波器上也能抓到差分信号在翻转但屏幕就是不亮或者初始化命令发不下去读回来的寄存器值永远是0xFF或者0x00。这时候很多人第一反应是“时序不对”“时钟没配好”但真正卡住你的往往是那条看起来不起眼的低速通道——MIPI LPLow Power模式下的接收通路。MIPI LP RX说白了就是 MIPI D-PHY 里负责低速、低功耗状态下的信号接收部分。它不跑图像数据跑的是控制命令、寄存器读写、以及链路建立前的握手信息。你可以把它理解成一条“管理通道”高速通道是运货的大卡车LP 通道就是调度室的对讲机。对讲机不通卡车再多也进不了站。这个内容适合所有在做 MIPI 屏幕点亮、摄像头模组调试、FPGA 对接 MIPI 接口的工程师尤其是那些 HS 已经通了、却卡在初始化阶段的同学。我这些年接触过 ST7701S、ILI9881、以及各种 MIPI 液晶屏的调试也用过紫光同创、Xilinx 的 FPGA 去实现 MIPI 收发。踩过的坑里至少有一半跟 LP RX 有关。下面我把这套东西从设计思路到实操细节完整拆一遍尽量让你少走弯路。2. 内容整体设计与思路拆解2.1 为什么 LP 通道比 HS 更容易出问题很多人有个误区HS 速率高肯定更难做。实际上在工程里HS 差分信号只要阻抗控制好、走线等长、参考时钟稳定反而容易一次通。LP 通道是单端信号电平标准跟 HS 完全不同而且它依赖上拉电阻、驱动能力、以及收发两端的时序配合。任何一个环节偏了LP 就收不到正确的电平。MIPI D-PHY 的 LP 模式定义了四种线路状态LP-00、LP-01、LP-10、LP-11。这四种状态通过两条线Dp 和 Dn的不同电平组合来表示。LP-11 是空闲态Stop StateLP-00 到 LP-10 的跳变序列用来表示进入 HS 或者发送 Escape 命令。接收端要能准确识别这些状态才能正确解析出控制信息。注意LP 状态的电平阈值不是固定的 1.2V 或 1.8V而是相对于 VDD 的比例。很多新手直接拿 1.8V 的 GPIO 去接结果电平不匹配LP RX 永远识别不到 LP-11。2.2 方案选型的核心考量用硬核还是软核在实际项目里实现 MIPI LP RX 有三条路专用 PHY 芯片比如一些 MIPI 桥接芯片内部集成了完整的 D-PHY你只需要配置寄存器。优点是省心缺点是灵活性差成本高而且有些芯片的 LP 时序是固定的改不了。FPGA 软核实现用 FPGA 的普通 IO 加上拉电阻自己写状态机去采样 LP 信号。优点是灵活可以针对特定屏幕调时序缺点是对 IO 的输入延迟、采样时钟要求高尤其是 LP 的脉宽可能只有几十纳秒。SoC 内置 PHY像 RK3588 这类芯片MIPI 控制器和 PHY 都是集成的你只需要配置设备树和驱动。这是最省事的但一旦出问题排查手段有限因为你看不到 PHY 内部的状态。我个人的经验是如果是产品量产优先用 SoC 内置 PHY如果是调试阶段或者需要对接非标屏幕FPGA 软核更可控。紫光同创的 FPGA 我用来驱动过 MIPI 屏LP RX 部分就是用普通 IO 加状态机实现的后面会详细讲。2.3 LP RX 在整个链路中的位置一条完整的 MIPI 链路从发送端到接收端LP 信号要经过发送端 LP 驱动器 - PCB 走线 - 接收端 LP 接收器 - 状态机解析。LP RX 的任务就是把线路上的四种状态准确还原成数字逻辑然后交给协议层去判断是 Short Packet、Long Packet 还是 Escape 模式命令。这里有个关键点LP RX 不是简单的 GPIO 读取。因为 LP 信号的跳变可能很快而且要在 HS 和 LP 之间切换接收端需要有一个稳定的采样机制。通常做法是用一个比 LP 信号频率高得多的时钟去过采样然后做边沿检测和状态解码。3. 核心细节解析与实操要点3.1 LP 四种状态的物理层定义先把这个基础打牢。MIPI D-PHY 规定每条 Lane 有两根线Dp 和 Dn。LP 模式下这两根线是独立驱动的单端信号。四种状态如下状态Dp 电平Dn 电平含义LP-00低低Bridge 状态用于 Escape 模式LP-01低高表示数据 0LP-10高低表示数据 1LP-11高高Stop 状态空闲这里的“高”和“低”是相对于接收端的供电电压。通常 LP 信号的摆幅是 0 到 1.2V但阈值一般在 0.4V 到 0.8V 之间。具体要看 PHY 的规格书。提示如果你用 FPGA 的普通 IO 去接收 LP 信号一定要确认 IO 的输入阈值。有些 FPGA 的 LVCMOS 输入阈值是 0.5*VCC如果 VCC 是 3.3V阈值就是 1.65V而 LP 信号最高才 1.2V那就永远识别不到高电平。这时候需要加电平转换或者用支持更低阈值的 IO Bank。3.2 LP RX 状态机的设计思路在 FPGA 里实现 LP RX核心是一个状态机。我一般会这样设计用一个 200MHz 的时钟去采样 Dp 和 Dn假设 LP 信号最窄脉宽是 50ns200MHz 采样周期 5ns足够过采样。对 Dp 和 Dn 分别做同步和去抖通常连续采样 3 次相同才认为电平稳定。根据 Dp 和 Dn 的当前电平解码出 LP 状态。检测状态跳变序列判断是进入 HS 还是 Escape 命令。这里有个细节LP 信号在进入 HS 之前会有一个 LP-11 - LP-01 - LP-00 的序列然后才是 HS-0。接收端要能准确捕捉这个序列否则会误判。我试过用简单的边沿检测结果因为信号振铃导致误触发后来加了数字滤波才稳定。3.3 上拉电阻和驱动能力的匹配LP 模式是单端信号发送端和接收端都需要有上拉电阻。通常发送端有可配置的上拉接收端也有。如果两边都上拉可能会导致电平拉不低如果都不上拉又可能浮空。我的经验是接收端保持一个弱上拉比如 10kΩ 到 100kΩ发送端根据协议要求配置。在 FPGA 实现时如果 FPGA 的 IO 支持内部上拉可以用内部上拉但要注意内部上拉的阻值可能不准最好还是外部加一个。注意LP 信号的上升沿和下降沿时间也有要求太快会导致 EMI 问题太慢会导致接收端识别错误。一般建议上升/下降时间在 1ns 到 10ns 之间。如果走线很长可能需要加串联电阻来匹配。3.4 与 HS 模式的切换时序LP RX 不仅要能接收 LP 信号还要能正确判断什么时候切换到 HS 模式。这个切换过程是LP-11 - LP-01 - LP-00 - HS-0。接收端在检测到 LP-00 之后要在一个很短的时间内切换到 HS 接收模式否则会丢失 HS 同步头。在 FPGA 里这个切换通常是通过一个多路选择器来实现的LP 状态机检测到进入 HS 的序列后输出一个切换信号把接收通路从 LP 采样切换到 HS 差分接收。这个切换的延迟要尽可能小否则 HS 的第一个 bit 可能采不到。我实测下来如果用普通 IO 做 LP 接收切换延迟大概在 10ns 到 20ns 左右对于大多数 MIPI 屏幕来说够用了。但如果 HS 速率很高比如 1Gbps 以上这个延迟就可能造成问题需要考虑用专用的 SelectIO 或者 ISERDES 来做。4. 实操过程与核心环节实现4.1 硬件准备与信号测量在开始写代码之前先确认硬件。你需要一块带 MIPI 接口的屏幕或者摄像头模组。主控板SoC 或者 FPGA 开发板。示波器或者逻辑分析仪带宽至少 500MHz最好 1GHz 以上。如果可能准备一个 MIPI 协议分析仪但那个东西很贵一般用示波器抓 LP 信号就够了。先上电用示波器抓 Dp 和 Dn 的波形。正常情况下你应该能看到 LP-11 的空闲态然后是一串 LP 跳变。如果什么都看不到先检查供电和上拉电阻。如果看到的是乱七八糟的波形可能是发送端没有正确配置。提示抓 LP 信号的时候示波器探头要用高阻探头不要用 50Ω 匹配否则会把信号拉死。触发方式可以设成 Dp 的下降沿这样容易抓到进入 HS 的序列。4.2 FPGA 端 LP RX 的 Verilog 实现下面是我在紫光同创 FPGA 上实际用过的 LP RX 核心代码。为了便于理解我做了简化去掉了跟具体项目相关的部分。module mipi_lp_rx ( input wire clk, // 200MHz 采样时钟 input wire rst_n, input wire dp_in, // Dp 输入 input wire dn_in, // Dn 输入 output reg lp_state, // 解码后的 LP 状态 output reg lp11_flag, // LP-11 检测 output reg hs_req // 请求切换到 HS ); // 同步和去抖 reg dp_sync0, dp_sync1, dp_sync2; reg dn_sync0, dn_sync1, dn_sync2; always (posedge clk or negedge rst_n) begin if (!rst_n) begin dp_sync0 1b0; dp_sync1 1b0; dp_sync2 1b0; dn_sync0 1b0; dn_sync1 1b0; dn_sync2 1b0; end else begin dp_sync0 dp_in; dp_sync1 dp_sync0; dp_sync2 dp_sync1; dn_sync0 dn_in; dn_sync1 dn_sync0; dn_sync2 dn_sync1; end end wire dp_stable (dp_sync0 dp_sync1 dp_sync2) | (~dp_sync0 ~dp_sync1 ~dp_sync2); wire dn_stable (dn_sync0 dn_sync1 dn_sync2) | (~dn_sync0 ~dn_sync1 ~dn_sync2); // 状态解码 always (posedge clk or negedge rst_n) begin if (!rst_n) begin lp_state 2b00; lp11_flag 1b0; hs_req 1b0; end else if (dp_stable dn_stable) begin case ({dp_sync2, dn_sync2}) 2b00: lp_state 2b00; // LP-00 2b01: lp_state 2b01; // LP-01 2b10: lp_state 2b10; // LP-10 2b11: lp_state 2b11; // LP-11 endcase lp11_flag (dp_sync2 dn_sync2); // 检测 LP-11 - LP-01 - LP-00 序列 if (lp_state 2b11 {dp_sync2, dn_sync2} 2b01) hs_req 1b1; else if (lp_state 2b00) hs_req 1b0; end end endmodule这段代码的核心就是同步、去抖、解码、序列检测。实际项目中你可能还需要加上超时检测、错误计数等功能。4.3 参数计算与时钟选择采样时钟的选择很关键。假设 LP 信号的最窄脉宽是 50ns那么采样周期至少要小于 25ns也就是采样频率要大于 40MHz。但为了可靠去抖我一般会用 200MHz这样每个 LP 状态至少能采到 10 个点。如果你用的 FPGA 时钟资源有限可以用 100MHz但去抖的连续采样次数要相应减少比如改成 2 次。不过 2 次去抖的抗干扰能力会差一些信号质量不好的时候容易误判。提示LP 信号的脉宽跟具体协议有关。比如 Escape 模式下的命令有些脉宽只有 20ns 左右。如果你的采样时钟只有 100MHz可能采不到。所以建议先用示波器量一下最窄脉宽再决定采样时钟。4.4 与协议层的对接LP RX 解码出来的状态最终要交给协议层去解析。协议层需要知道当前是 LP 模式还是 HS 模式。如果是 LP 模式是 Short Packet 还是 Escape 命令。如果是 Escape 命令具体是什么命令比如 Reset、ULPS、Trigger 等。在 FPGA 里我通常会用一个简单的状态机来解析 Escape 命令。Escape 模式的进入序列是 LP-11 - LP-01 - LP-00 - LP-01 - LP-00然后才是具体的命令。这个序列比较长需要仔细检测。5. 常见问题与排查技巧实录5.1 LP RX 收不到任何信号这是最常见的问题。排查顺序如下检查供电和上拉用万用表量 Dp 和 Dn 的静态电平。如果是 LP-11应该都是高电平。如果都是低电平可能是上拉没接或者发送端在驱动低。检查 IO 阈值确认 FPGA 或 SoC 的 IO 输入阈值是否低于 LP 信号的高电平。如果阈值太高需要换 IO Bank 或者加电平转换。检查采样时钟用示波器看采样时钟是否正常。如果时钟没起来状态机就不会工作。检查约束文件FPGA 的引脚约束是否正确输入延迟是否设置合理。我遇到过一种情况FPGA 的 IO 约束里把 Dp 和 Dn 配成了差分对结果 LP 模式下单端信号被差分接收器吃掉了什么都收不到。后来改成普通单端 IO 就正常了。5.2 LP 状态跳变误判有时候 LP RX 能收到信号但状态跳变总是误判导致协议层解析错误。原因通常是信号振铃或者去抖不够。解决办法增加去抖的连续采样次数比如从 3 次增加到 5 次。在 PCB 上靠近接收端加一个小电容比如 10pF来滤高频振铃但注意电容不能太大否则会拖慢边沿。调整采样时钟的相位让采样点落在信号稳定的中间位置。注意加电容滤波是一把双刃剑。LP 信号本身速率不高加 10pF 一般没问题但如果加到 100pF边沿就会变得很慢可能导致 HS 切换时丢失同步头。5.3 进入 HS 后 LP RX 干扰 HS 接收有些设计里LP RX 和 HS RX 共用同一组引脚。如果 LP RX 的状态机在 HS 模式下还在运行可能会产生错误的切换信号干扰 HS 接收。解决办法是在进入 HS 模式后把 LP RX 的状态机暂停或者复位等 HS 传输结束、回到 LP-11 后再重新使能。这个控制逻辑要跟协议层配合好。5.4 常见问题速查表现象可能原因排查方法解决措施完全无信号供电/上拉异常万用表量静态电平检查上拉电阻和供电电平识别错误IO 阈值不匹配查 FPGA IO 手册换 IO Bank 或加电平转换状态跳变误判振铃/去抖不足示波器看波形增加去抖次数或加小电容HS 切换失败切换延迟太大逻辑分析仪抓时序优化状态机或改用专用 IOEscape 命令解析错误序列检测不全对照协议查序列完善状态机5.5 独家避坑技巧先抓波形再写代码不要一上来就写 Verilog先用示波器把 LP 信号的波形抓清楚知道脉宽、电平、跳变序列再动手写。用 LED 做状态指示在调试阶段把 LP 状态机的关键状态输出到 LED 上比如 LP-11 亮一个灯HS 请求亮另一个灯。这样不用逻辑分析仪也能大致判断状态。保留测试点PCB 上一定要留 Dp 和 Dn 的测试点最好还有采样时钟的测试点。调试的时候你会感谢自己。不要忽略地线LP 信号是单端的对地线质量很敏感。如果地线不好信号上会有很多噪声。确保接收端和发送端有良好的共地。6. 从屏幕点亮到系统集成LP RX 的延伸思考6.1 不同屏幕的 LP 时序差异ST7701S 和 ILI9881 这类屏幕LP 初始化序列的时序要求不完全一样。有些屏幕对 LP 的脉宽要求很严格比如要求 LP-00 的持续时间在 40ns 到 80ns 之间。如果你的 FPGA 状态机响应太慢可能就错过了。我在调试 ST7701S 的时候发现它的 Escape 模式进入序列比标准协议要求的要快一些。后来把采样时钟提高到 250MHz并且减少了去抖次数才稳定下来。所以不要迷信“标准”要以实际屏幕的规格书为准。6.2 FPGA 实现 MIPI 的优劣势用 FPGA 实现 MIPI LP RX最大的优势是灵活。你可以根据屏幕的实际情况调整采样时钟、去抖次数、状态机响应速度。而且 FPGA 可以同时做多路 LP RX适合多 Lane 的应用。劣势也很明显占用逻辑资源而且 LP 信号的时序约束比较麻烦。如果 FPGA 的 IO 延迟太大可能需要在 PCB 上做补偿。另外FPGA 的普通 IO 做 LP 接收抗干扰能力不如专用 PHY。6.3 与 SoC 方案的对比RK3588 这类 SoCMIPI 控制器是集成的LP RX 由硬件自动处理。你只需要在设备树里配置好参数比如时钟频率、Lane 数量、LP 时序等。优点是省事缺点是出了问题不好排查。我遇到过 RK3588 的 MIPI 输入 1080i 信号时LP RX 偶尔会丢帧。后来发现是设备树里的 LP 时序参数跟屏幕不匹配调整之后就好了。所以即使是 SoC 方案也要仔细看屏幕的规格书把 LP 相关的参数配对。6.4 实际项目中的经验总结做了这么多项目我最大的体会是LP RX 虽然只是 MIPI 链路里的一小部分但它决定了整个链路能不能建立起来。很多“屏幕不亮”“没信号”的问题根源都在 LP 通道。如果你正在调试 MIPI 屏幕建议先把 LP RX 调通确认能正确收到 LP-11 和 Escape 命令再去调 HS。这样问题会少很多。另外不要怕麻烦多用示波器和逻辑分析仪把波形抓清楚比盲目改代码有效得多。最后分享一个小技巧如果你用的是 Xilinx 或紫光同创的 FPGA可以用 IDELAY 或者 IDELAYE2 来调整输入延迟这样可以在不改变 PCB 的情况下微调 LP 信号的采样点。我试过用 IDELAY 把 LP RX 的误码率从 10% 降到几乎为零效果很明显。
返回列表