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