本文转自公众号,欢迎关注
基于DWC2的USB驱动开发-USB连接详解 (qq.com)
一.前言
之前一直在阅读手册,规格书,练习招式,学习心法,从这一篇开始我们就要真刀实枪的干了,当然不是一味蛮干。驱动编写,调试,实践的过程会结合阅读规格书,手册,理论结合实践,招式和心法要同步进行。
二.USB连接需要几步?
进行USB连接需要几步?我们参考把大象装进冰箱需要几步:第一步打开冰箱门,第二步把大象装入冰箱,第三步关闭冰箱门,完成。USB连接同样的简单,第一步插上开发板USB接口到电脑,第二步电脑识别到USB设备,第三步恭喜你获得一个黄色告警对话框!完美完成!也许很不幸,你没有获得黄色告警对话框,那么就是失败了,后面我们会详细介绍怎么去分析调试。
三.USB连接原理
前面我们已经完成了USB连接的操作,实践了师傅教的第一招黑虎掏心,but what?我干了什么?前面我们说过需要理论结合实践,招式结合心法,招式已经尝试了,但是到底是什么原理呢?到底是怎么做到的呢?那么就要从心法去探究,USB江湖的最基础的心法,就是USB2.0的规格书。当然招式也有招式的拳谱剑谱,我们这里就对应的使用的USB控制器IP的规格书(这里是新思的DDC2)和PHY的规格书(microChip的USB334x)。
我们打开USB2.0规格书,翻到141页看到如下图,主机(或HUB)端D+和D-均由Rpd=15KΩ的电阻下拉,未接入设备时此时D+和D-都是0V。设备(或者下级HUB)端通过D+或D-上拉Rpu=1.5KΩ来区分是全速还是低速设备,全速设备D+上拉,低速设备D-上拉。设备端的上拉电阻和主机端下拉电阻分压得到和未接设备时不一样的电平,主机检测该电平即可知道有设备插入,原理就是这么简单,牛逼的武功也往往是很简单,比如六脉神剑也就那么一弹手指。
为什么是上拉1.5K呢,因为上拉电阻要保证分压值不小于VIH(min),因为只有满足该条件才能被识别为高,为什么这个电压能识别为高呢,那就是硬件电气特性决定的了,我喜欢死缠烂打的追问的伙伴,可以继续深挖到收发器,晶体管,半导体.... ,如果能追到这一层的那么肯定是孤独求败级别的高手了,膜拜之。VIH在规格书中的要求如下至少要为2V(可以规格书中搜索找到)
除了上述要求,上拉电阻还要保证能够在2.5µs的最小复位时间内将D+或D-从0V上拉至VIH(min),因为在复位结束时要进行总线状态评估。
2.5uS的要求在如下表格中说明,即复位最短时间是2.5uS.
综上要求,具有可拆卸电缆的设备使用1.5 kΩ ±5%电阻器连接到3.0 V和3.6 V之间的电压源(VTERM),以满足这些要求。带有固定电缆的设备可以使用替代端接方式。但是,任何终端的Thevenin(戴维宁)电阻必须不小于900Ω.注:终端的Thevenin(戴维宁)电阻不包括主机/集线器上的15 k±5%的电阻。
上拉电阻器上的电压源必须来源于USB电缆上提供的电源或由USB电缆上的电源控制,以便在移除VBUS时,上拉电阻器不会在其连接的数据线上提供电流。即VBUS断开时上拉也应该断开。
上述表中描述的是针对低速和高速设备连接检测,高速呢,高速设备的连接检测和全速一样,只是后面速度枚举有不同,这个先按下不表,后面再讲解。
四.USB连接驱动
驱动编写我们参考控制器IP的手册,找到如下寄存器
手册P529的5.4.48 DCTL,Offset: 0x804,bit1
可以看到默认值是1,即默认是断开上拉电阻的,注意这里的逻辑,这个bit表示断开连接。
软件写0上拉电阻,这样在DP或者DM上上拉电阻(根据速度而定,如何设置速度枚举速度后面再讲),这样主机就可以检测到了。
注意软件操作这个bit时不要过于频繁,一般留个10mS以上充足的间隔时间,大于上述手册中的描述时间。
注意该位不受控制器软件复位影响。
我们的驱动代码如下,寄存器的操作封装,参考之前的文章,为什么用宏不用结构体,也有专门的文章讲解,可以去瞅瞅。
static void usb_dev_crtl_sft_discon(uint8_t dis)
{
if (dis) {
REG_OTG_DCTL |= DCTL_SOFT_DISCONN;
} else {
REG_OTG_DCTL &= ~(DCTL_SOFT_DISCONN);
}
}
我们之前一直强调,要了解根本原理,不管学习招式还是学习心法,一定要追其核心根本原理。那么这个bit写0就能上拉,到底是怎么实现的呢,
我们这里操作的是控制器即LINK,但是实际工作是由PHY去完成的,所以写了这个bit之后,
LINK会通过PHY和LINK之间的UTMI或者ULPI接口告诉PHY,最终由PHY去完成这个上拉工作。于是乎我们去翻阅PHY的手册这里是USB334x,看到如下图,正是PHY将如下上拉电阻拉高来实现连接,至此我们已经了解了整个过程。
从ULPI的规格书中还可以看到实际是通过PHY对应的寄存器相关位配置为不同的模式来控制的
而UTMI接口中直接对应的是信号线
这里顺便提一下,ULPI对UTMI引脚的缩减,实际就是通过将一些信号线直接控制转为寄存器控制来达到的。
但是有好问者,会问那么LINK是怎么告诉PHY要去上拉电阻的呢,问得很好,高手总是从刨根问底开始的。这个就要了解UTMI和ULPI协议了,可以参考本系列文章,讲解了ULPI协议,甚至讲解了如何使用逻辑分析仪抓包ULPI,那么你就可以抓到ULPI接口上具体的数据,来调试分析了,比如最终没能上拉,通过ULPI抓包可以确定是没有发送到PHY还是PHY没有执行,进一步缩小范围。
https://mp.weixin.qq.com/s/e4MCpASUXW4oKzfYOdMRwg
https://mp.weixin.qq.com/s/7oTIgxvrui_ZdjCktFo87g
还有更细致的会问,那么这个上拉电阻是所有芯片都会有吗,答案是否,有些芯片是没有的,比如一些STM32的MCU,这个时候需要外部提供上拉电路,使用IO控制。如下(网上随便找的一张图),USB_E来控制上拉。
五.调试
上面我们如果能看到电脑弹出黄色告警的对话框,恭喜你,你已经练就了第一招黑虎掏心。如果不幸没有弹出呢,那么我们就需要进行调试。那么就要派出示波器出来一展身手了。
我们直接使用示波器监控DP和DM的电平,查看初始是否都为0,然后connect后DP,DM是否对应的拉高,拉高的值是否符合要求达到了VIH(min)。如果没有拉高则从以下方面去分析:
1.硬件检查,使用万用表测量DP DM到芯片的相应引脚是否联通,测试DP,DM是否和地或者VCC短路。如果外置PHY则检查PHY是否工作,通过时钟等关键引脚判断。
2.将DP DM配置为普通IO,翻转IO使用示波器查看硬件连通性。强调下该方式是嵌入式一种常用的测试方法,用于确认IO到硬件上是否正常联通,有时还可以使用IO做时序分析测试,即在一定的事件发生时翻转IO,用示波器测量,这比使用软件定时器和串口打印更精确。多个通道还可以可视化展现相位关系,简单的一招确是调试的大招。
3.检查DP DM是否按照芯片手册配置为了对应的功能,包括输入输出模式,功能选择等,有些芯片可能需要重映射。
4.检查USB相关的初始化是否正确,包括时钟使能,IO模块使能,外设模块使能,时钟配置(比如48M时钟源等),检查模块复位,模块寄存器保护等。回读寄存器确认相应的寄存器是否确实配置成功,回读总是必要的,可靠性编程中需要考虑,写入不一定成功的,芯片也是有出错概率的。
我这里针对DWC的IP,测试代码如下,10mS进行一次断开和连接使用示波器查看
while(1)
{
usb_dev_crtl_sft_discon(0);
iot_timer_delay_ms(10);
usb_dev_crtl_sft_discon(1);
iot_timer_delay_ms(10);
}
我这里是高速模式,示波器测试DP波形(黄色)如下:
六.总结
以上可以看出USB连接原理很简单,就是一个上拉电阻,就好比将大象装进冰箱一样简单。招式虽简单,但是其背后的心法,原理确很重要,细节也很重要。这就是为什么乔峰使出黑虎掏心如此威力巨大,而一些绿林大汉使出来确平平无奇,这是心法和招式理解是否达到了炉火纯晴的地步的区别。USB连接也是如此,只是知道上拉,还是知道LINK的寄存器如何配置,还是知道LINK和PHY如何通讯告诉PHY去上拉,甚至知道如何去抓包确认,还是知道上拉电阻为什么是1.5K有什么要满足的条件,还是知道芯片不带上拉如何去外置上拉等等,都是对应不同的级别。看来一招USB连接,一招黑虎掏心也可以分为18级,只有练到最高级炉火纯青才能所向披靡,遇BUG解BUG,遇fault杀fault。
审核编辑 黄宇
-
usb
+关注
关注
60文章
7888浏览量
263914 -
USB驱动
+关注
关注
1文章
136浏览量
20169 -
驱动开发
+关注
关注
0文章
130浏览量
12061 -
DWC2
+关注
关注
0文章
35浏览量
119
发布评论请先 登录
相关推荐
评论