打印

USB复合设备(USB键盘和自定义HID)遇到的问题

[复制链接]
11300|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 everbright 于 2012-1-5 20:39 编辑

这两个设备都是USB HID设备.计算机已经识别出这两种设备,并且自定义的HID设备已经可以操作,只是HID键盘不能操作,键盘所使用的端口收不到数据,打断点不能进来.不知道是那里问题. 源码如下:
/* USB Standard Device Descriptor */
const u8 DeviceDescriptor[SIZ_DEVICE_DESC] =
  {
    0x12,                       /*bLength */
    USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/
    0x10,                       /*bcdUSB USB1.1 */
    0x01,
    0x00,                       /*bDeviceClass:Miscellaneous Device Class*/
    0x00,                       /*bDeviceSubClass:Common Class*/
    0x00,                       //bDeviceProtocol: Interface Association Descriptor
    0x40,                       /*bMaxPacketSize40*/
    ID_VENDOR_L,                /*idVendor (0x1234)这个是需要跟USB组织申请的ID号,表示厂商代号*/
    ID_VENDOR_H,
    ID_PRODUCT_L,               /*idProduct = 0x5678该产品的编号,跟厂商编号一起配合使用,让主机注册该设备并加载相应的驱动程序*/
    ID_PRODUCT_H,
    0x00,                       /*bcdDevice rel. 1.00 BCD码表示的设备版本号*/
    0x01,
    1,                          /*Index of string descriptor describing
                                              manufacturer */
    2,                          /*Index of string descriptor describing
                                             product*/
    3,                          /*Index of string descriptor describing the
                                             device serial number */
    0x01                        /*bNumConfigurations*/
  }
  ; /* DeviceDescriptor */

/* USB Configuration Descriptor */
/*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
const u8 ConfigDescriptor[SIZ_CONFIG_DESC] =
  {
    0x09, /* bLength: Configuation Descriptor size */
    USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
    SIZ_CONFIG_DESC,
    /* wTotalLength: Bytes returned */
    0x00,
    0x02,         /*bNumInterfaces: 2 interface*/
    0x01,         /*bConfigurationValue: Configuration value*/
    0x00,         /*iConfiguration: Index of string descriptor describing
                                 the configuration*/
    0xA0,         /*bmAttributes: 总线供电,支持远程唤醒 */
    0x64,         /*MaxPower 200 mA: this current is used for detecting Vbus*/

    /************** Descriptor of interface ****************/
    /* 9 */
    0x09,         /*bLength: Interface Descriptor size*/
    USB_INTERFACE_DESCRIPTOR_TYPE,/*bDescriptorType: Interface descriptor type*/
    0x00,         /*bInterfaceNumber: Number of Interface*/
    0x00,         /*bAlternateSetting: Alternate setting*/        
    0x02,         /*bNumEndpoints*/
    0x03,         /*bInterfaceClass: HID*/
    0x00,         /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
    0x00,         /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
    0,            /*iInterface: Index of string descriptor*/
   
