]> git.donarmstrong.com Git - qmk_firmware.git/blob - tmk_core/protocol/arm_atsam/usb/udc.c
Merge branch 'master' into debounce_refactor
[qmk_firmware.git] / tmk_core / protocol / arm_atsam / usb / udc.c
1 /**
2  * \file
3  *
4  * \brief USB Device Controller (UDC)
5  *
6  * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved.
7  *
8  * \asf_license_start
9  *
10  * \page License
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions are met:
14  *
15  * 1. Redistributions of source code must retain the above copyright notice,
16  *    this list of conditions and the following disclaimer.
17  *
18  * 2. Redistributions in binary form must reproduce the above copyright notice,
19  *    this list of conditions and the following disclaimer in the documentation
20  *    and/or other materials provided with the distribution.
21  *
22  * 3. The name of Atmel may not be used to endorse or promote products derived
23  *    from this software without specific prior written permission.
24  *
25  * 4. This software may only be redistributed and used in connection with an
26  *    Atmel microcontroller product.
27  *
28  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
29  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
30  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
31  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
32  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  *
40  * \asf_license_stop
41  *
42  */
43 /*
44  * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
45  */
46
47 #include "conf_usb.h"
48 #include "usb_protocol.h"
49 #include "udd.h"
50 #include "udc_desc.h"
51 #include "udi_device_conf.h"
52 #include "udi.h"
53 #include "udc.h"
54 #include "md_bootloader.h"
55
56 /**
57  * \ingroup udc_group
58  * \defgroup udc_group_interne Implementation of UDC
59  *
60  * Internal implementation
61  * @{
62  */
63
64 //! \name Internal variables to manage the USB device
65 //! @{
66
67 //! Device status state (see enum usb_device_status in usb_protocol.h)
68 static le16_t udc_device_status;
69
70 COMPILER_WORD_ALIGNED
71 //! Device interface setting value
72 static uint8_t udc_iface_setting = 0;
73
74 //! Device Configuration number selected by the USB host
75 COMPILER_WORD_ALIGNED
76 static uint8_t udc_num_configuration = 0;
77
78 //! Pointer on the selected speed device configuration
79 static udc_config_speed_t UDC_DESC_STORAGE *udc_ptr_conf;
80
81 //! Pointer on interface descriptor used by SETUP request.
82 static usb_iface_desc_t UDC_DESC_STORAGE *udc_ptr_iface;
83
84 //! @}
85
86
87 //! \name Internal structure to store the USB device main strings
88 //! @{
89
90 /**
91  * \brief Language ID of USB device (US ID by default)
92  */
93 COMPILER_WORD_ALIGNED
94 static UDC_DESC_STORAGE usb_str_lgid_desc_t udc_string_desc_languageid = {
95     .desc.bLength = sizeof(usb_str_lgid_desc_t),
96     .desc.bDescriptorType = USB_DT_STRING,
97     .string = {LE16(USB_LANGID_EN_US)}
98 };
99
100 /**
101  * \brief USB device manufacture name storage
102  * String is allocated only if USB_DEVICE_MANUFACTURE_NAME is declared
103  * by usb application configuration
104  */
105 #ifdef USB_DEVICE_MANUFACTURE_NAME
106 static uint8_t udc_string_manufacturer_name[] = USB_DEVICE_MANUFACTURE_NAME;
107 #define USB_DEVICE_MANUFACTURE_NAME_SIZE (sizeof(udc_string_manufacturer_name)-1)
108 #else
109 #define USB_DEVICE_MANUFACTURE_NAME_SIZE 0
110 #endif
111
112 /**
113  * \brief USB device product name storage
114  * String is allocated only if USB_DEVICE_PRODUCT_NAME is declared
115  * by usb application configuration
116  */
117 #ifdef USB_DEVICE_PRODUCT_NAME
118 static uint8_t udc_string_product_name[] = USB_DEVICE_PRODUCT_NAME;
119 #define USB_DEVICE_PRODUCT_NAME_SIZE (sizeof(udc_string_product_name)-1)
120 #else
121 #define USB_DEVICE_PRODUCT_NAME_SIZE 0
122 #endif
123
124 #if defined USB_DEVICE_SERIAL_NAME
125 #define USB_DEVICE_SERIAL_NAME_SIZE (sizeof(USB_DEVICE_SERIAL_NAME)-1)
126 #else
127 #define USB_DEVICE_SERIAL_NAME_SIZE 0
128 #endif
129
130 uint8_t usb_device_serial_name_size = 0;
131 #if defined USB_DEVICE_SERIAL_USE_BOOTLOADER_SERIAL
132 uint8_t bootloader_serial_number[BOOTLOADER_SERIAL_MAX_SIZE+1]="";
133 #endif
134 static const uint8_t *udc_get_string_serial_name(void)
135 {
136 #if defined USB_DEVICE_SERIAL_USE_BOOTLOADER_SERIAL
137     uint32_t serial_ptrloc = (uint32_t)&_srom - 4;
138     uint32_t serial_address = *(uint32_t *)serial_ptrloc; //Address of bootloader's serial number if available
139
140     if (serial_address != 0xFFFFFFFF && serial_address < serial_ptrloc) //Check for factory programmed serial address
141     {
142         if ((serial_address & 0xFF) % 4 == 0) //Check alignment
143         {
144             uint16_t *serial_use = (uint16_t *)(serial_address); //Point to address of string in rom
145             uint8_t serial_length = 0;
146
147             while ((*(serial_use + serial_length) > 32 && *(serial_use + serial_length) < 127) &&
148                    serial_length < BOOTLOADER_SERIAL_MAX_SIZE)
149             {
150                 bootloader_serial_number[serial_length] = *(serial_use + serial_length) & 0xFF;
151                 serial_length++;
152             }
153             bootloader_serial_number[serial_length] = 0;
154
155             usb_device_serial_name_size = serial_length;
156
157             return bootloader_serial_number; //Use serial programmed into bootloader rom
158         }
159     }
160 #endif
161
162     usb_device_serial_name_size = USB_DEVICE_SERIAL_NAME_SIZE;
163
164 #if defined USB_DEVICE_SERIAL_NAME
165     return (const uint8_t *)USB_DEVICE_SERIAL_NAME; //Use serial supplied by keyboard's config.h
166 #else
167     return 0; //No serial supplied
168 #endif
169 }
170
171 /**
172  * \brief USB device string descriptor
173  * Structure used to transfer ASCII strings to USB String descriptor structure.
174  */
175 #ifndef BOOTLOADER_SERIAL_MAX_SIZE
176 #define BOOTLOADER_SERIAL_MAX_SIZE 0
177 #endif //BOOTLOADER_SERIAL_MAX_SIZE
178 struct udc_string_desc_t {
179     usb_str_desc_t header;
180     le16_t string[Max(Max(Max(USB_DEVICE_MANUFACTURE_NAME_SIZE, \
181                   USB_DEVICE_PRODUCT_NAME_SIZE), USB_DEVICE_SERIAL_NAME_SIZE), \
182                   BOOTLOADER_SERIAL_MAX_SIZE)];
183 };
184 COMPILER_WORD_ALIGNED
185 static UDC_DESC_STORAGE struct udc_string_desc_t udc_string_desc = {
186     .header.bDescriptorType = USB_DT_STRING
187 };
188 //! @}
189
190 usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void)
191 {
192     return udc_ptr_iface;
193 }
194
195 /**
196  * \brief Returns a value to check the end of USB Configuration descriptor
197  *
198  * \return address after the last byte of USB Configuration descriptor
199  */
200 static usb_conf_desc_t UDC_DESC_STORAGE *udc_get_eof_conf(void)
201 {
202     return (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *)
203             udc_ptr_conf->desc +
204             le16_to_cpu(udc_ptr_conf->desc->wTotalLength));
205 }
206
207 #if (0!=USB_DEVICE_MAX_EP)
208 /**
209  * \brief Search specific descriptor in global interface descriptor
210  *
211  * \param desc       Address of interface descriptor
212  *                   or previous specific descriptor found
213  * \param desc_id    Descriptor ID to search
214  *
215  * \return address of specific descriptor found
216  * \return NULL if it is the end of global interface descriptor
217  */
218 static usb_conf_desc_t UDC_DESC_STORAGE *udc_next_desc_in_iface(usb_conf_desc_t
219         UDC_DESC_STORAGE * desc, uint8_t desc_id)
220 {
221     usb_conf_desc_t UDC_DESC_STORAGE *ptr_eof_desc;
222
223     ptr_eof_desc = udc_get_eof_conf();
224     // Go to next descriptor
225     desc = (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) desc +
226             desc->bLength);
227     // Check the end of configuration descriptor
228     while (ptr_eof_desc > desc) {
229         // If new interface descriptor is found,
230         // then it is the end of the current global interface descriptor
231         if (USB_DT_INTERFACE == desc->bDescriptorType) {
232             break; // End of global interface descriptor
233         }
234         if (desc_id == desc->bDescriptorType) {
235             return desc; // Specific descriptor found
236         }
237         // Go to next descriptor
238         desc = (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) desc +
239                 desc->bLength);
240     }
241     return NULL; // No specific descriptor found
242 }
243 #endif
244
245 /**
246  * \brief Search an interface descriptor
247  * This routine updates the internal pointer udc_ptr_iface.
248  *
249  * \param iface_num     Interface number to find in Configuration Descriptor
250  * \param setting_num   Setting number of interface to find
251  *
252  * \return 1 if found or 0 if not found
253  */
254 static bool udc_update_iface_desc(uint8_t iface_num, uint8_t setting_num)
255 {
256     usb_conf_desc_t UDC_DESC_STORAGE *ptr_end_desc;
257
258     if (0 == udc_num_configuration) {
259         return false;
260     }
261
262     if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) {
263         return false;
264     }
265
266     // Start at the beginning of configuration descriptor
267     udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *)
268             udc_ptr_conf->desc;
269
270     // Check the end of configuration descriptor
271     ptr_end_desc = udc_get_eof_conf();
272     while (ptr_end_desc >
273             (UDC_DESC_STORAGE usb_conf_desc_t *) udc_ptr_iface) {
274         if (USB_DT_INTERFACE == udc_ptr_iface->bDescriptorType) {
275             // A interface descriptor is found
276             // Check interface and alternate setting number
277             if ((iface_num == udc_ptr_iface->bInterfaceNumber) &&
278                     (setting_num ==
279                     udc_ptr_iface->bAlternateSetting)) {
280                 return true; // Interface found
281             }
282         }
283         // Go to next descriptor
284         udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *) (
285                 (uint8_t *) udc_ptr_iface +
286                 udc_ptr_iface->bLength);
287     }
288     return false; // Interface not found
289 }
290
291 /**
292  * \brief Disables an usb device interface (UDI)
293  * This routine call the UDI corresponding to interface number
294  *
295  * \param iface_num     Interface number to disable
296  *
297  * \return 1 if it is done or 0 if interface is not found
298  */
299 static bool udc_iface_disable(uint8_t iface_num)
300 {
301     udi_api_t UDC_DESC_STORAGE *udi_api;
302
303     // Select first alternate setting of the interface
304     // to update udc_ptr_iface before call iface->getsetting()
305     if (!udc_update_iface_desc(iface_num, 0)) {
306         return false;
307     }
308
309     // Select the interface with the current alternate setting
310     udi_api = udc_ptr_conf->udi_apis[iface_num];
311
312 #if (0!=USB_DEVICE_MAX_EP)
313     if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) {
314         return false;
315     }
316
317     // Start at the beginning of interface descriptor
318     {
319         usb_ep_desc_t UDC_DESC_STORAGE *ep_desc;
320         ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) udc_ptr_iface;
321         while (1) {
322             // Search Endpoint descriptor included in global interface descriptor
323             ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *)
324                     udc_next_desc_in_iface((UDC_DESC_STORAGE
325                     usb_conf_desc_t *)
326                     ep_desc, USB_DT_ENDPOINT);
327             if (NULL == ep_desc) {
328                 break;
329             }
330             // Free the endpoint used by the interface
331             udd_ep_free(ep_desc->bEndpointAddress);
332         }
333     }
334 #endif
335
336     // Disable interface
337     udi_api->disable();
338     return true;
339 }
340
341 /**
342  * \brief Enables an usb device interface (UDI)
343  * This routine calls the UDI corresponding
344  * to the interface and setting number.
345  *
346  * \param iface_num     Interface number to enable
347  * \param setting_num   Setting number to enable
348  *
349  * \return 1 if it is done or 0 if interface is not found
350  */
351 static bool udc_iface_enable(uint8_t iface_num, uint8_t setting_num)
352 {
353     // Select the interface descriptor
354     if (!udc_update_iface_desc(iface_num, setting_num)) {
355         return false;
356     }
357
358 #if (0!=USB_DEVICE_MAX_EP)
359     usb_ep_desc_t UDC_DESC_STORAGE *ep_desc;
360
361     // Start at the beginning of the global interface descriptor
362     ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) udc_ptr_iface;
363     while (1) {
364         // Search Endpoint descriptor included in the global interface descriptor
365         ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *)
366                 udc_next_desc_in_iface((UDC_DESC_STORAGE
367                         usb_conf_desc_t *) ep_desc,
368                 USB_DT_ENDPOINT);
369         if (NULL == ep_desc)
370             break;
371         // Alloc the endpoint used by the interface
372         if (!udd_ep_alloc(ep_desc->bEndpointAddress,
373                 ep_desc->bmAttributes,
374                 le16_to_cpu
375                 (ep_desc->wMaxPacketSize))) {
376             return false;
377         }
378     }
379 #endif
380     // Enable the interface
381     return udc_ptr_conf->udi_apis[iface_num]->enable();
382 }
383
384 /*! \brief Start the USB Device stack
385  */
386 void udc_start(void)
387 {
388     udd_enable();
389 }
390
391 /*! \brief Stop the USB Device stack
392  */
393 void udc_stop(void)
394 {
395     udd_disable();
396     udc_reset();
397 }
398
399 /**
400  * \brief Reset the current configuration of the USB device,
401  * This routines can be called by UDD when a RESET on the USB line occurs.
402  */
403 void udc_reset(void)
404 {
405     uint8_t iface_num;
406
407     if (udc_num_configuration) {
408         for (iface_num = 0;
409                 iface_num < udc_ptr_conf->desc->bNumInterfaces;
410                 iface_num++) {
411             udc_iface_disable(iface_num);
412         }
413     }
414     udc_num_configuration = 0;
415 #if (USB_CONFIG_ATTR_REMOTE_WAKEUP \
416     == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP))
417     if (CPU_TO_LE16(USB_DEV_STATUS_REMOTEWAKEUP) & udc_device_status) {
418         // Remote wakeup is enabled then disable it
419         UDC_REMOTEWAKEUP_DISABLE();
420     }
421 #endif
422     udc_device_status =
423 #if (USB_DEVICE_ATTR & USB_CONFIG_ATTR_SELF_POWERED)
424             CPU_TO_LE16(USB_DEV_STATUS_SELF_POWERED);
425 #else
426             CPU_TO_LE16(USB_DEV_STATUS_BUS_POWERED);
427 #endif
428 }
429
430 void udc_sof_notify(void)
431 {
432     uint8_t iface_num;
433
434     if (udc_num_configuration) {
435         for (iface_num = 0;
436                 iface_num < udc_ptr_conf->desc->bNumInterfaces;
437                 iface_num++) {
438             if (udc_ptr_conf->udi_apis[iface_num]->sof_notify != NULL) {
439                 udc_ptr_conf->udi_apis[iface_num]->sof_notify();
440             }
441         }
442     }
443 }
444
445 /**
446  * \brief Standard device request to get device status
447  *
448  * \return true if success
449  */
450 static bool udc_req_std_dev_get_status(void)
451 {
452     if (udd_g_ctrlreq.req.wLength != sizeof(udc_device_status)) {
453         return false;
454     }
455
456     udd_set_setup_payload( (uint8_t *) & udc_device_status,
457             sizeof(udc_device_status));
458     return true;
459 }
460
461 #if (0!=USB_DEVICE_MAX_EP)
462 /**
463  * \brief Standard endpoint request to get endpoint status
464  *
465  * \return true if success
466  */
467 static bool udc_req_std_ep_get_status(void)
468 {
469     static le16_t udc_ep_status;
470
471     if (udd_g_ctrlreq.req.wLength != sizeof(udc_ep_status)) {
472         return false;
473     }
474
475     udc_ep_status = udd_ep_is_halted(udd_g_ctrlreq.req.
476             wIndex & 0xFF) ? CPU_TO_LE16(USB_EP_STATUS_HALTED) : 0;
477
478     udd_set_setup_payload( (uint8_t *) & udc_ep_status,
479             sizeof(udc_ep_status));
480     return true;
481 }
482 #endif
483
484 /**
485  * \brief Standard device request to change device status
486  *
487  * \return true if success
488  */
489 static bool udc_req_std_dev_clear_feature(void)
490 {
491     if (udd_g_ctrlreq.req.wLength) {
492         return false;
493     }
494
495     if (udd_g_ctrlreq.req.wValue == USB_DEV_FEATURE_REMOTE_WAKEUP) {
496         udc_device_status &= CPU_TO_LE16(~(uint32_t)USB_DEV_STATUS_REMOTEWAKEUP);
497 #if (USB_CONFIG_ATTR_REMOTE_WAKEUP \
498     == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP))
499         UDC_REMOTEWAKEUP_DISABLE();
500 #endif
501         return true;
502     }
503     return false;
504 }
505
506 #if (0!=USB_DEVICE_MAX_EP)
507 /**
508  * \brief Standard endpoint request to clear endpoint feature
509  *
510  * \return true if success
511  */
512 static bool udc_req_std_ep_clear_feature(void)
513 {
514     if (udd_g_ctrlreq.req.wLength) {
515         return false;
516     }
517
518     if (udd_g_ctrlreq.req.wValue == USB_EP_FEATURE_HALT) {
519         return udd_ep_clear_halt(udd_g_ctrlreq.req.wIndex & 0xFF);
520     }
521     return false;
522 }
523 #endif
524
525 /**
526  * \brief Standard device request to set a feature
527  *
528  * \return true if success
529  */
530 static bool udc_req_std_dev_set_feature(void)
531 {
532     if (udd_g_ctrlreq.req.wLength) {
533         return false;
534     }
535
536     switch (udd_g_ctrlreq.req.wValue) {
537
538     case USB_DEV_FEATURE_REMOTE_WAKEUP:
539 #if (USB_CONFIG_ATTR_REMOTE_WAKEUP \
540     == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP))
541         udc_device_status |= CPU_TO_LE16(USB_DEV_STATUS_REMOTEWAKEUP);
542         UDC_REMOTEWAKEUP_ENABLE();
543         return true;
544 #else
545         return false;
546 #endif
547
548 #ifdef USB_DEVICE_HS_SUPPORT
549     case USB_DEV_FEATURE_TEST_MODE:
550         if (!udd_is_high_speed()) {
551             break;
552         }
553         if (udd_g_ctrlreq.req.wIndex & 0xff) {
554             break;
555         }
556         // Unconfigure the device, terminating all ongoing requests
557         udc_reset();
558         switch ((udd_g_ctrlreq.req.wIndex >> 8) & 0xFF) {
559         case USB_DEV_TEST_MODE_J:
560             udd_g_ctrlreq.callback = udd_test_mode_j;
561             return true;
562
563         case USB_DEV_TEST_MODE_K:
564             udd_g_ctrlreq.callback = udd_test_mode_k;
565             return true;
566
567         case USB_DEV_TEST_MODE_SE0_NAK:
568             udd_g_ctrlreq.callback = udd_test_mode_se0_nak;
569             return true;
570
571         case USB_DEV_TEST_MODE_PACKET:
572             udd_g_ctrlreq.callback = udd_test_mode_packet;
573             return true;
574
575         case USB_DEV_TEST_MODE_FORCE_ENABLE: // Only for downstream facing hub ports
576         default:
577             break;
578         }
579         break;
580 #endif
581     default:
582         break;
583     }
584     return false;
585 }
586
587 /**
588  * \brief Standard endpoint request to halt an endpoint
589  *
590  * \return true if success
591  */
592 #if (0!=USB_DEVICE_MAX_EP)
593 static bool udc_req_std_ep_set_feature(void)
594 {
595     if (udd_g_ctrlreq.req.wLength) {
596         return false;
597     }
598     if (udd_g_ctrlreq.req.wValue == USB_EP_FEATURE_HALT) {
599         udd_ep_abort(udd_g_ctrlreq.req.wIndex & 0xFF);
600         return udd_ep_set_halt(udd_g_ctrlreq.req.wIndex & 0xFF);
601     }
602     return false;
603 }
604 #endif
605
606 /**
607  * \brief Change the address of device
608  * Callback called at the end of request set address
609  */
610 static void udc_valid_address(void)
611 {
612     udd_set_address(udd_g_ctrlreq.req.wValue & 0x7F);
613 }
614
615 /**
616  * \brief Standard device request to set device address
617  *
618  * \return true if success
619  */
620 static bool udc_req_std_dev_set_address(void)
621 {
622     if (udd_g_ctrlreq.req.wLength) {
623         return false;
624     }
625
626     // The address must be changed at the end of setup request after the handshake
627     // then we use a callback to change address
628     udd_g_ctrlreq.callback = udc_valid_address;
629     return true;
630 }
631
632 /**
633  * \brief Standard device request to get device string descriptor
634  *
635  * \return true if success
636  */
637 static bool udc_req_std_dev_get_str_desc(void)
638 {
639     uint8_t i;
640     const uint8_t *str;
641     uint8_t str_length = 0;
642
643     // Link payload pointer to the string corresponding at request
644     switch (udd_g_ctrlreq.req.wValue & 0xff) {
645     case 0:
646         udd_set_setup_payload((uint8_t *) &udc_string_desc_languageid,
647                 sizeof(udc_string_desc_languageid));
648         break;
649
650 #ifdef USB_DEVICE_MANUFACTURE_NAME
651     case 1:
652         str_length = USB_DEVICE_MANUFACTURE_NAME_SIZE;
653         str = udc_string_manufacturer_name;
654         break;
655 #endif
656 #ifdef USB_DEVICE_PRODUCT_NAME
657     case 2:
658         str_length = USB_DEVICE_PRODUCT_NAME_SIZE;
659         str = udc_string_product_name;
660         break;
661 #endif
662     case 3:
663         str = udc_get_string_serial_name();
664         str_length = usb_device_serial_name_size;
665         break;
666     default:
667 #ifdef UDC_GET_EXTRA_STRING
668         if (UDC_GET_EXTRA_STRING()) {
669             break;
670         }
671 #endif
672         return false;
673     }
674
675     if (str_length) {
676         for(i = 0; i < str_length; i++) {
677             udc_string_desc.string[i] = cpu_to_le16((le16_t)str[i]);
678         }
679
680         udc_string_desc.header.bLength = 2 + (str_length) * 2;
681         udd_set_setup_payload(
682             (uint8_t *) &udc_string_desc,
683             udc_string_desc.header.bLength);
684     }
685
686     return true;
687 }
688
689 /**
690  * \brief Standard device request to get descriptors about USB device
691  *
692  * \return true if success
693  */
694 static bool udc_req_std_dev_get_descriptor(void)
695 {
696     uint8_t conf_num;
697
698     conf_num = udd_g_ctrlreq.req.wValue & 0xff;
699
700     // Check descriptor ID
701     switch ((uint8_t) (udd_g_ctrlreq.req.wValue >> 8)) {
702     case USB_DT_DEVICE:
703         // Device descriptor requested
704 #ifdef USB_DEVICE_HS_SUPPORT
705         if (!udd_is_high_speed()) {
706             udd_set_setup_payload(
707                 (uint8_t *) udc_config.confdev_hs,
708                 udc_config.confdev_hs->bLength);
709         } else
710 #endif
711         {
712             udd_set_setup_payload(
713                 (uint8_t *) udc_config.confdev_lsfs,
714                 udc_config.confdev_lsfs->bLength);
715         }
716         break;
717
718     case USB_DT_CONFIGURATION:
719         // Configuration descriptor requested
720 #ifdef USB_DEVICE_HS_SUPPORT
721         if (udd_is_high_speed()) {
722             // HS descriptor
723             if (conf_num >= udc_config.confdev_hs->bNumConfigurations) {
724                 return false;
725             }
726             udd_set_setup_payload(
727                 (uint8_t *)udc_config.conf_hs[conf_num].desc,
728                 le16_to_cpu(udc_config.conf_hs[conf_num].desc->wTotalLength));
729         } else
730 #endif
731         {
732             // FS descriptor
733             if (conf_num >= udc_config.confdev_lsfs->bNumConfigurations) {
734                 return false;
735             }
736             udd_set_setup_payload(
737                 (uint8_t *)udc_config.conf_lsfs[conf_num].desc,
738                 le16_to_cpu(udc_config.conf_lsfs[conf_num].desc->wTotalLength));
739         }
740         ((usb_conf_desc_t *) udd_g_ctrlreq.payload)->bDescriptorType =
741                 USB_DT_CONFIGURATION;
742         break;
743
744 #ifdef USB_DEVICE_HS_SUPPORT
745     case USB_DT_DEVICE_QUALIFIER:
746         // Device qualifier descriptor requested
747         udd_set_setup_payload( (uint8_t *) udc_config.qualifier,
748                 udc_config.qualifier->bLength);
749         break;
750
751     case USB_DT_OTHER_SPEED_CONFIGURATION:
752         // Other configuration descriptor requested
753         if (!udd_is_high_speed()) {
754             // HS descriptor
755             if (conf_num >= udc_config.confdev_hs->bNumConfigurations) {
756                 return false;
757             }
758             udd_set_setup_payload(
759                 (uint8_t *)udc_config.conf_hs[conf_num].desc,
760                 le16_to_cpu(udc_config.conf_hs[conf_num].desc->wTotalLength));
761         } else {
762             // FS descriptor
763             if (conf_num >= udc_config.confdev_lsfs->bNumConfigurations) {
764                 return false;
765             }
766             udd_set_setup_payload(
767                 (uint8_t *)udc_config.conf_lsfs[conf_num].desc,
768                 le16_to_cpu(udc_config.conf_lsfs[conf_num].desc->wTotalLength));
769         }
770         ((usb_conf_desc_t *) udd_g_ctrlreq.payload)->bDescriptorType =
771                 USB_DT_OTHER_SPEED_CONFIGURATION;
772         break;
773 #endif
774
775     case USB_DT_BOS:
776         // Device BOS descriptor requested
777         if (udc_config.conf_bos == NULL) {
778             return false;
779         }
780         udd_set_setup_payload( (uint8_t *) udc_config.conf_bos,
781                 udc_config.conf_bos->wTotalLength);
782         break;
783
784     case USB_DT_STRING:
785         // String descriptor requested
786         if (!udc_req_std_dev_get_str_desc()) {
787             return false;
788         }
789         break;
790
791     default:
792         // Unknown descriptor requested
793         return false;
794     }
795     // if the descriptor is larger than length requested, then reduce it
796     if (udd_g_ctrlreq.req.wLength < udd_g_ctrlreq.payload_size) {
797         udd_g_ctrlreq.payload_size = udd_g_ctrlreq.req.wLength;
798     }
799     return true;
800 }
801
802 /**
803  * \brief Standard device request to get configuration number
804  *
805  * \return true if success
806  */
807 static bool udc_req_std_dev_get_configuration(void)
808 {
809     if (udd_g_ctrlreq.req.wLength != 1) {
810         return false;
811     }
812
813     udd_set_setup_payload(&udc_num_configuration,1);
814     return true;
815 }
816
817 /**
818  * \brief Standard device request to enable a configuration
819  *
820  * \return true if success
821  */
822 static bool udc_req_std_dev_set_configuration(void)
823 {
824     uint8_t iface_num;
825
826     // Check request length
827     if (udd_g_ctrlreq.req.wLength) {
828         return false;
829     }
830     // Authorize configuration only if the address is valid
831     if (!udd_getaddress()) {
832         return false;
833     }
834     // Check the configuration number requested
835 #ifdef USB_DEVICE_HS_SUPPORT
836     if (udd_is_high_speed()) {
837         // HS descriptor
838         if ((udd_g_ctrlreq.req.wValue & 0xFF) >
839                 udc_config.confdev_hs->bNumConfigurations) {
840             return false;
841         }
842     } else
843 #endif
844     {
845         // FS descriptor
846         if ((udd_g_ctrlreq.req.wValue & 0xFF) >
847                 udc_config.confdev_lsfs->bNumConfigurations) {
848             return false;
849         }
850     }
851
852     // Reset current configuration
853     udc_reset();
854
855     // Enable new configuration
856     udc_num_configuration = udd_g_ctrlreq.req.wValue & 0xFF;
857     if (udc_num_configuration == 0) {
858         return true; // Default empty configuration requested
859     }
860     // Update pointer of the configuration descriptor
861 #ifdef USB_DEVICE_HS_SUPPORT
862     if (udd_is_high_speed()) {
863         // HS descriptor
864         udc_ptr_conf = &udc_config.conf_hs[udc_num_configuration - 1];
865     } else
866 #endif
867     {
868         // FS descriptor
869         udc_ptr_conf = &udc_config.conf_lsfs[udc_num_configuration - 1];
870     }
871     // Enable all interfaces of the selected configuration
872     for (iface_num = 0; iface_num < udc_ptr_conf->desc->bNumInterfaces;
873             iface_num++) {
874         if (!udc_iface_enable(iface_num, 0)) {
875             return false;
876         }
877     }
878     return true;
879 }
880
881 /**
882  * \brief Standard interface request
883  * to get the alternate setting number of an interface
884  *
885  * \return true if success
886  */
887 static bool udc_req_std_iface_get_setting(void)
888 {
889     uint8_t iface_num;
890     udi_api_t UDC_DESC_STORAGE *udi_api;
891
892     if (udd_g_ctrlreq.req.wLength != 1) {
893         return false; // Error in request
894     }
895     if (!udc_num_configuration) {
896         return false; // The device is not is configured state yet
897     }
898
899     // Check the interface number included in the request
900     iface_num = udd_g_ctrlreq.req.wIndex & 0xFF;
901     if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) {
902         return false;
903     }
904
905     // Select first alternate setting of the interface to update udc_ptr_iface
906     // before call iface->getsetting()
907     if (!udc_update_iface_desc(iface_num, 0)) {
908         return false;
909     }
910     // Get alternate setting from UDI
911     udi_api = udc_ptr_conf->udi_apis[iface_num];
912     udc_iface_setting = udi_api->getsetting();
913
914     // Link value to payload pointer of request
915     udd_set_setup_payload(&udc_iface_setting,1);
916     return true;
917 }
918
919 /**
920  * \brief Standard interface request
921  * to set an alternate setting of an interface
922  *
923  * \return true if success
924  */
925 static bool udc_req_std_iface_set_setting(void)
926 {
927     uint8_t iface_num, setting_num;
928
929     if (udd_g_ctrlreq.req.wLength) {
930         return false; // Error in request
931     }
932     if (!udc_num_configuration) {
933         return false; // The device is not is configured state yet
934     }
935
936     iface_num = udd_g_ctrlreq.req.wIndex & 0xFF;
937     setting_num = udd_g_ctrlreq.req.wValue & 0xFF;
938
939     // Disable current setting
940     if (!udc_iface_disable(iface_num)) {
941         return false;
942     }
943
944     // Enable new setting
945     return udc_iface_enable(iface_num, setting_num);
946 }
947
948 /**
949  * \brief Main routine to manage the standard USB SETUP request
950  *
951  * \return true if the request is supported
952  */
953 static bool udc_reqstd(void)
954 {
955     if (Udd_setup_is_in()) {
956         // GET Standard Requests
957         if (udd_g_ctrlreq.req.wLength == 0) {
958             return false; // Error for USB host
959         }
960
961         if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) {
962             // Standard Get Device request
963             switch (udd_g_ctrlreq.req.bRequest) {
964             case USB_REQ_GET_STATUS:
965                 return udc_req_std_dev_get_status();
966             case USB_REQ_GET_DESCRIPTOR:
967                 return udc_req_std_dev_get_descriptor();
968             case USB_REQ_GET_CONFIGURATION:
969                 return udc_req_std_dev_get_configuration();
970             default:
971                 break;
972             }
973         }
974
975         if (USB_REQ_RECIP_INTERFACE == Udd_setup_recipient()) {
976             // Standard Get Interface request
977             switch (udd_g_ctrlreq.req.bRequest) {
978             case USB_REQ_GET_INTERFACE:
979                 return udc_req_std_iface_get_setting();
980             default:
981                 break;
982             }
983         }
984 #if (0!=USB_DEVICE_MAX_EP)
985         if (USB_REQ_RECIP_ENDPOINT == Udd_setup_recipient()) {
986             // Standard Get Endpoint request
987             switch (udd_g_ctrlreq.req.bRequest) {
988             case USB_REQ_GET_STATUS:
989                 return udc_req_std_ep_get_status();
990             default:
991                 break;
992             }
993         }
994 #endif
995     } else {
996         // SET Standard Requests
997         if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) {
998             // Standard Set Device request
999             switch (udd_g_ctrlreq.req.bRequest) {
1000             case USB_REQ_SET_ADDRESS:
1001                 return udc_req_std_dev_set_address();
1002             case USB_REQ_CLEAR_FEATURE:
1003                 return udc_req_std_dev_clear_feature();
1004             case USB_REQ_SET_FEATURE:
1005                 return udc_req_std_dev_set_feature();
1006             case USB_REQ_SET_CONFIGURATION:
1007                 return udc_req_std_dev_set_configuration();
1008             case USB_REQ_SET_DESCRIPTOR:
1009                 /* Not supported (defined as optional by the USB 2.0 spec) */
1010                 break;
1011             default:
1012                 break;
1013             }
1014         }
1015
1016         if (USB_REQ_RECIP_INTERFACE == Udd_setup_recipient()) {
1017             // Standard Set Interface request
1018             switch (udd_g_ctrlreq.req.bRequest) {
1019             case USB_REQ_SET_INTERFACE:
1020                 return udc_req_std_iface_set_setting();
1021             default:
1022                 break;
1023             }
1024         }
1025 #if (0!=USB_DEVICE_MAX_EP)
1026         if (USB_REQ_RECIP_ENDPOINT == Udd_setup_recipient()) {
1027             // Standard Set Endpoint request
1028             switch (udd_g_ctrlreq.req.bRequest) {
1029             case USB_REQ_CLEAR_FEATURE:
1030                 return udc_req_std_ep_clear_feature();
1031             case USB_REQ_SET_FEATURE:
1032                 return udc_req_std_ep_set_feature();
1033             default:
1034                 break;
1035             }
1036         }
1037 #endif
1038     }
1039     return false;
1040 }
1041
1042 /**
1043  * \brief Send the SETUP interface request to UDI
1044  *
1045  * \return true if the request is supported
1046  */
1047 static bool udc_req_iface(void)
1048 {
1049     uint8_t iface_num;
1050     udi_api_t UDC_DESC_STORAGE *udi_api;
1051
1052     if (0 == udc_num_configuration) {
1053         return false; // The device is not is configured state yet
1054     }
1055     // Check interface number
1056     iface_num = udd_g_ctrlreq.req.wIndex & 0xFF;
1057     if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) {
1058         return false;
1059     }
1060
1061     //* To update udc_ptr_iface with the selected interface in request
1062     // Select first alternate setting of interface to update udc_ptr_iface
1063     // before calling udi_api->getsetting()
1064     if (!udc_update_iface_desc(iface_num, 0)) {
1065         return false;
1066     }
1067     // Select the interface with the current alternate setting
1068     udi_api = udc_ptr_conf->udi_apis[iface_num];
1069     if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) {
1070         return false;
1071     }
1072
1073     // Send the SETUP request to the UDI corresponding to the interface number
1074     return udi_api->setup();
1075 }
1076
1077 /**
1078  * \brief Send the SETUP interface request to UDI
1079  *
1080  * \return true if the request is supported
1081  */
1082 static bool udc_req_ep(void)
1083 {
1084     uint8_t iface_num;
1085     udi_api_t UDC_DESC_STORAGE *udi_api;
1086
1087     if (0 == udc_num_configuration) {
1088         return false; // The device is not is configured state yet
1089     }
1090     // Send this request on all enabled interfaces
1091     iface_num = udd_g_ctrlreq.req.wIndex & 0xFF;
1092     for (iface_num = 0; iface_num < udc_ptr_conf->desc->bNumInterfaces;
1093             iface_num++) {
1094         // Select the interface with the current alternate setting
1095         udi_api = udc_ptr_conf->udi_apis[iface_num];
1096         if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) {
1097             return false;
1098         }
1099
1100         // Send the SETUP request to the UDI
1101         if (udi_api->setup()) {
1102             return true;
1103         }
1104     }
1105     return false;
1106 }
1107
1108 /**
1109  * \brief Main routine to manage the USB SETUP request.
1110  *
1111  * This function parses a USB SETUP request and submits an appropriate
1112  * response back to the host or, in the case of SETUP OUT requests
1113  * with data, sets up a buffer for receiving the data payload.
1114  *
1115  * The main standard requests defined by the USB 2.0 standard are handled
1116  * internally. The interface requests are sent to UDI, and the specific request
1117  * sent to a specific application callback.
1118  *
1119  * \return true if the request is supported, else the request is stalled by UDD
1120  */
1121 bool udc_process_setup(void)
1122 {
1123     // By default no data (receive/send) and no callbacks registered
1124     udd_g_ctrlreq.payload_size = 0;
1125     udd_g_ctrlreq.callback = NULL;
1126     udd_g_ctrlreq.over_under_run = NULL;
1127
1128     if (Udd_setup_is_in()) {
1129         if (udd_g_ctrlreq.req.wLength == 0) {
1130             return false; // Error from USB host
1131         }
1132     }
1133
1134     // If standard request then try to decode it in UDC
1135     if (Udd_setup_type() == USB_REQ_TYPE_STANDARD) {
1136         if (udc_reqstd()) {
1137             return true;
1138         }
1139     }
1140
1141     // If interface request then try to decode it in UDI
1142     if (Udd_setup_recipient() == USB_REQ_RECIP_INTERFACE) {
1143         if (udc_req_iface()) {
1144             return true;
1145         }
1146     }
1147
1148     // If endpoint request then try to decode it in UDI
1149     if (Udd_setup_recipient() == USB_REQ_RECIP_ENDPOINT) {
1150         if (udc_req_ep()) {
1151             return true;
1152         }
1153     }
1154
1155     // Here SETUP request unknown by UDC and UDIs
1156 #ifdef USB_DEVICE_SPECIFIC_REQUEST
1157     // Try to decode it in specific callback
1158     return USB_DEVICE_SPECIFIC_REQUEST(); // Ex: Vendor request,...
1159 #else
1160     return false;
1161 #endif
1162 }
1163
1164 //! @}