blob: 9cf99126ebd1fbb87caebb4b80e6b55cc97cb13f (
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
/*
* SPDX-FileCopyrightText: Copyright (c) 2024, Brent Kowal (Analog Devices, Inc)
* SPDX-FileCopyrightText: Copyright (c) 2024 Ha Thach (tinyusb.org)
* SPDX-License-Identifier: MIT
*
* This file is part of the TinyUSB stack.
*/
#ifndef TUSB_MUSB_MAX32_H_
#define TUSB_MUSB_MAX32_H_
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wredundant-decls"
#endif
#include "mxc_device.h"
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
#include "usbhs_regs.h"
#define MUSB_CFG_SHARED_FIFO 1 // shared FIFO for TX and RX endpoints
#define MUSB_CFG_DYNAMIC_FIFO 0 // dynamic EP FIFO sizing
#define MUSB_INTR_EP_TX_RX_SWAP 0
static const uintptr_t MUSB_BASES[] = { MXC_BASE_USBHS };
#if CFG_TUD_ENABLED
#define USBHS_M31_CLOCK_RECOVERY
// Mapping of IRQ numbers to port. Currently just 1.
static const IRQn_Type musb_irqs[] = {
USB_IRQn
};
TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_enable(uint8_t rhport) {
NVIC_EnableIRQ(musb_irqs[rhport]);
}
TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_disable(uint8_t rhport) {
NVIC_DisableIRQ(musb_irqs[rhport]);
}
TU_ATTR_ALWAYS_INLINE static inline unsigned musb_dcd_get_int_enable(uint8_t rhport) {
#ifdef NVIC_GetEnableIRQ // only defined in CMSIS 5
return NVIC_GetEnableIRQ(musb_irqs[rhport]);
#else
uint32_t IRQn = (uint32_t) musb_irqs[rhport];
return ((NVIC->ISER[IRQn >> 5UL] & (1UL << (IRQn & 0x1FUL))) != 0UL) ? 1UL : 0UL;
#endif
}
TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_clear(uint8_t rhport) {
NVIC_ClearPendingIRQ(musb_irqs[rhport]);
}
static inline void musb_dcd_int_handler_enter(uint8_t rhport) {
mxc_usbhs_regs_t* hs_phy = MXC_USBHS;
uint32_t mxm_int, mxm_int_en, mxm_is;
//Handle PHY specific events
mxm_int = hs_phy->mxm_int;
mxm_int_en = hs_phy->mxm_int_en;
mxm_is = mxm_int & mxm_int_en;
hs_phy->mxm_int = mxm_is;
if (mxm_is & MXC_F_USBHS_MXM_INT_NOVBUS) {
dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true);
}
}
static inline void musb_dcd_phy_init(uint8_t rhport) {
(void) rhport;
mxc_usbhs_regs_t* hs_phy = MXC_USBHS;
// Interrupt for VBUS disconnect
hs_phy->mxm_int_en |= MXC_F_USBHS_MXM_INT_EN_NOVBUS;
musb_dcd_int_clear(rhport);
// Unsuspend the MAC
hs_phy->mxm_suspend = 0;
// Configure PHY
hs_phy->m31_phy_xcfgi_31_0 = (0x1 << 3) | (0x1 << 11);
hs_phy->m31_phy_xcfgi_63_32 = 0;
hs_phy->m31_phy_xcfgi_95_64 = 0x1 << (72 - 64);
hs_phy->m31_phy_xcfgi_127_96 = 0;
#ifdef USBHS_M31_CLOCK_RECOVERY
hs_phy->m31_phy_noncry_rstb = 1;
hs_phy->m31_phy_noncry_en = 1;
hs_phy->m31_phy_outclksel = 0;
hs_phy->m31_phy_coreclkin = 0;
hs_phy->m31_phy_xtlsel = 2; /* Select 25 MHz clock */
#else
hs_phy->m31_phy_noncry_rstb = 0;
hs_phy->m31_phy_noncry_en = 0;
hs_phy->m31_phy_outclksel = 1;
hs_phy->m31_phy_coreclkin = 1;
hs_phy->m31_phy_xtlsel = 3; /* Select 30 MHz clock */
#endif
hs_phy->m31_phy_pll_en = 1;
hs_phy->m31_phy_oscouten = 1;
/* Reset PHY */
hs_phy->m31_phy_ponrst = 0;
hs_phy->m31_phy_ponrst = 1;
}
// static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in, unsigned mps) {
// (void) mps;
//
// //Most likely the caller has already grabbed the right register block. But
// //as a precaution save and restore the register bank anyways
// unsigned saved_index = musb_periph_inst[rhport]->index;
//
// musb_periph_inst[rhport]->index = epnum;
//
// //Disable double buffering
// if (dir_in) {
// musb_periph_inst[rhport]->incsru |= (MXC_F_USBHS_INCSRU_DPKTBUFDIS | MXC_F_USBHS_INCSRU_MODE);
// } else {
// musb_periph_inst[rhport]->outcsru |= (MXC_F_USBHS_OUTCSRU_DPKTBUFDIS);
// }
//
// musb_periph_inst[rhport]->index = saved_index;
// }
#endif // CFG_TUD_ENABLED
#ifdef __cplusplus
}
#endif
#endif // TUSB_MUSB_MAX32_H_
|