USB HID设备枚举失败,返回STALL(请大侠们帮帮手,急)

cjyoung 2013-05-01 02:28:05
如题,最近在做一个项目,需要把USB作为自定义的HID设备,但总是枚举不成功,到“获取HID报告描述符”一步就返回STALL了,郁闷了一个星期,请高手帮忙分析一下问题的原因。下面截图作一下描述:
插入USB接口,计算机可以识别为HID设备,如下图所示:

但查看设备状态为“该设备无法启动。(代码10)”,如下图所示:

用Bus Hound监控,枚举过程的获取“设备描述符”,“配置描述符”等都是成功的,但到获取“HID报告描述符”的时候(从Bus Hound可以看出重试了3次)就返回了STALL,枚举过程就停止了。程序处理中当接收到获取“报告描述符”的SETUP令牌包的时候,我已经有作出处理,就是把“报告描述符”数组写到EP0 的IN 端点中。具体的Bus Hound日志如图所示:
...全文
852 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
flexman09 2013-08-09
  • 打赏
  • 举报
回复
为什么换了就对了啊?
引用 6 楼 xinghaiwang197 的回复:
我也遇到跟你类似的问题点,后来我自已重新抓了一组描述符的值就可以过了 CON_INT_ENDP_DESCRIPTOR_STRUCT con_int_endp_descriptor={ //0x09,0x02,0x3b,0x00,0x02,0x01,0x00,0xa0,0x32,//0x3b表示为字符描述总长度,0x02表示为几个接口 0x09,0x02,0x29,0x00,0x01,0x01,0x00,0xa0,0x32, 0x09,0x04,0x00,0x00,0x01,0x03,0x01,0x01,0x00, 0x09,0x21,0x10,0x01,0x00,0x01,0x22,0x3e,0x00, 0x07,0x05,0x81,0x03,0x08,0x00,0x0a, //0x09,0x04,0x01,0x00,0x01,0x03,0x00,0x00,0x00, //0x09,0x21,0x10,0x01,0x00,0x01,0x22,0x65,0x00, 0x07,0x05,0x82,0x03,0x08,0x00,0x0a }; static U8 KeyBoardReportDescriptor[] ={ 0x05,0x01,0x09,0x06,0xa1,0x01,0x05,0x07, 0x19,0xe0,0x29,0xe7,0x15,0x00,0x25,0x01, 0x75,0x01,0x95,0x08,0x81,0x02,0x95,0x01, 0x75,0x08,0x81,0x01,0x95,0x03,0x75,0x01, 0x05,0x08,0x19,0x01,0x29,0x03,0x91,0x02, 0x95,0x05,0x75,0x01,0x91,0x01,0x95,0x06, 0x75,0x08,0x26,0xff,0x00,0x05,0x07,0x19, 0x00,0x29,0x91,0x81,0x00,0xc0}; struct USB_DEVICE_DESCRIPTOR descDev={ 0x12,0x01,0x10,0x01,0x00,0x00,0x00,0x08, 0xd9,0x04,0x03,0x18,0x10,0x03,0x01,0x02,0x00,0x01 }; static const U8 descStr0[4]={0x04,STRING_TYPE,0x09,0x04}; static const U8 descStr1[80]={80,STRING_TYPE,0x35,0x75,0x11,0x81,0x08,0x57,0x08,0x57,0x84,0x76,'U',0x00, 'S',0x00,'B',0x00,0x13,0x4E,0x3A,0x53,0x20,0x00,'H',0,'t',0,'t',0, 'p',0,':',0,'/',0,'/',0,'g',0,'r',0,'o',0,'u',0,'p',0,'.',0,'e',0,'d',0,'n',0, 'c',0,'h',0,'i',0,'n',0,'a',0,'.',0,'c',0,'o',0,'m',0,'/',0,'9',0,'3',0}; static const U8 descStr2[26]={0x1a,0x03,0x55,0x00,0x53,0x00,0x42,0x00,0x20,0x00,0x4b,0x00,0x65,0x00,0x79,0x00,0x62,0x00,0x6f,0x00,0x61,0x00,0x72,0x00,0x64,0x00}; static const U8 descStr2_R[26]={0x1a,0x03,0x55,0x00,0x53,0x00,0x42,0x00,0x20,0x00,0x4b,0x00,0x65,0x00,0x79,0x00,0x05,0x01,0x09,0x06,0xa1,0x01,0x05,0x07,0x64,0x00};
xinghaiwang197 2013-07-04
  • 打赏
  • 举报
回复
我也遇到跟你类似的问题点,后来我自已重新抓了一组描述符的值就可以过了 CON_INT_ENDP_DESCRIPTOR_STRUCT con_int_endp_descriptor={ //0x09,0x02,0x3b,0x00,0x02,0x01,0x00,0xa0,0x32,//0x3b表示为字符描述总长度,0x02表示为几个接口 0x09,0x02,0x29,0x00,0x01,0x01,0x00,0xa0,0x32, 0x09,0x04,0x00,0x00,0x01,0x03,0x01,0x01,0x00, 0x09,0x21,0x10,0x01,0x00,0x01,0x22,0x3e,0x00, 0x07,0x05,0x81,0x03,0x08,0x00,0x0a, //0x09,0x04,0x01,0x00,0x01,0x03,0x00,0x00,0x00, //0x09,0x21,0x10,0x01,0x00,0x01,0x22,0x65,0x00, 0x07,0x05,0x82,0x03,0x08,0x00,0x0a }; static U8 KeyBoardReportDescriptor[] ={ 0x05,0x01,0x09,0x06,0xa1,0x01,0x05,0x07, 0x19,0xe0,0x29,0xe7,0x15,0x00,0x25,0x01, 0x75,0x01,0x95,0x08,0x81,0x02,0x95,0x01, 0x75,0x08,0x81,0x01,0x95,0x03,0x75,0x01, 0x05,0x08,0x19,0x01,0x29,0x03,0x91,0x02, 0x95,0x05,0x75,0x01,0x91,0x01,0x95,0x06, 0x75,0x08,0x26,0xff,0x00,0x05,0x07,0x19, 0x00,0x29,0x91,0x81,0x00,0xc0}; struct USB_DEVICE_DESCRIPTOR descDev={ 0x12,0x01,0x10,0x01,0x00,0x00,0x00,0x08, 0xd9,0x04,0x03,0x18,0x10,0x03,0x01,0x02,0x00,0x01 }; static const U8 descStr0[4]={0x04,STRING_TYPE,0x09,0x04}; static const U8 descStr1[80]={80,STRING_TYPE,0x35,0x75,0x11,0x81,0x08,0x57,0x08,0x57,0x84,0x76,'U',0x00, 'S',0x00,'B',0x00,0x13,0x4E,0x3A,0x53,0x20,0x00,'H',0,'t',0,'t',0, 'p',0,':',0,'/',0,'/',0,'g',0,'r',0,'o',0,'u',0,'p',0,'.',0,'e',0,'d',0,'n',0, 'c',0,'h',0,'i',0,'n',0,'a',0,'.',0,'c',0,'o',0,'m',0,'/',0,'9',0,'3',0}; static const U8 descStr2[26]={0x1a,0x03,0x55,0x00,0x53,0x00,0x42,0x00,0x20,0x00,0x4b,0x00,0x65,0x00,0x79,0x00,0x62,0x00,0x6f,0x00,0x61,0x00,0x72,0x00,0x64,0x00}; static const U8 descStr2_R[26]={0x1a,0x03,0x55,0x00,0x53,0x00,0x42,0x00,0x20,0x00,0x4b,0x00,0x65,0x00,0x79,0x00,0x05,0x01,0x09,0x06,0xa1,0x01,0x05,0x07,0x64,0x00};
bluesnail1986 2013-05-09
  • 打赏
  • 举报
回复
这个还是代码的问题。很可能是收到GetDescriptor命令后,代码没有回复或者错误地回复了命令,楼主不妨自己跟下,这种Bug不难解决的...
of123 2013-05-06
  • 打赏
  • 举报
回复
要看你代码中是如何处理的了。一般标准请求的处理,对于未处理的缺省项是发送 Stall 信令的,表示不支持的请求。
曹大夯 2013-05-05
  • 打赏
  • 举报
回复
是不是你的firmware代码确实STALL了这个GET_DESCRIPTOR Request?你能调试一下么? 注意:系统要求的Descriptor Length是0x5b,设备端不用返回那么多数据,因为你没有那么多。
cjyoung 2013-05-02
  • 打赏
  • 举报
回复
引用 1 楼 Huntercao 的回复:
你的“HID报告描述符”是什么样的?先确保描述符本身是对的。
Huntercao你好,不是应该报告描述符错了也应该接收到数据吗?但我从Bus Hound上看是直接给STALL了,根本没机会让程序返回“HID报告描述符”。我是从“圈圈”那直接拷贝了他的报告描述符的:
__align(4) LOCAL const USB_HID_REPORT_DESCRIPTOR_T s_UHID_ReportDescr = 
{
	// 每行开始的第一字节为该条目的前缀,前缀的格式为:
	// D7~D4:bTag。D3~D2:bType;D1~D0:bSize。以下分别对每个条目注释。

	// 这是一个全局(bType为1)条目,将用途页选择为普通桌面Generic Desktop Page。
	// 后面跟1字节数据(bSize为1),后面的字节数就不注释了,自己根据bSize来判断。
	0x05, 0x01, // USAGE_PAGE (Generic Desktop)

	// 这是一个局部(bType为2)条目,用途选择为0x00。在普通桌面页中,
	// 该用途是未定义的,如果使用该用途来开集合,那么系统将不会把它
	// 当作标准系统设备,从而就成了一个用户自定义的HID设备。
	0x09, 0x00, // USAGE (0)

	// 这是一个主条目(bType为0)条目,开集合,后面跟的数据0x01表示
	// 该集合是一个应用集合。它的性质在前面由用途页和用途定义为
	// 用户自定义。
	0xa1, 0x01, // COLLECTION (Application)

	// 这是一个全局条目,说明逻辑值最小值为0。
	0x15, 0x00, // LOGICAL_MINIMUM (0)

	// 这是一个全局条目,说明逻辑值最大为255。
	0x25, 0xff, // LOGICAL_MAXIMUM (255)

	// 这是一个局部条目,说明用途的最小值为1。
	0x19, 0x01, // USAGE_MINIMUM (1)

	// 这是一个局部条目,说明用途的最大值8。
	0x29, 0x08, // USAGE_MAXIMUM (8) 

	// 这是一个全局条目,说明数据域的数量为八个。
	0x95, 0x08, // REPORT_COUNT (8)

	// 这是一个全局条目,说明每个数据域的长度为8bit,即1字节。
	0x75, 0x08, // REPORT_SIZE (8)

	// 这是一个主条目,说明有8个长度为8bit的数据域做为输入。
	0x81, 0x02, // INPUT (Data,Var,Abs)

	// 这是一个局部条目,说明用途的最小值为1。
	0x19, 0x01, // USAGE_MINIMUM (1)

	// 这是一个局部条目,说明用途的最大值8。
	0x29, 0x08, // USAGE_MAXIMUM (8) 

	// 这是一个主条目。定义输出数据(8字节,注意前面的全局条目)。
	0x91, 0x02, // OUTPUT (Data,Var,Abs)

	// 下面这个主条目用来关闭前面的集合。bSize为0,所以后面没数据。
	0xc0		// END_COLLECTION
};
曹大夯 2013-05-02
  • 打赏
  • 举报
回复
你的“HID报告描述符”是什么样的?先确保描述符本身是对的。

21,597

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