基于DWC2的USB驱动开发-高速设备速度握手详解 (qq.com)
前面我们分析了USB连接和复位的过程, 也知道低速和全速/高速的USB设备分别是上拉DM和DP,主机通过不同的上拉区分接的是低速还是全速/高速设备的。但是怎么区分全速和高速呢? 这就需要额外的一些握手过程,本篇就来详细介绍该过程。
USB连接检测过程见如下
https://mp.weixin.qq.com/s/T6pbLP83IIeJDvM_6ogQDA
USB复位过程见
https://mp.weixin.qq.com/s/8xKca-XPjZXAiO6MOQVGAQ
对于低速设备上拉DM,主机检测到该上拉,然后发送复位就完了
对于全速和高速设备上拉DP,主机检测到该上拉,然后发送复位,接下来是速度握手过程。
老规矩我们从规格书入手,USB2.0规格书P154中《High-speed Detection Handshake (not performed if low-speed device detected by hub):》有描述整个过程,但是这都是文字描述,不是很直观,所以我们理论结合实践,直接根据真实的波形和规格书的描述对照进行分析。
在速度握手中,主机(集线器)和设备都需要检测拥有最小持续时间的Chirp J和K, 涉及到两个关键信号Chirp J和K(参见规格书7.1 Signaling或者本系列文章)。
整个过程如下
(1)设备使能DP上拉1.5K,如下图的(1)处,此时DP大概3V左右
(2)主机检测到DP拉高,检测到设备连接,发送SE0进行复位
如上图的(2),因为时间很短,下面是细节图,可以看到下图SE0状态只维持了8uS,后面就是蓝色线(DM)高于黄色线即Chirp K信号,对应上图的(3)部分。
回顾一下复位分析那一篇文章,发送放复位会持续50mS,但是接收方在最低2.5uS就可以识别到复位,这里实测是8uS设备就识别到复位然后开始发送Chirp K信号了。
保持D+上的1.5K上拉电阻使能,设备发送Chirp K信号是通过,禁用高速终端电阻,并将高速信号电流驱动到D-线完成的。
这里有点不理解禁用了终端电阻,电流驱动到D-线,电流环路是什么?
并且如下可以看到DM有1.2V左右,这个电压是如何来的?
该Chirp K信号必须持续不少于1.0 ms(TUCH),并且在高速复位时间T0点(即主机发出的SE0开始)后不超过7.0 ms(TUCHEND)结束。
Chirp K持续时间如下所示,这里是2mS,满足上述要求
参数TUCH和TUCHEND的值在手册中的描述如下
上述可以看到Chirp K的信号,DM大概是1.1V左右,比后面的KJ序列高一点。
(3)主机(集线器)必须在看到chirp K信号持续2.5µs(TFILT)时间以上,后认为检测到设备发出的ChirpK,这里的2.5uS的要是实际是相当于滤波避免干扰。如果主机(集线器)未检测到设备发出的chirp K信号,则必须继续发送SE0,直到复位结束(持续50mS)。
TFILT参数见规格书如下处说明
在Chirp K状态结束后不超过100µs(TWTDCH),主机(集线器)必须开始发送Chirp K和Chirp J的交替序列,J和K之间不得存在空闲状态。此序列必须持续到复位结束前不超过500µs且不少于100µs的时间(TDCHSE0)(这样的目的是保证总线保持活动状态,防止设备进入高速挂起状态。)。每个单独的Chirp K和Chirp J必须持续不少于40µs且不超过60µs(TDCHBIT)。
TWTDCH,TDCHSE0,TDCHBIT的参数上图。
如下图(4)处
细节图如下
如下可以看到要求Chirp K结束100µs(TWTDCH)以内开始后面的KJ序列,实际10uS左右就开始了,满足要求。
如下图所示,主机发送的KJ序列持续了约50mS,即约复位的时间,实际要求是发送到复位结束前的100µs~500uS,这里示波器能力有限就不展示下图右边红色圈处的细节了。
在K-J序列之后,主机(集线器)发送SE0,直到复位结束,即上面说的KJ序列之后100~500uS复位结束。复位结束时,主机(集线器)必须转换到高速启用状态,而不会在数据线上引起任何转换。
(4)设备这端发送完Chirp K之后监控主机发送的K-J序列。设备端需要至少看到3对K-J序列,即序列Chirp K-J-K-J-K-J才认为是有效的KJ序列。每个单独的Chirp K和Chirp J必须检测不少于2.5µs(TFILT)。
我们这里看到有持续50uS满足要求
如果设备检测到序列Chirp K-J-K-J-K-J,则检测后不超过500µs(TWTHS),设备需要断开D+上拉电阻器,启用高速终端,并进入高速默认状态。
如下图所示,这里刚好约500uS左右进行了上述切换,上述切换也导致了DP和DM的电平的变化,原来KJ序列大概是0.8V左右,即主机发送KJ是通过电流17.78mA驱动45欧终端电阻实现的,17.78mA*45即0.8V。而我们又看到后面箭头处的电压下降,是因为正好是上述的设备切换到了高速模式,使能了45Ω终端电阻,所以设备的终端电阻和主机的终端电阻并联只有一般电阻,所以电压就只有一般0.4V左右了。
如果设备在完成其自己的Chirp K之后,在不小于1.0ms且不大于2.5ms(TWTFS)的时间内未检测到有效KJ序列,则设备需要恢复到全速默认状态并等待复位结束。
以上就是整个速度握手的过程,比较细节,我们再做一些总结
关于整体电压的变化,如下图,有4个等级,图中(1)和(2)之间还有个复位的SE0电平这里就略掉了。
(1)即设备通过DP上拉,即15K和1.5k的分压,3.3x15/(1.5+15) DP大概3V.
(2)设备发送Chirp K,DP 1.5K上拉还在,设备终端电阻禁用,实测D-上的电压是大概1.2V,这里的电流路径是什么? 待确定。
(3)主机发送KJ序列,主机通过驱动17.78mA电流到对应45欧终端电阻,发送KJ,所以DP DM是0.8V
(4)设备也进入了高速模式,1.5k上拉断开,设备使能了45欧终端电阻,和主机的终端电阻并联,主机继续在发KJ序列,此时主机的17.78mA电流驱动只能产生0.4V的电压。
手册P522 5.4.47 DCFG的bit[1:0]DevSpd用于配置设备期望工作过的速度,注意这里是期望,而不是一定,因为还需要速度握手过程,比如这里配置为高速,则还需要看主机是否支持高速。
所以我们需要在初始化时配置该位,告诉控制器后面以该速度去进行速度握手。那么握手结束之后实际是什么速度呢,手册P539的5.4.49 DSTS寄存器的位[2:1]EnumSpd可以看到
在速度握手完成之后还会产生中断,
手册P369寄存器5.4.7 GINTMSK的位13 EnumDoneMsk设置为1使能,速度握手完成中断。
相应的手册P357寄存器5.4.6 GINTSTS的位13EnumDone为中断标志,写1清除标志
所以驱动的基本过程是
1.初始化配置DevSpd设置期望的工作速度
2.配置EnumDoneMsk使能中断,清除标志EnumDone
3.等待中断,查询实际握手的速度EnumSpd,根据该速度再次重新配置DevSpd设置工作过速度。并清除标志EnumDone。
以上就完成了整个速度握手过程。
实际以上逻辑如果是非标主机,可能会存在BUG,后面会有一个实际案例进行分享,先卖个关子以后再单独写一篇文章分享该案例。
如下图两个箭头处分别对应的是复位中断,和速度握手完成中断
我们通过中断服务函数中打印时间戳(注意要用非阻塞方式),看到Reset_Intr和High speed之间的时间刚好是50mS(打印的是uS单位),和图中对应
而我们在usb_dev_crtl_sft_discon(0);使能DP上拉时也加一个打印,即上面connect后打印的时间戳和Reset_Intr之间是50mS,如下图
以上介绍了整个速度握手过程,以及设备驱动的编写。重点是结合手册的描述对照波形去看和分析,要了解没以一个实践段,每一个信号,每一个电平的含义和原理,知道那个信号是谁驱动的,为什么是这个波形,一定要自己亲自用示波器去抓波形,而不要使用别人的波形,因为不同的设备可能略有差异,如何去触发,如何去抓波形,也会加深自己的理解。
全部0条评论
快来发表一下你的评论吧 !