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