3--STM32 USB-三个HID-interface 复合(组合)设备的代码实现-基于固件库(原创)

一、概论:

在STM32_USB-FS-Device_Lib_V4.1.0的Custom_HID工程基础上进行修改;

开发一款设备,有三个HID接口,mouse+pen+自定义HID

其中:0_HID 是mouse(端点1 IN);1_HID 是pen(端点2 IN);2_HID 是自定义(端点3 IN-OUT)。

在设备管理器和bus hound可以看到如下:

 

 二、修改步骤:

 1、修改设备$$配置描述符


/* USB Standard Device Descriptor */
const uint8_t CustomHID_DeviceDescriptor[CUSTOMHID_SIZ_DEVICE_DESC] =
  {
    0x12,                       /*bLength */
    USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/
    0x10,                       /*bcdUSB */
    0x01,
    0x00,                       /*bDeviceClass*/
    0x00,                       /*bDeviceSubClass*/
    0x00,                       /*bDeviceProtocol*/
    0x40,                       /*bMaxPacketSize:64 bytes*/
    LOBYTE(USBD_VID),           /*idVendor*/
    HIBYTE(USBD_VID),           /*idVendor*/
    LOBYTE(USBD_PID),           /*idVendor*/
    HIBYTE(USBD_PID),           /*idVendor*/
    0x00,                       /*bcdDevice rel. 00.00*/
    0x00,
    USBD_IDX_MFC_STR,           /*Index of manufacturer  string*/
    USBD_IDX_PRODUCT_STR,       /*Index of product string*/
    USBD_IDX_SERIAL_STR,        /*Index of serial number string*/
    USBD_CFG_MAX_NUM            /*bNumConfigurations*/
  }; /* CustomHID_DeviceDescriptor */

/* USB Configuration Descriptor */
/*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
const uint8_t CustomHID_ConfigDescriptor[CUSTOMHID_SIZ_CONFIG_DESC] =
  {
    /************** Configuration Descriptor  Bus Powered, 100 mA ****************/
    0x09, /* bLength: Configuration Descriptor size */
    USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
    0x5b,         /* wTotalLength: Bytes returned */
    0x00,
    0x03,         /* bNumInterfaces: 1 interface *///3个HID接口  
    0x01,         /* bConfigurationValue: Configuration value */
    0x00,         /* iConfiguration: Index of string descriptor describing the configuration*/
    0xA0,         /* bmAttributes: Self powered:C0 Bus Powered, Remote Wakeup:A0 */
    0x32,         /* MaxPower 100 mA: this current is used for detecting Vbus */

// 0/0 HID 1 Endpoint IN of 端点1
    /************** Descriptor of 0/0 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 */
    0x01,         /* bNumEndpoints */
    0x03,         /* bInterfaceClass: HID */
    0x01,         /* bInterfaceSubClass : 1=BOOT, 0=no boot */
    0x02,         /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
    0x00,         /* iInterface: Index of string descriptor */
    /******************** Descriptor of 0/0 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 */
    sizeof(mouse_ReportDescriptor)&0xFF,         /* wItemLength: Total length of Report descriptor :177 bytes*/
    (sizeof(mouse_ReportDescriptor)>>8)&0xFF,
    /******************** Descriptor of 0/0 HID endpoints :1IN ******************/
    /* 27 */
    0x07,          /* bLength: Endpoint Descriptor size */
    USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */
    0x81,          /* bEndpointAddress: Endpoint Address (IN) */
    0x03,          /* bmAttributes: Interrupt endpoint */
    0x08,          /* wMaxPacketSize: 8 Bytes max */
    0x00,
    0x04,          /* bInterval: Polling Interval (4 ms) */
    
