USB概述及S3C2440 USB DEVICE
USB概述 USB主要用于中速和低速的外设。USB通过PCI总线和PC机的内部系统数据线连接,实现数据的传送。USB的网络协议中规定每个USB的系统有且仅有一个HOST。 USB2.0协议的理论速度是480Mb/s ,现在的USB3.0协议理论速度能达到4Gb/s。 主要特点: 支持即插即用,传输速度快,连接方便,独立供电,低成本;USB 使用一个4针插头作为标准插头,通过这个标准插头,采用菊花链形式可以把多达127个的 USB 外设连接起来,所有的外设通过协议来共享 USB 的带宽。 组成: USB 规范中将 USB 分为五个部分:控制器、控制器驱动程序、USB芯片驱动程序、USB 设备以及针对不同USB 设备的客户驱动程序。 控制器(Host Controller),主要负责执行由控制器驱动程序发出的命令,如位于 PC 主板的USB 控制芯片。 控制器驱动程序(Host Controller Driver),在控制器与USB 设备之间建立通信信道,一般由操作系统或控制器厂商提供。 USB芯片驱动程序(USB Driver),提供对USB芯片的支持,设备上的固件。 USB设备(USB Device),包括与 PC 相连的USB 外围设备。 设备驱动程序(Client Driver Software),驱动USB 设备的程序,一般由USB 设备制造商提供。 传输方式: 每次传输会分解成若干个数据包在USB总线上传输。每次传输必须经历两个或三个部分,第一部分是USB控制器向USB设备发出命令,第二部分是USB控制器和USB设备之间传递读写请求,其方向主要看第一部分的命令式读还是写,第二部分有时可以没有。第三部分是握手信号。 1.控制传输方式:负责向USB设置一些控制信息,传送这种事务的管道是控制管道。在每个USB设备中都会有控制管道,也就是说控制管道在USB设备中是必须的。控制传输也分为三个阶段,令牌阶段、数据传送阶段、握手阶段。 2.同步传输方式:该方式用来联接需要连续传输数据,且对数据的正确性要求不高而对时间极为敏感的外部设备,如麦克风、嗽叭以及电话等。同步传输方式以固定的传输速率,连续不断地在主机与 USB 设备之间传输数据,在传送数据发生错误时,USB 并不处理这些错误,而是继续传送新的数据。同步传输方式的发送方和接收方都必须保证传输速率的匹配,不然会造成数据的丢失。 同步传输事务只有两个阶段,令牌阶段、数据阶段,因为不关心数据的正确性,故没有握手阶段。 3.中断传输 (Interrupt):该方式用来传送数据量较小, 但需要及时处理, 以达到实时效果的设备, 此方式主要用在偶然需要少量数据通信,但服务时间受限制的键盘、鼠标以及操纵杆等设备上。 也分上述三个阶段。 4.批量传输方式:主要是大块的数据,传输这种事务的管道叫做Bulk管道。这种事务传输的时候分为三个部分:第一部分是HOST端发出一个BULK的令牌请求,如果令牌是IN请求则是从Device到Host端的请求,如果是OUT令牌,则是从HOST到DEVICE端的请求。第二部分是传输数据的阶段,根据先前请求的令牌的类型,数据传输有可能是IN方向和OUT方向。传输数据的时候用DATA0和DATA1令牌携带着数据交替传送。第三部分是握手信号。如果是IN方向,数据信号应该是HOST端发出,如果是OUT方向,握手信号应该是DEVICE端发出。握手信号可以是ACK,表示正常响应,也可以是NAK表示没有正确传送。STALL表示出现主机出现不可预知的错误。在第二部分,数据传送由DATA0和DATA1数据包交替传送。数据传输格式DATA1和DATA0,两个是重复数据,确保在1数据丢失时0可以补上,不止数据丢失。 USB描述符: USB设备通过描述符来反映他们的属性。描述符是有定义好的格式的数据结构,每个描述符以一个字节打头表明本描述符的长度,紧跟其后是一个字节的描述符类信息。 一个USB设备有一个设备描述符,设备描述符里面决定了该设备有多少种配置,每种配置描述符对应着配置描述符;而在配置描述符中又定义了该配置里面有多少个接口,每个接口有对应的接口描述符;在接口描述符里面又定义了该接口有多少个端点,每个端点对应一个端点描述符;端点描述符定义了端点的大小,类型等等。由此我们可以看出,USB的描述符之间的关系是一层一层的,最上一层是设备描述符,下面是配置描述符,再下面是接口描述符,再下面是端点描述符。在获取描述符时,先获取设备描述符,然后再获取配置描述符,根据配置描述符中的配置集合长度,一次将配置描述符、接口描述符、端点描述符一起一次读回。其中可能还会有获取设备序列号,厂商字符串,产品字符串等。 以下详细介绍USB描述符: //设备描述符 struct USB_Dev_descriptor { U8 blength; //设备描述符的字节数大小 U8 bDescriptorType; //设备描述符类型编号 U16 bcdUSB; //USB版本号 U8 bDeviceClass; //USB分配的设备类代码 U8 bDeviceSubClass; //USB分配的子类代码 U8 bDeviceProtocol; //USB分配的设备协议代码 U8 bMaxPacketSize0; //端点0的最大包大小 U16 idVendor; //厂商编号 U16 idProduct; //产品编号 U16 bcdDevice; //设备出厂编号 U8 iManufacturer; //设备厂商字符串的索引 U8 iProduct; //描述产品字符串的索引 U8 iSerialNumber; //描述设备序列号字符串的索引 U8 bNumConfigurations; //可能的配置数量 }descDev; //配置描述符 struct USB_Con_descriptor { U8 bLength; //配置描述符的字节数大小 U8 bDescriptorType; //配置描述符类型编号 U8 wTotalLength; //此配置返回的所有数据大小 U8 bNumInterfaces; //此配置所支持的接口数量 U8 bConfigurationValue; //Set_Configuration命令所需要的参数值 U8 iConfiguration; //描述该配置的字符串的索引值 U8 bmAttributes; //供电模式的选择 U8 MaxPower; //设备从总线提取的最大电流 }descCon; //接口描述符 struct USB_Inf_descriptor { U8 bLength; //接口描述符的字节数大小 U8 bDescriptorType; //接口描述符的类型编号 U8 bInterfaceNumber; //该接口的编号 U8 bAlternateSetting; //备用的接口描述符编号 U8 bNumEndpoints; //该接口使用的端点数,不包括端点0 U8 bInterfaceClass; //接口类型 U8 bInterfaceSubClass; //接口子类型 U8 bInterfaceProtocol; //接口遵循的协议 U8 iInterface; //描述该接口的字符串索引值 }descInf; //端口描述符 struct USB_Epn_descriptor { U8 bLength; //端点描述符字节数大小 U8 bDescriptorType; //端点描述符类型编号 U8 bEndpointAddress; //端点地址及输入输出属性 U8 bmAttributes; //端点的传输类型属性 U16 wMaxPacketSize; //端点收、发的最大包大小 U8 bInterval; //主机查询端点的时间间隔 }descEp0,descEp1; 描述符配置实例: void USB_descriptor() { //设备描述符 descDev.blength=0x12; //设备描述符的字节数大小,这里是18字节 descDev.bDescriptorType=1; //设备描述符类型编号,设备描述符是01 descDev.bcdUSB=0x0110; //USB版本号,这里是USB01.10,即USB1.1。 descDev.bDeviceClass=0xFF; descDev.bDeviceSubClass=0; descDev.bDeviceProtocol=0; descDev.bMaxPacketSize0=8; //端点0的最大包大小,这里为8字节 descDev.idVendor=0x5345; descDev.idProduct=0x1234; descDev.bcdDevice=0x100; descDev.iManufacturer=1; descDev.iProduct=2; descDev.iSerialNumber=0; descDev.bNumConfigurations=1; //配置描述符 descCon.bLength=9; //配置描述符的字节数大小 descCon.bDescriptorType=2; //配置描述符类型编号 descCon.wTotalLength=0x20; //配置描述符集合的总大小 descCon.bNumInterfaces=1; //只包含一个接口 descCon.bConfigurationValue=1; //该配置的编号 descCon.iConfiguration=0; //iConfiguration字段 descCon.bmAttributes=0x80; //采用总线供电,不支持远程唤醒 descCon.MaxPower=25; //从总线获取最大电流50mA //接口描述符 descInf.bLength=9; //接口描述符的字节数大小,这里为9 descInf.bDescriptorType=4; //接口数4 descInf.bInterfaceNumber=0; //接口编号为4 descInf.bAlternateSetting=0; //该接口描述符的编号为0 descInf.bNumEndpoints=2; //非0端点数量为2,只使用端点主端点输入和输出 descInf.bInterfaceClass=0xff; descInf.bInterfaceSubClass=0; descInf.bInterfaceProtocol=0; descInf.iInterface=0; //接口描述符字符串索引,为0,表示没有字符串 //端口描述符 descEp0.bLength=7; //端点描述符的字节数大小,这里为7 descEp0.bDescriptorType=5; //端点描述符类型编号,端点描述符为5 descEp0.bEndpointAddress=0x81; //端点号,主输入端点 descEp0.bmAttributes=2; //使用的传输类型,批量传输 descEp0.wMaxPacketSize=32; //该端点支持的最大包尺寸,64字节 descEp0.bInterval=0; //中断扫描时间,对批量传输无效 descEp1.bLength=7; descEp1.bDescriptorType=5; descEp1.bEndpointAddress=3; descEp1.bmAttributes=2; descEp1.wMaxPacketSize=32; descEp1.bInterval=0; } USB设备枚举过程: 1. 主机检测到设备插上,总线复位:当设备与主机连接时,主机将检测到连接条件。当USB线的D+数据线拉至Vse以上2.5us时,主机就开始进行总线复位。 2. 主机读取设备描述符(第一次):主机连接时使用默认地址(0)读取设备描述符。S3C2440的端点0的缓冲区是16个字节,程序中设置为8个字节,故S3C2440作为设备先发送8个字节的设备描述符。当主机接收到这8个字节后,就认为有设备连接,即发送一个0字节的数据包到设备作为应答。 3. 分配地址:主机给设备分配一个地址。默认分配地址为0x02,在以后通信中,设备只对0x02地址的信息应答。 4. 主机从新地址获取设备描述符:程序中接收数据包设置成8字节,18字节的设备描述符要分3次发送。最后主机发送一个0字节的数据包到设备作为应答。 5. 主机获取配置描述符。 6. 主机读取描述符集合:主机除了读取设备描述符和配置描述符之外,还读取接口描述符。在这里主机使用再次读取配置的方法来读取配置描述符、接口描述符和端点描述符的集合。这里请求的字节数为0xFF。 7. 设置配置:主机读取完描述符后,需要对设备进行配置,使设备从地址状态进入配置状态。 8. 读取配置状态(可选):主机设置完配置后,设备即可使用。主机有时会对设备的状态进行读取。 9. 读取接口状态(可选)。 S3C2440 USB DEVICE S3C2440 USB DEVICE简介: USB设备控制器采用DMA接口方案,提供全速高性能的控制器,允许控制传输、中断传输和DMA接口的批量传输。它兼容USB1.1,具有5个带FIFO的端点:端点0(EP0,16字节,双向控制端点)、端点1,2,3,4(128字节,中断或DMA,批量端点)。 USB初始化: 1. UCLK初始化:USB主机和USB设备接口都需要48MHz的时钟。在S3C2440中,这个时钟是由UPLL(USB专用)提供,所以操作前要对UPLLCON寄存器进行设置。由于CLKDIVN(DIVN_UPLL)和CLKSLOW(UCLK_ON)两个寄存器中有关UCLK的位的初始值均为0,故只要设置UPLLCON=0x38022。 2. 初始化描述符,见描述符配置实例。 3. 重新配置USB设备:主要配置各端点的最大包字节数,传输模式,IN/OUT(数据方向)和使能需要的中断。 需要设置的寄存器有:电源管理寄存器PWR_REG、索引寄存器INDEX_REG(对各端点进行设置前要使索引寄存器指向该端点,如设置端点0,INDEX_REG=0。)、最大包寄存器MAXP_REG、端点0控制状态寄存器EP0_CSR、端点输入控制状态寄存器IN_CSR1_REG、端点输入控制状态寄存器2(IN_CSR2_REG)、端点输出控制状态寄存器OUT_CSR1_REG、端点输出控制状态寄存器2(OUT_CSR2_REG)、端点中断寄存器EP_INT_REG、USB中断寄存器USB_INT_REG、端点中断使能寄存器EP_INT_EN_REG、USB中断使能寄存器USB_INT_EN_REG。 各寄存器的具体设置请参考有关手册(可参考GEC2440实战手册或芯片手册)。 实例: void USB_reset() { rPWR_REG=0; //禁止睡眠模式 rINDEX_REG=0; //对EP0有关的寄存器进行操作 rMAXP_REG=1; //EP0最大包8字节 rEP0_CSR=0xC0; rINDEX_REG=1; //对EP1有关的寄存器进行操作 rMAXP_REG=4; //EP1最大包32字节 rIN_CSR1_REG=(1<<6)|(1<<3); //冲掉FIFO中的数据,数据包中的PID保持DATA0 rIN_CSR2_REG=(1<<5)|(1<<4)|(0<<6); //IN模式,禁止DMA中断,批量传输模式 rOUT_CSR1_REG=0x80; //数据切换序列位复位到DATA0 rOUT_CSR2_REG=(0<<6)|(1<<5); //端点配置成批量传输模式,禁止中断 rINDEX_REG=2; rMAXP_REG=8; //EP2最大包64字节 rIN_CSR1_REG=(1<<6)|(1<<3); rIN_CSR2_REG=(1<<5)|(1<<4); rOUT_CSR1_REG=0x80; rOUT_CSR2_REG=(0<<6)|(1<<5); rINDEX_REG=3; rMAXP_REG=4; //EP3最大包32字节 rIN_CSR1_REG=(1<<6)|(1<<3); //冲掉FIFO中的数据,数据包中的PID保持DATA0 rIN_CSR2_REG=(0<<5)|(1<<4); //OUT模式,禁止DMA中断 rOUT_CSR1_REG=0x80; rOUT_CSR2_REG=(0<<6)|(1<<5); //端点配置成BULK模式,禁止中断 rINDEX_REG=4; rMAXP_REG=8; //EP4最大包64字节 rIN_CSR1_REG=(1<<6)|(1<<3); rIN_CSR2_REG=(0<<5)|(1<<4); //OUT模式,禁止DMA中断 rOUT_CSR1_REG=0x80; rOUT_CSR2_REG=(0<<6)|(1<<5); //端点配置成批量传输模式,禁止中断 rEP_INT_REG=(1<<3)|(1<<2)|(1<<1)|(1<<0); //清除所有端点的中断 rUSB_INT_REG=(1<<2)|(1<<1)|(1<<0); //清零USB中断寄存器rEP_INT_EN_REG=(1<<3)|(1<<1)|(1<<0)/*0xD*/;//使能EP0,EP1,EP3中断 rUSB_INT_EN_REG=4; //使能复位中断
} 4. 中断初始化:中断时指向中断服务程序。 数据传输: 一般采用中断传输模式,故进入中断后先判断中断类型,再具体执行中断类型的服务程序。如下程序: void __irq USB_INT() { U8 usb_Int, Ep_Int; U8 Index=rINDEX_REG; //保存索引寄存器值(现场保护) usb_Int=rUSB_INT_REG; //保存中断标志寄存器 Ep_Int=rEP_INT_REG; if(usb_Int&1) //总线上超过3ms没有活动信号引起中断 { rUSB_INT_REG=1; //清除中断标志位 } if(usb_Int&2) rUSB_INT_REG=2; //恢复引起的中断 if(usb_Int&4) //接收到复位信号引起的中断 { USB_reset(); //重新配置USB设备 rUSB_INT_REG=4; //复位USB后清除复位中断 PrepareEp1Fifo(); //准备发送数据 } if(Ep_Int&1) //端点0中断 { rEP_INT_REG=1; Ep0Handler(); //进入控制传输中断处理程序 } if(Ep_Int&2) { rEP_INT_REG=2; Ep1Handler(); //进入Ep1中断处理程序(BULK IN) } if(Ep_Int&4) rEP_INT_REG=4; if(Ep_Int&8) { rEP_INT_REG=8; Ep3Handler(); //进入Ep3中断处理程序(BULK OUT) } if(Ep_Int&0x10) rEP_INT_REG=0x10; ClearPending(BIT_USBD); //USB设备中断处理完毕,清除中断标志位 rINDEX_REG=Index; //恢复索引寄存器原来的值(恢复现场) } 其中控制传输中断服务程序(Ep0Handler())处理主机向USB设备发出命令的中断。在此程序中,要分别对接收命令过程中出现的有效命令(即令牌包)写入(包括对命令内容的处理)、命令写入出错引起的停止、命令传输结束进行处理。Ep1/3中断处理程序处理数据的发送和接收,在数据发送和接收结束之后清除标志位。具体程序见实战手册(可参考GEC2440实战手册或2410_MDK实验教程)。 |
|