M480 BSP  V3.05.001
The Board Support Package for M480 Series
usb_core.c
Go to the documentation of this file.
1 /**************************************************************************/
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 
14 #include "NuMicro.h"
15 
16 #include "usb.h"
17 #include "hub.h"
18 
19 
21 
22 USBH_T *_ohci;
23 HSUSBH_T *_ehci;
24 
25 int _IsInUsbInterrupt = 0;
26 
27 static UDEV_DRV_T * _drivers[MAX_UDEV_DRIVER];
28 
29 static CONN_FUNC *g_conn_func, *g_disconn_func;
30 
32 
33 
40 {
41  NVIC_DisableIRQ(HSUSBH_IRQn);
42  NVIC_DisableIRQ(USBH_IRQn);
43 
44  _ohci = USBH;
45  _ehci = HSUSBH;
46 
47  memset(_drivers, 0, sizeof(_drivers));
48 
49  g_conn_func = NULL;
50  g_disconn_func = NULL;
51 
52  usbh_hub_init();
53 
54  if ((SYS->CSERVER & SYS_CSERVER_VERSION_Msk) == 0x0) /* Only M480MD has EHCI. */
55  {
56  _ehci->USBPCR0 = 0x160; /* enable PHY 0 */
57  _ehci->USBPCR1 = 0x520; /* enable PHY 1 */
58  }
59 
60  usbh_memory_init();
61 
62  _ohci->HcMiscControl |= USBH_HcMiscControl_OCAL_Msk; /* Over-current active low */
63  //_ohci->HcMiscControl &= ~USBH_HcMiscControl_OCAL_Msk; /* Over-current active high */
64 
65 #ifdef ENABLE_OHCI
66  ohci_driver.init();
67  ENABLE_OHCI_IRQ();
68 #endif
69 
70 #ifdef ENABLE_EHCI
71  if ((SYS->CSERVER & SYS_CSERVER_VERSION_Msk) == 0x0) /* Only M480MD has EHCI. */
72  {
73  ehci_driver.init();
74  ENABLE_EHCI_IRQ();
75  }
76 #endif
77 }
78 
86 void usbh_install_conn_callback(CONN_FUNC *conn_func, CONN_FUNC *disconn_func)
87 {
88  g_conn_func = conn_func;
89  g_disconn_func = disconn_func;
90 }
91 
92 static int reset_device(UDEV_T *udev)
93 {
94  if (udev->parent == NULL)
95  {
96  if (udev->hc_driver)
97  return udev->hc_driver->rthub_port_reset(udev->port_num-1);
98  else
99  return USBH_ERR_NOT_FOUND;
100  }
101  else
102  {
103  return udev->parent->port_reset(udev->parent, udev->port_num);
104  }
105 }
106 
107 #ifdef ENABLE_EHCI
108 static uint32_t ehci_UCMDR;
109 #endif
110 
116 {
117 #ifdef ENABLE_EHCI
118  int time_out = 10; /* ms */
119 #endif
120 
121 #ifdef ENABLE_OHCI
122  /* set port suspend if connected */
123  if ((SYS->CSERVER & SYS_CSERVER_VERSION_Msk) == 0x0)
124  {
125  /* M480MD has port1, but M480LD has not port1 */
127  _ohci->HcRhPortStatus[0] = USBH_HcRhPortStatus_PSS_Msk; /* set port suspend */
128  }
129 
131  _ohci->HcRhPortStatus[1] = USBH_HcRhPortStatus_PSS_Msk; /* set port suspend */
132 
133  /* enable Device Remote Wakeup */
135 
136  /* enable USBH RHSC interrupt for system wakeup */
138 
139  /* set Host Controller enter suspend state */
141 #endif
142 
143 #ifdef ENABLE_EHCI
144  if ((SYS->CSERVER & SYS_CSERVER_VERSION_Msk) == 0x0) /* Only M480MD has EHCI. */
145  {
146  ehci_UCMDR = _ehci->UCMDR;
147 
148  if (_ehci->UPSCR[0] & HSUSBH_UPSCR_PE_Msk)
149  {
150  _ehci->UPSCR[0] |= HSUSBH_UPSCR_SUSPEND_Msk;
151  delay_us(2000); /* wait 2 ms */
152  }
153 
155  while (time_out > 0)
156  {
157  if (!(_ehci->UCMDR & HSUSBH_UCMDR_RUN_Msk) && (_ehci->USTSR & HSUSBH_USTSR_HCHalted_Msk))
158  {
159  break;
160  }
161  }
162  if (time_out == 0)
163  {
164  USB_error("usbh_suspend - RUN/HCHalted error!\n");
165  }
166  delay_us(100);
167  }
168 #endif
169 }
170 
171 
176 void usbh_resume(void)
177 {
178 #ifdef ENABLE_OHCI
180 
181  if ((SYS->CSERVER & SYS_CSERVER_VERSION_Msk) == 0x0)
182  {
184  _ohci->HcRhPortStatus[0] = USBH_HcRhPortStatus_POCI_Msk; /* clear suspend status */
185  }
187  _ohci->HcRhPortStatus[1] = USBH_HcRhPortStatus_POCI_Msk; /* clear suspend status */
188 
189  delay_us(30000); /* wait at least 20ms for Host to resume device */
190 
191  /* enter operational state */
193 #endif
194 
195 #ifdef ENABLE_EHCI
196  if ((SYS->CSERVER & SYS_CSERVER_VERSION_Msk) == 0x0) /* Only M480MD has EHCI. */
197  {
198  _ehci->UCMDR = ehci_UCMDR;
199 
200  if (_ehci->UPSCR[0] & HSUSBH_UPSCR_PE_Msk)
201  {
202  _ehci->UPSCR[0] |= HSUSBH_UPSCR_FPR_Msk;
203  delay_us(20000); /* keep resume signal for 20 ms */
204  _ehci->UPSCR[0] &= ~HSUSBH_UPSCR_FPR_Msk;
205  }
206  delay_us(1000);
207  }
208 #endif
209 }
210 
211 
212 
214 
223 int usbh_register_driver(UDEV_DRV_T *udrv)
224 {
225  int i;
226 
227  for (i = 0; i < MAX_UDEV_DRIVER; i++)
228  {
229  if (_drivers[i] == udrv)
230  return 0; /* already registered, do nothing */
231 
232  if (_drivers[i] == NULL)
233  {
234  _drivers[i] = udrv; /* register this driver */
235  return 0;
236  }
237  }
238  return USBH_ERR_MEMORY_OUT; /* reached MAX_UDEV_DRIVER limitation, aborted */
239 }
240 
241 
258 int usbh_ctrl_xfer(UDEV_T *udev, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
259  uint16_t wLength, uint8_t *buff, uint32_t *xfer_len, uint32_t timeout)
260 {
261  UTR_T *utr;
262  uint32_t t0;
263  int status;
264 
265  *xfer_len = 0;
266 
267  //if (check_device(udev))
268  // return USBH_ERR_INVALID_PARAM;
269 
270  utr = alloc_utr(udev);
271  if (utr == NULL)
272  return USBH_ERR_MEMORY_OUT;
273 
274  utr->setup.bmRequestType = bmRequestType;
275  utr->setup.bRequest = bRequest;
276  utr->setup.wValue = wValue;
277  utr->setup.wIndex = wIndex;
278  utr->setup.wLength = wLength;
279 
280  utr->buff = buff;
281  utr->data_len = wLength;
282  utr->bIsTransferDone = 0;
283  status = udev->hc_driver->ctrl_xfer(utr);
284  if (status < 0)
285  {
286  udev->ep0.hw_pipe = NULL;
287  free_utr(utr);
288  return status;
289  }
290 
291  t0 = get_ticks();
292  while (utr->bIsTransferDone == 0)
293  {
294  if (get_ticks() - t0 > timeout)
295  {
296  usbh_quit_utr(utr);
297  free_utr(utr);
298  udev->ep0.hw_pipe = NULL;
299  return USBH_ERR_TIMEOUT;
300  }
301  }
302 
303  status = utr->status;
304 
305  if (status == 0)
306  {
307  *xfer_len = utr->xfer_len;
308  }
309  free_utr(utr);
310 
311  return status;
312 }
313 
314 
323 int usbh_bulk_xfer(UTR_T *utr)
324 {
325  return utr->udev->hc_driver->bulk_xfer(utr);
326 }
327 
336 int usbh_int_xfer(UTR_T *utr)
337 {
338  return utr->udev->hc_driver->int_xfer(utr);
339 }
340 
349 int usbh_iso_xfer(UTR_T *utr)
350 {
351  if (utr->udev->hc_driver == NULL)
352  {
353  printf("hc_driver - 0x%x\n", (int)utr->udev->hc_driver);
354  return -1;
355  }
356  if (utr->udev->hc_driver->iso_xfer == NULL)
357  {
358  printf("iso_xfer - 0x%x\n", (int)utr->udev->hc_driver->iso_xfer);
359  return -1;
360  }
361  return utr->udev->hc_driver->iso_xfer(utr);
362 }
363 
370 int usbh_quit_utr(UTR_T *utr)
371 {
372  if (!utr || !utr->udev)
373  return USBH_ERR_NOT_FOUND;
374 
375  return utr->udev->hc_driver->quit_xfer(utr, NULL);
376 }
377 
378 
386 int usbh_quit_xfer(UDEV_T *udev, EP_INFO_T *ep)
387 {
388  return udev->hc_driver->quit_xfer(NULL, ep);
389 }
390 
391 
392 void dump_device_descriptor(DESC_DEV_T *desc)
393 {
394  USB_debug("\n[Device Descriptor]\n");
395  USB_debug("----------------------------------------------\n");
396  USB_debug(" Length = %2d\n", desc->bLength);
397  USB_debug(" DescriptorType = 0x%02x\n", desc->bDescriptorType);
398  USB_debug(" USB version = %x.%02x\n",
399  desc->bcdUSB >> 8, desc->bcdUSB & 0xff);
400  USB_debug(" Vendor:Product = %04x:%04x\n",
401  desc->idVendor, desc->idProduct);
402  USB_debug(" MaxPacketSize0 = %d\n", desc->bMaxPacketSize0);
403  USB_debug(" NumConfigurations = %d\n", desc->bNumConfigurations);
404  USB_debug(" Device version = %x.%02x\n",
405  desc->bcdDevice >> 8, desc->bcdDevice & 0xff);
406  USB_debug(" Device Class:SubClass:Protocol = %02x:%02x:%02x\n",
407  desc->bDeviceClass, desc->bDeviceSubClass, desc->bDeviceProtocol);
408 }
409 
410 void usbh_dump_interface_descriptor(DESC_IF_T *if_desc)
411 {
412  USB_debug("\n [Interface Descriptor]\n");
413  USB_debug(" ----------------------------------------------\n");
414  USB_debug(" Length = %2d\n", if_desc->bLength);
415  USB_debug(" DescriptorType = %02x\n", if_desc->bDescriptorType);
416  USB_debug(" bInterfaceNumber = %d\n", if_desc->bInterfaceNumber);
417  USB_debug(" bAlternateSetting = %d\n", if_desc->bAlternateSetting);
418  USB_debug(" bNumEndpoints = %d\n", if_desc->bNumEndpoints);
419  USB_debug(" bInterfaceClass = 0x%02x\n", if_desc->bInterfaceClass);
420  USB_debug(" bInterfaceSubClass = 0x%02x\n", if_desc->bInterfaceSubClass);
421  USB_debug(" bInterfaceProtocol = 0x%02x\n", if_desc->bInterfaceProtocol);
422  USB_debug(" iInterface = %d\n", if_desc->iInterface);
423 }
424 
425 void usbh_dump_endpoint_descriptor(DESC_EP_T *ep_desc)
426 {
427  USB_debug("\n [Endpoint Descriptor]\n");
428  USB_debug(" ----------------------------------------------\n");
429  USB_debug(" Length = %2d\n", ep_desc->bLength);
430  USB_debug(" DescriptorType = %02x\n", ep_desc->bDescriptorType);
431  USB_debug(" bEndpointAddress = 0x%02x\n", ep_desc->bEndpointAddress);
432  USB_debug(" bmAttributes = 0x%02x\n", ep_desc->bmAttributes);
433  USB_debug(" wMaxPacketSize = %d\n", ep_desc->wMaxPacketSize);
434  USB_debug(" bInterval = %d\n", ep_desc->bInterval);
435  USB_debug(" bRefresh = %d\n", ep_desc->bRefresh);
436  USB_debug(" bSynchAddress = %d\n", ep_desc->bSynchAddress);
437 }
438 
439 void dump_config_descriptor(DESC_CONF_T *desc)
440 {
441  uint8_t *bptr = (uint8_t *)desc;
442  DESC_HDR_T *hdr;
443  int tlen = desc->wTotalLength;
444 
445  while (tlen > 0)
446  {
447  switch (bptr[1])
448  {
449  case USB_DT_CONFIGURATION:
450  USB_debug("\n[Configuration Descriptor]\n");
451  USB_debug("----------------------------------------------\n");
452  USB_debug(" Length = %2d\n", desc->bLength);
453  USB_debug(" DescriptorType = %02x\n", desc->bDescriptorType);
454  USB_debug(" wTotalLength = %2d\n", desc->wTotalLength);
455  USB_debug(" bNumInterfaces = %d\n", desc->bNumInterfaces);
456  USB_debug(" bConfigurationValue = %d\n", desc->bConfigurationValue);
457  USB_debug(" iConfiguration = %d\n", desc->iConfiguration);
458  USB_debug(" bmAttributes = 0x%02x\n", desc->bmAttributes);
459  USB_debug(" MaxPower = %d\n", desc->MaxPower);
460  break;
461 
462  case USB_DT_INTERFACE:
463  usbh_dump_interface_descriptor((DESC_IF_T *)bptr);
464  break;
465 
466  case USB_DT_ENDPOINT:
467  usbh_dump_endpoint_descriptor((DESC_EP_T *)bptr);
468  break;
469 
470  default:
471  hdr = (DESC_HDR_T *)bptr;
472  USB_debug("\n!![Unknown Descriptor]\n");
473  USB_debug("----------------------------------------------\n");
474  USB_debug("Length = %2d\n", hdr->bLength);
475  USB_debug("DescriptorType = %02x\n", hdr->bDescriptorType);
476  break;
477  }
478  if (bptr[0] == 0)
479  break;
480  tlen -= bptr[0];
481  bptr += bptr[0];
482  }
483 }
484 
490 int usbh_set_address(UDEV_T *udev)
491 {
492  uint32_t read_len;
493  int dev_num, ret;
494 
495  if (udev->dev_num != 0)
496  return USBH_ERR_SET_DEV_ADDR;
497 
498  dev_num = alloc_dev_address();
499 
500  /*------------------------------------------------------------------------------------*/
501  /* Issue SET ADDRESS command to set device address */
502  /*------------------------------------------------------------------------------------*/
503  ret = usbh_ctrl_xfer(udev, REQ_TYPE_OUT | REQ_TYPE_STD_DEV | REQ_TYPE_TO_DEV,
504  USB_REQ_SET_ADDRESS, dev_num, 0, 0,
505  NULL, &read_len, 100);
506  if (ret < 0)
507  {
508  free_dev_address(dev_num);
509  return ret;
510  }
511 
512  udev->dev_num = dev_num;
513 
514  return 0;
515 }
516 
522 int usbh_set_configuration(UDEV_T *udev, uint8_t conf_val)
523 {
524  uint32_t read_len;
525  int ret;
526 
527  /* Current configuration is the same. Do nothing. */
528  if (udev->cur_conf == conf_val)
529  return 0;
530 
531  /* Set another configuration is currently not supported! */
532  if (udev->cur_conf != -1)
533  return USBH_ERR_SET_CONFIG;
534 
535  /*------------------------------------------------------------------------------------*/
536  /* Issue SET CONFIGURATION command to select device configuration */
537  /*------------------------------------------------------------------------------------*/
538  ret = usbh_ctrl_xfer(udev, REQ_TYPE_OUT | REQ_TYPE_STD_DEV | REQ_TYPE_TO_DEV,
539  USB_REQ_SET_CONFIGURATION, conf_val, 0, 0,
540  NULL, &read_len, 300);
541  if (ret < 0)
542  return ret;
543 
544  udev->cur_conf = (int8_t)conf_val;
545 
546  return 0;
547 }
548 
556 int usbh_set_interface(IFACE_T *iface, uint16_t alt_setting)
557 {
558  ALT_IFACE_T *aif = NULL;
559  uint32_t xfer_len;
560  int i, ret;
561 
562  for (i = 0; i < iface->num_alt; i++)
563  {
564  if (iface->alt[i].ifd->bAlternateSetting == alt_setting)
565  {
566  aif = &iface->alt[i];
567  break;
568  }
569  }
570  if (aif == NULL)
571  return USBH_ERR_NOT_FOUND; /* cannot find desired alternative setting */
572 
573  ret = usbh_ctrl_xfer(iface->udev, REQ_TYPE_OUT | REQ_TYPE_STD_DEV | REQ_TYPE_TO_IFACE,
574  USB_REQ_SET_INTERFACE, alt_setting, iface->if_num, 0,
575  NULL, &xfer_len, 100);
576  if (ret == 0)
577  iface->aif = aif; /* change active alternative setting */
578  return ret;
579 }
580 
588 int usbh_get_device_descriptor(UDEV_T *udev, DESC_DEV_T *desc_buff)
589 {
590  uint32_t read_len;
591  int ret, retry;
592  int timeout = 10;
593 
594  for (retry = 0; retry < 3; retry++)
595  {
596  ret = usbh_ctrl_xfer(udev, REQ_TYPE_IN | REQ_TYPE_STD_DEV | REQ_TYPE_TO_DEV,
597  USB_REQ_GET_DESCRIPTOR,
598  ((USB_DT_STANDARD | USB_DT_DEVICE) << 8), 0, sizeof(DESC_DEV_T),
599  (uint8_t *)desc_buff, &read_len, timeout);
600  if (ret == 0)
601  return 0;
602 
603  USB_debug("Get device descriptor failed - %d, retry!\n", ret);
604  }
605  return ret;
606 }
607 
616 int usbh_get_config_descriptor(UDEV_T *udev, uint8_t *desc_buff, int buff_len)
617 {
618  uint32_t read_len;
619  DESC_CONF_T *conf = (DESC_CONF_T *)desc_buff;
620  int ret;
621 
622  /*------------------------------------------------------------------------------------*/
623  /* Issue GET DESCRIPTOR command to get configuration descriptor */
624  /*------------------------------------------------------------------------------------*/
625  ret = usbh_ctrl_xfer(udev, REQ_TYPE_IN | REQ_TYPE_STD_DEV | REQ_TYPE_TO_DEV,
626  USB_REQ_GET_DESCRIPTOR,
627  ((USB_DT_STANDARD | USB_DT_CONFIGURATION) << 8), 0, 9,
628  desc_buff, &read_len, 200);
629  if (ret < 0)
630  return ret;
631 
632  if (conf->wTotalLength > buff_len)
633  {
634  USB_error("Device configuration %d length > %d!\n", conf->wTotalLength, buff_len);
635  return USBH_ERR_DATA_OVERRUN;
636  }
637 
638  read_len = conf->wTotalLength;
639 
640  ret = usbh_ctrl_xfer(udev, REQ_TYPE_IN | REQ_TYPE_STD_DEV | REQ_TYPE_TO_DEV,
641  USB_REQ_GET_DESCRIPTOR,
642  ((USB_DT_STANDARD | USB_DT_CONFIGURATION) << 8), 0, read_len,
643  desc_buff, &read_len, 200);
644  if (ret < 0)
645  return ret;
646 
647  return 0;
648 }
649 
660 int usbh_get_string_descriptor(UDEV_T *udev, int index, uint8_t *desc_buff, int buff_len)
661 {
662  uint32_t read_len;
663  int ret;
664 
665  /*------------------------------------------------------------------------------------*/
666  /* Issue GET DESCRIPTOR command to get configuration descriptor */
667  /*------------------------------------------------------------------------------------*/
668  ret = usbh_ctrl_xfer(udev, REQ_TYPE_IN | REQ_TYPE_STD_DEV | REQ_TYPE_TO_DEV,
669  USB_REQ_GET_DESCRIPTOR,
670  ((USB_DT_STANDARD | USB_DT_STRING) << 8) | index, 0x0409, buff_len,
671  desc_buff, &read_len, 200);
672  return ret;
673 }
674 
682 int usbh_clear_halt(UDEV_T *udev, uint16_t ep_addr)
683 {
684  uint32_t read_len;
685 
686  USB_debug("Clear endpoint 0x%x halt.\n", ep_addr);
687  return usbh_ctrl_xfer(udev, REQ_TYPE_OUT | REQ_TYPE_STD_DEV | REQ_TYPE_TO_EP,
688  USB_REQ_CLEAR_FEATURE, 0, ep_addr, 0,
689  NULL, &read_len, 100);
690 }
691 
692 static int usbh_parse_endpoint(ALT_IFACE_T *alt, int ep_idx, uint8_t *desc_buff, int len)
693 {
694  DESC_EP_T *ep_desc;
695  int parsed_len = 0;
696  int pksz;
697 
698  while (len > 0)
699  {
700  ep_desc = (DESC_EP_T *)desc_buff;
701 
702  if ((len < ep_desc->bLength) || (ep_desc->bLength < 2))
703  {
704  USB_error("ERR DESCRIPTOR EP LEN [0x%X %d]\n", ep_desc->bDescriptorType, ep_desc->bLength);
705  return USBH_ERR_DESCRIPTOR;
706  }
707 
708  if (ep_desc->bDescriptorType == USB_DT_ENDPOINT)
709  break; /* endpoint descriptor found */
710 
711  /* unrecognized descriptor */
712  USB_vdebug("ignore descriptor 0x%X %d\n", ep_desc->bDescriptorType, ep_desc->bLength);
713  desc_buff += ep_desc->bLength;
714  parsed_len += ep_desc->bLength;
715  len -= ep_desc->bLength;
716  }
717 
718  USB_vdebug("Descriptor Found - Alt: %d, Endpoint 0x%x, remaining len: %d\n", alt->ifd->bAlternateSetting, ep_desc->bEndpointAddress, len);
719 
720  alt->ep[ep_idx].bEndpointAddress = ep_desc->bEndpointAddress;
721  alt->ep[ep_idx].bmAttributes = ep_desc->bmAttributes;
722  alt->ep[ep_idx].bInterval = ep_desc->bInterval;
723  pksz = ep_desc->wMaxPacketSize;
724  pksz = (pksz & 0x07ff) * (1 + ((pksz >> 11) & 3));
725  alt->ep[ep_idx].wMaxPacketSize = pksz;
726  alt->ep[ep_idx].hw_pipe = NULL;
727 
728  return parsed_len + ep_desc->bLength;
729 }
730 
740 static int usbh_parse_interface(UDEV_T *udev, uint8_t *desc_buff, int len)
741 {
742  int i, matched, parsed_len = 0;
743  DESC_HDR_T *hdr;
744  DESC_IF_T *if_desc;
745  IFACE_T *iface = NULL;
746  int ret;
747 
748  iface = usbh_alloc_mem(sizeof(*iface)); /* create an interface */
749  if (iface == NULL)
750  return USBH_ERR_MEMORY_OUT;
751  iface->udev = udev;
752  iface->aif = &iface->alt[0]; /* Default active interface should be the
753  first found alternative interface */
754  iface->if_num = ((DESC_IF_T *)desc_buff)->bInterfaceNumber;
755 
756  while (len > 0)
757  {
758  /*--------------------------------------------------------------------------------*/
759  /* Find the first/next interface descriptor */
760  /*--------------------------------------------------------------------------------*/
761  if_desc = (DESC_IF_T *)desc_buff;
762 
763  if (if_desc->bDescriptorType != USB_DT_INTERFACE)
764  {
765  desc_buff += if_desc->bLength;
766  parsed_len += if_desc->bLength;
767  len -= if_desc->bLength;
768  continue;
769  }
770 
771  if (if_desc->bInterfaceNumber != iface->if_num)
772  {
773  goto parse_done;
774  }
775 
776  if (if_desc->bNumEndpoints > MAX_EP_PER_IFACE)
777  {
778  USB_error("IF EP LIMITE %d\n", if_desc->bNumEndpoints);
779  ret = USBH_ERR_IF_EP_LIMIT;
780  goto err_out;
781  }
782 
783  /* Step over the interface descriptor */
784  desc_buff += if_desc->bLength;
785  parsed_len += if_desc->bLength;
786  len -= if_desc->bLength;
787  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);
788 
789  /*--------------------------------------------------------------------------------*/
790  /* Add to alternative interface list */
791  /*--------------------------------------------------------------------------------*/
792  if (iface->num_alt >= MAX_ALT_PER_IFACE)
793  {
794  ret = USBH_ERR_IF_ALT_LIMIT;
795  goto err_out;
796  }
797 
798  /*--------------------------------------------------------------------------------*/
799  /* Find the next alternative interface or endpoint descriptor */
800  /*--------------------------------------------------------------------------------*/
801  while (len > 0)
802  {
803  hdr = (DESC_HDR_T *)desc_buff;
804 
805  if ((len < hdr->bLength) || (hdr->bLength < 2))
806  {
807  USB_error("ERR DESCRIPTOR IF LEN [0x%X %d]\n", hdr->bDescriptorType, hdr->bLength);
808  ret = USBH_ERR_DESCRIPTOR;
809  goto err_out;
810  }
811 
812  if (hdr->bDescriptorType == USB_DT_CONFIGURATION)
813  goto parse_done; /* is other configuration, parsing completed */
814 
815  if ((hdr->bDescriptorType == USB_DT_INTERFACE) || (hdr->bDescriptorType == USB_DT_ENDPOINT))
816  break; /* the first endpoint descriptor found */
817 
818  /* unrecognized descriptor */
819  USB_vdebug("ignore descriptor 0x%X %d\n", hdr->bDescriptorType, hdr->bLength);
820  desc_buff += hdr->bLength;
821  parsed_len += hdr->bLength;
822  len -= hdr->bLength;
823  }
824 
825  iface->alt[iface->num_alt].ifd = if_desc;
826  iface->num_alt++;
827 
828  if (len == 0)
829  goto parse_done;
830 
831  if (hdr->bDescriptorType == USB_DT_INTERFACE)
832  continue; /* is the next interface descriptor */
833 
834  USB_vdebug("Finding %d endpoints of interface %d, alt %d...\n", if_desc->bNumEndpoints, if_desc->bInterfaceNumber, if_desc->bAlternateSetting);
835 
836  /* parsign all endpoint descriptors */
837  for (i = 0; i < if_desc->bNumEndpoints; i++)
838  {
839  ret = usbh_parse_endpoint(&iface->alt[iface->num_alt-1], i, desc_buff, len);
840  if (ret < 0)
841  goto err_out;
842 
843  desc_buff += ret;
844  parsed_len += ret;
845  len -= ret;
846  USB_vdebug("EP parse remaining %d\n", len);
847  }
848  }
849 
850 parse_done:
851 
852  /*
853  * Probing all registered USB device drivers to find a matched driver.
854  */
855  matched = 0;
856  for (i = 0; i < MAX_UDEV_DRIVER; i++)
857  {
858  if ((_drivers[i] != NULL) && (_drivers[i]->probe(iface) == 0))
859  {
860  matched = 1;
861  break;
862  }
863  }
864 
865  if (matched)
866  {
867  iface->driver = _drivers[i]; /* have a driver now */
868  iface->next = NULL;
869 
870  /* Added this interface to USB device interface list */
871  if (udev->iface_list == NULL)
872  udev->iface_list = iface;
873  else
874  {
875  iface->next = udev->iface_list;
876  udev->iface_list = iface;
877  }
878  }
879  else
880  {
881  usbh_free_mem(iface, sizeof(*iface));
882  iface = NULL;
883  }
884 
885  return parsed_len;
886 
887 err_out:
888  usbh_free_mem(iface, sizeof(*iface));
889  return ret;
890 }
891 
892 
893 static int usbh_parse_configuration(UDEV_T *udev, uint8_t *desc_buff)
894 {
895  DESC_CONF_T *config = (DESC_CONF_T *)desc_buff;
896  DESC_HDR_T *hdr;
897  int i, ret, len;
898 
899  len = config->wTotalLength;
900 
901  desc_buff += config->bLength;
902  len -= config->bLength;
903 
904  USB_vdebug("Parsing CONFIG =>\n");
905 
906  for (i = 0; i < config->bNumInterfaces; i++)
907  {
908  /*
909  * find the next interface descriptor
910  */
911  while (len >= sizeof(DESC_HDR_T))
912  {
913  hdr = (DESC_HDR_T *)desc_buff;
914 
915  if ((hdr->bLength > len) || (hdr->bLength < 2))
916  {
917  USB_error("ERR DESCRIPTOR CONFIG [%d]\n", hdr->bLength);
918  return USBH_ERR_DESCRIPTOR;
919  }
920 
921  if (hdr->bDescriptorType == USB_DT_INTERFACE)
922  break;
923 
924  USB_debug("ignore descriptor 0x%X %d\n", hdr->bDescriptorType, hdr->bLength);
925 
926  desc_buff += hdr->bLength;
927  len -= hdr->bLength;
928  }
929 
930  ret = usbh_parse_interface(udev, desc_buff, len);
931  if (ret < 0)
932  return ret;
933 
934  desc_buff += ret;
935  len -= ret;
936  USB_vdebug("IFACE parse remaining %d\n", len);
937  }
938 
939  if (len > 0)
940  {
941  USB_debug("ERR DESCRIPTOR CONFIG LEN %d\n", len);
942  return USBH_ERR_DESCRIPTOR;
943  }
944  return len;
945 }
946 
947 void print_usb_string(char *lead, uint8_t *str)
948 {
949  int len, i = 2;
950 
951  USB_debug("%s", lead);
952  len = str[0];
953  while (i < len)
954  {
955  USB_debug("%c", str[i]);
956  i += 2;
957  }
958  USB_debug("\n");
959 }
960 
961 int connect_device(UDEV_T *udev)
962 {
963  DESC_CONF_T *conf;
964  uint32_t read_len;
965  int ret;
966 
967  USB_debug("Connect device =>\n");
968 
969  delay_us(100 * 1000); /* initially, give 100 ms delay */
970 
971  usbh_get_device_descriptor(udev, &udev->descriptor);
972 
974 
975  delay_us(100 * 1000);
976 
977  ret = usbh_set_address(udev);
978  if (ret < 0)
979  {
980  USB_debug("Set address command failed!!\n");
981  return ret;
982  }
983 
984  delay_us(100 * 1000); /* after set address, give 100 ms delay */
985 
986  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);
987 
988  /* Get device descriptor again with new device address */
989  ret = usbh_get_device_descriptor(udev, &udev->descriptor);
990  if (ret < 0)
991  {
992  free_dev_address(udev->dev_num);
993  return ret;
994  }
995 
996 #if defined(DUMP_DESCRIPTOR) && defined(ENABLE_DEBUG_MSG)
997  dump_device_descriptor(&udev->descriptor);
998 #endif
999 
1000  if (udev->descriptor.bNumConfigurations != 1)
1001  {
1002  USB_debug("Warning! This device has multiple configurations [%d]. \n", udev->descriptor.bNumConfigurations);
1003  }
1004 
1005  conf = (DESC_CONF_T *)usbh_alloc_mem(MAX_DESC_BUFF_SIZE);
1006  if (conf == NULL)
1007  {
1008  free_dev_address(udev->dev_num);
1009  return USBH_ERR_MEMORY_OUT;
1010  }
1011 
1012  udev->cfd_buff = (uint8_t *)conf;
1013 
1014  /* Get configuration descriptor again with new device address */
1015  ret = usbh_get_config_descriptor(udev, (uint8_t *)conf, MAX_DESC_BUFF_SIZE);
1016  if (ret < 0)
1017  {
1018  free_dev_address(udev->dev_num);
1019  return ret;
1020  }
1021 
1022 #if defined(DUMP_DESCRIPTOR) && defined(ENABLE_DEBUG_MSG)
1023  dump_config_descriptor(conf);
1024 #endif
1025 
1026 #if 0 /* printf string descriptors, for debug only */
1027  str_buff = (uint8_t *)usbh_alloc_mem(MAX_DESC_BUFF_SIZE);
1028  if (udev->descriptor.iManufacturer != 0)
1029  {
1030  usbh_get_string_descriptor(udev, udev->descriptor.iManufacturer, str_buff, MAX_DESC_BUFF_SIZE);
1031  print_usb_string("Manufactor: ", str_buff);
1032  }
1033  if (udev->descriptor.iProduct != 0)
1034  {
1035  usbh_get_string_descriptor(udev, udev->descriptor.iProduct, str_buff, MAX_DESC_BUFF_SIZE);
1036  print_usb_string("Product: ", str_buff);
1037  }
1038  if (udev->descriptor.iSerialNumber != 0)
1039  {
1040  usbh_get_string_descriptor(udev, udev->descriptor.iSerialNumber, str_buff, MAX_DESC_BUFF_SIZE);
1041  print_usb_string("Serial Number: ", str_buff);
1042  }
1043  usbh_free_mem(str_buff, MAX_DESC_BUFF_SIZE);
1044 #endif
1045 
1046  /* Always select the first configuration */
1047  ret = usbh_set_configuration(udev, conf->bConfigurationValue);
1048  if (ret < 0)
1049  {
1050  USB_debug("Set configuration %d failed!\n", conf->bConfigurationValue);
1051  free_dev_address(udev->dev_num);
1052  return ret;
1053  }
1054 
1055  /* Parse the configuration/interface/endpoint descriptors and find corresponding drivers. */
1056  ret = usbh_parse_configuration(udev, (uint8_t *)conf);
1057  if (ret < 0)
1058  {
1059  USB_debug("Parse configuration %d failed!\n", conf->bConfigurationValue);
1060  free_dev_address(udev->dev_num);
1061  return ret;
1062  }
1063 
1064  if (conf->bmAttributes & (1<<5))
1065  {
1066  /* If this configuration supports remote wakeup, enable it. */
1067  if (usbh_ctrl_xfer(udev, REQ_TYPE_OUT | REQ_TYPE_STD_DEV | REQ_TYPE_TO_DEV,
1068  USB_REQ_SET_FEATURE, 0x01, 0x0000, 0x0000,
1069  NULL, &read_len, 300) < 0)
1070  {
1071  USB_debug("Device does not accept remote wakeup enable command.\n");
1072  }
1073  }
1074 
1075  if (g_conn_func)
1076  g_conn_func(udev, 0);
1077 
1078  return ret;
1079 }
1080 
1081 int usbh_reset_device(UDEV_T *udev)
1082 {
1083  IFACE_T *iface;
1084  DESC_CONF_T *conf;
1085  uint32_t read_len;
1086  int dev_num, ret;
1087 
1088  USB_debug("Reset device =>\n");
1089 
1091 
1092  /*------------------------------------------------------------------------------------*/
1093  /* Disconnect device */
1094  /*------------------------------------------------------------------------------------*/
1095 
1096  if (g_disconn_func)
1097  g_disconn_func(udev, 0);
1098 
1099  usbh_quit_xfer(udev, &(udev->ep0)); /* Quit control transfer if hw_pipe is not NULL. */
1100 
1101  /* Notified all actived interface device driver */
1102  iface = udev->iface_list;
1103  while (iface != NULL)
1104  {
1105  udev->iface_list = iface->next;
1106  iface->driver->disconnect(iface);
1107  usbh_free_mem(iface, sizeof(*iface));
1108  iface = udev->iface_list;
1109  }
1110 
1111  /*------------------------------------------------------------------------------------*/
1112  /* Reset device */
1113  /*------------------------------------------------------------------------------------*/
1114 
1115  reset_device(udev);
1116 
1117  delay_us(100 * 1000);
1118 
1119  /*------------------------------------------------------------------------------------*/
1120  /* Set address (use current address) */
1121  /*------------------------------------------------------------------------------------*/
1122 
1123  dev_num = udev->dev_num;
1124  udev->dev_num = 0;
1125  /* Issue SET ADDRESS command to set the same device address */
1126  ret = usbh_ctrl_xfer(udev, REQ_TYPE_OUT | REQ_TYPE_STD_DEV | REQ_TYPE_TO_DEV,
1127  USB_REQ_SET_ADDRESS, dev_num, 0, 0,
1128  NULL, &read_len, 100);
1129  udev->dev_num = dev_num;
1130  if (ret < 0)
1131  return ret;
1132 
1133  delay_us(100 * 1000); /* after set address, give 100 ms delay */
1134 
1135  /*------------------------------------------------------------------------------------*/
1136  /* Get device descriptor */
1137  /*------------------------------------------------------------------------------------*/
1138 
1139  /* Get device descriptor again with new device address */
1140  ret = usbh_get_device_descriptor(udev, &udev->descriptor);
1141  if (ret < 0)
1142  return ret;
1143 
1144  /*------------------------------------------------------------------------------------*/
1145  /* Get configuration descriptor */
1146  /*------------------------------------------------------------------------------------*/
1147 
1148  conf = (DESC_CONF_T *)udev->cfd_buff; /* using the previously allocated buffer */
1149 
1150  /* Get configuration descriptor again with new device address */
1151  ret = usbh_get_config_descriptor(udev, (uint8_t *)conf, MAX_DESC_BUFF_SIZE);
1152  if (ret < 0)
1153  return ret;
1154 
1155  /* Always select the first configuration */
1156  ret = usbh_set_configuration(udev, udev->cur_conf);
1157  if (ret < 0)
1158  {
1159  USB_debug("Set configuration %d failed!\n", udev->cur_conf);
1160  return ret;
1161  }
1162 
1163  /* Parse the configuration/interface/endpoint descriptors and find corresponding drivers. */
1164  ret = usbh_parse_configuration(udev, (uint8_t *)conf);
1165  if (ret < 0)
1166  {
1167  USB_debug("Parse configuration %d failed!\n", conf->bConfigurationValue);
1168  return ret;
1169  }
1170 
1171  /* Enable remote wakeup */
1172  if (usbh_ctrl_xfer(udev, REQ_TYPE_OUT | REQ_TYPE_STD_DEV | REQ_TYPE_TO_DEV,
1173  USB_REQ_SET_FEATURE, 0x01, 0x0000, 0x0000,
1174  NULL, &read_len, 300) < 0)
1175  {
1176  USB_debug("Device not accept remote wakeup enable command.\n");
1177  }
1178 
1179  if (g_conn_func)
1180  g_conn_func(udev, 0);
1181 
1182  return ret;
1183 }
1184 
1185 void disconnect_device(UDEV_T *udev)
1186 {
1187  IFACE_T *iface;
1188 
1189  USB_debug("disconnect device...\n");
1190 
1191  if (g_disconn_func)
1192  g_disconn_func(udev, 0);
1193 
1194  usbh_quit_xfer(udev, &(udev->ep0)); /* Quit control transfer if hw_pipe is not NULL. */
1195 
1196  /* Notified all actived interface device driver */
1197  iface = udev->iface_list;
1198  while (iface != NULL)
1199  {
1200  udev->iface_list = iface->next;
1201  iface->driver->disconnect(iface);
1202  usbh_free_mem(iface, sizeof(*iface));
1203  iface = udev->iface_list;
1204  }
1205 
1206  /* remove device from global device list */
1207  free_dev_address(udev->dev_num);
1208  free_device(udev);
1209 
1210  usbh_memory_used();
1211 }
1212 
1213 #if 0
1214 static int check_device(UDEV_T *udev)
1215 {
1216  UDEV_T *d;
1217 
1218  if (udev == NULL)
1219  return USBH_ERR_INVALID_PARAM;
1220 
1221  //if ((udev->hc_driver != &ohci_driver) && (udev->hc_driver != &ehci_driver))
1222  // return USBH_ERR_INVALID_PARAM;
1223 
1224  d = g_udev_list;
1225  while (d)
1226  {
1227  if (d == udev)
1228  return USBH_OK;
1229  d = d->next;
1230  }
1231  return USBH_ERR_INVALID_PARAM;
1232 }
1233 #endif
1234 
1235 EP_INFO_T * usbh_iface_find_ep(IFACE_T *iface, uint8_t ep_addr, uint8_t dir_type)
1236 {
1237  ALT_IFACE_T *aif = iface->aif;
1238  int i;
1239 
1240  if (ep_addr == 0) /* find the first EP matched with specified direction and type */
1241  {
1242  for (i = 0; i < aif->ifd->bNumEndpoints; i++)
1243  {
1244  if (((aif->ep[i].bEndpointAddress & EP_ADDR_DIR_MASK) == (dir_type & EP_ADDR_DIR_MASK)) &&
1245  ((aif->ep[i].bmAttributes & EP_ATTR_TT_MASK) == (dir_type & EP_ATTR_TT_MASK)))
1246  return &aif->ep[i];
1247  }
1248  }
1249  else /* find the EP with specified endpoint address */
1250  {
1251  for (i = 0; i < aif->ifd->bNumEndpoints; i++)
1252  {
1253  if (aif->ep[i].bEndpointAddress == ep_addr)
1254  return &aif->ep[i];
1255  }
1256  }
1257  return NULL;
1258 }
1259 
1260 void usbh_dump_buff_bytes(uint8_t *buff, int nSize)
1261 {
1262  int nIdx, i;
1263 
1264  nIdx = 0;
1265  while (nSize > 0)
1266  {
1267  printf("0x%04X ", nIdx);
1268  for (i = 0; i < 16; i++)
1269  printf("%02x ", buff[nIdx + i]);
1270  printf(" ");
1271  for (i = 0; i < 16; i++)
1272  {
1273  if ((buff[nIdx + i] >= 0x20) && (buff[nIdx + i] < 127))
1274  printf("%c", buff[nIdx + i]);
1275  else
1276  printf(".");
1277  nSize--;
1278  }
1279  nIdx += 16;
1280  printf("\n");
1281  }
1282  printf("\n");
1283 }
1284 
1285 void usbh_dump_iface(IFACE_T *iface)
1286 {
1287  USB_debug("\n [IFACE info] (0x%x)\n", (int)iface);
1288  USB_debug(" ----------------------------------------------\n");
1289  USB_debug(" udev = 0x%x\n", iface->udev);
1290  USB_debug(" if_num = %d\n", iface->if_num);
1291  USB_debug(" driver = 0x%x\n", (int)iface->driver);
1292  USB_debug(" next = 0x%x\n", (int)iface->next);
1293  usbh_dump_interface_descriptor(iface->aif->ifd);
1294 }
1295 
1296 void usbh_dump_ep_info(EP_INFO_T *ep)
1297 {
1298  USB_debug("\n [Endpoint Info] (0x%x)\n", (int)ep);
1299  USB_debug(" ----------------------------------------------\n");
1300  USB_debug(" bEndpointAddress = 0x%02x\n", ep->bEndpointAddress);
1301  USB_debug(" bmAttributes = 0x%02x\n", ep->bmAttributes);
1302  USB_debug(" bInterval = %d\n", ep->bInterval);
1303  USB_debug(" wMaxPacketSize = %d\n", ep->wMaxPacketSize);
1304  USB_debug(" hw_pipe = 0x%x\n", (int)ep->hw_pipe);
1305 }
1306 
1308 
1309 
1310 /*** (C) COPYRIGHT 2017 Nuvoton Technology Corp. ***/
static int reset_device(UDEV_T *udev)
Definition: usb_core.c:92
#define USBH_ERR_NOT_FOUND
Definition: usbh_lib.h:39
#define USBH_ERR_INVALID_PARAM
Definition: usbh_lib.h:38
#define HSUSBH
Definition: M480.h:389
__IO uint32_t HcRhPortStatus[2]
Definition: usbh_reg.h:1206
#define USBH_HcRhPortStatus_CCS_Msk
Definition: usbh_reg.h:1392
#define HSUSBH_UPSCR_SUSPEND_Msk
Definition: hsusbh_reg.h:1131
HIDDEN_SYMBOLS void usbh_core_init()
Initialize M480 USB Host controller and USB stack.
Definition: usb_core.c:39
__IO uint32_t HcInterruptEnable
Definition: usbh_reg.h:1189
#define USBH_HcInterruptEnable_RD_Msk
Definition: usbh_reg.h:1281
__IO uint32_t HcControl
Definition: usbh_reg.h:1186
#define USBH_HcInterruptEnable_RHSC_Msk
Definition: usbh_reg.h:1287
#define USBH_ERR_SET_DEV_ADDR
Definition: usbh_lib.h:42
#define USBH_ERR_TIMEOUT
Definition: usbh_lib.h:46
void usbh_suspend()
Suspend USB Host Controller and devices.
Definition: usb_core.c:115
void usbh_install_conn_callback(CONN_FUNC *conn_func, CONN_FUNC *disconn_func)
Install device connect and disconnect callback function.
Definition: usb_core.c:86
__IO uint32_t UPSCR[2]
Definition: hsusbh_reg.h:978
#define HSUSBH_USTSR_HCHalted_Msk
Definition: hsusbh_reg.h:1065
NuMicro peripheral access layer header file.
#define SYS
Definition: M480.h:367
USB Host hub class driver header file.
#define SYS_CSERVER_VERSION_Msk
Definition: sys_reg.h:6034
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:637
#define USBH_ERR_DESCRIPTOR
Definition: usbh_lib.h:41
#define HSUSBH_UCMDR_ASEN_Msk
Definition: hsusbh_reg.h:1038
#define USBH_ERR_IF_EP_LIMIT
Definition: usbh_lib.h:34
#define USBH_HcRhStatus_DRWE_Msk
Definition: usbh_reg.h:1380
#define HSUSBH_UCMDR_PSEN_Msk
Definition: hsusbh_reg.h:1035
#define USBH_ERR_IF_ALT_LIMIT
Definition: usbh_lib.h:33
__IO uint32_t UCMDR
Definition: hsusbh_reg.h:964
#define HSUSBH_UCMDR_RUN_Msk
Definition: hsusbh_reg.h:1026
#define HSUSBH_UPSCR_FPR_Msk
Definition: hsusbh_reg.h:1128
__IO uint32_t HcRhStatus
Definition: usbh_reg.h:1205
void() CONN_FUNC(struct udev_t *udev, int param)
Definition: usbh_lib.h:116
uint32_t get_ticks(void)
A function return current tick count.
__IO uint32_t HcMiscControl
Definition: usbh_reg.h:1211
#define USBH_HcControl_HCFS_Msk
Definition: usbh_reg.h:1239
#define USBH_HcRhPortStatus_POCI_Msk
Definition: usbh_reg.h:1401
#define USBH_ERR_MEMORY_OUT
Definition: usbh_lib.h:32
__IO uint32_t USBPCR0
Definition: hsusbh_reg.h:982
#define USBH_ERR_SET_CONFIG
Definition: usbh_lib.h:43
#define USBH
Definition: M480.h:388
#define HSUSBH_UPSCR_PE_Msk
Definition: hsusbh_reg.h:1116
#define USBH_HcControl_HCFS_Pos
Definition: usbh_reg.h:1238
UDEV_T * udev
Definition: usbh_uac.h:111
USB Host library header file.
#define USBH_HcRhPortStatus_PSS_Msk
Definition: usbh_reg.h:1398
#define USBH_HcMiscControl_OCAL_Msk
Definition: usbh_reg.h:1434
#define USBH_ERR_DATA_OVERRUN
Definition: usbh_lib.h:64
#define NULL
NULL pointer.
Definition: M480.h:604
#define USBH_OK
Definition: usbh_lib.h:31
void usbh_resume(void)
Resume USB Host controller and devices.
Definition: usb_core.c:176
__IO uint32_t USTSR
Definition: hsusbh_reg.h:965
__IO uint32_t USBPCR1
Definition: hsusbh_reg.h:983