/******************** Descriptor of HID ********************/
    /* 18 */
    0x09,         /*bLength: HID Descriptor size*/
    HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
    0x00,         /*bcdHID: HID Class Spec release number*/
    0x01,
    0x00,         /*bCountryCode: Hardware target country*/
    0x01,         /*bNumDescriptors: Number of HID class descriptors to follow*/
    0x22,         /*bDescriptorType*/
    SIZ_REPORT_DESC,/*wItemLength: Total length of Report descriptor*/
    0x00,
   
   
    /******************** Descriptor of  endpoint ********************/
    /* 27 */
    0x07,          /*bLength: Endpoint Descriptor size*/
    USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/
    0x81,          /*bEndpointAddress: Endpoint Address (IN)*/
    0x03,          /*bmAttributes: Interrupt endpoint*/
    REC_BUFFER_SIZE,          /*wMaxPacketSize: 64 Byte max */
    0x00,
    0x0A,          /*bInterval: Polling Interval (10 ms)*/
    /******************** Descriptor of  endpoint ********************/
    /* 34 */
    0x07,          /*bLength: Endpoint Descriptor size*/
    USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/
    0x01,          /*bEndpointAddress: Endpoint Address (OUT)*/
    0x03,          /*bmAttributes: Interrupt endpoint*/
    REC_BUFFER_SIZE,    /*wMaxPacketSize: 64 Byte max */
    0x00,
    0x0A,          /*bInterval: Polling Interval (10 ms)*/
    /* 41 */
  
    // Add a hid keyboard descriptor
    /************** Descriptor of Joystick Mouse interface ****************/
    0x09,         /*bLength: Interface Descriptor size*/
    USB_INTERFACE_DESCRIPTOR_TYPE,/*bDescriptorType: Interface descriptor type*/
    0x01,         /*bInterfaceNumber: Number of Interface*/
    0x00,         /*bAlternateSetting: Alternate setting*/
    0x02,         /*bNumEndpoints*/
    0x03,         /*bInterfaceClass: HID*/
    0x01,         /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
    0x01,         /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
    0x00,            /*iInterface: Index of string descriptor*/
    /******************** Descriptor of Joystick Mouse HID ********************/
    /* 50 */
    0x09,         /*bLength: HID Descriptor size*/
    HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
    0x00,         /*bcdHID: HID Class Spec release number*/
    0x01,
    0x00,         /*bCountryCode: Hardware target country*/
    0x01,         /*bNumDescriptors: Number of HID class descriptors to follow*/
    0x22,         /*bDescriptorType*/
    KEYBOARD_SIZ_REPORT_DESC,/*wItemLength: Total length of Report descriptor*/
    0x00,
    /******************** Descriptor of Joystick Mouse endpoint ********************/
    /* 59 */
    0x07,          /*bLength: Endpoint Descriptor size*/
    USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/
    0x83,          /*bEndpointAddress: Endpoint Address (IN)*/
    0x03,          /*bmAttributes: Interrupt endpoint*/
    0x20,     /*wMaxPacketSize: 4 Byte max */
    0x00,
    0x01,          /*bInterval: Polling Interval (32 ms)*/
    /******************** Descriptor of  endpoint ********************/
    /* 27 */
    0x07,          /*bLength: Endpoint Descriptor size*/
    USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:*/
    0x03,          /*bEndpointAddress: Endpoint Address (OUT)*/
    0x03,          /*bmAttributes: Interrupt endpoint*/
    0x20,    /*wMaxPacketSize: 8 Byte max */
    0x00,
    0x01,          /*bInterval: Polling Interval (8 ms)*/

  }
  ; /* ConfigDescriptor */
const u8 ReportDescriptor[SIZ_REPORT_DESC] =
  {
    0x05, 0xFF,                    // USAGE_PAGE(User define) Device Use=USAGE_PAGE*255+USAGE=0xff*255+USAGE
    0x09, 0x30,                    // USAGE(User define)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x05, 0x01,                    // USAGE_PAGE(1)
    0x19, 0x00,                    //   USAGE_MINIMUM(0)
    0x29, 0xFF,                    //   USAGE_MAXIMUM(255)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0xFF,                    //   LOGICAL_MAXIMUM (255)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x95, REC_BUFFER_SIZE,         //   REPORT_COUNT (64)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0x05, 0x02,                    // USAGE_PAGE(2)
    0x19, 0x00,                    //   USAGE_MINIMUM (0)
    0x29, 0xFF,                    //   USAGE_MAXIMUM (255)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0xFF,                    //   LOGICAL_MAXIMUM (255)
    0x95, REC_BUFFER_SIZE,         //   REPORT_COUNT (8)
    0x75, 0x08,              //   REPORT_SIZE (64)
    0x91, 0x02,                    //   OUTPUT (Data,Var,Abs)
    0xc0                           // END_COLLECTION                    // END_COLLECTION
  }; /* ReportDescriptor */
