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