1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2012-10-01     Yi Qiu       first version
9  * 2012-12-12     heyuanjie87  change endpoint and function handler
10  * 2012-12-30     heyuanjie87  change inferface handler
11  * 2013-04-26     aozima       add DEVICEQUALIFIER support.
12  * 2013-07-25     Yi Qiu       update for USB CV test
13  * 2017-11-15     ZYH          fix ep0 transform error
14  */
15 
16 #include <rtthread.h>
17 #include "drivers/usb_common.h"
18 #include "drivers/usb_device.h"
19 
20 #define DBG_TAG           "usbdevice.core"
21 #define DBG_LVL           DBG_INFO
22 #include <rtdbg.h>
23 
24 static rt_list_t device_list;
25 
26 static rt_ssize_t rt_usbd_ep_write(udevice_t device, uep_t ep, void *buffer, rt_size_t size);
27 static rt_ssize_t rt_usbd_ep_read_prepare(udevice_t device, uep_t ep, void *buffer, rt_size_t size);
28 static rt_err_t rt_usbd_ep_assign(udevice_t device, uep_t ep);
29 rt_err_t rt_usbd_ep_unassign(udevice_t device, uep_t ep);
30 
31 /**
32  * This function will handle get_device_descriptor bRequest.
33  *
34  * @param device the usb device object.
35  * @param setup the setup bRequest.
36  *
37  * @return RT_EOK on successful.
38  */
_get_device_descriptor(struct udevice * device,ureq_t setup)39 static rt_err_t _get_device_descriptor(struct udevice* device, ureq_t setup)
40 {
41     rt_size_t size;
42 
43     /* parameter check */
44     RT_ASSERT(device != RT_NULL);
45     RT_ASSERT(setup != RT_NULL);
46 
47     LOG_D("_get_device_descriptor");
48 
49     /* device descriptor wLength should less than USB_DESC_LENGTH_DEVICE*/
50     size = (setup->wLength > USB_DESC_LENGTH_DEVICE) ?
51            USB_DESC_LENGTH_DEVICE : setup->wLength;
52 
53     /* send device descriptor to endpoint 0 */
54     rt_usbd_ep0_write(device, (rt_uint8_t*) &device->dev_desc, size);
55 
56     return RT_EOK;
57 }
58 
59 /**
60  * This function will handle get_config_descriptor bRequest.
61  *
62  * @param device the usb device object.
63  * @param setup the setup bRequest.
64  *
65  * @return RT_EOK on successful.
66  */
_get_config_descriptor(struct udevice * device,ureq_t setup)67 static rt_err_t _get_config_descriptor(struct udevice* device, ureq_t setup)
68 {
69     rt_size_t size;
70     ucfg_desc_t cfg_desc;
71 
72     /* parameter check */
73     RT_ASSERT(device != RT_NULL);
74     RT_ASSERT(setup != RT_NULL);
75 
76     LOG_D("_get_config_descriptor");
77 
78     cfg_desc = &device->curr_cfg->cfg_desc;
79     size = (setup->wLength > cfg_desc->wTotalLength) ?
80            cfg_desc->wTotalLength : setup->wLength;
81 
82     /* send configuration descriptor to endpoint 0 */
83     rt_usbd_ep0_write(device, (rt_uint8_t*)cfg_desc, size);
84 
85     return RT_EOK;
86 }
87 
88 /**
89  * This function will handle get_string_descriptor bRequest.
90  *
91  * @param device the usb device object.
92  * @param setup the setup bRequest.
93  *
94  * @return RT_EOK on successful, -RT_ERROR on invalid bRequest.
95  */
_get_string_descriptor(struct udevice * device,ureq_t setup)96 static rt_err_t _get_string_descriptor(struct udevice* device, ureq_t setup)
97 {
98     struct ustring_descriptor str_desc;
99     rt_uint8_t index, i;
100     rt_uint32_t len;
101 
102     /* parameter check */
103     RT_ASSERT(device != RT_NULL);
104     RT_ASSERT(setup != RT_NULL);
105 
106     LOG_D("_get_string_descriptor");
107 
108     str_desc.type = USB_DESC_TYPE_STRING;
109     index = setup->wValue & 0xFF;
110 
111     if(index == 0xEE)
112     {
113         index = USB_STRING_OS_INDEX;
114     }
115 
116     if(index > USB_STRING_MAX)
117     {
118         rt_kprintf("unknown string index\n");
119         rt_usbd_ep0_set_stall(device);
120         return -RT_ERROR;
121     }
122     else if(index == USB_STRING_LANGID_INDEX)
123     {
124         str_desc.bLength = 4;
125         str_desc.String[0] = 0x09;
126         str_desc.String[1] = 0x04;
127     }
128     else
129     {
130         if(index < 5)
131             len = rt_strlen(device->str[index]);
132         else
133             len = rt_strlen(device->str_intf[index]);
134         str_desc.bLength = len*2 + 2;
135 
136         for(i=0; i<len; i++)
137         {
138             if(index < 5)
139                 str_desc.String[i*2] = device->str[index][i];
140             else
141                 str_desc.String[i*2] = device->str_intf[index][i];
142             str_desc.String[i*2 + 1] = 0;
143         }
144     }
145 
146     if (setup->wLength > str_desc.bLength)
147         len = str_desc.bLength;
148     else
149         len = setup->wLength;
150 
151     /* send string descriptor to endpoint 0 */
152     rt_usbd_ep0_write(device, (rt_uint8_t*)&str_desc, len);
153 
154     return RT_EOK;
155 }
156 
_get_qualifier_descriptor(struct udevice * device,ureq_t setup)157 static rt_err_t _get_qualifier_descriptor(struct udevice* device, ureq_t setup)
158 {
159     LOG_D("_get_qualifier_descriptor");
160 
161     /* parameter check */
162     RT_ASSERT(device != RT_NULL);
163     RT_ASSERT(setup != RT_NULL);
164 
165     if(device->dev_qualifier && device->dcd->device_is_hs)
166     {
167         /* send device qualifier descriptor to endpoint 0 */
168         rt_usbd_ep0_write(device, (rt_uint8_t*)device->dev_qualifier,
169                      sizeof(struct usb_qualifier_descriptor));
170     }
171     else
172     {
173         rt_usbd_ep0_set_stall(device);
174     }
175 
176     return RT_EOK;
177 }
178 
179 /**
180  * This function will handle get_descriptor bRequest.
181  *
182  * @param device the usb device object.
183  * @param setup the setup bRequest.
184  *
185  * @return RT_EOK on successful.
186  */
_get_descriptor(struct udevice * device,ureq_t setup)187 static rt_err_t _get_descriptor(struct udevice* device, ureq_t setup)
188 {
189     /* parameter check */
190     RT_ASSERT(device != RT_NULL);
191     RT_ASSERT(setup != RT_NULL);
192 
193     if(setup->request_type == USB_REQ_TYPE_DIR_IN)
194     {
195         switch(setup->wValue >> 8)
196         {
197         case USB_DESC_TYPE_DEVICE:
198             _get_device_descriptor(device, setup);
199             break;
200         case USB_DESC_TYPE_CONFIGURATION:
201             _get_config_descriptor(device, setup);
202             break;
203         case USB_DESC_TYPE_STRING:
204             _get_string_descriptor(device, setup);
205             break;
206         case USB_DESC_TYPE_DEVICEQUALIFIER:
207             /* If a full-speed only device (with a device descriptor version number equal to 0200H) receives a
208             GetDescriptor() request for a device_qualifier, it must respond with a request error. The host must not make
209             a request for an other_speed_configuration descriptor unless it first successfully retrieves the
210             device_qualifier descriptor. */
211             if(device->dcd->device_is_hs)
212             {
213                 _get_qualifier_descriptor(device, setup);
214             }
215             else
216             {
217                 rt_usbd_ep0_set_stall(device);
218             }
219             break;
220         case USB_DESC_TYPE_OTHERSPEED:
221             _get_config_descriptor(device, setup);
222             break;
223         default:
224             rt_kprintf("unsupported descriptor request\n");
225             rt_usbd_ep0_set_stall(device);
226             break;
227         }
228     }
229     else
230     {
231         rt_kprintf("request direction error\n");
232         rt_usbd_ep0_set_stall(device);
233     }
234 
235     return RT_EOK;
236 }
237 
238 /**
239  * This function will handle get_interface bRequest.
240  *
241  * @param device the usb device object.
242  * @param setup the setup bRequest.
243  *
244  * @return RT_EOK on successful.
245  */
_get_interface(struct udevice * device,ureq_t setup)246 static rt_err_t _get_interface(struct udevice* device, ureq_t setup)
247 {
248     rt_uint8_t value;
249     uintf_t intf;
250     ufunction_t func;
251 
252     /* parameter check */
253     RT_ASSERT(device != RT_NULL);
254     RT_ASSERT(setup != RT_NULL);
255 
256     LOG_D("_get_interface");
257 
258     if (device->state != USB_STATE_CONFIGURED)
259     {
260         rt_usbd_ep0_set_stall(device);
261         return -RT_ERROR;
262     }
263 
264     /* find the specified interface and its alternate setting */
265     intf = rt_usbd_find_interface(device, setup->wIndex & 0xFF, &func);
266     value = intf->curr_setting->intf_desc->bAlternateSetting;
267 
268     /* send the interface alternate setting to endpoint 0*/
269     rt_usbd_ep0_write(device, &value, 1);
270 
271     if (intf->handler)
272     {
273         intf->handler(func, setup);
274     }
275 
276     return RT_EOK;
277 }
278 
279 /**
280  * This function will handle set_interface bRequest.
281  *
282  * @param device the usb device object.
283  * @param setup the setup bRequest.
284  *
285  * @return RT_EOK on successful.
286  */
_set_interface(struct udevice * device,ureq_t setup)287 static rt_err_t _set_interface(struct udevice* device, ureq_t setup)
288 {
289     ufunction_t func;
290     uintf_t intf;
291     uep_t ep;
292     struct rt_list_node* i;
293     ualtsetting_t setting;
294 
295     /* parameter check */
296     RT_ASSERT(device != RT_NULL);
297     RT_ASSERT(setup != RT_NULL);
298 
299     LOG_D("_set_interface");
300 
301     if (device->state != USB_STATE_CONFIGURED)
302     {
303         rt_usbd_ep0_set_stall(device);
304         return -RT_ERROR;
305     }
306 
307     /* find the specified interface */
308     intf = rt_usbd_find_interface(device, setup->wIndex & 0xFF, &func);
309 
310     /* set alternate setting to the interface */
311     rt_usbd_set_altsetting(intf, setup->wValue & 0xFF);
312     setting = intf->curr_setting;
313 
314     /* start all endpoints of the interface alternate setting */
315     for(i=setting->ep_list.next; i != &setting->ep_list; i=i->next)
316     {
317         ep = (uep_t)rt_list_entry(i, struct uendpoint, list);
318         dcd_ep_disable(device->dcd, ep);
319         dcd_ep_enable(device->dcd, ep);
320     }
321     dcd_ep0_send_status(device->dcd);
322 
323     if (intf->handler)
324     {
325         intf->handler(func, setup);
326     }
327 
328     return RT_EOK;
329 }
330 
331 /**
332  * This function will handle get_config bRequest.
333  *
334  * @param device the usb device object.
335  * @param setup the setup bRequest.
336  *
337  * @return RT_EOK on successful.
338  */
_get_config(struct udevice * device,ureq_t setup)339 static rt_err_t _get_config(struct udevice* device, ureq_t setup)
340 {
341     rt_uint8_t value;
342 
343     /* parameter check */
344     RT_ASSERT(device != RT_NULL);
345     RT_ASSERT(setup != RT_NULL);
346     RT_ASSERT(device->curr_cfg != RT_NULL);
347 
348     LOG_D("_get_config");
349 
350     if (device->state == USB_STATE_CONFIGURED)
351     {
352         /* get current configuration */
353         value = device->curr_cfg->cfg_desc.bConfigurationValue;
354     }
355     else
356     {
357         value = 0;
358     }
359     /* write the current configuration to endpoint 0 */
360     rt_usbd_ep0_write(device, &value, 1);
361 
362     return RT_EOK;
363 }
364 
365 /**
366  * This function will handle set_config bRequest.
367  *
368  * @param device the usb device object.
369  * @param setup the setup bRequest.
370  *
371  * @return RT_EOK on successful.
372  */
_set_config(struct udevice * device,ureq_t setup)373 static rt_err_t _set_config(struct udevice* device, ureq_t setup)
374 {
375     struct rt_list_node *i, *j, *k;
376     uconfig_t cfg;
377     uintf_t intf;
378     ualtsetting_t setting;
379     uep_t ep;
380 
381     /* parameter check */
382     RT_ASSERT(device != RT_NULL);
383     RT_ASSERT(setup != RT_NULL);
384 
385     LOG_D("_set_config");
386 
387     if (setup->wValue > device->dev_desc.bNumConfigurations)
388     {
389         rt_usbd_ep0_set_stall(device);
390         return -RT_ERROR;
391     }
392 
393     if (setup->wValue == 0)
394     {
395         LOG_D("address state");
396         device->state = USB_STATE_ADDRESS;
397 
398         goto _exit;
399     }
400 
401     /* set current configuration */
402     rt_usbd_set_config(device, setup->wValue);
403     cfg = device->curr_cfg;
404 
405     for (i=cfg->func_list.next; i!=&cfg->func_list; i=i->next)
406     {
407         /* run all functiones and their endpoints in the configuration */
408         ufunction_t func = (ufunction_t)rt_list_entry(i, struct ufunction, list);
409         for(j=func->intf_list.next; j!=&func->intf_list; j=j->next)
410         {
411             intf = (uintf_t)rt_list_entry(j, struct uinterface, list);
412             setting = intf->curr_setting;
413             for(k=setting->ep_list.next; k != &setting->ep_list; k=k->next)
414             {
415                 ep = (uep_t)rt_list_entry(k, struct uendpoint, list);
416 
417                 /* first disable then enable an endpoint */
418                 dcd_ep_disable(device->dcd, ep);
419                 dcd_ep_enable(device->dcd, ep);
420             }
421         }
422         /* after enabled endpoints, then enable function */
423         FUNC_ENABLE(func);
424     }
425 
426     device->state = USB_STATE_CONFIGURED;
427 
428 _exit:
429     /* issue status stage */
430     dcd_ep0_send_status(device->dcd);
431 
432     return RT_EOK;
433 }
434 
435 /**
436  * This function will handle set_address bRequest.
437  *
438  * @param device the usb device object.
439  * @param setup the setup bRequest.
440  *
441  * @return RT_EOK on successful.
442  */
_set_address(struct udevice * device,ureq_t setup)443 static rt_err_t _set_address(struct udevice* device, ureq_t setup)
444 {
445     /* parameter check */
446     RT_ASSERT(device != RT_NULL);
447     RT_ASSERT(setup != RT_NULL);
448 
449     /* set address in device control driver */
450     dcd_set_address(device->dcd, setup->wValue);
451 
452     /* issue status stage */
453     dcd_ep0_send_status(device->dcd);
454 
455     LOG_D("_set_address");
456 
457     device->state = USB_STATE_ADDRESS;
458 
459     return RT_EOK;
460 }
461 
462 /**
463  * This function will handle standard bRequest to
464  * interface that defined in function-specifics
465  *
466  * @param device the usb device object.
467  * @param setup the setup bRequest.
468  *
469  * @return RT_EOK on successful.
470  */
_request_interface(struct udevice * device,ureq_t setup)471 static rt_err_t _request_interface(struct udevice* device, ureq_t setup)
472 {
473     uintf_t intf;
474     ufunction_t func;
475     rt_err_t ret;
476 
477     /* parameter check */
478     RT_ASSERT(device != RT_NULL);
479     RT_ASSERT(setup != RT_NULL);
480 
481     LOG_D("_request_interface");
482 
483     intf = rt_usbd_find_interface(device, setup->wIndex & 0xFF, &func);
484     if (intf != RT_NULL)
485     {
486         ret = intf->handler(func, setup);
487     }
488     else
489     {
490         ret = -RT_ERROR;
491     }
492 
493     return ret;
494 }
495 
496 /**
497  * This function will handle standard bRequest.
498  *
499  * @param device the usb device object.
500  * @param setup the setup bRequest.
501  *
502  * @return RT_EOK on successful.
503  */
_standard_request(struct udevice * device,ureq_t setup)504 static rt_err_t _standard_request(struct udevice* device, ureq_t setup)
505 {
506     udcd_t dcd;
507     rt_uint16_t value = 0;
508 
509     /* parameter check */
510     RT_ASSERT(device != RT_NULL);
511     RT_ASSERT(setup != RT_NULL);
512 
513     dcd = device->dcd;
514 
515     switch(setup->request_type & USB_REQ_TYPE_RECIPIENT_MASK)
516     {
517     case USB_REQ_TYPE_DEVICE:
518         switch(setup->bRequest)
519         {
520         case USB_REQ_GET_STATUS:
521             rt_usbd_ep0_write(device, &value, 2);
522             break;
523         case USB_REQ_CLEAR_FEATURE:
524             rt_usbd_clear_feature(device, setup->wValue, setup->wIndex);
525             dcd_ep0_send_status(dcd);
526             break;
527         case USB_REQ_SET_FEATURE:
528             rt_usbd_set_feature(device, setup->wValue, setup->wIndex);
529             break;
530         case USB_REQ_SET_ADDRESS:
531             _set_address(device, setup);
532             break;
533         case USB_REQ_GET_DESCRIPTOR:
534             _get_descriptor(device, setup);
535             break;
536         case USB_REQ_SET_DESCRIPTOR:
537             rt_usbd_ep0_set_stall(device);
538             break;
539         case USB_REQ_GET_CONFIGURATION:
540             _get_config(device, setup);
541             break;
542         case USB_REQ_SET_CONFIGURATION:
543             _set_config(device, setup);
544             break;
545         default:
546             rt_kprintf("unknown device request\n");
547             rt_usbd_ep0_set_stall(device);
548             break;
549         }
550         break;
551     case USB_REQ_TYPE_INTERFACE:
552         switch(setup->bRequest)
553         {
554         case USB_REQ_GET_INTERFACE:
555             _get_interface(device, setup);
556             break;
557         case USB_REQ_SET_INTERFACE:
558             _set_interface(device, setup);
559             break;
560         default:
561             if (_request_interface(device, setup) != RT_EOK)
562             {
563                 rt_kprintf("unknown interface request\n");
564                 rt_usbd_ep0_set_stall(device);
565                 return -RT_ERROR;
566             }
567             else
568                 break;
569         }
570         break;
571     case USB_REQ_TYPE_ENDPOINT:
572         switch(setup->bRequest)
573         {
574         case USB_REQ_GET_STATUS:
575         {
576             uep_t ep;
577 
578             ep = rt_usbd_find_endpoint(device, RT_NULL, setup->wIndex);
579             value = ep->stalled;
580             rt_usbd_ep0_write(device, &value, 2);
581         }
582         break;
583         case USB_REQ_CLEAR_FEATURE:
584         {
585             uep_t ep;
586             uio_request_t req;
587             struct rt_list_node *node;
588 
589             ep = rt_usbd_find_endpoint(device, RT_NULL, setup->wIndex);
590             if(USB_EP_HALT == setup->wValue && ep->stalled == RT_TRUE)
591             {
592                 rt_usbd_clear_feature(device, setup->wValue, setup->wIndex);
593                 dcd_ep0_send_status(dcd);
594                 ep->stalled = RT_FALSE;
595 
596                 for (node = ep->request_list.next; node != &ep->request_list; node = node->next)
597                 {
598                     req = (uio_request_t)rt_list_entry(node, struct uio_request, list);
599                     rt_usbd_io_request(device, ep, req);
600                     LOG_D("fired a request");
601                 }
602 
603                 rt_list_init(&ep->request_list);
604             }
605         }
606         break;
607         case USB_REQ_SET_FEATURE:
608         {
609             uep_t ep;
610 
611             if(USB_EP_HALT == setup->wValue)
612             {
613                 ep = rt_usbd_find_endpoint(device, RT_NULL, setup->wIndex);
614                 ep->stalled = RT_TRUE;
615                 rt_usbd_set_feature(device, setup->wValue, setup->wIndex);
616                 dcd_ep0_send_status(dcd);
617             }
618         }
619         break;
620         case USB_REQ_SYNCH_FRAME:
621             break;
622         default:
623             rt_kprintf("unknown endpoint request\n");
624             rt_usbd_ep0_set_stall(device);
625             break;
626         }
627         break;
628     case USB_REQ_TYPE_OTHER:
629         rt_kprintf("unknown other type request\n");
630         rt_usbd_ep0_set_stall(device);
631         break;
632     default:
633         rt_kprintf("unknown type request\n");
634         rt_usbd_ep0_set_stall(device);
635         break;
636     }
637 
638     return RT_EOK;
639 }
640 
641 /**
642  * This function will handle function bRequest.
643  *
644  * @param device the usb device object.
645  * @param setup the setup bRequest.
646  *
647  * @return RT_EOK on successful, -RT_ERROR on invalid bRequest.
648  */
_function_request(udevice_t device,ureq_t setup)649 static rt_err_t _function_request(udevice_t device, ureq_t setup)
650 {
651     uintf_t intf;
652     ufunction_t func;
653 
654     /* parameter check */
655     RT_ASSERT(device != RT_NULL);
656     RT_ASSERT(setup != RT_NULL);
657 
658     /* verify bRequest wValue */
659     if(setup->wIndex > device->curr_cfg->cfg_desc.bNumInterfaces)
660     {
661         rt_usbd_ep0_set_stall(device);
662         return -RT_ERROR;
663     }
664 
665     switch(setup->request_type & USB_REQ_TYPE_RECIPIENT_MASK)
666     {
667     case USB_REQ_TYPE_INTERFACE:
668         intf = rt_usbd_find_interface(device, setup->wIndex & 0xFF, &func);
669         if(intf == RT_NULL)
670         {
671             rt_kprintf("unkwown interface request\n");
672             rt_usbd_ep0_set_stall(device);
673         }
674         else
675         {
676             intf->handler(func, setup);
677         }
678         break;
679     case USB_REQ_TYPE_ENDPOINT:
680         break;
681     default:
682         rt_kprintf("unknown function request type\n");
683         rt_usbd_ep0_set_stall(device);
684         break;
685     }
686 
687     return RT_EOK;
688 }
_vendor_request(udevice_t device,ureq_t setup)689 static rt_err_t _vendor_request(udevice_t device, ureq_t setup)
690 {
691     static rt_uint8_t * usb_comp_id_desc = RT_NULL;
692     static rt_uint32_t  usb_comp_id_desc_size = 0;
693     usb_os_func_comp_id_desc_t func_comp_id_desc;
694     uintf_t intf;
695     ufunction_t func;
696     switch(setup->bRequest)
697     {
698         case 'A':
699         switch(setup->wIndex)
700         {
701             case 0x04:
702                 if(rt_list_len(&device->os_comp_id_desc->func_desc) == 0)
703                 {
704                     rt_usbd_ep0_set_stall(device);
705                     return RT_EOK;
706                 }
707                 if(usb_comp_id_desc == RT_NULL)
708                 {
709                     rt_uint8_t * pusb_comp_id_desc;
710                     rt_list_t *p;
711                     usb_comp_id_desc_size = sizeof(struct usb_os_header_comp_id_descriptor) +
712                     (sizeof(struct usb_os_function_comp_id_descriptor)-sizeof(rt_list_t))*rt_list_len(&device->os_comp_id_desc->func_desc);
713 
714                     usb_comp_id_desc = (rt_uint8_t *)rt_malloc(usb_comp_id_desc_size);
715                     RT_ASSERT(usb_comp_id_desc != RT_NULL);
716                     device->os_comp_id_desc->head_desc.dwLength = usb_comp_id_desc_size;
717                     pusb_comp_id_desc = usb_comp_id_desc;
718                     rt_memcpy((void *)pusb_comp_id_desc,(void *)&device->os_comp_id_desc->head_desc,sizeof(struct usb_os_header_comp_id_descriptor));
719                     pusb_comp_id_desc += sizeof(struct usb_os_header_comp_id_descriptor);
720 
721                     for (p = device->os_comp_id_desc->func_desc.next; p != &device->os_comp_id_desc->func_desc; p = p->next)
722                     {
723                         func_comp_id_desc = rt_list_entry(p,struct usb_os_function_comp_id_descriptor,list);
724                         rt_memcpy(pusb_comp_id_desc,(void *)&func_comp_id_desc->bFirstInterfaceNumber,
725                         sizeof(struct usb_os_function_comp_id_descriptor)-sizeof(rt_list_t));
726                         pusb_comp_id_desc += sizeof(struct usb_os_function_comp_id_descriptor)-sizeof(rt_list_t);
727                     }
728                 }
729                 rt_usbd_ep0_write(device, (void*)usb_comp_id_desc, setup->wLength);
730             break;
731             case 0x05:
732                 intf = rt_usbd_find_interface(device, setup->wValue & 0xFF, &func);
733                 if(intf != RT_NULL)
734                 {
735                     intf->handler(func, setup);
736                 }
737                 break;
738         }
739 
740         break;
741     }
742     return RT_EOK;
743 }
_dump_setup_packet(ureq_t setup)744 static rt_err_t _dump_setup_packet(ureq_t setup)
745 {
746     LOG_D("[");
747     LOG_D("  setup_request : 0x%x",
748                                 setup->request_type);
749     LOG_D("  value         : 0x%x", setup->wValue);
750     LOG_D("  length        : 0x%x", setup->wLength);
751     LOG_D("  index         : 0x%x", setup->wIndex);
752     LOG_D("  request       : 0x%x", setup->bRequest);
753     LOG_D("]");
754 
755     return RT_EOK;
756 }
757 
758 /**
759  * This function will handle setup bRequest.
760  *
761  * @param device the usb device object.
762  * @param setup the setup bRequest.
763  *
764  * @return RT_EOK on successful, -RT_ERROR on invalid bRequest.
765  */
_setup_request(udevice_t device,ureq_t setup)766 static rt_err_t _setup_request(udevice_t device, ureq_t setup)
767 {
768     /* parameter check */
769     RT_ASSERT(device != RT_NULL);
770     RT_ASSERT(setup != RT_NULL);
771 
772     _dump_setup_packet(setup);
773 
774     switch((setup->request_type & USB_REQ_TYPE_MASK))
775     {
776     case USB_REQ_TYPE_STANDARD:
777         _standard_request(device, setup);
778         break;
779     case USB_REQ_TYPE_CLASS:
780         _function_request(device, setup);
781         break;
782     case USB_REQ_TYPE_VENDOR:
783         _vendor_request(device, setup);
784         break;
785     default:
786         rt_kprintf("unknown setup request type\n");
787         rt_usbd_ep0_set_stall(device);
788         return -RT_ERROR;
789     }
790 
791     return RT_EOK;
792 }
793 
794 /**
795  * This function will hanle data notify event.
796  *
797  * @param device the usb device object.
798  * @param ep_msg the endpoint message.
799  *
800  * @return RT_EOK.
801  */
_data_notify(udevice_t device,struct ep_msg * ep_msg)802 static rt_err_t _data_notify(udevice_t device, struct ep_msg* ep_msg)
803 {
804     uep_t ep;
805     ufunction_t func;
806     rt_size_t size = 0;
807 
808     RT_ASSERT(device != RT_NULL);
809     RT_ASSERT(ep_msg != RT_NULL);
810 
811     if (device->state != USB_STATE_CONFIGURED)
812     {
813         return -RT_ERROR;
814     }
815 
816     ep = rt_usbd_find_endpoint(device, &func, ep_msg->ep_addr);
817     if(ep == RT_NULL)
818     {
819         rt_kprintf("invalid endpoint\n");
820         return -RT_ERROR;
821     }
822 
823     if(EP_ADDRESS(ep) & USB_DIR_IN)
824     {
825         size = ep_msg->size;
826         if(ep->request.remain_size >= EP_MAXPACKET(ep))
827         {
828             dcd_ep_write(device->dcd, EP_ADDRESS(ep), ep->request.buffer, EP_MAXPACKET(ep));
829             ep->request.remain_size -= EP_MAXPACKET(ep);
830             ep->request.buffer += EP_MAXPACKET(ep);
831         }
832         else if(ep->request.remain_size > 0)
833         {
834             dcd_ep_write(device->dcd, EP_ADDRESS(ep), ep->request.buffer, ep->request.remain_size);
835             ep->request.remain_size = 0;
836         }
837         else
838         {
839             EP_HANDLER(ep, func, size);
840         }
841     }
842     else
843     {
844         size = ep_msg->size;
845         if(ep->request.remain_size == 0)
846         {
847             return RT_EOK;
848         }
849 
850         if(size == 0)
851         {
852             size = dcd_ep_read(device->dcd, EP_ADDRESS(ep), ep->request.buffer);
853         }
854         ep->request.remain_size -= size;
855         ep->request.buffer += size;
856 
857         if(ep->request.req_type == UIO_REQUEST_READ_BEST)
858         {
859             EP_HANDLER(ep, func, size);
860         }
861         else if(ep->request.remain_size == 0)
862         {
863             EP_HANDLER(ep, func, ep->request.size);
864         }
865         else
866         {
867             dcd_ep_read_prepare(device->dcd, EP_ADDRESS(ep), ep->request.buffer, ep->request.remain_size > EP_MAXPACKET(ep) ? EP_MAXPACKET(ep) : ep->request.remain_size);
868         }
869     }
870 
871     return RT_EOK;
872 }
873 
_ep0_out_notify(udevice_t device,struct ep_msg * ep_msg)874 static rt_err_t _ep0_out_notify(udevice_t device, struct ep_msg* ep_msg)
875 {
876     uep_t ep0;
877     rt_size_t size;
878 
879     RT_ASSERT(device != RT_NULL);
880     RT_ASSERT(ep_msg != RT_NULL);
881     RT_ASSERT(device->dcd != RT_NULL);
882 
883     ep0 = &device->dcd->ep0;
884     size = ep_msg->size;
885 
886     if(ep0->request.remain_size == 0)
887     {
888         return RT_EOK;
889     }
890     if(size == 0)
891     {
892         size = dcd_ep_read(device->dcd, EP0_OUT_ADDR, ep0->request.buffer);
893         if(size == 0)
894         {
895             return RT_EOK;
896         }
897     }
898 
899     ep0->request.remain_size -= size;
900     ep0->request.buffer += size;
901     if(ep0->request.remain_size == 0)
902     {
903         /* invoke callback */
904         if(ep0->rx_indicate != RT_NULL)
905         {
906             ep0->rx_indicate(device, size);
907         }
908     }
909     else
910     {
911         rt_usbd_ep0_read(device, ep0->request.buffer, ep0->request.remain_size,ep0->rx_indicate);
912     }
913 
914     return RT_EOK;
915 }
916 
917 /**
918  * This function will notity sof event to all of function.
919  *
920  * @param device the usb device object.
921  *
922  * @return RT_EOK.
923  */
_sof_notify(udevice_t device)924 static rt_err_t _sof_notify(udevice_t device)
925 {
926     struct rt_list_node *i;
927     ufunction_t func;
928 
929     RT_ASSERT(device != RT_NULL);
930 
931     /* to notity every function that sof event comes */
932     for (i=device->curr_cfg->func_list.next;
933             i!=&device->curr_cfg->func_list; i=i->next)
934     {
935         func = (ufunction_t)rt_list_entry(i, struct ufunction, list);
936         if(func->ops->sof_handler != RT_NULL)
937             func->ops->sof_handler(func);
938     }
939 
940     return RT_EOK;
941 }
942 
943 /**
944  * This function will disable all USB functions.
945  *
946  * @param device the usb device object.
947  *
948  * @return RT_EOK.
949  */
_stop_notify(udevice_t device)950 static rt_err_t _stop_notify(udevice_t device)
951 {
952     struct rt_list_node *i;
953     ufunction_t func;
954 
955     RT_ASSERT(device != RT_NULL);
956 
957     /* to notity every function */
958     for (i  = device->curr_cfg->func_list.next;
959          i != &device->curr_cfg->func_list;
960          i  = i->next)
961     {
962         func = (ufunction_t)rt_list_entry(i, struct ufunction, list);
963         FUNC_DISABLE(func);
964     }
965 
966     return RT_EOK;
967 }
968 
rt_usbd_ep_write(udevice_t device,uep_t ep,void * buffer,rt_size_t size)969 static rt_ssize_t rt_usbd_ep_write(udevice_t device, uep_t ep, void *buffer, rt_size_t size)
970 {
971     rt_uint16_t maxpacket;
972 
973     RT_ASSERT(device != RT_NULL);
974     RT_ASSERT(device->dcd != RT_NULL);
975     RT_ASSERT(ep != RT_NULL);
976 
977     rt_enter_critical();
978     maxpacket = EP_MAXPACKET(ep);
979     if(ep->request.remain_size >= maxpacket)
980     {
981         dcd_ep_write(device->dcd, EP_ADDRESS(ep), ep->request.buffer, maxpacket);
982         ep->request.remain_size -= maxpacket;
983         ep->request.buffer += maxpacket;
984     }
985     else
986     {
987         dcd_ep_write(device->dcd, EP_ADDRESS(ep), ep->request.buffer,
988             ep->request.remain_size);
989         ep->request.remain_size = 0;
990     }
991     rt_exit_critical();
992     return size;
993 }
994 
rt_usbd_ep_read_prepare(udevice_t device,uep_t ep,void * buffer,rt_size_t size)995 static rt_ssize_t rt_usbd_ep_read_prepare(udevice_t device, uep_t ep, void *buffer, rt_size_t size)
996 {
997     RT_ASSERT(device != RT_NULL);
998     RT_ASSERT(device->dcd != RT_NULL);
999     RT_ASSERT(ep != RT_NULL);
1000     RT_ASSERT(buffer != RT_NULL);
1001     RT_ASSERT(ep->ep_desc != RT_NULL);
1002 
1003     return dcd_ep_read_prepare(device->dcd, EP_ADDRESS(ep), buffer, size > EP_MAXPACKET(ep) ? EP_MAXPACKET(ep) : size);
1004 }
1005 
1006 /**
1007  * This function will create an usb device object.
1008  *
1009  * @param ustring the usb string array to contain string descriptor.
1010  *
1011  * @return an usb device object on success, RT_NULL on fail.
1012  */
rt_usbd_device_new(void)1013 udevice_t rt_usbd_device_new(void)
1014 {
1015     udevice_t udevice;
1016 
1017     LOG_D("rt_usbd_device_new");
1018 
1019     /* allocate memory for the object */
1020     udevice = (udevice_t)rt_malloc(sizeof(struct udevice));
1021     if(udevice == RT_NULL)
1022     {
1023         rt_kprintf("alloc memory failed\n");
1024         return RT_NULL;
1025     }
1026     rt_memset(udevice, 0, sizeof(struct udevice));
1027 
1028     /* to initialize configuration list */
1029     rt_list_init(&udevice->cfg_list);
1030 
1031     /* insert the device object to device list */
1032     rt_list_insert_before(&device_list, &udevice->list);
1033 
1034     return udevice;
1035 }
1036 
1037 /**
1038  * This function will set usb device string description.
1039  *
1040  * @param device the usb device object.
1041  * @param ustring pointer to string pointer array.
1042  *
1043  * @return RT_EOK.
1044  */
rt_usbd_device_set_string(udevice_t device,const char ** ustring)1045 rt_err_t rt_usbd_device_set_string(udevice_t device, const char** ustring)
1046 {
1047     /* parameter check */
1048     RT_ASSERT(device != RT_NULL);
1049     RT_ASSERT(ustring != RT_NULL);
1050 
1051     /* set string descriptor array to the device object */
1052     device->str = ustring;
1053 
1054     return RT_EOK;
1055 }
1056 
1057 /**
1058  * This function will set usb device interface string description.
1059  *
1060  * @param device the usb device object.
1061  * @param index of interface string
1062  * @param string pointer to interface string description.
1063  *
1064  * @return RT_EOK.
1065  */
rt_usbd_device_set_interface_string(udevice_t device,int index,const char * string)1066 rt_err_t rt_usbd_device_set_interface_string(udevice_t device, int index, const char* string)
1067 {
1068     /* parameter check */
1069     RT_ASSERT(device != RT_NULL);
1070     RT_ASSERT(string != RT_NULL);
1071     RT_ASSERT(index < MAX_INTF_STR);
1072 
1073     /* set string descriptor array to the device object */
1074     device->str_intf[index] = string;
1075 
1076     return RT_EOK;
1077 }
1078 
rt_usbd_device_set_os_comp_id_desc(udevice_t device,usb_os_comp_id_desc_t os_comp_id_desc)1079 rt_err_t rt_usbd_device_set_os_comp_id_desc(udevice_t device, usb_os_comp_id_desc_t os_comp_id_desc)
1080 {
1081     /* parameter check */
1082     RT_ASSERT(device != RT_NULL);
1083     RT_ASSERT(os_comp_id_desc != RT_NULL);
1084 
1085     /* set string descriptor array to the device object */
1086     device->os_comp_id_desc = os_comp_id_desc;
1087     rt_list_init(&device->os_comp_id_desc->func_desc);
1088     return RT_EOK;
1089 }
1090 
rt_usbd_device_set_qualifier(udevice_t device,struct usb_qualifier_descriptor * qualifier)1091 rt_err_t rt_usbd_device_set_qualifier(udevice_t device, struct usb_qualifier_descriptor* qualifier)
1092 {
1093     /* parameter check */
1094     RT_ASSERT(device != RT_NULL);
1095     RT_ASSERT(qualifier != RT_NULL);
1096 
1097     device->dev_qualifier = qualifier;
1098 
1099     return RT_EOK;
1100 }
1101 
1102 /**
1103  * This function will set an usb controller driver to a device.
1104  *
1105  * @param device the usb device object.
1106  * @param dcd the usb device controller driver.
1107  *
1108  * @return RT_EOK on successful.
1109  */
rt_usbd_device_set_controller(udevice_t device,udcd_t dcd)1110 rt_err_t rt_usbd_device_set_controller(udevice_t device, udcd_t dcd)
1111 {
1112     /* parameter check */
1113     RT_ASSERT(device != RT_NULL);
1114     RT_ASSERT(dcd != RT_NULL);
1115 
1116     /* set usb device controller driver to the device */
1117     device->dcd = dcd;
1118 
1119     return RT_EOK;
1120 }
1121 
1122 /**
1123  * This function will set an usb device descriptor to a device.
1124  *
1125  * @param device the usb device object.
1126  * @param dev_desc the usb device descriptor.
1127  *
1128  * @return RT_EOK on successful.
1129  */
rt_usbd_device_set_descriptor(udevice_t device,udev_desc_t dev_desc)1130 rt_err_t rt_usbd_device_set_descriptor(udevice_t device, udev_desc_t dev_desc)
1131 {
1132     /* parameter check */
1133     RT_ASSERT(device != RT_NULL);
1134     RT_ASSERT(dev_desc != RT_NULL);
1135 
1136     /* copy the usb device descriptor to the device */
1137     rt_memcpy((void *)&device->dev_desc, (void *)dev_desc, USB_DESC_LENGTH_DEVICE);
1138 
1139     return RT_EOK;
1140 }
1141 
1142 /**
1143  * This function will create an usb configuration object.
1144  *
1145  * @param none.
1146  *
1147  * @return an usb configuration object.
1148  */
rt_usbd_config_new(void)1149 uconfig_t rt_usbd_config_new(void)
1150 {
1151     uconfig_t cfg;
1152 
1153     LOG_D("rt_usbd_config_new");
1154 
1155     /* allocate memory for the object */
1156     cfg = (uconfig_t)rt_malloc(sizeof(struct uconfig));
1157     if(cfg == RT_NULL)
1158     {
1159         rt_kprintf("alloc memory failed\n");
1160         return RT_NULL;
1161     }
1162     rt_memset(cfg, 0, sizeof(struct uconfig));
1163 
1164     /* set default wValue */
1165     cfg->cfg_desc.bLength = USB_DESC_LENGTH_CONFIG;
1166     cfg->cfg_desc.type = USB_DESC_TYPE_CONFIGURATION;
1167     cfg->cfg_desc.wTotalLength = USB_DESC_LENGTH_CONFIG;
1168     cfg->cfg_desc.bmAttributes = 0xC0;
1169     cfg->cfg_desc.MaxPower = 0x32;
1170 
1171     /* to initialize function object list */
1172     rt_list_init(&cfg->func_list);
1173 
1174     return cfg;
1175 }
1176 
1177 /**
1178  * This function will create an usb interface object.
1179  *
1180  * @param device the usb device object.
1181  * @handler the callback handler of object
1182  *
1183  * @return an usb interface object on success, RT_NULL on fail.
1184  */
rt_usbd_interface_new(udevice_t device,uintf_handler_t handler)1185 uintf_t rt_usbd_interface_new(udevice_t device, uintf_handler_t handler)
1186 {
1187     uintf_t intf;
1188 
1189     LOG_D("rt_usbd_interface_new");
1190 
1191     /* parameter check */
1192     RT_ASSERT(device != RT_NULL);
1193 
1194     /* allocate memory for the object */
1195     intf = (uintf_t)rt_malloc(sizeof(struct uinterface));
1196     if(intf == RT_NULL)
1197     {
1198         rt_kprintf("alloc memory failed\n");
1199         return RT_NULL;
1200     }
1201     intf->intf_num = device->nr_intf;
1202     device->nr_intf++;
1203     intf->handler = handler;
1204     intf->curr_setting = RT_NULL;
1205 
1206     /* to initialize the alternate setting object list */
1207     rt_list_init(&intf->setting_list);
1208 
1209     return intf;
1210 }
1211 
1212 /**
1213  * This function will create an usb alternate setting object.
1214  *
1215  * @param intf_desc the interface descriptor.
1216  * @desc_size the size of the interface descriptor.
1217  *
1218  * @return an usb alternate setting object on success, RT_NULL on fail.
1219  */
rt_usbd_altsetting_new(rt_size_t desc_size)1220 ualtsetting_t rt_usbd_altsetting_new(rt_size_t desc_size)
1221 {
1222     ualtsetting_t setting;
1223 
1224     LOG_D("rt_usbd_altsetting_new");
1225 
1226     /* parameter check */
1227     RT_ASSERT(desc_size > 0);
1228 
1229     /* allocate memory for the object */
1230     setting = (ualtsetting_t)rt_malloc(sizeof(struct ualtsetting));
1231     if(setting == RT_NULL)
1232     {
1233         rt_kprintf("alloc memory failed\n");
1234         return RT_NULL;
1235     }
1236     /* allocate memory for the desc */
1237     setting->desc = rt_malloc(desc_size);
1238     if (setting->desc == RT_NULL)
1239     {
1240         rt_kprintf("alloc desc memory failed\n");
1241         rt_free(setting);
1242         return RT_NULL;
1243     }
1244 
1245     setting->desc_size = desc_size;
1246     setting->intf_desc = RT_NULL;
1247 
1248     /* to initialize endpoint list */
1249     rt_list_init(&setting->ep_list);
1250 
1251     return setting;
1252 }
1253 
1254 /**
1255  * This function will config an desc in alternate setting object.
1256  *
1257  * @param setting the altsetting to be config.
1258  * @param desc use it to init desc in setting.
1259  * @param intf_pos the offset of interface descriptor in desc.
1260  *
1261  * @return RT_EOK.
1262  */
rt_usbd_altsetting_config_descriptor(ualtsetting_t setting,const void * desc,rt_off_t intf_pos)1263 rt_err_t rt_usbd_altsetting_config_descriptor(ualtsetting_t setting, const void* desc, rt_off_t intf_pos)
1264 {
1265     RT_ASSERT(setting != RT_NULL);
1266     RT_ASSERT(setting->desc !=RT_NULL);
1267 
1268     rt_memcpy(setting->desc, desc, setting->desc_size);
1269     setting->intf_desc = (uintf_desc_t)((char*)setting->desc + intf_pos);
1270 
1271     return RT_EOK;
1272 }
1273 
1274 /**
1275  * This function will create an usb function object.
1276  *
1277  * @param device the usb device object.
1278  * @param dev_desc the device descriptor.
1279  * @param ops the operation set.
1280  *
1281  * @return an usb function object on success, RT_NULL on fail.
1282  */
rt_usbd_function_new(udevice_t device,udev_desc_t dev_desc,ufunction_ops_t ops)1283 ufunction_t rt_usbd_function_new(udevice_t device, udev_desc_t dev_desc,
1284                               ufunction_ops_t ops)
1285 {
1286     ufunction_t func;
1287 
1288     LOG_D("rt_usbd_function_new");
1289 
1290     /* parameter check */
1291     RT_ASSERT(device != RT_NULL);
1292     RT_ASSERT(dev_desc != RT_NULL);
1293 
1294     /* allocate memory for the object */
1295     func = (ufunction_t)rt_malloc(sizeof(struct ufunction));
1296     if(func == RT_NULL)
1297     {
1298         rt_kprintf("alloc memory failed\n");
1299         return RT_NULL;
1300     }
1301     func->dev_desc = dev_desc;
1302     func->ops = ops;
1303     func->device = device;
1304     func->enabled = RT_FALSE;
1305 
1306     /* to initialize interface list */
1307     rt_list_init(&func->intf_list);
1308 
1309     return func;
1310 }
1311 
1312 /**
1313  * This function will create an usb endpoint object.
1314  *
1315  * @param ep_desc the endpoint descriptor.
1316  * @handler the callback handler of object
1317  *
1318  * @return an usb endpoint object on success, RT_NULL on fail.
1319  */
rt_usbd_endpoint_new(uep_desc_t ep_desc,udep_handler_t handler)1320 uep_t rt_usbd_endpoint_new(uep_desc_t ep_desc, udep_handler_t handler)
1321 {
1322     uep_t ep;
1323 
1324     LOG_D("rt_usbd_endpoint_new");
1325 
1326     /* parameter check */
1327     RT_ASSERT(ep_desc != RT_NULL);
1328 
1329     /* allocate memory for the object */
1330     ep = (uep_t)rt_malloc(sizeof(struct uendpoint));
1331     if(ep == RT_NULL)
1332     {
1333         rt_kprintf("alloc memory failed\n");
1334         return RT_NULL;
1335     }
1336     ep->ep_desc = ep_desc;
1337     ep->handler = handler;
1338     ep->buffer  = RT_NULL;
1339     ep->stalled = RT_FALSE;
1340     rt_list_init(&ep->request_list);
1341 
1342     return ep;
1343 }
1344 
1345 /**
1346  * This function will find an usb device object.
1347  *
1348  * @dcd usd device controller driver.
1349  *
1350  * @return an usb device object on found or RT_NULL on not found.
1351  */
rt_usbd_find_device(udcd_t dcd)1352 udevice_t rt_usbd_find_device(udcd_t dcd)
1353 {
1354     struct rt_list_node* node;
1355     udevice_t device;
1356 
1357     /* parameter check */
1358     RT_ASSERT(dcd != RT_NULL);
1359 
1360     /* search a device in the the device list */
1361     for (node = device_list.next; node != &device_list; node = node->next)
1362     {
1363         device = (udevice_t)rt_list_entry(node, struct udevice, list);
1364         if(device->dcd == dcd) return device;
1365     }
1366 
1367     rt_kprintf("can't find device\n");
1368     return RT_NULL;
1369 }
1370 
1371 /**
1372  * This function will find an usb configuration object.
1373  *
1374  * @param device the usb device object.
1375  * @param wValue the configuration number.
1376  *
1377  * @return an usb configuration object on found or RT_NULL on not found.
1378  */
rt_usbd_find_config(udevice_t device,rt_uint8_t value)1379 uconfig_t rt_usbd_find_config(udevice_t device, rt_uint8_t value)
1380 {
1381     struct rt_list_node* node;
1382     uconfig_t cfg = RT_NULL;
1383 
1384     LOG_D("rt_usbd_find_config");
1385 
1386     /* parameter check */
1387     RT_ASSERT(device != RT_NULL);
1388     RT_ASSERT(value <= device->dev_desc.bNumConfigurations);
1389 
1390     /* search a configration in the the device */
1391     for (node = device->cfg_list.next; node != &device->cfg_list; node = node->next)
1392     {
1393         cfg = (uconfig_t)rt_list_entry(node, struct udevice, list);
1394         if(cfg->cfg_desc.bConfigurationValue == value)
1395         {
1396             return cfg;
1397         }
1398     }
1399 
1400     rt_kprintf("can't find configuration %d\n", value);
1401     return RT_NULL;
1402 }
1403 
1404 /**
1405  * This function will find an usb interface object.
1406  *
1407  * @param device the usb device object.
1408  * @param wValue the interface number.
1409  *
1410  * @return an usb configuration object on found or RT_NULL on not found.
1411  */
rt_usbd_find_interface(udevice_t device,rt_uint8_t value,ufunction_t * pfunc)1412 uintf_t rt_usbd_find_interface(udevice_t device, rt_uint8_t value, ufunction_t *pfunc)
1413 {
1414     struct rt_list_node *i, *j;
1415     ufunction_t func;
1416     uintf_t intf;
1417 
1418     LOG_D("rt_usbd_find_interface");
1419 
1420     /* parameter check */
1421     RT_ASSERT(device != RT_NULL);
1422     RT_ASSERT(value < device->nr_intf);
1423 
1424     /* search an interface in the current configuration */
1425     for (i=device->curr_cfg->func_list.next;
1426             i!=&device->curr_cfg->func_list; i=i->next)
1427     {
1428         func = (ufunction_t)rt_list_entry(i, struct ufunction, list);
1429         for(j=func->intf_list.next; j!=&func->intf_list; j=j->next)
1430         {
1431             intf = (uintf_t)rt_list_entry(j, struct uinterface, list);
1432             if(intf->intf_num == value)
1433             {
1434                 if (pfunc != RT_NULL)
1435                     *pfunc = func;
1436                 return intf;
1437             }
1438         }
1439     }
1440 
1441     rt_kprintf("can't find interface %d\n", value);
1442     return RT_NULL;
1443 }
1444 
1445 /**
1446  * This function will find an usb interface alternate setting object.
1447  *
1448  * @param device the usb device object.
1449  * @param wValue the alternate setting number.
1450  *
1451  * @return an usb interface alternate setting object on found or RT_NULL on not found.
1452  */
rt_usbd_find_altsetting(uintf_t intf,rt_uint8_t value)1453 ualtsetting_t rt_usbd_find_altsetting(uintf_t intf, rt_uint8_t value)
1454 {
1455     struct rt_list_node *i;
1456     ualtsetting_t setting;
1457 
1458     LOG_D("rt_usbd_find_altsetting");
1459 
1460     /* parameter check */
1461     RT_ASSERT(intf != RT_NULL);
1462 
1463     if(intf->curr_setting != RT_NULL)
1464     {
1465         /* if the wValue equal to the current alternate setting, then do not search */
1466         if(intf->curr_setting->intf_desc->bAlternateSetting == value)
1467             return intf->curr_setting;
1468     }
1469 
1470     /* search a setting in the alternate setting list */
1471     for(i=intf->setting_list.next; i!=&intf->setting_list; i=i->next)
1472     {
1473         setting =(ualtsetting_t)rt_list_entry(i, struct ualtsetting, list);
1474         if(setting->intf_desc->bAlternateSetting == value)
1475             return setting;
1476     }
1477 
1478     rt_kprintf("can't find alternate setting %d\n", value);
1479     return RT_NULL;
1480 }
1481 
1482 /**
1483  * This function will find an usb endpoint object.
1484  *
1485  * @param device the usb device object.
1486  * @param ep_addr endpoint address.
1487  *
1488  * @return an usb endpoint object on found or RT_NULL on not found.
1489  */
rt_usbd_find_endpoint(udevice_t device,ufunction_t * pfunc,rt_uint8_t ep_addr)1490 uep_t rt_usbd_find_endpoint(udevice_t device, ufunction_t* pfunc, rt_uint8_t ep_addr)
1491 {
1492     uep_t ep;
1493     struct rt_list_node *i, *j, *k;
1494     ufunction_t func;
1495     uintf_t intf;
1496 
1497     /* parameter check */
1498     RT_ASSERT(device != RT_NULL);
1499 
1500     /* search a endpoint in the current configuration */
1501     for (i=device->curr_cfg->func_list.next; i!=&device->curr_cfg->func_list; i=i->next)
1502     {
1503         func = (ufunction_t)rt_list_entry(i, struct ufunction, list);
1504         for(j=func->intf_list.next; j!=&func->intf_list; j=j->next)
1505         {
1506             intf = (uintf_t)rt_list_entry(j, struct uinterface, list);
1507             for(k=intf->curr_setting->ep_list.next;
1508                     k!=&intf->curr_setting->ep_list; k=k->next)
1509             {
1510                 ep = (uep_t)rt_list_entry(k, struct uendpoint, list);
1511                 if(EP_ADDRESS(ep) == ep_addr)
1512                 {
1513                     if (pfunc != RT_NULL)
1514                         *pfunc = func;
1515                     return ep;
1516                 }
1517             }
1518         }
1519     }
1520 
1521     rt_kprintf("can't find endpoint 0x%x\n", ep_addr);
1522     return RT_NULL;
1523 }
1524 
1525 /**
1526  * This function will add a configuration to an usb device.
1527  *
1528  * @param device the usb device object.
1529  * @param cfg the configuration object.
1530  *
1531  * @return RT_EOK.
1532  */
rt_usbd_device_add_config(udevice_t device,uconfig_t cfg)1533 rt_err_t rt_usbd_device_add_config(udevice_t device, uconfig_t cfg)
1534 {
1535     struct rt_list_node *i, *j, *k, *m;
1536     ufunction_t func;
1537     uintf_t intf;
1538     ualtsetting_t altsetting;
1539     uep_t ep;
1540 
1541     LOG_D("rt_usbd_device_add_config");
1542 
1543     /* parameter check */
1544     RT_ASSERT(device != RT_NULL);
1545     RT_ASSERT(cfg != RT_NULL);
1546 
1547     /* set configuration number to the configuration descriptor */
1548     cfg->cfg_desc.bConfigurationValue = device->dev_desc.bNumConfigurations + 1;
1549     device->dev_desc.bNumConfigurations++;
1550 
1551     for (i=cfg->func_list.next; i!=&cfg->func_list; i=i->next)
1552     {
1553         func = (ufunction_t)rt_list_entry(i, struct ufunction, list);
1554 
1555         for(j=func->intf_list.next; j!=&func->intf_list; j=j->next)
1556         {
1557             intf = (uintf_t)rt_list_entry(j, struct uinterface, list);
1558             cfg->cfg_desc.bNumInterfaces++;
1559 
1560             for(k=intf->setting_list.next; k!=&intf->setting_list;k=k->next)
1561             {
1562                 altsetting = (ualtsetting_t)rt_list_entry(k, struct ualtsetting, list);
1563 
1564                 /* allocate address for every endpoint in the interface alternate setting */
1565                 for(m=altsetting->ep_list.next; m!=&altsetting->ep_list; m=m->next)
1566                 {
1567                     ep = (uep_t)rt_list_entry(m, struct uendpoint, list);
1568                     if(rt_usbd_ep_assign(device, ep) != RT_EOK)
1569                     {
1570                         rt_kprintf("endpoint assign error\n");
1571                     }
1572                 }
1573 
1574                 /* construct complete configuration descriptor */
1575                 rt_memcpy((void*)&cfg->cfg_desc.data[cfg->cfg_desc.wTotalLength - USB_DESC_LENGTH_CONFIG],
1576                             (void*)altsetting->desc,
1577                             altsetting->desc_size);
1578                 cfg->cfg_desc.wTotalLength += altsetting->desc_size;
1579             }
1580         }
1581     }
1582 
1583     /* insert the configuration to the list */
1584     rt_list_insert_before(&device->cfg_list, &cfg->list);
1585 
1586     return RT_EOK;
1587 }
1588 
1589 /**
1590  * This function will add a function to a configuration.
1591  *
1592  * @param cfg the configuration object.
1593  * @param func the function object.
1594  *
1595  * @return RT_EOK.
1596  */
rt_usbd_config_add_function(uconfig_t cfg,ufunction_t func)1597 rt_err_t rt_usbd_config_add_function(uconfig_t cfg, ufunction_t func)
1598 {
1599     LOG_D("rt_usbd_config_add_function");
1600 
1601     /* parameter check */
1602     RT_ASSERT(cfg != RT_NULL);
1603     RT_ASSERT(func != RT_NULL);
1604 
1605     /* insert the function to the list */
1606     rt_list_insert_before(&cfg->func_list, &func->list);
1607 
1608     return RT_EOK;
1609 }
1610 
1611 /**
1612  * This function will add an interface to a function.
1613  *
1614  * @param func the function object.
1615  * @param intf the interface object.
1616  *
1617  * @return RT_EOK.
1618  */
rt_usbd_function_add_interface(ufunction_t func,uintf_t intf)1619 rt_err_t rt_usbd_function_add_interface(ufunction_t func, uintf_t intf)
1620 {
1621 
1622     LOG_D("rt_usbd_function_add_interface");
1623 
1624     /* parameter check */
1625     RT_ASSERT(func != RT_NULL);
1626     RT_ASSERT(intf != RT_NULL);
1627 
1628     /* insert the interface to the list */
1629     rt_list_insert_before(&func->intf_list, &intf->list);
1630 
1631     return RT_EOK;
1632 }
1633 
1634 /**
1635  * This function will add an alternate setting to an interface.
1636  *
1637  * @param intf the interface object.
1638  * @param setting the alternate setting object.
1639  *
1640  * @return RT_EOK.
1641  */
rt_usbd_interface_add_altsetting(uintf_t intf,ualtsetting_t setting)1642 rt_err_t rt_usbd_interface_add_altsetting(uintf_t intf, ualtsetting_t setting)
1643 {
1644     LOG_D("rt_usbd_interface_add_altsetting");
1645 
1646     /* parameter check */
1647     RT_ASSERT(intf != RT_NULL);
1648     RT_ASSERT(setting != RT_NULL);
1649 
1650     setting->intf_desc->bInterfaceNumber = intf->intf_num;
1651 
1652     /* insert the alternate setting to the list */
1653     rt_list_insert_before(&intf->setting_list, &setting->list);
1654 
1655     return RT_EOK;
1656 }
1657 
1658 /**
1659  * This function will add an endpoint to an alternate setting.
1660  *
1661  * @param setting the alternate setting object.
1662  * @param ep the endpoint object.
1663  *
1664  * @return RT_EOK.
1665  */
rt_usbd_altsetting_add_endpoint(ualtsetting_t setting,uep_t ep)1666 rt_err_t rt_usbd_altsetting_add_endpoint(ualtsetting_t setting, uep_t ep)
1667 {
1668     LOG_D("rt_usbd_altsetting_add_endpoint");
1669 
1670     /* parameter check */
1671     RT_ASSERT(setting != RT_NULL);
1672     RT_ASSERT(ep != RT_NULL);
1673 
1674     /* insert the endpoint to the list */
1675     rt_list_insert_before(&setting->ep_list, &ep->list);
1676 
1677     return RT_EOK;
1678 }
1679 
rt_usbd_os_comp_id_desc_add_os_func_comp_id_desc(usb_os_comp_id_desc_t os_comp_id_desc,usb_os_func_comp_id_desc_t os_func_comp_id_desc)1680 rt_err_t rt_usbd_os_comp_id_desc_add_os_func_comp_id_desc(usb_os_comp_id_desc_t os_comp_id_desc, usb_os_func_comp_id_desc_t os_func_comp_id_desc)
1681 {
1682     RT_ASSERT(os_comp_id_desc != RT_NULL);
1683     RT_ASSERT(os_func_comp_id_desc != RT_NULL);
1684     rt_list_insert_before(&os_comp_id_desc->func_desc, &os_func_comp_id_desc->list);
1685     os_comp_id_desc->head_desc.bCount++;
1686     return RT_EOK;
1687 }
1688 
1689 /**
1690  * This function will set an alternate setting for an interface.
1691  *
1692  * @param intf_desc the interface descriptor.
1693  * @param wValue the alternate setting number.
1694  *
1695  * @return RT_EOK.
1696  */
rt_usbd_set_altsetting(uintf_t intf,rt_uint8_t value)1697 rt_err_t rt_usbd_set_altsetting(uintf_t intf, rt_uint8_t value)
1698 {
1699     ualtsetting_t setting;
1700 
1701     LOG_D("rt_usbd_set_altsetting");
1702 
1703     /* parameter check */
1704     RT_ASSERT(intf != RT_NULL);
1705 
1706     /* find an alternate setting */
1707     setting = rt_usbd_find_altsetting(intf, value);
1708 
1709     /* set as current alternate setting */
1710     intf->curr_setting = setting;
1711 
1712     return RT_EOK;
1713 }
1714 
1715 /**
1716  * This function will set a configuration for an usb device.
1717  *
1718  * @param device the usb device object.
1719  * @param wValue the configuration number.
1720  *
1721  * @return RT_EOK.
1722  */
rt_usbd_set_config(udevice_t device,rt_uint8_t value)1723 rt_err_t rt_usbd_set_config(udevice_t device, rt_uint8_t value)
1724 {
1725     uconfig_t cfg;
1726 
1727     LOG_D("rt_usbd_set_config");
1728 
1729     /* parameter check */
1730     RT_ASSERT(device != RT_NULL);
1731     RT_ASSERT(value <= device->dev_desc.bNumConfigurations);
1732 
1733     /* find a configuration */
1734     cfg = rt_usbd_find_config(device, value);
1735 
1736     /* set as current configuration */
1737     device->curr_cfg = cfg;
1738 
1739     dcd_set_config(device->dcd, value);
1740 
1741     return RT_TRUE;
1742 }
1743 
1744 /**
1745  * This function will bRequest an IO transaction.
1746  *
1747  * @param device the usb device object.
1748  * @param ep the endpoint object.
1749  * @param req IO bRequest.
1750  *
1751  * @return RT_EOK.
1752  */
rt_usbd_io_request(udevice_t device,uep_t ep,uio_request_t req)1753 rt_size_t rt_usbd_io_request(udevice_t device, uep_t ep, uio_request_t req)
1754 {
1755     rt_size_t size = 0;
1756 
1757     RT_ASSERT(device != RT_NULL);
1758     RT_ASSERT(req != RT_NULL);
1759 
1760     if(ep->stalled == RT_FALSE)
1761     {
1762         switch(req->req_type)
1763         {
1764         case UIO_REQUEST_READ_BEST:
1765         case UIO_REQUEST_READ_FULL:
1766             ep->request.remain_size = ep->request.size;
1767             size = rt_usbd_ep_read_prepare(device, ep, req->buffer, req->size);
1768             break;
1769         case UIO_REQUEST_WRITE:
1770             ep->request.remain_size = ep->request.size;
1771             size = rt_usbd_ep_write(device, ep, req->buffer, req->size);
1772             break;
1773         default:
1774             rt_kprintf("unknown request type\n");
1775             break;
1776         }
1777     }
1778     else
1779     {
1780         rt_list_insert_before(&ep->request_list, &req->list);
1781         LOG_D("suspend a request");
1782     }
1783 
1784     return size;
1785 }
1786 
1787 /**
1788  * This function will set feature for an usb device.
1789  *
1790  * @param device the usb device object.
1791  * @param wValue the configuration number.
1792  *
1793  * @return RT_EOK.
1794  */
rt_usbd_set_feature(udevice_t device,rt_uint16_t value,rt_uint16_t index)1795 rt_err_t rt_usbd_set_feature(udevice_t device, rt_uint16_t value, rt_uint16_t index)
1796 {
1797     RT_ASSERT(device != RT_NULL);
1798 
1799     if (value == USB_FEATURE_DEV_REMOTE_WAKEUP)
1800     {
1801         LOG_D("set feature remote wakeup");
1802     }
1803     else if (value == USB_FEATURE_ENDPOINT_HALT)
1804     {
1805         LOG_D("set feature stall");
1806         dcd_ep_set_stall(device->dcd, (rt_uint32_t)(index & 0xFF));
1807     }
1808 
1809     return RT_EOK;
1810 }
1811 
1812 /**
1813  * This function will clear feature for an usb device.
1814  *
1815  * @param device the usb device object.
1816  * @param wValue the configuration number.
1817  *
1818  * @return RT_EOK.
1819  */
rt_usbd_clear_feature(udevice_t device,rt_uint16_t value,rt_uint16_t index)1820 rt_err_t rt_usbd_clear_feature(udevice_t device, rt_uint16_t value, rt_uint16_t index)
1821 {
1822     RT_ASSERT(device != RT_NULL);
1823 
1824     if (value == USB_FEATURE_DEV_REMOTE_WAKEUP)
1825     {
1826         LOG_D("clear feature remote wakeup");
1827     }
1828     else if (value == USB_FEATURE_ENDPOINT_HALT)
1829     {
1830         LOG_D("clear feature stall");
1831         dcd_ep_clear_stall(device->dcd, (rt_uint32_t)(index & 0xFF));
1832     }
1833 
1834     return RT_EOK;
1835 }
1836 
rt_usbd_ep0_set_stall(udevice_t device)1837 rt_err_t rt_usbd_ep0_set_stall(udevice_t device)
1838 {
1839     RT_ASSERT(device != RT_NULL);
1840 
1841     return dcd_ep_set_stall(device->dcd, 0x80);
1842 }
1843 
rt_usbd_ep0_clear_stall(udevice_t device)1844 rt_err_t rt_usbd_ep0_clear_stall(udevice_t device)
1845 {
1846     RT_ASSERT(device != RT_NULL);
1847 
1848     return dcd_ep_clear_stall(device->dcd, 0x80);
1849 }
1850 
rt_usbd_ep_set_stall(udevice_t device,uep_t ep)1851 rt_err_t rt_usbd_ep_set_stall(udevice_t device, uep_t ep)
1852 {
1853     rt_err_t ret;
1854 
1855     RT_ASSERT(device != RT_NULL);
1856     RT_ASSERT(ep != RT_NULL);
1857     RT_ASSERT(ep->ep_desc != RT_NULL);
1858 
1859     ret = dcd_ep_set_stall(device->dcd, EP_ADDRESS(ep));
1860     if(ret == RT_EOK)
1861     {
1862         ep->stalled = RT_TRUE;
1863     }
1864 
1865     return ret;
1866 }
1867 
rt_usbd_ep_clear_stall(udevice_t device,uep_t ep)1868 rt_err_t rt_usbd_ep_clear_stall(udevice_t device, uep_t ep)
1869 {
1870     rt_err_t ret;
1871 
1872     RT_ASSERT(device != RT_NULL);
1873     RT_ASSERT(ep != RT_NULL);
1874     RT_ASSERT(ep->ep_desc != RT_NULL);
1875 
1876     ret = dcd_ep_clear_stall(device->dcd, EP_ADDRESS(ep));
1877     if(ret == RT_EOK)
1878     {
1879         ep->stalled = RT_FALSE;
1880     }
1881 
1882     return ret;
1883 }
1884 
rt_usbd_ep_assign(udevice_t device,uep_t ep)1885 static rt_err_t rt_usbd_ep_assign(udevice_t device, uep_t ep)
1886 {
1887     int i = 0;
1888 
1889     RT_ASSERT(device != RT_NULL);
1890     RT_ASSERT(device->dcd != RT_NULL);
1891     RT_ASSERT(device->dcd->ep_pool != RT_NULL);
1892     RT_ASSERT(ep != RT_NULL);
1893     RT_ASSERT(ep->ep_desc != RT_NULL);
1894 
1895     while(device->dcd->ep_pool[i].addr != 0xFF)
1896     {
1897         if(device->dcd->ep_pool[i].status == ID_UNASSIGNED &&
1898             ep->ep_desc->bmAttributes == device->dcd->ep_pool[i].type && (EP_ADDRESS(ep) & 0x80) == device->dcd->ep_pool[i].dir)
1899         {
1900             EP_ADDRESS(ep) |= device->dcd->ep_pool[i].addr;
1901             ep->id = &device->dcd->ep_pool[i];
1902             device->dcd->ep_pool[i].status = ID_ASSIGNED;
1903 
1904             LOG_D("assigned %d", device->dcd->ep_pool[i].addr);
1905             return RT_EOK;
1906         }
1907 
1908         i++;
1909     }
1910 
1911     return -RT_ERROR;
1912 }
1913 
rt_usbd_ep_unassign(udevice_t device,uep_t ep)1914 rt_err_t rt_usbd_ep_unassign(udevice_t device, uep_t ep)
1915 {
1916     RT_ASSERT(device != RT_NULL);
1917     RT_ASSERT(device->dcd != RT_NULL);
1918     RT_ASSERT(device->dcd->ep_pool != RT_NULL);
1919     RT_ASSERT(ep != RT_NULL);
1920     RT_ASSERT(ep->ep_desc != RT_NULL);
1921 
1922     ep->id->status = ID_UNASSIGNED;
1923 
1924     return RT_EOK;
1925 }
1926 
rt_usbd_ep0_setup_handler(udcd_t dcd,struct urequest * setup)1927 rt_err_t rt_usbd_ep0_setup_handler(udcd_t dcd, struct urequest* setup)
1928 {
1929     struct udev_msg msg;
1930     rt_size_t size;
1931 
1932     RT_ASSERT(dcd != RT_NULL);
1933 
1934     if(setup == RT_NULL)
1935     {
1936         size = dcd_ep_read(dcd, EP0_OUT_ADDR, (void*)&msg.content.setup);
1937         if(size != sizeof(struct urequest))
1938         {
1939             rt_kprintf("read setup packet error\n");
1940             return -RT_ERROR;
1941         }
1942     }
1943     else
1944     {
1945         rt_memcpy((void*)&msg.content.setup, (void*)setup, sizeof(struct urequest));
1946     }
1947 
1948     msg.type = USB_MSG_SETUP_NOTIFY;
1949     msg.dcd = dcd;
1950     rt_usbd_event_signal(&msg);
1951 
1952     return RT_EOK;
1953 }
1954 
rt_usbd_ep0_in_handler(udcd_t dcd)1955 rt_err_t rt_usbd_ep0_in_handler(udcd_t dcd)
1956 {
1957     rt_int32_t remain, mps;
1958 
1959     RT_ASSERT(dcd != RT_NULL);
1960 
1961     if (dcd->stage != STAGE_DIN)
1962         return RT_EOK;
1963 
1964     mps = dcd->ep0.id->maxpacket;
1965     dcd->ep0.request.remain_size -= mps;
1966     remain = dcd->ep0.request.remain_size;
1967 
1968     if (remain > 0)
1969     {
1970         if (remain >= mps)
1971         {
1972             remain = mps;
1973         }
1974 
1975         dcd->ep0.request.buffer += mps;
1976         dcd_ep_write(dcd, EP0_IN_ADDR, dcd->ep0.request.buffer, remain);
1977     }
1978     else
1979     {
1980         /* last packet is MPS multiple, so send ZLP packet */
1981         if ((remain == 0) && (dcd->ep0.request.size > 0))
1982         {
1983             dcd->ep0.request.size = 0;
1984             dcd_ep_write(dcd, EP0_IN_ADDR, RT_NULL, 0);
1985         }
1986         else
1987         {
1988             /* receive status */
1989             dcd->stage = STAGE_STATUS_OUT;
1990             dcd_ep_read_prepare(dcd, EP0_OUT_ADDR, RT_NULL, 0);
1991         }
1992     }
1993 
1994     return RT_EOK;
1995 }
1996 
rt_usbd_ep0_out_handler(udcd_t dcd,rt_size_t size)1997 rt_err_t rt_usbd_ep0_out_handler(udcd_t dcd, rt_size_t size)
1998 {
1999     struct udev_msg msg;
2000 
2001     RT_ASSERT(dcd != RT_NULL);
2002 
2003     msg.type = USB_MSG_EP0_OUT;
2004     msg.dcd = dcd;
2005     msg.content.ep_msg.size = size;
2006     rt_usbd_event_signal(&msg);
2007 
2008     return RT_EOK;
2009 }
2010 
rt_usbd_ep_in_handler(udcd_t dcd,rt_uint8_t address,rt_size_t size)2011 rt_err_t rt_usbd_ep_in_handler(udcd_t dcd, rt_uint8_t address, rt_size_t size)
2012 {
2013     struct udev_msg msg;
2014 
2015     RT_ASSERT(dcd != RT_NULL);
2016 
2017     msg.type = USB_MSG_DATA_NOTIFY;
2018     msg.dcd = dcd;
2019     msg.content.ep_msg.ep_addr = address;
2020     msg.content.ep_msg.size = size;
2021     rt_usbd_event_signal(&msg);
2022 
2023     return RT_EOK;
2024 }
2025 
rt_usbd_ep_out_handler(udcd_t dcd,rt_uint8_t address,rt_size_t size)2026 rt_err_t rt_usbd_ep_out_handler(udcd_t dcd, rt_uint8_t address, rt_size_t size)
2027 {
2028     struct udev_msg msg;
2029 
2030     RT_ASSERT(dcd != RT_NULL);
2031 
2032     msg.type = USB_MSG_DATA_NOTIFY;
2033     msg.dcd = dcd;
2034     msg.content.ep_msg.ep_addr = address;
2035     msg.content.ep_msg.size = size;
2036     rt_usbd_event_signal(&msg);
2037 
2038     return RT_EOK;
2039 }
2040 
rt_usbd_reset_handler(udcd_t dcd)2041 rt_err_t rt_usbd_reset_handler(udcd_t dcd)
2042 {
2043     struct udev_msg msg;
2044 
2045     RT_ASSERT(dcd != RT_NULL);
2046 
2047     msg.type = USB_MSG_RESET;
2048     msg.dcd = dcd;
2049     rt_usbd_event_signal(&msg);
2050 
2051     return RT_EOK;
2052 }
2053 
rt_usbd_connect_handler(udcd_t dcd)2054 rt_err_t rt_usbd_connect_handler(udcd_t dcd)
2055 {
2056     struct udev_msg msg;
2057 
2058     RT_ASSERT(dcd != RT_NULL);
2059 
2060     msg.type = USB_MSG_PLUG_IN;
2061     msg.dcd = dcd;
2062     rt_usbd_event_signal(&msg);
2063 
2064     return RT_EOK;
2065 }
2066 
rt_usbd_disconnect_handler(udcd_t dcd)2067 rt_err_t rt_usbd_disconnect_handler(udcd_t dcd)
2068 {
2069     struct udev_msg msg;
2070 
2071     RT_ASSERT(dcd != RT_NULL);
2072 
2073     msg.type = USB_MSG_PLUG_OUT;
2074     msg.dcd = dcd;
2075     rt_usbd_event_signal(&msg);
2076 
2077     return RT_EOK;
2078 }
2079 
rt_usbd_sof_handler(udcd_t dcd)2080 rt_err_t rt_usbd_sof_handler(udcd_t dcd)
2081 {
2082     struct udev_msg msg;
2083 
2084     RT_ASSERT(dcd != RT_NULL);
2085 
2086     msg.type = USB_MSG_SOF;
2087     msg.dcd = dcd;
2088     rt_usbd_event_signal(&msg);
2089 
2090     return RT_EOK;
2091 }
2092 
rt_usbd_ep0_write(udevice_t device,void * buffer,rt_size_t size)2093 rt_size_t rt_usbd_ep0_write(udevice_t device, void *buffer, rt_size_t size)
2094 {
2095     uep_t ep0;
2096     rt_size_t sent_size = 0;
2097 
2098     RT_ASSERT(device != RT_NULL);
2099     RT_ASSERT(device->dcd != RT_NULL);
2100     RT_ASSERT(buffer != RT_NULL);
2101     RT_ASSERT(size > 0);
2102 
2103     ep0 = &device->dcd->ep0;
2104     ep0->request.size = size;
2105     ep0->request.buffer = (rt_uint8_t *)buffer;
2106     ep0->request.remain_size = size;
2107     if(size >= ep0->id->maxpacket)
2108     {
2109         sent_size = ep0->id->maxpacket;
2110     }
2111     else
2112     {
2113         sent_size = size;
2114     }
2115     device->dcd->stage = STAGE_DIN;
2116 
2117     return dcd_ep_write(device->dcd, EP0_IN_ADDR, ep0->request.buffer, sent_size);
2118 }
2119 
rt_usbd_ep0_read(udevice_t device,void * buffer,rt_size_t size,rt_err_t (* rx_ind)(udevice_t device,rt_size_t size))2120 rt_size_t rt_usbd_ep0_read(udevice_t device, void *buffer, rt_size_t size,
2121     rt_err_t (*rx_ind)(udevice_t device, rt_size_t size))
2122 {
2123     uep_t ep0;
2124     rt_size_t read_size = 0;
2125 
2126     RT_ASSERT(device != RT_NULL);
2127     RT_ASSERT(device->dcd != RT_NULL);
2128     RT_ASSERT(buffer != RT_NULL);
2129 
2130     ep0 = &device->dcd->ep0;
2131     ep0->request.buffer = (rt_uint8_t *)buffer;
2132     ep0->request.remain_size = size;
2133     ep0->rx_indicate = rx_ind;
2134     if(size >= ep0->id->maxpacket)
2135     {
2136         read_size = ep0->id->maxpacket;
2137     }
2138     else
2139     {
2140         read_size = size;
2141     }
2142     device->dcd->stage = STAGE_DOUT;
2143     dcd_ep_read_prepare(device->dcd, EP0_OUT_ADDR, buffer, read_size);
2144 
2145     return size;
2146 }
2147 
2148 static struct rt_messagequeue usb_mq;
2149 
2150 /**
2151  * This function is the main entry of usb device thread, it is in charge of
2152  * processing all messages received from the usb message buffer.
2153  *
2154  * @param parameter the parameter of the usb device thread.
2155  *
2156  * @return none.
2157  */
rt_usbd_thread_entry(void * parameter)2158 static void rt_usbd_thread_entry(void* parameter)
2159 {
2160     while(1)
2161     {
2162         struct udev_msg msg;
2163         udevice_t device;
2164 
2165         /* receive message */
2166         if(rt_mq_recv(&usb_mq, &msg, sizeof(struct udev_msg),
2167                     RT_WAITING_FOREVER) < 0)
2168             continue;
2169 
2170         device = rt_usbd_find_device(msg.dcd);
2171         if(device == RT_NULL)
2172         {
2173             rt_kprintf("invalid usb device\n");
2174             continue;
2175         }
2176 
2177         LOG_D("message type %d", msg.type);
2178 
2179         switch (msg.type)
2180         {
2181         case USB_MSG_SOF:
2182             _sof_notify(device);
2183             break;
2184         case USB_MSG_DATA_NOTIFY:
2185             /* some buggy drivers will have USB_MSG_DATA_NOTIFY before the core
2186              * got configured. */
2187             _data_notify(device, &msg.content.ep_msg);
2188             break;
2189         case USB_MSG_SETUP_NOTIFY:
2190             _setup_request(device, &msg.content.setup);
2191             break;
2192         case USB_MSG_EP0_OUT:
2193             _ep0_out_notify(device, &msg.content.ep_msg);
2194             break;
2195         case USB_MSG_RESET:
2196             LOG_D("reset %d", device->state);
2197             if (device->state == USB_STATE_ADDRESS || device->state == USB_STATE_CONFIGURED)
2198                 _stop_notify(device);
2199             device->state = USB_STATE_NOTATTACHED;
2200             break;
2201         case USB_MSG_PLUG_IN:
2202             device->state = USB_STATE_ATTACHED;
2203             break;
2204         case USB_MSG_PLUG_OUT:
2205             device->state = USB_STATE_NOTATTACHED;
2206             _stop_notify(device);
2207             break;
2208         default:
2209             rt_kprintf("unknown msg type %d\n", msg.type);
2210             break;
2211         }
2212     }
2213 }
2214 
2215 /**
2216  * This function will post an message to usb message queue,
2217  *
2218  * @param msg the message to be posted
2219  * @param size the size of the message .
2220  *
2221  * @return the error code, RT_EOK on successfully.
2222  */
rt_usbd_event_signal(struct udev_msg * msg)2223 rt_err_t rt_usbd_event_signal(struct udev_msg* msg)
2224 {
2225     RT_ASSERT(msg != RT_NULL);
2226 
2227     /* send message to usb message queue */
2228     return rt_mq_send(&usb_mq, (void*)msg, sizeof(struct udev_msg));
2229 }
2230 
2231 
2232 rt_align(RT_ALIGN_SIZE)
2233 static rt_uint8_t usb_thread_stack[RT_USBD_THREAD_STACK_SZ];
2234 static struct rt_thread usb_thread;
2235 #define USBD_MQ_MSG_SZ  32
2236 #define USBD_MQ_MAX_MSG 16
2237 /* internal of the message queue: every message is associated with a pointer,
2238  * so in order to recveive USBD_MQ_MAX_MSG messages, we have to allocate more
2239  * than USBD_MQ_MSG_SZ*USBD_MQ_MAX_MSG memory. */
2240 static rt_uint8_t usb_mq_pool[(USBD_MQ_MSG_SZ+sizeof(void*))*USBD_MQ_MAX_MSG];
2241 
2242 /**
2243  * This function will initialize usb device thread.
2244  *
2245  * @return none.
2246  *
2247  */
rt_usbd_core_init(void)2248 rt_err_t rt_usbd_core_init(void)
2249 {
2250     rt_list_init(&device_list);
2251 
2252     /* create an usb message queue */
2253     rt_mq_init(&usb_mq,
2254                "usbd",
2255                usb_mq_pool, USBD_MQ_MSG_SZ,
2256                sizeof(usb_mq_pool),
2257                RT_IPC_FLAG_FIFO);
2258 
2259     /* init usb device thread */
2260     rt_thread_init(&usb_thread,
2261                    "usbd",
2262                    rt_usbd_thread_entry, RT_NULL,
2263                    usb_thread_stack, RT_USBD_THREAD_STACK_SZ,
2264                    RT_USBD_THREAD_PRIO, 20);
2265     /* rt_thread_init should always be OK, so start the thread without further
2266      * checking. */
2267     return rt_thread_startup(&usb_thread);
2268 }
2269 
2270