const u8 Keyboard_ReportDescriptor[KEYBOARD_SIZ_REPORT_DESC] =
  {
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x06, // USAGE (Keyboard)
0xa1, 0x01, // COLLECTION (Application)
0x05, 0x07, //     USAGE_PAGE (Keyboard/Keypad)
0x19, 0xe0, //     USAGE_MINIMUM (Keyboard LeftControl)
0x29, 0xe7, //     USAGE_MAXIMUM (Keyboard Right GUI)
0x15, 0x00, //     LOGICAL_MINIMUM (0)
0x25, 0x01, //     LOGICAL_MAXIMUM (1)
0x95, 0x08, //     REPORT_COUNT (8)
0x75, 0x01, //     REPORT_SIZE (1)
0x81, 0x02, //     INPUT (Data,Var,Abs)
0x95, 0x01, //     REPORT_COUNT (1)
0x75, 0x08, //     REPORT_SIZE (8)   
0x81, 0x03, //     INPUT (Cnst,Var,Abs)
0x95, 0x06, //   REPORT_COUNT (6)
0x75, 0x08, //   REPORT_SIZE (8)
0x25, 0xFF, //   LOGICAL_MAXIMUM (255)
0x19, 0x00, //   USAGE_MINIMUM (Reserved (no event indicated))
0x29, 0x65, //   USAGE_MAXIMUM (Keyboard Application)
0x81, 0x00, //     INPUT (Data,Ary,Abs)
0x15, 0x00, //     LOGICAL_MINIMUM (0)
0x25, 0x01, //     LOGICAL_MAXIMUM (1)
0x95, 0x02, //   REPORT_COUNT (2)
0x75, 0x01, //   REPORT_SIZE (1)
0x05, 0x08, //   USAGE_PAGE (LEDs)
0x19, 0x01, //   USAGE_MINIMUM (Num Lock)
0x29, 0x02, //   USAGE_MAXIMUM (Caps Lock)
0x91, 0x02, //   OUTPUT (Data,Var,Abs)
0x95, 0x01, //   REPORT_COUNT (1)
0x75, 0x06, //   REPORT_SIZE (6)
0x91, 0x03, //   OUTPUT (Cnst,Var,Abs)
0xc0        // END_COLLECTION
  }; /* Keyboard_ReportDescriptor */
/* USB String Descriptors (optional) */
const u8 StringLangID[SIZ_STRING_LANGID] =
  {
    SIZ_STRING_LANGID,
    USB_STRING_DESCRIPTOR_TYPE,
    0x09,
    0x04
  }
  ; /* LangID = 0x0409: U.S. English */

复位初始代码如下:
void USB_Reader_Reset(void)
{
  /* Set USB_Reader_DEVICE as not configured */
  pInformation->Current_Configuration = 0;
  pInformation->Current_Interface = 0;/*the default Interface*/
  SetBTABLE(BTABLE_ADDRESS);
  /* Initialize Endpoint 0 */
  SetEPType(ENDP0, EP_CONTROL);
  SetEPTxStatus(ENDP0, EP_TX_STALL);
  SetEPRxAddr(ENDP0, ENDP0_RXADDR);
  SetEPTxAddr(ENDP0, ENDP0_TXADDR);
  Clear_Status_Out(ENDP0);
  SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
  SetEPRxValid(ENDP0);
  /* Initialize Endpoint 1 */
  SetEPType(ENDP1, EP_INTERRUPT);
  SetEPTxAddr(ENDP1, ENDP1_TXADDR);
  SetEPTxCount(ENDP1, REC_BUFFER_SIZE);
  SetEPRxStatus(ENDP1, EP_RX_DIS);
  SetEPTxStatus(ENDP1, EP_TX_NAK);
  /* Initialize Endpoint 1 */
// SetEPType(ENDP1, EP_INTERRUPT);
  SetEPRxAddr(ENDP1, ENDP1_RXADDR);
  SetEPRxCount(ENDP1, REC_BUFFER_SIZE);
// SetEPTxStatus(ENDP1, EP_TX_DIS);
  SetEPRxStatus(ENDP1, EP_RX_VALID);
  // Initialize Endpoint 3
  SetEPType(ENDP3, EP_INTERRUPT);
  SetEPTxAddr(ENDP3, ENDP3_TXADDR);
  SetEPTxCount(ENDP3, 0x20);
  SetEPRxStatus(ENDP3, EP_RX_DIS);
  SetEPTxStatus(ENDP3, EP_TX_NAK);
  SetEPRxAddr(ENDP3, ENDP3_RXADDR);
  SetEPRxCount(ENDP3, 0x20);
  SetEPRxStatus(ENDP3, EP_RX_VALID);
  /* Set this device to response on default address */
  SetDeviceAddress(0);
}

