USB硬件
USB设备,从物理上的逻辑结构来说,包含了主机Host端和设备Device端。 其中,主机Host端,有对应的硬件的USB主机控制器Host Controller,而设备Device端,有对应的硬件的USB总线控制器Bus Controller。
USB Host端控制整个总线数据的传输。单个USB总线上,只能有一个Host,可通过HUB向下连接最多可127个设备,同一个总线上的设备共享该总线的带宽。USB协议本身,是不支持多个Host端的。Host端,负责所有底层数据传输的控制以及数据带宽的安排调度。
EHCI : Enhanced Host Controller Interface
NRZI : Non-Return-to-Zero Inverted
OHCI : Open Host Controller Interface
UHCI : Universal Host Controller Interface
xHCI : eXtensible Host Controller Interface
不同USB控制器类型OHCI,UHCI,EHCI,xHCI的区别和联系
USB主机控制器类型 | 共同点 | 区别 | |||
对应的USB的协议和支持的速率 | 创立者 | 功能划分 | 常用于 | ||
OHCI | 都实现了对应的USB的规范中所要求的功能 | USB 1.1=Low Speed和Full Speed | Compaq,Microsoft和National Semiconductor | 硬件功能 > 软件功能⇒硬件做的事情更多,所以实现对应的软件驱动的任务,就相对较简单 | 扩展卡,嵌入式开发板的USB主控 |
UHCI | Intel | 软件功能 > 硬件功能⇒软件的任务重,可以使用较便宜的硬件的USB控制器 | PC端的主板上的USB主控 | ||
EHCI | USB 2.0=High Speed | Intel | 定义了USB 2.0主控中所要实现何种功能,以及如何实现 | 各种USB 2.0主控 | |
xHCI | USB 3.0=Super Speed | Intel | 定义了USB 3.0主控中所要实现何种功能,以及如何实现 | 各种USB 3.0主控 |
USB NRZI编码
USB 2.0的两根数据线D+和D-所对应的数据传输,却没有详细介绍。此处就是介绍,在此串行数据线中,数据是如何被编码和传送的。
USB所传输的数据,用的数据编码方式是NRZI(Non-Return-to-Zero Inverted),首先,USB 的数据是串行发送的,就像 UART、I2C、SPI 等等,连续的01 信号只通过一根数据线发送给接受者。
但是因为发送者和接收者运行的频率不一样,信号的同步就是个问题,比如,接受者接收到了一个持续一段时间的低电平,无法得知这究竟是代表了5个0 还是1000个0。
一个解决办法,就是在传输数据信号的同时,附加一个时钟信号,用来同步两端的传输,接受者在时钟信号的辅助下对数据信号采样,就可以正确解析出发送的数据了,比如 I2C 就是这样做的,SDA 来传输数据,SCL 来传输同步时钟:
|
虽然这样解决了问题,但是却需要附加一根时钟信号线来传输时钟。有没有不需要附加的时钟信号,也能保持两端的同步呢?
有的,这就是 RZ 编码(Return-to-zero Code),也叫做归零编码。
在 RZ 编码中,正电平代表逻辑 1,负电平代表逻辑 0,并且,每传输完一位数据,信号返回到零电平,也就是说,信号线上会出现 3 种电平:正电平、负电平、零电平:
|
从图上就可以看出来,因为每位传输之后都要归零,所以接收者只要在信号归零后采样即可,这样就不在需要单独的时钟信号。实际上, RZ 编码就是相当于把时钟信号用归零编码在了数据之内。这样的信号也叫做自同步(self-clocking)信号。
这样虽然省了时钟数据线,但是还是有缺点的,因为在 RZ 编码中,大部分的数据带宽,都用来传输“归零”而浪费掉了。
那么,我们去掉这个归零步骤,NRZ 编码(Non-return-to-zero Code)就出现了,和 RZ 的区别就是 NRZ 是不需要归零的:
|
这样,浪费的带宽又回来了,不过又丧失宝贵的自同步特性了,貌似我们又回到了原点,其实这个问题也是可以解决的,不过待会儿再讲,先看看什么是 NRZI:
NRZI 编码(Non-Return-to-Zero Inverted Code)和 NRZ 的区别就是 NRZI 用信号的翻转代表一个逻辑,信号保持不变代表另外一个逻辑。
USB 传输的编码就是 NRZI 格式,在 USB 中,电平翻转代表逻辑 0,电平不变代表逻辑1:
|
翻转的信号本身可以作为一种通知机制,而且可以看到,即使把 NRZI 的波形完全翻转,所代表的数据序列还是一样的,对于像 USB 这种通过差分线来传输的信号尤其方便~
现在再回到那个同步问题:
的确,NRZ 和 NRZI 都没有自同步特性,但是可以用一些特殊的技巧解决。
比如,先发送一个同步头,内容是 0101010 的方波,让接受者通过这个同步头计算出发送者的频率,然后再用这个频率来采样之后的数据信号,就可以了。
在 USB 中,每个 USB 数据包,最开始都有个同步域(SYNC),这个域固定为 0000 0001,这个域通过 NRZI 编码之后,就是一串方波(复习下前面:NRZI 遇 0 翻转遇 1
此外,因为在 USB 的 NRZI 编码下,逻辑 0 会造成电平翻转,所以接收者在接收数据的同时,根据接收到的翻转信号不断调整同步频率,保证数据传输正确。
但是,这样还是会有一个问题,就是虽然接收者可以主动和发送者的频率匹配,但是两者之间总会有误差。
假如数据信号是 1000个逻辑1,经过 USB 的 NRZI 编码之后,就是很长一段没有变化的电平,在这种情况下,即使接受者的频率和发送者相差千分之一,就会造成把数据采样成 1001个或者 999个了。
USB对这个问题的解决办法,就是强制插0,也就是传说中的bit-stuffing,如果要传输的数据中有7个连续的1,发送前就会在第6个1后面强制插入一个0,让发送的信号强制出现翻转,从而强制接受者进行频率调整。接受者只要删除6个连续 1 之后的0,就可以恢复原始的数据了。
USB接口
Pin Name Color Description
1 VCC Red +5 V
2 D− White Data −
3 D+ Green Data +
4 ID none Type A: 接口内部接地, Type B: 悬空
5 GND Black Signal Ground
TYPE C接口:
USB OTG
USB On-The-Go通常缩写为USB OTG,是USB 2.0规格的补充标准。它可使USB设备,例如播放器或手机,从USB外设变为USB主机,与其他USB外设连接通信。
USB OTG为设备定义了两种角色:OTG A设备和OTG B设备。初始情况下A设备为主机,B设备为外设。主机和外设模式可能会在以后使用HNP协议进行交换,因此它们通常也被称为双重角色控制器。但是,无论主机和外设如何分配,OTG A设备始终是VBUS提供端,而OTG B设备始终是VBUS接受端。
OTG mini接口
USB OTG mini-AB的插座,可以接受mini-A插头或mini-B插头。纯mini-A插座也存在,用于需要尺寸小的主机端口的地方,只接受mini-A插头,默认只能做主机。
OTG micro接口
随着USB微型插头的推出,还引入了一种名为micro-AB的新插头插座,用法与mini插座类似。
USB也引入了3.0的micro-AB插座和micro-A和micro-B插头,兼容USB2.0 OTG的SuperSpeed扩展接口。它们包含USB2.0的所有引脚,并使用ID引脚标识A设备和B设备角色,并包含3.0 SuperSpeed引脚。
相比USB标准协议,OTG额外补充了三个协议:
Attach Detection Protocol (ADP)
Session Request Protocol (SRP)
Host Negotiation Protocol (HNP)
ADP:USB主从设备或USB OTG设备,如何知道USB总线上有没有挂接其它USB设备呢?USB设备会通过在VBUS线上施加一定时长的周期性脉冲来检测USB端口的电容值,如果USB端口电容值变化足够大,大到可以确定有新的USB设备接入了,那么USB A型设备会为USB总线提供电源,并检测设备连接;而USB B型设备则发起一个会话请求(SRP),并等待A型设备的响应。
SRP: B设备通过先在VUBS线上发起脉冲,然后在数据线上发起脉冲,使A设备能识别出来其中任一种变化,则A设备打开VBUS并且开始一个Session。Session为从VBUS打开到关闭这一段时间。A设备必须回应SRP,B设备允许发起SRP。VBUS常打开的Host不必响应SRP。
HNP: 允许两个设备交换其主机/外设角色,前提是两者都是 OTG 双角色设备。通过使用 HNP 来反转主机/外设角色,USB OTG 设备能够获得对数据传输调度的控制。最新版本的补充还引入了 HNP 轮询,其中主机设备在活动会话期间定期轮询外围设备以确定它是否希望成为主机,并主动放弃BUS控制,给B设备有机会获取BUS控制权。
USB连接
USB设备连接到充电器、标准USB设备、带充电功能USB设备的示意图:
1.IDP_SRC(约10uA)和RDP_DWN/RDM_DWN(约24.8K)用于检测DATA PIN脚是否接触;
当没接触上时,IDP_SRC导致D+电压大于2V,表示管脚没连接。
当接触上时,IDP_SRC会和RDM_DWN或RDP_DWN形成回路,电压会约0.24V。
(RDCHG_DAT<200Ω)
2.VDP_SRC/VDM_SRC(0.7V),IDP_SINK/IDM_SINK(100uA),VDAT_REF(0.4V)用于检测所连接的设备是否具备充电功能。
当连接充电器或带充电USB设备时,根据D-电压大于VDAT_REF,CHG_DET会输出高电平。其中带充电USB设备会一直打开IDP_SINK,直到D+输出逻辑高电平,并检测PRTBL_DET输出高电平,打开D-线上的VDM_SRC,使得CHG_DET会输出高电平。
当连接标准USB设备时,由于D+/D-断开,CHG_DET会输出低电平。
3.使能D+上拉电阻,用于检测所连接的设备是充电器还是带充电功能USB。当连接的是充电器,D-也为高电平。当连接的是USB设备,D-为低电平。
USB设备(含电池供电)高速连接时序图:
USB设备(没电池)情况下连接时序图
电流参数:
在高速情况下,不同阶段的电流限制要求
ACA(Accessory Charger Adapter)应用
当OTG用于ACA(Accessory Charger Adapter)应用,即同时连接充电器和另一USB设备,其中Adapter受Adapter Controller的控制,其主要功能:
ID_OTG引脚会存在5种不同阻值,用于OTG Device识别不同的连接情景。(老版本OTG设备只能识别出GND和FLOAT两种状态,其它三种会存在识别错误的情况)
不同连接情景:
第5和7情况下,允许OTG设备充电和发起SRP,但不允许连接(USB协议规定)。
第8情况下,允许OTG设备充电并连接,但不允许发起SRP。
第6情况下,OTG设备被允许充电并进入主机模式。
以上内容针对Battery Charging Specification 1.1版本,1.2以上版本有明显技术更新。
进行通信前,Host需要了解设备,并为其分配相应的驱动。枚举就是互相了解的过程,这个过程包括,确定设备速率,给设备分配地址,从设备读取描术字,分配并加载驱动程序以及选择规定了设备功耗要求和接口的配置信息。枚举过程如下:
1.设备插入主机,此时设备可以从主机获得100mA电流,并开始检测接口状态。
2.主机集线器开始检测设备。集线器在D+和D-上有一个15K的下拉电阻,集线器会监测D+和D-线上的电压。低速设备在D-上有一个1.5K上拉(到3.3V)电阻,而全速和高速设备的上拉电阻在D+上。集线器监测到任何一根线上的电压,就认为设备已连接到主机。
3.主机获悉新设备。主机的集线器得知设备已经插入,向主机上报事件。主机得知事件,给集线器一个Get Port Status请求,以了解更多信息。
4.集线器监测设备是LS还是FS。之后集线器发送给你主机信息,然后响应下一个Get Port Status请求。
5.集线器复位新设备。主机得知有新设备后,立即发送Get Port Status请求,要求集线器复位端口设备。这是D+和D-都拉低至少10ms。
6.主机了解全速设备是否支持高速状态。检测设备是否支持高速状态使用两个特殊信号状态。Chirp J状态只有D+线被驱动,Chirp K状态只有D-线被驱动。
7.复位期间,高速设备会发送Chirp K信号。高速集线器检测到该Chirp K信号后,会立即响应一串KJKJKJ….。当设备检测到连续三对KJ的信号后,设备移除它的上拉电阻,使能内部D+和D-对GND的45ohm电阻,后面以高速模式通信。如果集线器在收到K信号后,没有响应KJKJKJ,设备得知它连接到了一个全速设备,那就以全速模式通信。在完成数个KJ信号之后,Hub会再次发送一次SE0复位USB设备。
集线器在设备和总线间建立一条信号路径。主机发送Get Port Status请求证明设备已经摆脱了复位状态。返回数据中的一个数据位将用于标明设备是否处于复位状态。若有必要,主机还会重复此请求直到设备离开复位状态。
当集线器的复位信号被移除,设备处于缺省状态(Default state)。设备的USB寄存器都处于复位状态。且设备已经准备好响应断电0处的控制传输。设备会使用缺省地址00h来与主机通信。
8.主机发送首个64 bytes 的Device Descriptor请求,然后在收到设备响应的前8 bytes 的Device Descriptor后,主机立即复位总线。
9.主机指定设备新的地址。
10.主机通过新地址了继续了解设备信息,Device Descriptor、 Configuration Descriptor、String Descriptor。
11.主机制定并加载设备驱动程序,加载INF文件。
12.主机的设备驱动程序会选择配置,发送Set Configuration请求对设备进行配置。通常情况下在发送配置请求前,主机会再次发送Descriptor请求再次获取设备信息。设备接到请求,进入相应配置,设备接口就算是使能了。
USB速率 | Chirp | DP | DM | IDLE |
Low Speed | K | 1 | 0 | J |
J | 0 | 1 | ||
Full Speed | K | 0 | 1 | J |
J | 1 | 0 | ||
High Speed | K | 0 | 1 | SE0 |
J | 1 | 0 | ||
L/F/H Speed | SE0 | 0 | 0 |
USB chirp信号分为K信号和J信号。根据USB速率,chirp信号有不同定义。
另外SUSPEND和RESET状态,是由HOST输出SEO时长决定。超过3ms没超过10ms就进入suspend,超过则进入reset。在suspend期间,总线切换到J状态,退出时需发起resume,把总线由J状态切换到K状态。High Speed模式下,host进入IDLE超过3ms不超过10ms,将进入suspend模式,device需将转化为Full Speed模式,host和device会保留之前HS模式信息,恢复后直接进入High Speed模式;超过10ms,则进入RESET模式,device会重置为默认模式,需重新握手进入High Speed模式。
下图是手机(USB2.0高速设备)插入电脑端口的实测波形,
阶段(1)是充电器识别过程,阶段(2)是USB枚举和通信过程。
把阶段(2)放大,如下图。
(a)USB全速/低速设备判定阶段;这个阶段,USB高速设备也当做全速设备来判断。HOST端的D+和D-线上都有15K下拉电阻。如果插入的是USB高速或全速设备,设备的D+上有一个1.5K上拉(到3.3V)电阻,所以D+线被拉高。如果插入的是USB低速设备,D-线被拉高。由于插入的手机是高速设备,可以看到D+线被拉高。
(b)USB HOST立即拉低D+和D-,也就是SE0状态,持续10ms,使USB设备复位。
(c)USB设备发送Chirp K信号。USB设备内部持续向D-灌电流17.78mA。USB HOST在发送SE0的阶段,已经使能了D+和D-线上对GND的45ohm电阻。
所以D+线电压接近0V,D-线电压=17.78mA*45ohm=800mV,从图中也可以看到D+信号在(b)和(c)阶段都接近于0V。
这个时候D+和D-线的阻抗结构如下:
(d)HOST接收到K信号后,立即回应一连串的KJKJKJ…(也是Hub交替地向D+和D-灌17.78mA电流)。
(e)当USB设备检测到来自Hub的三对KJ后,它在500us内切换到高速模式,使能内部D+和D-对GND的45ohm电阻,断开1.5K上拉电阻。由于Hub在一直发送KJ信号,这是在D+和D-上观测到的电压都是400mV。此时的阻抗结构如下:
在完成数个KJ信号之后,Hub会再次发送一次SE0复位USB设备,然后开始480Mbps的通信。
参考文档
1. https://www.crifan.com/files/doc/docbook/usb_basic/release/html/usb_basic.html
2. https://blog.csdn.net/AirCity123/article/details/103124338?spm=1001.2014.3001.5506
3.《Battery Charging Specification Revision 1.1》
4.Infineon AN65231 《USB On-The-Go (OTG) Basics》