usb键盘和commonhid合体问题

xheshui   2010-8-5 13:36 楼主
2者都是hid 类的,如果想把他们做在一起,应该如何实现呢?
按下面的配置描述可以识别成键盘,也没有报错,但是如何启用Alternate setting1呢?

const u8 Joystick_ConfigDescriptor[JOYSTICK_SIZ_CONFIG_DESC] =
  {
/*offset  0*/  
//以下为配置描述符
0x09,                              /* bLength: Configuation Descriptor size */
USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
JOYSTICK_SIZ_CONFIG_DESC,          /* wTotalLength: Bytes returned ;2字节*/
0x00,
0x01,                              /*bNumInterfaces: 1 interface;接口数量*/
0x01,                              /*bConfigurationValue: Configuration value*/
0x00,                              /*iConfiguration: Index of string descriptor describing the configuration*/
0xC0,                              /*bmAttributes: self powered */
0x32,                              /*MaxPower 100 mA: this current is used for detecting Vbus*/

  //以下为接口描述符1
/************** Descriptor of Joystick Mouse interface ****************/
/*offset  9 */
0x09,         /*bLength: Interface Descriptor size*/
USB_INTERFACE_DESCRIPTOR_TYPE,/*bDescriptorType: Interface descriptor type接口描述类型*/
0x00,         /*bInterfaceNumber: Number of Interface*/
0x00,         /*bAlternateSetting: Alternate setting 可选设置的索引值。xx1*/
0x02,         /*bNumEndpoints*/
0x03,         /*bInterfaceClass: HID*/
0x00,         /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
0x01,         /*bInterfaceProtocol : 键盘 0=none, 1=keyboard, 2=mouse*/
0,            /*iInterface: Index of string descriptor*/

/******************** Descriptor of Joystick Mouse HID ********************/
/*offset  18 */
0x09,         /*bLength: HID Descriptor size*/
HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID 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*/
JOYSTICK_SIZ_REPORT_DESC,/*wItemLength: Total length of Report descriptor*/
0x00,

/******************** Descriptor of Joystick Mouse endpoint ********************/
/*offset  27 */
0x07,          /*bLength: Endpoint Descriptor size*/
USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:输入端点1描述符*/
0x81,          /*bEndpointAddress: Endpoint Address (IN)*/
0x03,          /*bmAttributes: Interrupt endpoint*/
0x08,          /*wMaxPacketSize: 8 Byte max */
0x00,
0x20,          /*bInterval: Polling Interval (32 ms)*/
/*offset  34 */
0x07,          /*bLength: Endpoint Descriptor size*/
USB_ENDPOINT_DESCRIPTOR_TYPE, /*bDescriptorType:输出端但1描述符*/
0x01,          /*bEndpointAddress: Endpoint Address (OUT)*/
0x03,          /*bmAttributes: Interrupt endpoint*/
0x08,          /*wMaxPacketSize: 8 Byte max */
0x00,
0x20,          /*bInterval: Polling Interval (32 ms)*/
      //以下为接口描述符2
         /************** Descriptor of Custom HID interface ****************/
/*offset  41 */
            0x09,         /* bLength: Interface Descriptor size */
            USB_INTERFACE_DESCRIPTOR_TYPE,/* bDescriptorType: Interface descriptor type接口描述类型 */
            0x00,         /* bInterfaceNumber: Number of Interface */
            0x01,         /* 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 Custom HID HID ********************/
/*offset  50 */
            0x09,                           /* bLength: HID Descriptor size */
            HID_DESCRIPTOR_TYPE,            /* bDescriptorType: HID HID描述类型*/
            0x10,                           /* bcdHID: HID Class Spec release number */
            0x01,
            0x00,                           /* bCountryCode: Hardware target country */
            0x01,                           /* bNumDescriptors: Number of HID class descriptors to follow */
            0x22,                           /* bDescriptorType */
            CUSTOMHID_SIZ_REPORT_DESC,      /* wItemLength: Total length of Report descriptor */
            0x00,
            /******************** Descriptor of Custom HID endpoints ******************/
/*offset  59 */
            0x07,                           /* bLength: Endpoint Descriptor size */
            USB_ENDPOINT_DESCRIPTOR_TYPE,   /* bDescriptorType: 端点描述类型*/        
            0x81,                           /* bEndpointAddress: Endpoint Address (IN) */
            0x03,                           /* bmAttributes: Interrupt endpoint */
            0x02,                           /* wMaxPacketSize: 2 Bytes max */
            0x00,
            0x20,                           /* bInterval: Polling Interval (32 ms) */
/* offset  59+7=66 */               
            0x07,                            /* bLength: Endpoint Descriptor size */
            USB_ENDPOINT_DESCRIPTOR_TYPE,    /* bDescriptorType: Endpoint descriptor type */
            0x01,                            /* bEndpointAddress: Endpoint Address (OUT) */
            0x03,                            /* bmAttributes: Interrupt endpoint */
            0x02,                            /* wMaxPacketSize: 2 Bytes max  */
            0x00,
            0x20,                            /* bInterval: Polling Interval (20 ms) */     
/* offset  66+7=73 */

回复评论 (16)

                                 如果是多个Interface,在MS-Windows下会识别为复合设备(Composite Device),即可以看到不止一个设备。
点赞  2010-8-5 13:47
那是不是要多个interface呢?
我现在的设置是一个interface ,2个Alternate setting
点赞  2010-8-5 13:50
这2种功能(usbkeyboard和usb common hid)不会同时使用,
还需要2个interface吗?
点赞  2010-8-5 13:53
Alternate setting是在Configuration下面的概念,要看主机端的驱动是否支持这个概念。

我不知道Windows的HID驱动,如何选择Alternate setting,你问问其他人吧。
点赞  2010-8-5 14:39
恩,谢谢。
我等等有无其他高手回答。
点赞  2010-8-5 14:45
                                 关注中。。。。。。。
点赞  2010-8-9 11:18
                                 已完成,参考了圈圈的 usb keyboard+ mouse 例子,他提供了2种方式来实现,都很简单。
点赞  2010-8-9 17:15
已完成,参考了圈圈的 usb keyboard+ mouse 例子,他提供了2种方式来实现,都很简单。
介绍一下怎么做的?
点赞  2010-8-9 18:49


可以用多Interface的方式
也可以用多Collection的方式,用Report ID区分
Windows这两种都支持的
点赞  2010-8-9 20:47
楼上的正解。
我本想把圈圈的源码发上来,但怕侵犯圈圈的权利。
我把我修改的部分发上来吧。用的是“多Collection的方式,用Report ID区分”这种。
在custom hid例子上修改的。


const uint8_t CustomHID_ReportDescriptor[CUSTOMHID_SIZ_REPORT_DESC] =
  {   
    0x05, 0x8c,            /* USAGE_PAGE (ST Page)           */                  
    0x09, 0x01,            /* USAGE (Demo Kit)               */   
    0xa1, 0x01,            /* COLLECTION (Application)       */            
    /* 6 */
   
    /* Led 1 */        
    0x85, 0x01,            /*     REPORT_ID (1)                     */
    0x09, 0x01,            /*     USAGE (LED 1)                     */
    0x15, 0x00,            /*     LOGICAL_MINIMUM (0)        */         
    0x25, 0x01,            /*     LOGICAL_MAXIMUM (1)        */           
    0x75, 0x08,            /*     REPORT_SIZE (8)            */        
    0x95, 0x01,            /*     REPORT_COUNT (1)           */    //一个 字节   
    0xB1, 0x82,             /*    FEATURE (Data,Var,Abs,Vol) */     

    0x85, 0x01,            /*     REPORT_ID (1)              */    //上面是定义,下面使用?
    0x09, 0x01,            /*     USAGE (LED 1)              */
    0x91, 0x82,            /*     OUTPUT (Data,Var,Abs,Vol)  */   //PC->dev
    /* 26 */
   
    /* Led 2 */
    0x85, 0x02,            /*     REPORT_ID 2                     */
    0x09, 0x02,            /*     USAGE (LED 2)                     */
    0x15, 0x00,            /*     LOGICAL_MINIMUM (0)        */         
    0x25, 0x01,            /*     LOGICAL_MAXIMUM (1)        */           
    0x75, 0x08,            /*     REPORT_SIZE (8)            */        
    0x95, 0x01,            /*     REPORT_COUNT (1)           */      
    0xB1, 0x82,             /*    FEATURE (Data,Var,Abs,Vol) */     

    0x85, 0x02,            /*     REPORT_ID (2)              */
    0x09, 0x02,            /*     USAGE (LED 2)              */
    0x91, 0x82,            /*     OUTPUT (Data,Var,Abs,Vol)  */
    /* 46 */
   
    /* Led 3 */        
    0x85, 0x03,            /*     REPORT_ID (3)                     */
    0x09, 0x03,            /*     USAGE (LED 3)                     */
    0x15, 0x00,            /*     LOGICAL_MINIMUM (0)        */         
    0x25, 0x01,            /*     LOGICAL_MAXIMUM (1)        */           
    0x75, 0x08,            /*     REPORT_SIZE (8)            */        
    0x95, 0x01,            /*     REPORT_COUNT (1)           */      
    0xB1, 0x82,             /*    FEATURE (Data,Var,Abs,Vol) */     

    0x85, 0x03,            /*     REPORT_ID (3)              */
    0x09, 0x03,            /*     USAGE (LED 3)              */
    0x91, 0x82,            /*     OUTPUT (Data,Var,Abs,Vol)  */
    /* 66 */
   
    /* Led 4 */
    0x85, 0x04,            /*     REPORT_ID 4)                     */
    0x09, 0x04,            /*     USAGE (LED 4)                     */
    0x15, 0x00,            /*     LOGICAL_MINIMUM (0)        */         
    0x25, 0x01,            /*     LOGICAL_MAXIMUM (1)        */           
    0x75, 0x08,            /*     REPORT_SIZE (8)            */        
    0x95, 0x01,            /*     REPORT_COUNT (1)           */      
    0xB1, 0x82,            /*     FEATURE (Data,Var,Abs,Vol) */     

    0x85, 0x04,            /*     REPORT_ID (4)              */
    0x09, 0x04,            /*     USAGE (LED 4)              */
    0x91, 0x82,            /*     OUTPUT (Data,Var,Abs,Vol)  */
    /* 86 */
   
    /* key Push Button */  
    0x85, 0x05,            /*     REPORT_ID (5)              */
    0x09, 0x05,            /*     USAGE (Push Button)        */      
    0x15, 0x00,            /*     LOGICAL_MINIMUM (0)        */      
    0x25, 0x01,            /*     LOGICAL_MAXIMUM (1)        */      
    0x75, 0x01,            /*     REPORT_SIZE (1)            */  
    0x81, 0x82,            /*     INPUT (Data,Var,Abs,Vol)   */   //输出1位按键信号
   
    0x09, 0x05,            /*     USAGE (Push Button)        */               
    0x75, 0x01,            /*     REPORT_SIZE (1)            */           
    0xb1, 0x82,            /*     FEATURE (Data,Var,Abs,Vol) */  //上面定义,下面使用,输出到pc1位有效信号
         
    0x75, 0x07,            /*     REPORT_SIZE (7)            */           
    0x81, 0x83,            /*     INPUT (Cnst,Var,Abs,Vol)   */    //输出7位无效信号,凑满1字节                 
    0x85, 0x05,            /*     REPORT_ID (5)              */         
                    
    0x75, 0x07,            /*     REPORT_SIZE (7)            */           
    0xb1, 0x83,            /*     FEATURE (Cnst,Var,Abs,Vol) */                     
    /* 114 */

    /* Tamper Push Button */  
    0x85, 0x06,            /*     REPORT_ID (6)              */
    0x09, 0x06,            /*     USAGE (Tamper Push Button) */      
    0x15, 0x00,            /*     LOGICAL_MINIMUM (0)        */      
    0x25, 0x01,            /*     LOGICAL_MAXIMUM (1)        */      
    0x75, 0x01,            /*     REPORT_SIZE (1)            */  
    0x81, 0x82,            /*     INPUT (Data,Var,Abs,Vol)   */   
   
    0x09, 0x06,            /*     USAGE (Tamper Push Button) */               
    0x75, 0x01,            /*     REPORT_SIZE (1)            */           
    0xb1, 0x82,            /*     FEATURE (Data,Var,Abs,Vol) */  
         
    0x75, 0x07,            /*     REPORT_SIZE (7)            */           
    0x81, 0x83,            /*     INPUT (Cnst,Var,Abs,Vol)   */                    
    0x85, 0x06,            /*     REPORT_ID (6)              */         
                    
    0x75, 0x07,            /*     REPORT_SIZE (7)            */           
    0xb1, 0x83,            /*     FEATURE (Cnst,Var,Abs,Vol) */  
    /* 142 */
   
    /* ADC IN */
    0x85, 0x07,            /*     REPORT_ID (7)              */         
    0x09, 0x07,            /*     USAGE (ADC IN)             */         
    0x15, 0x00,            /*     LOGICAL_MINIMUM (0)        */               
    0x26, 0xff, 0x00,      /*     LOGICAL_MAXIMUM (255)      */                 
    0x75, 0x08,            /*     REPORT_SIZE (8)            */           
    0x81, 0x82,            /*     INPUT (Data,Var,Abs,Vol)   */                    
    0x85, 0x07,            /*     REPORT_ID (7)              */                 
    0x09, 0x07,            /*     USAGE (ADC in)             */                     
    0xb1, 0x82,            /*     FEATURE (Data,Var,Abs,Vol) */                                 
    /* 161 */

    0xc0,                   /*     END_COLLECTION                     */
//--------按键部分---------------------------------------------------------
/* offset 162  */
     0x05, 0x01, // USAGE_PAGE (Generic Desktop)
     0x09, 0x06, // USAGE (Keyboard)
     0xa1, 0x01, // COLLECTION (Application)
     0x85, 0x08,            /*     REPORT_ID (8)              */         

/* offset 170  */   
     0x05, 0x07, //     USAGE_PAGE (Keyboard/Keypad)
      
     0x19, 0xe0, //     USAGE_MINIMUM (Keyboard LeftControl) LCtrl,LShift,LAlt,LGUI,RCtrl,RShift,RAlt,RGUI
     0x29, 0xe7, //     USAGE_MAXIMUM (Keyboard Right GUI)//总共是8个按键0xe0~0xe7
     0x15, 0x00, //     LOGICAL_MINIMUM (0)
     0x25, 0x01, //     LOGICAL_MAXIMUM (1)
/* offset 180  */     
     0x95, 0x08, //     REPORT_COUNT (8)      
     0x75, 0x01, //     REPORT_SIZE (1)     //单位为bit
     0x81, 0x02, //     INPUT (Data,Var,Abs)    //to PC 一个字节(1st)控制键部分
     
     0x95, 0x01, //     REPORT_COUNT (1)
     0x75, 0x08, //     REPORT_SIZE (8)
/* offset 190  */
     
     0x81, 0x03, //     INPUT (Cnst,Var,Abs)    //to pc 一个字节(2nd)
     
     0x95, 0x06, //   REPORT_COUNT (6)         //to pc 6个字节(3rd~8th)
     0x75, 0x08, //   REPORT_SIZE (8)
     0x25, 0xFF, //   LOGICAL_MAXIMUM (255)
     0x19, 0x00, //   USAGE_MINIMUM (Reserved (no event indicated))
/* offset 200  */     
     0x29, 0x65, //   USAGE_MAXIMUM (Keyboard Application)     
     0x81, 0x00, //     INPUT (Data,Ary,Abs)
     
     0x25, 0x01, //   LOGICAL_MAXIMUM (1)//大小写等led部分,需要
     0x95, 0x02, //   REPORT_COUNT (2)
     0x75, 0x01, //   REPORT_SIZE (1)
/* offset 210  */     
     0x05, 0x08, //   USAGE_PAGE (LEDs)
     
     0x19, 0x01, //   USAGE_MINIMUM (Num Lock)
     0x29, 0x02, //   USAGE_MAXIMUM (Caps Lock)
     0x91, 0x02, //   OUTPUT (Data,Var,Abs) //2位有效信号led
     0x95, 0x01, //   REPORT_COUNT (1)
/* offset 220  */     
     0x75, 0x06, //   REPORT_SIZE (6)     
     0x91, 0x03, //   OUTPUT (Cnst,Var,Abs)  //剩下的6位,补足1字节
     
     0xc0        // END_COLLECTION   
/* offset 225  */
      
  }; /* CustomHID_ReportDescriptor */
点赞  2010-8-9 20:58
const uint8_t CustomHID_ConfigDescriptor[CUSTOMHID_SIZ_CONFIG_DESC] =
  {
    0x09, /* bLength: Configuation Descriptor size */
    USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
    CUSTOMHID_SIZ_CONFIG_DESC,
    /* wTotalLength: Bytes returned */
    0x00,
    0x01,         /* bNumInterfaces: 1 interface */
    0x01,         /* bConfigurationValue: Configuration value */
    0x00,         /* iConfiguration: Index of string descriptor describing
                                 the configuration*/
    0xC0,         /* bmAttributes: Bus powered */
    0x32,         /* MaxPower 100 mA: this current is used for detecting Vbus */

    /************** Descriptor of Custom HID interface ****************/
    /* 09 */
    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 Custom HID HID ********************/
    /* 18 */
    0x09,         /* bLength: HID Descriptor size */
    HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */
    0x10,         /* bcdHID: HID Class Spec release number */
    0x01,
    0x00,         /* bCountryCode: Hardware target country */
    0x01,         /* bNumDescriptors: Number of HID class descriptors to follow */
    0x22,         /* bDescriptorType */
    CUSTOMHID_SIZ_REPORT_DESC,/* wItemLength: Total length of Report descriptor */
    0x00,
    /******************** Descriptor of Custom HID endpoints ******************/
    /* 27 */
    0x07,          /* bLength: Endpoint Descriptor size */
    USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */

    0x81,          /* bEndpointAddress: Endpoint Address (IN) */
    0x03,          /* bmAttributes: Interrupt endpoint */
    0x10,          /* wMaxPacketSize: 16 Bytes max */
    0x00,
    0x20,          /* bInterval: Polling Interval (32 ms) */
    /* 34 */
           
    0x07,        /* bLength: Endpoint Descriptor size */
    USB_ENDPOINT_DESCRIPTOR_TYPE,        /* bDescriptorType: */
                        /*        Endpoint descriptor type */
    0x01,        /* bEndpointAddress: */
                        /*        Endpoint Address (OUT) */
    0x03,        /* bmAttributes: Interrupt endpoint */
    0x10,        /* wMaxPacketSize: 16 Bytes max  */
    0x00,
    0x20,        /* bInterval: Polling Interval (20 ms) */
    /* 41 */
  }
  ; /* CustomHID_ConfigDescriptor */
点赞  2010-8-9 21:16
                                 网上还有一个st usb 键盘的例子,结合起来看,就可以了。
点赞  2010-8-9 21:18
谢谢楼主分享。

其实我在5楼就说了“我不知道Windows的HID驱动,如何选择Alternate setting,你问问其他人吧。”
然后你在6楼说:“我等等有无其他高手回答。”
最后在8楼就说:“已完成,参考了圈圈的 usb keyboard+ mouse 例子,他提供了2种方式来实现,都很简单。”

按照这个思路,我还一直以为你实现了Alternate setting,
点赞  2010-8-9 21:29
henry_wu001

网上还有一个st usb 键盘的例子

圈圈的 usb keyboard+ mouse
可否给个连接啊,我怎么没有搜索到,多谢
点赞  2010-8-10 09:29
额,我昨天以为你一定要找2个Alternate setting的方案。。。。。


不然昨天就可以告诉你,可以用2个interface或者1个interface2个report ID。但是MS不是所有的HID设备都可以共享一个interface然后用reportID来区分数据的,对于某些特定的HID设备,微软的驱动MS需要一个单独的interface
点赞  2010-8-10 09:59
                                 谢谢各位。谢谢。
点赞  2010-8-10 10:17
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复