一、平台
全志 T527
二、问题背景
1、USB OTG标准,允许设备既可作为主机,也可作为外设。通过判断USB VBUS和USB ID引脚的状态进行ko的加载与卸载
- 查看dts,确认是否vbus和id是否共用一个IO
- find /sys/ -name otg_role,找到otg节点所在目录,切换至该目录
- cat ./otg_role即可查看当前的otg_role
- USB接口接入PC或者OTG线,重复步骤2
- 通过cat ./usb_null, cat ./usb_device,,cat ./usb_host强切otg模式
三、具体表现
不接外设 | 接入PC | 接入OTG线 | |
---|---|---|---|
VBUS | 低 | 高 | 低 |
ID | 高 | 高 | 低 |
OTG_ROLE | NULL | DEVICE | HOST |
此外,有时为了节省IO,可能会出现ID和VBUS为一个IO的情况:
不接外设 | 接入PC | 接入OTG线 | |
---|---|---|---|
VBUS | 高 | 高 | 低 |
ID | 高 | 高 | 低 |
OTG_ROLE | DEVICE | DEVICE | HOST |
四、问题分析
-
参考下图,pc设备插头会把ID引脚悬空,从而ID引脚为高电平,相反,OTG设备插头会把ID引脚接地,从而置低电平。VBUS为电源接口,当ID引脚为高时,可以判断VBUS引脚电平,如果为高电平则表明接入了PC设备,反之则表示没有接入外设。
-
在otg模式下。内核的otg manager会创建线程usb_hardware_scan_thread,该线程通过轮询的方式监测这两个引脚的电平变化:lichee/kernel/linux-4.9/drivers/usb/sunxi_usb/manager/usb_manager.c
-
usb_hardware_scan_thread会调用到vbus_id_hw_scan,该函数会读取vbus和id引脚状态,并作对应操作:lichee/kernel/linux-4.9/drivers/usb/sunxi_usb/manager/usb_hw_scan.c
-
以do_vbus0_id0为例,这个函数会结合当前otg_role,进行驱动的卸载与加载。id为0表示此时接入了otg线,应该切换到host状态。如果此时状态为null,则直接加载host驱动。如果是device则先卸载device驱动,下一次轮询再加载host驱动。如果是host,则无需再操作。
五、根本原因
OTG使用总结:
1、结合原理图,自行配置board.dts的vbus以及id引脚,如果只用一个,把vbus配置成与id配置成相同即可。同时otg模式要将usb_port_type配置成0x02
2、如果需要调整USB接口悬空时的otg状态,可以修改do_vbus0_id1函数
3、查看当前otg_role状态:
(1)find /sys/ -name otg_role
(2)切换到改目录
(3)cat ./otg_role
4、强切otg_role:
切换到上述目录:
(1)cat ./usb_null
(2)cat ./usb_device
(3)cat ./usb_host
5、节省IO的优缺点
优点 | 缺点 | |
---|---|---|
一个IO | 节省IO资源 | USB接口悬空时,功耗更大,可能有硬件射频影响 |
两个IO | 功耗更低 | 耗费IO资源 |