3. 训练初始化阶段(FRL Start):Source端发送CLK/Data模式、接收端同步检测失败原因
好,咱们进入第3章。训练初始化阶段,准确说是FRL Start这个子状态——有人叫它“握手前奏”。Source端开始往Sink端发CLK/Data pattern,Sink要做的第一件事就是检测到这个Pattern,然后完成同步。这一步卡住了,后面所有训练都白搭。我在项目里遇到最多的坑,其实都埋在这个阶段。
3.1 FRL Start到底在干嘛?
说白了,Source端先把4条lane中的一条或几条切到一种特殊的时钟/数据交替模式。具体说,就是发一连串的CLK pattern和数据pattern交替出现。Sink端的CDR(Clock Data Recovery)电路要在这个阶段锁定频率、对齐相位,然后识别出Pattern的边界。等Sink确认收到了有效的Pattern,它会回复一个“同步成功”的信号,训练才能往下走。
为什么会失败呢?我个人习惯先把它分成两大类:
- 物理层问题——信号完整性、噪声、抖动、反射,导致Sink根本收不到干净的Pattern。
- 协议/逻辑层问题——Pattern发错了、时序关系不对、或者Sink侧的同步状态机没跑到正确状态。
下面我拆开讲。
3.2 同步检测失败的典型表现
你遇到的情况可能是以下某一种(或几种兼有):
| 现象 | 可能的根因 |
|---|---|
| Sink报告Link Training failed,Log里显示FRL Start未完成 | CDR未锁定,或Pattern识别失败 |
| Source端看到AUX回送的状态一直是FRL_Start_Retry | Sink侧电源不稳定或参考时钟有漂移 |
| 示波器量到差分信号幅值正常,但眼图完全闭合 | 插损过大,或者接收端EQ没来得及收敛 |
| 链路偶尔能训练成功,冷启动/热拔插就失败 | 时序裕量不足,或者Sink的启动顺序有冲撞 |
3.3 常见原因深度拆解
3.3.1 差分电压不够或共模偏移
HDMI 2.1 FRL模式下,每lane的差分摆幅有明确要求(典型800mVpp)。有些PCB走线过长或用了便宜的连接器,电压掉到600mV以下,Sink的CDR可能就锁不上了。你想想看,CDR需要足够大的信号幅度来驱动内部的VCO控制环路,信号太小,相位噪声直接飙升。
我曾经在一块FPC排线上吃过亏,排线长度超过300mm,中间还没做阻抗补偿。Source端差分信号摆幅实测只剩450mV。换了一根短排线,OK了。
3.3.2 CDR锁定窗口与Pattern结构不匹配
FRL Start发送的Pattern是固定的:先发一段CLK pattern(比如连续的1-0-1-0),再发一段Data pattern(伪随机序列)。Sink的CDR需要在这两段之间完成“频率锁定”和“相位追踪”。如果Source发Pattern时频率跳变太大(比如从CLK pattern的3GHz突然切到Data pattern的6Gbps),CDR来不及跟踪,就会失锁。
标准里其实规定了Pattern切换的过渡时间(tFRAME和tSYNC参数)。我在调试时习惯在Source侧加上一个“渐入”的压控振荡器偏置,让频率慢慢过渡,而不是突变。很多芯片厂商的参考代码里默认是硬切换,我个人建议检查一下寄存器设置。
3.3.3 终端匹配与回波损耗
Sink侧的接收端终端电阻通常为50Ω到地,但PCB走线的特性阻抗偏差、ESD器件的寄生电容,可能导致回波损耗超标。回波造成的过冲和振铃会干扰CDR的采样判决。记住,FRL Start阶段Sink还没做均衡训练(EQ Training在后面),所以完全靠原始信号质量硬扛。一旦回波损耗大于-10dB,眼睛很可能睁开得不够。
3.3.4 参考时钟的抖动与漂移
Source和Sink的参考时钟如果来源于同源,问题不大。但许多设计里Source用晶振,Sink用PLL从Source转发来的TMDS clock恢复——在FRL模式下,TMDS clock lane也要参与数据。如果Sink的晶振精度不够(比如±100ppm),锁定窗口就会偏移。我曾经在实验室遇到一个案例:Sink端的晶振是24MHz ±50ppm,但老化后漂到±120ppm,FRL Start经常失败。换了高精度晶振(±25ppm),再也没出过问题。
3.4 硬件调试快速指南
如果你现在手头有一个FRL Start失败的板子,我建议你按下面的顺序排查:
- 用差分探头量信号——量Source端输出(到连接器前)和Sink端输入(到芯片引脚前)。看幅值、眼图、抖动。
- 检查CDR锁定指示——Sink芯片通常有寄存器可以读CDR状态。我习惯先写一个小脚本轮询这个寄存器,看CDR有没有从“失锁”变到“锁定”。如果一直失锁,先查参考时钟。
- 抓AUX总线——看Source和Sink交换的FRL Start消息。标准里定义了详细的AUX事务,如果Source连续发送Start request但没有收到ACK,说明Sink根本没有进入同步状态。
- 换一个Sink设备(比如用另一家芯片)——这种方法很笨,但如果能复现,就能快速定位是Source问题还是Sink问题。我自己备了好几块不同品牌的HDMI 2.1接收板。
3.5 知识体系:FRL Start同步检测故障树
下面这张图是我自己整理的一个故障树,方便你在调试时对照:
3.6 实战避坑清单
最后,我还是想把这些年踩过的坑总结成一张检查表,你可以直接打印出来放在调试台旁边:
| 检查项 | 具体行动 | 常见错误案例 |
|---|---|---|
| Source输出的FRL Pattern幅值 | 在连接器处量差分电压,目标≥700mVpp | 某方案用0.8V电源给PHY供电,实际输出只有600mV |
| Sink参考时钟精度 | 用频率计测,要求≤±50ppm(建议±25ppm) | 一批晶振来料精度正常,但回流焊后漂了30ppm |
| PCB走线阻抗 | 用TDR测单端50Ω±5%,差分100Ω±5% | Via段阻抗突降到70Ω,导致反射 |
| 均衡训练前信号质量 | 看眼图交叉点,要求抖动≤0.2UI | 长线缆下抖动到0.35UI,CDR失锁 |
| 模式切换的时序参数 | 检查Source寄存器中的tFRAME、tSYNC值 | 某SDK默认tSYNC=1ms,但Sink要求≥3ms |
| AUX交互日志 | 抓取FRL Start阶段的AUX事务 | Source发了Start Request,Sink没回应(I2C读写失败) |
嗯,以上就是我对训练初始化阶段常见问题的总结。如果你在实际调试中遇到别的怪现象,不妨回来对照这张故障树,或者直接拿着示波器去量最前端的信号。相信我,九成问题都出在物理层,别一上来就怀疑协议栈。