<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
四、USB应用层主要函数分析
1、用户协议的主要描述:usb_desc.c
为了使枚举过程更清晰,对于控制传输阶段描述符的使用更形象,我在核心处理函数中加入一些调试语句,向串口输出数据,得到“JoyStickMouse”的枚举过程完整数据。这样对于学习标准请求和控制传输很直观。
调试函数以下列形式出现,如果不需要后,定义usb_debug为0就行了。
#if usb_debug
Uart_PutString("setup中断\r\n" );
Uart_PutHex ( pInformation->USBbmRequestType );
Uart_PutHex ( pInformation->USBbRequest );
Uart_PutHex ( pInformation->USBwValue0 );
Uart_PutHex ( pInformation->USBwValue1 );
Uart_PutHex ( pInformation->USBwIndex0 );
Uart_PutHex ( pInformation->USBwIndex1 );
Uart_PutHex ( pInformation->USBwLength1 );
Uart_PutHex ( pInformation->USBwLength0 );
Uart_PutString("\r\n" );
#endif
进入USB鼠标实现过程!
总线复位中断
总线复位中断
setup中断 //80表示数据输入、主机请求发往设备。06是获取描述符
80 06 00 01 00 00 40 00 // 00 01Value高字节01表示设备,请求0x40字节。
获取设备描述符
设备准备发送12 字节12 01 00 02 00 00 00 40 83 04 10 57 00 02 01 02 03 01 // 40表示端点支持的包长64字节
IN令牌04 中断 //04表示这是“LAST_IN_DATA”,一次性传输完。02表示需要分成多次传输。
OUT状态中断
总线复位中断
setup中断 // 00 表示 主机标准请求到设备,数据输出。
00 05 02 00 00 00 00 00
设置地址 //地址00 02
IN状态中断
setup中断
80 06 00 01 00 00 12 00
获取设备描述符 // 以新地址02 获取描述符。
设备准备发送12 字节12 01 00 02 00 00 00 40 83 04 10 57 00 02 01 02 03 01 // 00 00 00 代表设备类、设备子类、协议。
IN令牌04 中断
OUT状态中断
setup中断
80 06 00 02 00 00 09 00
获取配置描述符 // 00 22 表示配置集合有34个字节。
设备准备发送09 字节09 02 22 00 01 01 00 E0 32
IN令牌04 中断 //一个接口、配置号为1。E0表示自供电、支持远程唤醒。32表示50个电流单位,100mA。
OUT状态中断
setup中断
80 06 00 03 00 00 FF 00
获取字符串描述符 // 03 表示获取字符串描述符,00表示获取语言ID。
设备准备发送04 字节04 03 09 04
IN令牌04 中断 // 04 09 表示英语。
OUT状态中断
setup中断
80 06 03 03 09 04 FF 00
获取字符串描述符 //以用户提供的语言ID获取 设备序列号字符串(03)。
设备准备发送<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />1A 字节1A 03 53 00 54 00 4D 00 33 00 32 00 31 00 30 00 00 00 00 00 00 00 00 00 00 00
IN令牌04 中断
OUT状态中断
setup中断
80 06 00 02 00 00 FF 00
获取配置集合:包括蓝色的接口描述符、红色HID类描述符、蓝色端点描述符。//01 03 01 02 后面3个字节表示接口类、接口子类、接口协议。
设备准备发送22 字节09 02 22 00 01 01 00 E0 32 09 04 00 00 01 03 01 02 00 09 21 00 01 00 01 22 4A 00 07 05 81 03 04 00 20
IN令牌04 中断 // 22表示报告描述符类型。4A表示76个字节。
OUT状态中断 // 81 03 表示使用1号端点输入、中断类型,20 表示轮询时间要求32ms。
setup中断
80 06 00 06 00 00 0A 00
setup中断
80 06 00 03 00 00 FF 00
获取字符串描述符
设备准备发送04 字节04 03 09 04
IN令牌04 中断
OUT状态中断
setup中断
80 06 02 03 09 04 FF 00
获取字符串描述符 //又获取字符串描述符,这次是产品名称字符串。
设备准备发送1E 字节1E 03 53 00 54 00 4D 00 33 00 32 00 20 00 4A 00 6F 00 79 00 73 00 74 00 69 00 63 00 6B 00
IN令牌04 中断
OUT状态中断
setup中断
80 06 00 03 00 00 FF 00
获取字符串描述符
设备准备发送04 字节04 03 09 04
IN令牌04 中断
OUT状态中断
setup中断
80 06 02 03 09 04 FF 00
获取字符串描述符 //重复获取,为什么这么做呢?
设备准备发送1E 字节1E 03 53 00 54 00 4D 00 33 00 32 00 20 00 4A 00 6F 00 79 00 73 00 74 00 69 00 63 00 6B 00
IN令牌04 中断
OUT状态中断
setup中断
80 06 00 01 00 00 12 00
获取设备描述符 //又获取设备描述符,新地址下第二次。
设备准备发送12 字节12 01 00 02 00 00 00 40 83 04 10 57 00 02 01 02 03 01
IN令牌04 中断
OUT状态中断
setup中断
80 06 00 02 00 00 09 00
获取配置描述符 //又获取配置描述符,新地址下第二次。
设备准备发送09 字节09 02 22 00 01 01 00 E0 32
IN令牌04 中断
OUT状态中断
setup中断
80 06 00 02 00 00 22 00
获取配置描述符集合。 //又获取配置描述集合,新地址下第二次
设备准备发送22 字节09 02 22 00 01 01 00 E0 32 09 04 00 00 01 03 01 02 00 09 21 00 01 00 01 22 4A 00 07 05 81 03 04 00 20
IN令牌04 中断
OUT状态中断
setup中断
00 09 01 00 00 00 00 00
设置配置 //设置配置,用户的配置就有效了。
IN状态中断
setup中断 // 21表示类请求,发送到接口。
21 0A 00 00 00 00 00 00 //0A 表示 Set_Idle请求,设备无反应,故主机忽略。
setup中断
81 06 00 22 00 00 8A 00 //这里大小应该是 00 4A吧?
获取报告描述符
设备准备发送40 字节05 01 09 02 A1 01 09 01 A1 00 05 09 19 01 29 03 15 00 25 01 95 03 75 01 81 02 95 01 75 05 81 03 05 01 09 30 09 31 09 38 15 81 25 7F 75 08 95 03 81 06 C0 09 3C 05 FF 09 01 15 00 25 01 75 01 95
IN令牌02 中断 //02表示后面还有数据传输。
设备准备发送0A 字节02 B1 22 75 06 95 01 B1 01 C0
IN令牌04 中断
OUT状态中断
2、用户协议的主要实现:usb_prop.c
主要是实现两个函数指针结构体。
DEVICE_PROP Device_Property =
{
Joystick_init, //用户初始化,清除复位、开启中断、连接电缆。
Joystick_Reset, // 使能端口0
Joystick_Status_In,
Joystick_Status_Out, // 两个空函数。
Joystick_Data_Setup, // 实现报告描述符请求、HID类描述符请求、协议获取请求
Joystick_NoData_Setup, // 实现设置协议请求。
Joystick_Get_Interface_Setting, // 有实现,但意义不太明白。
Joystick_GetDeviceDescriptor,
Joystick_GetConfigDescriptor,
Joystick_GetStringDescriptor, //以上三个是上层协议为底层描述符请求提供具体数据。
0,
0x40 /*MAX PACKET SIZE*/ // 端点支持的包长。
};
USER_STANDARD_REQUESTS User_Standard_Requests =
{
Joystick_GetConfiguration,
Joystick_SetConfiguration, //这个函数调用后,设备为可用状态。
Joystick_GetInterface,
Joystick_SetInterface,
Joystick_GetStatus,
Joystick_ClearFeature,
Joystick_SetEndPointFeature,
Joystick_SetDeviceFeature,
Joystick_SetDeviceAddress // 这个函数调用后,设备状态为地址状态。
}; // 其它函数都是空函数。是在控制传输过程中用户提供的回调函数。
鼠标的上层协议函数比较简单,这里就不一一分析了。
文章评论(0条评论)
登录后参与讨论