1 /**************************************************************************/ /**
2 *
3 * @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Change Logs:
8 * Date            Author           Notes
9 * 2023-8-8        Wayne            First version
10 *
11 ******************************************************************************/
12 #include "rtthread.h"
13 
14 #include "NuMicro.h"
15 #include "rthw.h"
16 #include "drv_sys.h"
17 
18 #define LOG_TAG "drv.cherry"
19 #define DBG_ENABLE
20 #define DBG_SECTION_NAME LOG_TAG
21 #define DBG_LEVEL        DBG_LOG
22 #define DBG_COLOR
23 #include <rtdbg.h>
24 
25 #if defined(PKG_CHERRYUSB_HOST)
26 
27 #include "usbh_core.h"
28 
nu_echi_isr(int vector,void * param)29 static void nu_echi_isr(int vector, void *param)
30 {
31     uint8_t busid = (uint8_t)param;
32     extern void USBH_IRQHandler(uint8_t busid);
33     USBH_IRQHandler(busid);
34 }
35 
nu_ochi_isr(int vector,void * param)36 static void nu_ochi_isr(int vector, void *param)
37 {
38 }
39 
usb_hc_low_level_init(struct usbh_bus * bus)40 void usb_hc_low_level_init(struct usbh_bus *bus)
41 {
42     int timeout = 100;
43 
44     if (bus->hcd.reg_base == HSUSBH0_BASE) {
45         /* Enable USBH clock */
46         CLK_EnableModuleClock(HUSBH0_MODULE);
47         SYS_ResetModule(HSUSBH0_RST);
48 
49         /* Clock engine clock Configuration */
50         SYS->USBPMISCR &= ~(SYS_USBPMISCR_PHY0POR_Msk | SYS_USBPMISCR_PHY0COMN_Msk);
51         rt_thread_mdelay(20);
52         SYS->USBPMISCR |= SYS_USBPMISCR_PHY0SUSPEND_Msk | SYS_USBPMISCR_PHY0COMN_Msk;
53 
54         /* set UHOVRCURH(SYS_MISCFCR0[12]) 1 => USBH Host over-current detect is high-active */
55         /*                                 0 => USBH Host over-current detect is low-active  */
56         //SYS->MISCFCR0 |= SYS_MISCFCR0_UHOVRCURH_Msk;
57         SYS->MISCFCR0 &= ~SYS_MISCFCR0_UHOVRCURH_Msk;
58         while (1) {
59             rt_thread_mdelay(1);
60             if (SYS->USBPMISCR & SYS_USBPMISCR_PHY0HSTCKSTB_Msk)
61                 break; /* both USB PHY0 and PHY1 clock 60MHz UTMI clock stable */
62 
63             timeout--;
64             if (timeout == 0) {
65                 rt_kprintf("USB PHY reset failed. USBPMISCR = 0x%08x\n", SYS->USBPMISCR);
66                 return;
67             }
68         }
69 
70         /* Register interrupt service routine. */
71         rt_hw_interrupt_install(HSUSBH0_IRQn, nu_echi_isr, (void *)bus->hcd.hcd_id, "ehci0");
72 
73         /* Enable interrupt */
74         rt_hw_interrupt_umask(HSUSBH0_IRQn);
75     } else if (bus->hcd.reg_base == HSUSBH1_BASE) {
76         /* Enable USBH clock */
77         CLK_EnableModuleClock(HUSBH1_MODULE);
78         SYS_ResetModule(HSUSBH1_RST);
79 
80         /* Clock engine clock Configuration */
81         SYS->USBPMISCR &= ~(SYS_USBPMISCR_PHY1POR_Msk | SYS_USBPMISCR_PHY1COMN_Msk);
82         rt_thread_mdelay(20);
83         SYS->USBPMISCR |= SYS_USBPMISCR_PHY1SUSPEND_Msk | SYS_USBPMISCR_PHY1COMN_Msk;
84 
85         /* set UHOVRCURH(SYS_MISCFCR0[12]) 1 => USBH Host over-current detect is high-active */
86         /*                                 0 => USBH Host over-current detect is low-active  */
87         //SYS->MISCFCR0 |= SYS_MISCFCR0_UHOVRCURH_Msk;
88         SYS->MISCFCR0 &= ~SYS_MISCFCR0_UHOVRCURH_Msk;
89         while (1) {
90             rt_thread_mdelay(1);
91             if (SYS->USBPMISCR & SYS_USBPMISCR_PHY1HSTCKSTB_Msk)
92                 break; /* both USB PHY0 and PHY1 clock 60MHz UTMI clock stable */
93 
94             timeout--;
95             if (timeout == 0) {
96                 rt_kprintf("USB PHY reset failed. USBPMISCR = 0x%08x\n", SYS->USBPMISCR);
97                 return;
98             }
99         }
100         /* Register interrupt service routine. */
101         rt_hw_interrupt_install(HSUSBH1_IRQn, nu_echi_isr, (void *)bus->hcd.hcd_id, "ehci1");
102 
103         /* Enable interrupt */
104         rt_hw_interrupt_umask(HSUSBH1_IRQn);
105     }
106 }
107 
usb_hc_low_level2_init(struct usbh_bus * bus)108 void usb_hc_low_level2_init(struct usbh_bus *bus)
109 {
110 }
111 
usbh_get_port_speed(struct usbh_bus * bus,const uint8_t port)112 uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port)
113 {
114     return USB_SPEED_HIGH;
115 }
116 
117 #endif
118