本帖最后由 kokoromi 于 2013-5-8 12:41 编辑
做了一个自定义HID设备,首次枚举后会提示硬件安装出现问题。
我的配置描述符集合是34字节,端点0最大包长为8字节
调试环境下发现,设备第二次获取配置描述符集合的时候,本应该触发5次IN中断,但是却触发了8次IN中断,然后就复位了...而且复位之后还能继续获取字符串描述符和报告描述符... 但是拔出USB然后再插入枚举就一切正常了,主机第二次获取配置描述符的时候也正常的触发了5次IN中断,这是怎么回事啊?我都要崩溃了,这问题怎么这么诡异?只要我更改了设备描述符里的VID和PID,枚举的时候就会发生上面的情况,拔出再插入就正常...
发送数据这块和描述符我都检查好几遍了,没问题的,真是不明白,主机要想触发设备的IN中断,必须是设备清除了端点NAK使能发送后主机才能发来IN令牌并让设备发送数据并触发IN中断,为什么会在第一次枚举的时候多触发了3次IN中断呢,实在是不明白了,有人遇到过这情况吗? 望各位指点啊~
下面是枚举涉及到的描述符:
//定义设备描述符
const BYTE DeviceDescriptor[18] =
{
0x12, //描述符长度(18字节)
0x01, //描述符类型(设备描述符)
0x10, 0x01, //USB协议版本(1.1)
0x00, //设备使用的类代码
0x00, //设备使用的子类代码
0x00, //设备使用的协议代码
0x08, //端点0最大包长
0xFF, 0x88, //厂商 ID
0xEE, 0x99, //产品 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
};
调试信息如下:
USB复位中断:USB复位
USB挂起中断:USB挂起
USB挂起中断:USB挂起
USB复位中断:USB复位
USB端点0 输出中断:获取设备描述符
USB端点0 输入中断
USB复位中断
USB端点0 输出中断:设置地址
USB端点0 输出中断:获取设备描述符
USB端点0 输入中断
USB端点0 输入中断
USB端点0 输入中断
USB端点0 输出中断:获取配置描述符
USB端点0 输入中断
USB端点0 输入中断
USB端点0 输出中断:获取字符串描述符(语言ID)
USB端点0 输入中断
USB端点0 输出中断:获取字符串描述符(产品序列号)
USB端点0 输入中断
USB端点0 输入中断
USB端点0 输入中断
USB端点0 输出中断:获取配置描述符
USB端点0 输入中断
USB端点0 输入中断
USB端点0 输入中断
USB端点0 输入中断
USB端点0 输入中断
USB端点0 输入中断
USB端点0 输入中断
USB端点0 输入中断
USB复位中断
USB端点0 输出中断:获取字符串描述符(语言ID)
USB端点0 输入中断
USB端点0 输出中断:获取字符串描述符(产品字符串)
USB端点0 输入中断
USB端点0 输入中断
USB端点0 输入中断
USB端点0 输入中断
USB端点0 输入中断
USB端点0 输入中断
... ...
后面的就省略了,都是请求字符串描述符、设备描述符、配置描述符、设置配置、设置空闲和获取报告描述符等等。麻烦大家帮我看看我的 设备描述符 和 配置描述符 有没有问题,只要修改完设备描述符里的厂商ID和产品ID然后插入USB就会出现上面的调试信息里的情况,第二次获取配置描述符集合的时候多了三次输入中断并且紧接着就复位了,但是,只要不修改厂商ID和产品ID再插入USB,调试信息红色部分就没有了,一切正常。
麻烦大家帮我看看到底哪儿出的问题,太诡异了~ 不胜感激~~
|