1 /*!
2     \file    usbd_enum.c
3     \brief   USB enumeration function
4 
5     \version 2020-08-04, V1.1.0, firmware for GD32VF103
6 */
7 
8 /*
9     Copyright (c) 2020, GigaDevice Semiconductor Inc.
10 
11     Redistribution and use in source and binary forms, with or without modification,
12 are permitted provided that the following conditions are met:
13 
14     1. Redistributions of source code must retain the above copyright notice, this
15        list of conditions and the following disclaimer.
16     2. Redistributions in binary form must reproduce the above copyright notice,
17        this list of conditions and the following disclaimer in the documentation
18        and/or other materials provided with the distribution.
19     3. Neither the name of the copyright holder nor the names of its contributors
20        may be used to endorse or promote products derived from this software without
21        specific prior written permission.
22 
23     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
32 OF SUCH DAMAGE.
33 */
34 
35 #include "usbd_enum.h"
36 #include "usb_ch9_std.h"
37 
38 #ifdef WINUSB_EXEMPT_DRIVER
39 
40 extern usbd_status usbd_OEM_req(usb_dev *udev, usb_req *req);
41 
42 #endif /* WINUSB_EXEMPT_DRIVER */
43 
44 /* local function prototypes ('static') */
45 static usb_reqsta _usb_std_reserved         (usb_core_driver *udev, usb_req *req);
46 static uint8_t* _usb_dev_desc_get           (usb_core_driver *udev, uint8_t index, uint16_t *len);
47 static uint8_t* _usb_config_desc_get        (usb_core_driver *udev, uint8_t index, uint16_t *len);
48 static uint8_t* _usb_bos_desc_get           (usb_core_driver *udev, uint8_t index, uint16_t *len);
49 static uint8_t* _usb_str_desc_get           (usb_core_driver *udev, uint8_t index, uint16_t *len);
50 static usb_reqsta _usb_std_getstatus        (usb_core_driver *udev, usb_req *req);
51 static usb_reqsta _usb_std_clearfeature     (usb_core_driver *udev, usb_req *req);
52 static usb_reqsta _usb_std_setfeature       (usb_core_driver *udev, usb_req *req);
53 static usb_reqsta _usb_std_setaddress       (usb_core_driver *udev, usb_req *req);
54 static usb_reqsta _usb_std_getdescriptor    (usb_core_driver *udev, usb_req *req);
55 static usb_reqsta _usb_std_setdescriptor    (usb_core_driver *udev, usb_req *req);
56 static usb_reqsta _usb_std_getconfiguration (usb_core_driver *udev, usb_req *req);
57 static usb_reqsta _usb_std_setconfiguration (usb_core_driver *udev, usb_req *req);
58 static usb_reqsta _usb_std_getinterface     (usb_core_driver *udev, usb_req *req);
59 static usb_reqsta _usb_std_setinterface     (usb_core_driver *udev, usb_req *req);
60 static usb_reqsta _usb_std_synchframe       (usb_core_driver *udev, usb_req *req);
61 
62 static usb_reqsta (*_std_dev_req[])(usb_core_driver *udev, usb_req *req) =
63 {
64     [USB_GET_STATUS]        = _usb_std_getstatus,
65     [USB_CLEAR_FEATURE]     = _usb_std_clearfeature,
66     [USB_RESERVED2]         = _usb_std_reserved,
67     [USB_SET_FEATURE]       = _usb_std_setfeature,
68     [USB_RESERVED4]         = _usb_std_reserved,
69     [USB_SET_ADDRESS]       = _usb_std_setaddress,
70     [USB_GET_DESCRIPTOR]    = _usb_std_getdescriptor,
71     [USB_SET_DESCRIPTOR]    = _usb_std_setdescriptor,
72     [USB_GET_CONFIGURATION] = _usb_std_getconfiguration,
73     [USB_SET_CONFIGURATION] = _usb_std_setconfiguration,
74     [USB_GET_INTERFACE]     = _usb_std_getinterface,
75     [USB_SET_INTERFACE]     = _usb_std_setinterface,
76     [USB_SYNCH_FRAME]       = _usb_std_synchframe,
77 };
78 
79 /* get standard descriptor handler */
80 static uint8_t* (*std_desc_get[])(usb_core_driver *udev, uint8_t index, uint16_t *len) = {
81     [(uint8_t)USB_DESCTYPE_DEV - 1U]    = _usb_dev_desc_get,
82     [(uint8_t)USB_DESCTYPE_CONFIG - 1U] = _usb_config_desc_get,
83     [(uint8_t)USB_DESCTYPE_STR - 1U]    = _usb_str_desc_get
84 };
85 
86 /*!
87     \brief      handle USB standard device request
88     \param[in]  udev: pointer to USB device instance
89     \param[in]  req: pointer to USB device request
90     \param[out] none
91     \retval     USB device request status
92 */
usbd_standard_request(usb_core_driver * udev,usb_req * req)93 usb_reqsta usbd_standard_request (usb_core_driver *udev, usb_req *req)
94 {
95     return (*_std_dev_req[req->bRequest])(udev, req);
96 }
97 
98 /*!
99     \brief      handle USB device class request
100     \param[in]  udev: pointer to USB device instance
101     \param[in]  req: pointer to USB device class request
102     \param[out] none
103     \retval     USB device request status
104 */
usbd_class_request(usb_core_driver * udev,usb_req * req)105 usb_reqsta usbd_class_request (usb_core_driver *udev, usb_req *req)
106 {
107     if ((uint8_t)USBD_CONFIGURED == udev->dev.cur_status) {
108         if (BYTE_LOW(req->wIndex) <= USBD_ITF_MAX_NUM) {
109             /* call device class handle function */
110             return (usb_reqsta)udev->dev.class_core->req_proc(udev, req);
111         }
112     }
113 
114     return REQ_NOTSUPP;
115 }
116 
117 /*!
118     \brief      handle USB vendor request
119     \param[in]  udev: pointer to USB device instance
120     \param[in]  req: pointer to USB vendor request
121     \param[out] none
122     \retval     USB device request status
123 */
usbd_vendor_request(usb_core_driver * udev,usb_req * req)124 usb_reqsta usbd_vendor_request (usb_core_driver *udev, usb_req *req)
125 {
126     (void)udev;
127     (void)req;
128 
129     /* added by user... */
130 #ifdef WINUSB_EXEMPT_DRIVER
131    usbd_OEM_req(udev, req);
132 #endif
133 
134     return REQ_SUPP;
135 }
136 
137 /*!
138     \brief      handle USB enumeration error
139     \param[in]  udev: pointer to USB device instance
140     \param[in]  req: pointer to USB device request
141     \param[out] none
142     \retval     none
143 */
usbd_enum_error(usb_core_driver * udev,usb_req * req)144 void usbd_enum_error (usb_core_driver *udev, usb_req *req)
145 {
146     (void)req;
147 
148     (void)usbd_ep_stall (udev, 0x80U);
149     (void)usbd_ep_stall (udev, 0x00U);
150 
151     usb_ctlep_startout(udev);
152 }
153 
154 /*!
155     \brief      convert hex 32bits value into unicode char
156     \param[in]  value: hex 32bits value
157     \param[in]  pbuf: buffer pointer to store unicode char
158     \param[in]  len: value length
159     \param[out] none
160     \retval     none
161 */
int_to_unicode(uint32_t value,uint8_t * pbuf,uint8_t len)162 void int_to_unicode (uint32_t value, uint8_t *pbuf, uint8_t len)
163 {
164     uint8_t index;
165 
166     for (index = 0U; index < len; index++) {
167         if ((value >> 28U) < 0x0AU) {
168             pbuf[2U * index] = (uint8_t)((value >> 28U) + '0');
169         } else {
170             pbuf[2U * index] = (uint8_t)((value >> 28U) + 'A' - 10U);
171         }
172 
173         value = value << 4U;
174 
175         pbuf[2U * index + 1U] = 0U;
176     }
177 }
178 
179 /*!
180     \brief      convert hex 32bits value into unicode char
181     \param[in]  unicode_str: pointer to unicode string
182     \param[out] none
183     \retval     none
184 */
serial_string_get(uint16_t * unicode_str)185 void serial_string_get (uint16_t *unicode_str)
186 {
187     if ((unicode_str[0] & 0x00FFU) != 6U) {
188         uint32_t DeviceSerial0, DeviceSerial1, DeviceSerial2;
189 
190         DeviceSerial0 = *(uint32_t*)DEVICE_ID1;
191         DeviceSerial1 = *(uint32_t*)DEVICE_ID2;
192         DeviceSerial2 = *(uint32_t*)DEVICE_ID3;
193 
194         DeviceSerial0 += DeviceSerial2;
195 
196         if (0U != DeviceSerial0) {
197             int_to_unicode(DeviceSerial0, (uint8_t*)&(unicode_str[1]), 8U);
198             int_to_unicode(DeviceSerial1, (uint8_t*)&(unicode_str[9]), 4U);
199         }
200     } else {
201         uint32_t device_serial = *(uint32_t*)DEVICE_ID;
202 
203         if(0U != device_serial) {
204             unicode_str[1] = (uint16_t)(device_serial & 0x0000FFFFU);
205             unicode_str[2] = (uint16_t)((device_serial & 0xFFFF0000U) >> 16U);
206 
207         }
208     }
209 }
210 
211 /*!
212     \brief      no operation, just for reserved
213     \param[in]  udev: pointer to USB device instance
214     \param[in]  req: pointer to USB vendor request
215     \param[out] none
216     \retval     USB device request status
217 */
_usb_std_reserved(usb_core_driver * udev,usb_req * req)218 static usb_reqsta _usb_std_reserved (usb_core_driver *udev, usb_req *req)
219 {
220     (void)udev;
221     (void)req;
222 
223     /* no operation... */
224 
225     return REQ_NOTSUPP;
226 }
227 
228 /*!
229     \brief      get the device descriptor
230     \param[in]  udev: pointer to USB device instance
231     \param[in]  index: no use
232     \param[out] len: data length pointer
233     \retval     descriptor buffer pointer
234 */
_usb_dev_desc_get(usb_core_driver * udev,uint8_t index,uint16_t * len)235 static uint8_t* _usb_dev_desc_get (usb_core_driver *udev, uint8_t index, uint16_t *len)
236 {
237     (void)index;
238 
239     *len = udev->dev.desc->dev_desc[0];
240 
241     return udev->dev.desc->dev_desc;
242 }
243 
244 /*!
245     \brief      get the configuration descriptor
246     \brief[in]  udev: pointer to USB device instance
247     \brief[in]  index: no use
248     \param[out] len: data length pointer
249     \retval     descriptor buffer pointer
250 */
_usb_config_desc_get(usb_core_driver * udev,uint8_t index,uint16_t * len)251 static uint8_t* _usb_config_desc_get (usb_core_driver *udev, uint8_t index, uint16_t *len)
252 {
253     (void)index;
254 
255     *len = udev->dev.desc->config_desc[2];
256 
257     return udev->dev.desc->config_desc;
258 }
259 
260 /*!
261     \brief      get the BOS descriptor
262     \brief[in]  udev: pointer to USB device instance
263     \brief[in]  index: no use
264     \param[out] len: data length pointer
265     \retval     descriptor buffer pointer
266 */
_usb_bos_desc_get(usb_core_driver * udev,uint8_t index,uint16_t * len)267 static uint8_t* _usb_bos_desc_get (usb_core_driver *udev, uint8_t index, uint16_t *len)
268 {
269     (void)index;
270 
271     *len = udev->dev.desc->bos_desc[2];
272 
273     return udev->dev.desc->bos_desc;
274 }
275 
276 /*!
277     \brief      get string descriptor
278     \param[in]  udev: pointer to USB device instance
279     \param[in]  index: string descriptor index
280     \param[out] len: pointer to string length
281     \retval     descriptor buffer pointer
282 */
_usb_str_desc_get(usb_core_driver * udev,uint8_t index,uint16_t * len)283 static uint8_t* _usb_str_desc_get (usb_core_driver *udev, uint8_t index, uint16_t *len)
284 {
285     uint8_t *desc = udev->dev.desc->strings[index];
286 
287     *len = desc[0];
288 
289     return desc;
290 }
291 
292 /*!
293     \brief      handle Get_Status request
294     \param[in]  udev: pointer to USB device instance
295     \param[in]  req: pointer to USB device request
296     \param[out] none
297     \retval     USB device request status
298 */
_usb_std_getstatus(usb_core_driver * udev,usb_req * req)299 static usb_reqsta _usb_std_getstatus (usb_core_driver *udev, usb_req *req)
300 {
301     uint8_t recp = BYTE_LOW(req->wIndex);
302     usb_reqsta req_status = REQ_NOTSUPP;
303     usb_transc *transc = &udev->dev.transc_in[0];
304 
305     static uint8_t status[2] = {0};
306 
307     switch(req->bmRequestType & (uint8_t)USB_RECPTYPE_MASK) {
308     case USB_RECPTYPE_DEV:
309         if (((uint8_t)USBD_ADDRESSED == udev->dev.cur_status) || \
310             ((uint8_t)USBD_CONFIGURED == udev->dev.cur_status)) {
311 
312             if (udev->dev.pm.power_mode) {
313                 status[0] = USB_STATUS_SELF_POWERED;
314             } else {
315                 status[0] = 0U;
316             }
317 
318             if (udev->dev.pm.dev_remote_wakeup) {
319                 status[0] |= USB_STATUS_REMOTE_WAKEUP;
320             } else {
321                 status[0] = 0U;
322             }
323 
324             req_status = REQ_SUPP;
325         }
326         break;
327 
328     case USB_RECPTYPE_ITF:
329         if (((uint8_t)USBD_CONFIGURED == udev->dev.cur_status) && (recp <= USBD_ITF_MAX_NUM)) {
330             req_status = REQ_SUPP;
331         }
332         break;
333 
334     case USB_RECPTYPE_EP:
335         if ((uint8_t)USBD_CONFIGURED == udev->dev.cur_status) {
336             if (0x80U == (recp & 0x80U)) {
337                 status[0] = udev->dev.transc_in[EP_ID(recp)].ep_stall;
338             } else {
339                 status[0] = udev->dev.transc_out[recp].ep_stall;
340             }
341 
342             req_status = REQ_SUPP;
343         }
344         break;
345 
346     default:
347         break;
348     }
349 
350     if (REQ_SUPP == req_status) {
351         transc->xfer_buf = status;
352         transc->remain_len = 2U;
353     }
354 
355     return req_status;
356 }
357 
358 /*!
359     \brief      handle USB Clear_Feature request
360     \param[in]  udev: pointer to USB device instance
361     \param[in]  req: USB device request
362     \param[out] none
363     \retval     USB device request status
364 */
_usb_std_clearfeature(usb_core_driver * udev,usb_req * req)365 static usb_reqsta _usb_std_clearfeature (usb_core_driver *udev, usb_req *req)
366 {
367     uint8_t ep = 0U;
368 
369     switch(req->bmRequestType & (uint8_t)USB_RECPTYPE_MASK) {
370     case USB_RECPTYPE_DEV:
371         if (((uint8_t)USBD_ADDRESSED == udev->dev.cur_status) || \
372             ((uint8_t)USBD_CONFIGURED == udev->dev.cur_status)) {
373 
374             /* clear device remote wakeup feature */
375             if ((uint16_t)USB_FEATURE_REMOTE_WAKEUP == req->wValue) {
376                 udev->dev.pm.dev_remote_wakeup = 0U;
377 
378                 return REQ_SUPP;
379             }
380         }
381         break;
382 
383     case USB_RECPTYPE_ITF:
384         break;
385 
386     case USB_RECPTYPE_EP:
387         /* get endpoint address */
388         ep = BYTE_LOW(req->wIndex);
389 
390         if ((uint8_t)USBD_CONFIGURED == udev->dev.cur_status) {
391             /* clear endpoint halt feature */
392             if (((uint16_t)USB_FEATURE_EP_HALT == req->wValue) && (!CTL_EP(ep))) {
393                 (void)usbd_ep_stall_clear (udev, ep);
394 
395                 (void)udev->dev.class_core->req_proc (udev, req);
396             }
397 
398             return REQ_SUPP;
399         }
400         break;
401 
402     default:
403         break;
404     }
405 
406     return REQ_NOTSUPP;
407 }
408 
409 /*!
410     \brief      handle USB Set_Feature request
411     \param[in]  udev: pointer to USB device instance
412     \param[in]  req: pointer to USB device request
413     \param[out] none
414     \retval     USB device request status
415 */
_usb_std_setfeature(usb_core_driver * udev,usb_req * req)416 static usb_reqsta _usb_std_setfeature (usb_core_driver *udev, usb_req *req)
417 {
418     uint8_t ep = 0U;
419 
420     switch (req->bmRequestType & (uint8_t)USB_RECPTYPE_MASK) {
421     case USB_RECPTYPE_DEV:
422         if (((uint8_t)USBD_ADDRESSED == udev->dev.cur_status) || \
423             ((uint8_t)USBD_CONFIGURED == udev->dev.cur_status)) {
424             /* set device remote wakeup feature */
425             if ((uint16_t)USB_FEATURE_REMOTE_WAKEUP == req->wValue) {
426                 udev->dev.pm.dev_remote_wakeup = 1U;
427             }
428 
429             return REQ_SUPP;
430         }
431         break;
432 
433     case USB_RECPTYPE_ITF:
434         break;
435 
436     case USB_RECPTYPE_EP:
437         /* get endpoint address */
438         ep = BYTE_LOW(req->wIndex);
439 
440         if ((uint8_t)USBD_CONFIGURED == udev->dev.cur_status) {
441             /* set endpoint halt feature */
442             if (((uint16_t)USB_FEATURE_EP_HALT == req->wValue) && (!CTL_EP(ep))) {
443                 (void)usbd_ep_stall (udev, ep);
444             }
445 
446             return REQ_SUPP;
447         }
448         break;
449 
450     default:
451         break;
452     }
453 
454     return REQ_NOTSUPP;
455 }
456 
457 /*!
458     \brief      handle USB Set_Address request
459     \param[in]  udev: pointer to USB device instance
460     \param[in]  req: pointer to USB device request
461     \param[out] none
462     \retval     USB device request status
463 */
_usb_std_setaddress(usb_core_driver * udev,usb_req * req)464 static usb_reqsta _usb_std_setaddress (usb_core_driver *udev, usb_req *req)
465 {
466     if ((0U == req->wIndex) && (0U == req->wLength)) {
467         udev->dev.dev_addr = (uint8_t)(req->wValue) & 0x7FU;
468 
469         if (udev->dev.cur_status != (uint8_t)USBD_CONFIGURED) {
470             usbd_addr_set (udev, udev->dev.dev_addr);
471 
472             if (udev->dev.dev_addr) {
473                 udev->dev.cur_status = (uint8_t)USBD_ADDRESSED;
474             } else {
475                 udev->dev.cur_status = (uint8_t)USBD_DEFAULT;
476             }
477 
478             return REQ_SUPP;
479         }
480     }
481 
482     return REQ_NOTSUPP;
483 }
484 
485 /*!
486     \brief      handle USB Get_Descriptor request
487     \param[in]  udev: pointer to USB device instance
488     \param[in]  req: pointer to USB device request
489     \param[out] none
490     \retval     USB device request status
491 */
_usb_std_getdescriptor(usb_core_driver * udev,usb_req * req)492 static usb_reqsta _usb_std_getdescriptor (usb_core_driver *udev, usb_req *req)
493 {
494     uint8_t desc_type = 0U;
495     uint8_t desc_index = 0U;
496 
497     usb_reqsta status = REQ_NOTSUPP;
498 
499     usb_transc *transc = &udev->dev.transc_in[0];
500 
501     /* get device standard descriptor */
502     switch (req->bmRequestType & USB_RECPTYPE_MASK) {
503     case USB_RECPTYPE_DEV:
504         desc_type = BYTE_HIGH(req->wValue);
505         desc_index = BYTE_LOW(req->wValue);
506 
507         switch (desc_type) {
508         case USB_DESCTYPE_DEV:
509             transc->xfer_buf = std_desc_get[desc_type - 1U](udev, desc_index, (uint16_t *)&(transc->remain_len));
510 
511             if (64U == req->wLength) {
512                 transc->remain_len = 8U;
513             }
514             break;
515 
516         case USB_DESCTYPE_CONFIG:
517             transc->xfer_buf = std_desc_get[desc_type - 1U](udev, desc_index, (uint16_t *)&(transc->remain_len));
518             break;
519 
520         case USB_DESCTYPE_STR:
521             if (desc_index < (uint8_t)STR_IDX_MAX) {
522                 transc->xfer_buf = std_desc_get[desc_type - 1U](udev, desc_index, (uint16_t *)&(transc->remain_len));
523             }
524             break;
525 
526         case USB_DESCTYPE_ITF:
527         case USB_DESCTYPE_EP:
528         case USB_DESCTYPE_DEV_QUALIFIER:
529         case USB_DESCTYPE_OTHER_SPD_CONFIG:
530         case USB_DESCTYPE_ITF_POWER:
531             break;
532 
533         case USB_DESCTYPE_BOS:
534             transc->xfer_buf = _usb_bos_desc_get(udev, desc_index, (uint16_t *)&(transc->remain_len));
535             break;
536 
537         default:
538             break;
539         }
540         break;
541 
542     case USB_RECPTYPE_ITF:
543         /* get device class special descriptor */
544         status = (usb_reqsta)(udev->dev.class_core->req_proc(udev, req));
545         break;
546 
547     case USB_RECPTYPE_EP:
548         break;
549 
550     default:
551         break;
552     }
553 
554     if ((0U != transc->remain_len) && (0U != req->wLength)) {
555         if (transc->remain_len < req->wLength) {
556             if ((transc->remain_len >= transc->max_len) && (0U == (transc->remain_len % transc->max_len))) {
557                 udev->dev.control.ctl_zlp = 1U;
558             }
559         } else {
560             transc->remain_len = req->wLength;
561         }
562 
563         status = REQ_SUPP;
564     }
565 
566     return status;
567 }
568 
569 /*!
570     \brief      handle USB Set_Descriptor request
571     \param[in]  udev: pointer to USB device instance
572     \param[in]  req: pointer to USB device request
573     \param[out] none
574     \retval     USB device request status
575 */
_usb_std_setdescriptor(usb_core_driver * udev,usb_req * req)576 static usb_reqsta _usb_std_setdescriptor (usb_core_driver *udev, usb_req *req)
577 {
578     (void)udev;
579     (void)req;
580 
581     /* no handle... */
582     return REQ_SUPP;
583 }
584 
585 /*!
586     \brief      handle USB Get_Configuration request
587     \param[in]  udev: pointer to USB device instance
588     \param[in]  req: pointer to USB device request
589     \param[out] none
590     \retval     USB device request status
591 */
_usb_std_getconfiguration(usb_core_driver * udev,usb_req * req)592 static usb_reqsta _usb_std_getconfiguration (usb_core_driver *udev, usb_req *req)
593 {
594     (void)req;
595 
596     usb_reqsta req_status = REQ_NOTSUPP;
597     usb_transc *transc = &udev->dev.transc_in[0];
598 
599     switch (udev->dev.cur_status) {
600     case USBD_ADDRESSED:
601         if (USB_DEFAULT_CONFIG == udev->dev.config) {
602             req_status = REQ_SUPP;
603         }
604         break;
605 
606     case USBD_CONFIGURED:
607         if (udev->dev.config != USB_DEFAULT_CONFIG) {
608             req_status = REQ_SUPP;
609         }
610         break;
611 
612     default:
613         break;
614     }
615 
616     if (REQ_SUPP == req_status) {
617         transc->xfer_buf = &(udev->dev.config);
618         transc->remain_len = 1U;
619     }
620 
621     return req_status;
622 }
623 
624 /*!
625     \brief      handle USB Set_Configuration request
626     \param[in]  udev: pointer to USB device instance
627     \param[in]  req: pointer to USB device request
628     \param[out] none
629     \retval     USB device request status
630 */
_usb_std_setconfiguration(usb_core_driver * udev,usb_req * req)631 static usb_reqsta _usb_std_setconfiguration (usb_core_driver *udev, usb_req *req)
632 {
633     static uint8_t config;
634     usb_reqsta status = REQ_NOTSUPP;
635 
636     config = (uint8_t)(req->wValue);
637 
638     if (config <= USBD_CFG_MAX_NUM) {
639         switch (udev->dev.cur_status) {
640         case USBD_ADDRESSED:
641             if (config){
642                 (void)udev->dev.class_core->init(udev, config);
643 
644                 udev->dev.config = config;
645                 udev->dev.cur_status = (uint8_t)USBD_CONFIGURED;
646             }
647 
648             status = REQ_SUPP;
649             break;
650 
651         case USBD_CONFIGURED:
652             if (USB_DEFAULT_CONFIG == config) {
653                 (void)udev->dev.class_core->deinit(udev, config);
654 
655                 udev->dev.config = config;
656                 udev->dev.cur_status = (uint8_t)USBD_ADDRESSED;
657             } else if (config != udev->dev.config) {
658                 /* clear old configuration */
659                 (void)udev->dev.class_core->deinit(udev, config);
660 
661                 /* set new configuration */
662                 udev->dev.config = config;
663 
664                 (void)udev->dev.class_core->init(udev, config);
665             } else {
666                 /* no operation */
667             }
668 
669             status = REQ_SUPP;
670             break;
671 
672         case USBD_DEFAULT:
673             break;
674 
675         default:
676             break;
677         }
678     }
679 
680     return status;
681 }
682 
683 /*!
684     \brief      handle USB Get_Interface request
685     \param[in]  udev: pointer to USB device instance
686     \param[in]  req: pointer to USB device request
687     \param[out] none
688     \retval     USB device request status
689 */
_usb_std_getinterface(usb_core_driver * udev,usb_req * req)690 static usb_reqsta _usb_std_getinterface (usb_core_driver *udev, usb_req *req)
691 {
692     switch (udev->dev.cur_status) {
693     case USBD_DEFAULT:
694         break;
695 
696     case USBD_ADDRESSED:
697         break;
698 
699     case USBD_CONFIGURED:
700         if (BYTE_LOW(req->wIndex) <= USBD_ITF_MAX_NUM) {
701             usb_transc *transc = &udev->dev.transc_in[0];
702 
703             transc->xfer_buf = &(udev->dev.class_core->alter_set);
704             transc->remain_len = 1U;
705 
706             return REQ_SUPP;
707         }
708         break;
709 
710     default:
711         break;
712     }
713 
714     return REQ_NOTSUPP;
715 }
716 
717 /*!
718     \brief      handle USB Set_Interface request
719     \param[in]  udev: pointer to USB device instance
720     \param[in]  req: pointer to USB device request
721     \param[out] none
722     \retval     USB device request status
723 */
_usb_std_setinterface(usb_core_driver * udev,usb_req * req)724 static usb_reqsta _usb_std_setinterface (usb_core_driver *udev, usb_req *req)
725 {
726     switch (udev->dev.cur_status) {
727     case USBD_DEFAULT:
728         break;
729 
730     case USBD_ADDRESSED:
731         break;
732 
733     case USBD_CONFIGURED:
734         if (BYTE_LOW(req->wIndex) <= USBD_ITF_MAX_NUM) {
735             if (NULL != udev->dev.class_core->set_intf) {
736                 (void)udev->dev.class_core->set_intf (udev, req);
737             }
738 
739             return REQ_SUPP;
740         }
741         break;
742 
743     default:
744         break;
745     }
746 
747     return REQ_NOTSUPP;
748 }
749 
750 /*!
751     \brief      handle USB SynchFrame request
752     \param[in]  udev: pointer to USB device instance
753     \param[in]  req: pointer to USB device request
754     \param[out] none
755     \retval     USB device request status
756 */
_usb_std_synchframe(usb_core_driver * udev,usb_req * req)757 static usb_reqsta _usb_std_synchframe (usb_core_driver *udev, usb_req *req)
758 {
759     (void)udev;
760     (void)req;
761 
762     /* no handle */
763     return REQ_SUPP;
764 }
765