USB OTG学习笔记

http://blog.youkuaiyun.com/ccwwff/article/details/6334789

仅仅看了半天SPEC写的笔记,有些乱,等调试完毕再次整理,思路不是很成熟,推测成分较多,可能有不对的地方,欢迎拍砖交流指正。
 
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.协议
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。

ADP(Attach Detection Protocol):
提供设备检测是否有对端设备插入。
支持:任何OTG设备,Embedded Host,支持SRP的B-Device允许ADP Probing,B-Device和仅能作为外设的B-Device还必须支持ADP Senseing如果他们支持ADP Probing。

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,完成设备 连接。

6.OTG Device(Host/Device)与普通USB Host/Device
OTG Device(Device)插入普通USB Host:
SPEC指示OTG Device满足所有USB外设条件,电器原理实现未查明。
普通USB设备插入OTG Device(Host):
OTG兼容,但是电器原理实现未查明,对VBus的打开,以及ADP和SRP的处理有疑问。在usb.org上有人问起这个问题,回复只是讲会识别并且兼容,但是实现原理及监测细节未知。
原贴地址:

最新的一些思考和猜想:
1.ADP是OTG Device作为Host,既可以关闭VBus又能够监测普通USB设备的关键。

2.OTG Device作为Host如果不支持ADP,但是支持SRP的,VBus应当始终打开(或者通过插入中断?RootHub Polling),如果要关闭VBus则仅能支持会发起SRP的OTG Device,普通的USB设备和不支持SRP的OTG Device,在Host没有ADP的情况下无法在关闭VBus的情况下检测到设备(除了插入中断)插入并且通过SRP打开VBus。

注: OTG Device作为Host在A插头插入时会尝试打开VBus,如果插入设备线缆在A插头插入时已经连接完毕,则在这次插入时,正常枚举。如果插入设备线缆 在A插头插入时没有连接,作为Host的OTG Device又不支持ADP,但是支持SRP,那么插入设备可以在线缆插入后发起SRP打开VBus,如果插入设备不支持SRP。则设备工作不正常?

3.OTG Device在监测总线活动和设备连接前会在插头插入时首先检测插头(普通USB不会检测插头,因为不关心,OTG的ID引脚会起控制器中断),从而决定OTG Device角色,并且通过ADP等待设备连接,然后打开VBus进行总线活动。

关于SRP与ADP
作为一个B-Device或者是普通的USB Device,怎样打开VBus进行总线枚举是他们的最终目的。
SRP为B-Device请求A-Device打开A设备的手段之一,而ADP虽然作为检测插入设备为目的但是有些EH/OTG Device会在ADP检测到状况以后不等到SRP的到来(或者说不支持SRP)就打开VBus,倘若没有设备连接,再关闭VBus并且打开ADP继续侦 测(仅限于OTG Device EH不会),更有甚者检测完A插头直接打开VBus(ADP出来的较晚,很多早期的OTG控制器中,根本没有ADP和HNP Polling的字样,估计那时候可能SPEC里面还没有这些东西)这让SRP显得有些多余,但是我们作为一个B-Device的时候还是应当在开始总线 操作前发出SRP,保证不支持ADP只支持SRP并且插头插入时不打开VBus仅仅在受到SRP才打开VBus的控制器上,设备也能进行正常枚举。




Mentor Graphics USB OTG Controller IP Core调试笔记

MUSBHDRC与 MUSBMHDRC是Mentor Graphics出品的兼容支持OTG功能的IP Core被广泛的应用于 TI ADI的多媒体处理器中。两个IP的区别在于MUSBMHDRC带有Multipoint功能,可以接HUB。下面是我在FPGA上调试碰到的问题及解 决,欢迎交流拍砖。

MUSBHDRC RTL V1.8版本
BUG及解决
1.中断不会Pending
MUSBHDRC在关闭EP中断的情况下不会去置中断位,这样再次打开中断时,因为中断没有Pending,直接导致本次中断丢失。而 Mentor的做法也相当的令人鄙视,竟然只是在Datasheet中悄悄的把原先版本Datasheet中的中断会Pending的那句话悄悄的去掉。
解决:
只能在SOC级解决,Davinci的解决方法把相关的寄存器Shadow了一下,不允许操作原来MUSBHDRC中的相关中断寄存器而转而使用SOC提供的相关寄存器。

2.DMA部分的BUG
MUSB系列的DMA模式分为3种。DMA MODE 0,DMA MODE 1 REQ MODE 0, DMA MODE 1 REQ MODE 1。
其中DMA MODE 1 REQ MODE 1在MUSBHDRC上无法正常工作,一旦FIFO里有Packet,并且< MAXP 则不会再来中断。
DMA MODE 1 REQ MODE 0在连续的发起DMA请求时候会挂住总线,导致系统锁死,而且因为DMA MODE 1 REQ MODE 0必须知道数据总量的限制,在很多的USB上层的协议中都无法使用。
DMA MODE 0在Device方式时效率低下,不考虑。
解决:
只能在SOC级解决,可以见到Davinci和TUSB都没有使用MUSBHDRC的DMA控制器,都是在SOC上做了一个DMA控制器实现相关DMA操作。

MUSBMHDRC
基本解决了MUSBHDRC中的相关BUG,并且增加了Multipoint功能。可惜Linux驱动中尚没有端点复用及调度相关代码,所以目前仍然不可能支持太多数量的USB设备。

