36#define usb_dbg_msg printf
39#define usb_desc_dump printf
48#pragma data_alignment=256
49struct ohci_hcca _OHCI_HCCA;
51#pragma data_alignment=16
54#pragma data_alignment=16
57#pragma data_alignment=4
72static int get_ms_elapsed(
int jiffy)
74 uint32_t fnum =
USBH->HcFmNumber & 0xffff;
79 return (0xffff - jiffy) + fnum;
86 usb_desc_dump(
"\n[Device Descriptor]\n");
87 usb_desc_dump(
"----------------------------------------------\n");
88 usb_desc_dump(
" Length = %2d\n", desc->bLength);
89 usb_desc_dump(
" DescriptorType = %02x\n", desc->bDescriptorType);
90 usb_desc_dump(
" USB version = %x.%02x\n",
91 desc->bcdUSB >> 8, desc->bcdUSB & 0xff);
92 usb_desc_dump(
" Vendor:Product = %04x:%04x\n",
93 desc->idVendor, desc->idProduct);
94 usb_desc_dump(
" MaxPacketSize0 = %d\n", desc->bMaxPacketSize0);
95 usb_desc_dump(
" NumConfigurations = %d\n", desc->bNumConfigurations);
96 usb_desc_dump(
" Device version = %x.%02x\n",
97 desc->bcdDevice >> 8, desc->bcdDevice & 0xff);
98 usb_desc_dump(
" Device Class:SubClass:Protocol = %02x:%02x:%02x\n",
99 desc->bDeviceClass, desc->bDeviceSubClass, desc->bDeviceProtocol);
104 uint8_t *bptr = (uint8_t *)desc;
105 int tlen = desc->wTotalLength;
114 usb_desc_dump(
"\n[Configuration Descriptor]\n");
115 usb_desc_dump(
"----------------------------------------------\n");
116 usb_desc_dump(
" Length = %2d\n", desc->bLength);
117 usb_desc_dump(
" DescriptorType = %02x\n", desc->bDescriptorType);
118 usb_desc_dump(
" wTotalLength = %2d\n", desc->wTotalLength);
119 usb_desc_dump(
" bNumInterfaces = %d\n", desc->bNumInterfaces);
120 usb_desc_dump(
" bConfigurationValue = %d\n", desc->bConfigurationValue);
121 usb_desc_dump(
" iConfiguration = %d\n", desc->iConfiguration);
122 usb_desc_dump(
" bmAttributes = 0x%02x\n", desc->bmAttributes);
123 usb_desc_dump(
" MaxPower = %d\n", desc->MaxPower);
126 case USB_DT_INTERFACE:
128 usb_desc_dump(
"\n[Interface Descriptor]\n");
129 usb_desc_dump(
"----------------------------------------------\n");
130 usb_desc_dump(
" Length = %2d\n", if_desc->bLength);
131 usb_desc_dump(
" DescriptorType = %02x\n", if_desc->bDescriptorType);
132 usb_desc_dump(
" bInterfaceNumber = %d\n", if_desc->bInterfaceNumber);
133 usb_desc_dump(
" bAlternateSetting = %d\n", if_desc->bAlternateSetting);
134 usb_desc_dump(
" bNumEndpoints = %d\n", if_desc->bNumEndpoints);
135 usb_desc_dump(
" bInterfaceClass = 0x%02x\n", if_desc->bInterfaceClass);
136 usb_desc_dump(
" bInterfaceSubClass = 0x%02x\n", if_desc->bInterfaceSubClass);
137 usb_desc_dump(
" bInterfaceProtocol = 0x%02x\n", if_desc->bInterfaceProtocol);
138 usb_desc_dump(
" iInterface = %d\n", if_desc->iInterface);
141 case USB_DT_ENDPOINT:
143 usb_desc_dump(
"\n[Endoint Descriptor]\n");
144 usb_desc_dump(
"----------------------------------------------\n");
145 usb_desc_dump(
" Length = %2d\n", ep_desc->bLength);
146 usb_desc_dump(
" DescriptorType = %02x\n", ep_desc->bDescriptorType);
147 usb_desc_dump(
" bEndpointAddress = 0x%02x\n", ep_desc->bEndpointAddress);
148 usb_desc_dump(
" bmAttributes = 0x%02x\n", ep_desc->bmAttributes);
149 usb_desc_dump(
" wMaxPacketSize = %d\n", ep_desc->wMaxPacketSize);
150 usb_desc_dump(
" bInterval = %d\n", ep_desc->bInterval);
151 usb_desc_dump(
" bRefresh = %d\n", ep_desc->bRefresh);
152 usb_desc_dump(
" bSynchAddress = %d\n", ep_desc->bSynchAddress);
163static void td_fill(
int td_idx, uint32_t info, uint8_t *buff, uint32_t data_len)
165 TD_T *td = &_td[td_idx];
168 td->hwCBP = (uint32_t)((!buff || !data_len) ? 0 : buff);
169 td->hwBE = (uint32_t)((!buff || !data_len ) ? 0 : (uint32_t)buff + data_len - 1);
170 td->hwNextTD = (uint32_t)&_td[td_idx+1];
176static void fill_ctrl_xfer_descriptors(
int dev_addr, uint8_t *data_buff,
int data_len,
int pipe_out)
184 info = TD_CC | TD_DP_SETUP | TD_T_DATA0;
185 td_fill(td_idx, info, (uint8_t *)&_request, 8);
194 info = (TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1);
196 info = (TD_CC | TD_R | TD_DP_IN | TD_T_DATA1);
198 td_fill(td_idx, info, data_buff, data_len);
206 info = (TD_CC | TD_DP_IN | TD_T_DATA1);
208 info = (TD_CC | TD_DP_OUT | TD_T_DATA1);
210 td_fill(td_idx, info,
NULL, 0);
211 _last_td_idx = td_idx;
216 td_fill(td_idx, 0x01,
NULL, 0);
217 _td[td_idx].hwNextTD = 0;;
222 _ed.hwTailP = (uint32_t)&_td[td_idx];
223 _ed.hwHeadP = (uint32_t)&_td[0];
224 _ed.hwINFO = ((is_low_speed ? 8 : 64) << 16)
227 | (is_low_speed << 13)
235static void fill_bulk_xfer_descriptors(uint16_t ep_addr, uint8_t *toggle,
236 uint8_t *data_buff,
int data_len,
int pipe_out)
245 info = (TD_CC | TD_R | TD_DP_OUT);
247 info = (TD_CC | TD_R | TD_DP_IN);
256 td_fill(td_idx, info, data_buff, xfer_len);
257 _last_td_idx = td_idx;
259 data_buff += xfer_len;
260 data_len -= xfer_len;
262 while (data_len > 0);
265 td_fill(td_idx, 0x01,
NULL, 0);
266 _td[td_idx].hwNextTD = 0;
271 _ed.hwTailP = (uint32_t)&_td[td_idx];
272 _ed.hwHeadP = (uint32_t)&_td[0] | (*toggle << 1);
273 _ed.hwINFO = ((is_low_speed ? 8 : 64) << 16)
276 | (is_low_speed << 13)
278 | ((ep_addr & 0xf) << 7)
319 _request.requesttype = requesttype;
320 _request.request = request;
321 _request.value =
value;
322 _request.index = index;
323 _request.length = length;
325 USBH->HcInterruptStatus = 0xFF;
326 fill_ctrl_xfer_descriptors((request == USB_REQ_SET_ADDRESS) ? 0 : DEV_ADDR, buffer, data_len, dir);
331 USBH->HcControlHeadED = (uint32_t)&_ed;
333 USBH->HcCommandStatus = OHCI_CLF;
335 t0 =
USBH->HcFmNumber & 0xffff;
336 while (get_ms_elapsed(t0) < 1000)
339 ((_td[_last_td_idx].hwINFO & 0xf0000000) != 0xf0000000))
345 if (get_ms_elapsed(t0) >= 1000)
347 usb_dbg_msg(
"Control transfer failed!\n");
352 for (i = 0; i <= _last_td_idx; i++)
354 if (_td[i].hwINFO & 0xf0000000)
356 usb_dbg_msg(
"USB xfer error, CC=0x%x [0x%x]\n", (_td[i].hwINFO >> 28), (
int)&_td[i]);
361 if ((_td[i].hwINFO >> 28) == 0x4)
370 USBH->HcControl &= ~USBH_HcControl_CLE_Msk;
371 USBH->HcControlHeadED = 0;
372 USBH->HcDoneHead = 0;
373 _OHCI_HCCA.done_head = 0;
390 uint8_t *data_buff,
int data_len,
int timeout)
394 fill_bulk_xfer_descriptors(ep_addr, toggle, data_buff, data_len, (ep_addr & 0x80) ? 0: 1);
399 USBH->HcBulkHeadED = (uint32_t)&_ed;
401 USBH->HcCommandStatus = OHCI_BLF;
403 t0 =
USBH->HcFmNumber & 0xffff;
404 while (get_ms_elapsed(t0) < timeout)
407 ((_td[_last_td_idx].hwINFO & 0xf0000000) != 0xf0000000))
413 for (i = 0; i <= _last_td_idx; i++)
415 if (_td[i].hwINFO & 0xf0000000)
417 usb_dbg_msg(
"USB xfer error, CC=0x%x [0x%x]\n", (_td[i].hwINFO >> 28), (
int)&_td[i]);
422 if ((_td[i].hwINFO >> 28) == 0x4)
429 if (get_ms_elapsed(t0) >= timeout)
431 usb_dbg_msg(
"Bulk transfer failed!\n");
438 *toggle = (_ed.hwHeadP >> 1) & 0x1;
440 USBH->HcControl &= ~USBH_HcControl_BLE_Msk;
441 USBH->HcBulkHeadED = 0;
442 USBH->HcDoneHead = 0;
443 _OHCI_HCCA.done_head = 0;
464 ret =
usbh_drv_ctrl_req(USB_DIR_IN, USB_REQ_GET_DESCRIPTOR, USB_DT_DEVICE << 8, 0, 64,
465 64 , desc_buff , 0 );
470 if (len < 0x12) len = 0x12;
472 ret =
usbh_drv_ctrl_req(USB_DIR_IN, USB_REQ_GET_DESCRIPTOR, USB_DT_DEVICE << 8, 0, len,
473 len , desc_buff , 0 );
476 for (i = 0; i < MINISEC_10; i++);
501 ret =
usbh_drv_ctrl_req(USB_DIR_IN, USB_REQ_GET_DESCRIPTOR, USB_DT_CONFIG << 8, 0, 8,
508 ret =
usbh_drv_ctrl_req(USB_DIR_IN, USB_REQ_GET_DESCRIPTOR, USB_DT_CONFIG << 8, 0, len,
509 len , desc_buff , 0 );
544 usb_dbg_msg(
"Clear endpoint 0x%x halt.\n", ep_addr);
551static int do_port_reset(
int port)
555 for (retry = 1; retry <= 3; retry++)
558 for (i = 0; i < MINISEC_10*retry; i++)
568 usb_dbg_msg(
"Port reset failed\n");
572 usb_dbg_msg(
"Port reset OK.\n");
593 volatile int i, retry;
599 port_staus =
USBH->HcRhPortStatus[port];
600 USBH->HcRhPortStatus[port] = port_staus & 0xffff0000;
622 usb_dbg_msg(
"Device connected.\n");
627 if (do_port_reset(port) < 0)
630 if ((
USBH->HcRhPortStatus[port] & 0x03) == 0x03)
633 usb_dbg_msg(
"USB device enabled (%s).\n", is_low_speed ?
"Low-speed" :
"Full-speed");
637 usb_dbg_msg(
"Failed to enable USB device!!\n");
641 for (i = 0; i < MINISEC_10; i++);
648 for (retry = 0; retry < 3; retry++)
657 for (i = 0; i < MINISEC_100; i++);
661 usb_dbg_msg(
"Failed to set device address!!\n");
668 usb_dbg_msg(
"GET Device Descriptor command failed!!\n");
676static int ohci_reset(
void)
681 USBH->HcInterruptDisable = OHCI_INTR_MIE;
685 USBH->HcCommandStatus = OHCI_HCR;
687 for (t0 = 0; t0 < MINISEC_10; t0++)
689 if ((
USBH->HcCommandStatus & OHCI_HCR) == 0)
692 if (t0 >= MINISEC_10)
694 usb_dbg_msg(
"Error! - USB OHCI reset timed out!\n");
700 USBH->HcControl = OHCI_USB_RESET;
702 for (t0 = 0; t0 < MINISEC_10; t0++)
704 if ((
USBH->HcCommandStatus & OHCI_HCR) == 0)
707 if (t0 >= MINISEC_10)
709 usb_dbg_msg(
"Error! - USB HC reset timed out!\n");
716static int ohci_start()
721 for (i = 0; i < NUM_INTS; i++)
722 _OHCI_HCCA.int_table[i] = 0;
726 USBH->HcControlHeadED = 0;
727 USBH->HcBulkHeadED = 0;
729 USBH->HcHCCA = (uint32_t)&_OHCI_HCCA;
733 USBH->HcPeriodicStart = (fminterval * 9) / 10;
736 fminterval |= ((((fminterval - 210) * 6) / 7) << 16);
737 USBH->HcFmInterval = fminterval;
739 USBH->HcLSThreshold = 0x628;
742 USBH->HcControl = 0x3 | OHCI_USB_OPER;
754 for (i = 0; i < MINISEC_10 * 2; i++);
771 USBH->HcMiscControl &= ~0x8;
773 if (ohci_reset() < 0)
775 usb_dbg_msg(
"OHCI reset failed!!\n");
779 if (ohci_start() < 0)
781 usb_dbg_msg(
"OHCI reset failed!!\n");
785 for (loop = 0; loop < 0x100000; loop++);
void *__dso_handle __attribute__((weak))
NUC472/NUC442 peripheral access layer header file. This file contains all the peripheral register's d...
#define USBH_HcRhDescriptorA_NPS_Msk
#define USBH_HcRhStatus_LPSC_Msk
#define USBH_HcRhPortStatus_CSC_Msk
#define USBH_HcRhPortStatus_PRSC_Msk
#define USBH_HcRhDescriptorA_PSM_Msk
#define USBH_HcRhPortStatus_LSDA_Msk
#define USBH_HcControl_BLE_Msk
#define USBH_HcRhStatus_LPS_Msk
#define USBH_HcRhPortStatus_PRS_Msk
#define USBH_HcRhStatus_OCI_Msk
#define USBH_HcControl_CLE_Msk
#define USBH_HcRhPortStatus_PES_Msk
#define USBH_HcRhPortStatus_CCS_Msk
#define USBH_HcInterruptStatus_WDH_Msk
#define USBH_RET_XFER_ERR
#define USBH_RET_DEV_REMOVED
#define USBH_RET_XFER_TIMEOUT
#define USBH_RET_ERR_PORT_ENABLE
#define USBH_RET_ERR_PORT_RST
#define USBH_RET_DEV_CONN_KEEP
#define USBH_INTR_BUFF_SIZE
#define USBH_RET_ERR_PARM
#define USBH_RET_NO_DEVICE
int usbh_init(void)
Initialized USB host controller driver.
int usbh_probe_port(uint32_t port)
Probe USB root-hub port connect/disconnect status. A newly connected device will be initialized in th...
int usbh_set_configuration(int conf_val)
Issue a standard request SET_CONFIGURATION to USB device.
int usbh_drv_ctrl_req(uint8_t requesttype, uint8_t request, uint16_t value, uint16_t index, uint16_t length, int data_len, uint8_t *buffer, int dir)
Execute a control transfer request.
int usbh_get_device_descriptor(uint8_t *desc_buff)
Get device descriptor from the USB device.
int usbh_clear_halt(uint16_t ep_addr)
Issue a standard request SET_FEATURE to clear USB device endpoint halt state.
int usbh_drv_bulk_xfer(uint16_t ep_addr, uint8_t *toggle, uint8_t *data_buff, int data_len, int timeout)
Execute a control transfer request.
int get_config_descriptor(uint8_t *desc_buff)
Get configuration descriptor from the USB device.
#define NULL
NULL pointer.