usB DHH:干什么也别干销售没有

USB.org - Defined 1.0 Class Codes
Defined 1.0 Class Codes
USB Class Codes&&&&&&&&&&&&&&&&&&&&
June 15, 2016
USB defines class code information that is used to identify a device?s functionality and to nominally load a device driver based on that functionality. The information is contained in three bytes with the names Base Class, SubClass, and Protocol. (Note that ?Base Class? is used in this description to identify the first byte of the Class Code triple. That terminology is not used in the USB Specification).&There are two places on a device where class code information can be placed.One place is in the Device Descriptor, and the other is in Interface Descriptors. Some defined class codes are allowed to be used only in a Device Descriptor, others can be used in both Device and Interface Descriptors, and some can only be used in Interface Descriptors.&The table below shows the currently defined set of Base Class values, what the generic usage is, and where that Base Class can be used (either Device or Interface Descriptors or both).
This base class is defined to be used in Device Descriptors to indicate that class information should be determined from the Interface Descriptors in the device. There is one class code definition in this base class.& All other values are reserved.
This value is also used in Interface Descriptors to indicate a null class code triple.
Base Class
Use class code info from Interface Descriptors
This base class is defined for Audio capable devices that conform to the Audio Device Class Specification found on the USB-IF website. That specification defines the usable set of SubClass and Protocol values. Values outside of that defined spec are reserved. These class codes may only be used in Interface Descriptors.
Base Class
Audio device
This base class is defined for devices that conform to the Communications Device Class Specification found on the USB-IF website.&That specification defines the usable set of SubClass and Protocol values. Values outside of that defined spec are reserved.& Note that the Communication Device Class spec requires some class code values (triples) to be used in Device Descriptors and some to be used in Interface Descriptors.
Base Class
Communication device class
This base class is defined for devices that conform to the HID Device Class Specification found on the USB-IF website. That specification defines the usable set of SubClass and Protocol values.&& Values outside of that defined spec are reserved. These class codes can only be used in Interface Descriptors.
Base Class
HID device class
This base class is defined for devices that conform to the Physical Device Class Specification found on the USB-IF website. That specification defines the usable set of SubClass and Protocol values.& Values outside of that defined spec are reserved. These class codes can only be used in Interface Descriptors.
Base Class
Physical device class
This base class is defined for devices that conform to the Imaging Device Class Specification found on the USB-IF website. That specification defines the usable set of SubClass and Protocol values.&& Values outside of that defined spec are reserved.
Base Class
Still Imaging device
This base class is defined for devices that conform to the Printer Device Class Specification found on the USB-IF website.& That specification defines the usable set of SubClass and Protocol values.& Values outside of that defined spec are reserved.& These class codes can only be used in Interface Descriptors.
Base Class
Printer device
This base class is defined for devices that conform to the Mass Storage Device Class Specification found on the USB-IF website. That specification defines the usable set of SubClass and Protocol values.&Values outside of that defined spec are reserved.&These class codes can only be used in Interface Descriptors.
Base Class
Mass Storage device
This base class is defined for devices that are USB hubs and conform to the definition in the USB specification.& That specification defines the complete triples as shown below.& All other values are reserved.& These class codes can only be used in Device Descriptors.
Base Class
Full speed Hub
Hi-speed hub with single TT
Hi-speed hub with multiple TTs
This base class is defined for devices that conform to the Communications Device Class Specification found on the USB-IF website.&That specification defines the usable set of SubClass and Protocol values.Values outside of that defined spec are reserved. These class codes can only be used in Interface Descriptors.
Base Class
CDC data device
This base class is defined for devices that conform to the Smart Card Device Class Specification found on the USB-IF website.&That specification defines the usable set of SubClass and Protocol values.Values outside of that defined spec are reserved. These class codes can only be used in Interface Descriptors.
Base Class
Smart Card device
This base class is defined for devices that conform to the Content Security Device Class Specification found on the USB-IF website. That specification defines the usable set of SubClass and Protocol values. Values outside of that defined spec are reserved.&These class codes can only be used in Interface Descriptors.
Base Class
Content Security device
This base class is defined for devices that conform to the Video Device Class Specification found on the USB-IF website.&That specification defines the usable set of SubClass and Protocol values.&Values outside of that defined spec are reserved.&These class codes can only be used in Interface Descriptors.
Base Class
Video device
This base class is defined for devices that conform to the Personal Healthcare Device Class Specification found on the USB-IF website.&That specification defines the usable set of SubClass and Protocol values.&Values outside of that defined spec are reserved.&These class codes should only be used in Interface Descriptors.
Base Class
Personal Healthcare device
&&The USB Audio/Video (AV) Device Class Definition describes the methods used to communicate with devices or functions embedded in composite devices that are used to manipulate audio, video, voice, and all image- and sound-related functionality. That specification defines the usable set of SubClass and Protocol values. Values outside of that defined spec are reserved. These class codes can only be used in Interface Descriptors.&&Base Class SubClass Protocol Meaning 10h01h&02h&03h&&00h Audio/Video Device ? AVControl Interface00h Audio/Video Device ? AVData Video Streaming Interface00h Audio/Video Device ? AVData Audio Streaming Interface&
Class 11h (Billboard Device)
This base class is
defined for devices that conform to the Billboard Device Class Specification
found on the USB-IF website. That specification defines the usable set of
SubClass and Protocol values. Values outside of that defined spec are reserved.
These class codes can only be used in Device Descriptors.
Base Class
Billboard Device
This base class is defined for devices that diagnostic devices. This class code can be used in Device or Interface Descriptors. Trace is a form of debugging where processor or system activity is made externally visible in real-time or stored and later retrieved for viewing by an applications developer, applications program, or, external equipment specializing observing system activity. Design for Debug or Test (Dfx). This refers to a logic block that provides debug or test support (E.g. via Test Access Port (TAP)). DvC:& Debug Capability on the USB device (Device Capability)&
Base Class
USB2 Compliance
Device.& Definition for this device can
be found at
Debug Target vendor
defined. Please see
for more info.
GNU Remote Debug
Command Set. Please see
for more info.
Vendor defined Trace protocol
Vendor defined Dfx
protocol on DbC.
Vendor defined Trace
protocol over General Purpose (GP) endpoint on DvC.
GNU Protocol protocol
over General Purpose (GP) endpoint on DvC.
Vendor defined Dfx
protocol on DvC.
Vendor defined Trace
protocol on DvC.
This base class is defined for devices that are Wireless controllers.&Values not shown in the table below are reserved. These class codes are to be used in Interface Descriptors, with the exception of the Bluetooth class code which can also be used in a Device Descriptor.
Base Class
Bluetooth Programming
Interface.& Get specific information from .
UWB Radio Control
Interface.& Definition for this is found in the Wireless USB
Specification in Chapter 8.
Remote NDIS.&
Information can be found at:
Bluetooth AMP
Controller. Get specific information from .
Host Wire Adapter
Control/Data interface.& Definition can be found in the Wireless USB
Specification in Chapter 8.
Device Wire Adapter
Control/Data interface.& Definition can be found in the Wireless USB
Specification in Chapter 8.
Device Wire Adapter Isochronous interface.& Definition can be found in the Wireless USB
Specification in Chapter 8.
This base class is defined for miscellaneous device definitions. Values not shown in the table below are reserved.& The use of these class codes (Device or Interface descriptor) are specifically annotated in each entry below.
Base Class
Active Sync
device. This class code can be used in either Device or Interface
Descriptors. Contact Microsoft for more information on this class.
Palm Sync. This class code can be used in either Device
or Interface Descriptors.
Association Descriptor. The usage of this class code triple is defined in the
Interface Association Descriptor ECN that is provided on . This class code may only be used in Device Descriptors.
Wire Adapter
Multifunction Peripheral programming interface. Definition can be found in
the Wireless USB Specification in Chapter 8. This class code may only be used
in Device Descriptors
Cable Based
Association Framework. This is defined in the Association Model addendum to
the Wireless USB specification. This class code may only be used in Interface
Descriptors.
RNDIS over
Connecting a
host to the Internet via Ethernet mobile device. The device appears to the
host as an Ethernet gateway device.
This class code
may only be used in Interface Descriptors.
RNDIS over WiFi.
Connecting a
host to the Internet via WiFi enabled mobile device.& The device represents itself to the host as
an 802.11 compliant network device.
This class code
may only be used in Interface Descriptors.
RNDIS over WiMAX
Connecting a
host to the Internet via WiMAX enabled mobile device.& The device is represented to the host as an
802.16 network device.
This class code
may only be used in Interface Descriptors.
RNDIS over WWAN
Connecting a
host to the Internet via a device using mobile broadband, i.e. WWAN
(GSM/CDMA).
This class code
may only be used in Interface Descriptors.
RNDIS for Raw
Connecting a
host to the Internet using raw IPv4 via non-Ethernet mobile device.& Devices that provide raw IPv4, not in an
Ethernet packet, may use this form to in lieu of other stock types.
This class code
may only be used in Interface Descriptors.
RNDIS for Raw
Connecting a
host to the Internet using raw IPv6 via non-Ethernet mobile device.& Devices that provide raw IPv6, not in an
Ethernet packet, may use this form to in lieu of other stock types.
This class code
may only be used in Interface Descriptors.
RNDIS for GPRS
Connecting a
host to the Internet over GPRS mobile device using the device?s cellular
USB3 Vision
Control Interface
Machine Vision
Device conforming to the USB3 Vision specification. This standard covers
cameras and other related devices that are typically used in machine vision,
industrial, and embedded applications.
Reference:
This class code
may only be used in Interface Descriptors.
USB3 Vision
Event Interface
USB3 Vision
Streaming Interface
STEP. Stream Transport Efficient Protocol for
content protection.
RAW. Stream Transport Efficient Protocol for Raw content protection.
Command Interface in IAD
The DVB Common Interface (DVB-CI)
specification describes a system whereby a removable CI Conditional Access
Module (CICAM), given the appropriate usage rights, unscrambles protected
pay-TV content and routes it over the same interface back to a TV receiver
for display. An interface association for a DVB-CI function will contain a
DVB-CI Command Interface for command, control, and status information, it may
contain a DVB-CI Media Interface for audiovisual data streams, and it may
also contain a CDC EEM interface to provide bridged networking to the CICAM.
Reference: https://www.dvb.org/standards/dvb-ci-plus
Command Interface in Interface Descriptor
Media Interface in Interface Descriptor
This base class is defined for devices that conform to several class specifications found on the USB-IF website.& That specification defines the usable set of SubClass and Protocol values.& Values outside of that defined spec are reserved.& These class codes can only be used in Interface Descriptors.
Base Class
Device Firmware Upgrade.& Device class definition provided on .
IRDA Bridge device.& Device class definition provided on .
USB Test and Measurement Device.& Definition provided in the USB Test and Measurement Class spec found on .
USB Test and Measurement Device conforming to the USBTMC USB488 Subclass Specification found on www.usb.org.
This base class is defined for vendors to use as they please.& These class codes can be used in both Device and Interface Descriptors.
Base Class
Vendor specific
Site sponsored by USB Implementers Forum, Inc., creators of USB technology.DHH805A-CN 中文
hart手操器说明书_图文_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
DHH805A-CN 中文
hart手操器说明书
阅读已结束,下载文档到电脑
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,方便使用
还剩50页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢当前位置: >>
基于 OHCI 的 USB 主机第一部分 概述 基于 OHCI 的 USB 主机的背景介绍与总体构架,使读者了解相应的知识背景。 1、基于 OHCI 的 USB 主机 ―― 前言 2、基于 OHCI 的 USB 主机 ―― 背景介绍 3、基于 OHCI 的 USB 主机 ―― 总体构架第二部分 寄存器读写接口 对 OHCI 规范所要求的寄存器操
作接口。纯寄存器操作,与规范和业务无关。 1、基于 OHCI 的 USB 主机 ―― 寄存器层(说明) 2、基于 OHCI 的 USB 主机 ―― 寄存器(初始化) 3、基于 OHCI 的 USB 主机 ―― 寄存器(传输) 4、基于 OHCI 的 USB 主机 ―― 寄存器(复位) 5、基于 OHCI 的 USB 主机 ―― 寄存器(设备连接) 6、基于 OHCI 的 USB 主机 ―― 寄存器(其它)第三部分 OHCI 软件接口 基于 OHCI 规范的底层控制端口和批量端口读写接口。 1、基于 OHCI 的 USB 主机 ―― OHCI(端点) 2、基于 OHCI 的 USB 主机 ―― OHCI(传输描述符) 3、基于 OHCI 的 USB 主机 ―― OHCI(HCCA) 4、基于 OHCI 的 USB 主机 ―― OHCI(基本流程) 5、基于 OHCI 的 USB 主机 ―― OHCI(ED 结构) 6、基于 OHCI 的 USB 主机 ―― OHCI(ED 结构说明) 7、基于 OHCI 的 USB 主机 ―― OHCI(TD 结构) 8、基于 OHCI 的 USB 主机 ―― OHCI(TD 结构说明) 9、基于 OHCI 的 USB 主机 ―― OHCI(设计思路) 10、基于 OHCI 的 USB 主机 ―― OHCI(自定义数据结构) 11、基于 OHCI 的 USB 主机 ―― OHCI(控制端口读数据) 12、基于 OHCI 的 USB 主机 ―― OHCI(控制端口写数据) 13、基于 OHCI 的 USB 主机 ―― OHCI(批量端口读数据) 14、基于 OHCI 的 USB 主机 ―― OHCI(批量端口写数据) 15、基于 OHCI 的 USB 主机 ―― 中断寄存器初始化 16、基于 OHCI 的 USB 主机 ―― 中断向量处理 17、基于 OHCI 的 USB 主机 ―― 中断处理程序 第四部分 USB 设备管理 当 USB 设备连接到主机上以后,USB 主机对其进行的枚举过程。 1、基于 OHCI 的 USB 主机 ―― USB 设备命令介绍 2、基于 OHCI 的 USB 主机 ―― USB 标准请求 3、基于 OHCI 的 USB 主机 ―― 描述符说明 4、基于 OHCI 的 USB 主机 ―― USB 设备枚举过程 5、基于 OHCI 的 USB 主机 ―― USB 设备描述符数据结构 6、基于 OHCI 的 USB 主机 ―― USB 设备其它数据结构 7、基于 OHCI 的 USB 主机 ―― USB 设备常量定义 8、基于 OHCI 的 USB 主机 ―― USB 设备获取描述符通用函数 9、基于 OHCI 的 USB 主机 ―― USB 设备取得设备描述符 10、基于 OHCI 的 USB 主机 ―― USB 设备取得配置描述符 11、基于 OHCI 的 USB 主机 ―― USB 设备设置地址 12、基于 OHCI 的 USB 主机 ―― USB 设备设置配置值 13、基于 OHCI 的 USB 主机 ―― USB 设备设置接口值 14、基于 OHCI 的 USB 主机 ―― USB 设备枚举 15、基于 OHCI 的 USB 主机 ―― USB 设备端口特性清除 第五部分 UFI 命令 这是 U 盘读写操作的底层协议接口。 1、基于 OHCI 的 USB 主机 ―― UFI 命令概述 2、基于 OHCI 的 USB 主机 ―― UFI 命令 USB Mass Storage Class Bulk-Only Transport 协议介绍 3、基于 OHCI 的 USB 主机 ―― UFI 查询命令(Inquiry) 4、基于 OHCI 的 USB 主机 ―― UFI 读容量命令(ReadCapacity) 5、基于 OHCI 的 USB 主机 ―― UFI 读扇区命令(Read10) 6、基于 OHCI 的 USB 主机 ―― UFI 写扇区命令(Write10) 7、基于 OHCI 的 USB 主机 ―― UFI 数据结构 1 8、基于 OHCI 的 USB 主机 ―― UFI 数据结构 2 9、基于 OHCI 的 USB 主机 ―― UFI 数据结构 3 10、基于 OHCI 的 USB 主机 ―― UFI 查询代码 11、基于 OHCI 的 USB 主机 ―― UFI 读容量代码 12、基于 OHCI 的 USB 主机 ―― UFI 读扇区代码 13、基于 OHCI 的 USB 主机 ―― UFI 写扇区代码 14、基于 OHCI 的 USB 主机 ―― UFI 读状态代码 15、基于 OHCI 的 USB 主机 ―― 批量端口复位代码 16、基于 OHCI 的 USB 主机 ―― UFI 命令监视代码 第六部分 附录 1、随便说几句 ―― 关于 USB 主机系列 2、基于 OHCI 的 USB 主机 ―― 结束语 3、AT91RM9200 的 USB 主机官方例程基于 OHCI 的 USB 主机 ―― 前言基于 OHCI 的 USB 主机 ―― 背景介绍使用 AT91RM9200 作为主控 CPU,利用该芯片的 USB 主机接口访问 U 盘,根据接收的上层命 令把相应数据保存到 U 盘的指定文件上。不使用额外的专用 USB 控制芯片,要求稳定可靠, 效率高,不能影响运行在该 CPU 上的其它程序。 AT91RM9200 程序加载后直接运行,没有操作系统。 以上就是我做的基于 OHCI 的 USB 主机的项目背景,这个项目是做什么的不重要,你可以把 它想象成任何项目,关键是这个项目要求使用 U 盘来保存数据。 另外, 在我们的项目中没有使用任何一款嵌入式操作系统, 所有的程序都运行在同一个主循 环中,自己来实现任务调度。说到操作系统,其实很惭愧,自从我开始从事嵌入式系统的开 发到现在,十几年了,从来没有用过任何操作系统,所有程序都是裸机直接运行。好处是系 统简单,一切都在自己的掌握之中,出了问题可以很快得到解决。坏处是系统的移植性差, 换了个系统有很多通用的代码需要重新编写。 不过我做的那些嵌入式系统现在看来其实都是蛮简单的, 用了操作系统可能反而更麻烦, 首 先得花时间学习操作系统, 而且出了问题还要分析确认这问题是不是操作系统的问题, 一旦 是操作系统的问题还要想办法怎么规避,算了,有那个时间项目早就做完了。 没有操作系统,我的程序更加清晰,没有了驱动程序加载、操作系统 API 调用,反而可以更 加清楚地知道如何基于 OHCI 规范实现 USB 主机。在开始讲解之前,我想读者应该具备如下 的基础知识: 1、 USB 接口基础知识; 2、 USB 层通信协议及基本工作流程; 3、 USB 主机对 USB 设备的管理流程; 4、 OHCI 标准 ―― AT91AM9200 对 USB 接口的操作标准; 5、 Mass Storage Protocol ―― 对 U 盘访问的存储控制协议; 6、 UFI Command - U 盘读写等操作命令; 7、 FAT16 文件系统; 基于 OHCI 的 USB 主机 ―― 总体构架在我们的系统中,USB 主机就是用来对 U 盘进行读写操作,因此在设计和构架上就完全围绕 这个目的而进行。整个系统所涉及到的内容比较多,按照嵌入式系统开发的一般原则,采用 层次化的体系结构,将系统按照功能划分为若干层次,每一层完成相应的功能。 根据系统的业务需要,系统总体构架如下:9 业务应用层 8 文件操作 API 层 7 文件系统层 6 U 盘操作命令接口层 5 UFI 命令层 4 USB 设备管理层 3 OHCI 软件接口层 2 寄存器读写接口层 1 硬件层这是一个分层的结构,每层完成自己的功能,层与层之间都是通过接口完成,基本上上层应 用都只依赖于下一层,对于个别层的功能实现需要依赖其下的 2 层,这是考虑实现的方便。 下面对每一层的功能进行说明: 1、 硬件 这是系统最底层,直接完成 USB 协议处理的硬件部分。 2、 寄存器读写接口 AM9200 支持标准的 OHCI 接口, 提供了访问 OHCI 寄存器的指针 (pUhp) 和数据交换区 (HCCA) , 本层对该指针和数据交换区的访问进行封装, 对外屏蔽了寄存器读写的细节。 以后如果移植 到非 OHCI 的系统上,则可以保持在接口不变,对该层进行重新编码即可。 3、 OHCI 软件接口 根据 OHCI 标准,数据传输都是通过端点描述符(ED)和传输描述符(TD)这两种数据结构 来完成的, 在进行传输之前需要对 ED 和 TD 进行相应的设置, 才可以保证数据传输的正确性, 本层对 ED 和 TD 的操作进行了封装,提供基于 OHCI 的数据传输接口。 关于 ED 和 TD 的详细介绍请参考 OHCI 规范 《Open Host Controller Interface Specification for USB》。 4、 USB 设备管理 根据 USB 标准,USB 设备都需要提供设备描述符、配置描述符、接口描述符和端点描述符等 信息,本层代码提供了取得这些描述符的命令。 另外,本层还将这些取得描述符的命令组合起来,完成了 USB 设备的枚举和检测。 5、 UFI 命令 根据《Universal Serial Bus Mass Storage Class Bulk-Only Transport》和《Universal Serial Bus Mass Storage Class UFI Command Specification》规范,完成 BulkOnly 协议 的 UFI 命令,提供扇区读写命令给上层。 6、 U 盘操作命令接口 一方面封装 UFI 命令层, 提供以扇区为单位的磁盘读写命令, 譬如 diskRead()、 diskWrite() 等函数,另一方面,调用 UFI 命令完成 U 盘枚举和检测,确定逻辑 0 扇区的编号,为构建文 件系统奠定基础。 7、 文件系统 完成文件系统初始化,得到相关的参数,提供目录查找、簇操作等接口给上层。 8、 文件操作库函数 仿照 C 语言的标准文件库函数, 提供一套便于上层业务应用所使用的 API 函数库, 包括文件 打开、关闭、读写和定位等。 9、 业务应用 这就是业务逻辑层了, 也就是根据接收的计费信息调用相应的文件操作库函数, 完成话单保 存的功能。 采用这样的层次结构,系统具有良好的可维护性和扩展性,只要 CPU 支持 OHCI 标准,则本 系统就可以不用修改直接使用, 如果 CPU 不支持 OHCI 标准, 则需要将 OHCI 层的代码进行修 改,保持上层的调用接口不变,就可以完成系统移植了。 如果需要扩展支持更多的 USB 设备, 则保持 OHCI 层基本不变或适当扩展 (目前的 OHCI 层代 码只支持控制和批量传输, 不支持同步和中断传输) , 添加新的驱动以及上层应用就可以了。 在这一篇文章里, 我对我们的系统进行总体上的说明, 这是为了避免一上来就阐述各种技术 细节,导致一叶障目,不见泰山。在本系列文章中,所有的代码都是按照这个构架原则来编 写的,记住这个构架,对于理解代码会有很大的帮助。 基于 OHCI 的 USB 主机 ―― 寄存器层(说明)AM9200 支持标准的 OHCI 规范,在其开发文档中对于 USB 主机部分的说明干脆就直接说参见 OHCI 规范。阅读 AM9200 的例程《AT91RM9200-BasicUHP》代码,发现系统已经提供了访问 OHCI 寄存器 的指针 pUhp,使用该指针就可以访问到所有的 OHCI 寄存器,因此读写寄存器的操作就是对 pUhp 指针进行操作。按照面向对象的编程思想,将所有寄存器看作是一个对象,对其操作都是通过接口来完成, 在外部不会使用到 OHCI 寄存器。这样对于嵌入式系统来说,性能上稍微受到一些影响(主 要是增加了函数调用的开销),但是代码清晰、易于维护。OHCI 规范种提供了很多的寄存器,在 U 盘处理的程序只使用了其中的一部分,如下:名称 HcBulkCurrentED HcBulkDoneHead HcBulkHeadED HccaDoneHead HcCommandStatus HcControl功能 该寄存器用于设置批量列表的当前端点变量的地址 OHCI 文档中没有,使用例程中缺省设置。 该寄存器用于设置批量列表的第一个端点变量的地址 存放最近完成传输的 TD 变量的地址,用于确定 TD 对列是否发送完毕。 该寄存器可被 HC 用来接收 HCD 发送的指令,也可反映 HC 的当前状态。 定义了 HC 的操作模式。HcControlCurrentED 该寄存器用于设置控制列表的当前端点变量的地址 HcControlHeadED 该寄存器用于设置控制列表的第一个端点变量的地址 HcFmInterval 寄存器包含一个 14 位值[FrameInteral,FI](用于表示一帧之内所占 HcFmInterval 用的比特时间,2 个连续的 SOFs)和一个 15 位的值 [FSLargestDataPacket,PSMPS] (用于表示在没有引发调度溢出下可发送或接收全速最大包大小),FI,PSMPS 的推 荐值为 0x2EDF 和 0x2778。 用来设置 HCCA 数据区的地址,由于该寄存器的要求,HCCA 变量地址的低 8 位必须为 HcHCCA 0,例如变量定义为: __align(256) AT91S_UHP_HCCA HCCA; HcInterruptEnable 该寄存器的使能位与 HcInterruptStatus 寄存器中的中断位相对应,用来控制事件 产生的硬件中断。 HcInterruptStatus HcPeriodicStart HcRhDescriptorA该寄存器提供所有事件状态,并将产生硬件中断。 The HcPeriodicStart register has a 14-bit programmable value which determines when is the earliest time HC should start processing the periodic list. 对根集线器特性进行描述的寄存器。HcRhPortStatus[1:2] 用来控制和报告每个端口上的事件。 HcRhStatus 该寄存器分为两个部分,低字部分为集线器状态域,高字部分为集线器状态更改域。关于上述寄存器的详细说明,请参考 OHCI 规范《Open Host Controller Interface Specification for USB》。基于 OHCI 的 USB 主机 ―― 寄存器(初始化)在 AM9200 中,USB 的中断是基于 AIC 中断的,因此要设置对应的 AIC 中断。在此之前 要设置 OHCI 的中断寄存器,代码如下:/** * USB 主机初始化 * @return 0 - 成功 */ short ohciHardInit(void) { //打开 USB 主机所使用的时钟 AT91F_UHP_CfgPMC(); AT91C_BASE_PMC-&PMC_SCER |= (AT91C_PMC_UHP); // Forcing UHP_Hc to reset pUhp-&UHP_HcControl = 0; // Writing the UHP_HCCA pUhp-&UHP_HcHCCA = (unsigned int) &HCCA; // Enabling list processing pUhp-&UHP_HcControl = 0; // Set the frame interval pUhp-&UHP_HcFmInterval = AT91C_FMINTERVAL; pUhp-&UHP_HcPeriodicStart = AT91C_PRDSTRT; // Initializing the UHP_HcDoneHead pUhp-&UHP_HcBulkDoneHead = 0x00; HCCA.UHP_HccaDoneHead = 0x0000; // Forcing UHP_Hc to Operational State reg = pUhp-&UHP_HcC pUhp-&UHP_HcControl = 0x80; // Enabling port power pUhp-&UHP_HcRhPortStatus[0] = 0x; pUhp-&UHP_HcRhPortStatus[1] = 0x; pUhp-&UHP_HcRhDescriptorA = OHCI_HC_RHDESCRIPTORA_NPS; pUhp-&UHP_HcRhStatus = 0x; // UDP: Connect a pull-up //调试时发现不设置此寄存器则返回的数据有问题 AT91F_PIO_SetOutput(AT91C_BASE_PIOD, AT91C_PIO_PD5); //设置 USB Host 中断寄存器 pUhp-&UHP_HcInterruptEnable =OHCI_HC_INTR_MIE |OHCI_HC_INTR_RHSC | OHCI_HC_INTR_UE | OHCI_HC_INTR_WDH | OHCI_HC_INTR_FNO; pUhp-&UHP_HcInterruptStatus = OHCI_HC_INTR_RHSC | OHCI_HC_INTR_UE | OHCI_HC_INTR_WDH | OHCI_HC_INTR_FNO; //设置 AIC 中断信息 AT91F_AIC_ConfigureIt( AT91C_BASE_AIC,AT91C_ID_UHP, AT91C_AIC_PRIOR_HIGHEST, AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED, AT91F_ASM_UHP_Handler); AT91F_AIC_EnableIt(AT91C_BASE_AIC,AT91C_ID_UHP); return 0; } OHCI 中的中断寄存器设置了若干中断,实际上有用的就是 WDH 中断,该中断是 TD 传输 完毕后产生的。 通过判断该中断的产生以及配合 HCCA 判断是否到达 TD 队列尾, 可以确定数 据是否传输完毕。基于 OHCI 的 USB 主机 ―― 寄存器(传输)进行控制传输之前,需要设置好相应的 ED 和 TD 参数(参见下一章),启动传输时需要 设置 OHCI 寄存器中的控制传输 ED 头指针寄存器和控制传输的当前 ED 指针寄存器,然后设 置控制寄存器允许处理控制传输列表, 控制状态寄存器有控制传输列表数据需要传输, 代码 如下:/** * 通过 Control 端口传输数据 * @param *ed 需要进行数据收发的 ED 指针 * @return 0 - 成功 */ short ohciCtrlXfer(AT91S_UHP_ED *ed) { // Programming the CHED pUhp-&UHP_HcControlHeadED = (unsigned int) // Programming the CCED pUhp-&UHP_HcControlCurrentED = (unsigned int) // UHP: UHP is now operational and control list processing is enabled pUhp-&UHP_HcControl = 0x90; // UHP: Notify the Hc that the Control list is filled pUhp-&UHP_HcCommandStatus = OHCI_HC_COMMAND_STATUS_CLF; return 0; }&!--[if !supportLists]--&&!--[endif]--&启动批量传输启动批量传输的流程与控制传输类似,只不过相应寄存器换为批量传输的寄存器了:/** * 通过 Bulk 端口传输数据 * @param *ed 需要进行数据收发的 ED 指针 * @return 0 - 成功 */ short ohciBulkXfer(AT91S_UHP_ED *ed) { // 禁止 ED pUhp-&UHP_HcControl = 0x180; pUhp-&UHP_HcCommandStatus = 0x00; // Programming the BHED pUhp-&UHP_HcBulkHeadED = (unsigned int) // Programming the BCED pUhp-&UHP_HcBulkCurrentED = (unsigned int) // UHP: UHP is now operational and control list processing is enabled pUhp-&UHP_HcControl = 0x0A0; // UHP: Notify the Hc that the Bulk list is filled pUhp-&UHP_HcCommandStatus = OHCI_HC_COMMAND_STATUS_BLF; return 0; } 基于 OHCI 的 USB 主机 ―― 寄存器(复位)当 USB 设备连接到某个端口上以后,根据规范,需要对相应 USB 端口进行复位 ,对于 AT91RM9200 来说,其实只有一个端口,该端口号固定为 0:/** * USB 端口复位 * @param port 需要复位的端口 * @return 0 成功 */ short ohciPortReset(unsigned char port) { // SetPortReset pUhp-&UHP_HcRhPortStatus[port] = (1 && 4); pUhp-&UHP_HcRhPortStatus[port] = (1 && 20 | 1 && 4); return 0; }按照规范,执行完上述复位操作以后,需要延时若干时间,经过在网上查询资料和实际 调试,发现延时时间在 100-150ms 之间为好。对于嵌入式系统来说,不可能让系统为了等待 复位完成而什么事情都不做,因此端口复位和判断复位是否结束需要分别放到两个函数中, 在上层代码中进行延时处理。&!--[if !supportLists]--&USB 端口复位结束对 USB 端口进行复位后,使用下述代码判断复位是否完成:/** * USB 端口复位是否结束 * @return 0 C 没有结束,&0 C 结束 */ short udpIsBusResetOver(void) { return pUdp-&UDP_ISR & AT91C_UDP_ENDBUSRES; } 基于 OHCI 的 USB 主机 ―― 寄存器(设备连接)读取 HcRhPortStatus 寄存器可以得到相应 USB 端口是否有设备连接,但是在嵌入式系统 中, 为了增强系统的稳定性, 要有适当的算法保证在一段时间内, 连续读到设备连接或断开, 则才能确定设备的连接状态,下面的函数在定时中断中被调用,用来检测 USB 设备的连接 状况:/** * 读取 USB 设备连接情况 */ void ohciReadConState(unsigned short port) { ohciConnectState &&= 1; //读取寄存器,得到当前状态 if (pUhp-&UHP_HcRhPortStatus[port] & 0x01) { ohciConnectState |= 1; } if (ohciConnectState == 0xFF) { //设备连接 ohciConnectFlag = 0x55; } else if (ohciConnectState == 0x00) { //设备断开 ohciConnectFlag = 0x00; } }定时中断为 10ms,上述代码的意思就是连续 80ms 检测到设备连接或者断开,才能修 改设备的连接状态。 基于 OHCI 的 USB 主机 ―― 寄存器(其它)对 USB 端口进行关电处理的目的主要有两个,一是安全拔下 U 盘,防止带电插拔造成 数据丢失或错误,另一个是为了再次开电,对 U 盘内部程序进行复位。/** * 断开 USB 端口的供电 */ short ohciHardDisable(void) { // Disable port power pUhp-&UHP_HcRhPortStatus[0] = 0x; pUhp-&UHP_HcRhPortStatus[1] = 0x; // Disable global power pUhp-&UHP_HcRhStatus = 0x; return 0; }&!--[if !supportLists]--&清除中断状态该程序在中断程序中被调用,在 OHCI 规范中,设置中断是通过 HcInterruptEnable 寄 存器来完成的,而产生中断以后,中断状态寄存器(HcInterruptStatus)的对应位就会被设 置为 1,通过查询该寄存器的内容可以得知当前中断产生的原因。 但是如果中断状态寄存器的数据不清除的话, AM9200 就不会产生新的中断, 因此在中 断处理程序中需要调用本函数清除中断状态:/** * 清除中断状态寄存器的内容,以便能够产生新的中断 */ short ohciClearIntrStatus(void) { pUhp-&UHP_HcInterruptStatus = 0xFFFFFFFF; return 0; }说明: 按照 OHCI 规范, 在中断状态寄存器的相应位写 1, 就可以清除对应的中断状态。 基于 OHCI 的 USB 主机 ―― OHCI(端点)OHCI (Open Host Controller Interface),是康柏、微软、国家半导体等公司共同制定的 一个 USB 主机接口规范,它提供一个更抽象的接口来完成 USB 数据传输工作。 在 OHCI 规范中,最重要的几个概念是端点(EndPoint - ED)、传输描述符(Transport Descriptor - TD)、主机控制器通信区(HCCA)。其中 ED 负责确定传输类型(控制传输、 批量传输、同步传输和中断传输)。TD 确定传输参数。HCCA 用于确定数据传输是否完毕。 下面对上面的概念进行说明,主要是翻译了 OHCI 规范的相关内容,更详细的内容请参考 《Open Host Controller Interface Specification for USB》 。 端点 ED(Endpoint Descriptor 端点描述符)包含了 HC 所使用的端点的信息,包括端点地址、 传输速度和最大数据包尺寸等内容。另外 ED 还是 TD(传输描述符)链表的锚点。在 ED 里 保存该 ED 收发数据所使用的 TD 链表头指针。 当 HC 处理 ED 并且发现一个合法的 TD 地址时, HC 根据 ED 内标明的端点以及 TD 的地址完成数据传输。 在 USB 的规范中规定了 4 种数据传输类型:控制传输、批量传输、同步传输和中断传输。在 OHCI 中对应这 4 种传输类型有 4 个传输 ED 列表,主要使用控制寄存器(HcControl)和命 令状态寄存器(HcCommandStatus)进行控制。 控制和批量传输的 ED 组成列表,每个 ED 下面带着需要进行处理的 TD,ED 包含端点所允许 的最大的包大小,控制器硬件完成包的分割。每次传输后都会更新指向数据缓冲区的指针, 当起始和终止指针相等时,TD 就释放到完成队列(done-queue)。下图是一个典型的链表结 构图。 在 OHCI 中,每一帧的时间被分为 3 块,首先处理批量和端点列表,这段时间由 HcPeriodicStart 寄存器的设置来控制,然后处理周期性列表(中断和同步列表),处理完 毕如果还有时间,则继续处理批量和端点列表,如下图:对于控制和批量传输来说, 控制端点比批量端点有更多的总线处理机会。 每处理 1 个批量端 点就需要处理 N 个控制端点,这个 N:1 的比例叫做控制批量服务比例。HCD 通过 HcControl 寄存器的 ControlBulkServiceRatio 字段来设置比例,比例的范围从 1:1 到 4:1。 HC 强制按照控制批量服务比例进行处理,而不考虑相应列表中的控制和批量 ED 的数量。如 果只有 1 个控制 ED 在控制列表中,而控制批量服务比例为 4:1,则在批量 ED 被服务之前, 该控制 ED 被服务 4 次。如果控制或批量列表中没有 ED,HC 就会跳过对应的列表,而立刻处 理其它的列表并且完成需要的 ED 数量。HC 会根据控制批量服务比例继续检查空列表,如果 有新的 ED,就按照该比例进行处理。基于 OHCI 的 USB 主机 ―― OHCI(传输描述符)传输描述符(TD) 传输描述符(TD)是系统内存的数据结构,被 HC 用于定义从端点收发数据的缓冲区。 TD 分为 2 个类型:通用 TD 和同步 TD。通用 TD 用于中断、控制和批量端点,同步 TD 用于同 步传输。使用两种不同的 TD 类型是因为缓冲区类型的不同。对于 U 盘主机控制器来说,不 使用同步传输。若干个传输描述符组成队列链接到 ED 上。ED 提供传输 TD 数据所需要的端点地址。HCD 把 TD 增加到队列中,而 HC 把 TD 从队列中删除。HC 把 TD 从队列删除后,将其链接到已完 成队列,这个过程叫做“释放”。TD 的释放原因包括正常释放和错误释放。当 TD 释放后, 释放情况代码被写到 TD 中,以便 HCD 确定释放原因。TD 是按照顺序进行处理的。它们被链接到 ED 上。TD 队列的第一个 TD 指针放在 ED 的 NextTransferDescriptor 字段,HC 从该 TD 开始处理队列。当 TD 被释放,就会从队列中删 除,该 TD 的 NextTransferDescriptor 字段所指向的下一个 TD 被转移到队列头。当 HC 处 理 ED 的时候,只会产生一个事务。HC 只有在当前 ED 的所有 TD 都处理完毕后才会产生下一 个事务。 在每一个事务完成以后就会更新通用 TD。有 4 个字段会被更新:CompletionCode、 DataToggleControl、CurrentBufferPointer、ErrorCount。DataToggleControl 字段反映了下一次传输所需要的数据分组 PID。如果当前包成功传 输,HC 就会设置 DataToggleControl 字段最高位,并切换最低位以反映下一次传输所需要 的新的数据分组 PID。如果当前包没有收到 ACK 或 NAK,则该字段不会被修改。CurrentBufferPointer 表示当前包传输后是否收到 ACK 或者是否有错误。 如果 HC 收到 ACK 或带有不正确切换标记的 NAK,CurrentBufferPointer 字段就不会更新,因为 HC 需要 重试当前包。如果 CurrentBufferPointer 字段需要更新,包内传输的字节数将会加到当前 的 CurrentBufferPointer 字段。如果当前包跨越了页边界,则 CurrentBufferPointer 字 段的高 20 比特位将会更新为 BufferEnd 字段的高 20 比特位,以反映页基地址的变化。 CurrentBufferPointer 的低 12 位将会滚动到正确的值以代表新的包地址。如果包传输发生错误,ErrorCount 字段会加 1。如果 ErrorCount 的值为 2,同时有其 它的错误发生,TD 就会被释放,并且在 CompletionCode 字段设置错误代码。CompletionCode 字段表示通用 TD 是否传输成功。 如果事务成功, 则该字段被设置为 “无 错误”,否则设置为相应的错误代码。对于通用 TD,ConditionCode 字段的值只有在 TD 在 已完成队列中的时候才有意义。对于 CRC、位填充错和设备没响应错误,TD 在错误发生 3 次以后才会被释放到已完成队列。对于拖延、数据溢出、数据不足等错误,TD 在第一次发 生错误的时候就会被释放到已完成队列。 通用 TD 没有用到缓冲区溢出和缓冲区不足的错误。 当通用 TD 带着错误被转移到已完成队列时, ED 的 Halted 字段被设置为 1, 以暂停处理 TD 队列,直到软件清除了错误状态基于 OHCI 的 USB 主机 ―― OHCI(HCCA)主机控制器通信区(HCCA)是一个 256 字节对齐的内存数据结构,被系统软件用于与 HC 进行通信,收发相关控制和状态信息。系统软件通过 HcHCCA 寄存器设置 HCCA 的地址到 HC。 该结构允许软件给 HC 的函数指明方向, 而不需要从 HC 读取, 除非不寻常的状况发生 (例 如发生错误)。通常与 HC 的交互可以通过读取 HCCA 结构的值或者写入 HC 操作寄存器来完 成。HC 周期性的将 HcDoneHead 寄存器的值写入到内存 HccaDoneHead, 以便主机软件可以处 理已完成的 TD。通常 HcDoneHead 在每一帧的开始,并且中断延时计数器为 0 时完成数据更 新。在 HcDoneHead 被写入到 HccaDoneHead 之后,HC 设置 HcDoneHead 寄存器的值为 0,并 且设置 HcInterruptStatus 寄存器的 WD 位为 1。 在写完 HccaDoneHead 之后, HC 可以开始建 立新的已完成队列,但是新的队列只有在 HCD 清除了 WDH 位以后才可以进行。在 HC 产生的中断上,HCD 检查 HccaDoneHead 值。如果该值为 0,则该中断不是 HccaDoneHead 更新所产生,而是需要访问 HcInterruptStatus 寄存器以确定正确的中断原 因。如果 HccaDoneHead 非 0,表明该中断是由于已完成队列产生,如果最低位的值非 0,则 表明同时还产生了中断,需要访问 HcInterruptStatus 寄存器,确定中断原因。 基于 OHCI 的 USB 主机 ―― OHCI(基本流程)根据上面的介绍可以发现,通过 USB 端口进行数据收发的主要工作就是构建 ED 和 TD 列表。 其中 ED 列表控制数据的传输方向,TD 列表完成具体的数据打包和传输。 按照 OHCI 规范,ED 和 TD 列表都是可以在使用过程中对某个节点进行修改,比如增加和删 除。但是为了程序处理简便起见,最好采用顺序处理模式,也就是一个命令执行完毕以后, 再重新构建新的 ED 和 TD 列表,执行下一个命令。 进行控制/批量传输的主要处理流程如下: 1、 创建控制/批量传输的 ED 列表; 2、 创建 ED 下的 TD 列表; 3、 设置命令到相应寄存器开始数据传输; 4、 在中断处理程序中判断数据传输是否结束; 对于控制传输来说,实际上一次控制传输只需要 1 个 ED 即可,而批量传输则需要 2 个 ED, 分别用于批量出端口和批量入端口。 控制传输的 ED 下面需要有 3 个 TD,分别是 SETUP、DATA、STATUS(对于没有数据的命令, 则不需要 DATA,因此不需要相应的 TD)。 批量写数据命令 Out ED 下面有 2 个 TD,分别是 CBW、DATA,In ED 下面有 1 个 ED,是 CSW。 批量读数据命令 Out ED 下面有 1 个 TD,是 CBW,In ED 下面有 2 个 TD,分别是 DATA 和 CSW。 基于 OHCI 的 USB 主机 ―― OHCI(ED 结构)ED 数据结构,定义如下:typedef struct _AT91S_UHP_ED { volatile unsigned int C volatile unsigned int TailP; volatile unsigned int HeadP; volatile unsigned int NextEd; } AT91S_UHP_ED, *AT91PS_UHP_ED;Endpoint Descriptor FormatAn Endpoint Descriptor (ED) is a 16-byte, memory resident structure that must be aligned to a 16-byte boundary. The Host Controller traverses lists of EDs and if there are TDs linked to an ED, the Host Controller performs the indicated transfer.3 1 Dword 0 Dword 1 Dword 2 Dword 3 ― 2 6 MPS 1 1 1 1 1 1 1 6 5 4 3 2 1 0 F K S D EN 0 0 0 0 0 0 0 0 7 6 5 4 3 2 1 0 FA ― 0 ― C HTD Queue Tail Pointer (TailP) TD Queue Head Pointer (HeadP) Next Endpoint Descriptor (NextED)Notes: 1. Fields containing ‘―’ are not interpreted or modified by the Host Controller and are available for use by the Host Controller Driver for any purpose. 2. Fields containing ‘0’ must be written to 0 by the Host Controller Driver before queued for Host Controller processing. If Host Controller has write access to the field, it will always write the field to 0.基于 OHCI 的 USB 主机 ―― OHCI(ED 结构说明) ED 结构说明节选自 OHCI 的规范。Name HC Access FunctionAddress FA R This is the USB address of the function containing the endpoint that this ED controls EN R EndpointNumber This is the USB address of the endpoint within the function Direction This 2-bit field indicates the direction of data flow (IN or OUT.) PID field of the TD. The encoding of the bits of this field are: If neither IN nor OUT is specified, then the direction is determined from the DescriptionDRCode 00b 01b 10b 11bDirection Get direction From TD OUT IN Get direction From TDSpeed S R Indicates the speed of the endpoint: full-speed (S = 0) or low-speed (S = 1.) sKip K R When this bit is set, the HC continues on to the next ED on the list without attempting access to the TD queue or issuing any USB token for the endpoint Format This bit indicates the format of the TDs linked to this ED. F R General TD format is used. If this is a Control, Bulk, or Interrupt Endpoint, then F = 0, indicating that the If this is an Isochronous Endpoint, then F = 1, indicating that the Isochronous TD format is used. MaximumPacketSize MPS R This field indicates the maximum number of bytes that can be sent to or received from the endpoint in a single data packet TDQueueTailPointer TailP R If TailP and HeadP are the same, then the list contains no TD that the HC can process. If TailP and HeadP are different, then the list contains a TD to be processed. H R/W Halted This bit is set by the HC to indicate that processing of the TD queue on the endpoint is halted, usually due to an error in processing a TD. toggleCarry C R/W This bit is the data toggle carry bit. from the retired TD. HeadP R/W TDQueueHeadPointer Points to the next TD to be processed for this endpoint. NextED If nonzero, then this entry points to the next ED on the list Whenever a TD is retired, this bit is written to contain the last data toggle value (LSb of data Toggle field) This field is not used for Isochronous EndpointsNextEDR基于 OHCI 的 USB 主机 ―― OHCI(TD 结构)TD 数据结构定义如下:typedef struct _AT91S_UHP_TD { volatile unsigned int C volatile unsigned int CBP; volatile unsigned int NextTD; volatile unsigned int BE; } AT91S_UHP_TD, *AT91PS_UHP_TD;General Transfer DescriptorTransfers for control, bulk, and interrupt all use the same format for their Transfer Descriptor (TD). This General TD is a 16-byte, host memory structure that must bealigned to a 16-byte boundary.General Transfer Descriptor Format3 1 Dword 0 Dword 1 Dword 2 Dword 3 CC 2 2 2 2 2 2 8 7 6 5 4 3 EC T DI 2 2 1 1 1 0 9 8 DP R ― 0 3 0 0Current Buffer Pointer (CBP) Next TD (NextTD) Buffer End (BE) 0General TD Format Note:In Dword0, there are fields that are read/write by the HC.The unused portionof this Dword (indicated by ‘―’ ) must either not be written by Host Controller or must be read, and then written back unmodified. The Host Controller Driver should not modify any portion of the TD while it is accessible to the HC.基于 OHCI 的 USB 主机 ―― OHCI(TD 结构说明)Name HC Access bufferRounding If this bit is 0, then the last data packet to a TD from an endpoint must R R exactly fill the defined data buffer. condition on the TD. Direction/PID This 2-bit field indicates the direction of data flow and the PID to be used for the token. This field is only relevant to the HC if the D field in the ED was set to 00b or 11b indicating that the PID determination is deferred to the TD. The encoding of the bits within the byte for this field are: DP R If the bit is 1, then the last data packet may be smaller than the defined buffer without causing an error DescriptionCodePID TypeData Direction00b 01b 10b 11bSETUP OUT IN Reservedto endpoint to endpoint from endpointDelayInterrupt This field contains the interrupt delay count for this TD. DI R When a TD is complete the HC may wait for DelayInterrupt frames before generating an interrupt. If DelayInterrupt is 111b, then there is no interrupt associated with completion of this TD. DataToggle This 2-bit field is used to generate/compare the data PID value (DATA0 or T R/W DATA1). It is updated after each successful transmission/reception of a data packet. The MSb of this field is ‘0’ when the data toggle value is acquired from the toggleCarry field in the ED and ‘1’ when the data toggle value is taken from the LSb of this field. ErrorCount For each transmission error, this value is incremented. EC R/W field and placed on the done queue. error, ErrorCount is reset to 0. ConditionCode CC R/W This field contains the status of the last attempted transaction. (See Section 0.) CurrentBufferPointer CBP R/W Contains the physical address of the next memory location that will be accessed for transfer to/from the endpoint. A value of 0 indicates a zero-length data packet or that all bytes have been transferred. NextTD R/W NextTD This entry points to the next TD on the list of TDs linked to this endpoint BufferEnd Contains physical address of the last byte in the buffer for this TD If ErrorCount is 2 and another error occurs, the error type is recorded in the ConditionCode When a transaction completes withoutBERConditionCodeCode 0000 NoError Meaning Description General TD or isochronous data packet processing completed with no detected errors
CRC BitStuffing Last data packet from endpoint contained a CRC error. Last data packet from endpoint contained a bit stuffing violation 0011 DataToggleMismatch Last packet from endpoint had data toggle PID that did not match the expected value. 0100 Stall TD was moved to the Done Queue because the endpoint returned a STALL PID 0101 DeviceNotResponding Device did not respond to token (IN) or did not provide a handshake (OUT) 0110 PIDCheckFailure Check bits on PID from endpoint failed on data PID (IN) or handshake (OUT) 0111UnexpectedPIDReceive PID was not valid when encountered or PID value is not defined.1000DataOverrunThe amount of data returned by the endpoint exceeded either the size of the maximum data packet allowed from the endpoint (found in MaximumPacketSize field of ED) or the remaining buffer size.1001DataUnderrunThe endpoint returned less than MaximumPacketSize and that amount was not sufficient to fill the specified buffer00reserved reserved BufferOverrun During an IN, HC received data from endpoint faster than it could be written to system memory1101BufferUnderrunDuring an OUT, HC could not retrieve data from system memory fast enough to keep up with data USB data rate.111xNot AccessedThis code is set by software before the TD is placed on a list to be processed by the HC.基于 OHCI 的 USB 主机 ―― OHCI(设计思路)在 OHCI 层,主要完成如下功能: ???通过控制端口读写数据(包含 SETUP、DATA、STATUS 等 3 个 TD); ???通过控制端口发送设置命令(没有 DATA 的 TD); ???通过批量端口读数据; ???通过批量端口写数据; ???中断处理程序;本层将 OHCI 的 ED 和 TD 作为自己内部的对象进行包装,上层对象通过调用本层接口完 成所需要的功能,而不必关心 ED 和 TD 的细节。 通过 OHCI 接口进行数据收发,最主要的工作就是确定 ED 和 TD 队列。在网上广为流传 的周立功公司的相关资料以及该公司出版的《ARM 嵌入式系统软件开发实例》 (一)、 (二) 中, 关于 ED 和 TD 的处理非常复杂, 甚至为此建立了一个管理机制, 包括队列的建立、 插入、 删除、释放等一系列操作。其实对于一般的嵌入式系统来说, 没有必要把 ED 和 TD 搞得这么复杂。 在我们的系统中, ED 和 TD 的管理非常简单:把待处理的命令构建为 ED 和 TD 队列,然后执行,等到执行完毕 再根据上层代码的需要构建新的队列。 也就是说只有等到上一个命令全部执行完毕后, 才可 以执行下一个命令。这样的处理机制完全可以适应绝大多数的嵌入式系统了。基本上来说,每个端点使用一个 ED,譬如对于控制端口的命令,使用一个 ED 即可,而 对于批量端口,则会使用到两个 ED,分别对应批量出和批量入端口。对于端点来说,代码中需要注意的参数有如下几个: ???ED 的 ToggleCarry 用来确定 ED 使用哪个数据区收发收据,对于控制端点来说,根据 USB 规范,每个控制命令 总是从 Data0 开始的,后面再进行切换。因此控制端点的 ToggleCarry 字段随便设置,而批 量端点的该字段需要得到上一次传送完毕后的 ToggleCarry 的值。 ???TD 的 DataToggle 用来确定 TD 使用哪个数据区收发数据。该字段有 2 个比特,高位=0 表示使用 ED 的 ToggleCarry 字段的值作为要使用的数据区,=1 表示自己控制使用哪一个数据区。根据 USB 规范,对于控制端点收发数据来说,需要 TD 自己控制使用哪一个数据区。而对于批量端点, 不需要 TD 自己控制,交由 ED 进行控制。基于 OHCI 的 USB 主机 ―― OHCI(自定义数据结构)OHCI 接口层用到的数据结构定义如下,这些数据定义都是我自己的程序里所使用的自 定义数据结构,是根据 OHCI 的标准与程序的处理方式进行定义的:/** * USB 设备信息 */ typedef struct _USB_DEV_INFO { unsigned char bulkInP unsigned char bulkOutP }USB_DEV_INFO; //!& USB 设备地址 //!& 批量出端口号 //!& 批量入端口号常量定义:#define TD_SETUP #define TD_OUT #define TD_IN #define TD_DELAY_INT #define ED_SETUP #define ED_OUT #define ED_IN 0x0 0x1 0x2 0x2 0x0 0x1 0x2 1 100#define USB_CMD_WAIT_OVER #define USB_CMD_OVER#define USB_CMD_WAIT_OVER_2 2#define USB_CMD_TYPE_BULK_WRITE 1 #define USB_CMD_TYPE_BULK_READ #define USB_CMD_TYPE_BULK_CMD #define USB_CMD_TYPE_CTRL_READ 2 3 4#define USB_CMD_TYPE_CTRL_WRITE 5 USB 主机开发 ―― OHCI(控制端口读数据)根据 USB 的规范, 在系统初始化的时候需要从控制端口发送命令, 其中有一些命令是包 含数据的,对于这些命令,需要调用本函数来完成。函数内主要调用 AM9200 提供的 OHCI 接口:AT91F_CreateEd()和 AT91F_CreateGenTd()来完成 ED 和 TD 的参数设置:/** * 从控制端点读取数据 * @param pSetup Setup 包指针,用来设置数据长度和传输方向 * @param *pData 数据缓冲区指针 */ short ctrlCmdGet(unsigned int pSetup, unsigned short len, unsigned char *pData) { uns //初始化控制端点的 ED AT91F_CreateEd( (unsigned int) &controlEd, // ED Address 64, 0, 0, 0, 0x0, 0, usbDevInfo.addr, (unsigned int) &genTd[3], (unsigned int) &genTd[0], 0, 0x0); direction = TD_IN; //控制端点的第一个 TD,用于发送 Setup 包 AT91F_CreateGenTd( (unsigned int) &genTd[0], 2, TD_DELAY_INT, TD_SETUP, 1, (unsigned int) pSetup, (unsigned int) &genTd[1], // TD Address // Data Toggle // DelayInterrupt // Direction // Buffer Rounding // Current Buffer Pointer // Next TD // Max packet // TD format // Skip // Speed // Direction // Endpoint // Func Address // TDQTailPointer // TDQHeadPointer // ToggleCarry // NextED 8);// Buffer Length//控制端点的第二个 TD,用于接收数据 AT91F_CreateGenTd( (unsigned int) &genTd[1], 3, TD_DELAY_INT, direction, 1, (unsigned int) pData, (unsigned int) &genTd[2], len); // TD Address // Data Toggle // DelayInterrupt // Direction // Buffer Rounding // Current Buffer Pointer // Next TD // Buffer Length//控制端点的第三个 TD,用于得到命令的状态 AT91F_CreateGenTd( (unsigned int) &genTd[2], 3, TD_DELAY_INT, ~direction, 1, 0x0, (unsigned int) &genTd[3], 0x0); // TD Address // Data Toggle // DelayInterrupt // Direction // Buffer Rounding // Current Buffer Pointer // Next TD // Buffer Length//标志 TD 队列结束的最后一个 TD,设置为空 AT91F_CreateGenTd( (unsigned int) &genTd[3], 3, TD_DELAY_INT, ~direction, 1, 0x0, (unsigned int) 0, 0x0); //调用底层接口把数据发送出去 ohciCtrlXfer(&controlEd); //设置相关信息,以便中断程序中判断命令是否结束 usbRunCmd(USB_CMD_TYPE_CTRL_READ, 3); return 0; } // TD Address // Data Toggle // DelayInterrupt // Direction // Buffer Rounding // Current Buffer Pointer // Next TD // Buffer Length 基于 OHCI 的 USB 主机开发 ―― OHCI(控制端口写数据)在 USB 设备初始化枚举过程中, 需要发送一些设置命令到 USB 设备上, 需要调用本函数 来完成。函数的处理跟控制端口读数据差不多,只不过 TD 的数据传输方向设置不一样:/** * 通过控制端口发送设置数据的命令 * @param pSetup Setup 包指针 * @param *pData 数据缓冲区指针 */ short ctrlCmdSet(unsigned int pSetup, unsigned char *pData) { //初始化控制端点的 ED AT91F_CreateEd( (unsigned int) &controlEd, // ED Address 64, 0, 0, 0, 0x0, 0, usbDevInfo.addr, (unsigned int) &genTd[2], (unsigned int) &genTd[0], 0, 0x0); // Max packet // TD format // Skip // Speed // Direction // Endpoint // Func Address // TDQTailPointer // TDQHeadPointer // ToggleCarry // NextED//控制端点的第一个 TD,用于发送 Setup 包 AT91F_CreateGenTd( (unsigned int) &genTd[0], 2, TD_DELAY_INT, TD_SETUP, 1, (unsigned int) pSetup, (unsigned int) &genTd[1], 8); // TD Address // Data Toggle // DelayInterrupt // Direction // Buffer Rounding // Current Buffer Pointer // Next TD // Buffer Length//控制端点的第二个 TD,用于发送数据 AT91F_CreateGenTd( (unsigned int) &genTd[1], 3, TD_DELAY_INT, TD_IN, 1, (unsigned int) pData, (unsigned int) &genTd[2], 0);// TD Address // Data Toggle // DelayInterrupt // Direction // Buffer Rounding // Current Buffer Pointer // Next TD // Buffer Length//标志 TD 队列结束的最后一个 TD,设置为空 AT91F_CreateGenTd( (unsigned int) &genTd[2], 3, TD_DELAY_INT, TD_OUT, 1, 0x0, (unsigned int) 0, 0x0); //调用底层接口把数据发送出去 ohciCtrlXfer(&controlEd); usbRunCmd(USB_CMD_TYPE_CTRL_WRITE, 2); return 0; } // TD Address // Data Toggle // DelayInterrupt // Direction // Buffer Rounding // Current Buffer Pointer // Next TD // Buffer Length基于 OHCI 的 USB 主机 ―― OHCI(批量端口读数据)对于 U 盘来说, 进行 U 盘的数据传输时需要通过批量传输端口收发数据, 所使用的协议 为 Mass Storage 协议,参见《Universal Serial Bus Mass Storage Class Bulk-Only Transport》 。该协议是批量端口数据传输的底层协议,为了完成 U 盘扇区读写,还需要在 该协议上面实现 UFI 协议,参见《Universal Serial Bus Mass Storage Class UFI Command Specification》 。 在本函数内只处理 Mass Storage 协议,不理会 UFI 协议:/** * 从批量端点读取数据 * @param *pCbw CBW 数据区指针 * @param *pData 存放读取结果的数据区指针 * @param *pCsw CSW 数据区指针 */ short bulkRead(unsigned char *pCbw, unsigned char *pData, unsigned char *pCsw) { BYTE //得到批量出端点的下一次发送数据区编号 toggle = usbGetEdToggle(bulkEd[0]); //初始化批量出端点 ED AT91F_CreateEd( (unsigned int) &bulkEd[0], 64 , 0, 0, 0, ED_OUT, usbDevInfo.bulkOutPort, usbDevInfo.addr, (unsigned int) &genTd[1], (unsigned int) &genTd[0], toggle, // ED Address // Max packet // TD format // Skip // Speed // Direction // Endpoint // Func Address // TDQTailPointer // TDQHeadPointer // ToggleCarry(unsigned int) &bulkEd[1]); // NextED //设置批量出端点的 TD,用于发送 CBW 命令 AT91F_CreateGenTd( (unsigned int) &genTd[0], 0, TD_DELAY_INT, TD_OUT, 1, (unsigned int) pCbw, (unsigned int) &genTd[1], 31); AT91F_CreateGenTd( // TD Address // Data Toggle // DelayInterrupt // Direction // Buffer Rounding // Current Buffer Pointer // Next TD // Buffer Length (unsigned int) &genTd[1], 0, TD_DELAY_INT, TD_OUT, 1, 0x0, (unsigned int) 0, 0x0);// TD Address // Data Toggle // DelayInterrupt // Direction // Buffer Rounding // Current Buffer Pointer // Next TD // Buffer Length//得到批量入端点的下一次发送数据区编号 toggle = usbGetEdToggle(bulkEd[1]); //初始化批量入端点 ED AT91F_CreateEd( (unsigned int) &bulkEd[1], 64 , 0, 0, 0, ED_IN, usbDevInfo.bulkInPort, usbDevInfo.addr, (unsigned int) &genTd[4], (unsigned int) &genTd[2], toggle, (unsigned int) 0); //设置批量入端点的 TD //用于接收数据的 TD AT91F_CreateGenTd( (unsigned int) &genTd[2], 0, TD_DELAY_INT, TD_IN, 1, (unsigned int) pData, (unsigned int) &genTd[3], 512); //用于接收 CSW 的 TD AT91F_CreateGenTd( (unsigned int) &genTd[3], 0, TD_DELAY_INT, TD_IN, // TD Address // Data Toggle // DelayInterrupt // Direction // TD Address // Data Toggle // DelayInterrupt // Direction // Buffer Rounding // Current Buffer Pointer // Next TD // Buffer Length // ED Address // Max packet // TD format // Skip // Speed // Direction // Endpoint // Func Address // TDQTailPointer // TDQHeadPointer // ToggleCarry // NextED 1, (unsigned int) pCsw, (unsigned int) &genTd[4], 64); AT91F_CreateGenTd( (unsigned int) &genTd[4], 0, TD_DELAY_INT, TD_IN, 1, 0x0, (unsigned int) 0, 0x0); //调用底层接口把数据发送出去 ohciBulkXfer(&bulkEd[0]);// Buffer Rounding // Current Buffer Pointer // Next TD // Buffer Length// TD Address // Data Toggle // DelayInterrupt // Direction // Buffer Rounding // Current Buffer Pointer // Next TD // Buffer LengthusbRunCmd(USB_CMD_TYPE_BULK_READ, 3); return 0; }基于 OHCI 的 USB 主机开发 ―― OHCI(批量端口写数据)通过批量端口向 U 盘写数据的函数处理与上面类似, 只不过 ED[0]下面要有 2 个 TD, 一 个是 CBW,另一个是 DATA。而 ED[1]下只有 1 个 TD,是 CSW。在本函数内只处理 Mass Storage 协议,不理会 UFI 协议:/** * 从批量端点发送数据 * @param *pCbw CBW 数据区指针 * @param *pData 存放读取结果的数据区指针 * @param *pCsw CSW 数据区指针 */ short bulkWrite(unsigned char *pCbw, unsigned char *pData, unsigned char *pCsw) { BYTE //得到批量出端点的下一次发送数据区编号 toggle = usbGetEdToggle(bulkEd[0]); //初始化批量出端点 ED AT91F_CreateEd( (unsigned int) &bulkEd[0], 64 , 0, 0, 0, ED_OUT, usbDevInfo.bulkOutPort, usbDevInfo.addr, (unsigned int) &genTd[2], (unsigned int) &genTd[0], toggle, // ED Address // Max packet // TD format // Skip // Speed // Direction // Endpoint // Func Address // TDQTailPointer // TDQHeadPointer // ToggleCarry(unsigned int) &bulkEd[1]); // NextED //设置批量出端点的 TD //用于发送 CBW 命令的 TD AT91F_CreateGenTd( (unsigned int) &genTd[0], 0, TD_DELAY_INT, TD_OUT, 1, (unsigned int) pCbw, (unsigned int) &genTd[1], 31); //用于发送数据的 TD AT91F_CreateGenTd( (unsigned int) &genTd[1], 0, TD_DELAY_INT, TD_OUT, 1, (unsigned int) pData, (unsigned int) &genTd[2], 512); AT91F_CreateGenTd( (unsigned int) &genTd[2], 3, // TD Address // Data Toggle // TD Address // Data Toggle // DelayInterrupt // Direction // Buffer Rounding // Current Buffer Pointer // Next TD // Buffer Length // TD Address // Data Toggle // DelayInterrupt // Direction // Buffer Rounding // Current Buffer Pointer // Next TD // Buffer Length TD_DELAY_INT, TD_OUT, 1, 0x0, (unsigned int) 0, 0x0);// DelayInterrupt // Direction // Buffer Rounding // Current Buffer Pointer // Next TD // Buffer Length//得到批量入端点的下一次发送数据区编号 toggle = usbGetEdToggle(bulkEd[1]); //初始化批量入端点 ED AT91F_CreateEd( (unsigned int) &bulkEd[1], 64 , 0, 0, 0, ED_IN, usbDevInfo.bulkInPort, usbDevInfo.addr, (unsigned int) &genTd[4], (unsigned int) &genTd[3], toggle, (unsigned int) 0); //用于接收 CSW 的 TD AT91F_CreateGenTd( (unsigned int) &genTd[3], 0, TD_DELAY_INT, TD_IN, 1, (unsigned int) pCsw, (unsigned int) &genTd[4], 13); AT91F_CreateGenTd( (unsigned int) &genTd[4], 3, TD_DELAY_INT, TD_IN, 1, 0x0, (unsigned int) 0, 0x0); // TD Address // Data Toggle // DelayInterrupt // Direction // Buffer Rounding // Current Buffer Pointer // Next TD // Buffer Length // TD Address // Data Toggle // DelayInterrupt // Direction // Buffer Rounding // Current Buffer Pointer // Next TD // Buffer Length // ED Address // Max packet // TD format // Skip // Speed // Direction // Endpoint // Func Address // TDQTailPointer // TDQHeadPointer // ToggleCarry // NextED //调用底层接口把数据发送出去 ohciBulkXfer(&bulkEd[0]); usbRunCmd(USB_CMD_TYPE_BULK_WRITE, 3); return 0; }基于 OHCI 的 USB 主机 ―― 中断寄存器初始化在 AM9200 中, 中断寄存器分为 2 个层次, 一个是用来设置某个功能允许哪些中断产生, 另一个是 AIC 中断寄存器,用来设置是否允许该功能产生中断。当 AIC 对应的中断产生时, 需要读取相应功能的中断状态寄存器,以判断产生中断的具体原因。对于 USB 接口, 首先需要设置 UHP_HcInterruptEnable 和 UHP_HcInterruptStatus 寄存 器(关于这两个寄存器的功能,请参见 OHCI 规范)。这两个寄存器属于 USB 功能寄存器, 确定允许哪些 USB 中断。代码如下://设置 USB Host 中断寄存器 pUhp-&UHP_HcInterruptEnable =OHCI_HC_INTR_MIE | OHCI_HC_INTR_RHSC | OHCI_HC_INTR_UE | OHCI_HC_INTR_WDH | OHCI_HC_INTR_FNO;pUhp-&UHP_HcInterruptStatus =OHCI_HC_INTR_RHSC | OHCI_HC_INTR_UE | OHCI_HC_INTR_WDH | OHCI_HC_INTR_FNO;//设置 AIC 中断信息 AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_UHP,//AT91C_ID_TC1, AT91C_AIC_PRIOR_HIGHEST, AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED, AT91F_ASM_UHP_Handler);AT91F_AIC_EnableIt(AT91C_BASE_AIC,AT91C_ID_UHP); 基于 OHCI 的 USB 主机 ―― 中断向量处理使用芯片提供的例程,中断向量处理程序也非常简单。在上面的 AIC 中断配置中,中断 产生不是直接调用用于处理中断事务的函数, 而是调用一个用汇编语言编写的函数, 该函数 主要功能是在中断处理函数调用前后,完成寄存器现场的保护和恢复。 这部分代码实际上与 OHCI 没有关系,是属于 CPU 的处理,不同的 CPU 其中断向量处理 是不一样的。所以这里的代码仅作参考而已。;-----------------------------------------------------------------------------;ATMEL Microcontroller Software Support - ROUSSET ;-----------------------------------------------------------------------------; The software is delivered &AS IS& without warranty
kind, either express, implied or statutory. Th limitation any warranty or condition with respect to fitness for any particular purpose, or against t intellectual property rights of others. ;----------------------------------------------------------------------------;- F- O- C;- 1.0 26/11/02 AREA FB : Creation ARM ADS itHandler, CODE, READONLY ;-----------------------------------------------------------------------------;-----------------------------------------------------------------------------;- LISR vector handler for-------------------------------------------;- This macro save the context, call the LISR dispatch routine,------------------------------------------------------------------------------INCLUDE AT91RM9200.inc : arm_isr.s : Example of IT handler calling a C function : None;-------------------------------;- ARM Core Mode and Status B-------------------------------- ARM_MODE_USER ARM_MODE_FIQ ARM_MODE_IRQ ARM_MODE_SVC ARM_MODE_ABORT ARM_MODE_UNDEF ARM_MODE_SYS I_BIT F_BIT T_BITEQU EQU EQU EQU EQU EQU EQU EQU EQU EQU0x10 0x11 0x12 0x13 0x17 0x1B 0x1F 0x80 0x40 0x20;-----------------------------------------------------------------------------;- IRQ E----------;-----------------------------------------------------------------------------MACRO IRQ_ENTRY $reg;- Adjust and save LR_irq in IRQ stack sub stmfd r14, r14, #4 sp!, {r14};- Write in the IVR to support Protect M- No effect in Normal M- De-assert the NIRQ and clear the source in Protect Mode ldr str r14, =AT91C_BASE_AIC r14, [r14, #AIC_IVR];- Save SPSR and r0 in IRQ stack mrs stmfd r14, SPSR sp!, {r0, r14};- Enable Interrupt and Switch in SYS Mode mrs bic orr msr r0, CPSR r0, r0, #I_BIT r0, r0, #ARM_MODE_SYS CPSR_c, r0;- Save scratch/used registers and LR in User Stack IF &$reg& = && stmfd ELSE sp!, { r1-r3, r12, r14} stmfd ENDIF MENDsp!, { r1-r3, $reg, r12, r14};-----------------------------------------------------------------------------;- IRQ E --------;-----------------------------------------------------------------------------MACRO IRQ_EXIT $reg;- Restore scratch/used registers and LR from User Stack IF &$reg& = && sp!, { r1-r3, r12, r14} sp!, { r1-r3, $reg, r12, r14} ldmia ELSE ldmia ENDIF ;- Disable Interrupt and switch back in IRQ mode mrs bic orr msr r0, CPSR r0, r0, #ARM_MODE_SYS r0, r0, #I_BIT:OR:ARM_MODE_IRQ CPSR_c, r0;- Mark the End of Interrupt on the AIC ldr str r0, =AT91C_BASE_AIC r0, [r0, #AIC_EOICR];- Restore SPSR_irq and r0 from IRQ- Restore adjusted ldmia MEND ;-----------------------------------------------------------------------------; AT91F_ASM_UHP_H --------------------; ; ; Save context Handler called by the AIC sp!, {r0, r14} SPSR_cxsf, r14 LR_irq from IRQ stack directly in the PC sp!, {pc}^ ; ;Call C handler Restore context EXPORT AT91F_ASM_UHP_Handler IMPORT AT91F_UHP_Handler;------------------------------------------------------------------------------AT91F_ASM_UHP_Handler IRQ_ENTRY ldr mov bx r1, =AT91F_UHP_Handler r14, pc r1IRQ_EXIT END基于 OHCI 的 USB 主机 ―― 中断处理程序在 OHCI 的体系下,判断数据是否传输完毕是需要通过中断程序来判断的,当 USB 主机 设置了 HcControl 和 HcCommandStatus 寄存器开始传输数据后, AM9200 自动开始数据传输, 并且定期的检查 HcDoneHead 寄存器的内容,并且将其转移到 HCCA.DoneHead。然后产生中 断,触发中断处理程序。在中断处理程序中, 需要检查 HcInterruptStatus 寄存器的内容, 判断 WDH 位是否为 1, 以便确定是否有 TD 被处理完毕。一般来说,其余的中断状态位不用理会。当发现有 TD 被处 理完毕,则还需要判断已经完成的 TD 是否是当前传输命令的最后一个 TD,如果是则标志命 令执行结束,上层程序可以进行后续处理。/** * OHCI 中断处理程序 */ void AT91F_UHP_Handler(void) {
// //得到 HcInterruptStatus 寄存器的内容 status = ohciGetIntrStatus(); //检查 WDH 位,判断是否有 TD 传输完毕 if ((status & OHCI_HC_INTR_WDH) != 0) { //根据当前执行的命令类型,确定 TD 的数量 switch(usbCmdState.cmdType) { case USB_CMD_TYPE_BULK_WRITE: case USB_CMD_TYPE_BULK_READ: idx = 3; case USB_CMD_TYPE_CTRL_READ: idx = 2; case USB_CMD_TYPE_CTRL_WRITE: idx = 1; default: usbCmdState.state = USB_CMD_OVER; ohciClearIntrStatus(); } //取得当前完成的 TD 的 Complete Code 值 cc = getTdCC(ohciGetHccaDoneHead()); //判断当前完成的 TD 是否是命令的最后一个 TD if (ohciGetHccaDoneHead() == usbGetLastTdAddr(idx)) { usbCmdState.cmdResult = usbCmdState.state = USB_CMD_OVER; } else { //当前 TD 不是最后一个 TD,但是执行失败,不会继续处理 TD 列表,因此需要 返回 if (cc) { usbCmdState.cmdResult = usbCmdState.state = USB_CMD_OVER; } else //当前 TD 不是最后一个 TD,等待继续处理 usbCmdState.state++; } } //清除 HcInterruptStatus 寄存器的内容,以便能够产生新的中断 ohciClearIntrStatus(); }基于 OHCI 的 USB 主机 ―― USB 设备命令介绍USB 协议能够在启动或是当设备插入系统时对设备进行备置,这就是 USB 设备为什么 可以执插拨的原因。 USB 设备被分成以下几类: 显示器 (Monitors) 、 通讯设备 (Communication devices)、音频设备(Audio)、人机输入(Human input)、海量存储(Mass storage)。特定类(class)的设备又可划分成子类(subclass),划分子类的后软件就可以搜索 总线并选择所有它可以支持的设备。每个设备可以有一个或多个配置(Configuration), 配置用于定义设备的功能。如果某个设备有几种不同的功能,则每个功能都需要一个配置。 配置(configuration)是接口(interface)的集合。接口指定设备中的哪些硬件与 USB 交 换数据。 每一个与 USB 交换数据的硬件就叫做一个端点(endpoint)。因此,接口是端点的集 合。 USB 的设备类别定义(USB Device Class Definitions)定义特定类或子类中的设备需 要提供的缺省配置、接口和端点。描述符(descriptor)描述设备、配置、接口或端点的一般信息,下图为 USB 描述符 的层次结构。USB(Host)唯一通过描述符了解设备的有关信息,根据这些信息,建立起通信,在这 些描述符中,规定了设备所使用的协议、端点情况等。因此,正确地提供描述符,是 USB 设备正常工作的先决条件。USB 海量存储设备(USB Mass Storage Class)包括 General Mass Storage Subclass、 CD-ROM、Tape、Solid State。Mass Storage Class 只需要支持一个接口,即数据(Data) 接口,选择缺省配置时此接口即被激活。数据接口允许与设备之间进行数据传输,它提供三 个端点:Bulk Input 端点、Bulk Output 端点和中断端点。 通用海量存储设备(General Mass Storage Device)是随机存取、基于块/扇区存储 的设备。它只能存储和取回来自 CPU 的数据。这种设备的接口遵循 SCSI-2 标准的直接存 取存储设备(Direct Access Storage Device)协议。USB 设置上的介质使用与 SCSI-2 设 备相同的逻辑块(logical blocks)方式寻址。基于 OHCI 的 USB 主机 ―― USB 标准请求USB 标准设备请求是用来完成 USB 设备枚举的命令。USB 设备必须对标准设备请求做出 响应, 不管该设备是否已经被分配了一个默认的地址或该设备目前正在配置。 所有的标准请 求都是使用默认端点(0)来传输的。USB 设备请求格式:偏移值 字段名 字段长度 字段取值 请求特性: D7:数据传输方向 0:主机到设备 1:设备到主机 设 备 0 请 求 类 型 1 位图 D6,D5:类型 0:标准 1:类型 2:厂商 3:保留 D4D3D2D1D0: 0:设备 1:接口 2:端点 3:其它 4?31:保留 1 设备请求 1 数值 USB 设备请求 说明 2 4 6值 索引 长度2 2 2值根据不同请求,以字节为单位来定义字段编号索引 根据不同请求,以字节为单位来定义 如果传输一组数据,指出要传输数据的字节 计数 数USB 标准设备请求:请求类型 B B B B B B Clear Feature(01H) 特殊选择符 GetStatus(00H) 0 设备请求 值(2B) 索 (2B) 设备 接口 端点 设备 接口 端点 0 无 2 引 长度 数据设备、接 口或端点 状态B B B Set Featrue(03H) 特殊选择符设备 接口 端点 0 无BSet Address(05H)设备地址00无BGet Descriptor(06H)描述符的类 型和索引 描述符的类 型和索引 0 配置值 0 可选配置 00或 语言 描 述 符长 ID 度描述符BSet Descriptor(07H)0或 语言 描 述 符长 ID 0 0 接口 接口 端点 度 1 0 1 0 2描述符B B B B BGet Configuratipon(08H) Set Configuratipon(09H) Get Interface(0AH) Set Interface(0BH) Synch Frame(0CH)配置值 无 可选的接口 无 帧标号描述符类型描述符类型 设备 数值 1 配置 字符串 接口 端点2 3 4 5特殊选择符特殊选择符名称 设备远程唤醒 禁止端点 接收方 设备 端点 数值 1 0 基于 OHCI 的 USB 主机 ―― 描述符说明设备描述符:偏移值 0 1 2 4 5 6 7 8 10 12 14 15 16 17 字段名称 blength bDescriptorType bcdUSB bDeviceClass bDeviceSubClass bDeviceProtocol bMaxPackedSize0 idVendor idProduct bcdDevice iManufacturer iProduct iSerialNumber bNumConfigurations 字段大小 1 1 2 1 1 1 1 2 2 2 1 1 1 1 描述符长度 = 12H 设备描述符类型 = 01H USB 规划发布号 类型代码(由 USB 指定) 子类型代码(由 USB 分配) 协议代码(由 USB 分配) }

我要回帖

更多关于 黄洋也不是什么好东西 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信