summaryrefslogtreecommitdiff
path: root/port/ehci/usb_glue_ma35d0.c
blob: 3e03bbd84c39ddbe4e3fe5e99e2b0082ca9b0a6d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/**************************************************************************/ /**
*
* @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date            Author           Notes
* 2023-8-8        Wayne            First version
*
******************************************************************************/
#include "rtthread.h"

#include "NuMicro.h"
#include "rthw.h"
#include "drv_sys.h"

#define LOG_TAG "drv.cherry"
#define DBG_ENABLE
#define DBG_SECTION_NAME LOG_TAG
#define DBG_LEVEL        DBG_LOG
#define DBG_COLOR
#include <rtdbg.h>

#if defined(PKG_CHERRYUSB_HOST)

#include "usbh_core.h"

static void nu_echi_isr(int vector, void *param)
{
    uint8_t busid = (uint8_t)param;
    extern void USBH_IRQHandler(uint8_t busid);
    USBH_IRQHandler(busid);
}

static void nu_ochi_isr(int vector, void *param)
{
}

void usb_hc_low_level_init(struct usbh_bus *bus)
{
    int timeout = 100;

    if (bus->hcd.reg_base == HSUSBH0_BASE) {
        /* Enable USBH clock */
        CLK_EnableModuleClock(HUSBH0_MODULE);
        SYS_ResetModule(HSUSBH0_RST);

        /* Clock engine clock Configuration */
        SYS->USBPMISCR &= ~(SYS_USBPMISCR_PHY0POR_Msk | SYS_USBPMISCR_PHY0COMN_Msk);
        rt_thread_mdelay(20);
        SYS->USBPMISCR |= SYS_USBPMISCR_PHY0SUSPEND_Msk | SYS_USBPMISCR_PHY0COMN_Msk;

        /* set UHOVRCURH(SYS_MISCFCR0[12]) 1 => USBH Host over-current detect is high-active */
        /*                                 0 => USBH Host over-current detect is low-active  */
        //SYS->MISCFCR0 |= SYS_MISCFCR0_UHOVRCURH_Msk;
        SYS->MISCFCR0 &= ~SYS_MISCFCR0_UHOVRCURH_Msk;
        while (1) {
            rt_thread_mdelay(1);
            if (SYS->USBPMISCR & SYS_USBPMISCR_PHY0HSTCKSTB_Msk)
                break; /* both USB PHY0 and PHY1 clock 60MHz UTMI clock stable */

            timeout--;
            if (timeout == 0) {
                rt_kprintf("USB PHY reset failed. USBPMISCR = 0x%08x\n", SYS->USBPMISCR);
                return;
            }
        }

        /* Register interrupt service routine. */
        rt_hw_interrupt_install(HSUSBH0_IRQn, nu_echi_isr, (void *)bus->hcd.hcd_id, "ehci0");

        /* Enable interrupt */
        rt_hw_interrupt_umask(HSUSBH0_IRQn);
    } else if (bus->hcd.reg_base == HSUSBH1_BASE) {
        /* Enable USBH clock */
        CLK_EnableModuleClock(HUSBH1_MODULE);
        SYS_ResetModule(HSUSBH1_RST);

        /* Clock engine clock Configuration */
        SYS->USBPMISCR &= ~(SYS_USBPMISCR_PHY1POR_Msk | SYS_USBPMISCR_PHY1COMN_Msk);
        rt_thread_mdelay(20);
        SYS->USBPMISCR |= SYS_USBPMISCR_PHY1SUSPEND_Msk | SYS_USBPMISCR_PHY1COMN_Msk;

        /* set UHOVRCURH(SYS_MISCFCR0[12]) 1 => USBH Host over-current detect is high-active */
        /*                                 0 => USBH Host over-current detect is low-active  */
        //SYS->MISCFCR0 |= SYS_MISCFCR0_UHOVRCURH_Msk;
        SYS->MISCFCR0 &= ~SYS_MISCFCR0_UHOVRCURH_Msk;
        while (1) {
            rt_thread_mdelay(1);
            if (SYS->USBPMISCR & SYS_USBPMISCR_PHY1HSTCKSTB_Msk)
                break; /* both USB PHY0 and PHY1 clock 60MHz UTMI clock stable */

            timeout--;
            if (timeout == 0) {
                rt_kprintf("USB PHY reset failed. USBPMISCR = 0x%08x\n", SYS->USBPMISCR);
                return;
            }
        }
        /* Register interrupt service routine. */
        rt_hw_interrupt_install(HSUSBH1_IRQn, nu_echi_isr, (void *)bus->hcd.hcd_id, "ehci1");

        /* Enable interrupt */
        rt_hw_interrupt_umask(HSUSBH1_IRQn);
    }
}

void usb_hc_low_level2_init(struct usbh_bus *bus)
{
}

uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port)
{
    return USB_SPEED_HIGH;
}

#endif