关于ID Pin中断
MUSB系列没有提供ID Pin的中断,而我们从Controller看到的A/B Device逻辑也相当的奇怪。在A-Device状态下,写DEVCTL.SESSION则PHY拉起VBUS,DEVCTL.B-DEVICE和 DEVCTL.VBUS Session才有效,也就是说我们必须开始Session软件才能知道是目前A-Device还是B-Device,这在OTG状态机的A- Device向B-Device状态推进时会出现很大问题:驱动这边会出现许多协议里没有的状态变迁。这样在OTG Device-> Host 时插头发生变化而软件不知,没人来Drive VBUS,直接导致哑炮熄火(有朋友说我的没有啊,只是有时好用有时不好用,原因后面揭开)。而Host-> Device时,Host设备拔出时停留在A_WAIT_BCON状态,在换上B-Device插头时状态机没有经过A_WAIT_BCON-> A_WAIT_VBUS_FALL-> A_IDLE->B_IDLE的变迁,直接导致驱动程序中状态机状态变迁异常,而Davinci采取了Timer不停地写Session的方法来 Workaround,但是不是解决问题的根本,而我们又不能总是通过Session来检测,最根本的解决方法就是外加一个ID Pin中断来检测插头,同时推进状态机。

诡异的Session Request中断
在Datasheet中,这是一条仅仅会在Host方式下来的中断,但是在实际使用中,这条中断来的十分诡异,B-Device状态下有时候会 在插入B插头时每隔3-5秒来一次,有时候又不来,有时候没插插头时也回来,飘忽。而驱动中收到Session Request中断则立即Driver VBUS,这解释了前面Device->Host时而好用时而失效的原因。
解决:
走正规的ID PIN检测关闭此中断,在检测到A插头插入时立即打开Session -> Drive VBUS,这样就不用关心对方设备的SRP了。

关于Device方式下SetAddress的注意
按照Datasheet中的流程在收到Setup包的时候即可设置FADDR改变当前的Address,然后清掉RXPKTRDY并且置位 DataEND 回复0包,并且使Controller进入控制传输的Status Stage,完成后来一个MC_INT中断。实际则不然,如果这样操作会导致MUSB Controller失去响应,在协议分析仪上看到Controller在接下来的Get Deor的SETUP Transaction中的IN Token中没有任何回复,或者回复一些NAK后,失去响应。

正确的操作方法为:收到SetAddress以后,不要立即设置FADDR,在Status Stage结束后来的那次中断中设置SETUP包中的传来的地址。

关于DMA MODE 1 REQ MODE 1
Device方式下DMA MODE 1 REQ MODE 1为兼容性和效率最佳方式。然而在Host方式下只能使用DMA MODE 0。归根结底在于DMA MODE 1 REQ MODE 1的结束条件< MAXP 倘若Host连续开启两个IN Transaction,每个IN Transaction大小为MAXP的倍数,则在DMA停止时无法区分两个包,前一次IN Transaction因为结束时还满足DMA MODE 1 REQ MODE 1的条件,直接导致DMA控制器将下一个IN Transaction的包已经收到了FIFO/URB中,如果所有IN Transaction 如果都能被MAXP整除,开始的那个URB岂不成一团浆糊了。

解决:控制器设计问题非BUG无法解决,使用DMA MODE 0。

关于Linux中的驱动程序。驱动位于drivers/usb/musb下。
代码中没有端点复用和调度部分,因此Multipoint功能极大受限。Interrupt及Isochronous方式传输似乎有问题,尚未研究。

关于VBUS_ERROR的缺陷。
在一些需要电量较大的设备插入时MUSB在写入Devctl.Session时候VBus拉不起来,并且产生VBUS_ERROR中断,接下来 难堪的问题发生了,Controller居然切到B-Device状态,再也不能通过写Session拉起VBus。尚未找到恢复方法。
USB-IF高速;,经认证符合通用串行总线规范修订版 2.0 接口在 8 位模式下与 ULPI 规范修订版 1.1 兼容 工业标准 UTMI+ 低引脚接口 (ULPI) 可将 54 UTMI+ 信号转换为标准的 12 引脚链路控制器接口 54.7mA 未配置电流(典型情况)— 适用于总线供电的应用 83uA 挂起电流(典型情况)— 适用于电池供电的应用 闭锁性能超过 150 mA(每 EIA/JESD 78),Class II ESD 防护水平达 ±8kV HBM(在不使用外部保护设备的情况下) 集成了各种保护措施,在每个第三方的测试设备中均可耐受 IEC61000-4-2 ESD 测试(±8kV 接触电压和 ±15kV 空气电压) 支持用于附带 LS 设备的 FS 集线器的 FS 前导码 (UTMI+ Level 3) 支持 HS SOF 和 LS keep-alive 脉冲 包括对可选的 On-The-Go (OTG) 协议的全面支持,在 On-The-Go 附录修订版 1.0a 规范中有详细说明 支持 OTG 主机协商协议 (HNP) 和会话请求协议 (SRP) 允许主机关闭 VBUS,以便在 OTG 应用中节省电池电量 通过内部比较器支持 VBUS 电平的 OTG 监视。包括对外部 VBUS 或故障监视器的支持。 低潜伏高速接收器(最高为 43 高速时钟)允许使用带 ULPI 包装器的潜伏 UTMI 链路 用于接口保护的 STP 上的集成下拉电阻,允许在使用低速链路(针对低功率情况对软件进行了配置)的情况下,可靠地启动 Link/PHY 内置的 1.8V 调节器允许在使用单个 3.3V 电源的情况下工作 对 ID、DP 和 DM 线路到 VBUS 或接地进行内部短路保护 集成的 24MHz 晶振支持水晶操作或 24MHz 外部时钟输入 用于 480MHz 高速 USB 操作的内部 PLL 工业运行温度:-40°C 到 +85°C 符合 RoHS 的 32 引脚无铅 QFN 封装(5 x 5 毫米, 高度为 0.90 毫米)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值