2、链路训练与速度协商:Polling状态详解、速度协商的握手过程、我遇到过的协商失败案例
2.1 Polling状态——链路训练的“起跑线”
LTSSM状态机里,Polling状态是个很有意思的环节。说白了,它就是链路两端互相“打招呼”的阶段。我刚开始接触USB时,总觉得这步很简单——不就是发个信号嘛。后来踩了坑才明白,这里面的门道多着呢。
Polling状态的核心任务就两个:
- 检测对端是否存在——看看对面有没有设备接着
- 确定初始速度——大家商量好用多快跑
你想想看,两根线刚插上,谁都不知道对方是什么水平。这时候就得靠Polling状态来“破冰”。
关键点:Polling状态必须在100ms内完成。超时了?LTSSM会直接跳回Detect状态重新来。我见过不少板子就是因为这个超时设得太紧,导致兼容性问题。
2.2 速度协商的握手过程——谁先说话?
速度协商的握手,其实有点像两个人见面握手——你先伸手,我回应,然后大家确认力度合适。
具体流程是这样的:
- Host先发TS1序列——相当于说“喂,有人吗?”
- Device收到后回TS2序列——“我在呢,你什么速度?”
- 双方交换速度能力——通过TS1/TS2里的Speed Change字段
- 达成一致——选一个双方都支持的最高速度
嗯,这里要注意。TS1和TS2序列里有个叫“Speed Change”的bit,它决定了这次协商是继续还是结束。我记得有一次调试,发现Device老是回NACK,抓了波形一看——Speed Change bit没置对。这种问题,光看代码是看不出来的。
我的习惯:每次做速度协商调试,我都会先抓一下TS1/TS2序列的波形。看看Speed Change bit是不是按预期翻转。这招帮我省了不少排查时间。
2.3 我遇到过的协商失败案例
做USB验证这些年,协商失败的案例我见过不少。挑两个典型的说说。
案例一:信号质量问题导致Polling超时
有一次,客户反馈说他们的USB 3.0设备在特定主板上老是枚举失败。我排查了半天,发现Polling状态总是超时。抓了眼图一看——信号质量太差了,抖动大得离谱。
原因是什么?PCB走线没做阻抗匹配。Host端发出的TS1序列,到了Device那边已经变形了。Device根本认不出来,自然没法回应。
解决办法:调整PCB走线,加了一对AC耦合电容,问题就解决了。说白了,很多协商失败的问题,根源都在物理层。
案例二:固件逻辑Bug导致速度降级
另一个案例更有意思。设备能正常枚举,但速度始终跑在5Gbps,上不了10Gbps。我一开始以为是信号问题,查了一圈发现眼图挺好的。
后来仔细看了固件里的速度协商逻辑——原来Device在收到Host的TS1后,判断速度的算法写错了。它总是把自己降级到5Gbps,哪怕Host支持10Gbps。
避坑指南:我曾经因为一个if-else的顺序问题,让整个团队多花了两周时间排查。速度协商的代码,一定要仔细检查优先级逻辑。别让低级错误浪费大家的时间。
2.4 知识体系图:Polling与速度协商的核心逻辑
下面这张图,是我自己总结的Polling状态与速度协商的完整流程。你可以把它当作调试时的参考地图。
2.5 调试建议
最后,分享几个我自己的调试习惯:
- 先看物理层——眼图、抖动、信号幅度。很多协商问题都是信号质量引起的。
- 抓TS1/TS2序列——用逻辑分析仪或示波器抓一下,看看Speed Change bit是不是对的。
- 检查超时配置——Polling超时时间别设得太紧,留点余量。
- 固件代码逐行审查——特别是速度判断的if-else逻辑,别让顺序坑了你。
一个小技巧:我习惯在固件里加个调试打印,把每次协商的速度值打出来。这样不用抓波形,就能快速定位是Host还是Device的问题。省时省力。
好了,Polling状态和速度协商就聊到这儿。下一节我们聊聊Configuration状态——链路训练里最容易被忽视的环节。
公众号:蓝海资料掘金营,微信deep3321