mikroSDK Reference Manual
dwc2_stm32.h
1/*
2 * The MIT License (MIT)
3 *
4 * Copyright (c) 2021, Ha Thach (tinyusb.org)
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 *
24 * This file is part of the TinyUSB stack.
25 */
26
27#ifndef _DWC2_STM32_H_
28#define _DWC2_STM32_H_
29
30#ifdef __cplusplus
31 extern "C" {
32#endif
33
34#ifdef __PROJECT_MIKROSDK_MIKROE__
35// Note: Added for MikroE implementation.
36#include "usb_hw.h"
37#endif
38
39// EP_MAX : Max number of bi-directional endpoints including EP0
40// EP_FIFO_SIZE : Size of dedicated USB SRAM
41#if CFG_TUSB_MCU == OPT_MCU_STM32F1
42 #include "stm32f1xx.h"
43 #define EP_MAX_FS 4
44 #define EP_FIFO_SIZE_FS 1280
45
46#elif CFG_TUSB_MCU == OPT_MCU_STM32F2
47 #include "stm32f2xx.h"
48 #define EP_MAX_FS USB_OTG_FS_MAX_IN_ENDPOINTS
49 #define EP_FIFO_SIZE_FS USB_OTG_FS_TOTAL_FIFO_SIZE
50
51 #define EP_MAX_HS USB_OTG_HS_MAX_IN_ENDPOINTS
52 #define EP_FIFO_SIZE_HS USB_OTG_HS_TOTAL_FIFO_SIZE
53
54#elif CFG_TUSB_MCU == OPT_MCU_STM32F4
55 #include "stm32f4xx.h"
56 #define EP_MAX_FS USB_OTG_FS_MAX_IN_ENDPOINTS
57 #define EP_FIFO_SIZE_FS USB_OTG_FS_TOTAL_FIFO_SIZE
58
59 #define EP_MAX_HS USB_OTG_HS_MAX_IN_ENDPOINTS
60 #define EP_FIFO_SIZE_HS USB_OTG_HS_TOTAL_FIFO_SIZE
61
62#elif CFG_TUSB_MCU == OPT_MCU_STM32H7
63 #include "stm32h7xx.h"
64 #define EP_MAX_FS 9
65 #define EP_FIFO_SIZE_FS 4096
66
67 #define EP_MAX_HS 9
68 #define EP_FIFO_SIZE_HS 4096
69
70 // NOTE: H7 with only 1 USB port: H72x / H73x / H7Ax / H7Bx
71 // USB_OTG_FS_PERIPH_BASE and OTG_FS_IRQn not defined
72 #if (! defined USB2_OTG_FS)
73 #define USB_OTG_FS_PERIPH_BASE USB1_OTG_HS_PERIPH_BASE
74 #define OTG_FS_IRQn OTG_HS_IRQn
75 #endif
76
77#elif CFG_TUSB_MCU == OPT_MCU_STM32F7
78 #include "stm32f7xx.h"
79 #define EP_MAX_FS 6
80 #define EP_FIFO_SIZE_FS 1280
81
82 #define EP_MAX_HS 9
83 #define EP_FIFO_SIZE_HS 4096
84
85#elif CFG_TUSB_MCU == OPT_MCU_STM32L4
86 #ifndef __PROJECT_MIKROSDK_MIKROE__
87 // Note: Changed for MikroE implementation.
88 #include "stm32l4xx.h"
89 #endif
90 #define EP_MAX_FS 6
91 #define EP_FIFO_SIZE_FS 1280
92
93#elif CFG_TUSB_MCU == OPT_MCU_STM32U5
94 #include "stm32u5xx.h"
95 #define USB_OTG_FS_PERIPH_BASE USB_OTG_FS_BASE
96 #define EP_MAX_FS 6
97 #define EP_FIFO_SIZE_FS 1280
98
99#else
100 #error "Unsupported MCUs"
101#endif
102
103// OTG HS always has higher number of endpoints than FS
104#ifdef USB_OTG_HS_PERIPH_BASE
105 #define DWC2_EP_MAX EP_MAX_HS
106#else
107 #define DWC2_EP_MAX EP_MAX_FS
108#endif
109
110// On STM32 for consistency we associate
111// - Port0 to OTG_FS, and Port1 to OTG_HS
112static const dwc2_controller_t _dwc2_controller[] =
113{
114#ifdef USB_OTG_FS_PERIPH_BASE
115 { .reg_base = USB_OTG_FS_PERIPH_BASE, .irqnum = OTG_FS_IRQn, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS },
116#endif
117
118#ifdef USB_OTG_HS_PERIPH_BASE
119 { .reg_base = USB_OTG_HS_PERIPH_BASE, .irqnum = OTG_HS_IRQn, .ep_count = EP_MAX_HS, .ep_fifo_size = EP_FIFO_SIZE_HS },
120#endif
121};
122
123//--------------------------------------------------------------------+
124//
125//--------------------------------------------------------------------+
126
127// SystemCoreClock is already included by family header
128// extern uint32_t SystemCoreClock;
129
130TU_ATTR_ALWAYS_INLINE
131static inline void dwc2_dcd_int_enable(uint8_t rhport)
132{
133 NVIC_EnableIRQ((IRQn_Type)_dwc2_controller[rhport].irqnum);
134}
135
136TU_ATTR_ALWAYS_INLINE
137static inline void dwc2_dcd_int_disable (uint8_t rhport)
138{
139 NVIC_DisableIRQ((IRQn_Type)_dwc2_controller[rhport].irqnum);
140}
141
142TU_ATTR_ALWAYS_INLINE
143static inline void dwc2_remote_wakeup_delay(void)
144{
145 // try to delay for 1 ms
146 uint32_t count = SystemCoreClock / 1000;
147 while ( count-- ) __NOP();
148}
149
150// MCU specific PHY init, called BEFORE core reset
151static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type)
152{
153 if ( hs_phy_type == HS_PHY_TYPE_NONE )
154 {
155 // Enable on-chip FS PHY
156 dwc2->stm32_gccfg |= STM32_GCCFG_PWRDWN;
157 }else
158 {
159 // Disable FS PHY
160 dwc2->stm32_gccfg &= ~STM32_GCCFG_PWRDWN;
161
162 // Enable on-chip HS PHY
163 if (hs_phy_type == HS_PHY_TYPE_UTMI || hs_phy_type == HS_PHY_TYPE_UTMI_ULPI)
164 {
165#ifdef USB_HS_PHYC
166 // Enable UTMI HS PHY
167 dwc2->stm32_gccfg |= STM32_GCCFG_PHYHSEN;
168
169 // Enable LDO
170 USB_HS_PHYC->USB_HS_PHYC_LDO |= USB_HS_PHYC_LDO_ENABLE;
171
172 // Wait until LDO ready
173 while ( 0 == (USB_HS_PHYC->USB_HS_PHYC_LDO & USB_HS_PHYC_LDO_STATUS) ) {}
174
175 uint32_t phyc_pll = 0;
176
177 // TODO Try to get HSE_VALUE from registers instead of depending CFLAGS
178 switch ( HSE_VALUE )
179 {
180 case 12000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_12MHZ ; break;
181 case 12500000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_12_5MHZ ; break;
182 case 16000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_16MHZ ; break;
183 case 24000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_24MHZ ; break;
184 case 25000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_25MHZ ; break;
185 case 32000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_Msk ; break; // Value not defined in header
186 default:
187 TU_ASSERT(false, );
188 }
189 USB_HS_PHYC->USB_HS_PHYC_PLL = phyc_pll;
190
191 // Control the tuning interface of the High Speed PHY
192 // Use magic value (USB_HS_PHYC_TUNE_VALUE) from ST driver for F7
193 USB_HS_PHYC->USB_HS_PHYC_TUNE |= 0x00000F13U;
194
195 // Enable PLL internal PHY
196 USB_HS_PHYC->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL_PLLEN;
197#endif
198 }
199 }
200}
201
202// MCU specific PHY update, it is called AFTER init() and core reset
203static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type)
204{
205 // used to set turnaround time for fullspeed, nothing to do in highspeed mode
206 if ( hs_phy_type == HS_PHY_TYPE_NONE )
207 {
208 // Turnaround timeout depends on the AHB clock dictated by STM32 Reference Manual
209 uint32_t turnaround;
210
211 if ( SystemCoreClock >= 32000000u )
212 turnaround = 0x6u;
213 else if ( SystemCoreClock >= 27500000u )
214 turnaround = 0x7u;
215 else if ( SystemCoreClock >= 24000000u )
216 turnaround = 0x8u;
217 else if ( SystemCoreClock >= 21800000u )
218 turnaround = 0x9u;
219 else if ( SystemCoreClock >= 20000000u )
220 turnaround = 0xAu;
221 else if ( SystemCoreClock >= 18500000u )
222 turnaround = 0xBu;
223 else if ( SystemCoreClock >= 17200000u )
224 turnaround = 0xCu;
225 else if ( SystemCoreClock >= 16000000u )
226 turnaround = 0xDu;
227 else if ( SystemCoreClock >= 15000000u )
228 turnaround = 0xEu;
229 else
230 turnaround = 0xFu;
231
232 dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_TRDT_Msk) | (turnaround << GUSBCFG_TRDT_Pos);
233 }
234}
235
236#ifdef __cplusplus
237}
238#endif
239
240#endif /* _DWC2_STM32_H_ */
#define __NOP()
No Operation.
Definition cmsis_gcc.h:903
IRQn_Type
STM32F10x Interrupt Number Definition, according to the selected device in Library_configuration_sect...
Definition stm32f107xc.h:70
@ OTG_FS_IRQn
Definition stm32f107xc.h:143
@ OTG_HS_IRQn
Definition stm32f207xx.h:155
CMSIS STM32F1xx Device Peripheral Access Layer Header File.
#define HSE_VALUE
Adjust the value of External High Speed oscillator (HSE) used in your application....
Definition stm32f1xx_hal_conf.h:95
CMSIS STM32F2xx Device Peripheral Access Layer Header File.
CMSIS STM32F4xx Device Peripheral Access Layer Header File.
CMSIS STM32F7xx Device Peripheral Access Layer Header File.
CMSIS STM32H7xx Device Peripheral Access Layer Header File.
Definition dwc2_type.h:28
Definition dwc2_type.h:191