前端时间调试MSP430F5519的USB发现一个问题,就是第一次插入设备枚举时,总是在获取完配置描述符后复位设备…因为第一次插入USB的设备在加载驱动之前无法用分析总线的软件查看数据情况,所以后来买了一个USB分析仪,从得到的数据里看出一个奇怪的地方,就是Host在获取了完整的配置描述符后发送了一个索引是238的获取字符串描述符的请求,然后就复位设备….问题是我用到的字符串索引没有238啊,0是语言ID,1、2、3分别是厂商、产品和序列号的字符串索引,我单片机挂起端点 或者 返回0长度包 或者不处理 都阻止不了设备复位… USB的底层模块程序都是用的TI的。有人遇到这种情况吗?
这个请求的代码是:80 06 EE 03 00 00 12 00
USB分析仪截取的数据如下: 设备获取完全部配置描述符之后发了一个索引为238的获取字符串描述符请求,因为我程序里根本没有这个索引的字符串,所以就直接应答STALL了,之后主机就复位了… 我尝试应答NAK或者返回0长度包,都是一个结果,就是主机复位设备… 这个现象只发生在USB设备第一次连接Host的时候(就是插入USB后电脑右下角会显示发现新硬件),如果拔出来再插入枚举时就没有这个现象了,到底怎么回事呢,有人遇到这情况吗?求高人指点~~~
描述符如下(我觉得描述符应该没有问题,如果有问题的话,哪次连接都会出现问题,而不是只有第一次才出现问题):
//定义设备描述符
const BYTE DeviceDescriptor[18] ={
0x12, //描述符长度(18字节)
0x01, //描述符类型(设备描述符)
0x10, 0x01, //USB协议版本(1.1)
0x00, //设备使用的类代码
0x00, //设备使用的子类代码
0x00, //设备使用的协议代码
0x08, //端点0最大包长
0xA0, 0xAA, //厂商 ID
0x01, 0xA0, //产品 ID
0x00, 0x01, //设备版本号(1.0)
0x01, //厂商字符串索引
0x02, //产品字符串索引
0x03, //设备序列号字符窜索引
0x01 //设备拥有的配置数
};
//定义配置描述符集合
const BYTE ConfigurationDescriptorGroup[34] ={
//配置描述符
0x09, //描述符长度(9字节)
0x02, //描述符类型(配置描述符)
0x22, 0x00, //描述符总长度(不固定)
0x01, //该配置支持的接口数
0x01, //该配置的值
0x00, //该配置的字符串索引
0x80, //总线供电,不支持远程唤醒
0xFA, //总线最大电流输出(500mA)
//接口描述符
0x09, //描述符长度(9字节) 0x04, //描述符类型(接口描述符)
0x00, //该接口的编号
0x00, //该接口的备用编号
0x01, //该接口使用的端点数
0x03, //该接口使用的类(自定义 HID类)
0x00, //该接口使用的子类
0x00, //该接口使用的协议
0x00, //该接口的字符串索引
//HID描述符
0x09, //描述符长度(9字节)
0x21, //描述符类型(HID描述符)
0x11, 0x01, //HID协议版本(1.11)
0x00, //国家代码(无)
0x01, //下级描述符数量(1个)
0x22, //下级描述符类型(报告描述符)
0x15, 0x00, //下级描述符长度(不固定)
//端点描述符
0x07, //描述符长度(7字节)
0x05, //描述符类型(端点描述符)
0x81, //端点地址(输入端点 1)
0x03, //端点类型(中断传输端点)
0x40, 0x00, //端点最大包长 64字节
0x0A //端点查询时间(10ms)
};
//定义字符串描述符
const BYTE StringDescriptorID0[4] ={
//语言 ID描述符(索引 0)
0x04, //描述符长度(4字节,不固定)
0x03, //描述符类型(字符串描述符)
0x09, 0x04 //语言 ID号(美式英语)
};
const BYTE StringDescriptorID1[10] ={
//厂商字符串描述符(索引 1)
0x0A, //描述符长度(10字节)
0x03, //描述符类型(字符串描述符)
0x44, 0x00, //D
0x46, 0x00, //F
0x4D, 0x00, //M
0x43, 0x00 //C
};
const BYTE StringDescriptorID2[42] ={
//产品字符串描述符(索引 2)
0x2A, //描述符长度(42字节)
0x03, //描述符类型(字符串描述符)
0x48, 0x00, //H
0x41, 0x00, //A
0x52, 0x00, //R
0x54, 0x00, //T
0x20, 0x00, // 0x48, 0x00, //H
0x61, 0x00, //a
0x6E, 0x00, //n
0x64, 0x00, //d
0x68, 0x00, //h
0x65, 0x00, //e
0x6C, 0x00, //l
0x64, 0x00, //d
0x20, 0x00, //
0x44, 0x00, //D
0x65, 0x00, //e
0x76, 0x00, //v
0x69, 0x00, //i
0x63, 0x00, //c
0x65, 0x00 //e
};
const BYTE StringDescriptorID3[18] ={
//设备序列号字符串描述符(索引 3)
0x12, //描述符长度(18字节)
0x03, //描述符类型(字符串描述符)
0x32, 0x00, //2
0x30, 0x00, //0
0x31, 0x00, //1
0x33, 0x00, //3
0x30, 0x00, //0
0x34, 0x00, //4
0x32, 0x00, //2
0x36, 0x00 //6
};
//定义报告描述符(自定义 HID设备)
const BYTE ReportDescriptor[21] ={
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x00, // USAGE (Undefined)
0xa1, 0x01, // COLLECTION (Application)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
0x19, 0x01, // USAGE_MINIMUM (1)
0x29, 0x08, // USAGE_MAXIMUM (8)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x01, // REPORT_COUNT (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0xc0 // END_COLLECTION
};
Shi JianHua:
还真没弄过这些东西。高手指导吧!