// 1/0 HID 1 Endpoint IN of 端点2
    /************** Descriptor of 1/0 HID interface ****************/
    /* 34 */
    0x09,         /* bLength: Interface Descriptor size */
    USB_INTERFACE_DESCRIPTOR_TYPE,/* bDescriptorType: Interface descriptor type */
    0x01,         /* bInterfaceNumber: Number of Interface */
    0x00,         /* bAlternateSetting: Alternate setting */
    0x01,         /* bNumEndpoints */
    0x03,         /* bInterfaceClass: HID */
    0x01,         /* bInterfaceSubClass : 1=BOOT, 0=no boot */
    0x02,         /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
    0x00,         /* iInterface: Index of string descriptor */
    /******************** Descriptor of 1/0 HID ********************/
    /* 43 */
    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 */
    sizeof(pen_ReportDescriptor)&0xFF,         /* wItemLength: Total length of Report descriptor :237 bytes*/
    (sizeof(pen_ReportDescriptor)>>8)&0xFF,
    /******************** Descriptor of 1/0 HID endpoints :2 IN ******************/
    /* 52 */
    0x07,          /* bLength: Endpoint Descriptor size */
    USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */
    0x82,          /* bEndpointAddress: Endpoint Address (IN) */
    0x03,          /* bmAttributes: Interrupt endpoint */
    0x40,          /* wMaxPacketSize: 64 Bytes max */
    0x00,
    0x03,          /* bInterval: Polling Interval (3 ms) */  
    
// 2/0 HID 1 Endpoint IN /1 Endpoint OUT of 端点3
    /************** Descriptor of 2/0 HID interface ****************/
    /* 59 */
    0x09,         /* bLength: Interface Descriptor size */
    USB_INTERFACE_DESCRIPTOR_TYPE,/* bDescriptorType: Interface descriptor type */
    0x02,         /* 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 */
    0x00,         /* iInterface: Index of string descriptor */
    /******************** Descriptor of 2/0 HID ********************/
    /* 68 */
    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 */
    sizeof(HID_driver_ReportDescriptor)&0xFF,         /* wItemLength: Total length of Report descriptor :36 bytes*/
    (sizeof(HID_driver_ReportDescriptor)>>8)&0xFF,
    /******************** Descriptor of 2/0 HID endpoints :3 In, Interrupt, 3 ms******************/
    /* 77 */
    0x07,          /* bLength: Endpoint Descriptor size */
    USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */
    0x83,          /* bEndpointAddress: Endpoint Address (IN) */
    0x03,          /* bmAttributes: Interrupt endpoint */
    0x0A,          /* wMaxPacketSize: 10 Bytes max */
    0x00,
    0x03,          /* bInterval: Polling Interval (3 ms) */  
    /******************** Descriptor of 2/0 HID endpoints :3 Out, Interrupt, 3 ms******************/
    /* 84 */
    0x07,          /* bLength: Endpoint Descriptor size */
    USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */
    0x03,          /* bEndpointAddress: Endpoint Address (out) */
    0x03,          /* bmAttributes: Interrupt endpoint */
    0x0A,          /* wMaxPacketSize: 10 Bytes max */
    0x00,
    0x0A,          /* bInterval: Polling Interval (10 ms) */ 
  }; /* CustomHID_ConfigDescriptor */
View Code

