M471M/R1/S BSP V3.01.000
The Board Support Package for M4521
usb_core.c
Go to the documentation of this file.
1/**************************************************************************/
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12
13#include "NuMicro.h"
14
15#include "usb.h"
16#include "hub.h"
17
18
20
21USBH_T *_ohci;
22
23int _IsInUsbInterrupt = 0;
24
25static UDEV_DRV_T * _drivers[MAX_UDEV_DRIVER];
26
27static CONN_FUNC *g_conn_func, *g_disconn_func;
28
30
31
38{
39 DISABLE_OHCI_IRQ();
40
41 _ohci = USBH;
42
43 memset(_drivers, 0, sizeof(_drivers));
44
45 g_conn_func = NULL;
46 g_disconn_func = NULL;
47
48 usbh_hub_init();
49
50 usbh_memory_init();
51
52 _ohci->HcPhyControl &= ~USBH_HcPhyControl_STBYEN_Msk; /* Never enter the standby mode */
53
54 _ohci->HcMiscControl |= USBH_HcMiscControl_OCAL_Msk; /* Over-current active low */
55 //_ohci->HcMiscControl &= ~USBH_HcMiscControl_OCAL_Msk; /* Over-current active high */
56
57#ifdef ENABLE_OHCI
58 ohci_driver.init();
59 ENABLE_OHCI_IRQ();
60#endif
61}
62
70void usbh_install_conn_callback(CONN_FUNC *conn_func, CONN_FUNC *disconn_func)
71{
72 g_conn_func = conn_func;
73 g_disconn_func = disconn_func;
74}
75
76static int reset_device(UDEV_T *udev)
77{
78 if(udev->parent == NULL)
79 {
80 if(udev->hc_driver)
81 return udev->hc_driver->rthub_port_reset(udev->port_num - 1);
82 else
83 return USBH_ERR_NOT_FOUND;
84 }
85 else
86 {
87 return udev->parent->port_reset(udev->parent, udev->port_num);
88 }
89}
90
96{
97#ifdef ENABLE_OHCI
98 /* set port suspend if connected */
100 _ohci->HcRhPortStatus[0] = USBH_HcRhPortStatus_PSS_Msk; /* set port suspend */
101
103 _ohci->HcRhPortStatus[1] = USBH_HcRhPortStatus_PSS_Msk; /* set port suspend */
104
105 /* enable Device Remote Wakeup */
107
108 /* enable USBH RHSC interrupt for system wakeup */
110
111 /* set Host Controller enter suspend state */
112 _ohci->HcControl = (_ohci->HcControl & ~USBH_HcControl_HCFS_Msk) | (3 << USBH_HcControl_HCFS_Pos);
113#endif
114}
115
116
121void usbh_resume(void)
122{
123#ifdef ENABLE_OHCI
124 _ohci->HcControl = (_ohci->HcControl & ~USBH_HcControl_HCFS_Msk) | (1 << USBH_HcControl_HCFS_Pos);
125
127 _ohci->HcRhPortStatus[0] = USBH_HcRhPortStatus_POCI_Msk; /* clear suspend status */
129 _ohci->HcRhPortStatus[1] = USBH_HcRhPortStatus_POCI_Msk; /* clear suspend status */
130
131 delay_us(30000); /* wait at least 20ms for Host to resume device */
132
133 /* enter operational state */
134 _ohci->HcControl = (_ohci->HcControl & ~USBH_HcControl_HCFS_Msk) | (2 << USBH_HcControl_HCFS_Pos);
135#endif
136}
137
138
139
141
150int usbh_register_driver(UDEV_DRV_T *udrv)
151{
152 int i;
153
154 for(i = 0; i < MAX_UDEV_DRIVER; i++)
155 {
156 if(_drivers[i] == udrv)
157 return 0; /* already registered, do nothing */
158
159 if(_drivers[i] == NULL)
160 {
161 _drivers[i] = udrv; /* register this driver */
162 return 0;
163 }
164 }
165 return USBH_ERR_MEMORY_OUT; /* reached MAX_UDEV_DRIVER limitation, aborted */
166}
167
168
185int usbh_ctrl_xfer(UDEV_T *udev, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
186 uint16_t wLength, uint8_t *buff, uint32_t *xfer_len, uint32_t timeout)
187{
188 UTR_T *utr;
189 uint32_t t0;
190 int status;
191
192 *xfer_len = 0;
193
194 //if (check_device(udev))
195 // return USBH_ERR_INVALID_PARAM;
196
197 utr = alloc_utr(udev);
198 if(utr == NULL)
199 return USBH_ERR_MEMORY_OUT;
200
201 utr->setup.bmRequestType = bmRequestType;
202 utr->setup.bRequest = bRequest;
203 utr->setup.wValue = wValue;
204 utr->setup.wIndex = wIndex;
205 utr->setup.wLength = wLength;
206
207 utr->buff = buff;
208 utr->data_len = wLength;
209 utr->bIsTransferDone = 0;
210 status = udev->hc_driver->ctrl_xfer(utr);
211 if(status < 0)
212 {
213 udev->ep0.hw_pipe = NULL;
214 free_utr(utr);
215 return status;
216 }
217
218 t0 = get_ticks();
219 while(utr->bIsTransferDone == 0)
220 {
221 if(get_ticks() - t0 > timeout)
222 {
223 usbh_quit_utr(utr);
224 free_utr(utr);
225 udev->ep0.hw_pipe = NULL;
226 return USBH_ERR_TIMEOUT;
227 }
228 }
229
230 status = utr->status;
231
232 if(status == 0)
233 {
234 *xfer_len = utr->xfer_len;
235 }
236 free_utr(utr);
237
238 return status;
239}
240
241
250int usbh_bulk_xfer(UTR_T *utr)
251{
252 return utr->udev->hc_driver->bulk_xfer(utr);
253}
254
263int usbh_int_xfer(UTR_T *utr)
264{
265 return utr->udev->hc_driver->int_xfer(utr);
266}
267
276int usbh_iso_xfer(UTR_T *utr)
277{
278 if(utr->udev->hc_driver == NULL)
279 {
280 printf("hc_driver - 0x%x\n", (int)utr->udev->hc_driver);
281 return -1;
282 }
283 if(utr->udev->hc_driver->iso_xfer == NULL)
284 {
285 printf("iso_xfer - 0x%x\n", (int)utr->udev->hc_driver->iso_xfer);
286 return -1;
287 }
288 return utr->udev->hc_driver->iso_xfer(utr);
289}
290
297int usbh_quit_utr(UTR_T *utr)
298{
299 if(!utr || !utr->udev)
300 return USBH_ERR_NOT_FOUND;
301
302 return utr->udev->hc_driver->quit_xfer(utr, NULL);
303}
304
305
313int usbh_quit_xfer(UDEV_T *udev, EP_INFO_T *ep)
314{
315 return udev->hc_driver->quit_xfer(NULL, ep);
316}
317
318
319void dump_device_descriptor(DESC_DEV_T *desc)
320{
321 USB_debug("\n[Device Descriptor]\n");
322 USB_debug("----------------------------------------------\n");
323 USB_debug(" Length = %2d\n", desc->bLength);
324 USB_debug(" DescriptorType = 0x%02x\n", desc->bDescriptorType);
325 USB_debug(" USB version = %x.%02x\n",
326 desc->bcdUSB >> 8, desc->bcdUSB & 0xff);
327 USB_debug(" Vendor:Product = %04x:%04x\n",
328 desc->idVendor, desc->idProduct);
329 USB_debug(" MaxPacketSize0 = %d\n", desc->bMaxPacketSize0);
330 USB_debug(" NumConfigurations = %d\n", desc->bNumConfigurations);
331 USB_debug(" Device version = %x.%02x\n",
332 desc->bcdDevice >> 8, desc->bcdDevice & 0xff);
333 USB_debug(" Device Class:SubClass:Protocol = %02x:%02x:%02x\n",
334 desc->bDeviceClass, desc->bDeviceSubClass, desc->bDeviceProtocol);
335}
336
337void usbh_dump_interface_descriptor(DESC_IF_T *if_desc)
338{
339 USB_debug("\n [Interface Descriptor]\n");
340 USB_debug(" ----------------------------------------------\n");
341 USB_debug(" Length = %2d\n", if_desc->bLength);
342 USB_debug(" DescriptorType = %02x\n", if_desc->bDescriptorType);
343 USB_debug(" bInterfaceNumber = %d\n", if_desc->bInterfaceNumber);
344 USB_debug(" bAlternateSetting = %d\n", if_desc->bAlternateSetting);
345 USB_debug(" bNumEndpoints = %d\n", if_desc->bNumEndpoints);
346 USB_debug(" bInterfaceClass = 0x%02x\n", if_desc->bInterfaceClass);
347 USB_debug(" bInterfaceSubClass = 0x%02x\n", if_desc->bInterfaceSubClass);
348 USB_debug(" bInterfaceProtocol = 0x%02x\n", if_desc->bInterfaceProtocol);
349 USB_debug(" iInterface = %d\n", if_desc->iInterface);
350}
351
352void usbh_dump_endpoint_descriptor(DESC_EP_T *ep_desc)
353{
354 USB_debug("\n [Endpoint Descriptor]\n");
355 USB_debug(" ----------------------------------------------\n");
356 USB_debug(" Length = %2d\n", ep_desc->bLength);
357 USB_debug(" DescriptorType = %02x\n", ep_desc->bDescriptorType);
358 USB_debug(" bEndpointAddress = 0x%02x\n", ep_desc->bEndpointAddress);
359 USB_debug(" bmAttributes = 0x%02x\n", ep_desc->bmAttributes);
360 USB_debug(" wMaxPacketSize = %d\n", ep_desc->wMaxPacketSize);
361 USB_debug(" bInterval = %d\n", ep_desc->bInterval);
362 USB_debug(" bRefresh = %d\n", ep_desc->bRefresh);
363 USB_debug(" bSynchAddress = %d\n", ep_desc->bSynchAddress);
364}
365
366void dump_config_descriptor(DESC_CONF_T *desc)
367{
368 uint8_t *bptr = (uint8_t *)desc;
369 DESC_HDR_T *hdr;
370 int tlen = desc->wTotalLength;
371
372 while(tlen > 0)
373 {
374 switch(bptr[1])
375 {
376 case USB_DT_CONFIGURATION:
377 USB_debug("\n[Configuration Descriptor]\n");
378 USB_debug("----------------------------------------------\n");
379 USB_debug(" Length = %2d\n", desc->bLength);
380 USB_debug(" DescriptorType = %02x\n", desc->bDescriptorType);
381 USB_debug(" wTotalLength = %2d\n", desc->wTotalLength);
382 USB_debug(" bNumInterfaces = %d\n", desc->bNumInterfaces);
383 USB_debug(" bConfigurationValue = %d\n", desc->bConfigurationValue);
384 USB_debug(" iConfiguration = %d\n", desc->iConfiguration);
385 USB_debug(" bmAttributes = 0x%02x\n", desc->bmAttributes);
386 USB_debug(" MaxPower = %d\n", desc->MaxPower);
387 break;
388
389 case USB_DT_INTERFACE:
390 usbh_dump_interface_descriptor((DESC_IF_T *)bptr);
391 break;
392
393 case USB_DT_ENDPOINT:
394 usbh_dump_endpoint_descriptor((DESC_EP_T *)bptr);
395 break;
396
397 default:
398 hdr = (DESC_HDR_T *)bptr;
399 USB_debug("\n!![Unknown Descriptor]\n");
400 USB_debug("----------------------------------------------\n");
401 USB_debug("Length = %2d\n", hdr->bLength);
402 USB_debug("DescriptorType = %02x\n", hdr->bDescriptorType);
403 break;
404 }
405 if(bptr[0] == 0)
406 break;
407 tlen -= bptr[0];
408 bptr += bptr[0];
409 }
410}
411
417int usbh_set_address(UDEV_T *udev)
418{
419 uint32_t read_len;
420 int dev_num, ret;
421
422 if(udev->dev_num != 0)
424
425 dev_num = alloc_dev_address();
426
427 /*------------------------------------------------------------------------------------*/
428 /* Issue SET ADDRESS command to set device address */
429 /*------------------------------------------------------------------------------------*/
430 ret = usbh_ctrl_xfer(udev, REQ_TYPE_OUT | REQ_TYPE_STD_DEV | REQ_TYPE_TO_DEV,
431 USB_REQ_SET_ADDRESS, dev_num, 0, 0,
432 NULL, &read_len, 100);
433 if(ret < 0)
434 {
435 free_dev_address(dev_num);
436 return ret;
437 }
438
439 udev->dev_num = dev_num;
440
441 return 0;
442}
443
449int usbh_set_configuration(UDEV_T *udev, uint8_t conf_val)
450{
451 uint32_t read_len;
452 int ret;
453
454 /* Current configuration is the same. Do nothing. */
455 if(udev->cur_conf == conf_val)
456 return 0;
457
458 /* Set another configuration is currently not supported! */
459 if(udev->cur_conf != -1)
460 return USBH_ERR_SET_CONFIG;
461
462 /*------------------------------------------------------------------------------------*/
463 /* Issue SET CONFIGURATION command to select device configuration */
464 /*------------------------------------------------------------------------------------*/
465 ret = usbh_ctrl_xfer(udev, REQ_TYPE_OUT | REQ_TYPE_STD_DEV | REQ_TYPE_TO_DEV,
466 USB_REQ_SET_CONFIGURATION, conf_val, 0, 0,
467 NULL, &read_len, 300);
468 if(ret < 0)
469 return ret;
470
471 udev->cur_conf = (int8_t)conf_val;
472
473 return 0;
474}
475
483int usbh_set_interface(IFACE_T *iface, uint16_t alt_setting)
484{
485 ALT_IFACE_T *aif = NULL;
486 uint32_t xfer_len;
487 int i, ret;
488
489 for(i = 0; i < iface->num_alt; i++)
490 {
491 if(iface->alt[i].ifd->bAlternateSetting == alt_setting)
492 {
493 aif = &iface->alt[i];
494 break;
495 }
496 }
497 if(aif == NULL)
498 return USBH_ERR_NOT_FOUND; /* cannot find desired alternative setting */
499
500 ret = usbh_ctrl_xfer(iface->udev, REQ_TYPE_OUT | REQ_TYPE_STD_DEV | REQ_TYPE_TO_IFACE,
501 USB_REQ_SET_INTERFACE, alt_setting, iface->if_num, 0,
502 NULL, &xfer_len, 100);
503 if(ret == 0)
504 iface->aif = aif; /* change active alternative setting */
505 return ret;
506}
507
515int usbh_get_device_descriptor(UDEV_T *udev, DESC_DEV_T *desc_buff)
516{
517 uint32_t read_len;
518 int ret, retry;
519 int timeout = 10;
520
521 for(retry = 0; retry < 3; retry++)
522 {
523 ret = usbh_ctrl_xfer(udev, REQ_TYPE_IN | REQ_TYPE_STD_DEV | REQ_TYPE_TO_DEV,
524 USB_REQ_GET_DESCRIPTOR,
525 ((USB_DT_STANDARD | USB_DT_DEVICE) << 8), 0, sizeof(DESC_DEV_T),
526 (uint8_t *)desc_buff, &read_len, timeout);
527 if(ret == 0)
528 return 0;
529
530 USB_debug("Get device descriptor failed - %d, retry!\n", ret);
531 }
532 return ret;
533}
534
543int usbh_get_config_descriptor(UDEV_T *udev, uint8_t *desc_buff, int buff_len)
544{
545 uint32_t read_len;
546 DESC_CONF_T *conf = (DESC_CONF_T *)desc_buff;
547 int ret;
548
549 /*------------------------------------------------------------------------------------*/
550 /* Issue GET DESCRIPTOR command to get configuration descriptor */
551 /*------------------------------------------------------------------------------------*/
552 ret = usbh_ctrl_xfer(udev, REQ_TYPE_IN | REQ_TYPE_STD_DEV | REQ_TYPE_TO_DEV,
553 USB_REQ_GET_DESCRIPTOR,
554 ((USB_DT_STANDARD | USB_DT_CONFIGURATION) << 8), 0, 9,
555 desc_buff, &read_len, 200);
556 if(ret < 0)
557 return ret;
558
559 if(conf->wTotalLength > buff_len)
560 {
561 USB_error("Device configuration %d length > %d!\n", conf->wTotalLength, buff_len);
563 }
564
565 read_len = conf->wTotalLength;
566
567 ret = usbh_ctrl_xfer(udev, REQ_TYPE_IN | REQ_TYPE_STD_DEV | REQ_TYPE_TO_DEV,
568 USB_REQ_GET_DESCRIPTOR,
569 ((USB_DT_STANDARD | USB_DT_CONFIGURATION) << 8), 0, read_len,
570 desc_buff, &read_len, 200);
571 if(ret < 0)
572 return ret;
573
574 return 0;
575}
576
587int usbh_get_string_descriptor(UDEV_T *udev, int index, uint8_t *desc_buff, int buff_len)
588{
589 uint32_t read_len;
590 int ret;
591
592 /*------------------------------------------------------------------------------------*/
593 /* Issue GET DESCRIPTOR command to get configuration descriptor */
594 /*------------------------------------------------------------------------------------*/
595 ret = usbh_ctrl_xfer(udev, REQ_TYPE_IN | REQ_TYPE_STD_DEV | REQ_TYPE_TO_DEV,
596 USB_REQ_GET_DESCRIPTOR,
597 ((USB_DT_STANDARD | USB_DT_STRING) << 8) | index, 0x0409, buff_len,
598 desc_buff, &read_len, 200);
599 return ret;
600}
601
609int usbh_clear_halt(UDEV_T *udev, uint16_t ep_addr)
610{
611 uint32_t read_len;
612
613 USB_debug("Clear endpoint 0x%x halt.\n", ep_addr);
614 return usbh_ctrl_xfer(udev, REQ_TYPE_OUT | REQ_TYPE_STD_DEV | REQ_TYPE_TO_EP,
615 USB_REQ_CLEAR_FEATURE, 0, ep_addr, 0,
616 NULL, &read_len, 100);
617}
618
619static int usbh_parse_endpoint(ALT_IFACE_T *alt, int ep_idx, uint8_t *desc_buff, int len)
620{
621 DESC_EP_T *ep_desc;
622 int parsed_len = 0;
623 int pksz;
624
625 while(len > 0)
626 {
627 ep_desc = (DESC_EP_T *)desc_buff;
628
629 if((len < ep_desc->bLength) || (ep_desc->bLength < 2))
630 {
631 USB_error("ERR DESCRIPTOR EP LEN [0x%X %d]\n", ep_desc->bDescriptorType, ep_desc->bLength);
632 return USBH_ERR_DESCRIPTOR;
633 }
634
635 if(ep_desc->bDescriptorType == USB_DT_ENDPOINT)
636 break; /* endpoint descriptor found */
637
638 /* unrecognized descriptor */
639 USB_vdebug("ignore descriptor 0x%X %d\n", ep_desc->bDescriptorType, ep_desc->bLength);
640 desc_buff += ep_desc->bLength;
641 parsed_len += ep_desc->bLength;
642 len -= ep_desc->bLength;
643 }
644
645 USB_vdebug("Descriptor Found - Alt: %d, Endpoint 0x%x, remaining len: %d\n", alt->ifd->bAlternateSetting, ep_desc->bEndpointAddress, len);
646
647 alt->ep[ep_idx].bEndpointAddress = ep_desc->bEndpointAddress;
648 alt->ep[ep_idx].bmAttributes = ep_desc->bmAttributes;
649 alt->ep[ep_idx].bInterval = ep_desc->bInterval;
650 pksz = ep_desc->wMaxPacketSize;
651 pksz = (pksz & 0x07ff) * (1 + ((pksz >> 11) & 3));
652 alt->ep[ep_idx].wMaxPacketSize = pksz;
653 alt->ep[ep_idx].hw_pipe = NULL;
654
655 return parsed_len + ep_desc->bLength;
656}
657
667static int usbh_parse_interface(UDEV_T *udev, uint8_t *desc_buff, int len)
668{
669 int i, matched, parsed_len = 0;
670 DESC_HDR_T *hdr;
671 DESC_IF_T *if_desc;
672 IFACE_T *iface = NULL;
673 int ret;
674
675 iface = usbh_alloc_mem(sizeof(*iface)); /* create an interface */
676 if(iface == NULL)
677 return USBH_ERR_MEMORY_OUT;
678 iface->udev = udev;
679 iface->aif = &iface->alt[0]; /* Default active interface should be the
680 first found alternative interface */
681 iface->if_num = ((DESC_IF_T *)desc_buff)->bInterfaceNumber;
682
683 while(len > 0)
684 {
685 /*--------------------------------------------------------------------------------*/
686 /* Find the first/next interface descriptor */
687 /*--------------------------------------------------------------------------------*/
688 if_desc = (DESC_IF_T *)desc_buff;
689
690 if(if_desc->bDescriptorType != USB_DT_INTERFACE)
691 {
692 desc_buff += if_desc->bLength;
693 parsed_len += if_desc->bLength;
694 len -= if_desc->bLength;
695 continue;
696 }
697
698 if(if_desc->bInterfaceNumber != iface->if_num)
699 {
700 goto parse_done;
701 }
702
703 if(if_desc->bNumEndpoints > MAX_EP_PER_IFACE)
704 {
705 USB_error("IF EP LIMITE %d\n", if_desc->bNumEndpoints);
707 goto err_out;
708 }
709
710 /* Step over the interface descriptor */
711 desc_buff += if_desc->bLength;
712 parsed_len += if_desc->bLength;
713 len -= if_desc->bLength;
714 USB_vdebug("Descriptor Found - Interface %d, Alt: %d, num_alt:%d, remaining len: %d\n", if_desc->bInterfaceNumber, if_desc->bAlternateSetting, iface->num_alt, len);
715
716 /*--------------------------------------------------------------------------------*/
717 /* Add to alternative interface list */
718 /*--------------------------------------------------------------------------------*/
719 if(iface->num_alt >= MAX_ALT_PER_IFACE)
720 {
722 goto err_out;
723 }
724
725 /*--------------------------------------------------------------------------------*/
726 /* Find the next alternative interface or endpoint descriptor */
727 /*--------------------------------------------------------------------------------*/
728 while(len > 0)
729 {
730 hdr = (DESC_HDR_T *)desc_buff;
731
732 if((len < hdr->bLength) || (hdr->bLength < 2))
733 {
734 USB_error("ERR DESCRIPTOR IF LEN [0x%X %d]\n", hdr->bDescriptorType, hdr->bLength);
736 goto err_out;
737 }
738
739 if(hdr->bDescriptorType == USB_DT_CONFIGURATION)
740 goto parse_done; /* is other configuration, parsing completed */
741
742 if((hdr->bDescriptorType == USB_DT_INTERFACE) || (hdr->bDescriptorType == USB_DT_ENDPOINT))
743 break; /* the first endpoint descriptor found */
744
745 /* unrecognized descriptor */
746 USB_vdebug("ignore descriptor 0x%X %d\n", hdr->bDescriptorType, hdr->bLength);
747 desc_buff += hdr->bLength;
748 parsed_len += hdr->bLength;
749 len -= hdr->bLength;
750 }
751
752 iface->alt[iface->num_alt].ifd = if_desc;
753 iface->num_alt++;
754
755 if(len == 0)
756 goto parse_done;
757
758 if(hdr->bDescriptorType == USB_DT_INTERFACE)
759 continue; /* is the next interface descriptor */
760
761 USB_vdebug("Finding %d endpoints of interface %d, alt %d...\n", if_desc->bNumEndpoints, if_desc->bInterfaceNumber, if_desc->bAlternateSetting);
762
763 /* parsign all endpoint descriptors */
764 for(i = 0; i < if_desc->bNumEndpoints; i++)
765 {
766 ret = usbh_parse_endpoint(&iface->alt[iface->num_alt - 1], i, desc_buff, len);
767 if(ret < 0)
768 goto err_out;
769
770 desc_buff += ret;
771 parsed_len += ret;
772 len -= ret;
773 USB_vdebug("EP parse remaining %d\n", len);
774 }
775 }
776
777parse_done:
778
779 /*
780 * Probing all registered USB device drivers to find a matched driver.
781 */
782 matched = 0;
783 for(i = 0; i < MAX_UDEV_DRIVER; i++)
784 {
785 if((_drivers[i] != NULL) && (_drivers[i]->probe(iface) == 0))
786 {
787 matched = 1;
788 break;
789 }
790 }
791
792 if(matched)
793 {
794 iface->driver = _drivers[i]; /* have a driver now */
795 iface->next = NULL;
796
797 /* Added this interface to USB device interface list */
798 if(udev->iface_list == NULL)
799 udev->iface_list = iface;
800 else
801 {
802 iface->next = udev->iface_list;
803 udev->iface_list = iface;
804 }
805 }
806 else
807 {
808 usbh_free_mem(iface, sizeof(*iface));
809 iface = NULL;
810 }
811
812 return parsed_len;
813
814err_out:
815 usbh_free_mem(iface, sizeof(*iface));
816 return ret;
817}
818
819
820static int usbh_parse_configuration(UDEV_T *udev, uint8_t *desc_buff)
821{
822 DESC_CONF_T *config = (DESC_CONF_T *)desc_buff;
823 DESC_HDR_T *hdr;
824 int i, ret, len;
825
826 len = config->wTotalLength;
827
828 desc_buff += config->bLength;
829 len -= config->bLength;
830
831 USB_vdebug("Parsing CONFIG =>\n");
832
833 for(i = 0; i < config->bNumInterfaces; i++)
834 {
835 /*
836 * find the next interface descriptor
837 */
838 while(len >= sizeof(DESC_HDR_T))
839 {
840 hdr = (DESC_HDR_T *)desc_buff;
841
842 if((hdr->bLength > len) || (hdr->bLength < 2))
843 {
844 USB_error("ERR DESCRIPTOR CONFIG [%d]\n", hdr->bLength);
845 return USBH_ERR_DESCRIPTOR;
846 }
847
848 if(hdr->bDescriptorType == USB_DT_INTERFACE)
849 break;
850
851 USB_debug("ignore descriptor 0x%X %d\n", hdr->bDescriptorType, hdr->bLength);
852
853 desc_buff += hdr->bLength;
854 len -= hdr->bLength;
855 }
856
857 ret = usbh_parse_interface(udev, desc_buff, len);
858 if(ret < 0)
859 return ret;
860
861 desc_buff += ret;
862 len -= ret;
863 USB_vdebug("IFACE parse remaining %d\n", len);
864 }
865
866 if(len > 0)
867 {
868 USB_debug("ERR DESCRIPTOR CONFIG LEN %d\n", len);
869 return USBH_ERR_DESCRIPTOR;
870 }
871 return len;
872}
873
874void print_usb_string(char *lead, uint8_t *str)
875{
876 int len, i = 2;
877
878 USB_debug("%s", lead);
879 len = str[0];
880 while(i < len)
881 {
882 USB_debug("%c", str[i]);
883 i += 2;
884 }
885 USB_debug("\n");
886}
887
888int connect_device(UDEV_T *udev)
889{
890 DESC_CONF_T *conf;
891 uint32_t read_len;
892 int ret;
893
894 USB_debug("Connect device =>\n");
895
896 delay_us(100 * 1000); /* initially, give 100 ms delay */
897
898 usbh_get_device_descriptor(udev, &udev->descriptor);
899
900 reset_device(udev);
901
902 delay_us(100 * 1000);
903
904 ret = usbh_set_address(udev);
905 if(ret < 0)
906 {
907 USB_debug("Set address command failed!!\n");
908 return ret;
909 }
910
911 delay_us(100 * 1000); /* after set address, give 100 ms delay */
912
913 USB_debug("New %s device address %d assigned.\n", (udev->speed == SPEED_HIGH) ? "high-speed" : ((udev->speed == SPEED_FULL) ? "full-speed" : "low-speed"), udev->dev_num);
914
915 /* Get device descriptor again with new device address */
916 ret = usbh_get_device_descriptor(udev, &udev->descriptor);
917 if(ret < 0)
918 {
919 free_dev_address(udev->dev_num);
920 return ret;
921 }
922
923#if defined(DUMP_DESCRIPTOR) && defined(ENABLE_DEBUG_MSG)
924 dump_device_descriptor(&udev->descriptor);
925#endif
926
927 if(udev->descriptor.bNumConfigurations != 1)
928 {
929 USB_debug("Warning! This device has multiple configurations [%d]. \n", udev->descriptor.bNumConfigurations);
930 }
931
932 conf = (DESC_CONF_T *)usbh_alloc_mem(MAX_DESC_BUFF_SIZE);
933 if(conf == NULL)
934 {
935 free_dev_address(udev->dev_num);
936 return USBH_ERR_MEMORY_OUT;
937 }
938
939 udev->cfd_buff = (uint8_t *)conf;
940
941 /* Get configuration descriptor again with new device address */
942 ret = usbh_get_config_descriptor(udev, (uint8_t *)conf, MAX_DESC_BUFF_SIZE);
943 if(ret < 0)
944 {
945 free_dev_address(udev->dev_num);
946 return ret;
947 }
948
949#if defined(DUMP_DESCRIPTOR) && defined(ENABLE_DEBUG_MSG)
950 dump_config_descriptor(conf);
951#endif
952
953#if 0 /* printf string descriptors, for debug only */
954 str_buff = (uint8_t *)usbh_alloc_mem(MAX_DESC_BUFF_SIZE);
955 if(udev->descriptor.iManufacturer != 0)
956 {
957 usbh_get_string_descriptor(udev, udev->descriptor.iManufacturer, str_buff, MAX_DESC_BUFF_SIZE);
958 print_usb_string("Manufactor: ", str_buff);
959 }
960 if(udev->descriptor.iProduct != 0)
961 {
962 usbh_get_string_descriptor(udev, udev->descriptor.iProduct, str_buff, MAX_DESC_BUFF_SIZE);
963 print_usb_string("Product: ", str_buff);
964 }
965 if(udev->descriptor.iSerialNumber != 0)
966 {
967 usbh_get_string_descriptor(udev, udev->descriptor.iSerialNumber, str_buff, MAX_DESC_BUFF_SIZE);
968 print_usb_string("Serial Number: ", str_buff);
969 }
970 usbh_free_mem(str_buff, MAX_DESC_BUFF_SIZE);
971#endif
972
973 /* Always select the first configuration */
974 ret = usbh_set_configuration(udev, conf->bConfigurationValue);
975 if(ret < 0)
976 {
977 USB_debug("Set configuration %d failed!\n", conf->bConfigurationValue);
978 free_dev_address(udev->dev_num);
979 return ret;
980 }
981
982 /* Parse the configuration/interface/endpoint descriptors and find corresponding drivers. */
983 ret = usbh_parse_configuration(udev, (uint8_t *)conf);
984 if(ret < 0)
985 {
986 USB_debug("Parse configuration %d failed!\n", conf->bConfigurationValue);
987 free_dev_address(udev->dev_num);
988 return ret;
989 }
990
991 if(conf->bmAttributes & (1 << 5))
992 {
993 /* If this configuration supports remote wakeup, enable it. */
994 if(usbh_ctrl_xfer(udev, REQ_TYPE_OUT | REQ_TYPE_STD_DEV | REQ_TYPE_TO_DEV,
995 USB_REQ_SET_FEATURE, 0x01, 0x0000, 0x0000,
996 NULL, &read_len, 300) < 0)
997 {
998 USB_debug("Device does not accept remote wakeup enable command.\n");
999 }
1000 }
1001
1002 if(g_conn_func)
1003 g_conn_func(udev, 0);
1004
1005 return ret;
1006}
1007
1008int usbh_reset_device(UDEV_T *udev)
1009{
1010 IFACE_T *iface;
1011 DESC_CONF_T *conf;
1012 uint32_t read_len;
1013 int dev_num, ret;
1014
1015 USB_debug("Reset device =>\n");
1016
1018
1019 /*------------------------------------------------------------------------------------*/
1020 /* Disconnect device */
1021 /*------------------------------------------------------------------------------------*/
1022
1023 if(g_disconn_func)
1024 g_disconn_func(udev, 0);
1025
1026 usbh_quit_xfer(udev, &(udev->ep0)); /* Quit control transfer if hw_pipe is not NULL. */
1027
1028 /* Notified all actived interface device driver */
1029 iface = udev->iface_list;
1030 while(iface != NULL)
1031 {
1032 udev->iface_list = iface->next;
1033 iface->driver->disconnect(iface);
1034 usbh_free_mem(iface, sizeof(*iface));
1035 iface = udev->iface_list;
1036 }
1037
1038 /*------------------------------------------------------------------------------------*/
1039 /* Reset device */
1040 /*------------------------------------------------------------------------------------*/
1041
1042 reset_device(udev);
1043
1044 delay_us(100 * 1000);
1045
1046 /*------------------------------------------------------------------------------------*/
1047 /* Set address (use current address) */
1048 /*------------------------------------------------------------------------------------*/
1049
1050 dev_num = udev->dev_num;
1051 udev->dev_num = 0;
1052 /* Issue SET ADDRESS command to set the same device address */
1053 ret = usbh_ctrl_xfer(udev, REQ_TYPE_OUT | REQ_TYPE_STD_DEV | REQ_TYPE_TO_DEV,
1054 USB_REQ_SET_ADDRESS, dev_num, 0, 0,
1055 NULL, &read_len, 100);
1056 udev->dev_num = dev_num;
1057 if(ret < 0)
1058 return ret;
1059
1060 delay_us(100 * 1000); /* after set address, give 100 ms delay */
1061
1062 /*------------------------------------------------------------------------------------*/
1063 /* Get device descriptor */
1064 /*------------------------------------------------------------------------------------*/
1065
1066 /* Get device descriptor again with new device address */
1067 ret = usbh_get_device_descriptor(udev, &udev->descriptor);
1068 if(ret < 0)
1069 return ret;
1070
1071 /*------------------------------------------------------------------------------------*/
1072 /* Get configuration descriptor */
1073 /*------------------------------------------------------------------------------------*/
1074
1075 conf = (DESC_CONF_T *)udev->cfd_buff; /* using the previously allocated buffer */
1076
1077 /* Get configuration descriptor again with new device address */
1078 ret = usbh_get_config_descriptor(udev, (uint8_t *)conf, MAX_DESC_BUFF_SIZE);
1079 if(ret < 0)
1080 return ret;
1081
1082 /* Always select the first configuration */
1083 ret = usbh_set_configuration(udev, udev->cur_conf);
1084 if(ret < 0)
1085 {
1086 USB_debug("Set configuration %d failed!\n", udev->cur_conf);
1087 return ret;
1088 }
1089
1090 /* Parse the configuration/interface/endpoint descriptors and find corresponding drivers. */
1091 ret = usbh_parse_configuration(udev, (uint8_t *)conf);
1092 if(ret < 0)
1093 {
1094 USB_debug("Parse configuration %d failed!\n", conf->bConfigurationValue);
1095 return ret;
1096 }
1097
1098 /* Enable remote wakeup */
1099 if(usbh_ctrl_xfer(udev, REQ_TYPE_OUT | REQ_TYPE_STD_DEV | REQ_TYPE_TO_DEV,
1100 USB_REQ_SET_FEATURE, 0x01, 0x0000, 0x0000,
1101 NULL, &read_len, 300) < 0)
1102 {
1103 USB_debug("Device not accept remote wakeup enable command.\n");
1104 }
1105
1106 if(g_conn_func)
1107 g_conn_func(udev, 0);
1108
1109 return ret;
1110}
1111
1112void disconnect_device(UDEV_T *udev)
1113{
1114 IFACE_T *iface;
1115
1116 USB_debug("disconnect device...\n");
1117
1118 if(g_disconn_func)
1119 g_disconn_func(udev, 0);
1120
1121 usbh_quit_xfer(udev, &(udev->ep0)); /* Quit control transfer if hw_pipe is not NULL. */
1122
1123 /* Notified all actived interface device driver */
1124 iface = udev->iface_list;
1125 while(iface != NULL)
1126 {
1127 udev->iface_list = iface->next;
1128 iface->driver->disconnect(iface);
1129 usbh_free_mem(iface, sizeof(*iface));
1130 iface = udev->iface_list;
1131 }
1132
1133 /* remove device from global device list */
1134 free_dev_address(udev->dev_num);
1135 free_device(udev);
1136
1137 usbh_memory_used();
1138}
1139
1140#if 0
1141static int check_device(UDEV_T *udev)
1142{
1143 UDEV_T *d;
1144
1145 if(udev == NULL)
1147
1148 //if ((udev->hc_driver != &ohci_driver))
1149 // return USBH_ERR_INVALID_PARAM;
1150
1151 d = g_udev_list;
1152 while(d)
1153 {
1154 if(d == udev)
1155 return USBH_OK;
1156 d = d->next;
1157 }
1159}
1160#endif
1161
1162EP_INFO_T * usbh_iface_find_ep(IFACE_T *iface, uint8_t ep_addr, uint8_t dir_type)
1163{
1164 ALT_IFACE_T *aif = iface->aif;
1165 int i;
1166
1167 if(ep_addr == 0) /* find the first EP matched with specified direction and type */
1168 {
1169 for(i = 0; i < aif->ifd->bNumEndpoints; i++)
1170 {
1171 if(((aif->ep[i].bEndpointAddress & EP_ADDR_DIR_MASK) == (dir_type & EP_ADDR_DIR_MASK)) &&
1172 ((aif->ep[i].bmAttributes & EP_ATTR_TT_MASK) == (dir_type & EP_ATTR_TT_MASK)))
1173 return &aif->ep[i];
1174 }
1175 }
1176 else /* find the EP with specified endpoint address */
1177 {
1178 for(i = 0; i < aif->ifd->bNumEndpoints; i++)
1179 {
1180 if(aif->ep[i].bEndpointAddress == ep_addr)
1181 return &aif->ep[i];
1182 }
1183 }
1184 return NULL;
1185}
1186
1187void usbh_dump_buff_bytes(uint8_t *buff, int nSize)
1188{
1189 int nIdx, i;
1190
1191 nIdx = 0;
1192 while(nSize > 0)
1193 {
1194 printf("0x%04X ", nIdx);
1195 for(i = 0; i < 16; i++)
1196 printf("%02x ", buff[nIdx + i]);
1197 printf(" ");
1198 for(i = 0; i < 16; i++)
1199 {
1200 if((buff[nIdx + i] >= 0x20) && (buff[nIdx + i] < 127))
1201 printf("%c", buff[nIdx + i]);
1202 else
1203 printf(".");
1204 nSize--;
1205 }
1206 nIdx += 16;
1207 printf("\n");
1208 }
1209 printf("\n");
1210}
1211
1212void usbh_dump_iface(IFACE_T *iface)
1213{
1214 USB_debug("\n [IFACE info] (0x%x)\n", (int)iface);
1215 USB_debug(" ----------------------------------------------\n");
1216 USB_debug(" udev = 0x%x\n", (int)iface->udev);
1217 USB_debug(" if_num = %d\n", iface->if_num);
1218 USB_debug(" driver = 0x%x\n", (int)iface->driver);
1219 USB_debug(" next = 0x%x\n", (int)iface->next);
1220 usbh_dump_interface_descriptor(iface->aif->ifd);
1221}
1222
1223void usbh_dump_ep_info(EP_INFO_T *ep)
1224{
1225 USB_debug("\n [Endpoint Info] (0x%x)\n", (int)ep);
1226 USB_debug(" ----------------------------------------------\n");
1227 USB_debug(" bEndpointAddress = 0x%02x\n", ep->bEndpointAddress);
1228 USB_debug(" bmAttributes = 0x%02x\n", ep->bmAttributes);
1229 USB_debug(" bInterval = %d\n", ep->bInterval);
1230 USB_debug(" wMaxPacketSize = %d\n", ep->wMaxPacketSize);
1231 USB_debug(" hw_pipe = 0x%x\n", (int)ep->hw_pipe);
1232}
1233
#define USBH_HcRhStatus_DRWE_Msk
Definition: M471M_R1_S.h:13408
#define USBH_HcRhPortStatus_PSS_Msk
Definition: M471M_R1_S.h:13426
#define USBH_HcMiscControl_OCAL_Msk
Definition: M471M_R1_S.h:13462
#define USBH_HcInterruptEnable_RD_Msk
Definition: M471M_R1_S.h:13309
#define USBH_HcInterruptEnable_RHSC_Msk
Definition: M471M_R1_S.h:13315
#define USBH_HcControl_HCFS_Pos
Definition: M471M_R1_S.h:13266
#define USBH_HcRhPortStatus_CCS_Msk
Definition: M471M_R1_S.h:13420
#define USBH_HcRhPortStatus_POCI_Msk
Definition: M471M_R1_S.h:13429
NuMicro peripheral access layer header file.
#define NULL
Definition: M471M_R1_S.h:13908
__IO uint32_t HcPhyControl
Definition: M471M_R1_S.h:13235
__IO uint32_t HcRhPortStatus[2]
Definition: M471M_R1_S.h:13233
#define USBH
Definition: M471M_R1_S.h:13827
__IO uint32_t HcControl
Definition: M471M_R1_S.h:13213
__IO uint32_t HcMiscControl
Definition: M471M_R1_S.h:13236
__IO uint32_t HcRhStatus
Definition: M471M_R1_S.h:13232
__IO uint32_t HcInterruptEnable
Definition: M471M_R1_S.h:13216
#define USBH_ERR_TIMEOUT
Definition: usbh_lib.h:45
#define USBH_ERR_SET_CONFIG
Definition: usbh_lib.h:42
#define USBH_ERR_SET_DEV_ADDR
Definition: usbh_lib.h:41
#define USBH_OK
Definition: usbh_lib.h:30
#define USBH_ERR_INVALID_PARAM
Definition: usbh_lib.h:37
#define USBH_ERR_IF_EP_LIMIT
Definition: usbh_lib.h:33
#define USBH_ERR_NOT_FOUND
Definition: usbh_lib.h:38
#define USBH_ERR_DESCRIPTOR
Definition: usbh_lib.h:40
#define USBH_ERR_DATA_OVERRUN
Definition: usbh_lib.h:63
#define USBH_ERR_IF_ALT_LIMIT
Definition: usbh_lib.h:32
#define USBH_ERR_MEMORY_OUT
Definition: usbh_lib.h:31
void usbh_suspend()
Suspend USB Host Controller and devices.
Definition: usb_core.c:95
int usbh_pooling_hubs(void)
Let USB stack polls all root hubs and downstream hubs. If there's any hub port change found,...
Definition: hub.c:636
HIDDEN_SYMBOLS void usbh_core_init()
Initialize M471M/R1/S USB Host controller and USB stack.
Definition: usb_core.c:37
void usbh_install_conn_callback(CONN_FUNC *conn_func, CONN_FUNC *disconn_func)
Install device connect and disconnect callback function.
Definition: usb_core.c:70
uint32_t get_ticks(void)
A function return current tick count.
void usbh_resume(void)
Resume USB Host controller and devices.
Definition: usb_core.c:121
void() CONN_FUNC(struct udev_t *udev, int param)
Definition: usbh_lib.h:115
USB Host hub class driver header file.
USB Host library header file.
static int reset_device(UDEV_T *udev)
Definition: usb_core.c:76