文章来源:http://gliethttp.cublog.cn
<1>对于PDIUSBD12,对于OUT事务,只有当pc驱动程序把此次数据通过管道全部发送到usb设备端点
--PDIUSBD12的0或2的数据缓冲区和ACK之后,PDIUSBD12才会产生中断,通知cpu,处理接收到的OUT事务数据,
而不是在PDIUSBD12收到OUT令牌后就立即中断cpu,PDIUSBD12会等到OUT令牌之后的数据阶段
(也可能需要等到ACK握手阶段完成之后[gliethttp])完成之后,才触发中断通知cpu处理PDIUSBD12接收到的
数据缓冲区中的数据;
对于控制端点0、端点1和端点2的IN事务,只要IN令牌一收到,PDIUSBD12就会立即触发中断,
0xF4中断状态寄存器的bit1-控制输入端点状态位-置位,
以示cpu这次中断由于控制端点IN令牌包的收到而发生的,
固件驱动组织数据,之后发送给host主机.(gliethttp)
这样就比较麻烦,因为当固件驱动处理数据的时候,PDIUSBD12将主动返回NAK给host主机,host主机收到NAK
之后,会按固定时间间隔定时的发送IN事务令牌包,如果不将cpu的整个中断系统停掉的话,至少不把
PDIUSBD12的第14脚INT_N连接的cpu中断禁止的话,就会以很高的频繁对cpu进行INT_N中断,
当然也可以不使用中断,而是不停检测PDIUSBD12的第14脚INT_N是否为0.
<2>对于at91rm9200来说,只有如下几种情况才会引发中断:
(1.RXSETUP:当前端点收到了setup令牌包触发中断
(2.RX_DATA_BK0:当前端点收到了数据包并且已经安全放到了FIFO段0触发中断
(3.RX_DATA_BK1:当前端点收到了数据包并且已经安全放到了FIFO段1触发中断
(4.TXCOMP:当前端点上发的数据已经被host主机通过IN事务读取,同时PID_ACK也正常收到,触发TXCOMP中断
(5.STALLSENT:当前端点被挂起禁用触发中断
所以对于at91rm9200第1次收到"读取设备描述符"setup事务指令之后会引发cpu中断,在中断里边
usbEp0.DisptachSetup = AT91F_USB_DispatchRequest;回调函数中,得知是STD_GET_DESCRIPTOR-标准获取设备描述符,
固件驱动会立即把"设备描述符"送入控制端点的IN缓冲区,这个时候host主机可能还正在处理其他事情,没有时间来处理,
不怕,放到IN缓冲区中的数据at91rm9200的usb控制器不会在host主机没有发送PID_IN令牌之前,就把数据主动送到总线
上丢失掉,而是等待host主机对当前端点发送PID_IN令牌的时候,老早之前放到IN缓冲区的数据才会传输出去,
另外的那种情况就是,host主机速度快的惊人,刚刚发送完"读取设备描述符"setup事务指令,就立即又发送了PID_IN令牌,
这时at91rm9200的usb控制器还没有把"设备描述符"完全送到IN缓冲区,此时at91rm9200的usb控制器会自动向host主机
发送PID_NAK,作为PID_IN的握手回应.经过几次PID_NAK并且在没有超过50ms的前提下,at91rm9200固件驱动已经把数据放
到了IN缓冲区,并且使IN缓冲区生效,那么host定时再次发送过来的PID_IN令牌将能正常收到PID_DATA令牌下的数据了.
这种方式比较好,在OUT事务中,固件驱动得知是否有上传数据,然后直接在OUT中断中,把上传数据送到IN数据缓冲区,
当host正常读取IN缓冲区的数据之后,会触发IN中断,在IN中断中,固件驱动再去检查IN数据是否发送完毕,如果没有就
继续发送下去,这就好像"钟摆小球试验",当你轻轻给它一个"外力"--OUT事物中激活IN,之后,"小球"--IN事物中断,就开始
永远的"摆动"起来--IN事物中断,又有点类似自激震荡(gliethttp).
<3>usb通信时,每一次数据的传送都严格遵守3个阶段
[1]令牌PID阶段
[2]数据PID阶段
[3]握手PID阶段
PID域
-----------------------
令牌有4种:
PID_setup令牌--PID域值0xB4,用来标示数据阶段的数据为setup事务数据
PID_out令牌 --PID域值0x87,用来标示数据阶段的数据为out事务数据
PID_in令牌 --PID域值0x96,用来标示数据阶段的数据为in事务数据
PID_sof令牌 --PID域值0xA5,用来标示帧标号开始
-----------------------
数据阶段:
PID_DATA0数据--PID域值0xC3,用来标示此数据为PID偶分组数据
PID_DATA1数据--PID域值0xD2,用来标示此数据为PID奇分组数据
-----------------------
握手阶段有3种:
PID_ACK --PID域值0x4B,用来标示usb接收器硬件收到无误的数据分组
PID_NAK --PID域值0x5A,用来标示接收端不能接收数据(可能正在处理上一次接收到的数据)
或者发送端不能发送数据(固件驱动程序正在把IN数据放到管道端点缓冲区中)
PID_STALL --PID域值0x78,用来标示当前端点被禁用了.(gliethttp)
<4>一个usb设备只能有1个设备描述符,可以有多个配置描述符,
每个配置描述符可以有多个接口描述符,每个接口描述符可以管理多个端点.
====================================================================
阅读(1376) | 评论(0) | 转发(0) |