2、分别修改报告描述符

  1 /* 以下分别是三个报告描述符 */
  2 /*Interface 0 HID Report Descriptor Mouse*/    
  3 const uint8_t mouse_ReportDescriptor[mouse_SIZ_REPORT_DESC] =
  4 {                    
  5 /*******************************mouse 1******************************************/        
  6     0x05, 0x01,/*USAGE_PAGE (Generic Desktop)*/                       
  7     0x09, 0x02,/*USAGE (Mouse)*/    
  8     0xA1, 0x01,/*COLLECTION (Application)*/   
  9 
 10         0x85, 0x09,//Report ID (9)
 11         0x09, 0x01,//Usage (Pointer)
 12         0xA1, 0x00,//Collection (Physical)
 13 
 14             0x05, 0x09,//Usage Page (Button)
 15             0x19, 0x01,//USAGE_MINIMUM(1)    
 16             0x29, 0x03,//USAGE_MAXIMUM(3)
 17             0x15, 0x00,//LOGICAL_MINIMUM (0)
 18             0x25, 0x01,//LOGICAL_MAXIMUM (1)
 19             0x75, 0x01,//REPORT_SIZE (1) 
 20             0x95, 0x03,//Report Count (3) 
 21             0x81, 0x02,//Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
 22             
 23             0x95, 0x05,//Report Count (5)
 24             0x81, 0x01,//Input (Cnst,Ary,Abs)
 25             
 26             0x05, 0x01,//Usage Page (Generic Desktop)
 27             0x09, 0x30,//Usage (X)
 28             0x09, 0x31,//Usage (Y)
 29             0x26, 0xFF,0x7F,//Logical Maximum (32767)
 30             0x95, 0x02,//Report Count (2) 
 31             0x75, 0x10,//Report Size (16)
 32             0x81, 0x02,//Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)        
 33             
 34             0x05, 0x0D,//Usage Page (Digitizer)
 35             0x09, 0x30,//Usage (Tip Pressure)
 36             0x26, 0xFF,0x07,//Logical Maximum (2047)
 37             0x95, 0x01,//Report Count (1)
 38             0x75, 0x10,//Report Size (16)
 39             0x81, 0x02,//Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
 40             
 41         0xC0,//End Collection
 42     0xC0,//End Collection
 43         
 44 /*******************************mouse 2-75******************************************/        
 45     0x05, 0x01,/*USAGE_PAGE (Generic Desktop)*/                       
 46     0x09, 0x02,/*USAGE (Mouse)*/    
 47     0xA1, 0x01,/*COLLECTION (Application)*/   
 48 
 49         0x85, 0x01,//Report ID (1)
 50         0x09, 0x01,//Usage (Pointer)
 51         0xA1, 0x00,//Collection (Physical)
 52 
 53             0x05, 0x09,//Usage Page (Button)
 54             0x19, 0x01,//USAGE_MINIMUM(1)    
 55             0x29, 0x05,//USAGE_MAXIMUM(5)
 56             0x15, 0x00,//LOGICAL_MINIMUM (0)
 57             0x25, 0x01,//LOGICAL_MAXIMUM (1)
 58             0x75, 0x01,//REPORT_SIZE (1) 
 59             0x95, 0x05,//Report Count (5) 
 60             0x81, 0x02,//Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
 61             
 62             0x95, 0x03,//Report Count (3)
 63             0x81, 0x01,//Input (Cnst,Ary,Abs)
 64             
 65             0x05, 0x01,//Usage Page (Generic Desktop)
 66             0x09, 0x30,//Usage (X)
 67             0x09, 0x31,//Usage (Y)
 68             0x95, 0x02,//Report Count (2) 
 69             0x75, 0x10,//Report Size (16)
 70             0x16, 0x00,0x80,//Logical Minimum (-32767)
 71             0x26, 0xFF,0x7F,//Logical Maximum (32767)            
 72             0x81, 0x06,//Input (Data,Var,Rel,NWrp,Lin,Pref,NNul,Bit)
 73 
 74             0x09, 0x38,//Usage (Wheel)
 75             0x15, 0x81,//Logical Minimum (-127)
 76             0x25, 0x7F,//Logical Maximum (127)
 77             0x95, 0x01,//Report Count (1)
 78             0x75, 0x08,//Report Size (8)
 79             0x81, 0x06,//Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
 80             
 81             0x05, 0x0C,//Usage Page (Consumer Devices)
 82             0x0A, 0x38,0x02,//Usage (AC Pan)47)
 83             0x95, 0x01,//Report Count (1)
 84             0x75, 0x08,//Report Size (8)
 85             0x81, 0x06,//Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
 86             
 87         0xC0,//End Collection
 88     0xC0,//End Collection
 89     
 90 /********************************Keyboard-40*******************************************/
 91     0x05, 0x01,/*USAGE_PAGE (Generic Desktop)*/                       
 92     0x09, 0x06,/*USAGE (Keyboard)*/    
 93     0xA1, 0x01,/*COLLECTION (Application)*/   
 94 
 95         0x85, 0x06,//Report ID (6)--------------------------无驱动按键使用此report
 96         0x05, 0x07,//Usage Page (Keyboard/Keypad)
 97         0x19, 0xE0,//USAGE_MINIMUM(Keyboard Left Control)
 98         0x29, 0xE7,//USAGE_MAXIMUM(Keyboard Right GUI)
 99         0x15, 0x00,//LOGICAL_MINIMUM (0)
100         0x25, 0x01,//LOGICAL_MAXIMUM (1)
101         0x75, 0x01,//REPORT_SIZE (1) 
102         0x95, 0x08,//Report Count (8) 
103         0x81, 0x02,//Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
104             
105         0x05, 0x07,//Usage Page (Keyboard/Keypad)
106         0x19, 0x00,//Usage Minimum (Undefined)
107         0x29, 0xFF,//Usage Maximum
108         0x26, 0xFF,0x00,//Logical Maximum (255)
109         0x95, 0x06,//Report Count (6) 
110         0x75, 0x10,//Report Size (8)
111         0x81, 0x00,//Input (Data,Ary,Abs)    
112             
113     0xC0//End Collection    
114 };
115 
116 /*Interface 1 HID Report Descriptor Pen*/
117 const uint8_t pen_ReportDescriptor[pen_SIZ_REPORT_DESC] =
118 { 
119 /*******************************pen 1****x2**************************************/        
120     0x05, 0x0D,/*Usage Page (Digitizer)*/                       
121     0x09, 0x02,/*Usage (Pen)*/    
122     0xA1, 0x01,/*COLLECTION (Application)*/   
123 
124         0x85, 0x07,//Report ID (7)
125         0x09, 0x20,//Usage (Stylus)
126         0xA1, 0x00,//Collection (Physical)
127 
128             0x09, 0x42,//Usage (Tip Switch)
129                         0x09, 0x44,//Usage (Barrel Switch)
130                         0x09, 0x45,//Usage (Eraser)
131             0x15, 0x00,//LOGICAL_MINIMUM (0)
132             0x25, 0x01,//LOGICAL_MAXIMUM (1)
133             0x75, 0x01,//REPORT_SIZE (1) 
134             0x95, 0x03,//Report Count (3) 
135             0x81, 0x02,//Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
136             
137             0x95, 0x02,//Report Count (2)
138             0x81, 0x03,//Input (Cnst,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
139             
140             0x09, 0x32,//Usage (In Range)
141             0x95, 0x01,//Report Count (1)                     
142             0x81, 0x02,//Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
143                         
144             0x95, 0x02,//Report Count (2)
145             0x81, 0x03,//Input (Cnst,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
146 
147             0x95, 0x01,//Report Count (1)
148             0x75, 0x10,//Report Size (16)
149             0x35, 0x00,//Physical Minimum (0)
150                         
151                   0xA4,//Push
152                               0x05, 0x01,//Usage Page (Generic Desktop)
153                               0x09, 0x30,//Usage (X)
154                               0x65, 0x13,//Unit (Eng Lin: Length (in))
155                               0x55, 0x0D,//Unit Exponent (-3)
156                               0x46, 0xC1,0x28,//Physical Maximum (10433)
157                               0x46, 0xC2,0x65,//Logical Maximum (26050)
158                               0x81, 0x02,//Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
159                               0x09, 0x31,//Usage (Y)
160                               0x46, 0x9B,0x18,//Physical Maximum (6299)
161                               0x26, 0x80,0x3E,//Logical Maximum (16000)
162                               0x81, 0x02,//Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)                                                  
163                               0xB4,//Pop
164                               
165                         0x09, 0x30,//Usage (Tip Pressure)
166                         0x45, 0x00,//Physical Maximum (0)
167                         0x26, 0xFF,0x1F,//Logical Maximum (8191)
168                         0x81, 0x42,//Input (Data,Var,Abs,NWrp,Lin,Pref,Null,Bit)
169                         0x09, 0x3D,//Usage (X Tilt)
170                         0x15, 0x81,//Logical Minimum (-127)
171                         0x25, 0x7F,//Logical Maximum (127)
172                         0x95, 0x01,//Report Count (1) 
173                         0x75, 0x08,//Report Size (8)
174                         0x81, 0x02,//Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
175                                 
176                         0x09, 0x3E,//Usage (Y Tilt)
177                         0x15, 0x81,//Logical Minimum (-127)
178                         0x25, 0x7F,//Logical Maximum (127)
179                         0x81, 0x02,//Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)            
180                 0xC0,//End Collection
181     0xC0,//End Collection
182 
183 /*******************************pen 2******************************************/        
184     0x05, 0x0D,/*Usage Page (Digitizer)*/                       
185     0x09, 0x02,/*Usage (Pen)*/    
186     0xA1, 0x01,/*COLLECTION (Application)*/   
187 
188         0x85, 0x08,//Report ID (8)
189         0x09, 0x20,//Usage (Stylus)
190         0xA1, 0x00,//Collection (Physical)
191 
192             0x09, 0x42,//Usage (Tip Switch)
193                         0x09, 0x44,//Usage (Barrel Switch)
194                         0x09, 0x45,//Usage (Eraser)
195             0x15, 0x00,//LOGICAL_MINIMUM (0)
196             0x25, 0x01,//LOGICAL_MAXIMUM (1)
197             0x75, 0x01,//REPORT_SIZE (1) 
198             0x95, 0x03,//Report Count (3) 
199             0x81, 0x02,//Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
200             
201             0x95, 0x02,//Report Count (2)
202             0x81, 0x03,//Input (Cnst,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
203             
204             0x09, 0x32,//Usage (In Range)
205             0x95, 0x01,//Report Count (1)                     
206             0x81, 0x02,//Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
207                         
208             0x95, 0x02,//Report Count (2)
209             0x81, 0x03,//Input (Cnst,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
210 
211             0x95, 0x01,//Report Count (1)
212             0x75, 0x10,//Report Size (16)
213             0x35, 0x00,//Physical Minimum (0)
214                         
215                   0xA4,//Push
216                               0x05, 0x01,//Usage Page (Generic Desktop)
217                               0x09, 0x30,//Usage (X)
218                               0x65, 0x13,//Unit (Eng Lin: Length (in))
219                               0x55, 0x0D,//Unit Exponent (-3)
220                               0x46, 0xC1,0x28,//Physical Maximum (10433)
221                               0x46, 0xC2,0x65,//Logical Maximum (26050)
222                               0x81, 0x02,//Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
223                               0x09, 0x31,//Usage (Y)
224                               0x46, 0x9B,0x18,//Physical Maximum (6299)
225                               0x26, 0x80,0x3E,//Logical Maximum (16000)
226                               0x81, 0x02,//Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)                                                  
227                               0xB4,//Pop
228                               
229                         0x09, 0x30,//Usage (Tip Pressure)
230                         0x45, 0x00,//Physical Maximum (0)
231                         0x26, 0xFF,0x1F,//Logical Maximum (8191)
232                         0x81, 0x42,//Input (Data,Var,Abs,NWrp,Lin,Pref,Null,Bit)
233                         0x09, 0x3D,//Usage (X Tilt)
234                         0x15, 0x81,//Logical Minimum (-127)
235                         0x25, 0x7F,//Logical Maximum (127)
236                         0x95, 0x01,//Report Count (1) 
237                         0x75, 0x08,//Report Size (8)
238                         0x81, 0x02,//Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
239                                 
240                         0x09, 0x3E,//Usage (Y Tilt)
241                         0x15, 0x81,//Logical Minimum (-127)
242                         0x25, 0x7F,//Logical Maximum (127)
243                         0x81, 0x02,//Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)            
244                 0xC0,//End Collection
245     0xC0,//End Collection
246  /*******************************Vendor-Defined 4-23*****************************************/         
247     0x06, 0x03,0xFF,/*Usage Page (Vendor-Defined 4)*/                       
248     0x09, 0x000,/*Usage (Undefined)*/    
249     0xA1, 0x01,/*COLLECTION (Application)*/   
250 
251         0x85, 0x0B,//Report ID (11) 
252         0x15, 0x00,//LOGICAL_MINIMUM (0)
253         0x25, 0xFF,0x00,//LOGICAL_MAXIMUM (255)        
254         0x09, 0x00,//Usage (Undefined)
255         0x75, 0x08,//REPORT_SIZE (8)
256         0x95, 0x3F,//Report Count (63)
257         0x81, 0x02,//Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)            
258     0xC0//End Collection
259 };             
260 /*Interface 2 HID Report Descriptor */        
261 const uint8_t HID_driver_ReportDescriptor[HID_driver_SIZ_REPORT_DESC] =
262 {         
263 /********************************Vendor-Defined 11**36*****************************************/
264     0x06, 0x0A,0xFF,/*Usage Page (Vendor-Defined 11)*/                       
265     0x09, 0x01,/*Usage (Vendor-Defined 1)*/    
266     0xA1, 0x01,/*COLLECTION (Application)*/   
267 
268         0x85, 0x02,//Report ID (2)--------------------------驱动使用此report
269         0x09, 0x02,//Usage (Vendor-Defined 2)
270         0x15, 0x00,//LOGICAL_MINIMUM (0)
271         0x25, 0xFF,0x00,//LOGICAL_MAXIMUM (255)
272         0x75, 0x08,//REPORT_SIZE (8) 
273         0x95, 0x09,//Report Count (9) 
274         0x81, 0x02,//Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
275             
276         0x09, 0x03,//Usage (Vendor-Defined 3)
277         0x75, 0x08,//REPORT_SIZE (8)
278         0x95, 0x07,//Report Count (7)
279         0x15, 0x00,//LOGICAL_MINIMUM (0)
280         0x25, 0xFF,0x00,//LOGICAL_MAXIMUM (255)
281         0x91, 0x02,//Output (Data,Var,Abs,NWrp,Lin,Pref,NNul,NVol,Bit)
282             
283     0xC0,//End Collection
284 }; 
View Code

