2、链路训练基础:LTSSM状态机详解、链路训练序列(Polling, Detect, Training)、电气空闲与信号检测
链路训练,说白了就是USB设备之间互相“握手”的过程。我刚开始接触USB3.0时,总觉得这步很简单——不就是插上去就能用吗?后来在项目中遇到一次诡异的断连问题,折腾了两周才发现是训练序列没走对。嗯,从那以后我再也不敢小看LTSSM了。
2.1 LTSSM状态机:链路的“交通指挥”
LTSSM的全称是Link Training and Status State Machine。你可以把它想象成一个交通指挥系统。每个USB端口都内置了这套逻辑,负责协调链路从无到有、从休眠到工作的全过程。
我个人习惯把LTSSM的状态分成三大类:
- 初始化状态:Detect、Polling、Configuration、Recovery。链路刚建立或出问题后,先走这些状态。
- 电源管理状态:U0、U1、U2、U3。U0是正常工作,U1/U2是浅睡眠,U3是深度休眠。
- 错误处理状态:Rx.Detect、Hot Reset、Loopback。链路出岔子时,靠这些状态兜底。
你想想看,如果两个设备插在一起,一个在Detect状态,另一个却在U3休眠,那肯定没法通信。LTSSM就是确保双方“步调一致”的机制。
核心要点:LTSSM的每个状态切换,都对应着特定的电气信号变化。比如从Detect进入Polling,必须检测到接收端有端接电阻存在。我在项目中遇到过,有次因为PCB走线过长导致信号衰减,接收端电阻没被正确识别,结果链路一直卡在Detect状态出不来。
下面这张图是我手绘的LTSSM核心状态流转逻辑,你可以对照着看:
2.2 链路训练序列:Detect、Polling、Training
链路训练序列,就是LTSSM在初始化阶段发送的一组特定数据包。每个序列都有明确的目的。我习惯把它们拆开来看:
2.2.1 Detect 阶段
Detect是链路训练的起点。发送端会发出一个短脉冲,检测接收端是否有端接电阻存在。说白了,就是先确认“对面有没有人”。
- 电气特征:发送端输出一个约1ms的脉冲,然后测量线路上的反射。
- 成功条件:检测到接收端有正确的端接电阻(通常为45Ω ± 10%)。
- 失败处理:如果没检测到,LTSSM会重复Detect,直到超时或复位。
我的经验:曾经有个项目,USB接口在低温环境下经常检测不到设备。后来发现是端接电阻的温漂太大,低温时阻值超出了45Ω的容差范围。换成低温漂电阻后问题解决。所以选型时别只看常温参数。
2.2.2 Polling 阶段
Detect成功后,链路进入Polling。这个阶段的主要任务是:双方交换训练序列(TS1/TS2),协商链路参数。
Polling又细分为几个子状态:
| 子状态 | 动作 | 典型时长 |
|---|---|---|
| Polling.LFPS | 发送LFPS脉冲,唤醒接收端 | ~10ms |
| Polling.RxEQ | 接收端进行均衡训练 | ~5ms |
| Polling.Active | 交换TS1/TS2序列 | ~2ms |
| Polling.Configuration | 确认链路宽度和极性 | ~1ms |
你可能会问:为什么要分这么多子状态?因为每个子状态都在解决一个具体问题。比如Polling.RxEQ,就是让接收端调整它的均衡器参数,补偿高频信号在PCB走线上的衰减。我见过有些设计直接跳过这个子状态,结果高速信号眼图惨不忍睹。
2.2.3 Training 序列(TS1/TS2)
TS1和TS2是Polling阶段的核心数据包。它们包含以下关键信息:
- 链路编号:标识当前链路属于哪个端口。
- 链路宽度:协商是x1、x2还是x4模式。
- 极性反转标志:如果PCB走线时把差分对的正负接反了,这里可以纠正。
- 均衡请求:接收端告诉发送端“你的信号太强了,降一点”或“太弱了,加一点”。
注意:TS1和TS2的格式在USB3.0和USB3.1/3.2中略有不同。USB3.0使用8b/10b编码,而USB3.1之后改用128b/132b编码。如果你在做兼容性测试,一定要确认双方支持的版本。我曾经遇到一个USB3.0的U盘插在USB3.1的电脑上,训练序列一直失败,最后发现是TS2包里的均衡参数不兼容。
2.3 电气空闲与信号检测
电气空闲(Electrical Idle)是USB链路中一个容易被忽视的概念。说白了,就是链路上没有数据传输时的状态。但“没有数据”不等于“没有信号”。
在电气空闲状态下,发送端会输出一个共模电压(通常为0V),差分信号摆幅为0。接收端则通过检测差分信号幅度来判断链路是否处于空闲状态。
信号检测(Signal Detection)是接收端的一项基本功。它需要区分三种情况:
- 链路空闲:差分幅度为0,共模电压正常。
- 链路活动:差分幅度超过阈值(通常为100mV)。
- 链路断开:差分幅度为0,且共模电压也为0(或者浮动)。
我建议你在调试时重点关注信号检测的阈值。有些PHY芯片的阈值是可编程的,默认值可能不适合你的PCB设计。比如,如果PCB走线较长,信号衰减大,接收端可能检测不到有效的差分信号,误判为电气空闲。这时候就需要降低检测阈值。
避坑指南:我曾经调试过一个USB3.0的摄像头,插上后偶尔能识别,偶尔不行。用示波器抓了波形才发现,问题出在电气空闲检测上。摄像头端的PHY芯片在空闲时输出的共模电压有微小波动,而主机端的检测电路过于灵敏,把这种波动误判为信号活动,导致LTSSM状态混乱。解决办法是在PHY配置寄存器里加了一个50mV的迟滞窗口。
最后说一句,链路训练失败的原因千奇百怪,但80%的问题都出在Detect和Polling这两个阶段。要么是端接电阻没匹配好,要么是TS序列里的参数没协商成功。你只要把这两个阶段的逻辑吃透,大部分问题都能迎刃而解。
公众号:蓝海资料掘金营,微信deep3321