blob: 3cfd7bcb43b621fcf0fe02983d40d497d50c987e [file] [log] [blame]
Kévin Redon69b92d92019-01-24 16:39:20 +01001/**
2 * \file
3 *
4 * \brief USB Device Stack Core Layer Implementation.
5 *
6 * Copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries.
7 *
8 * \asf_license_start
9 *
10 * \page License
11 *
12 * Subject to your compliance with these terms, you may use Microchip
13 * software and any derivatives exclusively with Microchip products.
14 * It is your responsibility to comply with third party license terms applicable
15 * to your use of third party software (including open source software) that
16 * may accompany Microchip software.
17 *
18 * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
19 * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
20 * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
21 * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
22 * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
23 * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
24 * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
25 * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
26 * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
27 * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
28 * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
29 *
30 * \asf_license_stop
31 *
32 */
33
34#include "usbdc.h"
35
36#define USBDC_VERSION 0x00000001u
37
38/**
39 * \brief USB Device Core Sof Handler
40 */
41struct usbdc_sof_handler {
42 struct usbdc_sof_handler *next;
43 usbdc_sof_cb_t cb;
44};
45
46/**
47 * \brief USB Device Core Request Handler
48 */
49struct usbdc_req_handler {
50 struct usbdc_req_handler *next;
51 usbdc_req_cb_t cb;
52};
53
54/**
55 * \brief USB Device Core Change Handler
56 */
57struct usbdc_change_handler {
58 struct usbdc_change_handler *next;
59 usbdc_change_cb_t cb;
60};
61
62/**
63 * \brief USB Device Core Handler
64 */
65struct usbdc_handlers {
66 struct list_descriptor sof_list;
67 struct list_descriptor req_list;
68 struct list_descriptor change_list;
69};
70
71/**
72 * \brief USB Device Core Driver Structure
73 */
74struct usbdc_driver {
75 /** Pointer to descriptions of descriptors. */
76 struct usbdc_descriptors desces;
77 /** Callback handlers. */
78 struct usbdc_handlers handlers;
79 /** list of function drivers. */
80 struct list_descriptor func_list;
81 /** Control buffer. */
82 uint8_t *ctrl_buf;
83 /** Device status. */
84 uint16_t status;
85 /** Device state. */
86 uint8_t state;
87 /** Configuration value. */
88 uint8_t cfg_value;
89 /** Control endpoint size. */
90 uint8_t ctrl_size;
91 /** Alternate interface used map */
92 uint8_t ifc_alt_map;
93};
94
95/**
96 * \brief USB Device Core Driver Instance
97 */
98static struct usbdc_driver usbdc;
99
100/**
101 * \brief Process the GetDeviceDescriptor request
102 * \param[in] ep Endpoint address.
103 * \param[in] req Pointer to the request.
104 * \return Operation status.
105 * \retval true Request is handled OK.
106 * \retval false Request not supported.
107 */
108static bool usbdc_get_dev_desc(const uint8_t ep, struct usb_req *req)
109{
110 uint8_t *dev_desc = NULL;
111 uint16_t length = req->wLength;
112 if (length > 0x12) {
113 length = 0x12;
114 }
115#if CONF_USBD_HS_SP
116 if (usb_d_get_speed() == USB_SPEED_HS && usbdc.desces.hs) {
117 dev_desc = usb_find_desc(usbdc.desces.hs->sod, usbdc.desces.hs->eod, USB_DT_DEVICE);
118 } else {
119 /* Obtain descriptor from FS descriptors */
120 }
121#endif
122 if (!dev_desc) {
123 dev_desc = usb_find_desc(usbdc.desces.ls_fs->sod, usbdc.desces.ls_fs->eod, USB_DT_DEVICE);
124 }
125 if (!dev_desc) {
126 return false;
127 }
128 if (ERR_NONE != usbdc_xfer(ep, dev_desc, length, false)) {
129 return false;
130 }
131 return true;
132}
133
134/**
135 * \brief Process the GetConfigurationDescriptor request
136 * \param[in] ep Endpoint address.
137 * \param[in] req Pointer to the request.
138 * \return Operation status.
139 * \retval true Request is handled OK.
140 * \retval false Request not supported.
141 */
142static bool usbdc_get_cfg_desc(const uint8_t ep, struct usb_req *req)
143{
144 uint8_t *cfg_desc = NULL;
145 uint16_t total_len;
146 uint16_t length = req->wLength;
147 uint8_t index = req->wValue & 0x00FF;
148 bool need_zlp = !(length & (usbdc.ctrl_size - 1));
149
150#if CONF_USBD_HS_SP
151 if (usb_d_get_speed() == USB_SPEED_HS && usbdc.desces.hs) {
152 cfg_desc = usb_find_cfg_desc(usbdc.desces.hs->sod, usbdc.desces.hs->eod, index + 1);
153 } else {
154 /* Obtain descriptor from FS descriptors */
155 }
156#endif
157 if (!cfg_desc) {
158 cfg_desc = usb_find_cfg_desc(usbdc.desces.ls_fs->sod, usbdc.desces.ls_fs->eod, index + 1);
159 }
160 if (NULL == cfg_desc) {
161 return false;
162 }
163 total_len = usb_cfg_desc_total_len(cfg_desc);
164 if (length <= total_len) {
165 need_zlp = false;
166 } else {
167 length = total_len;
168 }
169 if (ERR_NONE != usbdc_xfer(ep, cfg_desc, length, need_zlp)) {
170 return false;
171 }
172 return true;
173}
174
175/**
176 * \brief Process the GetStringDescriptor request
177 * \param[in] ep Endpoint address.
178 * \param[in] req Pointer to the request.
179 * \return Operation status.
180 * \retval true Request is handled OK.
181 * \retval false Request not supported.
182 */
183static bool usbdc_get_str_desc(const uint8_t ep, struct usb_req *req)
184{
185 uint8_t *str_desc;
186 uint16_t length = req->wLength;
187 uint8_t index = req->wValue & 0x00FF;
188 bool need_zlp = !(length & (usbdc.ctrl_size - 1));
189 /* All string are in default descriptors block: FS/LS */
190 str_desc = usb_find_str_desc(usbdc.desces.ls_fs->sod, usbdc.desces.ls_fs->eod, index);
191 if (NULL == str_desc) {
192 return false;
193 }
194 if (length <= str_desc[0]) {
195 need_zlp = false;
196 } else {
197 length = str_desc[0];
198 }
199 if (ERR_NONE != usbdc_xfer(ep, str_desc, length, need_zlp)) {
200 return false;
201 }
202 return true;
203}
204
205#if CONF_USBD_HS_SP
206/**
207 * \brief Process the GetDeviceQualifierDescriptor request
208 * \param[in] ep Endpoint address.
209 * \param[in] req Pointer to the request.
210 * \return Operation status.
211 * \retval true Request is handled OK.
212 * \retval false Request not supported.
213 */
214static bool usbdc_get_devqual_desc(const uint8_t ep, struct usb_req *req)
215{
216 uint8_t *dev_desc = NULL;
217 uint16_t length = req->wLength;
218 if (length > 0x12) {
219 length = 0x12;
220 }
221 if (usb_d_get_speed() == USB_SPEED_HS && usbdc.desces.hs) {
222 dev_desc = usb_find_desc(usbdc.desces.hs->sod, usbdc.desces.hs->eod, USB_DT_DEVICE_QUALIFIER);
223 }
224 if (!dev_desc) {
225 dev_desc = usb_find_desc(usbdc.desces.ls_fs->sod, usbdc.desces.ls_fs->eod, USB_DT_DEVICE_QUALIFIER);
226 }
227 if (!dev_desc) {
228 return false;
229 }
230 if (ERR_NONE != usbdc_xfer(ep, dev_desc, length, false)) {
231 return false;
232 }
233 return true;
234}
235
236/**
237 * \brief Process the GetOtherSpeedConfigurationDescriptor request
238 * \param[in] ep Endpoint address.
239 * \param[in] req Pointer to the request.
240 * \return Operation status.
241 * \retval true Request is handled OK.
242 * \retval false Request not supported.
243 */
244static bool usbdc_get_othspdcfg_desc(const uint8_t ep, struct usb_req *req)
245{
246 uint8_t *cfg_desc = NULL;
247 uint16_t total_len;
248 uint16_t length = req->wLength;
249 uint8_t index = req->wValue & 0x00FF;
250 bool need_zlp = !(length & (usbdc.ctrl_size - 1));
251
252 if (usb_d_get_speed() == USB_SPEED_HS && usbdc.desces.hs) {
253 cfg_desc = usb_find_othspdcfg_desc(usbdc.desces.hs->sod, usbdc.desces.hs->eod, index + 1);
254 } else {
255 /* Obtain descriptor from FS descriptors */
256 }
257 if (!cfg_desc) {
258 cfg_desc = usb_find_othspdcfg_desc(usbdc.desces.ls_fs->sod, usbdc.desces.ls_fs->eod, index + 1);
259 }
260 if (NULL == cfg_desc) {
261 return false;
262 }
263 total_len = usb_cfg_desc_total_len(cfg_desc);
264 if (length <= total_len) {
265 need_zlp = false;
266 } else {
267 length = total_len;
268 }
269 if (ERR_NONE != usbdc_xfer(ep, cfg_desc, length, need_zlp)) {
270 return false;
271 }
272 return true;
273}
274#endif
275
276/**
277 * \brief Process the GetDescriptor request
278 * \param[in] ep Endpoint address.
279 * \param[in] req Pointer to the request.
280 * \return Operation status.
281 * \retval true Request is handled OK.
282 * \retval false Request not supported.
283 */
284static bool usbdc_get_desc_req(const uint8_t ep, struct usb_req *req)
285{
286 uint8_t type = (uint8_t)(req->wValue >> 8);
287 switch (type) {
288 case USB_DT_DEVICE:
289 return usbdc_get_dev_desc(ep, req);
290 case USB_DT_CONFIG:
291 return usbdc_get_cfg_desc(ep, req);
292#if CONF_USBD_HS_SP
293 case USB_DT_DEVICE_QUALIFIER:
294 return usbdc_get_devqual_desc(ep, req);
295 case USB_DT_OTHER_SPEED_CONFIG:
296 return usbdc_get_othspdcfg_desc(ep, req);
297#endif
298 case USB_DT_STRING:
299 return usbdc_get_str_desc(ep, req);
300 default:
301 break;
302 }
303 return false;
304}
305
306/**
307 * \brief Process the GetStatus request
308 * \param[in] ep Endpoint address.
309 * \param[in] req Pointer to the request.
310 * \return Operation status.
311 * \retval true Request is handled OK.
312 * \retval false Request not supported.
313 */
314static bool usbdc_get_status_req(const uint8_t ep, const struct usb_req *req)
315{
316 int32_t st;
317 (void)ep;
318
319 switch (req->bmRequestType & USB_REQT_RECIP_MASK) {
320 case USB_REQT_RECIP_DEVICE:
321 case USB_REQT_RECIP_INTERFACE:
322 st = 0;
323 break;
324 case USB_REQT_RECIP_ENDPOINT:
325 st = usb_d_ep_halt(req->wIndex & 0xFF, USB_EP_HALT_GET);
326 if (st < 0) {
327 return false;
328 }
329 st = st & 0x1;
330 break;
331 default:
332 return false;
333 }
334 memcpy(usbdc.ctrl_buf, &st, 2);
335 usbdc_xfer(ep, usbdc.ctrl_buf, 2, false);
336 return true;
337}
338
339/**
340 * \brief Process the standard Get Interface
341 * \param[in] req Point to usb request struct.
342 * \return Operation status.
343 * \retval true Request is handled OK.
344 * \retval false Request not supported.
345 */
346static bool usbdc_get_interface(struct usb_req *req)
347{
348 struct usbdf_driver *func = (struct usbdf_driver *)usbdc.func_list.head;
349 int32_t rc;
350
351 if (!(usbdc.ifc_alt_map & (1 << req->wIndex))) {
352 /* Return 0 if alternate is not used */
353 usbdc.ctrl_buf[0] = 0;
354 usbdc_xfer(0, usbdc.ctrl_buf, 1, false);
355 return true;
356 }
357 /* Check function drivers only if alternate is used */
358 while (NULL != func) {
359 if (0 > (rc = func->ctrl(func, USBDF_GET_IFACE, req))) {
360 func = func->next;
361 } else {
362 usbdc.ctrl_buf[0] = (uint8_t)rc;
363 usbdc_xfer(0, usbdc.ctrl_buf, 1, false);
364 return true;
365 }
366 }
367 return false;
368}
369
370/**
371 * \brief Process the standard Get request
372 * \param[in] ep Endpoint address.
373 * \param[in] req Pointer to the request.
374 * \return Operation status.
375 * \retval true Request is handled OK.
376 * \retval false Request not supported.
377 */
378static bool usbdc_get_req(const uint8_t ep, struct usb_req *req)
379{
380 switch (req->bRequest) {
381 case USB_REQ_GET_DESC:
382 return usbdc_get_desc_req(ep, req);
383 case USB_REQ_GET_CONFIG:
384 *(uint8_t *)usbdc.ctrl_buf = usbdc.cfg_value;
385 usbdc_xfer(ep, usbdc.ctrl_buf, 1, false);
386 return true;
387 case USB_REQ_GET_STATUS:
388 return usbdc_get_status_req(ep, req);
389 case USB_REQ_GET_INTERFACE:
390 return usbdc_get_interface(req);
391 default:
392 return false;
393 }
394}
395
396/**
397 * \brief Process the standard ClearFeature request
398 * \param[in] ep Endpoint address.
399 * \param[in] req Pointer to the request.
400 * \return Operation status.
401 * \retval true Request is handled OK.
402 * \retval false Request not supported.
403 */
404static bool usbdc_clear_ftr_req(const uint8_t ep, const struct usb_req *req)
405{
406 (void)ep;
407 switch (req->bmRequestType & USB_REQT_RECIP_MASK) {
408 case USB_REQT_RECIP_ENDPOINT:
409 if (req->wLength != 0) {
410 return false;
411 }
412 usb_d_ep_halt(req->wIndex & 0xFF, USB_EP_HALT_CLR);
413 usbdc_xfer(ep, NULL, 0, true);
414 return true;
415 default:
416 return false;
417 }
418}
419
420/**
421 * \brief Process the standard SetFeature request
422 * \param[in] ep Endpoint address.
423 * \param[in] req Pointer to the request.
424 * \return Operation status.
425 * \retval true Request is handled OK.
426 * \retval false Request not supported.
427 */
428static bool usbdc_set_ftr_req(const uint8_t ep, const struct usb_req *req)
429{
430 (void)ep;
431 switch (req->bmRequestType & USB_REQT_RECIP_MASK) {
432 case USB_REQT_RECIP_ENDPOINT:
433 if (req->wLength != 0) {
434 return false;
435 }
436 usb_d_ep_halt(req->wIndex & 0xFF, USB_EP_HALT_SET);
437 usbdc_xfer(ep, NULL, 0, true);
438 return true;
439 default:
440 return false;
441 }
442}
443
444/**
445 * \brief Unconfig, close all interfaces
446 */
447static void usbdc_unconfig(void)
448{
449 struct usbdf_driver *func = (struct usbdf_driver *)usbdc.func_list.head;
450 while (NULL != func) {
451 func->ctrl(func, USBDF_DISABLE, NULL);
452 func = func->next;
453 }
454}
455
456/**
457 * \brief Apply Set Configuration Value
458 * \param[in] cfg_value Configuration Value
459 * \retval true Set configuration OK.
460 * \retval false Request error.
461 */
462static bool usbdc_set_config(uint8_t cfg_value)
463{
464 struct usbd_descriptors desc;
465 struct usbdf_driver * func;
466 uint8_t * cfg_desc = NULL;
467 uint16_t total_len;
468 uint8_t last_iface = 0xFF;
469
470 if (cfg_value == 0) {
471 usbdc_unconfig();
472 return true;
473 }
474
475#if CONF_USBD_HS_SP
476 if (usb_d_get_speed() == USB_SPEED_HS && usbdc.desces.hs) {
477 cfg_desc = usb_find_cfg_desc(usbdc.desces.hs->sod, usbdc.desces.hs->eod, cfg_value);
478 } else {
479 /* Obtain descriptor from FS descriptors */
480 }
481#endif
482 if (!cfg_desc) {
483 cfg_desc = usb_find_cfg_desc(usbdc.desces.ls_fs->sod, usbdc.desces.ls_fs->eod, cfg_value);
484 }
485 if (NULL == cfg_desc) {
486 return false;
487 }
488
489 total_len = usb_cfg_desc_total_len(cfg_desc);
490 desc.eod = cfg_desc + total_len;
491 desc.sod = usb_find_desc(cfg_desc, desc.eod, USB_DT_INTERFACE);
492
493 while (NULL != desc.sod) {
494 /* Apply very first alternate setting (must be 0) of the interface */
495 if (last_iface != desc.sod[2] /* bInterfaceNumber */) {
496 last_iface = desc.sod[2];
497 func = (struct usbdf_driver *)usbdc.func_list.head;
498 while (NULL != func) {
499 if (func->ctrl(func, USBDF_ENABLE, &desc)) {
500 func = func->next;
501 } else {
502 break;
503 }
504 }
505 }
506 desc.sod = usb_desc_next(desc.sod);
507 desc.sod = usb_find_desc(desc.sod, desc.eod, USB_DT_INTERFACE);
508 }
509 return true;
510}
511
512/**
513 * \brief Apply the USB device address
514 * \param[in] addr address to be set.
515 */
516static void usbdc_set_address(uint8_t addr)
517{
518 usb_d_set_address(addr);
519}
520
521/**
522 * \brief Process the standard Set Interface
523 * \param[in] alt_set Alternate Setting.
524 * \param[in] ifc_id Interface Index.
525 * \return Operation status.
526 * \retval true Request is handled OK.
527 * \retval false Request not supported.
528 */
529static bool usbdc_set_interface(uint16_t alt_set, uint16_t ifc_id)
530{
531 struct usbd_descriptors desc;
532 struct usbdf_driver * func;
533 uint8_t * ifc = NULL;
534
535#if CONF_USBD_HS_SP
536 if (usb_d_get_speed() == USB_SPEED_HS && usbdc.desces.hs) {
537 ifc = usb_find_cfg_desc(usbdc.desces.hs->sod, usbdc.desces.hs->eod, usbdc.cfg_value);
538 } else {
539 /* Obtain descriptor from FS descriptors */
540 }
541#endif
542 if (!ifc) {
543 ifc = usb_find_cfg_desc(usbdc.desces.ls_fs->sod, usbdc.desces.ls_fs->eod, usbdc.cfg_value);
544 }
545 if (NULL == ifc) {
546 return false;
547 }
548 desc.sod = ifc;
549 desc.eod = ifc + usb_cfg_desc_total_len(ifc);
550
551 if (NULL == (ifc = usb_find_desc(desc.sod, desc.eod, USB_DT_INTERFACE))) {
552 return false;
553 }
554
555 while (ifc[2] != ifc_id || ifc[3] != alt_set) {
556 desc.sod = usb_desc_next(desc.sod);
557 ifc = usb_find_desc(desc.sod, desc.eod, USB_DT_INTERFACE);
558 if (NULL == ifc) {
559 return false;
560 }
561 }
562
563 desc.sod = ifc;
564 func = (struct usbdf_driver *)usbdc.func_list.head;
565
566 while (NULL != func) {
567 if (func->ctrl(func, USBDF_DISABLE, &desc)) {
568 func = func->next;
569 } else if (ERR_NONE == func->ctrl(func, USBDF_ENABLE, &desc)) {
570 if (alt_set) {
571 /* Alternate settings are used from now on */
572 usbdc.ifc_alt_map |= 1 << ifc_id;
573 }
574 usbdc_xfer(0, NULL, 0, 0);
575 return true;
576 } else {
577 return false;
578 }
579 }
580
581 return false;
582}
583
584/**
585 * \brief Process the standard Set request
586 * \param[in] ep Endpoint address.
587 * \param[in] req Pointer to the request.
588 * \return Operation status.
589 * \retval true Request is handled OK.
590 * \retval false Request not supported.
591 */
592static bool usbdc_set_req(const uint8_t ep, struct usb_req *req)
593{
594 switch (req->bRequest) {
595 case USB_REQ_SET_ADDRESS:
596 return (ERR_NONE == usbdc_xfer(ep, NULL, 0, true));
597 case USB_REQ_SET_CONFIG:
598 if (!usbdc_set_config(req->wValue)) {
599 return false;
600 }
601 return (ERR_NONE == usbdc_xfer(ep, NULL, 0, true));
602 case USB_REQ_CLEAR_FTR:
603 return usbdc_clear_ftr_req(ep, req);
604 case USB_REQ_SET_FTR:
605 return usbdc_set_ftr_req(ep, req);
606 case USB_REQ_SET_INTERFACE:
607 return usbdc_set_interface(req->wValue, req->wIndex);
608 default:
609 return false;
610 }
611}
612
613/** Invoke all registered SOF callbacks. */
614static void usbdc_sof_notify(void)
615{
616 struct usbdc_sof_handler *sof = (struct usbdc_sof_handler *)usbdc.handlers.sof_list.head;
617
618 while (sof != NULL) {
619 if (NULL != sof->cb) {
620 sof->cb();
621 }
622 sof = sof->next;
623 }
624}
625
626/** Invoke all registered Change notification callbacks. */
627static void usbdc_change_notify(enum usbdc_change_type change, uint32_t value)
628{
629 struct usbdc_change_handler *cg = (struct usbdc_change_handler *)usbdc.handlers.change_list.head;
630
631 while (cg != NULL) {
632 if (NULL != cg->cb) {
633 cg->cb(change, value);
634 }
635 cg = cg->next;
636 }
637}
638
639/** Invoke all registered request callbacks until request handled. */
640static int32_t usbdc_request_handler(uint8_t ep, struct usb_req *req, enum usb_ctrl_stage stage)
641{
642 struct usbdc_req_handler *h = (struct usbdc_req_handler *)usbdc.handlers.req_list.head;
643 int32_t rc;
644
645 while (h != NULL) {
646 if (NULL != h->cb) {
647 rc = h->cb(ep, req, stage);
648 if (0 == rc) {
649 return true;
650 } else if (ERR_NOT_FOUND != rc) {
651 return -1;
652 }
653 }
654 h = h->next;
655 }
656 return false;
657}
658
659/**
660 * \brief Callback invoked on USB device SOF
661 */
662static void usbd_sof_cb(void)
663{
664 usbdc_sof_notify();
665}
666
667/**
668 * \brief Callback invoked when control request is received
669 * \param[in] ep Endpoint address.
670 * \param[in] req Pointer to the request.
671 * \return Operation status.
672 * \retval true Request is handled OK.
673 * \retval false Request not supported.
674 */
675static bool usbdc_cb_ctl_req(const uint8_t ep, struct usb_req *req)
676{
677 switch (usbdc_request_handler(ep, req, USB_SETUP_STAGE)) {
678 case true:
679 return true;
680 case -1:
681 return false;
682 default:
683 break;
684 }
685
686 // STD request handling
687 switch (req->bmRequestType & (USB_REQT_TYPE_MASK | USB_REQT_DIR_IN)) {
688 case USB_REQT_TYPE_STANDARD:
689 return usbdc_set_req(ep, req);
690 case (USB_REQT_TYPE_STANDARD | USB_REQT_DIR_IN):
691 return usbdc_get_req(ep, req);
692 default:
693 return false;
694 }
695}
696
697/**
698 * \brief When control status stage is end
699 * \param[in] req Pointer to the request.
700 */
701static void usbdc_ctrl_status_end(const struct usb_req *req)
702{
703 if (req->bmRequestType != USB_REQT_TYPE_STANDARD) {
704 return;
705 }
706 switch (req->bRequest) {
707 case USB_REQ_SET_CONFIG:
708 usbdc.cfg_value = req->wValue;
709 usbdc.state = req->wValue ? USBD_S_CONFIG : USBD_S_ADDRESS;
710 usbdc_change_notify(USBDC_C_STATE, usbdc.state);
711 break;
712 case USB_REQ_SET_ADDRESS:
713 usbdc_set_address(req->wValue);
714 usbdc.state = req->wValue ? USBD_S_ADDRESS : USBD_S_DEFAULT;
715 usbdc_change_notify(USBDC_C_STATE, usbdc.state);
716 break;
717 default:
718 break;
719 }
720}
721
722/**
723 * \brief When control data stage is end
724 * \param[in] req Pointer to the request.
725 */
726static bool usbdc_ctrl_data_end(struct usb_req *req)
727{
728 usbdc_request_handler(0, req, USB_DATA_STAGE);
729 return false;
730}
731
732/**
733 * \brief Callback invoked when control data done or status done
734 * \param[in] ep Endpoint number with direction on bit 8.
735 * \param[in] code Status code.
736 * \param[in] req Pointer to the control setup request.
737 * \return Data has error or not.
738 * \retval true There is data error, protocol error.
739 * \retval false There is no data error.
740 */
741static bool usbdc_cb_ctl_done(const uint8_t ep, const enum usb_xfer_code code, struct usb_req *req)
742{
743 (void)ep;
744
745 switch (code) {
746 case USB_XFER_DONE:
747 usbdc_ctrl_status_end(req);
748 break;
749 case USB_XFER_DATA:
750 return usbdc_ctrl_data_end(req);
751 default:
752 break;
753 }
754 return false;
755}
756
757/**
758 * \brief USB Device Core Reset
759 */
760void usbdc_reset(void)
761{
762 usbdc_unconfig();
763
764 usbdc.state = USBD_S_DEFAULT;
765 usbdc.cfg_value = 0;
766 usbdc.ifc_alt_map = 0;
767
768 // Setup EP0
769 usb_d_ep_deinit(0);
770 usb_d_ep0_init(usbdc.ctrl_size);
771 usb_d_ep_register_callback(0, USB_D_EP_CB_SETUP, (FUNC_PTR)usbdc_cb_ctl_req);
772 usb_d_ep_register_callback(0, USB_D_EP_CB_XFER, (FUNC_PTR)usbdc_cb_ctl_done);
773 usb_d_ep_enable(0);
774}
775
776/**
777 * \brief Callback invoked on USB device events
778 * \param[in] ev Event code.
779 * \param[in] param Event parameter for event handling.
780 */
781static void usbd_event_cb(const enum usb_event ev, const uint32_t param)
782{
783 (void)param;
784
785 switch (ev) {
786 case USB_EV_VBUS:
787 usbdc_change_notify(USBDC_C_CONN, param);
788 break;
789
790 case USB_EV_RESET:
791 usbdc_reset();
792 break;
793
794 default:
795 break;
796 }
797}
798
799/**
800 * \brief Issue USB device transfer
801 */
802int32_t usbdc_xfer(uint8_t ep, uint8_t *buf, uint32_t size, bool zlp)
803{
804 struct usb_d_transfer xfer = {(uint8_t *)buf, size, ep, zlp};
805 return usb_d_ep_transfer(&xfer);
806}
807
808/**
809 * \brief Register the handler
810 */
811void usbdc_register_handler(enum usbdc_handler_type type, const struct usbdc_handler *h)
812{
813 switch (type) {
814 case USBDC_HDL_SOF:
815 list_insert_at_end(&usbdc.handlers.sof_list, (void *)h);
816 break;
817 case USBDC_HDL_REQ:
818 list_insert_at_end(&usbdc.handlers.req_list, (void *)h);
819 break;
820 case USBDC_HDL_CHANGE:
821 list_insert_at_end(&usbdc.handlers.change_list, (void *)h);
822 break;
823 default:
824 break;
825 }
826}
827
828/**
829 * \brief Unregister the handler
830 */
831void usbdc_unregister_handler(enum usbdc_handler_type type, const struct usbdc_handler *h)
832{
833 switch (type) {
834 case USBDC_HDL_SOF:
835 list_delete_element(&usbdc.handlers.sof_list, (void *)h);
836 break;
837 case USBDC_HDL_REQ:
838 list_delete_element(&usbdc.handlers.req_list, (void *)h);
839 break;
840 case USBDC_HDL_CHANGE:
841 list_delete_element(&usbdc.handlers.change_list, (void *)h);
842 break;
843 default:
844 break;
845 }
846}
847
848/**
849 * \brief Initialize the USB device core driver
850 */
851int32_t usbdc_init(uint8_t *ctrl_buf)
852{
853 ASSERT(ctrl_buf);
854
855 int32_t rc;
856
857 rc = usb_d_init();
858 if (rc < 0) {
859 return rc;
860 }
861
862 memset(&usbdc, 0, sizeof(usbdc));
863 usbdc.ctrl_buf = ctrl_buf;
864 usb_d_register_callback(USB_D_CB_SOF, (FUNC_PTR)usbd_sof_cb);
865 usb_d_register_callback(USB_D_CB_EVENT, (FUNC_PTR)usbd_event_cb);
866
867 return 0;
868}
869
870/**
871 * \brief De-initialize the USB device core driver
872 */
873int32_t usbdc_deinit(void)
874{
875 usb_d_deinit();
876 return 0;
877}
878
879/**
880 * \brief Register/unregister function support of a USB device function
881 *
882 * Must be invoked when USB device is stopped.
883 */
884void usbdc_register_function(struct usbdf_driver *func)
885{
886 list_insert_at_end(&usbdc.func_list, func);
887}
888
889/**
890 * \brief Unregister function support of a USB device function
891 *
892 * Must be invoked when USB device is stopped.
893 */
894void usbdc_unregister_function(struct usbdf_driver *func)
895{
896 list_delete_element(&usbdc.func_list, func);
897}
898
899/**
900 * \brief Validate the descriptor
901 */
902int32_t usbdc_validate_desces(struct usbd_descriptors *desces)
903{
904 uint8_t *sod, *eod;
905 if (desces == NULL) {
906 return ERR_NOT_FOUND;
907 }
908 sod = usb_find_desc(desces->sod, desces->eod, USB_DT_DEVICE);
909 if (sod == NULL) {
910 return ERR_BAD_DATA;
911 }
912 sod = usb_find_desc(desces->sod, desces->eod, USB_DT_CONFIG);
913 if (sod == NULL) {
914 return ERR_BAD_DATA;
915 }
916 eod = sod + usb_cfg_desc_total_len(sod);
917 if (eod > desces->eod) {
918 return ERR_BAD_DATA;
919 }
920 return 0;
921}
922
923/**
924 * \brief Validate the descriptor
925 */
926int32_t usbdc_check_desces(struct usbdc_descriptors *desces)
927{
928#if CONF_USBD_HS_SP
929 int32_t rc;
930 if (desces->hs == NULL && desces->ls_fs == NULL) {
931 return ERR_NOT_FOUND;
932 }
933 if (desces->hs) {
934 rc = usbdc_validate_desces(desces->hs);
935 if (rc < 0) {
936 return rc;
937 }
938 }
939#endif
940 return usbdc_validate_desces(desces->ls_fs);
941}
942
943/**
944 * \brief Start the USB device driver with specific descriptors set
945 */
946int32_t usbdc_start(struct usbd_descriptors *desces)
947{
948 if (usbdc.state >= USBD_S_POWER) {
949 return ERR_BUSY;
950 }
951
952 if (desces) {
953 usbdc.desces.ls_fs = desces;
954#if CONF_USBD_HS_SP
955 usbdc.desces.hs = &desces[1];
956#endif
957 } else {
958 return ERR_BAD_DATA;
959 }
960
961 usbdc.ctrl_size = desces->sod[7];
962 usbdc.state = USBD_S_POWER;
963 usb_d_enable();
964 return ERR_NONE;
965}
966
967/**
968 * \brief Stop the USB device driver
969 */
970int32_t usbdc_stop(void)
971{
972 usb_d_disable();
973 usbdc.state = USBD_S_OFF;
974 return ERR_NONE;
975}
976
977/**
978 * \brief Attach the USB device to host
979 */
980void usbdc_attach(void)
981{
982 usb_d_attach();
983}
984
985/**
986 * \brief Detach the USB device from host
987 */
988void usbdc_detach(void)
989{
990 usb_d_detach();
991}
992
993/**
994 * \brief Send remote wakeup to host
995 */
996void usbdc_remotewakeup(void)
997{
998 usb_d_send_remotewakeup();
999 usbdc.state = USBD_S_POWER;
1000}
1001
1002/**
1003 * \brief Return USB Device endpoint0 buffer
1004 */
1005uint8_t *usbdc_get_ctrl_buffer(void)
1006{
1007 return usbdc.ctrl_buf;
1008}
1009
1010/**
1011 * \brief Return current USB state
1012 */
1013uint8_t usbdc_get_state(void)
1014{
1015 if (usbdc.state & USBD_S_SUSPEND) {
1016 return USBD_S_SUSPEND;
1017 }
1018 return usbdc.state;
1019}
1020
1021/**
1022 * \brief Return version
1023 */
1024uint32_t usbdc_get_version(void)
1025{
1026 return USBDC_VERSION;
1027}