分类: LINUX
2009-07-07 19:01:16
ASIX中usb主要函数实现说明如下:
1) USB设备在接入主机时,产生一个USB中断进入USB的中断服务程序
进行设备列举,并实现主机对设备的配置,完成后即可以进行数据传输。
USB中断服务程序ER HA_GFDUSB_INTHANDLE(void)的流程如下:
ⅰ 控制端点:
RESET中断进行复位操作:包括对全局变量的重新初始化,并设置中断和端点状态寄存器;
SETUP中断进行控制传输:设备列举阶段的控制传输操作主要在此实现,响应中断后转入usb_irq_setup()函数,该函数的实现将在下面将阐述。
其他中断包括:out中断(在为控制端点时并没有进具体操作)、ping、(传输错误中断)、stov(统计中断)、ctraerr(控制传输错误中断),当为这些中断时,将进行相应寄存器的配置。
ⅱ Bulk端点:
Out中断:转入OUTINTR()函数,该函数主要在用作BULK_ONLY传输中主机向设备传送CBW封包,设备进行CBW封包的接收,并配置相应的DMA中断以在USB中断结束后转入相应的DMA中断服务程序。
其他中断:RESET、stov(统计中断)、traerr(传输错误中断),当为这些中断时,将进行相应寄存器的配置。
2) usb_irq_setup()函数的流程以及具体实现:该函数主要作为设备对主机的控制传输中请求的响应处理,并按下列顺序实现:
ⅰ 取主机发送的请求命令:通过get_irq_request_cmd()函数读取相应的寄存器,取得请求命令数据。
ⅱ 据获取的命令根据进行相应的操作,pdc_bus_ctrl_pipe_notificaion(unsigned long notif_type, unsigned char *cmd)实现该功能。其中调用pdc_bus_get_descriptor(U8 *command)
函数实现GET_DESCRIPTOR命令,pdc_bus_SET_CONFIGURATION(void)实现SET_CONFIG命令(但是该函数并为实现具体操作)。
ⅲ 断是否为SET_CONFIG命令:若是,则设置MSDevice.dUSBStat.setconstate中断返回;
ⅳ 则,调用transcl((unsigned char *)MSDevice.dUSBTrans.head_temp)实现控制传输中的数据阶段,该函数的实现请参阅下面说明。
3) transcl函数主要用于控制传输中,设备响应主机的请求给发送请求数据。该函数流程图如下:
ⅰ USB设备第一次接入主机是时,设备处于未配置状态,主机向设备发送请求要求发送64个字节长度的设备描述符,根据协议要求此时设备只向主机发送设备描述符的前8个字节;(见上图a处)
ⅱ 断空包标记是因为主机在设备列举时向设备要求发送0xFF字节长度的配置描述符,设备向主机发送完所有描述符(本设计中为32字节)后,需向主机发送空包以通知主机要求的数据已经发送完毕;(见上图b处)
ⅲ 空包和余数字节的发送在DMA中断中实现,请参见下面。
批传输的状态机设置说明如下:
ⅰMSDevice.dBulkStat.blkstate全局变量说明了BULK传输所处的具体阶段,一共有三个状态阶段:BLKCMD,BLKPRO和BLKEND,这三个阶段依赖于BULK_ONLY传输协议;
ⅱBLKCMD状态:由于已经在的USB的中断服务程序的OUTINTR函数完成了CBW封包的接收,在这个状态中usb_bulk()函数完成CBW封包合法性的判断,并根据主机的UFI命令进行UFI操作,但并未完成主机和设备间数据的交互,即只是为数据传输做好准备。接着根据MSDevice.dBulkStat.unsinglepocket标志判断BULK_ONLY传输是否有中间DATA-IN或DATA-OUT阶段,若要,则利用transbulk函数进行数据传输但该函数只是传输小于BUFFER(2K字节)长度的数据,若此次数据传输能在一次传送中完成,则跳入BLKEND状态,即在结束此次中断后又响应DMA中断(MSDevice.dUSBStat.usbdmapp仍然未APP)后跳入BLKEND状态,否则转入BLKPRO状态,显然此时主机发送的必为READ或WRITE命令。若不需要DATA-IN or DATA-OUT阶段,则进行CSW的传送,并设置MSDevice.dUSBStat.usbdmapp为NAPP,等待下一次USB中断。
ⅲ BLKPRO状态:继续进行未完成扇区的读写操作知道完成后跳入BLKEND状态;
ⅳBLKEND状态:结束本次数据传输过程,向主机发送CSW封包,并设置MSDevice.dUSBStat.usbdmapp为NAPP,等待下一次USB中断。
至此,该USB设备驱动程序的主要函数说明完毕。这中间的繁琐过程可能只有看源代码,你才会真正理解整个协议是怎么运行的。