OTG协议基础:主机与设备角色切换原理
传统USB的世界里,角色是固定的。电脑永远是主机,U盘、鼠标永远是设备。但OTG打破了这种硬绑定。你想想看,两台手机能不能直接传文件?打印机能不能没电脑就自己打照片?OTG说:可以。核心就是让设备能动态切换主从角色。嗯,这里有个关键——靠物理层加协议层配合完成。
从ID引脚到会话
OTG里,每个设备都有一个ID引脚。这个引脚接地还是悬空,直接决定了初始角色。
- ID接地:该设备初始作为A设备(主机角色),负责提供VBus电源。
- ID悬空:该设备初始作为B设备(外设角色),等待主机供电。
我在项目中遇到过一根OTG线内部ID引脚虚焊,结果设备插上后一直认成B设备,主机端死活枚举不到。查了三天,最后用万用表量ID对地电阻才找到问题。说白了,物理层不牢,协议层再对也没用。
另外还有一个概念叫“会话”(Session)。会话是指A设备提供VBus电源、B设备可以正常通信的那段时间。会话的开启、维持和结束,由SRP和HNP共同管理。
HNP:角色切换的握手协议
HNP的全称是Host Negotiation Protocol。它让B设备能申请成为主机,A设备可以主动让出主机角色。整个过程分三步:
- 初始分配:上电后,根据ID引脚确定A、B角色。A设备拉起VBus,开始会话。
- 请求切换:B设备觉得自己更适合当主机(比如它想读A设备里的数据),就在总线空闲时拉低D+线超过2ms,向A设备发出切换请求。
- 角色互换:A设备检测到B设备的HNP请求后,释放总线控制权(停止驱动VBus并断开DP/DM的上拉电阻),B设备随后拉高D+并开始驱动VBus——身份互换完成。
注意一点:HNP不是所有OTG设备都实现的可选功能。很多简单的OTG设备(比如读卡器)只做B设备,根本不支持HNP。你如果想让手机当主机去控制另一个设备,那个设备必须支持HNP才行。
SRP:唤醒沉睡主机的秘密
SRP(Session Request Protocol)解决的是另一类场景:如果A设备认为会话超时、为了省电关掉了VBus,B设备该怎么把它叫醒?
SRP分两个阶段:
- 数据线脉冲:B设备先在D+(或D-)上输出一个脉冲(~20ms),告诉A设备“我想开始通信”。
- VBus脉冲:如果A设备在线,它会回应一个VBus脉冲(维持电流>8mA),表示“我准备好给你供电了”。
我记得有一次客户反馈,手机接上U盘后插拔一次就再也识别不到了。追下去发现是U盘(B设备)发完SRP数据脉冲后,手机(A设备)没检测到VBus脉冲——因为手机端USB PHY在低功耗模式下把VBus检测功能关了。嗯,这里要注意,SRP的接收端必须始终保持VBus检测能力。
HNP与SRP对比一览
| 特性 | HNP | SRP |
|---|---|---|
| 目的 | 交换主机/外设角色 | 请求A设备重新供电 |
| 触发者 | B设备(请求成为主机) | B设备(请求恢复VBus) |
| 前提 | 会话已建立 | 会话已结束或未开始 |
| 物理信号 | D+线拉低≥2ms | D+脉冲 + VBus脉冲 |
| 典型应用 | 手机互传文件 | U盘插入无供电手机 |
完整的OTG角色切换流程
实际产品中,HNP和SRP常常交替使用。比如:B设备首次插入时可能依靠SRP唤醒A设备,建立会话后再用HNP反转角色。我画了一张流程图帮你理清关系。
角色切换的硬件保障
协议靠软件,但硬件是地基。我建议你在原理图阶段就确认以下三点:
- ID引脚必须能干净地连到地或悬空,不能有上拉/下拉干扰。
- VBus的开关(通常是一个P-MOSFET)必须能承受至少1A电流,且开通时间要小于SRP的超时窗口。
- D+/D-线上的上拉电阻(1.5kΩ)和下拉电阻(15kΩ)必须严格按照OTG规范安装,不要在BOM里随便替换成其他阻值。
调试心得
我记得刚做OTG产品那会儿,经常遇到设备插上后主机角色切换不成功。拿示波器抓ID引脚电平,发现A设备的ID在0V和3.3V之间波动——原来是机械接触不良。后来在ID引脚上并联一个100nF电容,波形才稳定下来。这种小坑,不是靠看协议就能知道的。
另外,你如果看到B设备反复发送SRP请求但A设备没反应,先别急着怀疑程序。把VBus波形抓出来,看看A设备在B设备发出数据线脉冲后,有没有在1秒内拉到有效电压。很多低功耗芯片在唤醒后需要几十ms才能准备好GPIO,这个时间差经常被忽略。