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