STM32F769IDiscovery  1.00
uDANTE Audio Networking with STM32F7 DISCO board
usbd_hid.c
Go to the documentation of this file.
1 
49 /* Includes ------------------------------------------------------------------*/
50 #include "usbd_hid.h"
51 #include "usbd_desc.h"
52 #include "usbd_ctlreq.h"
53 
54 
97 static uint8_t USBD_HID_Init (USBD_HandleTypeDef *pdev,
98  uint8_t cfgidx);
99 
100 static uint8_t USBD_HID_DeInit (USBD_HandleTypeDef *pdev,
101  uint8_t cfgidx);
102 
103 static uint8_t USBD_HID_Setup (USBD_HandleTypeDef *pdev,
104  USBD_SetupReqTypedef *req);
105 
106 static uint8_t *USBD_HID_GetCfgDesc (uint16_t *length);
107 
108 static uint8_t *USBD_HID_GetDeviceQualifierDesc (uint16_t *length);
109 
110 static uint8_t USBD_HID_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum);
120 {
121  USBD_HID_Init,
122  USBD_HID_DeInit,
123  USBD_HID_Setup,
124  NULL, /*EP0_TxSent*/
125  NULL, /*EP0_RxReady*/
126  USBD_HID_DataIn, /*DataIn*/
127  NULL, /*DataOut*/
128  NULL, /*SOF */
129  NULL,
130  NULL,
131  USBD_HID_GetCfgDesc,
132  USBD_HID_GetCfgDesc,
133  USBD_HID_GetCfgDesc,
134  USBD_HID_GetDeviceQualifierDesc,
135 };
136 
137 /* USB HID device Configuration Descriptor */
138 __ALIGN_BEGIN static uint8_t USBD_HID_CfgDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END =
139 {
140  0x09, /* bLength: Configuration Descriptor size */
141  USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
143  /* wTotalLength: Bytes returned */
144  0x00,
145  0x01, /*bNumInterfaces: 1 interface*/
146  0x01, /*bConfigurationValue: Configuration value*/
147  0x00, /*iConfiguration: Index of string descriptor describing
148  the configuration*/
149  0xE0, /*bmAttributes: bus powered and Support Remote Wake-up */
150  0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/
151 
152  /************** Descriptor of Joystick Mouse interface ****************/
153  /* 09 */
154  0x09, /*bLength: Interface Descriptor size*/
155  USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/
156  0x00, /*bInterfaceNumber: Number of Interface*/
157  0x00, /*bAlternateSetting: Alternate setting*/
158  0x01, /*bNumEndpoints*/
159  0x03, /*bInterfaceClass: HID*/
160  0x01, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
161  0x02, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
162  0, /*iInterface: Index of string descriptor*/
163  /******************** Descriptor of Joystick Mouse HID ********************/
164  /* 18 */
165  0x09, /*bLength: HID Descriptor size*/
166  HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
167  0x11, /*bcdHID: HID Class Spec release number*/
168  0x01,
169  0x00, /*bCountryCode: Hardware target country*/
170  0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/
171  0x22, /*bDescriptorType*/
172  HID_MOUSE_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/
173  0x00,
174  /******************** Descriptor of Mouse endpoint ********************/
175  /* 27 */
176  0x07, /*bLength: Endpoint Descriptor size*/
177  USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/
178 
179  HID_EPIN_ADDR, /*bEndpointAddress: Endpoint Address (IN)*/
180  0x03, /*bmAttributes: Interrupt endpoint*/
181  HID_EPIN_SIZE, /*wMaxPacketSize: 4 Byte max */
182  0x00,
183  HID_FS_BINTERVAL, /*bInterval: Polling Interval (10 ms)*/
184  /* 34 */
185 } ;
186 
187 /* USB HID device Configuration Descriptor */
188 __ALIGN_BEGIN static uint8_t USBD_HID_Desc[USB_HID_DESC_SIZ] __ALIGN_END =
189 {
190  /* 18 */
191  0x09, /*bLength: HID Descriptor size*/
192  HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
193  0x11, /*bcdHID: HID Class Spec release number*/
194  0x01,
195  0x00, /*bCountryCode: Hardware target country*/
196  0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/
197  0x22, /*bDescriptorType*/
198  HID_MOUSE_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/
199  0x00,
200 };
201 
202 /* USB Standard Device Descriptor */
203 __ALIGN_BEGIN static uint8_t USBD_HID_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
204 {
207  0x00,
208  0x02,
209  0x00,
210  0x00,
211  0x00,
212  0x40,
213  0x01,
214  0x00,
215 };
216 
217 __ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END =
218 {
219  0x05, 0x01,
220  0x09, 0x02,
221  0xA1, 0x01,
222  0x09, 0x01,
223 
224  0xA1, 0x00,
225  0x05, 0x09,
226  0x19, 0x01,
227  0x29, 0x03,
228 
229  0x15, 0x00,
230  0x25, 0x01,
231  0x95, 0x03,
232  0x75, 0x01,
233 
234  0x81, 0x02,
235  0x95, 0x01,
236  0x75, 0x05,
237  0x81, 0x01,
238 
239  0x05, 0x01,
240  0x09, 0x30,
241  0x09, 0x31,
242  0x09, 0x38,
243 
244  0x15, 0x81,
245  0x25, 0x7F,
246  0x75, 0x08,
247  0x95, 0x03,
248 
249  0x81, 0x06,
250  0xC0, 0x09,
251  0x3c, 0x05,
252  0xff, 0x09,
253 
254  0x01, 0x15,
255  0x00, 0x25,
256  0x01, 0x75,
257  0x01, 0x95,
258 
259  0x02, 0xb1,
260  0x22, 0x75,
261  0x06, 0x95,
262  0x01, 0xb1,
263 
264  0x01, 0xc0
265 };
266 
282 static uint8_t USBD_HID_Init (USBD_HandleTypeDef *pdev,
283  uint8_t cfgidx)
284 {
285  uint8_t ret = 0;
286 
287  /* Open EP IN */
288  USBD_LL_OpenEP(pdev,
291  HID_EPIN_SIZE);
292 
294 
295  if(pdev->pClassData == NULL)
296  {
297  ret = 1;
298  }
299  else
300  {
301  ((USBD_HID_HandleTypeDef *)pdev->pClassData)->state = HID_IDLE;
302  }
303  return ret;
304 }
305 
313 static uint8_t USBD_HID_DeInit (USBD_HandleTypeDef *pdev,
314  uint8_t cfgidx)
315 {
316  /* Close HID EPs */
317  USBD_LL_CloseEP(pdev,
318  HID_EPIN_ADDR);
319 
320  /* FRee allocated memory */
321  if(pdev->pClassData != NULL)
322  {
323  USBD_free(pdev->pClassData);
324  pdev->pClassData = NULL;
325  }
326 
327  return USBD_OK;
328 }
329 
337 static uint8_t USBD_HID_Setup (USBD_HandleTypeDef *pdev,
339 {
340  uint16_t len = 0;
341  uint8_t *pbuf = NULL;
343 
344  switch (req->bmRequest & USB_REQ_TYPE_MASK)
345  {
346  case USB_REQ_TYPE_CLASS :
347  switch (req->bRequest)
348  {
349 
350 
352  hhid->Protocol = (uint8_t)(req->wValue);
353  break;
354 
356  USBD_CtlSendData (pdev,
357  (uint8_t *)&hhid->Protocol,
358  1);
359  break;
360 
361  case HID_REQ_SET_IDLE:
362  hhid->IdleState = (uint8_t)(req->wValue >> 8);
363  break;
364 
365  case HID_REQ_GET_IDLE:
366  USBD_CtlSendData (pdev,
367  (uint8_t *)&hhid->IdleState,
368  1);
369  break;
370 
371  default:
372  USBD_CtlError (pdev, req);
373  return USBD_FAIL;
374  }
375  break;
376 
378  switch (req->bRequest)
379  {
381  if( req->wValue >> 8 == HID_REPORT_DESC)
382  {
383  len = MIN(HID_MOUSE_REPORT_DESC_SIZE , req->wLength);
384  pbuf = HID_MOUSE_ReportDesc;
385  }
386  else if( req->wValue >> 8 == HID_DESCRIPTOR_TYPE)
387  {
388  pbuf = USBD_HID_Desc;
389  len = MIN(USB_HID_DESC_SIZ , req->wLength);
390  }
391 
392  USBD_CtlSendData (pdev,
393  pbuf,
394  len);
395 
396  break;
397 
398  case USB_REQ_GET_INTERFACE :
399  USBD_CtlSendData (pdev,
400  (uint8_t *)&hhid->AltSetting,
401  1);
402  break;
403 
404  case USB_REQ_SET_INTERFACE :
405  hhid->AltSetting = (uint8_t)(req->wValue);
406  break;
407  }
408  }
409  return USBD_OK;
410 }
411 
420  uint8_t *report,
421  uint16_t len)
422 {
424 
426  {
427  if(hhid->state == HID_IDLE)
428  {
429  hhid->state = HID_BUSY;
430  USBD_LL_Transmit (pdev,
431  HID_EPIN_ADDR,
432  report,
433  len);
434  }
435  }
436  return USBD_OK;
437 }
438 
446 {
447  uint32_t polling_interval = 0;
448 
449  /* HIGH-speed endpoints */
450  if(pdev->dev_speed == USBD_SPEED_HIGH)
451  {
452  /* Sets the data transfer polling interval for high speed transfers.
453  Values between 1..16 are allowed. Values correspond to interval
454  of 2 ^ (bInterval-1). This option (8 ms, corresponds to HID_HS_BINTERVAL */
455  polling_interval = (((1 <<(HID_HS_BINTERVAL - 1)))/8);
456  }
457  else /* LOW and FULL-speed endpoints */
458  {
459  /* Sets the data transfer polling interval for low and full
460  speed transfers */
461  polling_interval = HID_FS_BINTERVAL;
462  }
463 
464  return ((uint32_t)(polling_interval));
465 }
466 
474 static uint8_t *USBD_HID_GetCfgDesc (uint16_t *length)
475 {
476  *length = sizeof (USBD_HID_CfgDesc);
477  return USBD_HID_CfgDesc;
478 }
479 
480 
488 static uint8_t USBD_HID_DataIn (USBD_HandleTypeDef *pdev,
489  uint8_t epnum)
490 {
491 
492  /* Ensure that the FIFO is empty before a new transfer, this condition could
493  be caused by a new transfer before the end of the previous transfer */
494  ((USBD_HID_HandleTypeDef *)pdev->pClassData)->state = HID_IDLE;
495  return USBD_OK;
496 }
497 
498 
505 static uint8_t *USBD_HID_GetDeviceQualifierDesc (uint16_t *length)
506 {
507  *length = sizeof (USBD_HID_DeviceQualifierDesc);
508  return USBD_HID_DeviceQualifierDesc;
509 }
510 
525 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
Closes an endpoint of the Low Level Driver.
Definition: usbd_conf.c:492
uint8_t bmRequest
Definition: usbd_def.h:151
uint16_t wValue
Definition: usbd_def.h:153
#define HID_HS_BINTERVAL
Definition: usbd_hid.h:62
uint8_t bRequest
Definition: usbd_def.h:152
#define USB_LEN_DEV_QUALIFIER_DESC
Definition: usbd_def.h:57
USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t *pbuf, uint16_t size)
Transmits data over an endpoint.
Definition: usbd_conf.c:574
#define HID_EPIN_ADDR
Definition: usbd_hid.h:52
#define USB_HID_DESC_SIZ
Definition: usbd_hid.h:56
if(LCD_Lock==DISABLE)
Definition: lcd_log.c:249
#define USB_REQ_GET_DESCRIPTOR
Definition: usbd_def.h:87
#define HID_MOUSE_REPORT_DESC_SIZE
Definition: usbd_hid.h:57
#define USB_REQ_GET_INTERFACE
Definition: usbd_def.h:91
USBD_SpeedTypeDef dev_speed
Definition: usbd_def.h:231
#define USBD_free
Definition: usbd_conf.h:74
Header file for the usbd_hid_core.c file.
uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len)
USBD_HID_SendReport Send HID Report.
Definition: usbd_hid.c:419
uint32_t USBD_HID_GetPollingInterval(USBD_HandleTypeDef *pdev)
USBD_HID_GetPollingInterval return polling interval from endpoint descriptor.
Definition: usbd_hid.c:445
#define NULL
Definition: usbd_def.h:53
#define __ALIGN_END
#define USBD_malloc
Definition: usbd_conf.h:73
#define USB_REQ_SET_INTERFACE
Definition: usbd_def.h:92
uint16_t wLength
Definition: usbd_def.h:155
void USBD_CtlError(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
USBD_CtlError Handle USB low level Error.
Definition: usbd_ctlreq.c:716
#define USB_DESC_TYPE_ENDPOINT
Definition: usbd_def.h:99
Definition: pbuf.h:108
#define HID_DESCRIPTOR_TYPE
Definition: usbd_hid.h:59
#define USB_DESC_TYPE_INTERFACE
Definition: usbd_def.h:98
#define USB_REQ_TYPE_CLASS
Definition: usbd_def.h:74
#define USB_DESC_TYPE_CONFIGURATION
Definition: usbd_def.h:96
#define USBD_EP_TYPE_INTR
Definition: usbd_def.h:136
#define USB_REQ_TYPE_STANDARD
Definition: usbd_def.h:73
#define HID_REQ_GET_IDLE
Definition: usbd_hid.h:70
#define HID_REQ_GET_PROTOCOL
Definition: usbd_hid.h:67
HID_StateTypeDef state
Definition: usbd_hid.h:95
USBD_ClassTypeDef USBD_HID
Definition: usbd_hid.c:119
USBD_StatusTypeDef USBD_CtlSendData(USBD_HandleTypeDef *pdev, uint8_t *buf, uint16_t len)
USBD_CtlSendData send data on the ctl pipe.
Definition: usbd_ioreq.c:95
#define HID_REPORT_DESC
Definition: usbd_hid.h:60
#define USB_DESC_TYPE_DEVICE_QUALIFIER
Definition: usbd_def.h:100
#define USB_HID_CONFIG_DESC_SIZ
Definition: usbd_hid.h:55
#define HID_EPIN_SIZE
Definition: usbd_hid.h:53
#define USB_REQ_TYPE_MASK
Definition: usbd_def.h:76
USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps)
Opens an endpoint of the Low Level Driver.
Definition: usbd_conf.c:473
#define USBD_STATE_CONFIGURED
Definition: usbd_def.h:120
#define MIN(a, b)
Definition: usbd_def.h:265
#define HID_FS_BINTERVAL
Definition: usbd_hid.h:63