键盘底层发送函数是这样的:
void USB_NumKey_SendMsg(u8 buffer[],u8 len)
{
u8 USB_Buffer[REC_BUFFER_SIZE];
u8 i;
  
  if(len>REC_BUFFER_SIZE) len=REC_BUFFER_SIZE;
  for(i=0;i<len;i++)
  {
    USB_Buffer=  buffer;
  }
  for(i=len;i<0x20;i++)
  {
    USB_Buffer=  0;
  }
  /*copy buffer in ENDP1 Tx Packet Memory Area*/
  UserToPMABufferCopy(USB_Buffer, GetEPTxAddr(ENDP3), 0x20);
  SetEPTxCount(ENDP3, 0x08);
  /* enable endpoint for transmission */
  SetEPTxValid(ENDP3);
}
键码发送函数,如下:
/*******************************************************************************
* Function Name  : Sent_Key_Code
* Description    : 发送键码
* Input          : buffer:键码缓存
*       Len:缓存长度
* Output         : None.
* Return         : None.
*******************************************************************************/
void Sent_Key_Code(u8 *buffer,u8 len)
{
u8 i;
u32 iTemp;
u8 keycode[12];
u8 InBuffer[32];

iTemp = 0;
for(i=0;i<len;i++)
  iTemp = (iTemp<<8)|buffer;    //0x2C9AF666
   keycode[0] =  iTemp/1000000000; //最高位
   keycode[1] = (iTemp%1000000000)/100000000;
   keycode[2] =  (iTemp%100000000)/10000000;
   keycode[3] =   (iTemp%10000000)/1000000;
   keycode[4] =    (iTemp%1000000)/100000;
   keycode[5] =     (iTemp%100000)/10000;
   keycode[6] =      (iTemp%10000)/1000;
   keycode[7] =      (iTemp%1000)/100;
   keycode[8] =       (iTemp%100)/10;
   keycode[9] =         (iTemp%10)/1;
for(i=0;i<10;i++)
  if(keycode==0)
   keycode = 0x62; //0x62为0的键码值
  else
   keycode = keycode + 0x58; //0x59为1的键码值
   
  //按键缓存第一字节为控制码,这里赋值为0
  //按键缓存第二字节为保留,
  for(i=0;i<8;i++)
   InBuffer = 0;
  for(i=2;i<8;i++)
   InBuffer = keycode[i-2];   //卡号的前6字节,已转换为10进制
  USB_NumKey_SendMsg(InBuffer,8);    //发送键码值,
   
}

请各位高手帮忙解答,谢谢.
沙发
everbright|  楼主 | 2012-1-5 13:51 | 只看该作者
香版主,放假了吗?呵呵。帮忙分析一下呗

使用特权

评论回复
板凳
香水城| | 2012-1-5 14:03 | 只看该作者
不好意思,我没有时间看你的程序。

你看看USB线路上是否有数据传输?是否有键盘设备的IN Token?

使用特权

评论回复
地板
everbright|  楼主 | 2012-1-5 21:01 | 只看该作者
键盘设别到了,IN Token当然也有.但是我通过端点3向计算机发送键码,计算机收不到.发送键码的程序是正确的.如果不是复合设备,我用端点3也能发出去.现在复合设备不知道那里不正确

使用特权

评论回复
5
heshunyi| | 2012-1-5 21:20 | 只看该作者
楼主,问题解决了吗?
推荐个地方,这里经常有高手出没,也许能帮你解决问题。
http://www.cogoask.com/?=3

使用特权

评论回复
6
everbright|  楼主 | 2012-1-5 23:47 | 只看该作者
本帖最后由 everbright 于 2012-1-10 20:27 编辑

怎么没人来help一下,有人用stm32做两个hid复合设备的吗?

有源码可供参考一下,也可以。谢谢
版主呀,有没有参考的东西来做?

使用特权

评论回复
7
z_zt| | 2012-6-14 17:03 | 只看该作者
楼主问题解决了吗?我也准备要入手这样的USB复合设备,如果问题解决了能否分享下?先谢过了。

使用特权

评论回复
8
秋天落叶| | 2012-6-14 17:06 | 只看该作者
估计一般人都没时间看LZ的程序,太长了

使用特权

评论回复
9
figo20042005| | 2012-6-14 20:17 | 只看该作者
楼主你的代码很长,建议你一步步查,把整个过程打印出来,用串口助手查看哪一步信息有问题

使用特权

评论回复
10
恋子炎| | 2013-7-9 15:59 | 只看该作者
这个情况普遍是描述符的问题,多排查吧 !

使用特权

评论回复
11
trumpxp| | 2013-7-9 18:36 | 只看该作者
程序太长了    楼主   你仔细查一查     帮你顶一个

使用特权

评论回复
12
feicien| | 2017-10-19 11:13 | 只看该作者
楼主解决了吗

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

21

主题

107

帖子

3

粉丝