3、在usb_des.h 文件定义报告描述符的大小及定义reportdescriptor并屏蔽原来的Custom_HID不需要的定义

#define mouse_SIZ_REPORT_DESC                   0x00B1            //0HID 报告描述符大小177BYTE
#define pen_SIZ_REPORT_DESC                     0x00ED             //1HID 报告描述符大小237BYTE
#define HID_driver_SIZ_REPORT_DESC              0x0024             //2HID 报告描述符大小177BYTE
//报告描述符定义
extern const uint8_t mouse_ReportDescriptor[mouse_SIZ_REPORT_DESC];
extern const uint8_t pen_ReportDescriptor[pen_SIZ_REPORT_DESC];
extern const uint8_t HID_driver_ReportDescriptor[HID_driver_SIZ_REPORT_DESC];
View Code

4、重点修改usb_pro.h文件

4.1 新增:ONE_DESCRIPTOR XX_Report_Descriptor及ONE_DESCRIPTOR XX_Hid_Descriptor函数,去除原来Custom_HID的。

/************分别获取3个HID的报告描述符****************/
ONE_DESCRIPTOR mouse_Report_Descriptor =           //用于获得报告描述符
  {
    (uint8_t *)mouse_ReportDescriptor,
    mouse_SIZ_REPORT_DESC
  };
