[求助]对复合设备的两个端点号的读写

现在我的usb设备是包括键盘和鼠标一体的,键盘的端点号是01,鼠标的端点号是02,现在只能单独读取键盘和鼠标,问题是 1怎么判断是端点1还是端点2发起的中断啊2怎么完成对2个端点号的同步读取呢

对于复合设备操作与单个设备类似,只是需要配置两个接口,因为你是做主机端点1还是端点2的中断是有你发起的,具体你可以参考一下CH376操作键盘鼠标的例子,里面又如何操作复合设备的例子:/bbs/View.asp?S=101&I=19463


看过了,但是上面程序里没有使用中断,是吗,有点不太明白


完全照抄参考例程, 并把这3句话 Device_Atti.Device[1].Device_report_len = (HID_Dev1->hid_class_descr2.wDescriptorLength>>8)|(HID_Dev1->hid_class_descr2.wDescriptorLength<<8); 改成了小端格式 Device_Atti.Device[1].Device_report_len = HID_Dev1->hid_class_descr2.wDescriptorLength; 结果不知道为什么在set idle success之后就狂发数据,我没招了,照着参考程序改,什么同步标志,端点号都分开,键盘反应一次就都没反应了;照着参考程序抄,又老是狂发数据。


而且1.ch376的参考程序的获取设备描述符等等程序名和程序内容与ch375中对应的也不很匹配,2.ch376的参考程序中用很多结构体,而ch375又很少用,貌似只有1个。 不明白为什么芯片型号差不多,程序要写的这么不兼容,不方面修改呢?


首先,我们的例程是针对51单片机的,你STM32肯定得修改。set idle之后应该是获取报表描述符,你狂发数据是什么数据?其次,CH375和CH376虽然都是USB接口芯片,但是还是有很大差别的。另外,你调试的话最好是使用USB分析仪来监控数据,这样可以知道问题出在那个地方!


