3. 链路训练状态机(LTSSM):状态定义与转换

搞 USB 3.0 协议,最绕不开的就是 LTSSM 。全称 Link Training and Status State Machine。

你想想看,一条 USB 3.0 链路从物理连接到真正能传数据,中间要干多少事?

  • 先判断对面有没有设备
  • 然后对齐位、做握手
  • 接着协商速度、通道数目
  • 再调均衡参数
  • 最后才能进入正常工作模式

这些步骤不是瞎来的。LTSSM 就是把这些流程串起来的状态机。我个人习惯把 LTSSM 理解为“链路的生命轨迹”。它规定了每条差分对在什么时刻该干什么。你在示波器上看到的那些电平跳变、低频周期性信令(LFPS)、训练序列……背后全是 LTSSM 在驱动。

小提醒:调试 USB 3.0 链路问题,第一步永远先查 LTSSM 卡在哪个状态。我有几次在客户现场排查断连问题,打开分析仪一看,状态在 Polling 和 Configuration 之间反复回退——典型的阻抗不匹配。调一下Tx 均衡就解决了。

3.1 状态概览

USB 3.0 规范把 LTSSM 分成十多个状态,但常用的核心状态就那么几个。我画了个简化的状态转换图,方便你建立整体印象。

LTSSM 核心状态转换图 Rx.Detect Polling Configuration U0(工作) Recovery U1 / U2 / U3(低功耗) 检测到接收端 位锁定+TS1交换 均衡协商完成 链路错误/超时 恢复失败→重训练 空闲/指令 退出低功耗 说明:实线为主路径,虚线为备用/异常路径。实际规范中还有更多中间状态。

从上图可以看到,链路从 Rx.Detect 开始,经过 Polling、Configuration 到达 U0,这是正常工作的主路径。一旦链路上出现错误或者对方请求进入低功耗,就会迁移到 Recovery 或 U1/U2/U3。

3.2 每个状态是干什么的?

下面我按顺序拆开讲。每个状态都有明确的目的,别搞混了。

3.2.1 Rx.Detect —— 探测对面是否有接收端

这是物理链路通电后干的第一件事。主机端口会输出一个短的 DC 电平,依靠接收端端接电阻产生的反射来判断。

  • 条件:端口上电后,如果没有检测到终端,就一直刷 Rx.Detect。
  • 成功转换:检测到接收端 → Polling
  • 失败处理:超时后重试,如果连续失败就进入 SS.Disabled。
实战经验:我在一款 Type-C 扩展坞上遇到过 Rx.Detect 反复失败。原因是 Type-C 的 CC 逻辑把 VBUS 切换慢了,导致接收端芯片还没上电,检测脉冲就打过去了。加了个简单的上电延迟,问题就没了。

3.2.2 Polling —— 位锁定与链路训练

一旦确认对面有人,马上发训练序列(TS1/TS2)。目的是让接收端的 CDR(时钟数据恢复)锁定频率和相位,同时让双方知道对方的存在。

Polling 里有两个子状态:Polling.Active 和 Polling.Passive。你别被名字吓到,其实就是谁主导发序列的问题。

子状态 行为 我遇上过的坑
Polling.Active 主动发送 TS1 序列,期待收到对方响应 信号质量差时,接收方 CDR 无法锁定,一直超时重试
Polling.Passive 只接收不发送,等待对方先完成锁定 链路两端的相位差太大,被动方容易收不到有效序列

3.2.3 Configuration —— 均衡与宽度协商

这是链路训练中最关键的一步。在这里双方要交换均衡参数(TxEQ Preset)、协商通道宽度(x1/x2/x4)、并做电源模式协商。

我记得有一次客户报告 USB 3.0 偶尔掉盘,抓 log 发现总是卡在 Configuration 状态。后来我打开示波器看训练序列,发现 Preset 值从主机发过去,设备回了一个不支持的 Preset 值。主机不认可,就一直重发。

注意:Configuration 阶段的均衡参数必须匹配。如果两端的 Preset 值不在对方支持的范围内,链路永远到不了 U0。调试时建议先用最保守的 Preset(比如 Preset 0 或 1)试试,排除芯片兼容性问题。

3.2.4 U0 —— 正常工作状态

走到这一步,恭喜你,链路通了。U0 状态里,数据可以随时双向传输。但别以为万事大吉。

U0 状态下链路仍然需要监视信号完整性。一旦误码率超过阈值(通常是 10⁻¹²),就会触发 Recovery 状态。

3.2.5 Recovery —— 链路修复与重新训练

Recovery 不是错误状态,它更像“临时刹车”。用来快速重训练,尝试恢复链路而不必回到 Polling 重新来一遍。

Recovery 里也有子状态:Recovery.Active、Recovery.Configuration 等。具体怎么做我不细说,你记住两点就够了:

  • 如果 Recovery 成功,回到 U0。
  • 如果 Recovery 失败(比如超时或收到错误序列),跳回 Polling 甚至 Rx.Detect。

我曾经在 EM 测试中发现机壳接地不良时,Recovery 反复失败。每隔几秒链路上就出现一次幅度波动,跟着就掉到 Polling。折腾了一个星期才找到是接地螺丝松了。

3.2.6 U1/U2/U3 —— 低功耗状态

USB 3.0 支持多种省电模式。U1、U2、U3 的功耗依次降低,退出延迟也依次增大。这里我不展开,你只需要知道退出低功耗状态时需要走 Recovery 而不是直接回到 U0。

3.3 状态转换的关键判断条件

为了让你调试时更有方向,我整理了一张表,列出最常见的转换触发条件。

当前状态 转换条件 目标状态
Rx.Detect 检测到接收端终端 Polling
Polling 完成 TS1/TS2 交换,位锁定 Configuration
Configuration 均衡参数协商完成,进入 U0 U0
U0 链路错误或超时 Recovery
U0 空闲进入低功耗 U1/U2/U3
Recovery 训练成功 U0
Recovery 失败超时 Polling / Rx.Detect
U1/U2/U3 退出低功耗 Recovery
我的个人习惯:调试时用协议分析仪锁定 LTSSM 状态变化。如果看到状态在 Polling 和 Configuration 之间来回跳,先怀疑均衡参数不匹配或者信号质量差。如果看到 U0 掉到 Recovery 再掉到 Polling,大概率是物理层噪声导致 CRD 失锁。

3.4 避坑指南

最后聊几个我踩过的坑,希望你别再碰。

  • Rx.Detect 假检测:有些端口对噪声敏感,会把终端检测搞成误触。我建议在硬件设计上给 Rx.Detect 加个去抖定时器,软件里也可以多读两次状态确认。
  • Polling 阶段 CDR 锁不住:很多情况是时钟抖动太大。检查 PLL 环路带宽,适当降低参考时钟的抖动指标。
  • Configuration 阶段 Preset 不匹配:设备芯片和主机芯片可能来自不同厂家,支持的 Preset 集合不一样。如果协商失败,尝试手动固定 Preset(比如都用 Preset 0),排除兼容性问题。
  • Recovery 频繁触发:这通常是电源噪声或者信号完整性下降的早期信号。不要只盯着状态机,去量一下供电纹波和信号眼图。

嗯,LTSSM 的状态定义和转换说完了。你给我一张图(上面那张),再对照表格和流程,基本就能看懂大部分链路训练行为。下一段我们真正上手实操,看看怎么用逻辑分析仪抓 TS1/TS2 序列,以及怎么通过调整均衡参数推动链路通过 Configuration。先消化这些基础状态吧。