打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
USB概述及S3C2440 USB DEVICE

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实验教程)。


 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
S3C2440 USB 设备控制器
USB设备枚举全纪录
USB固件开发总结(二)
系统设计精选 | 基于FPGA的USB接口控制器设计(附代码)
STM32处理器的USB接口
USB描述符
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服