ONE_DESCRIPTOR pen_Report_Descriptor =              
  {
    (uint8_t *)pen_ReportDescriptor,
    pen_SIZ_REPORT_DESC
  };
ONE_DESCRIPTOR HID_driver_Report_Descriptor =       
  {
    (uint8_t *)HID_driver_ReportDescriptor,
    HID_driver_SIZ_REPORT_DESC
  };

/************分别获取3个HID的配置描述符中的HID描述****************/
//mouse_OFF_HID_DESC/pen_OFF_HID_DESC/HID_driver_OFF_HID_DESC
//是HID描述在配置描述符中的偏移量
ONE_DESCRIPTOR mouse_Hid_Descriptor =              
  {
    (uint8_t*)CustomHID_ConfigDescriptor + mouse_OFF_HID_DESC,  
    CUSTOMHID_SIZ_HID_DESC
  };
ONE_DESCRIPTOR pen_Hid_Descriptor =              
  {
    (uint8_t*)CustomHID_ConfigDescriptor + pen_OFF_HID_DESC,
    CUSTOMHID_SIZ_HID_DESC
  };
ONE_DESCRIPTOR HID_driver_Hid_Descriptor =              
  {
    (uint8_t*)CustomHID_ConfigDescriptor + HID_driver_OFF_HID_DESC,
    CUSTOMHID_SIZ_HID_DESC
  };