谢谢您周六仍回答我,真不好意思。 1.不知道是什么数据,就是串口接收数字一直在加,数据太多了串口调试助手看不过来 2.好的 3.没有啊,实习的公司让我自己做,我只能自己做,不能说做不出来还申请买个东西啊,也许等我做出来了公司才会考虑买芯片做板子,而且前面我做的实验板子也是自己买的。关键是公司不关心我做的这个东西,我只是自己想要做出来,早结束,早毕业。 另外,我想请教几个问题, 1.主机端点是一个,复合设备的端点是2个,端点1是键盘,端点2是鼠标,我想问下端点的同步标志位、主机端点的同步触发标志是什么意思,是什么关系呢, 2.比如我设endp6_mode=0x80;就是我想接收端点0的DATA0放弃DATA1,那么下一步是不是不管端点是1还是2,我都该设endp6_mode=0xC0;接收DATA1,还是各自端点有各自的顺序,就是如果下一步是端点1,就设endp6_mode=0xC0;如果是端点2,就还是设endp6_mode=0x80;不知道我有没有表达清楚, 3.如果是问题2中的各自端点有各自的顺序,那我今天又试了下直接抄ch376的参考程序里的这段话,不用中断了,直接轮询 while(1) { //获取设备1的数据 s = get_int_in( Device_Atti.Device[0].tog,Device_Atti.Device[0].Device_endp);

//如果该设备是符合设备,则需要获取设备2的数据 if( Device_Atti.Device_compat ) { s = get_int_in( Device_Atti.Device[1].tog,Device_Atti.Device[1].Device_endp); } } get_int_in()和issue_token()也是照着改 结果却是串口一会有键盘值,一会没有,一会有鼠标值,一会没有,这会是什么原因呢


我感觉问题还是出在同步标志那一块,但是我get_int_in()和issue_token()也这两个函数都是照着参考程序改的,不明白还有什么不一样,还是ch375和ch376的关于同步标志的部分又不一样? 附上我改过的这两个函数 UINT8 get_int_in(UINT8 endptog,UINT8 endpint) { UINT8 s,t,j; endtog = endptog ? 0x80 : 0x00; issue_token(endptog,( endpint << 4 ) | DEF_USB_PID_IN); s = wait_interrupt( ); if(s == USB_INT_SUCCESS) { t = RD_USB_DATA(data_buf); for(j=0;j!=t;j++) printf("%02x ",(unsigned short)data_buf[j]); if( endpint == Device_Atti.Device[0].Device_endp ) Device_Atti.Device[0].tog = Device_Atti.Device[0].tog ? FALSE : TRUE; else Device_Atti.Device[1].tog = Device_Atti.Device[1].tog ? FALSE : TRUE; } return s; } void issue_token1(UINT8 endptog, UINT8 endp_and_pid ) { CH376_WR_CMD_PORT( CMD_ISSUE_TKN_X ); CH376_WR_DAT_PORT( endptog ); CH376_WR_DAT_PORT( endp_and_pid ); mDelay2uS(); } 现象挺诡异的,不知道怎么表达,就是按一下键盘,有反应,但是反应不对,按一下鼠标,没反应,再按一下键盘有反应,再按一下鼠标,有反应。郁闷+郁闷


根据你的现象有可能是同步标志的问题,同步标志是各自端点有各自的顺序,DATA0和DATA1来回切换,你看你调用get_int_in,endptog的赋值是两个不同的变量。你的函数就是我们的例程,你先不要看其他的,把CH376的例程看懂。


前几天仔细看了usb描述符,把ch376移植到ch375上的程序试了下,就是还是上次的问题,在set idle之后就狂发数据,将配置描述符打印出来了 Device_Atti.Device[0].Device_type=01 //01 Device_Atti.Device[0].Device_inf=00 //00 Device_Atti.Device[0].Device_endp=03 //81 Device_Atti.Device[0].Device_size=00 //08 Device_Atti.Device[0].Device_report_len=07 //3e

Device_Atti.Device[1].Device_type=00 //02 Device_Atti.Device[1].Device_inf=00 //01 Device_Atti.Device[1].Device_endp=08 //82 Device_Atti.Device[1].Device_size=0a //08 Device_Atti.Device[1].Device_report_len=705 //f1 左边是获得的值,右边是实际正确的值,就是说配置获取的不对。 我想问2个问题, 1.在ch376的参考程序中,配置获取的不对,是否影响后面的轮询?如果我直接赋正确的值给上面,是否可以不影响下面的轮询?今天这样试了下,完全没反应,诶 2.这个复合设备的端点描述符是这样的 typedef struct _USB_ENDPOINT_DESCRIPTOR_ { BYTE bLength, 07 07 BYTE bDescriptorType, 05 05 BYTE bEndpointAddress, 81 82 BYTE bmAttributes, 03 03 WORD wMaxPacketSize, 0008 0008 BYTE bInterval 0a 0a }USB_ENDPOINT_DESCRIPTOR; 左边的一组是键盘,右边的一组是鼠标,我先问下网上说bmAttributes=03;代表端点属性是中断,是否可以直接轮询这个端点,是没有影响的吗,因为我看ch376的参考程序是轮询的,而ch375的参考程序是用中断的?不明白为什么要不一样


首先,你获取的配置值不对,那说明你分析配置描述符的程序出了问题,这部分需要你在仔细的看下你的软件。 其次,端点属性为0X03仅仅表示是中断端点,并不能说明一定是某个键盘或则鼠标的端点。有很多键盘或者鼠标就复合了另外一个端点,但是这个端点并不是用于传输数据的。 再次,无论采用中断还是查询,都是去轮训的取数据,作为USB主机,针对中断端点都需要主机主动发送IN包来取数据。至于软件怎么实现无所谓。


1.分析配置描述符的程序出了问题,但是这部分是复制的ch376中的参考程序,就是用了很多结构体的,仔细看了,没看懂,我能看出程序正确读出了描述符,但是parse_config_descr()这个程序没有正确的分析和保存。 2.今天又试了下,直接在parse_config_descr()赋值,set idle第一个端点键盘可以,Device_report_len是59个,获取报表描述符也正确,第二个端点set idle可以,Device_report_len是241个,get_report_descr_ex就不正确了,那应该是get_report_descr_ex()有问题,不知道是否是241个太多了,只读了49个,后面就不对了。 但是get_int_in()能够获取键盘和鼠标值了。 3.我想问个一直很想问的问题,在get_int_in()获取设备数据之前的各种配置的目的是什么?因为我看get_int_in()仅仅使用了端点号Device_endp,那之前各种配置的意义是什么呢,刚刚试了下,把各种读取配置去掉,仅仅parse_config_descr()赋值,没反应,难道是因为usb都需要这样配置一下? 4.下面就想改成中断获取试试,不知怎样呢。


算了,不用中断了,因为之前的用中断读取数据的,经常插了一段时间后没反应了,不知道为什么。


我现在也在调试这个,哪个大神可以提供一下参考,谢谢。


只有登录才能回复,可以选择微信账号登录