1 /*
2 * Copyright (c) 2006-2024, 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 "usbd_code.h"
12 #include "usb_port.h"
13
14 #include <rtthread.h>
15 #include <rtdevice.h>
16 #include "drv_common.h"
17
18 #if 1
19
20 #define USB_NO_DATA (-1) /*!< For Device.Transfer.sByteLength */
21 /* Private function prototypes -----------------------------------------------------------------------------*/
22 static void _USBDCore_Suspend(USBDCore_TypeDef *pCore);
23 static void _USBDCore_Reset(USBDCore_TypeDef *pCore);
24 static void _USBDCore_Resume(USBDCore_TypeDef *pCore);
25
26 static void usbd_ept_init(USBDCore_TypeDef *udev);
27 /*********************************************************************************************************//**
28 * @brief USB Interrupt Service Routine.
29 * @param pCore: pointer of USB Device
30 * @retval None
31 ***********************************************************************************************************/
usbd_irq_handler(USBDCore_TypeDef * pCore)32 void usbd_irq_handler(USBDCore_TypeDef *pCore)
33 {
34 u32 USBISRFlag = API_USB_GET_INT();
35 u32 USBEPTISRFlag;
36 USBD_EPTn_Enum EPTn;
37
38 #if (USBDCORE_DEBUG == 1)
39 u32 USBAddr = HT_USB->DEVAR;
40 #endif
41
42 /*--------------------------------------------------------------------------------------------------------*/
43 /* USB SOF Interrupt */
44 /*--------------------------------------------------------------------------------------------------------*/
45 if (API_USB_IS_SOF_INT(USBISRFlag))
46 {
47 usbd_sof_callback(pCore);
48 API_USB_CLR_SOF_INT();
49 }
50
51 /*--------------------------------------------------------------------------------------------------------*/
52 /* USB SUSPEND Interrupt */
53 /*--------------------------------------------------------------------------------------------------------*/
54 if (API_USB_IS_SUSPEND_INT(USBISRFlag))
55 {
56 API_USB_CLR_SUSPEND_INT();
57 usbd_suspend_callback(pCore);
58 _USBDCore_Suspend(pCore);
59 }
60
61 /*--------------------------------------------------------------------------------------------------------*/
62 /* USB RESET Interrupt */
63 /*--------------------------------------------------------------------------------------------------------*/
64 if (API_USB_IS_RESET_INT(USBISRFlag))
65 {
66 if (API_USB_IS_FRES_INT(USBISRFlag))
67 {
68 API_USB_CLR_FRES_INT();
69 }
70 else
71 {
72 usbd_reset_callback(pCore);
73 _USBDCore_Reset(pCore);
74 }
75 API_USB_CLR_RESET_INT();
76 }
77
78 /*--------------------------------------------------------------------------------------------------------*/
79 /* USB RESUME Interrupt */
80 /*--------------------------------------------------------------------------------------------------------*/
81 if (API_USB_IS_RESUME_INT(USBISRFlag))
82 {
83 usbd_resume_callback(pCore);
84 _USBDCore_Resume(pCore);
85 API_USB_CLR_RESUME_INT();
86 }
87
88 /*--------------------------------------------------------------------------------------------------------*/
89 /* USB Endpoint 0 interrupt */
90 /*--------------------------------------------------------------------------------------------------------*/
91 if (API_USB_IS_EPTn_INT(USBISRFlag, USBD_EPT0))
92 {
93 USBEPTISRFlag = API_USB_EPTn_GET_INT(USBD_EPT0);
94
95 /*------------------------------------------------------------------------------------------------------*/
96 /* Control SETUP Stage */
97 /*------------------------------------------------------------------------------------------------------*/
98 if (API_USB_IS_SETUP_INT(USBEPTISRFlag))
99 {
100 API_USB_READ_SETUP(&(pCore->Device.Request)); /* Read SETUP Command data from USB Buffer*/
101 usbd_setup_callback(pCore);
102 API_USB_CLR_SETUP_INT(); /* Clear SETUP Interrupt */
103 }
104
105 /*------------------------------------------------------------------------------------------------------*/
106 /* Control Endpoint 0 IN */
107 /*------------------------------------------------------------------------------------------------------*/
108 if (API_USB_EPTn_IS_IN_INT(USBEPTISRFlag))
109 {
110 usbd_ep0_in_callback(pCore);
111 API_USB_EPTn_CLR_IN_INT(USBD_EPT0);
112 }
113
114 /*------------------------------------------------------------------------------------------------------*/
115 /* Control Endpoint 0 OUT */
116 /*------------------------------------------------------------------------------------------------------*/
117 if (API_USB_EPTn_IS_OUT_INT(USBEPTISRFlag))
118 {
119 /*----------------------------------------------------------------------------------------------------*/
120 /* Clear interrupt flag before USBDCore_ControlOUT is meaning since USBDCore_ControlOUT clear NAKRX */
121 /* bit which will cause another interrupt occur. */
122 /*----------------------------------------------------------------------------------------------------*/
123 API_USB_EPTn_CLR_OUT_INT(USBD_EPT0);
124 usbd_ep0_out_callback(pCore);
125 }
126
127 /*------------------------------------------------------------------------------------------------------*/
128 /* Clear Control Endpoint 0 global interrupt */
129 /*------------------------------------------------------------------------------------------------------*/
130 API_USB_CLR_EPTn_INT(USBD_EPT0);
131
132 } /* if (API_USB_IS_EP_INT(USBISRFlag, USBD_EPT0)) */
133
134
135 /*--------------------------------------------------------------------------------------------------------*/
136 /* USB Endpoint n call back function */
137 /*--------------------------------------------------------------------------------------------------------*/
138 while ((EPTn = API_USB_GET_EPT_NUM(API_USB_GET_INT())) != USBD_NOEPT)
139 {
140 USBEPTISRFlag = API_USB_EPTn_GET_INT((USBD_EPTn_Enum)EPTn);
141
142 if (API_USB_EPTn_IS_INT(USBEPTISRFlag))
143 {
144 API_USB_EPTn_CLR_INT(EPTn);
145 API_USB_CLR_EPTn_INT(EPTn);
146
147 if (USBEPTISRFlag & IDTXIF)
148 {
149 usbd_ep_in_callback(pCore, (USBD_EPTn_Enum)EPTn);
150 }
151 else
152 {
153 usbd_ep_out_callback(pCore, (USBD_EPTn_Enum)EPTn);
154 }
155
156 }
157 } /* while ((EPTn = API_USB_GET_EPTn_NUM(API_USB_GET_INT())) != USBD_NOEPT) */
158
159 return;
160 }
161 /*********************************************************************************************************//**
162 * @brief USB Core initialization.
163 * @param pCore: pointer of USB Device
164 * @retval None
165 ***********************************************************************************************************/
USBDCore_Init(USBDCore_TypeDef * pCore)166 void USBDCore_Init(USBDCore_TypeDef *pCore)
167 {
168 pCore->Info.CurrentStatus = USER_USB_STATE_POWERED;
169 API_USB_INIT(pCore->pDriver);
170
171 /* Endpoint information initialisation */
172 usbd_ept_init(pCore);
173
174 return;
175 }
176 /*********************************************************************************************************//**
177 * @brief USB Core Main Routine for application.
178 * @param pCore: pointer of USB Device
179 * @retval None
180 ***********************************************************************************************************/
USBDCore_MainRoutine(USBDCore_TypeDef * pCore)181 void USBDCore_MainRoutine(USBDCore_TypeDef *pCore)
182 {
183 API_USB_POWER_UP(pCore->pDriver, pCore->Info.CurrentFeature.Bits.bSelfPowered);
184
185 if (pCore->Info.CurrentStatus == USER_USB_STATE_SUSPENDED)
186 {
187 /*------------------------------------------------------------------------------------------------------*/
188 /* System Low Power call back function */
189 /*------------------------------------------------------------------------------------------------------*/
190 if (pCore->Power.CallBack_Suspend.func != NULL)
191 {
192 __DBG_USBPrintf("%06ld >LOWPOWER\r\n", ++__DBG_USBCount);
193
194 pCore->Power.CallBack_Suspend.func(pCore->Power.CallBack_Suspend.uPara);
195
196 __DBG_USBPrintf("%06ld <LOWPOWER\r\n", ++__DBG_USBCount);
197 }
198 }
199
200 return;
201 }
202 /*********************************************************************************************************//**
203 * @brief USB Suspend
204 * @param pCore: pointer of USB Device
205 * @retval None
206 ***********************************************************************************************************/
_USBDCore_Suspend(USBDCore_TypeDef * pCore)207 static void _USBDCore_Suspend(USBDCore_TypeDef *pCore)
208 {
209 /*--------------------------------------------------------------------------------------------------------*/
210 /* When Device has been suspended, Change CurrentStatus as SUSPEND and then USBDCore_PowerHandler will */
211 /* turn off chip power. */
212 /*--------------------------------------------------------------------------------------------------------*/
213 if (pCore->Info.CurrentStatus >= USER_USB_STATE_POWERED)
214 {
215 API_USB_POWER_OFF();
216 pCore->Info.LastStatus = pCore->Info.CurrentStatus;
217 pCore->Info.CurrentStatus = USER_USB_STATE_SUSPENDED;
218 }
219
220 return;
221 }
222 /*********************************************************************************************************//**
223 * @brief USB Reset
224 * @param pCore: pointer of USB Device
225 * @retval None
226 ***********************************************************************************************************/
_USBDCore_Reset(USBDCore_TypeDef * pCore)227 static void _USBDCore_Reset(USBDCore_TypeDef *pCore)
228 {
229 USBD_Driver_TypeDef *pDrv = (USBD_Driver_TypeDef *)pCore->pDriver;
230
231 pCore->Device.Transfer.sByteLength = USB_NO_DATA;
232 pCore->Info.uCurrentConfiguration = 0;
233 pCore->Info.uCurrentInterface = 0;
234 pCore->Info.CurrentFeature.Bits.bRemoteWakeup = 0;
235 pCore->Info.CurrentStatus = USER_USB_STATE_DEFAULT;
236 pCore->Info.uIsDiscardClearFeature = FALSE;
237
238 API_USB_DEINIT();
239
240 API_USB_POWER_ON();
241
242 /* Endpoint 0 initialization */
243 API_USB_EPTn_INIT(USBD_EPT0, pCore->pDriver); // To be modify, init from desc
244
245 /* Enable USB interrupt */
246 API_USB_ENABLE_INT(pDrv->uInterruptMask);
247
248 return;
249 }
250 /*********************************************************************************************************//**
251 * @brief USB Resume
252 * @param pCore: pointer of USB Device
253 * @retval None
254 ***********************************************************************************************************/
_USBDCore_Resume(USBDCore_TypeDef * pCore)255 static void _USBDCore_Resume(USBDCore_TypeDef *pCore)
256 {
257 API_USB_POWER_ON();
258 pCore->Info.CurrentStatus = pCore->Info.LastStatus;
259 return;
260 }
261 /****************************************************************************************************************************/
usbd_ep_enable(USBDCore_TypeDef * pCore,uint8_t ept_addr)262 void usbd_ep_enable(USBDCore_TypeDef *pCore, uint8_t ept_addr)
263 {
264 USBD_Driver_TypeDef *pDrv = (USBD_Driver_TypeDef *)pCore->pDriver;
265 pDrv->ept[ept_addr & 0x7f].CFGR.bits.EPEN = 1;
266 API_USB_EPTn_INIT((USBD_EPTn_Enum)(ept_addr & 0x7f), pCore->pDriver); // To be modify, init from desc
267 }
usbd_ep_disable(USBDCore_TypeDef * pCore,uint8_t ept_addr)268 void usbd_ep_disable(USBDCore_TypeDef *pCore, uint8_t ept_addr)
269 {
270 USBD_Driver_TypeDef *pDrv = (USBD_Driver_TypeDef *)pCore->pDriver;
271 pDrv->ept[ept_addr & 0x7f].CFGR.bits.EPEN = 0;
272 API_USB_EPTn_INIT((USBD_EPTn_Enum)(ept_addr & 0x7f), pCore->pDriver); // To be modify, init from desc
273 }
274
usbd_ept_init(USBDCore_TypeDef * udev)275 static void usbd_ept_init(USBDCore_TypeDef *udev)
276 {
277 uint8_t ept_num = 0;
278 usb_ept_info *ept_info;
279 for (ept_num = 0; ept_num < 8; ept_num++)
280 {
281 ept_info = &udev->ept_io[ept_num];
282
283 ept_info->maxpacket = 64;
284
285 ept_info->status = 1;
286
287 ept_info->total_len = 0;
288 ept_info->trans_len = 0;
289 ept_info->trans_buf = NULL;
290 }
291 }
292 /**
293 * @brief usb endpoint receive data
294 * @param udev: to the structure of usbd_core_type
295 * @param ept_addr: endpoint number
296 * @param buffer: receive data buffer
297 * @param len: receive data length
298 * @retval none
299 */
usbd_ept_recv(USBDCore_TypeDef * udev,uint8_t ept_addr,uint8_t * buffer,uint16_t len)300 void usbd_ept_recv(USBDCore_TypeDef *udev, uint8_t ept_addr, uint8_t *buffer, uint16_t len)
301 {
302 /* get endpoint info struct and register */
303 usb_ept_info *ept_info = &udev->ept_io[ept_addr & 0x7F];
304 uint32_t trs_len = 0;
305
306 /* set receive data buffer and length */
307 ept_info->trans_buf = buffer;
308 ept_info->total_len = len;
309 ept_info->trans_len = 0;
310
311 if (ept_info->total_len > ept_info->maxpacket)
312 {
313 trs_len = ept_info->maxpacket;
314 ept_info->total_len -= trs_len;
315 }
316 else
317 {
318 trs_len = len;
319 ept_info->total_len = 0;
320 }
321
322 ept_info->trans_len = trs_len;
323 /* set rx status valid */
324 ept_info->status = TRUE;
325 }
326
327 #endif /* BSP_USING_USBD */
328