一、USB OTG
USB
是主从模式的总线,主机称为Host
,丛机称为Device
(设备)。从机与从机之间、主机与主机之间(不包括USB4.0
),不能互联。每次通信都是由主机发起,从机不能主动发起通信,只能被动的应答主机的请求。
USB OTG
(On-The-Go
)是一个扩展的USB
标准,允许USB
设备之间直接进行通信,而无需通过主机。这意味着设备可以在作为主机和设备之间切换角色,实现了更灵活的连接方式。例如,两台智能手机之间可以通过USB OTG
直接连接并共享文件,而无需依赖计算机作为中介。
1.1 概述
对于标准USB2.0
来说,一共有4根引脚,一对差分线D+
/D-
,还有地线GND
、电源线VBUS
。
对于标准USB3.0
来说:一共有9根引脚,为了兼容USB2.0
除了拥有USB2.0
的一对差分线D+
/D-
、以及地线GND
、电源线VBUS
外,还会拥有两对差分线(SSTX+
和SSTX-
及SSRX+
和SSRX-
)和一根屏蔽地线;
USB2.0 OTG
在标准USB2.0
基础上增加了一根USB ID
线,使用USB2.0 OTG
的可设备是可以通过ID
脚位来判断其做为主机或是普通设备用途;
引脚 | 名称 | 线缆颜色 | 描述 |
---|---|---|---|
1 | VBUS | 红色 | +5V供电 |
2 | D- | 白色 | 差分数据- |
3 | D+ | 绿色 | 差分数据+ |
4 | ID | N/A | 可以用来区分另一端接口类型 主机:接地 设备:不连接 |
5 | GND | 黑色 | 地 |
对于支持OTG
功能的USB
控制器,我们称之为USB OTG
控制器。USB OTG
控制器的工作模式有三种(通过程序控制):OTG
、Device
、Host
;
OTG
:同时支持主机/设备,工作在这种模式时,我们可以通过ID
和VBUS
两个脚的状态来识别是否接入了USB
主机或USB
设备;Device
:作为USB
设备使用,由连接的USB
主机提供VBUS
电源;Host
:作为USB
主机使用,可以外接USB
设备,比如鼠标,键盘,并为所连接的USB
设备提供VBUS
电源;
USB
常见的接口有USB Type-A/B/C
三种,其中Type-A/B
又有标准A/B
、Mini-A/B
和Micro-A/B
三种。无论是 Type-A
、Type-B
还是Type-C
接口,只要设备支持USB OTG
功能,就可以在两个设备之间实现直接连接和数据传输。
接下来我们介绍一下这三种不同的接口是如何识别接入的是USB
主机还是USB
设备。
1.2 Type-A/B
接口
1.2.1 Type-A
Type-A
接口主要包括:标准Type-A
、Mini-A
、Micro-A
三种,每种接口有多少引脚呢?
接口 | 协议 | 引脚 |
---|---|---|
Type-A(标准) | USB1.0/2.0 | VBUS、D+/D-、GND |
Type-A(标准) | USB3.0 | VBUS、D+/D-、GND 两对差分线(SSTX+和SSTX以及SSRX+和SSRX-)和一根屏蔽地线 |
Mini-A | USB1.0/2.0 | VBUS、D+/D-、GND、ID |
Mini-A | USB3.0 | 未定义 |
Micro-A | USB1.0/2.0 | VBUS、D+/D-、GND、ID |
Micro-A | USB3.0 | 未定义 |
1.2.1 Type-B
Type-B
接口主要包括:标准Type-B
、Mini-B
、Micro-B
三种,每种接口有多少引脚呢?
接口 | 协议 | 引脚 |
---|---|---|
Type-B(标准) | USB1.0/2.0 | VBUS、D+/D-、GND |
Type-B(标准) | USB3.0 | VBUS、D+/D-、GND 两对差分线(SSTX+和SSTX以及SSRX+和SSRX-)和一根屏蔽地线 |
Mini-B | USB1.0/2.0 | VBUS、D+/D-、GND、ID |
Mini-B | USB3.0 | VBUS、D+/D-、GND、ID 两对差分线(SSTX+和SSTX以及SSRX+和SSRX-)和一根屏蔽地线 |
Micro-B | USB1.0/2.0 | VBUS、D+/D-、GND、ID |
Micro-B | USB3.0 | VBUS、D+/D-、GND、ID 两对差分线(SSTX+和SSTX以及SSRX+和SSRX-)和一根屏蔽地线 |
这里不做过多展开介绍,更多可以参考:《USB2.0、USB3.0和typec
引脚定义》。
1.2.3 角色识别
对于有ID
引脚的USB
接口,可通过VBUS
和ID
两个脚的状态来识别是否接入了USB
主机或USB
设备;
- 接入主机前,
VBUS
脚上没有电压,接入主机后,主机端会在VBUS
脚上提供5V
电压; - 接入设备前,
ID
脚为高电平,接入设备后,ID
脚被拉低。
于是软件可以通过主动读取这两个脚的电平或者异步响应这两个脚的中断来获知状态的变化。从而控制USB OTG
控制器工作在Host
/Device
模式。
需要注意的是:上图绘制只有5根接线,如果是USB3.0
通信协议,还会有两对差分线(SSTX+和SSTX以及SSRX+和SSRX-)和一根屏蔽地线。
1.3 Type-C
1.3.1 介绍
Type-C
接口又叫USB-C
接口。Type-C
接口尺寸为8.3×2.5毫米,小于当前PC
的Type-A
接口,但略大于Micro-B
接口。Type-C
相对于其它接口的优势:
- 可选集成
DisplayPort
、HDMI
,用于视频传输; - 通过
USB Power Delivery
技术,可用于3C
产品(如笔记本电脑、智能手机)的充电; - 它无需区分正反;
Type-C
规格所定义的插座及缆线可让使用者在插入其产品与缆线时,毋须考虑连接器的位置(正反皆可)。缆线两端皆可使用Type-C
插头,如有需要亦可在缆线一端使用旧型Type-A/B
插头。
为了满足更高频宽的应用,Type-C
规格在连接器中加入了多组USB3.0TX/RX
差分线。
1.3.2 引脚
(1) Type-C
母头
(2)Type-C
公头
Type-C
接口比Type-A/B
接口的引脚多多了,标准的Type-C
接口有24个引脚,共有有4对TX
/RX
差分线,2对USBD+
/D-
,一对SBU
,2个CC
,另外还有4个VBUS
和4个地线;
针 | 名 | 描述 | 针 | 名 | 描述 |
---|---|---|---|---|---|
A1 | GND | 接地 | B12 | GND | 接地 |
A2 | SSTXp1 | SuperSpeed差分信号#1,TX,正 | B11 | SSRXp1 | SuperSpeed差分信号#1,RX,正 |
A3 | SSTXn1 | SuperSpeed差分信号#1,TX,负 | B10 | SSRXn1 | SuperSpeed差分信号#1,RX,负 |
A4 | VBUS | 总线电源 | B9 | VBUS | 总线电源 |
A5 | CC1 | Configuration channel | B8 | SBU2 | Sideband use (SBU) |
A6 | Dp1 | USB 2.0差分信号,position 1,正 | B7 | Dn2 | USB 2.0差分信号,position 2,负 |
A7 | Dn1 | USB 2.0差分信号,position 1,负 | B6 | Dp2 | USB 2.0差分信号,position 2,正 |
A8 | SBU1 | Sideband use (SBU) | B5 | CC2 | Configuration channel |
A9 | VBUS | 总线电源 | B4 | VBUS | 总线电源 |
A10 | SSRXn2 | SuperSpeed差分信号#2,RX,负 | B3 | SSTXn2 | SuperSpeed差分信号#2,TX,负 |
A11 | SSRXp2 | SuperSpeed差分信号#2,RX,正 | B2 | SSTXp2 | SuperSpeed差分信号#2,TX,正 |
A12 | GND | 接地 | B1 | GND | 接地 |
引脚功能描述如下:
功能 | 引脚 | 描述 |
---|---|---|
USB3 | A2,A3,B2,B3,A10,A11,B10,B11 | USB3数据传输 |
USB2.0 | A6/B6(D+),A7/B7(D-) | USB2.0数据传输 |
配置 | CC1,CC2 | 配置功能接口,插拔检测,供电协议信息传输,VCONN功能 |
辅助信号 | SBU1,SBU2 | 辅助信号 |
供电 | VBUS,VCONN,GND | 供电 |
Type-C
插座中明显消失的是之前Type-A
和Type-B
接头的ID
引脚。在Type-C
中,使用配置通道 (CC
) 引脚这种不同的处理方式来决定设备是作为主机,还是作为外设。CC
引脚所执行的功能与ID
引脚之前执行的功能一样;它们表明了设备是作为主机、设备,还是兼具二者的功能。接下来我们重点介绍CC
引脚的功能。
petty-C就有点特别,从
Type-C规范可以看到,
Type-C是有一个状态机的,从
Unattached状态走到
Attached Sink状态(做从设备)或者
Attached Source状态(做主机),主控芯片内部是有相应的控制器的,控制器会通过寄存器汇报状态变化,并产生中断通知主控。
Type-C`控制器需要软件进行相应的编程来配置和使能它。
1.3.3 DFP
/UFP
/DRP
在USB
规范中为Host
、Device
定义了两个专业术语:
DFP
(Downstream Facing Port
):Source
,下行端口,可以理解为一个Host
,DFP
作为source
给VBUS
和VCCON
供电的,简单理解为一个提供电源的设备,如:电源适配器;UFP
(Upstream Facing Port
):Sink
,上行端口,可以理解为Device
,UFP
可以理解为受电端口,DFP
为供电端口,UFP
从VBUS
中取电,并可提供数据。典型设备如:U
盘、移动硬盘;
在USB
规范中如果一个设备的接口是DFP
,则其必然是主机或者说具有主机的功能,一个接口是UFP
,则其必然是设备或者说其具有从设备的功能。
而在Type-C
规范中,对原有的两种角色进行了扩充和重定义等,在Type-C
规范中定义了DRP
(Dual Role port
),DRP
可以做为DFP
也可以做为UFP
,可以供电,也可以受电;
- 当
DPR
接到UFP
装置,DRP
会转换为DFP
; - 当
DRP
接到DFP
装置,DRP
会转换为UFP
; - 当两个
DRP
装置接在一起,两个装置会Random
地,一方为DFP
,一方为UFP
;
1.3.4 角色识别
Type-C
的接口双方角色的识别其实是通过Type-C
接口中的两根CC
线进行检测设置的。如下图所示:
注:这里的线缆器件是指有eMark
芯片的线缆会用到VCONN
供电,当一个CC
确认方向后Source
端的另一个CC
会切换成VCONN
为eMark
供电,带有eMark
芯片的线缆能通过CC
与设备进行通信,反馈此线缆的温度,承受电流能信息,对于大功率充电的安全性还是有很大帮助的。
上图中左侧为DFP
,右侧为UFP
:
-
DFP
作为供电方,接口的两根CC
线上会加上上拉电阻(Rp
); -
UFP
作为耗电方,接口的两根CC
线上会加上下拉电阻(Rd
)。 -
两个接口相连时,
DFP
识别出对方的Rd
下拉时,则认为连接成功并且检测出对方的角色是耗电方; -
当
UFP
识别出对方的Rp
上拉时,则认为连接成功并且检测出对方的角色是供电方; -
如果两个同是供电方或者耗电方的接口相连,那么双方都不能识别出想要的
Rd
下拉或者Rp
上拉,双方都不能工作。
对于双重角色(DRP
) 接口,两根CC
上会在Rp
上拉状态和Rd
下拉状态这两种状态中不断地切换;
- 当与非双重角色设备连接时,如果对方是
Rp
上拉,此接口会停在Rd
下拉的状态,此时接口的供电角色为耗电方: - 如果对方是
Rd
下拉,此接口会停在Rp
上拉的状态,此时接口的供电角色为供电方; - 当与双重角色设备相连时, 双方会随机地停在
Rp
上拉状态或Rd
下拉状态,当一方停在Rp
上拉状态且另一方停在Rd
下拉状态时,连接就此建立;停在Rp
上拉状态的一方是供电方,停在Rd
下拉状态的一方是耗电方。
不管是供电角色还是通信功能角色,其连接时确定的初始角色并不是始终不变的,可以通过供电协议进行切换。 一个产品被设计为纯供电方并且通信功能是UFP
,因为连接时产品的供电角色只能是供电方,所以连接时通信功能是DFP
,连接之后此产品需要通过供电协议切换通信功能成UFP
。
1.3.5 功率检测
Type-C
规范中根据不同的供电方不同的Rp
阻值告诉耗电方自己默认的供电电流能力,而耗电方Rd
的电阻值一般固定;
供电电流能力 | Rp值(电流驱动) | Rp值(5V驱动) | Rp值(3.3V驱动) |
---|---|---|---|
900mA | 80uA±20% | 56kΩ±20% | 36kΩ±20% |
1.5A | 180uA±20% | 22kΩ±20% | 12kΩ±20% |
3.0A | 330uA±20% | 10kΩ±20% | 4.7kΩ±20% |
耗电方的Rd的定义如下:$$Rd = 5.1kΩ±20%$$
供电电流能力 | Rd的电压值 |
---|---|
900mA | 0.15~0.61V |
1.5A | 0.70~1.16V |
3.0A | 1.31~2.04V |
以上为固定的即默认的供电功率,其实根据PD
协议,可以通过CC
管脚的信号协商,实现更多的供电功率。
二、extcon驱动
extcon
是External Connector
的简称,用于抽象外部连接器,比如说Audio Jack
、USB MicroB
/TypeC
接口等。
extcon
驱动的主要功能是识别外部连接器状态变化,并将状态变化通知到与外部连接器相关的其他驱动。
使用extcon
驱动,有什么好处呢?之前的内核都没有extcon
驱动,又是怎么处理这些外部连接器的?不妨以USB
驱动为例,看看使用extcon
驱动前后的变化。
在extcon
驱动出现之前,同一份USB
控制器驱动代码,比较常见的做法就是在设备树中指明是哪种接口,USB
控制器驱动代码中会解析设备树中的定义,通过if...else...
来走不同的代码逻辑;
- 如果是
Micro-B
接口,就注册VBUS
和ID
脚的中断、查询IO
脚的电平状态; - 如果是
Type-C
接口,就注册Type-C
的中断,查询Type-C
的状态;
假设后续又有新的接口出现,工作原理不同于已有的接口,那就又需要在USB
控制器驱动中去增加相关代码。
在extcon
驱动出现后,USB
控制器驱动就能和外部接口驱动解耦。在USB
控制器驱动看来,不管外部接口是什么,我只需知道外部接口状态的变化就好了,比如是否接入主机了、是否有设备接入了。
使用extcon
驱动提供的函数接口来注册notifier
,当外部接口状态变化时,extcon
驱动负责回调notifier
,USB
控制器驱动代码无需再针对不同的外部接口改来改去。不同的外部接口,都用extcon
来抽象自己的行为。
有关具体驱动的实现这里这里就不介绍了,具体可以参考:《extcon
驱动及其在USB
驱动中的应用》。
参考文章:
[1] 搞定DFP
/UFP
角色侦测设计USB 2.0 OTG
升级Type-C