http://fangjian0518.blog.163.com/blog/static/5591965620116283232431/
关键理解USB主机检测到USB设备后,会对其发出复位请求。。
在复位之后,USB devcice固件完成端点等配置及初始化,特别是端点0.。而后才可以进入枚举阶段。
1.当主机用轮询的方式检测到USB端口有新的设备插入时,主机就会给HUB发送总线复位命令,要求HUB进行总线复位。 设备连接到主机并初始化完成(Softconnect 位被设置为 1),主机检测到D+与D-之间有电压差,就认为有新的设置接入。主机等待100ms后发出复位请求。设备接到复位请求后将产生一个外部中断信号。
2.主机使用默认地址0,来读取设备的描述符。
发送 Get_descriptor标准请求。主机向D12发送一个八字节请求:80 06 00 01 00 00 40 00 D12接收到请求后产生一个中断,我们可以通过读中断寄存器知道中断源,并且可以加读最后状态寄存器来确定第一个接到的包是否为一个Setup包。当控制器处理程序判断出它是一个Get_descriptor请求是,把设备描述符的前16个字节发送到端点0缓冲区中。剩下的2个字节描述符第一次请求时不再发送。
3.主机给设备分配一个地址
当主机收到正确的前16字节描述符后,会给设备分配一个地址,我的PC分配的地址为:0x03(这个要看你的机子当时的USB接口设备数目而定) Set_Address 请求所发送的数据为:00 05 03 00 00 00 00 00 ,其中的03就表示主机为设备分配的地址为0x03,在以后的通信里设备就只对0x03地址作出应答。当D12产生一个接收中断后,跟据所分配的地址设置D12的地址寄存器相应位
4.主机以地址0x03 ,重新请求设备描述符
主机发送设备描述符标准请求Get_descriptor :80 06 00 01 00 00 12 00 此次将要求把18个字节全部发送完。所以主机要分两次来读取。第一次发送16个字节,第三次发送两个字节,最后主机发送0表示发送完毕的应答。
5.主机发送Get_configuration请求
由于事先没有知道描述符的长度,所以先以0xff的长度进行请求。其数据为:80 06 00 02 00 00 FF 00 我用的是周立功公司卖的D12开发板光盘资料中提供的驱动程序,发送的应答是一个描述集合其结构如下:
typedef struct USB_DESCRIPTOR {
USB_CONFIGURATION_DESCRIPTOR ConfigDescr; //配置描述符
USB_INTERFACE_DESCRIPTOR InterfaceDescr; //接口描述符
USB_ENDPOINT_DESCRIPTOR EP1_TXDescr; //端点1输入描述符
USB_ENDPOINT_DESCRIPTOR EP1_RXDescr; //端点1输出描述符
USB_ENDPOINT_DESCRIPTOR EP2_TXDescr; //端点2输入描述符
USB_ENDPOINT_DESCRIPTOR EP2_RXDescr; //端点2输出描述符
} USB_DESCRIPTOR, *PUSB_DESCRIPTOR;
6.Set_Conficuration
当读取完成描述符之后,需要对设备进行配置,使得设备从地址状态进入配置状态。这个在写固件的时候可以提高运行效率。
7.读取配置状态。
8.当主机能正确地收到这些数据之后,就可以加载D12的驱动程序。这时就可能作应用中的数据传输了。
使用USB View 采集到的数据:
Device Descriptor:
bcdUSB: 0x0100
bDeviceClass: 0xDC
bDeviceSubClass: 0x00
bDeviceProtocol: 0x00
bMaxPacketSize0: 0x10 (16)
idVendor: 0x0471
idProduct: 0x0666
bcdDevice: 0x0100
iManufacturer: 0x00
iProduct: 0x00
iSerialNumber: 0x00
bNumConfigurations: 0x01
ConnectionStatus: DeviceConnected
Current Config Value: 0x01
Device Bus Speed: Full
Device Address: 0x02
Open Pipes: 4
Endpoint Descriptor:
bEndpointAddress: 0x81
Transfer Type: Interrupt
wMaxPacketSize: 0x0010 (16)
bInterval: 0x0A
Endpoint Descriptor:
bEndpointAddress: 0x01
Transfer Type: Interrupt
wMaxPacketSize: 0x0010 (16)
bInterval: 0x0A
Endpoint Descriptor:
bEndpointAddress: 0x82
Transfer Type: Bulk
wMaxPacketSize: 0x0040 (64)
bInterval: 0x0A
Endpoint Descriptor:
bEndpointAddress: 0x02
Transfer Type: Bulk
wMaxPacketSize: 0x0040 (64)
bInterval: 0x0A