STM32F769IDiscovery  1.00
uDANTE Audio Networking with STM32F7 DISCO board
usbd_ctlreq.c
Go to the documentation of this file.
1 
28 /* Includes ------------------------------------------------------------------*/
29 #include "usbd_ctlreq.h"
30 #include "usbd_ioreq.h"
31 
32 
79 static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev ,
81 
82 static void USBD_SetAddress(USBD_HandleTypeDef *pdev ,
84 
85 static void USBD_SetConfig(USBD_HandleTypeDef *pdev ,
87 
88 static void USBD_GetConfig(USBD_HandleTypeDef *pdev ,
90 
91 static void USBD_GetStatus(USBD_HandleTypeDef *pdev ,
93 
94 static void USBD_SetFeature(USBD_HandleTypeDef *pdev ,
96 
97 static void USBD_ClrFeature(USBD_HandleTypeDef *pdev ,
99 
100 static uint8_t USBD_GetLen(uint8_t *buf);
101 
120 {
122 
123  switch (req->bRequest)
124  {
126 
127  USBD_GetDescriptor (pdev, req) ;
128  break;
129 
130  case USB_REQ_SET_ADDRESS:
131  USBD_SetAddress(pdev, req);
132  break;
133 
135  USBD_SetConfig (pdev , req);
136  break;
137 
139  USBD_GetConfig (pdev , req);
140  break;
141 
142  case USB_REQ_GET_STATUS:
143  USBD_GetStatus (pdev , req);
144  break;
145 
146 
147  case USB_REQ_SET_FEATURE:
148  USBD_SetFeature (pdev , req);
149  break;
150 
151  case USB_REQ_CLEAR_FEATURE:
152  USBD_ClrFeature (pdev , req);
153  break;
154 
155  default:
156  USBD_CtlError(pdev , req);
157  break;
158  }
159 
160  return ret;
161 }
162 
171 {
173 
174  switch (pdev->dev_state)
175  {
177 
178  if (LOBYTE(req->wIndex) <= USBD_MAX_NUM_INTERFACES)
179  {
180  pdev->pClass->Setup (pdev, req);
181 
182  if((req->wLength == 0)&& (ret == USBD_OK))
183  {
184  USBD_CtlSendStatus(pdev);
185  }
186  }
187  else
188  {
189  USBD_CtlError(pdev , req);
190  }
191  break;
192 
193  default:
194  USBD_CtlError(pdev , req);
195  break;
196  }
197  return USBD_OK;
198 }
199 
208 {
209 
210  uint8_t ep_addr;
213  ep_addr = LOBYTE(req->wIndex);
214 
215  /* Check if it is a class request */
216  if ((req->bmRequest & 0x60) == 0x20)
217  {
218  pdev->pClass->Setup (pdev, req);
219 
220  return USBD_OK;
221  }
222 
223  switch (req->bRequest)
224  {
225 
226  case USB_REQ_SET_FEATURE :
227 
228  switch (pdev->dev_state)
229  {
230  case USBD_STATE_ADDRESSED:
231  if ((ep_addr != 0x00) && (ep_addr != 0x80))
232  {
233  USBD_LL_StallEP(pdev , ep_addr);
234  }
235  break;
236 
237  case USBD_STATE_CONFIGURED:
238  if (req->wValue == USB_FEATURE_EP_HALT)
239  {
240  if ((ep_addr != 0x00) && (ep_addr != 0x80))
241  {
242  USBD_LL_StallEP(pdev , ep_addr);
243 
244  }
245  }
246  pdev->pClass->Setup (pdev, req);
247  USBD_CtlSendStatus(pdev);
248 
249  break;
250 
251  default:
252  USBD_CtlError(pdev , req);
253  break;
254  }
255  break;
256 
257  case USB_REQ_CLEAR_FEATURE :
258 
259  switch (pdev->dev_state)
260  {
261  case USBD_STATE_ADDRESSED:
262  if ((ep_addr != 0x00) && (ep_addr != 0x80))
263  {
264  USBD_LL_StallEP(pdev , ep_addr);
265  }
266  break;
267 
268  case USBD_STATE_CONFIGURED:
269  if (req->wValue == USB_FEATURE_EP_HALT)
270  {
271  if ((ep_addr & 0x7F) != 0x00)
272  {
273  USBD_LL_ClearStallEP(pdev , ep_addr);
274  pdev->pClass->Setup (pdev, req);
275  }
276  USBD_CtlSendStatus(pdev);
277  }
278  break;
279 
280  default:
281  USBD_CtlError(pdev , req);
282  break;
283  }
284  break;
285 
286  case USB_REQ_GET_STATUS:
287  switch (pdev->dev_state)
288  {
289  case USBD_STATE_ADDRESSED:
290  if ((ep_addr & 0x7F) != 0x00)
291  {
292  USBD_LL_StallEP(pdev , ep_addr);
293  }
294  break;
295 
297  pep = ((ep_addr & 0x80) == 0x80) ? &pdev->ep_in[ep_addr & 0x7F]:\
298  &pdev->ep_out[ep_addr & 0x7F];
299  if(USBD_LL_IsStallEP(pdev, ep_addr))
300  {
301  pep->status = 0x0001;
302  }
303  else
304  {
305  pep->status = 0x0000;
306  }
307 
308  USBD_CtlSendData (pdev,
309  (uint8_t *)&pep->status,
310  2);
311  break;
312 
313  default:
314  USBD_CtlError(pdev , req);
315  break;
316  }
317  break;
318 
319  default:
320  break;
321  }
322  return ret;
323 }
331 static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev ,
333 {
334  uint16_t len;
335  uint8_t *pbuf;
336 
337 
338  switch (req->wValue >> 8)
339  {
340 #if (USBD_LPM_ENABLED == 1)
341  case USB_DESC_TYPE_BOS:
342  pbuf = pdev->pDesc->GetBOSDescriptor(pdev->dev_speed, &len);
343  break;
344 #endif
346  pbuf = pdev->pDesc->GetDeviceDescriptor(pdev->dev_speed, &len);
347  break;
348 
350  if(pdev->dev_speed == USBD_SPEED_HIGH )
351  {
352  pbuf = (uint8_t *)pdev->pClass->GetHSConfigDescriptor(&len);
353  pbuf[1] = USB_DESC_TYPE_CONFIGURATION;
354  }
355  else
356  {
357  pbuf = (uint8_t *)pdev->pClass->GetFSConfigDescriptor(&len);
358  pbuf[1] = USB_DESC_TYPE_CONFIGURATION;
359  }
360  break;
361 
363  switch ((uint8_t)(req->wValue))
364  {
365  case USBD_IDX_LANGID_STR:
366  pbuf = pdev->pDesc->GetLangIDStrDescriptor(pdev->dev_speed, &len);
367  break;
368 
369  case USBD_IDX_MFC_STR:
370  pbuf = pdev->pDesc->GetManufacturerStrDescriptor(pdev->dev_speed, &len);
371  break;
372 
374  pbuf = pdev->pDesc->GetProductStrDescriptor(pdev->dev_speed, &len);
375  break;
376 
377  case USBD_IDX_SERIAL_STR:
378  pbuf = pdev->pDesc->GetSerialStrDescriptor(pdev->dev_speed, &len);
379  break;
380 
381  case USBD_IDX_CONFIG_STR:
382  pbuf = pdev->pDesc->GetConfigurationStrDescriptor(pdev->dev_speed, &len);
383  break;
384 
386  pbuf = pdev->pDesc->GetInterfaceStrDescriptor(pdev->dev_speed, &len);
387  break;
388 
389  default:
390 #if (USBD_SUPPORT_USER_STRING == 1)
391  pbuf = pdev->pClass->GetUsrStrDescriptor(pdev, (req->wValue) , &len);
392  break;
393 #else
394  USBD_CtlError(pdev , req);
395  return;
396 #endif
397  }
398  break;
400 
401  if(pdev->dev_speed == USBD_SPEED_HIGH )
402  {
403  pbuf = (uint8_t *)pdev->pClass->GetDeviceQualifierDescriptor(&len);
404  break;
405  }
406  else
407  {
408  USBD_CtlError(pdev , req);
409  return;
410  }
411 
413  if(pdev->dev_speed == USBD_SPEED_HIGH )
414  {
415  pbuf = (uint8_t *)pdev->pClass->GetOtherSpeedConfigDescriptor(&len);
417  break;
418  }
419  else
420  {
421  USBD_CtlError(pdev , req);
422  return;
423  }
424 
425  default:
426  USBD_CtlError(pdev , req);
427  return;
428  }
429 
430  if((len != 0)&& (req->wLength != 0))
431  {
432 
433  len = MIN(len , req->wLength);
434 
435  USBD_CtlSendData (pdev,
436  pbuf,
437  len);
438  }
439 
440 }
441 
449 static void USBD_SetAddress(USBD_HandleTypeDef *pdev ,
451 {
452  uint8_t dev_addr;
453 
454  if ((req->wIndex == 0) && (req->wLength == 0))
455  {
456  dev_addr = (uint8_t)(req->wValue) & 0x7F;
457 
458  if (pdev->dev_state == USBD_STATE_CONFIGURED)
459  {
460  USBD_CtlError(pdev , req);
461  }
462  else
463  {
464  pdev->dev_address = dev_addr;
465  USBD_LL_SetUSBAddress(pdev, dev_addr);
466  USBD_CtlSendStatus(pdev);
467 
468  if (dev_addr != 0)
469  {
471  }
472  else
473  {
474  pdev->dev_state = USBD_STATE_DEFAULT;
475  }
476  }
477  }
478  else
479  {
480  USBD_CtlError(pdev , req);
481  }
482 }
483 
491 static void USBD_SetConfig(USBD_HandleTypeDef *pdev ,
493 {
494 
495  static uint8_t cfgidx;
496 
497  cfgidx = (uint8_t)(req->wValue);
498 
499  if (cfgidx > USBD_MAX_NUM_CONFIGURATION )
500  {
501  USBD_CtlError(pdev , req);
502  }
503  else
504  {
505  switch (pdev->dev_state)
506  {
508  if (cfgidx)
509  {
510  pdev->dev_config = cfgidx;
512  if(USBD_SetClassConfig(pdev , cfgidx) == USBD_FAIL)
513  {
514  USBD_CtlError(pdev , req);
515  return;
516  }
517  USBD_CtlSendStatus(pdev);
518  }
519  else
520  {
521  USBD_CtlSendStatus(pdev);
522  }
523  break;
524 
526  if (cfgidx == 0)
527  {
529  pdev->dev_config = cfgidx;
530  USBD_ClrClassConfig(pdev , cfgidx);
531  USBD_CtlSendStatus(pdev);
532 
533  }
534  else if (cfgidx != pdev->dev_config)
535  {
536  /* Clear old configuration */
537  USBD_ClrClassConfig(pdev , pdev->dev_config);
538 
539  /* set new configuration */
540  pdev->dev_config = cfgidx;
541  if(USBD_SetClassConfig(pdev , cfgidx) == USBD_FAIL)
542  {
543  USBD_CtlError(pdev , req);
544  return;
545  }
546  USBD_CtlSendStatus(pdev);
547  }
548  else
549  {
550  USBD_CtlSendStatus(pdev);
551  }
552  break;
553 
554  default:
555  USBD_CtlError(pdev , req);
556  break;
557  }
558  }
559 }
560 
568 static void USBD_GetConfig(USBD_HandleTypeDef *pdev ,
570 {
571 
572  if (req->wLength != 1)
573  {
574  USBD_CtlError(pdev , req);
575  }
576  else
577  {
578  switch (pdev->dev_state )
579  {
580  case USBD_STATE_ADDRESSED:
581  pdev->dev_default_config = 0;
582  USBD_CtlSendData (pdev,
583  (uint8_t *)&pdev->dev_default_config,
584  1);
585  break;
586 
587  case USBD_STATE_CONFIGURED:
588 
589  USBD_CtlSendData (pdev,
590  (uint8_t *)&pdev->dev_config,
591  1);
592  break;
593 
594  default:
595  USBD_CtlError(pdev , req);
596  break;
597  }
598  }
599 }
600 
608 static void USBD_GetStatus(USBD_HandleTypeDef *pdev ,
610 {
611 
612 
613  switch (pdev->dev_state)
614  {
617 
618 #if ( USBD_SELF_POWERED == 1)
620 #else
621  pdev->dev_config_status = 0;
622 #endif
623 
624  if (pdev->dev_remote_wakeup)
625  {
627  }
628 
629  USBD_CtlSendData (pdev,
630  (uint8_t *)& pdev->dev_config_status,
631  2);
632  break;
633 
634  default :
635  USBD_CtlError(pdev , req);
636  break;
637  }
638 }
639 
640 
648 static void USBD_SetFeature(USBD_HandleTypeDef *pdev ,
650 {
651 
652  if (req->wValue == USB_FEATURE_REMOTE_WAKEUP)
653  {
654  pdev->dev_remote_wakeup = 1;
655  pdev->pClass->Setup (pdev, req);
656  USBD_CtlSendStatus(pdev);
657  }
658 
659 }
660 
661 
669 static void USBD_ClrFeature(USBD_HandleTypeDef *pdev ,
671 {
672  switch (pdev->dev_state)
673  {
676  if (req->wValue == USB_FEATURE_REMOTE_WAKEUP)
677  {
678  pdev->dev_remote_wakeup = 0;
679  pdev->pClass->Setup (pdev, req);
680  USBD_CtlSendStatus(pdev);
681  }
682  break;
683 
684  default :
685  USBD_CtlError(pdev , req);
686  break;
687  }
688 }
689 
699 {
700  req->bmRequest = *(uint8_t *) (pdata);
701  req->bRequest = *(uint8_t *) (pdata + 1);
702  req->wValue = SWAPBYTE (pdata + 2);
703  req->wIndex = SWAPBYTE (pdata + 4);
704  req->wLength = SWAPBYTE (pdata + 6);
705 
706 }
707 
718 {
719  USBD_LL_StallEP(pdev , 0x80);
720  USBD_LL_StallEP(pdev , 0);
721 }
722 
723 
732 void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len)
733 {
734  uint8_t idx = 0;
735 
736  if (desc != NULL)
737  {
738  *len = USBD_GetLen(desc) * 2 + 2;
739  unicode[idx++] = *len;
740  unicode[idx++] = USB_DESC_TYPE_STRING;
741 
742  while (*desc != '\0')
743  {
744  unicode[idx++] = *desc++;
745  unicode[idx++] = 0x00;
746  }
747  }
748 }
749 
756 static uint8_t USBD_GetLen(uint8_t *buf)
757 {
758  uint8_t len = 0;
759 
760  while (*buf != '\0')
761  {
762  len++;
763  buf++;
764  }
765 
766  return len;
767 }
782 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
USBD_StatusTypeDef
Definition: usbd_def.h:194
#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION
Definition: usbd_def.h:101
USBD_StatusTypeDef USBD_CtlSendStatus(USBD_HandleTypeDef *pdev)
USBD_CtlSendStatus send zero lzngth packet on the ctl pipe.
Definition: usbd_ioreq.c:177
USBD_EndpointTypeDef ep_in[15]
Definition: usbd_def.h:232
uint32_t dev_default_config
Definition: usbd_def.h:229
#define USBD_IDX_LANGID_STR
Definition: usbd_def.h:66
uint8_t bmRequest
Definition: usbd_def.h:151
uint16_t wValue
Definition: usbd_def.h:153
#define USB_REQ_GET_CONFIGURATION
Definition: usbd_def.h:89
uint8_t *(* GetLangIDStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length)
Definition: usbd_def.h:204
#define LOBYTE(x)
Definition: usbd_def.h:263
uint32_t idx
Definition: lcd_log.c:247
uint8_t bRequest
Definition: usbd_def.h:152
uint8_t *(* GetHSConfigDescriptor)(uint16_t *length)
Definition: usbd_def.h:175
uint8_t dev_address
Definition: usbd_def.h:238
uint8_t *(* GetInterfaceStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length)
Definition: usbd_def.h:209
USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
USBD_StdEPReq Handle standard usb endpoint requests.
Definition: usbd_ctlreq.c:207
#define USB_REQ_GET_DESCRIPTOR
Definition: usbd_def.h:87
USBD_DescriptorsTypeDef * pDesc
Definition: usbd_def.h:244
USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
Clears a Stall condition on an endpoint of the Low Level Driver.
Definition: usbd_conf.c:528
uint32_t dev_config
Definition: usbd_def.h:228
#define USBD_MAX_NUM_CONFIGURATION
Definition: usbd_conf.h:62
#define USBD_IDX_CONFIG_STR
Definition: usbd_def.h:70
uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
Returns Stall condition.
Definition: usbd_conf.c:540
USBD_SpeedTypeDef dev_speed
Definition: usbd_def.h:231
#define USBD_STATE_ADDRESSED
Definition: usbd_def.h:119
void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len)
USBD_GetString Convert Ascii string into unicode one.
Definition: usbd_ctlreq.c:732
#define USB_REQ_SET_CONFIGURATION
Definition: usbd_def.h:90
#define USBD_STATE_DEFAULT
Definition: usbd_def.h:118
uint8_t(* Setup)(struct _USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
Definition: usbd_def.h:165
#define USBD_IDX_INTERFACE_STR
Definition: usbd_def.h:71
USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
USBD_SetClassConfig Configure device and start the interface.
Definition: usbd_core.c:227
#define NULL
Definition: usbd_def.h:53
USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
USBD_ClrClassConfig Clear current configuration.
Definition: usbd_core.c:249
uint8_t *(* GetManufacturerStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length)
Definition: usbd_def.h:205
#define USBD_IDX_PRODUCT_STR
Definition: usbd_def.h:68
uint16_t wLength
Definition: usbd_def.h:155
#define USB_FEATURE_EP_HALT
Definition: usbd_def.h:107
USBD_StatusTypeDef USBD_StdDevReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
USBD_StdDevReq Handle standard usb device requests.
Definition: usbd_ctlreq.c:119
Definition: pbuf.h:108
USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
Sets a Stall condition on an endpoint of the Low Level Driver.
Definition: usbd_conf.c:516
uint16_t wIndex
Definition: usbd_def.h:154
USBD_StatusTypeDef USBD_StdItfReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
USBD_StdItfReq Handle standard usb interface requests.
Definition: usbd_ctlreq.c:170
#define USB_REQ_SET_FEATURE
Definition: usbd_def.h:85
uint8_t *(* GetProductStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length)
Definition: usbd_def.h:206
#define USB_DESC_TYPE_CONFIGURATION
Definition: usbd_def.h:96
#define USB_DESC_TYPE_DEVICE
Definition: usbd_def.h:95
#define USB_CONFIG_REMOTE_WAKEUP
Definition: usbd_def.h:104
Header file for the usbd_ioreq.c file.
#define SWAPBYTE(addr)
Definition: usbd_def.h:260
uint8_t *(* GetConfigurationStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length)
Definition: usbd_def.h:208
USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr)
Assigns a USB address to the device.
Definition: usbd_conf.c:560
#define USBD_MAX_NUM_INTERFACES
Definition: usbd_conf.h:61
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
uint8_t *(* GetOtherSpeedConfigDescriptor)(uint16_t *length)
Definition: usbd_def.h:177
#define USB_DESC_TYPE_STRING
Definition: usbd_def.h:97
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_DEVICE_QUALIFIER
Definition: usbd_def.h:100
uint8_t *(* GetDeviceQualifierDescriptor)(uint16_t *length)
Definition: usbd_def.h:178
#define USB_CONFIG_SELF_POWERED
Definition: usbd_def.h:105
#define USBD_IDX_SERIAL_STR
Definition: usbd_def.h:69
USBD_ClassTypeDef * pClass
Definition: usbd_def.h:245
#define USB_REQ_GET_STATUS
Definition: usbd_def.h:83
#define USB_REQ_CLEAR_FEATURE
Definition: usbd_def.h:84
uint32_t dev_remote_wakeup
Definition: usbd_def.h:241
uint32_t dev_config_status
Definition: usbd_def.h:230
#define USB_REQ_SET_ADDRESS
Definition: usbd_def.h:86
#define USBD_STATE_CONFIGURED
Definition: usbd_def.h:120
#define USB_DESC_TYPE_BOS
Definition: usbd_def.h:102
USBD_EndpointTypeDef ep_out[15]
Definition: usbd_def.h:233
uint8_t *(* GetSerialStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length)
Definition: usbd_def.h:207
#define USBD_IDX_MFC_STR
Definition: usbd_def.h:67
#define MIN(a, b)
Definition: usbd_def.h:265
uint8_t *(* GetFSConfigDescriptor)(uint16_t *length)
Definition: usbd_def.h:176
void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata)
USBD_ParseSetupRequest Copy buffer into setup structure.
Definition: usbd_ctlreq.c:698
uint8_t *(* GetDeviceDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length)
Definition: usbd_def.h:203
#define USB_FEATURE_REMOTE_WAKEUP
Definition: usbd_def.h:108