1 /*
2  * SPDX-FileCopyrightText: 2016 STMicroelectronics
3  * SPDX-FileCopyrightText: 2019-2025 SiFli Technologies(Nanjing) Co., Ltd
4  *
5  * SPDX-License-Identifier: BSD-3-Clause AND Apache-2.0
6  */
7 
8 #include "bf0_hal.h"
9 #include "bf0_hal_usb_common.h"
10 
11 
12 /** @addtogroup BF0_HAL_Driver
13   * @{
14   */
15 
16 #if defined(HAL_PCD_MODULE_ENABLED)||defined(_SIFLI_DOXYGEN_)
17 
18 #ifndef SF32LB55X
19     #define USB_TX_DMA_ENABLED 1
20     #define USB_RX_DMA_ENABLED 1
21 #endif
22 
23 /** @defgroup PCD USB Device
24   * @brief PCD HAL module driver
25   * @{
26   */
27 
28 /* Private typedef -----------------------------------------------------------*/
29 /* Private define ------------------------------------------------------------*/
30 /* Private macro -------------------------------------------------------------*/
31 /* Private variables ---------------------------------------------------------*/
32 /* Private function prototypes -----------------------------------------------*/
33 /** @defgroup PCD_Private_Functions PCD Private Functions
34   * @{
35   */
36 static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd);
37 static const char *ep0_state_str(uint8_t state);
38 static uint8_t tx_packet_max = 0;
39 
40 #define ep0_state_change(hpcd,new_state) \
41 { \
42     HAL_DBG_printf("EP0 State %s -> %s, line %d\r\n", ep0_state_str(hpcd->ep0_state), ep0_state_str(new_state), __LINE__); \
43     hpcd->ep0_state = new_state; \
44 }
45 
46 /**
47   * @}
48   */
49 
50 /* Exported functions --------------------------------------------------------*/
51 /** @defgroup PCD_Exported_Functions PCD Exported Functions
52   * @{
53   */
54 
55 /** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
56  *  @brief    Initialization and Configuration functions
57  *
58 @verbatim
59  ===============================================================================
60             ##### Initialization and de-initialization functions #####
61  ===============================================================================
62     [..]  This section provides functions allowing to:
63 
64 @endverbatim
65   * @{
66   */
67 
68 /**
69   * @brief  Initializes the PCD according to the specified
70   *         parameters in the PCD_InitTypeDef and create the associated handle.
71   * @param  hpcd PCD handle
72   * @retval HAL status
73   */
74 
HAL_PCD_Init(PCD_HandleTypeDef * hpcd)75 HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd)
76 {
77     uint32_t i = 0U;
78 
79 
80     /* Check the PCD handle allocation */
81     if (hpcd == NULL)
82     {
83         return HAL_ERROR;
84     }
85 
86     if (hpcd->State == HAL_PCD_STATE_RESET)
87     {
88         /* Allocate lock resource and initialize it */
89         hpcd->Lock = HAL_UNLOCKED;
90 
91         /* Init the low level hardware : GPIO, CLOCK, NVIC... */
92         HAL_PCD_MspInit(hpcd);
93     }
94 
95     hpcd->State = HAL_PCD_STATE_BUSY;
96 
97     /* Init endpoints structures */
98     for (i = 0U; i < hpcd->Init.dev_endpoints ; i++)
99     {
100         /* Init ep structure */
101         hpcd->IN_ep[i].is_in = 1U;
102         hpcd->IN_ep[i].num = i;
103         /* Control until ep is actvated */
104         hpcd->IN_ep[i].type = PCD_EP_TYPE_CTRL;
105         hpcd->IN_ep[i].maxpacket =  0U;
106         hpcd->IN_ep[i].xfer_buff = 0U;
107         hpcd->IN_ep[i].xfer_len = 0U;
108     }
109 
110     for (i = 0U; i < hpcd->Init.dev_endpoints ; i++)
111     {
112         hpcd->OUT_ep[i].is_in = 0U;
113         hpcd->OUT_ep[i].num = i;
114         /* Control until ep is activated */
115         hpcd->OUT_ep[i].type = PCD_EP_TYPE_CTRL;
116         hpcd->OUT_ep[i].maxpacket = 0U;
117         hpcd->OUT_ep[i].xfer_buff = 0U;
118         hpcd->OUT_ep[i].xfer_len = 0U;
119     }
120 
121     /* Init Device, Clear session*/
122     // hpcd->Instance->devctl |= USB_DEVCTL_SESSION;
123 
124     // TODO: Turn on PHY???
125 
126     /* , start software connection */
127     {
128         uint8_t power = hpcd->Instance->power;
129         //power &= ~USB_POWER_HSENAB;
130         power |= USB_POWER_SOFTCONN;
131         hpcd->Instance->power = power;
132     }
133 
134 
135     hpcd->USB_Address = 0U;
136     hpcd->State = HAL_PCD_STATE_READY;
137     ep0_state_change(hpcd, HAL_PCD_EP0_SETUP);
138     hpcd->phy_state = OTG_STATE_B_PERIPHERALS;
139 
140     return HAL_OK;
141 }
142 
143 /**
144   * @brief  DeInitializes the PCD peripheral
145   * @param  hpcd PCD handle
146   * @retval HAL status
147   */
HAL_PCD_DeInit(PCD_HandleTypeDef * hpcd)148 HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
149 {
150     /* Check the PCD handle allocation */
151     if (hpcd == NULL)
152     {
153         return HAL_ERROR;
154     }
155 
156     hpcd->State = HAL_PCD_STATE_BUSY;
157 
158     /* Stop Device */
159     HAL_PCD_Stop(hpcd);
160 
161     /* DeInit the low level hardware */
162     HAL_PCD_MspDeInit(hpcd);
163 
164     hpcd->State = HAL_PCD_STATE_RESET;
165 
166     return HAL_OK;
167 }
168 
169 /**
170   * @brief  Initializes the PCD MSP.
171   * @param  hpcd PCD handle
172   * @retval None
173   */
HAL_PCD_MspInit(PCD_HandleTypeDef * hpcd)174 __weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
175 {
176     HAL_RCC_EnableModule(RCC_MOD_USBC);
177 
178 #ifdef SF32LB58X
179     //hwp_usbc->utmicfg12 = hwp_usbc->utmicfg12 | 0x3; //set xo_clk_sel
180     hwp_usbc->utmicfg23 = 0xd8;
181     hwp_usbc->ldo25 = hwp_usbc->ldo25 | 0xa; //set psw_en and ldo25_en
182     HAL_Delay(1);
183     hwp_usbc->swcntl3 = 0x1; //set utmi_en for USB2.0
184     hwp_usbc->usbcfg = hwp_usbc->usbcfg | 0x40; //enable usb PLL.
185 #elif defined(SF32LB56X)||defined(SF32LB52X)
186     hwp_hpsys_cfg->USBCR |= HPSYS_CFG_USBCR_DM_PD | HPSYS_CFG_USBCR_DP_EN | HPSYS_CFG_USBCR_USB_EN;
187 #elif defined(SF32LB55X)
188     hwp_hpsys_cfg->USBCR |= HPSYS_CFG_USBCR_DM_PD | HPSYS_CFG_USBCR_USB_EN;
189 #endif
190 }
191 
192 /**
193   * @brief  DeInitializes PCD MSP.
194   * @param  hpcd PCD handle
195   * @retval None
196   */
HAL_PCD_MspDeInit(PCD_HandleTypeDef * hpcd)197 __weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
198 {
199 #ifdef SF32LB58X
200     hwp_usbc->usbcfg &= ~0x40;  // Disable usb PLL.
201     hwp_usbc->swcntl3 = 0x0;
202     hwp_usbc->ldo25 &= ~0xa;    // Disable psw_en and ldo25_en
203 #elif defined(SF32LB56X)||defined(SF32LB52X)
204     hwp_hpsys_cfg->USBCR &= ~(HPSYS_CFG_USBCR_DM_PD | HPSYS_CFG_USBCR_DP_EN | HPSYS_CFG_USBCR_USB_EN);
205 #elif defined(SF32LB55X)
206     hwp_hpsys_cfg->USBCR &= ~(HPSYS_CFG_USBCR_DM_PD | HPSYS_CFG_USBCR_USB_EN);
207 #endif
208     /* reset USB to make DP change to PULLDOWN state */
209     hwp_hpsys_rcc->RSTR2 |= HPSYS_RCC_RSTR2_USBC;
210     HAL_Delay_us(100);
211     hwp_hpsys_rcc->RSTR2 &= ~HPSYS_RCC_RSTR2_USBC;
212     HAL_RCC_DisableModule(RCC_MOD_USBC);
213 }
214 
215 /**
216   * @}
217   */
218 
219 /** @defgroup PCD_Exported_Functions_Group2 IO operation functions
220  *  @brief   Data transfers functions
221  *
222 @verbatim
223  ===============================================================================
224                       ##### IO operation functions #####
225  ===============================================================================
226     [..]
227     This subsection provides a set of functions allowing to manage the PCD data
228     transfers.
229 
230 @endverbatim
231   * @{
232   */
233 
234 /**
235   * @brief  Start the USB device.
236   * @param  hpcd PCD handle
237   * @retval HAL status
238   */
HAL_PCD_Start(PCD_HandleTypeDef * hpcd)239 HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)
240 {
241     /* Enabling DP Pull-Down bit to Connect internal pull-up on USB DP line */
242     /* TODO: ?????*/
243     HAL_PCD_EP_Open(hpcd, 0x00, 0x40, EP_TYPE_CTRL);
244     HAL_PCD_EP_Open(hpcd, 0x80, 0x40, EP_TYPE_CTRL);
245     HAL_DBG_printf("Enable IRQ %d\n", USBC_IRQn);
246     NVIC_EnableIRQ(USBC_IRQn);
247     __HAL_SYSCFG_Enable_USB();
248 
249     return HAL_OK;
250 }
251 
252 /**
253   * @brief  Stop the USB device.
254   * @param  hpcd PCD handle
255   * @retval HAL status
256   */
HAL_PCD_Stop(PCD_HandleTypeDef * hpcd)257 HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
258 {
259     __HAL_LOCK(hpcd);
260 
261     NVIC_DisableIRQ(USBC_IRQn);
262     HAL_PCD_EP_Close(hpcd, 0x00);
263     HAL_PCD_EP_Close(hpcd, 0x80);
264 
265     __HAL_UNLOCK(hpcd);
266     return HAL_OK;
267 }
HAL_PCD_Get_RxbuffControl(uint8_t ep_num)268 __weak uint8_t HAL_PCD_Get_RxbuffControl(uint8_t ep_num)
269 {
270     return 0;
271 }
HAL_PCD_Set_RxbuffControl(uint8_t ep_num,uint8_t flag)272 __weak void HAL_PCD_Set_RxbuffControl(uint8_t ep_num, uint8_t flag)
273 {
274 }
HAL_PCD_Set_RxscrACK(uint8_t epnum)275 __weak void HAL_PCD_Set_RxscrACK(uint8_t epnum)
276 {
277 }
278 /**
279   * @brief  This function handles PCD interrupt request.
280   * @param  hpcd PCD handle
281   * @retval HAL status
282   */
HAL_PCD_IRQHandler(PCD_HandleTypeDef * hpcd)283 void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
284 {
285     /* servicing of the endpoint correct transfer interrupt */
286     /* clear of the CTR flag into the sub */
287     PCD_EP_ISR_Handler(hpcd);
288     // TODO: Other interrupt such as wake/suspend/stall etc not implemented yet
289 }
290 
291 /**
292   * @brief  Data out stage callbacks
293   * @param  hpcd PCD handle
294   * @param  epnum endpoint number
295   * @retval None
296   */
HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef * hpcd,uint8_t epnum)297 __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
298 {
299     /* Prevent unused argument(s) compilation warning */
300     UNUSED(hpcd);
301     UNUSED(epnum);
302 
303     /* NOTE : This function Should not be modified, when the callback is needed,
304               the HAL_PCD_DataOutStageCallback could be implemented in the user file
305      */
306 }
307 
308 /**
309   * @brief  Data IN stage callbacks
310   * @param  hpcd PCD handle
311   * @param  epnum endpoint number
312   * @retval None
313   */
HAL_PCD_DataInStageCallback(PCD_HandleTypeDef * hpcd,uint8_t epnum)314 __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
315 {
316     /* Prevent unused argument(s) compilation warning */
317     UNUSED(hpcd);
318     UNUSED(epnum);
319 
320     /* NOTE : This function Should not be modified, when the callback is needed,
321               the HAL_PCD_DataInStageCallback could be implemented in the user file
322      */
323 }
324 
325 /**
326   * @brief  Setup stage callback
327   * @param  hpcd PCD handle
328   * @retval None
329   */
HAL_PCD_SetupStageCallback(PCD_HandleTypeDef * hpcd)330 __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
331 {
332     /* Prevent unused argument(s) compilation warning */
333     UNUSED(hpcd);
334 
335     /* NOTE : This function Should not be modified, when the callback is needed,
336               the HAL_PCD_SetupStageCallback could be implemented in the user file
337      */
338 }
339 
340 /**
341   * @brief  USB Start Of Frame callbacks
342   * @param  hpcd PCD handle
343   * @retval None
344   */
HAL_PCD_SOFCallback(PCD_HandleTypeDef * hpcd)345 __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
346 {
347     /* Prevent unused argument(s) compilation warning */
348     UNUSED(hpcd);
349 
350     /* NOTE : This function Should not be modified, when the callback is needed,
351               the HAL_PCD_SOFCallback could be implemented in the user file
352      */
353 }
354 
355 /**
356   * @brief  USB Reset callbacks
357   * @param  hpcd PCD handle
358   * @retval None
359   */
HAL_PCD_ResetCallback(PCD_HandleTypeDef * hpcd)360 __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
361 {
362     /* Prevent unused argument(s) compilation warning */
363     UNUSED(hpcd);
364 
365     /* NOTE : This function Should not be modified, when the callback is needed,
366               the HAL_PCD_ResetCallback could be implemented in the user file
367      */
368 }
369 
370 /**
371   * @brief  Suspend event callbacks
372   * @param  hpcd PCD handle
373   * @retval None
374   */
HAL_PCD_SuspendCallback(PCD_HandleTypeDef * hpcd)375 __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
376 {
377     /* Prevent unused argument(s) compilation warning */
378     UNUSED(hpcd);
379 
380     /* NOTE : This function Should not be modified, when the callback is needed,
381               the HAL_PCD_SuspendCallback could be implemented in the user file
382      */
383 }
384 
385 /**
386   * @brief  Resume event callbacks
387   * @param  hpcd PCD handle
388   * @retval None
389   */
HAL_PCD_ResumeCallback(PCD_HandleTypeDef * hpcd)390 __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
391 {
392     /* Prevent unused argument(s) compilation warning */
393     UNUSED(hpcd);
394 
395     /* NOTE : This function Should not be modified, when the callback is needed,
396               the HAL_PCD_ResumeCallback could be implemented in the user file
397      */
398 }
399 
400 /**
401   * @brief  Incomplete ISO OUT callbacks
402   * @param  hpcd PCD handle
403   * @param  epnum endpoint number
404   * @retval None
405   */
HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef * hpcd,uint8_t epnum)406 __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
407 {
408     /* Prevent unused argument(s) compilation warning */
409     UNUSED(hpcd);
410     UNUSED(epnum);
411 
412     /* NOTE : This function Should not be modified, when the callback is needed,
413               the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file
414      */
415 }
416 
417 /**
418   * @brief  Incomplete ISO IN  callbacks
419   * @param  hpcd PCD handle
420   * @param  epnum endpoint number
421   * @retval None
422   */
HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef * hpcd,uint8_t epnum)423 __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
424 {
425     /* Prevent unused argument(s) compilation warning */
426     UNUSED(hpcd);
427     UNUSED(epnum);
428 
429     /* NOTE : This function Should not be modified, when the callback is needed,
430               the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file
431      */
432 }
433 
434 /**
435   * @brief  Connection event callbacks
436   * @param  hpcd PCD handle
437   * @retval None
438   */
HAL_PCD_ConnectCallback(PCD_HandleTypeDef * hpcd)439 __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
440 {
441     /* Prevent unused argument(s) compilation warning */
442     UNUSED(hpcd);
443 
444     /* NOTE : This function Should not be modified, when the callback is needed,
445               the HAL_PCD_ConnectCallback could be implemented in the user file
446      */
447 }
448 
449 /**
450   * @brief  Disconnection event callbacks
451   * @param  hpcd PCD handle
452   * @retval None
453   */
HAL_PCD_DisconnectCallback(PCD_HandleTypeDef * hpcd)454 __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
455 {
456     /* Prevent unused argument(s) compilation warning */
457     UNUSED(hpcd);
458 
459     /* NOTE : This function Should not be modified, when the callback is needed,
460               the HAL_PCD_DisconnectCallback could be implemented in the user file
461      */
462 }
463 /**
464   * @}
465   */
466 
467 /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
468  *  @brief   management functions
469  *
470 @verbatim
471  ===============================================================================
472                       ##### Peripheral Control functions #####
473  ===============================================================================
474     [..]
475     This subsection provides a set of functions allowing to control the PCD data
476     transfers.
477 
478 @endverbatim
479   * @{
480   */
481 
482 /**
483   * @brief  Set the USB Device address
484   * @param  hpcd PCD handle
485   * @param  address new device address
486   * @retval HAL status
487   */
HAL_PCD_SetAddress(PCD_HandleTypeDef * hpcd,uint8_t address)488 HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)
489 {
490     __HAL_LOCK(hpcd);
491 
492     /* set device address and enable function */
493     hpcd->Instance->faddr = address;
494     hpcd->USB_Address = address;
495     __HAL_UNLOCK(hpcd);
496     return HAL_OK;
497 }
498 /**
499   * @brief  Open and configure an endpoint
500   * @param  hpcd PCD handle
501   * @param  ep_addr endpoint address
502   * @param  ep_mps endpoint max packert size
503   * @param  ep_type endpoint type
504   * @retval HAL status
505   */
HAL_PCD_EP_Open(PCD_HandleTypeDef * hpcd,uint8_t ep_addr,uint16_t ep_mps,uint8_t ep_type)506 HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type)
507 {
508     HAL_StatusTypeDef  ret = HAL_OK;
509     PCD_EPTypeDef *ep;
510     uint16_t csr;
511 
512     if ((ep_addr & 0x80U) == 0x80U)
513     {
514         ep = &hpcd->IN_ep[ep_addr & 0x7FU];
515     }
516     else
517     {
518         ep = &hpcd->OUT_ep[ep_addr & 0x7FU];
519     }
520     ep->num   = ep_addr & 0x7FU;
521     ep->is_in = (0x80U & ep_addr) != 0U;
522     ep->maxpacket = ep_mps;
523     ep->type = ep_type;
524 
525     HAL_DBG_printf("ep_addr=%x, num=%d, is_in=%d\n", ep_addr, ep->num, ep->is_in);
526     __HAL_LOCK(hpcd);
527     NVIC_DisableIRQ(USBC_IRQn);
528     if (ep->num)
529     {
530         hpcd->Instance->index = ep->num;
531         if (ep->is_in)
532         {
533             hpcd->Instance->intrtx |= (1 << ep->num);
534             hpcd->Instance->txmaxp = ep_mps;
535             csr = USB_TXCSR_MODE | USB_TXCSR_CLRDATATOG;
536             if (hpcd->Instance->csr0_txcsr & USB_TXCSR_FIFONOTEMPTY)
537                 csr |= USB_TXCSR_FLUSHFIFO;
538             hpcd->Instance->csr0_txcsr = csr;
539         }
540         else
541         {
542             hpcd->Instance->intrrx |= (1 << ep->num);
543             hpcd->Instance->rxmaxp = ep_mps;
544             csr = USB_RXCSR_FLUSHFIFO | USB_RXCSR_CLRDATATOG ;
545             // USB_RXCSR_AUTOCLEAR
546 
547             if (ep->type == PCD_EP_TYPE_INTR)
548                 csr |= USB_RXCSR_DISNYET;
549             // Set twice in case of double buffering.
550             hpcd->Instance->rxcsr = csr;
551             hpcd->Instance->rxcsr = csr;
552         }
553     }
554     NVIC_EnableIRQ(USBC_IRQn);
555     __HAL_UNLOCK(hpcd);
556     return ret;
557 }
558 
559 
560 /**
561   * @brief  Deactivate an endpoint
562   * @param  hpcd PCD handle
563   * @param  ep_addr endpoint address
564   * @retval HAL status
565   */
HAL_PCD_EP_Close(PCD_HandleTypeDef * hpcd,uint8_t ep_addr)566 HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
567 {
568     PCD_EPTypeDef *ep;
569 
570     if ((ep_addr & 0x80U) == 0x80U)
571     {
572         ep = &hpcd->IN_ep[ep_addr & 0x7FU];
573     }
574     else
575     {
576         ep = &hpcd->OUT_ep[ep_addr & 0x7FU];
577     }
578     ep->num   = ep_addr & 0x7FU;
579 
580     ep->is_in = (0x80U & ep_addr) != 0U;
581 
582     __HAL_LOCK(hpcd);
583     NVIC_DisableIRQ(USBC_IRQn);
584 
585     if (ep->num)
586     {
587         hpcd->Instance->index = ep->num;
588         if (ep->is_in)
589         {
590             hpcd->Instance->intrtx &= ~(1 << ep->num);
591             hpcd->Instance->txmaxp = 0;
592             // The programming guide says that we must not clear the DMAMODE bit before DMAENAB,
593             // so we only clear it in the sconed write...
594             hpcd->Instance->csr0_txcsr = (USB_TXCSR_DMAMODE | USB_TXCSR_FLUSHFIFO);
595             hpcd->Instance->csr0_txcsr = USB_TXCSR_FLUSHFIFO;
596         }
597         else
598         {
599             hpcd->Instance->intrrx &= ~(1 << ep->num);
600             hpcd->Instance->rxmaxp = 0;
601             hpcd->Instance->rxcsr = USB_RXCSR_FLUSHFIFO;
602             hpcd->Instance->rxcsr = USB_RXCSR_FLUSHFIFO; // Why twice ???
603         }
604     }
605     NVIC_EnableIRQ(USBC_IRQn);
606     __HAL_UNLOCK(hpcd);
607     return HAL_OK;
608 }
609 
610 
611 /**
612   * @brief  Receive an amount of data
613   * @param  hpcd PCD handle
614   * @param  ep_addr endpoint address
615   * @param  pBuf pointer to the reception buffer
616   * @retval received packet size.
617   */
HAL_PCD_EP_Receive(PCD_HandleTypeDef * hpcd,uint8_t ep_addr,uint8_t * pBuf)618 uint32_t HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf)
619 {
620     PCD_EPTypeDef *ep;
621     uint32_t r = 0;
622 
623     ep = &hpcd->OUT_ep[ep_addr & 0x7FU];
624 
625     if (ep->num)
626     {
627         __IO struct musb_epN_regs *epn;
628         uint16_t csr;
629 
630         epn = &(hpcd->Instance->ep[ep->num].epN);
631         csr = epn->rxcsr;
632         if (csr & USB_RXCSR_P_SENDSTALL)
633         {
634             HAL_DBG_printf("ep stalling, rxcsr %03x\n", csr);
635         }
636         else
637         {
638             r = ep->xfer_count;
639             //HAL_DBG_printf("EP %d Rx: %p, %d, csr=%x\r\n", ep->num, pBuf, r, csr);
640             //HAL_DBG_print_data((char *)pBuf, 0, r);
641             if (csr & USB_RXCSR_RXPKTRDY)
642             {
643 #if !defined(USB_RX_DMA_ENABLED)
644                 __IO uint8_t *fifox = (__IO uint8_t *) & (hpcd->Instance->fifox[ep->num]);
645                 int i;
646                 r = epn->rxcount;
647                 for (i = 0; i < r; i++)
648                     *(pBuf + i) = *fifox;
649                 epn->rxcsr = 0;
650 #endif
651 
652 #if  defined(SF32LB58X) || defined(SF32LB55X)
653                 /* 58 Because it is 480MHz, it is necessary to clear USB-RXCSR-RXPKTRDY here.*/
654                 if (HAL_PCD_Get_RxbuffControl(ep->num)) //Control the receiving data flow of the channel 1:Control the receiving data flow of the channel;0 Stop receiving
655                     epn->rxcsr = 0;
656 #endif
657             }
658             ep->xfer_count = 0;
659         }
660     }
661     else
662     {
663         __IO struct musb_ep0_regs *ep0;
664         int i;
665         uint16_t csr;
666         __IO uint8_t *fifox = (__IO uint8_t *) & (hpcd->Instance->fifox[ep->num]);
667 
668         ep0 = &(hpcd->Instance->ep[ep->num].ep0);
669         r = ep0->count0;
670         if (r > ep->xfer_len)
671             r = ep->xfer_len;
672         for (i = 0; i < (int)r; i++)
673             *(pBuf + i) = *fifox;
674         csr = USB_CSR0_P_SVDRXPKTRDY;
675         if (r < ep->maxpacket)
676         {
677             ep0_state_change(hpcd, HAL_PCD_EP0_STATUSIN);
678             csr |= USB_CSR0_P_DATAEND;
679         }
680         ep0->csr0 = csr;
681         HAL_DBG_printf("EP0 Rx:%d\r\n", r);
682         //HAL_DBG_print_data((char *)pBuf, 0, r);
683     }
684 
685     return r;
686 }
687 
688 /**
689   * @brief  Receive an amount of data
690   * @param  hpcd PCD handle
691   * @param  ep_addr endpoint address
692   * @param  pBuf pointer to the reception buffer
693   * @param  len amount of data to be received
694   * @retval HAL status
695   */
HAL_PCD_EP_Prepare_Receive(PCD_HandleTypeDef * hpcd,uint8_t ep_addr,uint8_t * pBuf,uint32_t len)696 HAL_StatusTypeDef HAL_PCD_EP_Prepare_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
697 {
698 
699     PCD_EPTypeDef *ep;
700     uint16_t csr;
701 
702     ep = &hpcd->OUT_ep[ep_addr & 0x7FU];
703 
704     /*setup and start the Xfer */
705     ep->xfer_buff = pBuf;
706     ep->xfer_len = len;
707     ep->is_in = 0U;
708     ep->num = ep_addr & 0x7FU;
709 
710     if (ep->num)
711     {
712         __IO struct musb_epN_regs *epn = &(hpcd->Instance->ep[ep->num].epN);
713 
714         HAL_DBG_printf("Prepare_read on pipe %d:%p,len %d, is_in=%d\n", ep->num, pBuf, len, ep->is_in);
715         csr = epn->rxcsr;
716     }
717     else
718         ep0_state_change(hpcd, HAL_PCD_EP0_RX);
719 
720     return HAL_OK;
721 }
722 
723 /**
724   * @brief  Get Received Data Size
725   * @param  hpcd PCD handle
726   * @param  ep_addr endpoint address
727   * @retval Data Size
728   */
HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef * hpcd,uint8_t ep_addr)729 uint16_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
730 {
731     uint16_t r = 0;
732 
733     NVIC_DisableIRQ(USBC_IRQn);
734     hpcd->Instance->index = ep_addr & 0x7FU;
735     r = hpcd->Instance->rxcount;
736     NVIC_EnableIRQ(USBC_IRQn);
737     return r;
738 }
739 
740 /**
741   * @brief  Send an amount of data
742   * @param  hpcd PCD handle
743   * @param  ep_addr endpoint address
744   * @param  pBuf pointer to the transmission buffer
745   * @param  len amount of data to be sent
746   * @retval HAL status
747   */
HAL_PCD_EP_Transmit(PCD_HandleTypeDef * hpcd,uint8_t ep_addr,uint8_t * pBuf,uint32_t len)748 HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
749 {
750     PCD_EPTypeDef *ep;
751 
752     ep = &hpcd->IN_ep[ep_addr & 0x7FU];
753 
754     /*setup and start the Xfer */
755     ep->xfer_buff = pBuf;
756     ep->xfer_len = len;
757     ep->is_in = 1U;
758     ep->num = ep_addr & 0x7FU;
759     ep->xfer_count = len;
760 
761     if (ep->num)
762     {
763         uint16_t csr;
764         __IO struct musb_epN_regs *epn = &(hpcd->Instance->ep[ep->num].epN);
765 
766         csr = epn->txcsr;
767         HAL_DBG_printf("tx ep %d: csr=0x%x, %d\n", ep->num, csr, len);
768 #if USB_TX_DMA_ENABLED
769         if (IS_DCACHED_RAM((uint32_t)pBuf))
770             mpu_dcache_clean((void *)pBuf, len);
771 
772 
773         struct musb_dma_regs *dma = (struct musb_dma_regs *) & (hpcd->Instance->dma[ep->num]);
774         dma->addr = (REG32)pBuf;
775         dma->count = len;
776         dma->cntl = //(1 << USB_DMACTRL_ENABLE_SHIFT)   |
777             (1 << USB_DMACTRL_TRANSMIT_SHIFT) |
778             //(0 << USB_DMACTRL_MODE1_SHIFT)    |
779             (ep->num << USB_DMACTRL_ENDPOINT_SHIFT) |
780             (1 << USB_DMACTRL_IRQENABLE_SHIFT);
781         if ((len / ep->maxpacket) > 1)
782         {
783             dma->cntl |= (1 << USB_DMACTRL_ENABLE_SHIFT) | (1 << USB_DMACTRL_MODE1_SHIFT);
784             csr |= USB_TXCSR_DMAENAB | USB_TXCSR_AUTOSET;
785             tx_packet_max = 1;
786         }
787         else
788         {
789             dma->cntl |= (1 << USB_DMACTRL_ENABLE_SHIFT) | (0 << USB_DMACTRL_MODE1_SHIFT);
790             tx_packet_max = 0;
791         }
792         epn->txcsr = csr;
793 
794 #else
795         __IO uint8_t *fifox = (__IO uint8_t *) & (hpcd->Instance->fifox[ep->num]);
796 
797         if (csr & USB_TXCSR_TXPKTRDY)
798         {
799             //LOG_W("old packet still ready, txcsr %03x\n", csr);
800         }
801         if (csr & USB_TXCSR_P_SENDSTALL)
802         {
803             //LOG_W("ep stalling, txcsr %03x\n", csr);
804         }
805         for (int i = 0; i < len; i++) // REVISIT: Use 16bits/32bits FIFO to speed up
806             *fifox = *(pBuf + i);
807         csr &= ~USB_TXCSR_P_UNDERRUN;
808         csr |= USB_TXCSR_AUTOSET;
809         if (len <= ep->maxpacket)
810             csr |= USB_TXCSR_TXPKTRDY;
811 
812         epn->txcsr = csr;
813 #endif
814         //HAL_DBG_print_data((char *)pBuf, 0, len);
815     }
816     else
817     {
818         int i;
819         uint16_t csr;
820         __IO uint8_t *fifox = (__IO uint8_t *) & (hpcd->Instance->fifox[ep->num]);
821         __IO struct musb_ep0_regs *ep0 = &(hpcd->Instance->ep[ep->num].ep0);
822 
823         for (i = 0; i < (int)len; i++) // REVISIT: Use 16bits/32bits FIFO to speed up
824             *fifox = *(pBuf + i);
825         csr = USB_CSR0_TXPKTRDY;
826 
827         HAL_DBG_printf("tx ep0: csr=0x%x, %d\n", csr, len);
828         //HAL_DBG_print_data((char *)pBuf, 0, len);
829 
830         if (len && len < ep->maxpacket)
831         {
832             csr |= USB_CSR0_P_DATAEND;
833             ep0_state_change(hpcd, HAL_PCD_EP0_STATUSOUT);
834         }
835         ep0->csr0 = csr;
836 
837     }
838     return HAL_OK;
839 }
840 
musb_stall(__IO struct musb_epN_regs * epn,int value,int is_in)841 static void musb_stall(__IO struct musb_epN_regs *epn, int value, int is_in)
842 {
843     uint16_t csr;
844 
845     if (is_in)
846     {
847         csr = epn->txcsr;
848         csr |= USB_TXCSR_P_WZC_BITS | USB_TXCSR_CLRDATATOG;
849         if (value)
850             csr |= USB_TXCSR_P_SENDSTALL;
851         else
852             csr &= ~(USB_TXCSR_P_SENDSTALL | USB_TXCSR_P_SENTSTALL);
853         csr &= ~USB_TXCSR_TXPKTRDY;
854         epn->txcsr = csr;
855     }
856     else
857     {
858         csr = epn->rxcsr;
859         csr |= USB_RXCSR_P_WZC_BITS | USB_RXCSR_FLUSHFIFO | USB_RXCSR_CLRDATATOG;
860         if (value)
861             csr |= USB_RXCSR_P_SENDSTALL;
862         else
863             csr &= ~(USB_RXCSR_P_SENDSTALL | USB_RXCSR_P_SENTSTALL);
864         epn->rxcsr = csr;
865     }
866 
867 }
868 /**
869   * @brief  Set a STALL condition over an endpoint
870   * @param  hpcd PCD handle
871   * @param  ep_addr endpoint address
872   * @retval HAL status
873   */
HAL_PCD_EP_SetStall(PCD_HandleTypeDef * hpcd,uint8_t ep_addr)874 HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
875 {
876     PCD_EPTypeDef *ep;
877 
878     if ((0x80U & ep_addr) == 0x80U)
879         ep = &hpcd->IN_ep[ep_addr & 0x7FU];
880     else
881         ep = &hpcd->OUT_ep[ep_addr];
882 
883     ep->is_stall = 1;
884     ep->num   = ep_addr & 0x7FU;
885     ep->is_in = ((ep_addr & 0x80U) == 0x80U);
886 
887     __HAL_LOCK(hpcd);
888     if (ep->num)
889     {
890         __IO struct musb_epN_regs *epn = &(hpcd->Instance->ep[ep->num].epN);
891         musb_stall(epn, 1, ep->is_in);
892     }
893     else
894     {
895         __IO struct musb_ep0_regs *ep0 = &(hpcd->Instance->ep[ep->num].ep0);
896         ep0->csr0 |= USB_CSR0_P_SENDSTALL;
897     }
898     __HAL_UNLOCK(hpcd);
899     //ep->is_stall = 0;
900 
901     return HAL_OK;
902 }
903 
904 /**
905   * @brief  Clear a STALL condition over in an endpoint
906   * @param  hpcd PCD handle
907   * @param  ep_addr endpoint address
908   * @retval HAL status
909   */
HAL_PCD_EP_ClrStall(PCD_HandleTypeDef * hpcd,uint8_t ep_addr)910 HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
911 {
912     PCD_EPTypeDef *ep;
913 
914     if ((0x80U & ep_addr) == 0x80U)
915         ep = &hpcd->IN_ep[ep_addr & 0x7FU];
916     else
917         ep = &hpcd->OUT_ep[ep_addr];
918 
919     ep->is_stall = 0U;
920     ep->num   = ep_addr & 0x7FU;
921     ep->is_in = ((ep_addr & 0x80U) == 0x80U);
922 
923     __HAL_LOCK(hpcd);
924     if (ep->num)
925     {
926         __IO struct musb_epN_regs *epn = &(hpcd->Instance->ep[ep->num].epN);
927         musb_stall(epn, 0, ep->is_in);
928     }
929     else
930     {
931         __IO struct musb_ep0_regs *ep0 = &(hpcd->Instance->ep[ep->num].ep0);
932         ep0->csr0 &= ~USB_CSR0_P_SENDSTALL;
933     }
934     __HAL_UNLOCK(hpcd);
935 
936     return HAL_OK;
937 }
938 
939 /**
940   * @brief  Flush an endpoint
941   * @param  hpcd PCD handle
942   * @param  ep_addr endpoint address
943   * @retval HAL status
944   */
HAL_PCD_EP_Flush(PCD_HandleTypeDef * hpcd,uint8_t ep_addr)945 HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
946 {
947     PCD_EPTypeDef *ep;
948     uint16_t csr;
949 
950     if ((0x80U & ep_addr) == 0x80U)
951         ep = &hpcd->IN_ep[ep_addr & 0x7FU];
952     else
953         ep = &hpcd->OUT_ep[ep_addr];
954     __HAL_LOCK(hpcd);
955     if (ep->num)
956     {
957         __IO struct musb_epN_regs *epn = &(hpcd->Instance->ep[ep->num].epN);
958         hpcd->Instance->intrtx &= ~(1 << ep->num);
959         if (ep->is_in)
960         {
961             csr = epn->txcsr;
962             if (csr & USB_TXCSR_FIFONOTEMPTY)
963             {
964                 csr |= USB_TXCSR_FLUSHFIFO | USB_TXCSR_P_WZC_BITS;
965                 csr &= ~USB_TXCSR_TXPKTRDY;
966                 /*
967                     Setting both TXPKTRDY and FLUSHFIFO makes controller
968                     to interrupt current FIFP loading, but not flushing the already loaded ones.
969                 */
970                 epn->txcsr = csr;
971                 /*  REVISIT: may be inapproperiate w/o FIFONOTEMPTY... */
972                 epn->txcsr = csr;
973             }
974         }
975         else
976         {
977             csr = epn->rxcsr;
978             csr |= USB_RXCSR_P_WZC_BITS | USB_RXCSR_FLUSHFIFO;
979             epn->rxcsr = csr;
980             epn->rxcsr = csr;
981         }
982         hpcd->Instance->intrtx |= ~(1 << ep->num);
983     }
984     __HAL_UNLOCK(hpcd);
985 
986     return HAL_OK;
987 }
988 
989 
990 /**
991   * @}
992   */
993 
994 /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions
995  *  @brief   Peripheral State functions
996  *
997 @verbatim
998  ===============================================================================
999                       ##### Peripheral State functions #####
1000  ===============================================================================
1001     [..]
1002     This subsection permits to get in run-time the status of the peripheral
1003     and the data flow.
1004 
1005 @endverbatim
1006   * @{
1007   */
1008 
1009 /**
1010   * @brief  Return the PCD state
1011   * @param  hpcd PCD handle
1012   * @retval HAL state
1013   */
HAL_PCD_GetState(PCD_HandleTypeDef * hpcd)1014 PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd)
1015 {
1016     return hpcd->State;
1017 }
1018 
HAL_PCD_TestMode(PCD_HandleTypeDef * hpcd,uint16_t tm,uint8_t * data,uint8_t len)1019 HAL_StatusTypeDef HAL_PCD_TestMode(PCD_HandleTypeDef *hpcd, uint16_t tm, uint8_t *data, uint8_t len)
1020 {
1021     tm >>= 8;   // The most significant byte is the test mode
1022 
1023     switch (tm)
1024     {
1025     case 1:     // Test_J
1026         hpcd->Instance->testmode = USB_TEST_J;
1027         break;
1028     case 2:     // Test_K
1029         hpcd->Instance->testmode = USB_TEST_K;
1030         break;
1031     case 3:     // Test_SE0_NAK
1032         hpcd->Instance->testmode = USB_TEST_SE0_NAK;
1033         break;
1034     case 4:      // Test_Packet
1035     {
1036         __IO uint8_t *fifo = (__IO uint8_t *) & (hpcd->Instance->fifox[0]);
1037         __IO struct musb_ep0_regs *ep0 = &(hpcd->Instance->ep[0].ep0);
1038         int i;
1039 
1040         for (i = 0; i < len; i++) // REVISIT: Use 16bits/32bits FIFO to speed up
1041             *fifo = *(data + i);
1042         hpcd->Instance->testmode = USB_TEST_PACKET;
1043         ep0->csr0 |= USB_CSR0_TXPKTRDY;
1044         break;
1045     }
1046     case 5:     // Test_Force_Enable.
1047         hpcd->Instance->testmode = USB_TEST_FORCE_FS;
1048         break;
1049     default:    // Reserved
1050         ;
1051     }
1052     return HAL_OK;
1053 }
1054 
1055 /**
1056   * @}
1057   */
1058 
1059 /**
1060   * @}
1061   */
1062 
1063 /** @addtogroup PCD_Private_Functions
1064   * @{
1065   */
1066 
ep0_state_str(uint8_t state)1067 static const char *ep0_state_str(uint8_t state)
1068 {
1069     static const char *states_str[] =
1070     {
1071         "IDLE",
1072         "SETUP",
1073         "TX",
1074         "RX",
1075         "STATUSIN",
1076         "STATUSOUT",
1077         "ACKWAIT",
1078     };
1079     return states_str[state];
1080 }
1081 
1082 
1083 /*
1084  * Handle all control requests with no DATA stage, including standard
1085  * requests such as:
1086  * USB_REQ_SET_CONFIGURATION, USB_REQ_SET_INTERFACE, unrecognized
1087  *  always delegated to the gadget driver
1088  * USB_REQ_SET_ADDRESS, USB_REQ_CLEAR_FEATURE, USB_REQ_SET_FEATURE
1089  *  always handled here, except for class/vendor/... features
1090  *
1091  * Context:  caller holds controller lock
1092  */
1093 static int
service_zero_data_request(PCD_HandleTypeDef * hpcd,struct urequest * req)1094 service_zero_data_request(PCD_HandleTypeDef *hpcd,  struct urequest *req)
1095 {
1096     int handled = -1;
1097     const uint8_t recip = req->request_type & USB_REQ_TYPE_RECIPIENT_MASK;
1098 
1099     /* the gadget driver handles everything except what we MUST handle */
1100     if ((req->request_type & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_STANDARD)
1101     {
1102         switch (req->bRequest)
1103         {
1104         case USB_REQ_SET_ADDRESS:
1105         case USB_REQ_SET_CONFIGURATION:
1106             /* change it after the status stage */
1107             handled = 1;
1108             break;
1109 
1110         case USB_REQ_CLEAR_FEATURE:
1111             switch (recip)
1112             {
1113             case USB_REQ_TYPE_DEVICE:
1114                 if (req->wValue != USB_REMOTE_WAKEUP)
1115                     break;
1116                 handled = 1;
1117                 break;
1118             case USB_REQ_TYPE_INTERFACE:
1119                 break;
1120             case USB_REQ_TYPE_ENDPOINT:
1121             {
1122                 const uint8_t       epnum = req->wIndex & 0x0f;
1123                 uint16_t            csr;
1124                 __IO struct musb_epN_regs *epn = &(hpcd->Instance->ep[epnum].epN);
1125 
1126                 if (epnum == 0 || req->wValue != USB_FEATURE_ENDPOINT_HALT)
1127                     break;
1128                 handled = 1;
1129 
1130                 if (req->wIndex & USB_DIR_IN)
1131                 {
1132                     csr  = epn->txcsr;
1133                     csr |= USB_TXCSR_CLRDATATOG | USB_TXCSR_P_WZC_BITS;
1134                     csr &= ~(USB_TXCSR_P_SENDSTALL | USB_TXCSR_P_SENTSTALL | USB_TXCSR_TXPKTRDY);
1135                     epn->txcsr = csr;
1136                 }
1137                 else
1138                 {
1139                     csr  = epn->rxcsr;
1140                     csr |= USB_RXCSR_CLRDATATOG | USB_RXCSR_P_WZC_BITS;
1141                     csr &= ~(USB_RXCSR_P_SENDSTALL | USB_RXCSR_P_SENTSTALL);
1142                     epn->rxcsr = csr;
1143                 }
1144                 break;
1145             }
1146             default:
1147                 /* class, vendor, etc ... delegate */
1148                 handled = 0;
1149                 break;
1150             }
1151             break;
1152 
1153         case USB_REQ_SET_FEATURE:
1154             switch (recip)
1155             {
1156             case USB_REQ_TYPE_DEVICE:
1157                 handled = 1;
1158                 switch (req->wValue)
1159                 {
1160                 case USB_REMOTE_WAKEUP:
1161                     //musb->may_wakeup = 1;
1162                     break;
1163                 default:
1164                     handled = -1;
1165                     break;
1166                 }
1167                 break;
1168             case USB_REQ_TYPE_INTERFACE:
1169                 break;
1170 
1171             case USB_REQ_TYPE_ENDPOINT:
1172             {
1173                 const uint8_t       epnum = req->wIndex & 0x0f;
1174                 uint16_t            csr;
1175                 __IO struct musb_epN_regs *epn = &(hpcd->Instance->ep[epnum].epN);
1176 
1177                 if (epnum == 0 || req->wValue   != USB_FEATURE_ENDPOINT_HALT)
1178                     break;
1179 
1180                 if (req->wIndex & USB_DIR_IN)
1181                 {
1182                     csr = epn->txcsr;
1183                     if (csr & USB_TXCSR_FIFONOTEMPTY)
1184                         csr |= USB_TXCSR_FLUSHFIFO;
1185                     csr |= (USB_TXCSR_P_SENDSTALL | USB_TXCSR_CLRDATATOG | USB_TXCSR_P_WZC_BITS);
1186                     epn->txcsr = csr;
1187                 }
1188                 else
1189                 {
1190                     csr = epn->rxcsr;
1191                     csr |= (USB_RXCSR_P_SENDSTALL | USB_RXCSR_FLUSHFIFO | USB_RXCSR_CLRDATATOG | USB_RXCSR_P_WZC_BITS);
1192                     epn->rxcsr = csr;
1193                 }
1194                 handled = 1;
1195             }
1196             break;
1197 
1198             default:
1199                 /* class, vendor, etc ... delegate */
1200                 handled = 0;
1201                 break;
1202             }
1203             break;
1204             handled = 1;
1205             break;
1206         default:
1207             handled = 0;
1208         }
1209     }
1210     else
1211         handled = 0;
1212     return handled;
1213 }
1214 
1215 /**
1216   * @brief  This function handles PCD Endpoint 0 interrupt request.
1217   * @param  hpcd PCD handle
1218   * @retval HAL status
1219   */
PCD_EP0_ISR_Handler(PCD_HandleTypeDef * hpcd)1220 static HAL_StatusTypeDef PCD_EP0_ISR_Handler(PCD_HandleTypeDef *hpcd)
1221 {
1222     uint16_t csr;
1223     uint16_t len;
1224 
1225     __IO struct musb_ep0_regs *ep0 = &(hpcd->Instance->ep[0].ep0);
1226     __IO uint8_t *fifox = (__IO uint8_t *) & (hpcd->Instance->fifox[0]);
1227 
1228     csr = ep0->csr0;
1229     len = ep0->count0;
1230 
1231     HAL_DBG_printf("ep0 ISR: %s, csr=0x%x\r\n", ep0_state_str(hpcd->ep0_state), csr);
1232     /*
1233         if DATAEND is set, we should not call the callback,
1234         hence the status stage is not complete.
1235     */
1236     if (csr & USB_CSR0_P_DATAEND)
1237     {
1238         csr |= (~USB_CSR0_P_DATAEND);
1239         //return HAL_OK;//Will cause the failure of sending character descriptors
1240     }
1241 
1242     /*
1243         I sent a stall, need to acknowledge it now..
1244     */
1245     if (csr & USB_CSR0_P_SENTSTALL)
1246     {
1247         ep0->csr0 = (csr & (~USB_CSR0_P_SENTSTALL));
1248         ep0_state_change(hpcd, HAL_PCD_EP0_IDLE);
1249         csr = ep0->csr0;
1250     }
1251 
1252     /* Request ended "early". */
1253     if (csr & USB_CSR0_P_SETUPEND)
1254     {
1255         ep0->csr0 = USB_CSR0_P_SETUPEND;
1256         switch (hpcd->ep0_state)
1257         {
1258         case HAL_PCD_EP0_TX:
1259             ep0_state_change(hpcd, HAL_PCD_EP0_STATUSOUT);
1260             break;
1261         case HAL_PCD_EP0_RX:
1262             ep0_state_change(hpcd, HAL_PCD_EP0_STATUSIN);
1263         case HAL_PCD_EP0_IDLE:
1264             break;
1265         default:
1266             HAL_DBG_printf("SetupEnd case in wrong state %s\r\n", ep0_state_str(hpcd->ep0_state));
1267             break;
1268         }
1269         csr = ep0->csr0;
1270     }
1271 
1272     /*
1273         Docs from Mentor only describe tx,rx, and idle/setup states.
1274         We need to handle nuances around status stage, and also the
1275         case where status and setup stages come back-to-back..
1276     */
1277     switch (hpcd->ep0_state)
1278     {
1279     case HAL_PCD_EP0_TX:
1280         /*ireq on clearing txpktrdy*/
1281         if ((csr & USB_CSR0_TXPKTRDY) == 0)
1282             HAL_PCD_DataInStageCallback(hpcd, 0);
1283         break;
1284     case HAL_PCD_EP0_RX:
1285         /* irq on set rxpktrdy*/
1286         if (csr & USB_CSR0_RXPKTRDY)
1287             HAL_PCD_DataOutStageCallback(hpcd, 0);
1288         break;
1289     case HAL_PCD_EP0_STATUSIN:
1290     // Set USB address ???
1291     case HAL_PCD_EP0_STATUSOUT:
1292     case HAL_PCD_EP0_ACKWAIT:
1293         if (csr & USB_CSR0_RXPKTRDY)
1294             goto setup;
1295         ep0_state_change(hpcd, HAL_PCD_EP0_IDLE);
1296         break;
1297 
1298     case HAL_PCD_EP0_IDLE:
1299         ep0_state_change(hpcd, HAL_PCD_EP0_SETUP);
1300     /*FALL THROUGH*/
1301     case HAL_PCD_EP0_SETUP:
1302 setup:
1303         if (csr & USB_CSR0_RXPKTRDY)
1304         {
1305             uint8_t *p = (uint8_t *)hpcd->Setup;
1306             struct urequest *req = (struct urequest *)p;
1307             int i;
1308 
1309             HAL_ASSERT(len <= 12 * sizeof(uint32_t));
1310             for (i = 0; i < len; i++)
1311                 *(p + i) = *fifox;
1312             HAL_DBG_printf("Setup rx:%d", len);
1313             //HAL_DBG_print_data((char *)p, 0, len);
1314             if (len)
1315             {
1316                 ep0->csr0 = USB_CSR0_P_SVDSETUPEND;
1317                 while ((ep0->csr0 & USB_CSR0_P_SETUPEND) != 0);
1318                 hpcd->ackpend = USB_CSR0_P_SVDRXPKTRDY;
1319                 if (req->wLength == 0)
1320                 {
1321                     if (req->request_type & USB_REQ_TYPE_DIR_IN)
1322                         hpcd->ackpend |= USB_CSR0_TXPKTRDY;
1323                     ep0_state_change(hpcd, HAL_PCD_EP0_ACKWAIT);
1324                 }
1325                 else if (req->request_type & USB_REQ_TYPE_DIR_IN)
1326                 {
1327                     ep0_state_change(hpcd, HAL_PCD_EP0_TX);
1328                     ep0->csr0 = USB_CSR0_P_SVDRXPKTRDY;
1329                     while ((ep0->csr0 & USB_CSR0_RXPKTRDY) != 0);
1330                     hpcd->ackpend = 0;
1331                 }
1332                 else
1333                     ep0_state_change(hpcd, HAL_PCD_EP0_RX);
1334                 switch (hpcd->ep0_state)
1335                 {
1336                 case HAL_PCD_EP0_ACKWAIT:
1337                 {
1338                     int handled = service_zero_data_request(hpcd, req);
1339                     hpcd->ackpend |= USB_CSR0_P_DATAEND;
1340 
1341                     HAL_DBG_printf("Zero data handled %d\r\n", handled);
1342                     if (handled > 0)
1343                     {
1344                         ep0_state_change(hpcd, HAL_PCD_EP0_STATUSIN);
1345                     }
1346                     break;
1347                 }
1348                 case HAL_PCD_EP0_TX:
1349                 {
1350                     /*TODO: validate this*/
1351                     break;
1352                 }
1353                 default:
1354                     break;
1355                 }
1356                 ep0->csr0 = hpcd->ackpend;
1357                 hpcd->ackpend = 0;
1358                 HAL_PCD_SetupStageCallback(hpcd);
1359             }
1360         }
1361         break;
1362     default:
1363         break;
1364     }
1365     return HAL_OK;
1366 }
1367 
musbd_stage0_irq(PCD_HandleTypeDef * hpcd,uint8_t int_usb)1368 static int musbd_stage0_irq(PCD_HandleTypeDef *hpcd, uint8_t int_usb)
1369 {
1370     uint8_t devctl = hpcd->Instance->devctl;
1371     int r = 0;
1372 
1373     if (devctl & USB_DEVCTL_HM)     // No host mode supported yet.
1374         HAL_ASSERT(0);
1375 
1376     if (int_usb & USB_INTR_RESUME)
1377     {
1378         switch (hpcd->phy_state)
1379         {
1380         case OTG_STATE_B_WAIT_ACON:
1381         case OTG_STATE_B_PERIPHERALS:
1382             if ((devctl & USB_DEVCTL_VBUS) != (3 << USB_DEVCTL_VBUS_SHIFT))
1383             {
1384                 hpcd->Instance->intrusb |= USB_INTR_DISCONNECT;
1385                 hpcd->Instance->intrusb &= ~USB_INTR_SUSPEND;
1386             }
1387             // REVISIT: Resume???
1388             break;
1389         case OTG_STATE_B_IDLE:
1390             hpcd->Instance->intrusb &= ~USB_INTR_SUSPEND;
1391             break;
1392         default:
1393             HAL_ASSERT(0);        // Incorrect resume.
1394         }
1395     }
1396 
1397     if (int_usb & USB_INTR_SESSREQ)
1398     {
1399         if (((devctl & USB_DEVCTL_VBUS) == USB_DEVCTL_VBUS) && (devctl & USB_DEVCTL_BDEVICE))
1400             return 1;
1401 
1402         // REVISIT: A device ONLY????
1403         hpcd->Instance->devctl = USB_DEVCTL_SESSION;
1404         ep0_state_change(hpcd, HAL_PCD_EP0_IDLE);
1405         r = 1;
1406     }
1407 
1408     if (int_usb & USB_INTR_VBUSERROR)   // This is for A device only.
1409     {
1410         HAL_ASSERT(0);
1411         r = 1;
1412     }
1413 
1414     if (int_usb & USB_INTR_SUSPEND)
1415     {
1416         r = 1;
1417         switch (hpcd->phy_state)
1418         {
1419         case OTG_STATE_B_PERIPHERALS:
1420             // Go suspend;
1421             hpcd->phy_state = OTG_STATE_B_WAIT_ACON;
1422             break;
1423         case OTG_STATE_B_IDLE:
1424             break;
1425         default:
1426             HAL_DBG_printf("phy_state=%d\r\n", hpcd->phy_state);
1427             HAL_ASSERT(0);        // Should not happen
1428             break;
1429         }
1430     }
1431     if (int_usb & USB_INTR_CONNECT)
1432     {
1433         r = 1;
1434         ep0_state_change(hpcd, HAL_PCD_EP0_IDLE);
1435         HAL_PCD_ConnectCallback(hpcd);
1436         if (int_usb & USB_INTR_SUSPEND)
1437             int_usb &= ~USB_INTR_SUSPEND;
1438     }
1439     if (int_usb & USB_INTR_DISCONNECT)
1440     {
1441         r = 1;
1442         HAL_PCD_DisconnectCallback(hpcd);
1443         hpcd->Instance->devctl = USB_DEVCTL_SESSION;
1444         hpcd->phy_state = OTG_STATE_B_IDLE;
1445     }
1446     if (int_usb & USB_INTR_RESET)
1447     {
1448         r = 1;
1449         switch (hpcd->phy_state)
1450         {
1451         case OTG_STATE_B_WAIT_ACON:
1452         case OTG_STATE_B_PERIPHERALS:
1453         case OTG_STATE_B_IDLE:
1454             hpcd->phy_state = OTG_STATE_B_PERIPHERALS;
1455             ep0_state_change(hpcd, HAL_PCD_EP0_IDLE);
1456             HAL_PCD_ResetCallback(hpcd);
1457             break;
1458         default:
1459             HAL_ASSERT(0);
1460         }
1461     }
1462 
1463     return r;
1464 }
1465 
1466 /**
1467   * @brief  This function handles PCD Endpoint interrupt request.
1468   * @param  hpcd PCD handle
1469   * @retval HAL status
1470   */
PCD_EP_ISR_Handler(PCD_HandleTypeDef * hpcd)1471 static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
1472 {
1473     uint32_t reg;
1474     int ep_num;
1475     uint8_t int_usb = hpcd->Instance->intrusb;
1476     uint16_t int_tx = hpcd->Instance->intrtx;
1477     uint16_t int_rx = hpcd->Instance->intrrx;
1478     uint32_t dmaintr = hpcd->Instance->dmaintr;
1479 
1480     HAL_DBG_printf("USB interrupt usb=%x, tx=%d, rx=%d, usbe=%x, dma_intr=%x\r\n", int_usb, int_tx, int_rx, hpcd->Instance->intrusbe, dmaintr);
1481 
1482     if (int_usb)
1483         musbd_stage0_irq(hpcd, int_usb);
1484 
1485     if (int_tx && (int_tx & 1))
1486         PCD_EP0_ISR_Handler(hpcd);
1487 
1488 #if defined(USB_TX_DMA_ENABLED)||defined(USB_RX_DMA_ENABLED)
1489     reg = (dmaintr >> 1);
1490     ep_num = 1;
1491     while (reg)
1492     {
1493         if (reg & 1)
1494         {
1495             PCD_EPTypeDef *ep;
1496             __IO struct musb_epN_regs *epn = &(hpcd->Instance->ep[ep_num].epN);
1497 
1498             if (hpcd->IN_ep[ep_num].maxpacket)
1499                 ep = &hpcd->IN_ep[ep_num];
1500             else
1501                 ep = &hpcd->OUT_ep[ep_num];
1502 
1503             HAL_DBG_printf("DMA Done on EP: %d, is_in=%d, dmaintr=%x\n", ep->num, ep->is_in, dmaintr);
1504 
1505             if (ep->is_in)
1506             {
1507                 //TX
1508                 if (0 == tx_packet_max)
1509                 {
1510                     uint16_t csr = epn->txcsr;
1511                     csr &= ~USB_TXCSR_P_UNDERRUN;
1512                     csr |= USB_TXCSR_AUTOSET;
1513                     if (ep->xfer_len <= ep->maxpacket)
1514                         csr |= USB_TXCSR_TXPKTRDY;
1515                     epn->txcsr = csr;
1516                 }
1517                 else
1518                 {
1519                     HAL_PCD_DataInStageCallback(hpcd, ep_num);
1520                 }
1521             }
1522             else
1523             {
1524 #ifndef SF32LB58X
1525                 /*Clear RXPKTRDY and send an ACK to the host. 58 cannot be cleared here because there is no time to react.
1526                                             52/56 can be cleared here to increase the rate*/
1527                 if (HAL_PCD_Get_RxbuffControl(ep->num)) //Control the receiving data flow of the channel 1:Control the receiving data flow of the channel;0 Stop receiving
1528                     epn->rxcsr = 0;
1529 #endif
1530                 HAL_PCD_DataOutStageCallback(hpcd, ep_num); //RX
1531             }
1532 
1533         }
1534         ep_num++;
1535         reg >>= 1;
1536     }
1537 #endif
1538 
1539     reg = (int_rx >> 1);
1540     ep_num = 1;
1541     while (reg)
1542     {
1543         if (reg & 1)
1544         {
1545 #if USB_RX_DMA_ENABLED
1546             PCD_EPTypeDef *ep = &hpcd->OUT_ep[ep_num];
1547             struct musb_dma_regs *dma = (struct musb_dma_regs *) & (hpcd->Instance->dma[ep->num]);
1548             __IO struct musb_epN_regs *epn = &(hpcd->Instance->ep[ep->num].epN);
1549 
1550             HAL_DBG_printf("DMA RX pipe=%d, len=%d\n", ep->num,  epn->rxcount);
1551             if (epn->rxcount)
1552             {
1553                 if (IS_DCACHED_RAM(ep->xfer_buff))
1554                     SCB_InvalidateDCache_by_Addr(ep->xfer_buff, epn->rxcount);
1555                 dma->addr = (REG32)ep->xfer_buff;
1556                 dma->count = epn->rxcount;
1557                 ep->xfer_count = dma->count;
1558                 epn->rxcount = 0;
1559                 dma->cntl = (1 << USB_DMACTRL_ENABLE_SHIFT)   |
1560                             (0 << USB_DMACTRL_TRANSMIT_SHIFT) |
1561                             (0 << USB_DMACTRL_MODE1_SHIFT)    |
1562                             (ep->num << USB_DMACTRL_ENDPOINT_SHIFT) |
1563                             (1 << USB_DMACTRL_IRQENABLE_SHIFT);
1564             }
1565 #else
1566             HAL_PCD_DataOutStageCallback(hpcd, ep_num);
1567 #endif
1568 
1569         }
1570         ep_num++;
1571         reg >>= 1;
1572     }
1573 
1574 
1575     reg = (int_tx >> 1);
1576     ep_num = 1;
1577     while (reg)
1578     {
1579         if ((reg & 1) && (0 == tx_packet_max))
1580             HAL_PCD_DataInStageCallback(hpcd, ep_num);
1581         ep_num++;
1582         reg >>= 1;
1583     }
1584     __DSB();
1585     return HAL_OK;
1586 }
1587 
1588 
1589 /**
1590   * @}
1591   */
1592 
1593 /**
1594   * @}
1595   */
1596 
1597 #endif /* HAL_PCD_MODULE_ENABLED */
1598 
1599 /**
1600   * @}
1601   */