GD32F1x0: USB/GD32_USB_Device_Library/Core/src/usbd_enum.c Source File

GD32F1x0

usbd_enum.c
1 
12 /* Includes ------------------------------------------------------------------*/
13 #include "usbd_enum.h"
14 
27 /* USB enumeration handle functions */
28 static void USBD_GetDescriptor (USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req);
29 static void USBD_SetAddress (USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req);
30 static void USBD_SetConfiguration (USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req);
31 static void USBD_GetConfiguration (USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req);
32 static void USBD_GetStatus (USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req);
33 static void USBD_SetFeature (USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req);
34 static void USBD_ClearFeature (USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req);
35 static void USBD_Reserved (USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req);
36 static void USBD_SetDescriptor (USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req);
37 static void USBD_GetInterface (USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req);
38 static void USBD_SetInterface (USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req);
39 static void USBD_SynchFrame (USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req);
40 
44 uint8_t gAddress = 0;
45 uint8_t USBD_StrDesc[USB_STR_DESC_MAX_SIZE];
46 
47 static void (*StandardDeviceRequest[])(USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req) =
48 {
49  USBD_GetStatus,
50  USBD_ClearFeature,
51  USBD_Reserved,
52  USBD_SetFeature,
53  USBD_Reserved,
54  USBD_SetAddress,
55  USBD_GetDescriptor,
56  USBD_SetDescriptor,
57  USBD_GetConfiguration,
58  USBD_SetConfiguration,
59  USBD_GetInterface,
60  USBD_SetInterface,
61  USBD_SynchFrame,
62 };
63 
79 {
80  /* Call device request handle function */
81  (*StandardDeviceRequest[req->bRequest])(pudev, req);
82 
83  return USBD_OK;
84 }
85 
93 {
94  USBD_Status ret;
95 
96  switch (pudev->dev.device_cur_status)
97  {
98  case USB_STATUS_CONFIGURED:
99  if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM)
100  {
101  /* Call back device class handle function */
102  ret = (USBD_Status)(pudev->dev.class_cb->ClassReqHandle(pudev, req));
103 
104  if((req->wLength == 0) && (ret == USBD_OK))
105  {
106  /* No data stage */
107  USB_CtlTransmitStatus(pudev);
108  }
109  }
110  else
111  {
112  USBD_EnumError(pudev, req);
113  }
114  break;
115 
116  default:
117  USBD_EnumError(pudev, req);
118  break;
119  }
120 
121  return USBD_OK;
122 }
123 
131 {
132  /* Added by user... */
133 
134  return USBD_OK;
135 }
136 
143 static void USBD_Reserved (USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req)
144 {
145  /* No operation... */
146 }
147 
154 static void USBD_GetStatus (USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req)
155 {
156  uint8_t ep_addr;
157  uint16_t config_status = 0x0000;
158  uint16_t endp_status = 0x0000;
159 
160  switch(req->bmRequestType & USB_REQ_RECIPIENT_MASK)
161  {
162  case USB_REQTYPE_DEVICE:
163  switch (pudev->dev.device_cur_status)
164  {
165  case USB_STATUS_ADDRESSED:
166  case USB_STATUS_CONFIGURED:
167 
168 #ifdef USBD_SELF_POWERED
169  config_status = USB_STATUS_SELF_POWERED;
170 #endif
171 
172  if (pudev->dev.DevRemoteWakeup)
173  {
174  config_status |= USB_STATUS_REMOTE_WAKEUP;
175  }
176  USB_CtlTx(pudev, (uint8_t *)&config_status, 2);
177  break;
178 
179  default:
180  break;
181  }
182  break;
183 
184  case USB_REQTYPE_INTERFACE:
185  switch (pudev->dev.device_cur_status)
186  {
187  case USB_STATUS_ADDRESSED:
188  USBD_EnumError(pudev, req);
189  break;
190 
191  case USB_STATUS_CONFIGURED:
192  if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM)
193  {
194  USB_CtlTx(pudev, (uint8_t *)&config_status, 2);
195  }
196  else
197  {
198  USBD_EnumError(pudev, req);
199  }
200  break;
201 
202  default:
203  break;
204  }
205  break;
206 
207  case USB_REQTYPE_ENDPOINT:
208  ep_addr = LOWBYTE(req->wIndex);
209 
210  switch (pudev->dev.device_cur_status)
211  {
212  case USB_STATUS_ADDRESSED:
213  if (IS_NOT_EP0(ep_addr))
214  {
215  USBD_EnumError(pudev, req);
216  }
217  break;
218 
219  case USB_STATUS_CONFIGURED:
220  if ((ep_addr & 0x80)== 0x80)
221  {
222  if(pudev->dev.in_ep[ep_addr & 0x7F].is_stall)
223  {
224  endp_status = 0x0001;
225  }
226  }
227  else
228  {
229  if(pudev->dev.out_ep[ep_addr].is_stall)
230  {
231  endp_status = 0x0001;
232  }
233  }
234  USB_CtlTx(pudev, (uint8_t *)&endp_status, 2);
235  break;
236 
237  default:
238  break;
239  }
240  break;
241 
242  default:
243  USBD_EnumError(pudev, req);
244  break;
245  }
246 }
247 
254 static void USBD_ClearFeature (USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req)
255 {
256  uint8_t ep_addr = 0;
257 
258  switch(req->bmRequestType & USB_REQ_RECIPIENT_MASK)
259  {
260  case USB_REQTYPE_DEVICE:
261  switch (pudev->dev.device_cur_status)
262  {
263  case USB_STATUS_ADDRESSED:
264  case USB_STATUS_CONFIGURED:
265  if (req->wValue == USB_FEATURE_REMOTE_WAKEUP)
266  {
267  pudev->dev.DevRemoteWakeup = 0;
268  USB_CtlTransmitStatus(pudev);
269  }
270  else if(req->wValue == USB_FEATURE_TEST_MODE)
271  {
272  /* Can not clear test_mode feature */
273  USBD_EnumError(pudev, req);
274  }
275  break;
276 
277  default:
278  break;
279  }
280  break;
281 
282  case USB_REQTYPE_INTERFACE:
283  switch(pudev->dev.device_cur_state)
284  {
285  case USB_STATUS_ADDRESSED:
286  USBD_EnumError(pudev, req);
287  break;
288 
289  case USB_STATUS_CONFIGURED:
290  if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM)
291  {/* No operation */
292  }
293  else
294  {
295  USBD_EnumError(pudev, req);
296  }
297  break;
298 
299  default:
300  break;
301  }
302  break;
303 
304  case USB_REQTYPE_ENDPOINT:
305  ep_addr = LOWBYTE(req->wIndex);
306 
307  switch (pudev->dev.device_cur_status)
308  {
309  case USB_STATUS_ADDRESSED:
310  if (IS_NOT_EP0(ep_addr))
311  {
312  USBD_EnumError(pudev, req);
313  }
314  break;
315 
316  case USB_STATUS_CONFIGURED:
317  if (req->wValue == USB_FEATURE_ENDP_HALT)
318  {
319  if (IS_NOT_EP0(ep_addr))
320  {
321  USB_EP_ClrStall(pudev, ep_addr);
322  }
323  }
324  USB_CtlTransmitStatus(pudev);
325  break;
326 
327  default:
328  break;
329  }
330  break;
331 
332  default:
333  USBD_EnumError(pudev, req);
334  break;
335  }
336 }
337 
344 static void USBD_SetFeature (USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req)
345 {
346  uint8_t ep_addr = 0;
347 
348  switch(req->bmRequestType & USB_REQ_RECIPIENT_MASK)
349  {
350  case USB_REQTYPE_DEVICE:
351  switch (pudev->dev.device_cur_status)
352  {
353  case USB_STATUS_ADDRESSED:
354  case USB_STATUS_CONFIGURED:
355  if (req->wValue == USB_FEATURE_REMOTE_WAKEUP)
356  {
357  pudev->dev.DevRemoteWakeup = 1;
358  USB_CtlTransmitStatus(pudev);
359  }
360  break;
361 
362  default:
363  break;
364  }
365  break;
366 
367  case USB_REQTYPE_INTERFACE:
368  switch(pudev->dev.device_cur_state)
369  {
370  case USB_STATUS_ADDRESSED:
371  USBD_EnumError(pudev, req);
372  break;
373 
374  case USB_STATUS_CONFIGURED:
375  if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM)
376  {/* No operation */
377  }
378  else
379  {
380  USBD_EnumError(pudev, req);
381  }
382  break;
383 
384  default:
385  break;
386  }
387  break;
388 
389  case USB_REQTYPE_ENDPOINT:
390  switch (pudev->dev.device_cur_status)
391  {
392  case USB_STATUS_ADDRESSED:
393  if (IS_NOT_EP0(ep_addr))
394  {
395  USBD_EnumError(pudev, req);
396  }
397  break;
398 
399  case USB_STATUS_CONFIGURED:
400  if (req->wValue == USB_FEATURE_ENDP_HALT)
401  {
402  if (IS_NOT_EP0(ep_addr))
403  {
404  USB_EP_Stall(pudev, ep_addr);
405  }
406  }
407  USB_CtlTransmitStatus(pudev);
408  break;
409 
410  default:
411  break;
412  }
413  break;
414 
415  default:
416  USBD_EnumError(pudev, req);
417  break;
418  }
419 }
420 
427 static void USBD_SetAddress (USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req)
428 {
429  if ((req->wIndex == 0) && (req->wLength == 0))
430  {
431  gAddress = (uint8_t)(req->wValue) & 0x7F;
432 
433  if (pudev->dev.device_cur_status == USB_STATUS_CONFIGURED)
434  {
435  USBD_EnumError(pudev, req);
436  }
437  else
438  {
439  USB_CtlTransmitStatus(pudev);
440 
441  if (gAddress != 0)
442  {
443  pudev->dev.device_cur_status = USB_STATUS_ADDRESSED;
444  }
445  else
446  {
447  pudev->dev.device_cur_status = USB_STATUS_DEFAULT;
448  }
449  }
450  }
451  else
452  {
453  USBD_EnumError(pudev , req);
454  }
455 }
456 
463 static void USBD_GetDescriptor (USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req)
464 {
465  if((req->bmRequestType & USB_REQ_RECIPIENT_MASK) == USB_REQTYPE_DEVICE)
466  {
467  uint16_t len;
468  uint8_t *pbuf;
469 
470  switch (req->wValue >> 8)
471  {
472 #ifdef LPM_ENABLED
473  case USB_DESC_TYPE_BOS:
474  pbuf = pudev->dev.desc_cb->GetBOSDescriptor(pudev->dev.speed, &len);
475  break;
476 #endif
477  case USB_DESCTYPE_DEVICE:
478  pbuf = pudev->dev.desc_cb->GetDeviceDescriptor(pudev->dev.speed, &len);
479  if (req->wLength == 64) len = 8;
480  break;
481 
482  case USB_DESCTYPE_CONFIGURATION:
483  pbuf = (uint8_t *)pudev->dev.class_cb->GetConfigDescriptor(pudev->dev.speed, &len);
484  break;
485 
486  case USB_DESCTYPE_STRING:
487  switch ((uint8_t)(req->wValue))
488  {
489  case USBD_LANGID_STR_IDX:
490  pbuf = pudev->dev.desc_cb->GetLangIDStrDescriptor(pudev->dev.speed, &len);
491  break;
492 
493  case USBD_MFC_STR_IDX:
494  pbuf = pudev->dev.desc_cb->GetManufacturerStrDescriptor(pudev->dev.speed, &len);
495  break;
496 
497  case USBD_PRODUCT_STR_IDX:
498  pbuf = pudev->dev.desc_cb->GetProductStrDescriptor(pudev->dev.speed, &len);
499  break;
500 
501  case USBD_SERIAL_STR_IDX:
502  pbuf = pudev->dev.desc_cb->GetSerialStrDescriptor(pudev->dev.speed, &len);
503  break;
504 
505  case USBD_CONFIG_STR_IDX:
506  pbuf = pudev->dev.desc_cb->GetConfigurationStrDescriptor(pudev->dev.speed, &len);
507  break;
508 
509  case USBD_INTERFACE_STR_IDX:
510  pbuf = pudev->dev.desc_cb->GetInterfaceStrDescriptor(pudev->dev.speed, &len);
511  break;
512 
513  default:
514 #ifdef USB_SUPPORT_USER_STRING_DESC
515  pbuf = pudev->dev.class_cb->GetUsrStrDescriptor(pudev->dev.speed, (req->wValue), &len);
516  break;
517 #else
518  USBD_EnumError(pudev, req);
519  return;
520 #endif
521  }
522  break;
523 
524  case USB_DESCTYPE_DEVICE_QUALIFIER:
525  USBD_EnumError(pudev, req);
526  return;
527 
528  case USB_DESCTYPE_OTHER_SPEED_CONFIGURATION:
529  USBD_EnumError(pudev, req);
530  return;
531 
532  default:
533  USBD_EnumError(pudev, req);
534  return;
535  }
536 
537  if((len != 0) && (req->wLength != 0))
538  {
539  len = MIN(len, req->wLength);
540 
541  USB_CtlTx (pudev, pbuf,len);
542  }
543  }
544  else if((req->bmRequestType & USB_REQ_RECIPIENT_MASK) == USB_REQTYPE_INTERFACE)
545  {
546  pudev->dev.class_cb->GetClassDescriptor(pudev, req);
547  }
548 }
549 
556 static void USBD_SetDescriptor (USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req)
557 {
558  /* No handle... */
559 }
560 
567 static void USBD_GetConfiguration (USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req)
568 {
569  uint32_t USBD_default_config = 0;
570 
571  if (req->wLength != 1)
572  {
573  USBD_EnumError(pudev, req);
574  }
575  else
576  {
577  switch (pudev->dev.device_cur_status)
578  {
579  case USB_STATUS_ADDRESSED:
580  USB_CtlTx (pudev, (uint8_t *)&USBD_default_config, 1);
581  break;
582 
583  case USB_STATUS_CONFIGURED:
584  USB_CtlTx (pudev, &pudev->dev.device_cur_config, 1);
585  break;
586 
587  default:
588  break;
589  }
590  }
591 }
592 
599 static void USBD_SetConfiguration (USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req)
600 {
601  static uint8_t cfgidx;
602 
603  cfgidx = (uint8_t)(req->wValue);
604 
605  if (cfgidx > USBD_CFG_MAX_NUM)
606  {
607  USBD_EnumError(pudev, req);
608  }
609  else
610  {
611  switch (pudev->dev.device_cur_status)
612  {
613  case USB_STATUS_ADDRESSED:
614  if (cfgidx)
615  {
616  pudev->dev.device_cur_config = cfgidx;
617  pudev->dev.device_cur_status = USB_STATUS_CONFIGURED;
618  USBD_SetCfg(pudev, cfgidx);
619  USB_CtlTransmitStatus(pudev);
620  }
621  else
622  {
623  USB_CtlTransmitStatus(pudev);
624  }
625  break;
626 
627  case USB_STATUS_CONFIGURED:
628  if (cfgidx == 0)
629  {
630  pudev->dev.device_cur_status = USB_STATUS_ADDRESSED;
631  pudev->dev.device_cur_config = cfgidx;
632  USBD_ClrCfg(pudev, cfgidx);
633  USB_CtlTransmitStatus(pudev);
634  }
635  else if (cfgidx != pudev->dev.device_cur_config)
636  {
637  /* Clear old configuration */
638  USBD_ClrCfg(pudev, pudev->dev.device_cur_config);
639 
640  /* Set new configuration */
641  pudev->dev.device_cur_config = cfgidx;
642  USBD_SetCfg(pudev, cfgidx);
643  USB_CtlTransmitStatus(pudev);
644  }
645  else
646  {
647  USB_CtlTransmitStatus(pudev);
648  }
649  break;
650 
651  default:
652  break;
653  }
654  }
655 }
656 
663 static void USBD_GetInterface (USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req)
664 {
665  switch (pudev->dev.device_cur_status)
666  {
667  case USB_STATUS_ADDRESSED:
668  USBD_EnumError(pudev, req);
669  break;
670 
671  case USB_STATUS_CONFIGURED:
672  if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM)
673  {
674  pudev->dev.class_cb->GetInterface (pudev, req);
675  }
676  else
677  {
678  USBD_EnumError(pudev, req);
679  }
680  break;
681 
682  default:
683  break;
684  }
685 }
686 
693 static void USBD_SetInterface (USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req)
694 {
695  switch (pudev->dev.device_cur_status)
696  {
697  case USB_STATUS_ADDRESSED:
698  USBD_EnumError(pudev, req);
699  break;
700 
701  case USB_STATUS_CONFIGURED:
702  if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM)
703  {
704  pudev->dev.class_cb->SetInterface (pudev, req);
705  }
706  else
707  {
708  USBD_EnumError(pudev, req);
709  }
710  break;
711 
712  default:
713  break;
714  }
715 }
716 
723 static void USBD_SynchFrame (USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req)
724 {
725  /* No handle... */
726 }
727 
728 
737 {
738  req->bmRequestType = *(uint8_t *) (pudev->dev.setup_packet);
739  req->bRequest = *(uint8_t *) (pudev->dev.setup_packet + 1);
740  req->wValue = SWAPBYTE (pudev->dev.setup_packet + 2);
741  req->wIndex = SWAPBYTE (pudev->dev.setup_packet + 4);
742  req->wLength = SWAPBYTE (pudev->dev.setup_packet + 6);
743 
744  pudev->dev.in_ep[0].ctrl_count = req->wLength;
745  pudev->dev.device_cur_state = USB_CTRL_SETUP;
746 }
747 
756 {
757  USB_EP_Stall(pudev, EP0);
758 }
759 
767 void IntToUnicode (uint32_t Value, uint8_t *pbuf, uint8_t Len)
768 {
769  uint8_t Index = 0;
770 
771  for(Index = 0; Index < Len; Index++)
772  {
773  if((Value >> 28) < 0x0A)
774  {
775  pbuf[2 * Index] = (Value >> 28) + '0';
776  }
777  else
778  {
779  pbuf[2 * Index] = (Value >> 28) + 'A' - 10;
780  }
781 
782  Value = Value << 4;
783 
784  pbuf[2 * Index + 1] = 0;
785  }
786 }
787 
795 void USBD_GetUnicodeString (uint8_t *desc, uint8_t *unicode, uint16_t *len)
796 {
797  uint8_t idx = 1;
798 
799  if (desc != NULL)
800  {
801  unicode[idx++] = USB_DESCTYPE_STRING;
802 
803  for (; *desc != NULL; )
804  {
805  unicode[idx++] = *desc++;
806  unicode[idx++] = 0x00;
807  }
808 
809  *len = idx;
810  unicode[0] = *len;
811  }
812 }
813 
830 /************************ (C) COPYRIGHT 2014 GIGADEVICE *****END OF FILE****/
uint8_t USBD_VdrDefReq(USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req)
Handle usb vendor request.
Definition: usbd_enum.c:130
void USBD_EnumError(USB_CORE_HANDLE *pudev, USB_DEVICE_REQ *req)
Handle usb enumeration error event.
Definition: usbd_enum.c:755
uint8_t USBD_StdReq(USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req)
Handle usb standard device request.
Definition: usbd_enum.c:78
void USB_EP_ClrStall(USB_CORE_HANDLE *pudev, uint8_t EpID)
Clear endpoint stalled status.
Definition: usb_core.c:473
uint8_t USB_CtlTransmitStatus(USB_CORE_HANDLE *pudev)
Transmit status stage on the control pipe.
Definition: usb_core.c:609
uint8_t USBD_DevClsReq(USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req)
Handle device class request.
Definition: usbd_enum.c:92
USBD_Status USBD_SetCfg(USB_DEVICE_HANDLE *pudev, uint8_t ConfigIndex)
Device configuration and interface setting.
Definition: usbd_core.c:269
void IntToUnicode(uint32_t Value, uint8_t *pbuf, uint8_t Len)
Convert Hex 32bits value into unicode char.
Definition: usbd_enum.c:767
USBD_Status
USB device operation status.
Definition: usbd_core.h:40
uint8_t USB_CtlTx(USB_CORE_HANDLE *pudev, uint8_t *pbuf, uint16_t Len)
Transmit data on the control pipe.
Definition: usb_core.c:543
void USB_EP_Stall(USB_CORE_HANDLE *pudev, uint8_t EpID)
Set an endpoint to STALL status.
Definition: usb_core.c:438
void USBD_GetUnicodeString(uint8_t *desc, uint8_t *unicode, uint16_t *len)
Convert normal string into unicode one.
Definition: usbd_enum.c:795
void USBD_ParseSetupRequest(USB_CORE_HANDLE *pudev, USB_DEVICE_REQ *req)
Decode setup data packet.
Definition: usbd_enum.c:736
USB enumeration function prototypes.
USBD_Status USBD_ClrCfg(USB_DEVICE_HANDLE *pudev, uint8_t ConfigIndex)
Clear current configuration.
Definition: usbd_core.c:287
USB standard device request struct.
Definition: usb_core.h:122
Generated by   doxygen 1.8.10