View Code

4.2 XX_OFF_HID_DESC是HID描述符在usb_des.h文件中配置描述符函数CustomHID_ConfigDescriptor的偏移量

所以在usb_des.h 文件定义:

//ONE_DESCRIPTOR XX_Hid_Descriptor 偏移量定义
#define mouse_OFF_HID_DESC        0x12 //18
#define pen_OFF_HID_DESC        0x28 //43
#define HID_driver_OFF_HID_DESC       0x44 //68

4.3修改void CustomHID_Reset(void)函数中相关端点的定义,

void CustomHID_Reset(void)
{
  /* Set CustomHID_DEVICE as not configured */
  pInformation->Current_Configuration = 0;
  pInformation->Current_Interface = 0;/*the default Interface*/
  
  /* Current Feature initialization */
  pInformation->Current_Feature = CustomHID_ConfigDescriptor[7];
 
  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 IN 8 byte*/
  SetEPType(ENDP1, EP_INTERRUPT);
  SetEPTxAddr(ENDP1, ENDP1_TXADDR);
  SetEPTxCount(ENDP1, 8);
  SetEPTxStatus(ENDP1, EP_TX_NAK);

  /* Initialize Endpoint 2 IN 10 byte*/
  SetEPType(ENDP2, EP_INTERRUPT);
  SetEPTxAddr(ENDP2, ENDP2_TXADDR);
  SetEPTxCount(ENDP2, 10);
  SetEPTxStatus(ENDP2, EP_TX_NAK);  
  
  /* Initialize Endpoint 3 IN 10 byte*/ 
  SetEPType(ENDP3, EP_BULK);                    
  SetEPTxAddr(ENDP3, ENDP3_TXADDR); 
  SetEPTxCount(ENDP3, 10);                  //设置发送的长度
  SetEPTxStatus(ENDP3, EP_TX_NAK);          //设置发送端点非应答
 //SetEPRxStatus(ENDP3, EP_RX_DIS);          //设置接受端点关闭

  /* Initialize Endpoint 3 OUT 64 byte max */ 
  SetEPType(ENDP3, EP_BULK);   
  SetEPRxAddr(ENDP3, ENDP3_RXADDR); 
  SetEPRxCount(ENDP3, 64);  
  SetEPRxStatus(ENDP3, EP_RX_VALID);  
 //SetEPTxStatus(ENDP3, EP_TX_DIS); 


  /* Set this device to response on default address */
  SetDeviceAddress(0);
  bDeviceState = ATTACHED;
}
View Code

 及usb_conf.h文件相关端点地址定义:

