| NUC472_NUC442_BSP V3.03.003 The Board Support Package for NUC472/NUC442

lw_usbh.c
Go to the documentation of this file.
1/**************************************************************************/
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16
17#include "NUC472_442.h"
18#include "usb.h"
19#include "lw_usbh.h"
20
21
35
36#define usb_dbg_msg printf
37//#define usb_dbg_msg(...)
38
39#define usb_desc_dump printf
40//#define usb_desc_dump(...)
41
42 static int DEV_ADDR;
43
44 int is_low_speed;
45
46#ifdef __ICCARM__
47
48#pragma data_alignment=256
49 struct ohci_hcca _OHCI_HCCA;
50
51#pragma data_alignment=16
52ED_T _ed;
53
54#pragma data_alignment=16
55TD_T _td[8];
56
57#pragma data_alignment=4
58uint8_t _transfer_buffer[USBH_INTR_BUFF_SIZE];
59
60#else
61 struct ohci_hcca _OHCI_HCCA __attribute__((aligned(256)));
62ED_T _ed __attribute__((aligned(16)));
63TD_T _td[8] __attribute__((aligned(16)));
64uint8_t _transfer_buffer[USBH_INTR_BUFF_SIZE] __attribute__((aligned(4)));
65#endif
66
67
68 DEV_REQ_T _request;
69 int _last_td_idx;
70
71
72 static int get_ms_elapsed(int jiffy)
73{
74 uint32_t fnum = USBH->HcFmNumber & 0xffff;
75
76 if (fnum >= jiffy)
77 return fnum - jiffy;
78 else
79 return (0xffff - jiffy) + fnum;
80}
81
82
83#ifndef __GNUC__
84 static void dump_device_descriptor(USB_DEV_DESC_T *desc)
85{
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);
100}
101
102 static void dump_config_descriptor(USB_CONFIG_DESC_T *desc)
103{
104 uint8_t *bptr = (uint8_t *)desc;
105 int tlen = desc->wTotalLength;
106 USB_IF_DESC_T *if_desc;
107 USB_EP_DESC_T *ep_desc;
108
109 while (tlen > 0)
110 {
111 switch (bptr[1])
112 {
113 case USB_DT_CONFIG:
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);
124 break;
125
126 case USB_DT_INTERFACE:
127 if_desc = (USB_IF_DESC_T *)bptr;
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);
139 break;
140
141 case USB_DT_ENDPOINT:
142 ep_desc = (USB_EP_DESC_T *)bptr;
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);
153 break;
154 }
155 if (bptr[0] == 0)
156 break;
157 tlen -= bptr[0];
158 bptr += bptr[0];
159 }
160}
161#endif
162
163 static void td_fill(int td_idx, uint32_t info, uint8_t *buff, uint32_t data_len)
164{
165 TD_T *td = &_td[td_idx];
166
167 td->hwINFO = info;
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];
171
172 //usb_dbg_msg("TD [0x%x]: 0x%x, 0x%x, 0x%x, 0x%x\n", (int)td, td->hwINFO, td->hwCBP, td->hwBE, td->hwNextTD);
173}
174
175
176 static void fill_ctrl_xfer_descriptors(int dev_addr, uint8_t *data_buff, int data_len, int pipe_out)
177{
178 uint32_t info;
179 int td_idx = 0;
180
181 /*------------------------------------------------------------------------------------*/
182 /* prepare SETUP stage TD */
183 /*------------------------------------------------------------------------------------*/
184 info = TD_CC | TD_DP_SETUP | TD_T_DATA0;
185 td_fill(td_idx, info, (uint8_t *)&_request, 8);
186 td_idx++;
187
188 /*------------------------------------------------------------------------------------*/
189 /* prepare DATA stage TD */
190 /*------------------------------------------------------------------------------------*/
191 if (data_len > 0)
192 {
193 if (pipe_out)
194 info = (TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1);
195 else
196 info = (TD_CC | TD_R | TD_DP_IN | TD_T_DATA1);
197
198 td_fill(td_idx, info, data_buff, data_len);
199 td_idx++;
200 }
201
202 /*------------------------------------------------------------------------------------*/
203 /* prepare STATUS stage TD */
204 /*------------------------------------------------------------------------------------*/
205 if (pipe_out)
206 info = (TD_CC | TD_DP_IN | TD_T_DATA1);
207 else
208 info = (TD_CC | TD_DP_OUT | TD_T_DATA1);
209
210 td_fill(td_idx, info, NULL, 0);
211 _last_td_idx = td_idx;
212
213 td_idx++;
214
215 /* dummy TD */
216 td_fill(td_idx, 0x01, NULL, 0);
217 _td[td_idx].hwNextTD = 0;;
218
219 /*------------------------------------------------------------------------------------*/
220 /* prepare ED */
221 /*------------------------------------------------------------------------------------*/
222 _ed.hwTailP = (uint32_t)&_td[td_idx];
223 _ed.hwHeadP = (uint32_t)&_td[0];
224 _ed.hwINFO = ((is_low_speed ? 8 : 64) << 16) /* Maximum Packet Size */
225 | (0 << 15) /* Format */
226 | (0 << 14) /* Skip */
227 | (is_low_speed << 13) /* Speed: full speed */
228 | (0 << 11) /* Direction */
229 | (0 << 7) /* Endpoint Number */
230 | (dev_addr); /* Function Address */
231 _ed.hwNextED = 0;
232}
233
234
235 static void fill_bulk_xfer_descriptors(uint16_t ep_addr, uint8_t *toggle,
236 uint8_t *data_buff, int data_len, int pipe_out)
237{
238 uint32_t info;
239 int xfer_len;
240 int td_idx = 0;
241
242 do
243 {
244 if (pipe_out)
245 info = (TD_CC | TD_R | TD_DP_OUT);
246 else
247 info = (TD_CC | TD_R | TD_DP_IN);
248
249 info &= ~ (1 << 25); /* let OHCI hardware do the data toggle */
250
251 if (data_len > 4096)
252 xfer_len = 4096;
253 else
254 xfer_len = data_len;
255
256 td_fill(td_idx, info, data_buff, xfer_len);
257 _last_td_idx = td_idx;
258 td_idx++;
259 data_buff += xfer_len;
260 data_len -= xfer_len;
261 }
262 while (data_len > 0);
263
264 /* dummy TD */
265 td_fill(td_idx, 0x01, NULL, 0);
266 _td[td_idx].hwNextTD = 0;
267
268 /*------------------------------------------------------------------------------------*/
269 /* prepare ED */
270 /*------------------------------------------------------------------------------------*/
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) /* Maximum Packet Size */
274 | (0 << 15) /* Format */
275 | (0 << 14) /* Skip */
276 | (is_low_speed << 13) /* Speed: full speed */
277 | (0 << 11) /* Direction */
278 | ((ep_addr & 0xf) << 7) /* Enpoint Number */
279 | (DEV_ADDR); /* Function Address */
280 _ed.hwNextED = 0;
281}
282
284
285
305 int usbh_drv_ctrl_req(uint8_t requesttype,
306 uint8_t request,
307 uint16_t value,
308 uint16_t index,
309 uint16_t length,
310 int data_len,
311 uint8_t *buffer,
312 int dir)
313{
314 int t0, i, ret = USBH_RET_NO_ERR;
315
316 /*------------------------------------------------------------------------------------*/
317 /* Fill the SETUP packet for SET ADDRESS command */
318 /*------------------------------------------------------------------------------------*/
319 _request.requesttype = requesttype;
320 _request.request = request;
321 _request.value = value;
322 _request.index = index;
323 _request.length = length;
324
325 USBH->HcInterruptStatus = 0xFF; /* clear status */
326 fill_ctrl_xfer_descriptors((request == USB_REQ_SET_ADDRESS) ? 0 : DEV_ADDR, buffer, data_len, dir);
327
328 /*------------------------------------------------------------------------------------*/
329 /* Do transfer */
330 /*------------------------------------------------------------------------------------*/
331 USBH->HcControlHeadED = (uint32_t)&_ed; /* Link ED to OHCI */
332 USBH->HcControl |= USBH_HcControl_CLE_Msk;
333 USBH->HcCommandStatus = OHCI_CLF; /* start Control list */
334
335 t0 = USBH->HcFmNumber & 0xffff;
336 while (get_ms_elapsed(t0) < 1000)
337 {
338 if ((USBH->HcInterruptStatus & USBH_HcInterruptStatus_WDH_Msk) &&
339 ((_td[_last_td_idx].hwINFO & 0xf0000000) != 0xf0000000))
340 break;
341 }
342
343 USBH->HcInterruptStatus = USBH_HcInterruptStatus_WDH_Msk;
344
345 if (get_ms_elapsed(t0) >= 1000)
346 {
347 usb_dbg_msg("Control transfer failed!\n");
348 ret = USBH_RET_XFER_TIMEOUT;
349 goto ctrl_out;
350 }
351
352 for (i = 0; i <= _last_td_idx; i++)
353 {
354 if (_td[i].hwINFO & 0xf0000000)
355 {
356 usb_dbg_msg("USB xfer error, CC=0x%x [0x%x]\n", (_td[i].hwINFO >> 28), (int)&_td[i]);
357
358 if (ret == USBH_RET_STALL)
359 continue;
360
361 if ((_td[i].hwINFO >> 28) == 0x4)
362 ret = USBH_RET_STALL;
363 else
364 ret = USBH_RET_XFER_ERR;
365 }
366 }
367
368ctrl_out:
369
370 USBH->HcControl &= ~USBH_HcControl_CLE_Msk;
371 USBH->HcControlHeadED = 0;
372 USBH->HcDoneHead = 0;
373 _OHCI_HCCA.done_head = 0;
374 return ret;
375}
376
377
389 int usbh_drv_bulk_xfer(uint16_t ep_addr, uint8_t *toggle,
390 uint8_t *data_buff, int data_len, int timeout)
391{
392 int t0, i, ret = USBH_RET_NO_ERR;
393
394 fill_bulk_xfer_descriptors(ep_addr, toggle, data_buff, data_len, (ep_addr & 0x80) ? 0: 1);
395
396 /*------------------------------------------------------------------------------------*/
397 /* Do transfer */
398 /*------------------------------------------------------------------------------------*/
399 USBH->HcBulkHeadED = (uint32_t)&_ed; /* Link ED to OHCI */
400 USBH->HcControl |= USBH_HcControl_BLE_Msk;
401 USBH->HcCommandStatus = OHCI_BLF; /* start Control list */
402
403 t0 = USBH->HcFmNumber & 0xffff;
404 while (get_ms_elapsed(t0) < timeout)
405 {
406 if ((USBH->HcInterruptStatus & USBH_HcInterruptStatus_WDH_Msk) &&
407 ((_td[_last_td_idx].hwINFO & 0xf0000000) != 0xf0000000))
408 break;
409 }
410 //printf("0x%x, 0x%x\n", _OHCI_HCCA.done_head, &_td[_last_td_idx]);
411 USBH->HcInterruptStatus = USBH_HcInterruptStatus_WDH_Msk;
412
413 for (i = 0; i <= _last_td_idx; i++)
414 {
415 if (_td[i].hwINFO & 0xf0000000)
416 {
417 usb_dbg_msg("USB xfer error, CC=0x%x [0x%x]\n", (_td[i].hwINFO >> 28), (int)&_td[i]);
418
419 if (ret == USBH_RET_STALL)
420 continue;
421
422 if ((_td[i].hwINFO >> 28) == 0x4)
423 ret = USBH_RET_STALL;
424 else
425 ret = USBH_RET_XFER_ERR;
426 }
427 }
428
429 if (get_ms_elapsed(t0) >= timeout)
430 {
431 usb_dbg_msg("Bulk transfer failed!\n");
432 ret = USBH_RET_XFER_TIMEOUT;
433 goto bulk_exit;
434 }
435
436bulk_exit:
437
438 *toggle = (_ed.hwHeadP >> 1) & 0x1;
439
440 USBH->HcControl &= ~USBH_HcControl_BLE_Msk;
441 USBH->HcBulkHeadED = 0;
442 USBH->HcDoneHead = 0;
443 _OHCI_HCCA.done_head = 0;
444
445 return ret;
446}
447
448
456 int usbh_get_device_descriptor(uint8_t *desc_buff)
457{
458 volatile int i;
459 int ret, len;
460
461 /*------------------------------------------------------------------------------------*/
462 /* Issue GET DESCRIPTOR command to get device descriptor */
463 /*------------------------------------------------------------------------------------*/
464 ret = usbh_drv_ctrl_req(USB_DIR_IN, USB_REQ_GET_DESCRIPTOR, USB_DT_DEVICE << 8, 0, 64,
465 64 /* data len */, desc_buff /* buffer */, 0 /* dir in */);
466 if (ret < 0)
467 return ret;
468
469 len = desc_buff[0];
470 if (len < 0x12) len = 0x12;
471
472 ret = usbh_drv_ctrl_req(USB_DIR_IN, USB_REQ_GET_DESCRIPTOR, USB_DT_DEVICE << 8, 0, len,
473 len /* data len */, desc_buff /* buffer */, 0 /* dir in */);
474 if (ret < 0)
475 return ret;
476 for (i = 0; i < MINISEC_10; i++);
477
478#ifndef __GNUC__
479 dump_device_descriptor((USB_DEV_DESC_T *)desc_buff);
480#endif
481
482 return 0;
483}
484
485
493 int get_config_descriptor(uint8_t *desc_buff)
494{
495 int ret, len;
496
497 /*------------------------------------------------------------------------------------*/
498 /* Issue GET DESCRIPTOR command to get device descriptor */
499 /*------------------------------------------------------------------------------------*/
500
501 ret = usbh_drv_ctrl_req(USB_DIR_IN, USB_REQ_GET_DESCRIPTOR, USB_DT_CONFIG << 8, 0, 8,
502 8 /* data len */, desc_buff /* buffer */, 0 /* dir in */);
503 if (ret < 0)
504 return ret;
505
506 len = ((USB_CONFIG_DESC_T*)desc_buff)->wTotalLength & 0x1ff;
507
508 ret = usbh_drv_ctrl_req(USB_DIR_IN, USB_REQ_GET_DESCRIPTOR, USB_DT_CONFIG << 8, 0, len,
509 len /* data len */, desc_buff /* buffer */, 0 /* dir in */);
510 if (ret < 0)
511 return ret;
512
513#ifndef __GNUC__
514 dump_config_descriptor((USB_CONFIG_DESC_T *)desc_buff);
515#endif
516
517 return 0;
518}
519
520
528 int usbh_set_configuration(int conf_val)
529{
530 return usbh_drv_ctrl_req(0, USB_REQ_SET_CONFIGURATION, conf_val, 0, 0,
531 0 /* data len */, NULL /* buffer */, 1 /* dir out */);
532}
533
534
542 int usbh_clear_halt(uint16_t ep_addr)
543{
544 usb_dbg_msg("Clear endpoint 0x%x halt.\n", ep_addr);
545 return usbh_drv_ctrl_req(0x2, 0x1, 0, ep_addr, 0, 0, NULL, 1);
546}
547
548
550
551 static int do_port_reset(int port)
552{
553 int i, retry;
554
555 for (retry = 1; retry <= 3; retry++)
556 {
557 USBH->HcRhPortStatus[port] = USBH_HcRhPortStatus_PRS_Msk;
558 for (i = 0; i < MINISEC_10*retry; i++)
559 {
560 if (USBH->HcRhPortStatus[port] & USBH_HcRhPortStatus_PES_Msk)
561 break;
562 }
563 if (USBH->HcRhPortStatus[port] & USBH_HcRhPortStatus_PES_Msk)
564 break;
565 }
566 if (retry > 3)
567 {
568 usb_dbg_msg("Port reset failed\n");
569 return USBH_RET_ERR_PORT_RST;
570 }
571
572 usb_dbg_msg("Port reset OK.\n");
573 USBH->HcRhPortStatus[port] = USBH_HcRhPortStatus_PRSC_Msk; /* clear port reset status */
574 return 0;
575}
576
578
579
590 int usbh_probe_port(uint32_t port)
591{
592 uint32_t port_staus;
593 volatile int i, retry;
594 int ret;
595
596 if (port > 1)
597 return USBH_RET_ERR_PARM;
598
599 port_staus = USBH->HcRhPortStatus[port];
600 USBH->HcRhPortStatus[port] = port_staus & 0xffff0000; /* clear port chage status */
601
602 if (!(port_staus & USBH_HcRhPortStatus_CSC_Msk))
603 {
604 /*
605 * No connect change status
606 */
607 if (port_staus & USBH_HcRhPortStatus_CCS_Msk)
608 return USBH_RET_DEV_CONN_KEEP;
609 else
610 return USBH_RET_NO_DEVICE;
611 }
612
613 /*
614 * connect status change
615 */
616 if (!(port_staus & USBH_HcRhPortStatus_CCS_Msk))
617 return USBH_RET_DEV_REMOVED;
618
619 /*
620 * New device connected.
621 */
622 usb_dbg_msg("Device connected.\n");
623
624 /*------------------------------------------------------------------------------------*/
625 /* Doing port reset */
626 /*------------------------------------------------------------------------------------*/
627 if (do_port_reset(port) < 0)
628 return USBH_RET_ERR_PORT_RST;
629
630 if ((USBH->HcRhPortStatus[port] & 0x03) == 0x03)
631 {
632 is_low_speed = (USBH->HcRhPortStatus[port] & USBH_HcRhPortStatus_LSDA_Msk) ? 1 : 0;
633 usb_dbg_msg("USB device enabled (%s).\n", is_low_speed ? "Low-speed" : "Full-speed");
634 }
635 else
636 {
637 usb_dbg_msg("Failed to enable USB device!!\n");
638 return USBH_RET_ERR_PORT_ENABLE;
639 }
640
641 for (i = 0; i < MINISEC_10; i++);
642
643 DEV_ADDR = 1;
644
645 /*------------------------------------------------------------------------------------*/
646 /* Issue SET ADDRESS command */
647 /*------------------------------------------------------------------------------------*/
648 for (retry = 0; retry < 3; retry++)
649 {
650 ret = usbh_drv_ctrl_req(0, USB_REQ_SET_ADDRESS, DEV_ADDR, 0, 0,
651 0 /* data len */, NULL /* buffer */, 1 /* dir out */);
652 if (ret == 0)
653 break;
654
655 do_port_reset(port);
656
657 for (i = 0; i < MINISEC_100; i++);
658 }
659 if (ret < 0)
660 {
661 usb_dbg_msg("Failed to set device address!!\n");
662 return ret;
663 }
664
665 ret = usbh_get_device_descriptor(_transfer_buffer);
666 if (ret < 0)
667 {
668 usb_dbg_msg("GET Device Descriptor command failed!!\n");
669 return ret;
670 }
671 return ret;
672}
673
675
676 static int ohci_reset(void)
677{
678 volatile int t0;
679
680 /* Disable HC interrupts */
681 USBH->HcInterruptDisable = OHCI_INTR_MIE;
682
683 /* HC Reset requires max 10 ms delay */
684 USBH->HcControl = 0;
685 USBH->HcCommandStatus = OHCI_HCR;
686
687 for (t0 = 0; t0 < MINISEC_10; t0++)
688 {
689 if ((USBH->HcCommandStatus & OHCI_HCR) == 0)
690 break;
691 }
692 if (t0 >= MINISEC_10)
693 {
694 usb_dbg_msg("Error! - USB OHCI reset timed out!\n");
695 return -1;
696 }
697
698 USBH->HcRhStatus = USBH_HcRhStatus_OCI_Msk | USBH_HcRhStatus_LPS_Msk;
699
700 USBH->HcControl = OHCI_USB_RESET;
701
702 for (t0 = 0; t0 < MINISEC_10; t0++)
703 {
704 if ((USBH->HcCommandStatus & OHCI_HCR) == 0)
705 break;
706 }
707 if (t0 >= MINISEC_10)
708 {
709 usb_dbg_msg("Error! - USB HC reset timed out!\n");
710 return -1;
711 }
712 return 0;
713}
714
715
716 static int ohci_start()
717{
718 uint32_t fminterval;
719 volatile int i;
720
721 for (i = 0; i < NUM_INTS; i++)
722 _OHCI_HCCA.int_table[i] = 0;
723
724 /* Tell the controller where the control and bulk lists are
725 * The lists are empty now. */
726 USBH->HcControlHeadED = 0; /* control ED list head */
727 USBH->HcBulkHeadED = 0; /* bulk ED list head */
728
729 USBH->HcHCCA = (uint32_t)&_OHCI_HCCA; /* HCCA area */
730
731 /* periodic start 90% of frame interval */
732 fminterval = 0x2edf; /* 11,999 */
733 USBH->HcPeriodicStart = (fminterval * 9) / 10;
734
735 /* set FSLargestDataPacket, 10,104 for 0x2edf frame interval */
736 fminterval |= ((((fminterval - 210) * 6) / 7) << 16);
737 USBH->HcFmInterval = fminterval;
738
739 USBH->HcLSThreshold = 0x628;
740
741 /* start controller operations */
742 USBH->HcControl = 0x3 | OHCI_USB_OPER;
743
744 /* Choose the interrupts we care about now, others later on demand */
745 //mask = OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_WDH;
746 //USBH->HcIntEn = mask;
747 //USBH->HcInterruptStatus = mask;
748
749 /* NUC400 OCHI use no power switching mode */
750 USBH->HcRhDescriptorA = (USBH->HcRhDescriptorA | USBH_HcRhDescriptorA_NPS_Msk) & ~USBH_HcRhDescriptorA_PSM_Msk;
751 USBH->HcRhStatus = USBH_HcRhStatus_LPSC_Msk;
752
753 /* POTPGT delay is bits 24-31, in 20 ms units. */
754 for (i = 0; i < MINISEC_10 * 2; i++);
755
756 return 0;
757}
758
760
767 int usbh_init(void)
768{
769 volatile int loop;
770
771 USBH->HcMiscControl &= ~0x8; /* over current setting */
772
773 if (ohci_reset() < 0)
774 {
775 usb_dbg_msg("OHCI reset failed!!\n");
776 return USBH_RET_INIT;
777 }
778
779 if (ohci_start() < 0)
780 {
781 usb_dbg_msg("OHCI reset failed!!\n");
782 return USBH_RET_INIT;
783 }
784
785 for (loop = 0; loop < 0x100000; loop++);
786
787 return USBH_RET_NO_ERR;
788}
789 /* end of group NUC472_442_LWHCD_EXPORTED_FUNCTIONS */
791 /* end of group NUC472_442_LWHCD_Driver */
793 /* end of group NUC472_442_Device_Driver */
795
796/*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/
797
798
799
__attribute__
void *__dso_handle __attribute__((weak))
Definition: _syscalls.c:35
NUC472_442.h
NUC472/NUC442 peripheral access layer header file. This file contains all the peripheral register's d...
USBH_HcRhDescriptorA_NPS_Msk
#define USBH_HcRhDescriptorA_NPS_Msk
Definition: NUC472_442.h:26845
USBH_HcRhStatus_LPSC_Msk
#define USBH_HcRhStatus_LPSC_Msk
Definition: NUC472_442.h:26872
USBH_HcRhPortStatus_CSC_Msk
#define USBH_HcRhPortStatus_CSC_Msk
Definition: NUC472_442.h:26902
USBH_HcRhPortStatus_PRSC_Msk
#define USBH_HcRhPortStatus_PRSC_Msk
Definition: NUC472_442.h:26914
USBH_HcRhDescriptorA_PSM_Msk
#define USBH_HcRhDescriptorA_PSM_Msk
Definition: NUC472_442.h:26842
USBH_HcRhPortStatus_LSDA_Msk
#define USBH_HcRhPortStatus_LSDA_Msk
Definition: NUC472_442.h:26899
USBH_HcControl_BLE_Msk
#define USBH_HcControl_BLE_Msk
Definition: NUC472_442.h:26716
USBH_HcRhStatus_LPS_Msk
#define USBH_HcRhStatus_LPS_Msk
Definition: NUC472_442.h:26863
USBH_HcRhPortStatus_PRS_Msk
#define USBH_HcRhPortStatus_PRS_Msk
Definition: NUC472_442.h:26893
USBH_HcRhStatus_OCI_Msk
#define USBH_HcRhStatus_OCI_Msk
Definition: NUC472_442.h:26866
USBH_HcControl_CLE_Msk
#define USBH_HcControl_CLE_Msk
Definition: NUC472_442.h:26713
USBH_HcRhPortStatus_PES_Msk
#define USBH_HcRhPortStatus_PES_Msk
Definition: NUC472_442.h:26884
USBH_HcRhPortStatus_CCS_Msk
#define USBH_HcRhPortStatus_CCS_Msk
Definition: NUC472_442.h:26881
USBH_HcInterruptStatus_WDH_Msk
#define USBH_HcInterruptStatus_WDH_Msk
Definition: NUC472_442.h:26737
USBH_RET_XFER_ERR
#define USBH_RET_XFER_ERR
Definition: lw_usbh.h:44
USBH_RET_INIT
#define USBH_RET_INIT
Definition: lw_usbh.h:38
USBH_RET_DEV_REMOVED
#define USBH_RET_DEV_REMOVED
Definition: lw_usbh.h:41
USBH_RET_XFER_TIMEOUT
#define USBH_RET_XFER_TIMEOUT
Definition: lw_usbh.h:42
USBH_RET_STALL
#define USBH_RET_STALL
Definition: lw_usbh.h:43
USBH_RET_ERR_PORT_ENABLE
#define USBH_RET_ERR_PORT_ENABLE
Definition: lw_usbh.h:50
USBH_RET_ERR_PORT_RST
#define USBH_RET_ERR_PORT_RST
Definition: lw_usbh.h:49
USBH_RET_DEV_CONN_KEEP
#define USBH_RET_DEV_CONN_KEEP
Definition: lw_usbh.h:40
USBH_RET_NO_ERR
#define USBH_RET_NO_ERR
Definition: lw_usbh.h:36
USBH_INTR_BUFF_SIZE
#define USBH_INTR_BUFF_SIZE
Definition: lw_usbh.h:23
USBH_RET_ERR_PARM
#define USBH_RET_ERR_PARM
Definition: lw_usbh.h:37
USBH_RET_NO_DEVICE
#define USBH_RET_NO_DEVICE
Definition: lw_usbh.h:39
usbh_init
int usbh_init(void)
Initialized USB host controller driver.
Definition: lw_usbh.c:767
usbh_probe_port
int usbh_probe_port(uint32_t port)
Probe USB root-hub port connect/disconnect status. A newly connected device will be initialized in th...
Definition: lw_usbh.c:590
usbh_set_configuration
int usbh_set_configuration(int conf_val)
Issue a standard request SET_CONFIGURATION to USB device.
Definition: lw_usbh.c:528
usbh_drv_ctrl_req
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.
Definition: lw_usbh.c:305
usbh_get_device_descriptor
int usbh_get_device_descriptor(uint8_t *desc_buff)
Get device descriptor from the USB device.
Definition: lw_usbh.c:456
usbh_clear_halt
int usbh_clear_halt(uint16_t ep_addr)
Issue a standard request SET_FEATURE to clear USB device endpoint halt state.
Definition: lw_usbh.c:542
usbh_drv_bulk_xfer
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.
Definition: lw_usbh.c:389
get_config_descriptor
int get_config_descriptor(uint8_t *desc_buff)
Get configuration descriptor from the USB device.
Definition: lw_usbh.c:493
USBH
#define USBH
Definition: NUC472_442.h:28818
USB_IF_DESC_T
USB_IF_DESC_T
Definition: usbh_core.h:335
DEV_REQ_T
DEV_REQ_T
Definition: usbh_core.h:190
USB_CONFIG_DESC_T
USB_CONFIG_DESC_T
Definition: usbh_core.h:366
USB_DEV_DESC_T
USB_DEV_DESC_T
Definition: usbh_core.h:270
USB_EP_DESC_T
USB_EP_DESC_T
Definition: usbh_core.h:300
NULL
#define NULL
NULL pointer.
Definition: NUC472_442.h:29018
lw_usbh.h
value
return value
Definition: semihosting.h:98
usb.h