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