1 /*
2 * Copyright (c) 2006-2025, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2024-07-09 QT-one first version
9 */
10
11 #include "usb_port.h"
12
13 /* Global variables ----------------------------------------------------------------------------------------*/
14 USBDCore_TypeDef *gUSBCore;
15 USBD_Driver_TypeDef gUSBDriver;
16 u32 gIsLowPowerAllowed = TRUE;
17
18 #if (LIBCFG_CKCU_USB_PLL)
19 /*********************************************************************************************************//**
20 * @brief Configure USB PLL
21 * @retval None
22 ************************************************************************************************************/
USBPLL_Configuration(void)23 static void USBPLL_Configuration(void)
24 {
25 {
26 /* USB PLL configuration */
27
28 /* !!! NOTICE !!!
29 Notice that the local variable (structure) did not have an initial value.
30 Please confirm that there are no missing members in the parameter settings below in this function.
31 */
32 CKCU_PLLInitTypeDef PLLInit;
33
34 PLLInit.ClockSource = CKCU_PLLSRC_HSE; // CKCU_PLLSRC_HSE or CKCU_PLLSRC_HSI
35 #if (LIBCFG_CKCU_USB_PLL_96M)
36 PLLInit.CFG = CKCU_USBPLL_8M_96M;
37 #else
38 PLLInit.CFG = CKCU_USBPLL_8M_48M;
39 #endif
40 PLLInit.BYPASSCmd = DISABLE;
41 CKCU_USBPLLInit(&PLLInit);
42 }
43
44 CKCU_USBPLLCmd(ENABLE);
45
46 while (CKCU_GetClockReadyStatus(CKCU_FLAG_USBPLLRDY) == RESET);
47 CKCU_USBClockConfig(CKCU_CKUSBPLL);
48 }
49 #endif
50
51 #if (LIBCFG_PWRCU_VREG)
52 /*********************************************************************************************************//**
53 * @brief Configure USB Voltage
54 * @retval None
55 ************************************************************************************************************/
USBVRG_Configuration(void)56 static void USBVRG_Configuration(void)
57 {
58 CKCU_PeripClockConfig_TypeDef CKCUClock = {{ 0 }};
59 CKCUClock.Bit.BKP = 1;
60 CKCU_PeripClockConfig(CKCUClock, ENABLE);
61
62 PWRCU_SetVREG(PWRCU_VREG_3V3);
63
64 /* !!! NOTICE !!!
65 USB LDO should be enabled (PWRCU_VREG_ENABLE) if the MCU VDD > 3.6 V.
66 */
67 PWRCU_VREGConfig(PWRCU_VREG_BYPASS);
68 }
69 #endif
70
71 #define REMOTE_WAKEUP (0)
72 /*********************************************************************************************************//**
73 * @brief Suspend call back function which enter DeepSleep1
74 * @param uPara: Parameter for Call back function
75 * @retval None
76 ***********************************************************************************************************/
Suspend(u32 uPara)77 static void Suspend(u32 uPara)
78 {
79 #if (REMOTE_WAKEUP == 1)
80 u32 IsRemoteWakeupAllowed;
81 #endif
82
83 if (gIsLowPowerAllowed)
84 {
85
86 #if (REMOTE_WAKEUP == 1)
87 /* Disable EXTI interrupt to prevent interrupt occurred after wakeup */
88 EXTI_IntConfig(KEY1_BUTTON_EXTI_CHANNEL, DISABLE);
89 IsRemoteWakeupAllowed = USBDCore_GetRemoteWakeUpFeature(&gUSBCore);
90
91 if (IsRemoteWakeupAllowed == TRUE)
92 {
93 /* Enable EXTI wake event and clear wakeup flag */
94 EXTI_WakeupEventConfig(KEY1_BUTTON_EXTI_CHANNEL, EXTI_WAKEUP_LOW_LEVEL, ENABLE);
95 EXTI_ClearWakeupFlag(KEY1_BUTTON_EXTI_CHANNEL);
96 }
97 #endif
98
99 __DBG_USBPrintf("%06ld >DEEPSLEEP\r\n", ++__DBG_USBCount);
100
101 // Add your procedure here which disable related IO to reduce power consumption
102 // ..................
103 //
104
105 if ((gUSBCore->Info.CurrentStatus == USER_USB_STATE_SUSPENDED) && ((HT_USB->CSR & 0xC0) == 0x40)) // D+ = 1, D- = 0
106 {
107 /* For Bus powered device, you must enter DeepSleep1 when device has been suspended. For self-powered */
108 /* device, you may decide to enter DeepSleep1 or not depended on your application. */
109
110 /* For the convenient during debugging and evaluation stage, the USBDCore_LowPower() is map to a null */
111 /* function by default. In the real product, you must map this function to the low power function of */
112 /* firmware library by setting USBDCORE_ENABLE_LOW_POWER as 1 (in the ht32fxxxx_usbdconf.h file). */
113 USBDCore_LowPower();
114 }
115
116 // Add your procedure here which recovery related IO for application
117 // ..................
118 //
119
120 __DBG_USBPrintf("%06ld <DEEPSLEEP\r\n", ++__DBG_USBCount);
121
122 #if (REMOTE_WAKEUP == 1)
123 if (EXTI_GetWakeupFlagStatus(KEY1_BUTTON_EXTI_CHANNEL) == SET)
124 {
125 __DBG_USBPrintf("%06ld WAKEUP\r\n", ++__DBG_USBCount);
126 if (IsRemoteWakeupAllowed == TRUE && USBDCore_IsSuspend(&gUSBCore) == TRUE)
127 {
128 USBDCore_TriggerRemoteWakeup();
129 }
130 }
131
132 if (IsRemoteWakeupAllowed == TRUE)
133 {
134 /* Disable EXTI wake event and clear wakeup flag */
135 EXTI_WakeupEventConfig(KEY1_BUTTON_EXTI_CHANNEL, EXTI_WAKEUP_LOW_LEVEL, DISABLE);
136 EXTI_ClearWakeupFlag(KEY1_BUTTON_EXTI_CHANNEL);
137 }
138
139 /* Clear EXTI edge flag and enable EXTI interrupt */
140 EXTI_ClearEdgeFlag(KEY1_BUTTON_EXTI_CHANNEL);
141 EXTI_IntConfig(KEY1_BUTTON_EXTI_CHANNEL, ENABLE);
142 #endif
143 }
144
145 return;
146 }
147 /*********************************************************************************************************//**
148 * @brief Configure USB.
149 * @retval None
150 ***********************************************************************************************************/
USB_Configuration(USBDCore_TypeDef * pCore)151 void USB_Configuration(USBDCore_TypeDef *pCore)
152 {
153
154 /* Enable peripheral clock */
155 CKCU_PeripClockConfig_TypeDef CKCUClock = {{ 0 }};
156 CKCUClock.Bit.USBD = 1;
157 CKCUClock.Bit.EXTI = 1;
158 CKCU_PeripClockConfig(CKCUClock, ENABLE);
159
160 gUSBCore = pCore;
161
162 #if (LIBCFG_CKCU_USB_PLL)
163 USBPLL_Configuration();
164 #endif
165
166 #if (LIBCFG_PWRCU_VREG)
167 USBVRG_Configuration(); /* Voltage of USB setting */
168 #endif
169
170 /* !!! NOTICE !!!
171 Must turn on if the USB clock source is from HSI (PLL clock Source)
172 */
173 #if 0
174
175 /* Turn on HSI auto trim function */
176 CKCU_HSIAutoTrimClkConfig(CKCU_ATC_USB);
177 CKCU_HSIAutoTrimCmd(ENABLE);
178
179 #endif
180
181
182 /* USB Descriptor, Core, and Class initialization */
183 gUSBCore->pDriver = (u32 *)&gUSBDriver; /* Initiate memory pointer of USB driver */
184 gUSBCore->Power.CallBack_Suspend.func = Suspend; /* Install suspend call back function into USB core */
185
186 // USBDDesc_Init(&gUSBCore.Device.Desc); /* Initiate memory pointer of descriptor */
187 // USBDClass_Init(&gUSBCore.Class); /* Initiate USB Class layer */
188 USBDCore_Init(gUSBCore); /* Initiate USB Core layer */
189
190 NVIC_SetPriority(USB_IRQn,0);
191 NVIC_EnableIRQ(USB_IRQn); /* Enable USB device interrupt */
192
193 HT32F_DVB_USBConnect();
194
195 }
196
197
198
199
200
201
202
203
204