我有一个应用CC2540采集数据后发送到PC端,PC使用的是CC2540 USB Dongle。由于CDC的驱动到客户手上后经常出现驱动安装不上的问题。所以想到了把CC2540 USB Dongle改成HID设备的想法。
目前我能找到的例子是HID类的鼠标键盘,不知道改怎么修改?
也不知道HID类应该怎样去扫描和连接我的采集器。
还有我的采集器应该不需要改吧?如果改那个是很麻烦的事情,因为已经出了几批货了。
Liao Wei1:
我把描述符改了,改成了普通的HID,用Bus Hound能成功的收到数据而且是对的,但是用自己的程序收不到。自己的程序是以前做其它HID设备用得好好的,应该只需要改一下读去数据的长度、VID和PID就可以了的呀?
另外我用PortHelper工具能找到这个工具,但是设备名是空的,我查了一下描述符配置,有几个字符串但是没有和程序关联上,这个怎么弄的?
以下是我修改的描述符:
/***********************************************************************************
Filename: usb_hid_descriptor.s51
Description: USB descriptor for HID-devices.
***********************************************************************************/#define ASM_FILE#include "../library/usb_descriptor.h"
MODULE usb_descriptor
RSEG RCODE
PUBLIC usbDescStart; PUBLIC usbDescEnd; PUBLIC deviceDesc; PUBLIC configDesc; PUBLIC interface0Desc; PUBLIC hid0Desc; PUBLIC endpoint0Desc; PUBLIC endpoint1Desc; PUBLIC entity0Desc; PUBLIC entity0DescEnd; PUBLIC string0Desc; PUBLIC string1Desc; PUBLIC string2Desc; PUBLIC string3Desc; PUBLIC usbDescLut; PUBLIC usbDescLutEnd; PUBLIC usbDblbufLut; PUBLIC usbDblbufLutEnd;
;;——————————————————————————————————-;; USB descriptors
usbDescStart:deviceDesc: ; Device descriptor DB deviceDescEnd – deviceDesc ; bLength DB DESC_TYPE_DEVICE ; bDescriptorType DW 0200H ; bcdUSB (USB 2.0) DB 00H ; bDeviceClass (given by interface) DB 00H ; bDeviceSubClass DB 00H ; bDeviceProtocol DB EP0_PACKET_SIZE ;bMaxPacketSize 端点0最大包尺寸,所有设备必须支持端点0 DW 0451H ; idVendor (Texas Instruments) DW 16B4H ; idProduct (CC2540 HID) DW 0100H ; bcdDevice (v1.0) DB 01H ; iManufacturer DB 02H ; iProduct DB 03H ; iSerialNumber DB 01H ; bNumConfigurationsdeviceDescEnd:
config1LengthStart:configDesc: ; Configuration descriptor DB configDescEnd – configDesc ; bLength DB DESC_TYPE_CONFIG ; bDescriptorType DW config1LengthEnd – config1LengthStart ; wTotalLength DB 01H ; bNumInterfaces DB 01H ; bConfigurationValue DB 00H ; iConfiguration DB 0xc0 ;levivi raw=0xa0 ; bmAttributes (bit 5 remote wakeup) DB 0x96 ;levivi raw=25 ; bMaxPower (max 2 * 25 = 50 mA)configDescEnd:
interface0Desc: ; consumer interface descriptor DB interface0DescEnd – interface0Desc ; bLength DB DESC_TYPE_INTERFACE ; bDescriptorType DB 00H ; levivi raw=DB 01H ; bInterfaceNumber DB 00H ; bAlternateSetting (none) DB 02H ; bNumEndpoints//levivi raw=1 DB 03H ; bInterfaceClass (HID) DB 00H ; bInterfaceSubClass (None) DB 00H ; bInterfaceProcotol (Don't Care) DB 00H ; iInterfaceinterface0DescEnd:
hid0Desc: ; consumer HID descriptor DB hid0DescEnd – hid0Desc ; bLength DB DESC_TYPE_HID ; bDescriptor DW 0110H ; bcdHID (HID v1.11) DB 00H ; bCountryCode (not localized) DB 01H ; bNumDescriptors DB 0x22 ;DESC_TYPE_HIDREPORT ; bDescriptorType DW entity0DescEnd – entity0Desc ; wDescriptorLengthhid0DescEnd:
endpoint0Desc: ; consumer endpoint descriptor (EP2 IN) DB endpoint0DescEnd – endpoint0Desc DB DESC_TYPE_ENDPOINT ; bDescriptorType DB 82H ; bEndpointAddress levivi bit7表示方向'0'输出'1'输入 DB EP_ATTR_INT ; bmAttributes (INT) DB EP0_PACKET_SIZE, 00H ; wMaxPacketSize//levivi DB 01H ; bInterval//leviviendpoint0DescEnd:
endpoint1Desc: ; consumer endpoint descriptor (EP1 out) DB endpoint1DescEnd – endpoint1Desc DB DESC_TYPE_ENDPOINT ; bDescriptorType DB 01H ; bEndpointAddress levivi bit7表示方向'0'输出'1'输入 DB EP_ATTR_INT ; bmAttributes (INT) DB EP0_PACKET_SIZE, 00H ; wMaxPacketSize//levivi DB 01H ; bInterval//leviviendpoint1DescEnd:
config1LengthEnd;;——————————————————————————————————-
;;——————————————————————————————————-;; String descriptorsstring0Desc: ; Language ID DB string0DescEnd – string0Desc ; bLength DB DESC_TYPE_STRING ; bDescriptorType DW 0409H ; wLangID (English-US)string0DescEnd:
string1Desc: ; Manufacturer DB string1DescEnd – string1Desc ; bLength DB DESC_TYPE_STRING ; bDescriptorType DB 'T', 0 ; unicode string DB 'e', 0 DB 'x', 0 DB 'a', 0 DB 's', 0 DB ' ', 0 DB 'I', 0 DB 'n', 0 DB 's', 0 DB 't', 0 DB 'r', 0 DB 'u', 0 DB 'm', 0 DB 'e', 0 DB 'n', 0 DB 't', 0 DB 's', 0string1DescEnd:
string2Desc: ; Product DB string2DescEnd – string2Desc ; bLength DB DESC_TYPE_STRING ; bDescriptorType DB 'U', 0 ; unicode string DB 'S', 0 DB 'B', 0 DB ' ', 0 DB 'C', 0 DB 'C', 0 DB '2', 0 DB '5', 0 DB '4', 0 DB '0', 0 DB ' ', 0 DB 'H', 0 DB 'I', 0 DB 'D', 0string2DescEnd:
; To enable multiple HID dongles to connect to a PC,; program a unique serial number for each dongle.string3Desc: ; Serial Number DB string3DescEnd – string3Desc DB DESC_TYPE_STRING ; bDescriptorType DB '0', 0 DB '0', 0 DB '1', 0string3DescEnd:usbDescEnd:;;——————————————————————————————————-
;;——————————————————————————————————-;; HID report descriptors
entity0Desc: ; consumer report descriptor (using format for Boot interface descriptor) DB 0x05, 0x8c ; * USAGE_PAGE (ST Page) */ DB 0x09, 0x01 ; * USAGE (Demo Kit) */ DB 0xa1, 0x01 ; * COLLECTION (Application) */ ;// The Input report DB 0x09,0x03 ; / USAGE ID – Vendor defined DB 0x15,0x00 ; / LOGICAL_MINIMUM (0) DB 0x26,0x00, 0xFF ; / LOGICAL_MAXIMUM (255) DB 0x75,0x08 ; / REPORT_SIZE (8bit) DB 0x95,EP0_PACKET_SIZE ; / REPORT_COUNT (32Byte) DB 0x81,0x02 ; / INPUT (Data,Var,Abs)
;// The Output report DB 0x09,0x04 ; / USAGE ID – Vendor defined DB 0x15,0x00 ; / LOGICAL_MINIMUM (0) DB 0x26,0x00,0xFF ; / LOGICAL_MAXIMUM (255) DB 0x75,0x08 ; / REPORT_SIZE (8bit) DB 0x95,EP0_PACKET_SIZE ; / REPORT_COUNT (32Byte) DB 0x91,0x02 ; / OUTPUT (Data,Var,Abs)
DB 0xc0 ;/* END_COLLECTION */ entity0DescEnd:
;;——————————————————————————————————-
;;——————————————————————————————————-;; Look-up table for descriptors that are not returned through requests for DSC_DEVICE, DSC_CONFIG or;; DSC_STRING (e.g. HID report descriptors)usbDescLut: DB DESC_TYPE_HIDREPORT, 00H ; value (MSB:LSB) DB 00H, 00H ; index (MSB:LSB) DW entity0Desc ; pDesc DW entity0DescEnd – entity0Desc ; length
DB DESC_TYPE_HID, 00H ; value (MSB:LSB)
DB 00H, 00H ; index (MSB:LSB) DW hid0Desc ; pDesc DW hid0DescEnd – hid0Desc ; length
usbDescLutEnd:;;——————————————————————————————————-
;;——————————————————————————————————-;; Look-up table for double buffer settings (one set of bit masks for each defined interface)usbDblbufLut: DW interface0Desc ; pInterface DB 00H ; inMask DB 00H ; outMask
usbDblbufLutEnd:;;——————————————————————————————————-
END;
Liao Wei1:
回复 Liao Wei1:
改成1次发32个字节,PC端该成1次读33个字节,能成功读到了。
下周再试试PC往下发数据。
Liao Wei1:
回复 Liao Wei1:
从PC上发送下来的数据似乎在usbHidProcessEvents里可以收到
void usbHidProcessEvents(void){
//………………
if (USBIRQ_GET_EVENT_MASK() & USBIRQ_EVENT_EP1OUT) { USBIRQ_CLEAR_EVENTS(USBIRQ_EVENT_EP1OUT); g_test_cnt++;//levivi usbfwSetupHandler();
hidRevHidOutReport(g_rev, 1, 32); }}
调试发送,只要我从PC发1次数据后,中断就会不断的进来,usbfwData.pEpOutStatus[1] 是为 EP_HALT
收到的数据,32个字节都等于我发的第一个数据,而其它31个数据则没有对应等于我发的数据???
uint8 hidRevHidOutReport(uint8 *pReport, uint8 endPoint, uint8 len)//levivi{ uint8 result = FALSE;
if (endPoint < 6) { uint8 ea = halIntLock();
USBFW_SELECT_ENDPOINT(endPoint); if (!(USBCSOL & USBCSOL_OUTPKT_RDY)) { usbfwReadFifo(((&USBF0) + (endPoint << 1)), len, pReport); USBCSOL |= USBCSOL_OUTPKT_RDY; result = TRUE; } /// Arms the selected OUT endpoint, so that the FIFO can receive data from the host//#define USBFW_ARM_OUT_ENDPOINT() (USBCSOL = 0) USBFW_ARM_OUT_ENDPOINT() ; halIntUnlock(ea); }
return result;}
Liao Wei1:
回复 Liao Wei1:
应该清除那个标志就不再进USBIRQ_EVENT_EP1OUT中断了呢???
Liao Wei1:
回复 Liao Wei1:
上面说错了,ENDPOINT1应该对应usbfwData.pEpOutStatus[0] 中断里读出来是EP_IDLE,怎么就没有EP_RX或EP_MANUAL_RX?
Liao Wei1:
回复 Liao Wei1:
轮询读有bug,PC发一次数据,这个if会进入两次,1次读出来是上次发送的数据,另一次读出来是这次发的。
虽然有bug,可以勉强用了,不想在这上面浪费太多时间。
明天把扫描连接设备,和收发数据加进来。
if(USBFW_GET_OUT_ENDPOINT_COUNT_LOW()==32) {hidRevHidOutReport(g_rev, 1, 32);
}
Liao Wei1:
回复 Liao Wei1:
cedar_xuesong:
回复 Liao Wei1:
威武霸气,赞一个
Yan:
回复 Liao Wei1:
你可以的。