usb总线枚举过程:
1.对从设备供电并延时待稳定.
2.主usb通过检测设备在总线上的上拉电阻检测到新的设备连接并获释是全速设备还是低速设备,然后主机向该端口发出一复位信号.
(从设备收到复位信号后才对总线操作有反应,从设备使用默认地址00h来相应主机的命令)
3.延时25毫秒后,主机从地址00h请求设备描述符,待从设备响应后,对设备分配一个空闲的地址,以后该设备只对该地址进行响应.
确认usb设备的属性
4.主机再次从新地址读取USB设备的设备描述符,获释端点0的最大数据包大小(可在上步做),保存厂商,产品 id号
5.主机从新地址读取USB设备的配置描述符(从设备响应的数据依次是配置描述符,接口描述符,端点描述符),并从接口描述符中获释设备的
类型
是海量存储器还是一般器件.(a.字符串描述符可不处理,b.海量存储器还要再次对文件系统进行枚举)
从配置描述符中可知设备的供电方式和最大功耗;从接口描述符中可知设备除端点0的端点个数以及设备类型;
从端点描述符中可知端点类型(地址,in,out),传输方式,最大包的大小和中断传输时传输时间间隔.
6.主机按照usb的描述符进行配置,如果主机能够满足设备所需资源,就发送配置命令给USB设备,表示配置完毕.
完成以上步骤,USB设备枚举完成.USB设备就可以工作了.
控制传输:主要用于枚举时,端点0 作为主机和设备的命令和状态通道;
中断传输:主要用于数据量小,偶尔传输,服务时间受限制的设备,主机按端点的轮询时间间隔定时读取\发送数据.如键盘\鼠标等.
批量传输:主要用于传输大量数据,而没有周期和传输速率要求的设备上,他并不能保证传送速率,但可保证传输的可靠性,当出现
错误时会要求发送方重发.如海量存储器等.
同步传输:要求以恒定的速率传输,设备和主机都必须保证传输速率匹配,否则就会丢失数据,一般不用.
标准的设备,配置,接口,端点,字符串描述符的结构体如下:(祥见周立功D12USB接口开发资料)
// Standard Device Descriptor
typedef struct
{ BYTE bLength;
BYTE bDescriptorType;
WORD bcdUSB;
BYTE bDeviceClass;
BYTE bDeviceSubClass;
BYTE bDeviceProtocol;
BYTE bMaxPacketSize0;
WORD idVendor;
WORD idProduct;
WORD bcdDevice;
BYTE iManufacturer;
BYTE iProduct;
BYTE iSerialNumber;
BYTE bNumConfigurations;
} sDevDesc, *pDevDesc;
// Standard Configuration Descriptor
typedef struct
{
BYTE bLength; // Size of descriptor in Byte
BYTE bType; // Configuration
WORD wLength; // Total length “配置描述符、接口描述符和端点描述符的总长度”
BYTE bNumIntf; // Number of interface
BYTE bCV; // bConfigurationValue
BYTE bIndex; // iConfiguration
BYTE bAttr; // Configuration Characteristic
BYTE bMaxPower; // Power config
} sCfgDesc, *pCfgDesc;
// Standard Interface Descriptor
typedef struct
{ BYTE bLength;
BYTE bType;
BYTE iNum;
BYTE iAltString;
BYTE bEndPoints;
BYTE iClass;
BYTE iSub;
BYTE iProto;
BYTE iIndex;
} sIntfDesc, *pIntfDesc;
// Standard EndPoint Descriptor
typedef struct
{ BYTE bLength;
BYTE bType;
BYTE bEPAdd;
BYTE bAttr;
WORD wPayLoad; // low-speed this must be 0x08
BYTE bInterval;
} sEPDesc, *pEPDesc;
// Standard String Descriptor
typedef struct
{ BYTE bLength;
BYTE bType;
WORD wLang;
} sStrDesc, *pStrDesc;
//设备描述符
code USB_DEVICE_DESCRIPTOR DeviceDescr =
{
sizeof(USB_DEVICE_DESCRIPTOR),
USB_DEVICE_DESCRIPTOR_TYPE,
SWAP(0x0110),
USB_CLASS_CODE_TEST_CLASS_DEVICE,
0, 0,
EP0_PACKET_SIZE,
SWAP(0x0471),
SWAP(0x0666),
SWAP(0x0100),
0, 0, 0,
1
};
//配置描述符
code USB_CONFIGURATION_DESCRIPTOR ConfigDescr =
{
sizeof(USB_CONFIGURATION_DESCRIPTOR),
USB_CONFIGURATION_DESCRIPTOR_TYPE,
SWAP(CONFIG_DESCRIPTOR_LENGTH),
1,
1,
0,
0xa0,
0x1
};
//接口描述符
code USB_INTERFACE_DESCRIPTOR InterfaceDescr =
{
sizeof(USB_INTERFACE_DESCRIPTOR),
USB_INTERFACE_DESCRIPTOR_TYPE,
0,
0,
NUM_ENDPOINTS,
USB_CLASS_CODE_TEST_CLASS_DEVICE,
USB_SUBCLASS_CODE_TEST_CLASS_D12,
USB_PROTOCOL_CODE_TEST_CLASS_D12,
0
};
//端点描述符
code USB_ENDPOINT_DESCRIPTOR EP1_TXDescr =
{
sizeof(USB_ENDPOINT_DESCRIPTOR),
USB_ENDPOINT_DESCRIPTOR_TYPE,
0x81,
USB_ENDPOINT_TYPE_INTERRUPT,
SWAP(EP1_PACKET_SIZE),
10
};
code USB_ENDPOINT_DESCRIPTOR EP1_RXDescr =
{
sizeof(USB_ENDPOINT_DESCRIPTOR),
USB_ENDPOINT_DESCRIPTOR_TYPE,
0x1,
USB_ENDPOINT_TYPE_INTERRUPT,
SWAP(EP1_PACKET_SIZE),
10
};
code USB_ENDPOINT_DESCRIPTOR EP2_TXDescr =
{
sizeof(USB_ENDPOINT_DESCRIPTOR),
USB_ENDPOINT_DESCRIPTOR_TYPE,
0x82,
USB_ENDPOINT_TYPE_BULK,
SWAP(EP2_PACKET_SIZE),
10
};
code USB_ENDPOINT_DESCRIPTOR EP2_RXDescr =
{
sizeof(USB_ENDPOINT_DESCRIPTOR),
USB_ENDPOINT_DESCRIPTOR_TYPE,
0x2,
USB_ENDPOINT_TYPE_BULK,
SWAP(EP2_PACKET_SIZE),
10
};
/*-------------------------------------------------------------------------
* Standard Chapter 9 definition
*-------------------------------------------------------------------------
*/
#define GET_STATUS 0x00
#define CLEAR_FEATURE 0x01
#define SET_FEATURE 0x03
#define SET_ADDRESS 0x05
#define GET_DESCRIPTOR 0x06
#define SET_DESCRIPTOR 0x07
#define GET_CONFIG 0x08
#define SET_CONFIG 0x09
#define GET_INTERFACE 0x0a
#define SET_INTERFACE 0x0b
#define SYNCH_FRAME 0x0c
#define DEVICE 0x01
#define CONFIGURATION 0x02
#define STRING 0x03
#define INTERFACE 0x04
#define ENDPOINT 0x05
#define STDCLASS 0x00
//#define HIDCLASS 0x03
//#define HUBCLASS 0x09 // bDeviceClass, bInterfaceClass |