#define EP_NUM     (3)     //修改支持的端点数量by linxw

/*-------------------------------------------------------------*/
/* --------------   Buffer Description Table  -----------------*/
/*-------------------------------------------------------------*/
/* buffer table base address */
#define BTABLE_ADDRESS      (0x00)

/* EP0  */
/* rx/tx buffer base address */
#define ENDP0_RXADDR        (0x40)
#define ENDP0_TXADDR        (0x80)

/* EP1  */
/* tx buffer base address */
#define ENDP1_TXADDR        (0xC0)  //ENDP0_TXADDR+0x40开始


/* EP2  */
/* tx buffer base address */
#define ENDP2_TXADDR        (0x100) //ENDP1_TXADDR+0x40开始

/* EP3  */
/* tx buffer base address */
#define ENDP3_TXADDR        (0x140) //ENDP2_TXADDR+0x40开始
#define ENDP3_RXADDR        (0x180)
View Code

4.4修改RESULT CustomHID_Data_Setup(uint8_t RequestNo相关HID配置

/*******************************************************************************
* Function Name  : CustomHID_Data_Setup
* Description    : Handle the data class specific requests.
*这个函数对不同的接口进行区分,USBwIndex0反应出接口数量,不同接口返回不同的报告描述符
*第0接口:返回mouse相关的描述符
*第1接口:返回prn相关的描述符
*第2接口:返回driver相关的描述符
* Input          : Request Nb.
* Output         : None.
* Return         : USB_UNSUPPORT or USB_SUCCESS.
*******************************************************************************/

RESULT CustomHID_Data_Setup(uint8_t RequestNo)
{
  uint8_t *(*CopyRoutine)(uint16_t);
  
  if (pInformation->USBwIndex != 0) 
    return USB_UNSUPPORT;    
  
  CopyRoutine = NULL;
  
  if ((RequestNo == GET_DESCRIPTOR)
      && (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
      && (pInformation->USBwIndex0 < 3))  
  {
//在下面对3个接口进行区分
//CopyRoutine是指针函数,以指示运行哪个函数  
//需要构建6个函数 XX_GetReportDescriptor 和 XX_GetHIDDescriptor
    if (pInformation->USBwValue1 == REPORT_DESCRIPTOR)
    {
      //判断
      if (pInformation->USBwIndex0 == 0)
      {
          CopyRoutine = mouse_GetReportDescriptor;
      }
      else if (pInformation->USBwIndex0 == 1)
      {
          CopyRoutine = pen_GetReportDescriptor;
      }
      else if (pInformation->USBwIndex0 == 2)
      {
          CopyRoutine = HID_driver_GetReportDescriptor;
      }
     
    }
    else if (pInformation->USBwValue1 == HID_DESCRIPTOR_TYPE)
    {
      //判断
      if (pInformation->USBwIndex0 == 0)
      {
          CopyRoutine = mouse_GetHIDDescriptor;
      }
      else if (pInformation->USBwIndex0 == 1)
      {
          CopyRoutine = pen_GetHIDDescriptor;
      }
      else if (pInformation->USBwIndex0 == 2)
      {
          CopyRoutine = HID_driver_GetHIDDescriptor;
      }
       
    }
    
  } /* End of GET_DESCRIPTOR */
  
  /*** GET_PROTOCOL, GET_REPORT, SET_REPORT ***/
  //这部分看是否需要更改
  else if ( (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) )
  {         
    switch( RequestNo )
    {
    case GET_PROTOCOL:
      CopyRoutine = CustomHID_GetProtocolValue;
      break;
    case SET_REPORT:
      CopyRoutine = CustomHID_SetReport_Feature;
      Request = SET_REPORT;
      break;
    default:
      break;
    }
  }
  
  if (CopyRoutine == NULL)
  {
    return USB_UNSUPPORT;
  }
  
  pInformation->Ctrl_Info.CopyData = CopyRoutine;
  pInformation->Ctrl_Info.Usb_wOffset = 0;
  (*CopyRoutine)(0);
  return USB_SUCCESS;
}
View Code 

4.5以上CustomHID_Data_Setup函数需要构建6个函数:

在usb_prop.h增加函数的定义并去除无关的Custom_HID函数定义:

//新增函数定义
uint8_t *mouse_GetReportDescriptor(uint16_t Length);
uint8_t *pen_GetReportDescriptor(uint16_t Length);
uint8_t *HID_driver_GetReportDescriptor(uint16_t Length);

uint8_t *mouse_GetHIDDescriptor(uint16_t Length);
uint8_t *pen_GetHIDDescriptor(uint16_t Length);
uint8_t *HID_driver_GetHIDDescriptor(uint16_t Length);

在usb_proc.c定义:

/*******************************************************************************
* Function Name  : XX_GetReportDescriptor.
* Description    : Gets the HID report descriptor.
* Input          : Length
* Output         : None.
* Return         : The address of the configuration descriptor.
*******************************************************************************/
uint8_t *mouse_GetReportDescriptor(uint16_t Length)
{
  return Standard_GetDescriptorData(Length, &mouse_Report_Descriptor);
}
uint8_t *pen_GetReportDescriptor(uint16_t Length)
{
  return Standard_GetDescriptorData(Length, &pen_Report_Descriptor);
}
uint8_t *HID_driver_GetReportDescriptor(uint16_t Length)
{
  return Standard_GetDescriptorData(Length, &HID_driver_Report_Descriptor);
}

/*******************************************************************************
* Function Name  : XX_GetHIDDescriptor.
* Description    : Gets the HID descriptor.
* Input          : Length
* Output         : None.
* Return         : The address of the configuration descriptor.
*******************************************************************************/
uint8_t *mouse_GetHIDDescriptor(uint16_t Length)
{
  return Standard_GetDescriptorData(Length, &mouse_Hid_Descriptor);
}
uint8_t *pen_GetHIDDescriptor(uint16_t Length)
{
  return Standard_GetDescriptorData(Length, &pen_Hid_Descriptor);
}
uint8_t *HID_driver_GetHIDDescriptor(uint16_t Length)
{
  return Standard_GetDescriptorData(Length, &HID_driver_Hid_Descriptor);
}
View Code

5、完成测试:

 枚举成功,but在bus hound下看到,每一个HID的枚举,主机PC发送set_idle。设备并没有解析,出现stall pid错误,虽然不影响HID的使用,看着别扭,于是查找了大量的文件,了解清楚,

最终,在固件库usb_proc.c文件里,修改以下函数,

出现的stall pid现象:

CustomHID_NoData_Setup:资料下载链接https://download.csdn.net/download/weixin_43245044/11052195
RESULT CustomHID_NoData_Setup(uint8_t RequestNo)
{
  if ((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
      && (RequestNo == SET_PROTOCOL))
  {
    return CustomHID_SetProtocol();
  }
  //增加对PC端set_idle 请求的回应,不回复---by linxw
  if ((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
      && (RequestNo == SET_IDLE))
  {
    return USB_SUCCESS;
  }
  else
  {
    return USB_UNSUPPORT;
  }
}

 

posted @ 2019-03-23 15:56  寻觅左岸  阅读(8073)  评论(1编辑  收藏  举报