1.概要
OTG设备使用插头中的ID引脚来区分A/B Device,ID接地被称作为A-Device,为连接时候的USB Host,A-Device始终为总线提供电力,ID悬空被称作为B-Device,为连接时候的USB Device,设备的USB Host/USB Device角色可以通过HNP切换。
OTG设备连接时不能跨越USB Hub,如果跨越USB Hub则失去HNP功能。
这里要注意A-Device/B-Device与USB Host/Device不是一回事没有必然的绑定关系A-Device就一定要是Host,A-Device只是连接时的Host可以通过HNP切换,切换完毕A-Device变成USB Device但是仍然为总线提供电力。
2.设备类型
Embedded Host:提供标准的A插座,普通的USB Host并带有TPL(支持设备列表)
OTG Device:使用Micro AB插座,可以在运行时切换Host/Device。
仅外设B-Device:仅仅能作为外设的B-Device(分为插头一体和插头线缆分离的)。
注意:OTG Device在插头插入后会先打开VBus,如果没有设备连接则关闭VBus,并开启ADP侦测,而Embedded Host则不会再次关闭VBus。
3.协议
(1)SRP(Session Request Protocol):B-Device使用。通过数据线上的脉冲,请求A-Device打开VBUS并且开始一个Session。Session为从VBUS打开到关闭这一段时间。
支持:A-Device允许回应SRP,B-Device(包括仅能作为外设的B-Device),允许发起SRP。一个能够支持HNP的B- Device应该能够发起SRP。当A插头插入时关闭VBus的Host必须支持回应SRP,VBus总是打开的Host不必响应SRP。
(2)ADP(Attach Detection Protocol):提供设备检测是否有对端设备插入。
支持:任何OTG设备,Embedded Host,支持SRP的B-Device允许ADP Probing,B-Device和仅能作为外设的B-Device还必须支持ADP Senseing如果他们支持ADP Probing。
(3)HNP(Host Negotiation Protocol):OTG设备通过HNP来切换Host/Device角色。
当前的USB Host通过HNP Polling(类似Polling Hub)通过轮询GetStatus()命令返回的数据中的Host request flag查询对端设备是否请求变为Host,Polling间隔为1-2秒。
当前的USB Host决定允许B-Device转变为Host以后通过SetFeature()打开b_hnp_enable,本次Session结束后Host回到A-Device手里。
4.设备框架
OTG描述符
在设备枚举时,A-Device通过GetDeor向B设备请求OTG描述符。OTG描述符也应当作为GetConfiguration()的一部分返回。其中的bmAttributes标示B-Device是否支持ADP/HNP/SRP标准设备特性,通过SetFeature()设置。
b_hnp_enable
设置此特性,显示B-Device被允许进行HNP,A设备必须在T(HOST_REQ_SUSP)时间内挂起总线。
a_hnp_support
早期OTG版本的兼容特性,设置这个特性指示B-Device对端的A-Device支持HNP。A-Device应当对B-Device设置此特性如果A-Device支持HNP。
a_alt_hnp_support
废弃
GetStatus()
其中数据部分OTG Status最低位为Host Request flag,指示当期的USB Device角色期望变为USB Host角色。
5.一般连接过程(Host -> Device)
OTG Device /Embedded Host 与 仅作为外设的B-device(带A插头型)
Host端检测到A插头插入,停止ADP,打开VBus,因为B-Device的A插头与设备作为一体,此时B-Device必定与A插头连接,Host检测到外设连接,开始枚举。
OTG Device/Embedded Host 与 仅作为外设的B-device(A插头为线缆连接)
Host段检测到A插头插入,停止ADP,打开VBus,如果B-Device是线缆连接完毕在将A插头插入则整个连接过程与上面无异,因为此时B-Device可能还没有插入插头,则设备连接超时,VBus再次关闭,等待下一次ADP的改变(线缆连接完毕),再次打开VBus,此时开始正常总线枚举。
OTG Device 与 OTG Device
Host端检测到插头插入,则打开VBus,如果没有外设检测到,则关闭VBus,打开ADP Probing,Device端检测到插头插入,则打开SRP,如果线缆没有插入,则SRP超时,Device端开始进行ADP Probing,当线缆连接完毕,Device端侦测到ADP变化,发送SRP请求Host打开VBus,Host回应SRP并且打开VBus,完成设备连接。
USB插入检测过程,看下面一个简单的电路,Samsung Exynos4412平台的例子:
电路描述:CON1为micro usb连接器,VBUS连接系统XuotgVBUS脚,同时提供一个中断输出脚到XEINT28
同时外部一个DC5V经过控制芯片也输出到XuotgVBUS,作为host时需要用到给外部供电
ID脚上拉1.8V作为Host/Slave检测,同时提供另一个中断输入脚到XEINT29
该设备支持OTG,下面说下设备的发现过程:
作为从设备插入PC端口时:
1. 系统检测到VBUS上的XEINT28上升沿触发中断,因为PC端会有一个5V从VBUS给过来,进入中断处理函数进一步确认ID脚状态,ID脚为低则状态错误,ID脚为高表示设备应该切换到从设备模式
2. 通知usb gadget使能vbus,按照device模式使能PHY。gadget在probe时注册了一个SPI软中断IRQ_USB_HSOTG,用于响应数据接收
3. 开启usb clk,使能PHY,此时外部5V电源供给系统XuotgVBUS,gadget收到IRQ_USB_HSOTG中断要求重启OTG core
4. USB DP(高速设备为DP,低速设备为DM)上产生一个高电平脉冲,此时PC识别到一个USB设备插入,windows会提示用户
5. 后续就是SETUP,GET DISCRIPTOR的过程
作为主设备发现设备插入时:
1. 系统检测到ID脚上XEINT29下降沿触发中断(实际是插入的usb公口第四脚直接连接到第五脚地上面),进入中断处理,切换到主设备模式
2. 关中断,使能DC5V给VBUS上电,唤醒ehci与ohci
3. usb core在内核初始化时注册了一个名为khubd的内核线程,由khubd监控port event。(实际过程我理解是从设别由VUBS供电后,会在DP或DM上产生一个高电平脉冲
ehci在接收到脉冲信号后识别到设备插入,仅仅是理解,这一点未验证)
4. khubd获取port,speed后交给ehci,接下来就是usb的SETUP,GET DISCRIPTOR过程