1 /**
2   ******************************************************************************
3   * @file    stm32u5xx_hal_pcd.c
4   * @author  MCD Application Team
5   * @brief   PCD HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the USB Peripheral Controller:
8   *           + Initialization and de-initialization functions
9   *           + IO operation functions
10   *           + Peripheral Control functions
11   *           + Peripheral State functions
12   *
13   ******************************************************************************
14   * @attention
15   *
16   * Copyright (c) 2021 STMicroelectronics.
17   * All rights reserved.
18   *
19   * This software is licensed under terms that can be found in the LICENSE file
20   * in the root directory of this software component.
21   * If no LICENSE file comes with this software, it is provided AS-IS.
22   *
23   ******************************************************************************
24   @verbatim
25   ==============================================================================
26                     ##### How to use this driver #####
27   ==============================================================================
28     [..]
29       The PCD HAL driver can be used as follows:
30 
31      (#) Declare a PCD_HandleTypeDef handle structure, for example:
32          PCD_HandleTypeDef  hpcd;
33 
34      (#) Fill parameters of Init structure in HCD handle
35 
36      (#) Call HAL_PCD_Init() API to initialize the PCD peripheral (Core, Device core, ...)
37 
38      (#) Initialize the PCD low level resources through the HAL_PCD_MspInit() API:
39          (##) Enable the PCD/USB Low Level interface clock using
40               (+++) __HAL_RCC_USB_CLK_ENABLE(); For USB Device FS peripheral
41               (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
42               (+++) __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); (For High Speed Mode)
43 
44          (##) Initialize the related GPIO clocks
45          (##) Configure PCD pin-out
46          (##) Configure PCD NVIC interrupt
47 
48      (#)Associate the Upper USB device stack to the HAL PCD Driver:
49          (##) hpcd.pData = pdev;
50 
51      (#)Enable PCD transmission and reception:
52          (##) HAL_PCD_Start();
53 
54   @endverbatim
55   ******************************************************************************
56   */
57 
58 /* Includes ------------------------------------------------------------------*/
59 #include "stm32u5xx_hal.h"
60 
61 /** @addtogroup STM32U5xx_HAL_Driver
62   * @{
63   */
64 
65 /** @defgroup PCD PCD
66   * @brief PCD HAL module driver
67   * @{
68   */
69 
70 #ifdef HAL_PCD_MODULE_ENABLED
71 
72 #if defined (USB_OTG_FS) || defined (USB_OTG_HS) || defined (USB_DRD_FS)
73 
74 /* Private types -------------------------------------------------------------*/
75 /* Private variables ---------------------------------------------------------*/
76 /* Private constants ---------------------------------------------------------*/
77 /* Private macros ------------------------------------------------------------*/
78 /** @defgroup PCD_Private_Macros PCD Private Macros
79   * @{
80   */
81 #define PCD_MIN(a, b)  (((a) < (b)) ? (a) : (b))
82 #define PCD_MAX(a, b)  (((a) > (b)) ? (a) : (b))
83 /**
84   * @}
85   */
86 
87 /* Private functions prototypes ----------------------------------------------*/
88 /** @defgroup PCD_Private_Functions PCD Private Functions
89   * @{
90   */
91 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
92 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum);
93 static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef *hpcd, uint32_t epnum);
94 static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef *hpcd, uint32_t epnum);
95 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
96 
97 #if defined (USB_DRD_FS)
98 static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd);
99 #if (USE_USB_DOUBLE_BUFFER == 1U)
100 static HAL_StatusTypeDef HAL_PCD_EP_DB_Transmit(PCD_HandleTypeDef *hpcd, PCD_EPTypeDef *ep, uint16_t wEPVal);
101 static uint16_t HAL_PCD_EP_DB_Receive(PCD_HandleTypeDef *hpcd, PCD_EPTypeDef *ep, uint16_t wEPVal);
102 #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
103 #endif /* defined (USB_DRD_FS) */
104 /**
105   * @}
106   */
107 
108 /* Exported functions --------------------------------------------------------*/
109 /** @defgroup PCD_Exported_Functions PCD Exported Functions
110   * @{
111   */
112 
113 /** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
114   *  @brief    Initialization and Configuration functions
115   *
116 @verbatim
117  ===============================================================================
118             ##### Initialization and de-initialization functions #####
119  ===============================================================================
120     [..]  This section provides functions allowing to:
121 
122 @endverbatim
123   * @{
124   */
125 
126 /**
127   * @brief  Initializes the PCD according to the specified
128   *         parameters in the PCD_InitTypeDef and initialize the associated handle.
129   * @param  hpcd PCD handle
130   * @retval HAL status
131   */
HAL_PCD_Init(PCD_HandleTypeDef * hpcd)132 HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd)
133 {
134 #if defined (STM32U575xx) || defined (STM32U585xx)
135   USB_OTG_GlobalTypeDef *USBx;
136 #endif /* defined (STM32U575xx) || defined (STM32U585xx) */
137   uint8_t i;
138 
139   /* Check the PCD handle allocation */
140   if (hpcd == NULL)
141   {
142     return HAL_ERROR;
143   }
144 
145   /* Check the parameters */
146   assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance));
147 
148 #if defined (STM32U575xx) || defined (STM32U585xx)
149   USBx = hpcd->Instance;
150 #endif /* defined (STM32U575xx) || defined (STM32U585xx) */
151 
152   if (hpcd->State == HAL_PCD_STATE_RESET)
153   {
154     /* Allocate lock resource and initialize it */
155     hpcd->Lock = HAL_UNLOCKED;
156 
157 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
158     hpcd->SOFCallback = HAL_PCD_SOFCallback;
159     hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
160     hpcd->ResetCallback = HAL_PCD_ResetCallback;
161     hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
162     hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
163     hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
164     hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
165     hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback;
166     hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback;
167     hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback;
168     hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback;
169     hpcd->LPMCallback = HAL_PCDEx_LPM_Callback;
170     hpcd->BCDCallback = HAL_PCDEx_BCD_Callback;
171 
172     if (hpcd->MspInitCallback == NULL)
173     {
174       hpcd->MspInitCallback = HAL_PCD_MspInit;
175     }
176 
177     /* Init the low level hardware */
178     hpcd->MspInitCallback(hpcd);
179 #else
180     /* Init the low level hardware : GPIO, CLOCK, NVIC... */
181     HAL_PCD_MspInit(hpcd);
182 #endif /* (USE_HAL_PCD_REGISTER_CALLBACKS) */
183   }
184 
185   hpcd->State = HAL_PCD_STATE_BUSY;
186 
187 #if defined (STM32U575xx) || defined (STM32U585xx)
188   /* Disable DMA mode for FS instance */
189   if ((USBx->CID & (0x1U << 14)) == 0U)
190   {
191     hpcd->Init.dma_enable = 0U;
192   }
193 #endif /* defined (STM32U575xx) || defined (STM32U585xx) */
194 
195   /* Disable the Interrupts */
196   __HAL_PCD_DISABLE(hpcd);
197 
198   /*Init the Core (common init.) */
199   if (USB_CoreInit(hpcd->Instance, hpcd->Init) != HAL_OK)
200   {
201     hpcd->State = HAL_PCD_STATE_ERROR;
202     return HAL_ERROR;
203   }
204 
205   /* Force Device Mode*/
206   (void)USB_SetCurrentMode(hpcd->Instance, USB_DEVICE_MODE);
207 
208   /* Init endpoints structures */
209   for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
210   {
211     /* Init ep structure */
212     hpcd->IN_ep[i].is_in = 1U;
213     hpcd->IN_ep[i].num = i;
214 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
215     hpcd->IN_ep[i].tx_fifo_num = i;
216 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
217     /* Control until ep is activated */
218     hpcd->IN_ep[i].type = EP_TYPE_CTRL;
219     hpcd->IN_ep[i].maxpacket = 0U;
220     hpcd->IN_ep[i].xfer_buff = 0U;
221     hpcd->IN_ep[i].xfer_len = 0U;
222   }
223 
224   for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
225   {
226     hpcd->OUT_ep[i].is_in = 0U;
227     hpcd->OUT_ep[i].num = i;
228     /* Control until ep is activated */
229     hpcd->OUT_ep[i].type = EP_TYPE_CTRL;
230     hpcd->OUT_ep[i].maxpacket = 0U;
231     hpcd->OUT_ep[i].xfer_buff = 0U;
232     hpcd->OUT_ep[i].xfer_len = 0U;
233   }
234 
235   /* Init Device */
236   if (USB_DevInit(hpcd->Instance, hpcd->Init) != HAL_OK)
237   {
238     hpcd->State = HAL_PCD_STATE_ERROR;
239     return HAL_ERROR;
240   }
241 
242   hpcd->USB_Address = 0U;
243   hpcd->State = HAL_PCD_STATE_READY;
244 
245   /* Activate LPM */
246   if (hpcd->Init.lpm_enable == 1U)
247   {
248     (void)HAL_PCDEx_ActivateLPM(hpcd);
249   }
250 
251   (void)USB_DevDisconnect(hpcd->Instance);
252 
253   return HAL_OK;
254 }
255 
256 /**
257   * @brief  DeInitializes the PCD peripheral.
258   * @param  hpcd PCD handle
259   * @retval HAL status
260   */
HAL_PCD_DeInit(PCD_HandleTypeDef * hpcd)261 HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
262 {
263   /* Check the PCD handle allocation */
264   if (hpcd == NULL)
265   {
266     return HAL_ERROR;
267   }
268 
269   hpcd->State = HAL_PCD_STATE_BUSY;
270 
271   /* Stop Device */
272   if (USB_StopDevice(hpcd->Instance) != HAL_OK)
273   {
274     return HAL_ERROR;
275   }
276 
277 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
278   if (hpcd->MspDeInitCallback == NULL)
279   {
280     hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; /* Legacy weak MspDeInit  */
281   }
282 
283   /* DeInit the low level hardware */
284   hpcd->MspDeInitCallback(hpcd);
285 #else
286   /* DeInit the low level hardware: CLOCK, NVIC.*/
287   HAL_PCD_MspDeInit(hpcd);
288 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
289 
290   hpcd->State = HAL_PCD_STATE_RESET;
291 
292   return HAL_OK;
293 }
294 
295 /**
296   * @brief  Initializes the PCD MSP.
297   * @param  hpcd PCD handle
298   * @retval None
299   */
HAL_PCD_MspInit(PCD_HandleTypeDef * hpcd)300 __weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
301 {
302   /* Prevent unused argument(s) compilation warning */
303   UNUSED(hpcd);
304 
305   /* NOTE : This function should not be modified, when the callback is needed,
306             the HAL_PCD_MspInit could be implemented in the user file
307    */
308 }
309 
310 /**
311   * @brief  DeInitializes PCD MSP.
312   * @param  hpcd PCD handle
313   * @retval None
314   */
HAL_PCD_MspDeInit(PCD_HandleTypeDef * hpcd)315 __weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
316 {
317   /* Prevent unused argument(s) compilation warning */
318   UNUSED(hpcd);
319 
320   /* NOTE : This function should not be modified, when the callback is needed,
321             the HAL_PCD_MspDeInit could be implemented in the user file
322    */
323 }
324 
325 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
326 /**
327   * @brief  Register a User USB PCD Callback
328   *         To be used instead of the weak predefined callback
329   * @param  hpcd USB PCD handle
330   * @param  CallbackID ID of the callback to be registered
331   *         This parameter can be one of the following values:
332   *          @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
333   *          @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
334   *          @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
335   *          @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
336   *          @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
337   *          @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
338   *          @arg @ref HAL_PCD_DISCONNECT_CB_ID USB PCD Disconnect callback ID
339   *          @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
340   *          @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
341   * @param  pCallback pointer to the Callback function
342   * @retval HAL status
343   */
HAL_PCD_RegisterCallback(PCD_HandleTypeDef * hpcd,HAL_PCD_CallbackIDTypeDef CallbackID,pPCD_CallbackTypeDef pCallback)344 HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd,
345                                            HAL_PCD_CallbackIDTypeDef CallbackID,
346                                            pPCD_CallbackTypeDef pCallback)
347 {
348   HAL_StatusTypeDef status = HAL_OK;
349 
350   if (pCallback == NULL)
351   {
352     /* Update the error code */
353     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
354     return HAL_ERROR;
355   }
356   /* Process locked */
357   __HAL_LOCK(hpcd);
358 
359   if (hpcd->State == HAL_PCD_STATE_READY)
360   {
361     switch (CallbackID)
362     {
363       case HAL_PCD_SOF_CB_ID :
364         hpcd->SOFCallback = pCallback;
365         break;
366 
367       case HAL_PCD_SETUPSTAGE_CB_ID :
368         hpcd->SetupStageCallback = pCallback;
369         break;
370 
371       case HAL_PCD_RESET_CB_ID :
372         hpcd->ResetCallback = pCallback;
373         break;
374 
375       case HAL_PCD_SUSPEND_CB_ID :
376         hpcd->SuspendCallback = pCallback;
377         break;
378 
379       case HAL_PCD_RESUME_CB_ID :
380         hpcd->ResumeCallback = pCallback;
381         break;
382 
383       case HAL_PCD_CONNECT_CB_ID :
384         hpcd->ConnectCallback = pCallback;
385         break;
386 
387       case HAL_PCD_DISCONNECT_CB_ID :
388         hpcd->DisconnectCallback = pCallback;
389         break;
390 
391       case HAL_PCD_MSPINIT_CB_ID :
392         hpcd->MspInitCallback = pCallback;
393         break;
394 
395       case HAL_PCD_MSPDEINIT_CB_ID :
396         hpcd->MspDeInitCallback = pCallback;
397         break;
398 
399       default :
400         /* Update the error code */
401         hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
402         /* Return error status */
403         status =  HAL_ERROR;
404         break;
405     }
406   }
407   else if (hpcd->State == HAL_PCD_STATE_RESET)
408   {
409     switch (CallbackID)
410     {
411       case HAL_PCD_MSPINIT_CB_ID :
412         hpcd->MspInitCallback = pCallback;
413         break;
414 
415       case HAL_PCD_MSPDEINIT_CB_ID :
416         hpcd->MspDeInitCallback = pCallback;
417         break;
418 
419       default :
420         /* Update the error code */
421         hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
422         /* Return error status */
423         status =  HAL_ERROR;
424         break;
425     }
426   }
427   else
428   {
429     /* Update the error code */
430     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
431     /* Return error status */
432     status =  HAL_ERROR;
433   }
434 
435   /* Release Lock */
436   __HAL_UNLOCK(hpcd);
437   return status;
438 }
439 
440 /**
441   * @brief  Unregister an USB PCD Callback
442   *         USB PCD callback is redirected to the weak predefined callback
443   * @param  hpcd USB PCD handle
444   * @param  CallbackID ID of the callback to be unregistered
445   *         This parameter can be one of the following values:
446   *          @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
447   *          @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
448   *          @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
449   *          @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
450   *          @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
451   *          @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
452   *          @arg @ref HAL_PCD_DISCONNECT_CB_ID USB PCD Disconnect callback ID
453   *          @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
454   *          @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
455   * @retval HAL status
456   */
HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef * hpcd,HAL_PCD_CallbackIDTypeDef CallbackID)457 HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID)
458 {
459   HAL_StatusTypeDef status = HAL_OK;
460 
461   /* Process locked */
462   __HAL_LOCK(hpcd);
463 
464   /* Setup Legacy weak Callbacks  */
465   if (hpcd->State == HAL_PCD_STATE_READY)
466   {
467     switch (CallbackID)
468     {
469       case HAL_PCD_SOF_CB_ID :
470         hpcd->SOFCallback = HAL_PCD_SOFCallback;
471         break;
472 
473       case HAL_PCD_SETUPSTAGE_CB_ID :
474         hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
475         break;
476 
477       case HAL_PCD_RESET_CB_ID :
478         hpcd->ResetCallback = HAL_PCD_ResetCallback;
479         break;
480 
481       case HAL_PCD_SUSPEND_CB_ID :
482         hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
483         break;
484 
485       case HAL_PCD_RESUME_CB_ID :
486         hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
487         break;
488 
489       case HAL_PCD_CONNECT_CB_ID :
490         hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
491         break;
492 
493       case HAL_PCD_DISCONNECT_CB_ID :
494         hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
495         break;
496 
497       case HAL_PCD_MSPINIT_CB_ID :
498         hpcd->MspInitCallback = HAL_PCD_MspInit;
499         break;
500 
501       case HAL_PCD_MSPDEINIT_CB_ID :
502         hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
503         break;
504 
505       default :
506         /* Update the error code */
507         hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
508 
509         /* Return error status */
510         status =  HAL_ERROR;
511         break;
512     }
513   }
514   else if (hpcd->State == HAL_PCD_STATE_RESET)
515   {
516     switch (CallbackID)
517     {
518       case HAL_PCD_MSPINIT_CB_ID :
519         hpcd->MspInitCallback = HAL_PCD_MspInit;
520         break;
521 
522       case HAL_PCD_MSPDEINIT_CB_ID :
523         hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
524         break;
525 
526       default :
527         /* Update the error code */
528         hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
529 
530         /* Return error status */
531         status =  HAL_ERROR;
532         break;
533     }
534   }
535   else
536   {
537     /* Update the error code */
538     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
539 
540     /* Return error status */
541     status =  HAL_ERROR;
542   }
543 
544   /* Release Lock */
545   __HAL_UNLOCK(hpcd);
546   return status;
547 }
548 
549 /**
550   * @brief  Register USB PCD Data OUT Stage Callback
551   *         To be used instead of the weak HAL_PCD_DataOutStageCallback() predefined callback
552   * @param  hpcd PCD handle
553   * @param  pCallback pointer to the USB PCD Data OUT Stage Callback function
554   * @retval HAL status
555   */
HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef * hpcd,pPCD_DataOutStageCallbackTypeDef pCallback)556 HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd,
557                                                        pPCD_DataOutStageCallbackTypeDef pCallback)
558 {
559   HAL_StatusTypeDef status = HAL_OK;
560 
561   if (pCallback == NULL)
562   {
563     /* Update the error code */
564     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
565 
566     return HAL_ERROR;
567   }
568 
569   /* Process locked */
570   __HAL_LOCK(hpcd);
571 
572   if (hpcd->State == HAL_PCD_STATE_READY)
573   {
574     hpcd->DataOutStageCallback = pCallback;
575   }
576   else
577   {
578     /* Update the error code */
579     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
580 
581     /* Return error status */
582     status =  HAL_ERROR;
583   }
584 
585   /* Release Lock */
586   __HAL_UNLOCK(hpcd);
587 
588   return status;
589 }
590 
591 /**
592   * @brief  Unregister the USB PCD Data OUT Stage Callback
593   *         USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataOutStageCallback() predefined callback
594   * @param  hpcd PCD handle
595   * @retval HAL status
596   */
HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef * hpcd)597 HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd)
598 {
599   HAL_StatusTypeDef status = HAL_OK;
600 
601   /* Process locked */
602   __HAL_LOCK(hpcd);
603 
604   if (hpcd->State == HAL_PCD_STATE_READY)
605   {
606     hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback; /* Legacy weak DataOutStageCallback  */
607   }
608   else
609   {
610     /* Update the error code */
611     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
612 
613     /* Return error status */
614     status =  HAL_ERROR;
615   }
616 
617   /* Release Lock */
618   __HAL_UNLOCK(hpcd);
619 
620   return status;
621 }
622 
623 /**
624   * @brief  Register USB PCD Data IN Stage Callback
625   *         To be used instead of the weak HAL_PCD_DataInStageCallback() predefined callback
626   * @param  hpcd PCD handle
627   * @param  pCallback pointer to the USB PCD Data IN Stage Callback function
628   * @retval HAL status
629   */
HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef * hpcd,pPCD_DataInStageCallbackTypeDef pCallback)630 HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd,
631                                                       pPCD_DataInStageCallbackTypeDef pCallback)
632 {
633   HAL_StatusTypeDef status = HAL_OK;
634 
635   if (pCallback == NULL)
636   {
637     /* Update the error code */
638     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
639 
640     return HAL_ERROR;
641   }
642 
643   /* Process locked */
644   __HAL_LOCK(hpcd);
645 
646   if (hpcd->State == HAL_PCD_STATE_READY)
647   {
648     hpcd->DataInStageCallback = pCallback;
649   }
650   else
651   {
652     /* Update the error code */
653     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
654 
655     /* Return error status */
656     status =  HAL_ERROR;
657   }
658 
659   /* Release Lock */
660   __HAL_UNLOCK(hpcd);
661 
662   return status;
663 }
664 
665 /**
666   * @brief  Unregister the USB PCD Data IN Stage Callback
667   *         USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataInStageCallback() predefined callback
668   * @param  hpcd PCD handle
669   * @retval HAL status
670   */
HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef * hpcd)671 HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd)
672 {
673   HAL_StatusTypeDef status = HAL_OK;
674 
675   /* Process locked */
676   __HAL_LOCK(hpcd);
677 
678   if (hpcd->State == HAL_PCD_STATE_READY)
679   {
680     hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback; /* Legacy weak DataInStageCallback  */
681   }
682   else
683   {
684     /* Update the error code */
685     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
686 
687     /* Return error status */
688     status =  HAL_ERROR;
689   }
690 
691   /* Release Lock */
692   __HAL_UNLOCK(hpcd);
693 
694   return status;
695 }
696 
697 /**
698   * @brief  Register USB PCD Iso OUT incomplete Callback
699   *         To be used instead of the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
700   * @param  hpcd PCD handle
701   * @param  pCallback pointer to the USB PCD Iso OUT incomplete Callback function
702   * @retval HAL status
703   */
HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef * hpcd,pPCD_IsoOutIncpltCallbackTypeDef pCallback)704 HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd,
705                                                        pPCD_IsoOutIncpltCallbackTypeDef pCallback)
706 {
707   HAL_StatusTypeDef status = HAL_OK;
708 
709   if (pCallback == NULL)
710   {
711     /* Update the error code */
712     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
713 
714     return HAL_ERROR;
715   }
716 
717   /* Process locked */
718   __HAL_LOCK(hpcd);
719 
720   if (hpcd->State == HAL_PCD_STATE_READY)
721   {
722     hpcd->ISOOUTIncompleteCallback = pCallback;
723   }
724   else
725   {
726     /* Update the error code */
727     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
728 
729     /* Return error status */
730     status =  HAL_ERROR;
731   }
732 
733   /* Release Lock */
734   __HAL_UNLOCK(hpcd);
735 
736   return status;
737 }
738 
739 /**
740   * @brief  Unregister the USB PCD Iso OUT incomplete Callback
741   *         USB PCD Iso OUT incomplete Callback is redirected
742   *         to the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
743   * @param  hpcd PCD handle
744   * @retval HAL status
745   */
HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef * hpcd)746 HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd)
747 {
748   HAL_StatusTypeDef status = HAL_OK;
749 
750   /* Process locked */
751   __HAL_LOCK(hpcd);
752 
753   if (hpcd->State == HAL_PCD_STATE_READY)
754   {
755     hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback; /* Legacy weak ISOOUTIncompleteCallback  */
756   }
757   else
758   {
759     /* Update the error code */
760     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
761 
762     /* Return error status */
763     status =  HAL_ERROR;
764   }
765 
766   /* Release Lock */
767   __HAL_UNLOCK(hpcd);
768 
769   return status;
770 }
771 
772 /**
773   * @brief  Register USB PCD Iso IN incomplete Callback
774   *         To be used instead of the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
775   * @param  hpcd PCD handle
776   * @param  pCallback pointer to the USB PCD Iso IN incomplete Callback function
777   * @retval HAL status
778   */
HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef * hpcd,pPCD_IsoInIncpltCallbackTypeDef pCallback)779 HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd,
780                                                       pPCD_IsoInIncpltCallbackTypeDef pCallback)
781 {
782   HAL_StatusTypeDef status = HAL_OK;
783 
784   if (pCallback == NULL)
785   {
786     /* Update the error code */
787     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
788 
789     return HAL_ERROR;
790   }
791 
792   /* Process locked */
793   __HAL_LOCK(hpcd);
794 
795   if (hpcd->State == HAL_PCD_STATE_READY)
796   {
797     hpcd->ISOINIncompleteCallback = pCallback;
798   }
799   else
800   {
801     /* Update the error code */
802     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
803 
804     /* Return error status */
805     status =  HAL_ERROR;
806   }
807 
808   /* Release Lock */
809   __HAL_UNLOCK(hpcd);
810 
811   return status;
812 }
813 
814 /**
815   * @brief  Unregister the USB PCD Iso IN incomplete Callback
816   *         USB PCD Iso IN incomplete Callback is redirected
817   *         to the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
818   * @param  hpcd PCD handle
819   * @retval HAL status
820   */
HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef * hpcd)821 HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd)
822 {
823   HAL_StatusTypeDef status = HAL_OK;
824 
825   /* Process locked */
826   __HAL_LOCK(hpcd);
827 
828   if (hpcd->State == HAL_PCD_STATE_READY)
829   {
830     hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback; /* Legacy weak ISOINIncompleteCallback  */
831   }
832   else
833   {
834     /* Update the error code */
835     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
836 
837     /* Return error status */
838     status =  HAL_ERROR;
839   }
840 
841   /* Release Lock */
842   __HAL_UNLOCK(hpcd);
843 
844   return status;
845 }
846 
847 /**
848   * @brief  Register USB PCD BCD Callback
849   *         To be used instead of the weak HAL_PCDEx_BCD_Callback() predefined callback
850   * @param  hpcd PCD handle
851   * @param  pCallback pointer to the USB PCD BCD Callback function
852   * @retval HAL status
853   */
HAL_PCD_RegisterBcdCallback(PCD_HandleTypeDef * hpcd,pPCD_BcdCallbackTypeDef pCallback)854 HAL_StatusTypeDef HAL_PCD_RegisterBcdCallback(PCD_HandleTypeDef *hpcd, pPCD_BcdCallbackTypeDef pCallback)
855 {
856   HAL_StatusTypeDef status = HAL_OK;
857 
858   if (pCallback == NULL)
859   {
860     /* Update the error code */
861     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
862 
863     return HAL_ERROR;
864   }
865 
866   /* Process locked */
867   __HAL_LOCK(hpcd);
868 
869   if (hpcd->State == HAL_PCD_STATE_READY)
870   {
871     hpcd->BCDCallback = pCallback;
872   }
873   else
874   {
875     /* Update the error code */
876     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
877 
878     /* Return error status */
879     status =  HAL_ERROR;
880   }
881 
882   /* Release Lock */
883   __HAL_UNLOCK(hpcd);
884 
885   return status;
886 }
887 
888 /**
889   * @brief  Unregister the USB PCD BCD Callback
890   *         USB BCD Callback is redirected to the weak HAL_PCDEx_BCD_Callback() predefined callback
891   * @param  hpcd PCD handle
892   * @retval HAL status
893   */
HAL_PCD_UnRegisterBcdCallback(PCD_HandleTypeDef * hpcd)894 HAL_StatusTypeDef HAL_PCD_UnRegisterBcdCallback(PCD_HandleTypeDef *hpcd)
895 {
896   HAL_StatusTypeDef status = HAL_OK;
897 
898   /* Process locked */
899   __HAL_LOCK(hpcd);
900 
901   if (hpcd->State == HAL_PCD_STATE_READY)
902   {
903     hpcd->BCDCallback = HAL_PCDEx_BCD_Callback; /* Legacy weak HAL_PCDEx_BCD_Callback  */
904   }
905   else
906   {
907     /* Update the error code */
908     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
909 
910     /* Return error status */
911     status =  HAL_ERROR;
912   }
913 
914   /* Release Lock */
915   __HAL_UNLOCK(hpcd);
916 
917   return status;
918 }
919 
920 /**
921   * @brief  Register USB PCD LPM Callback
922   *         To be used instead of the weak HAL_PCDEx_LPM_Callback() predefined callback
923   * @param  hpcd PCD handle
924   * @param  pCallback pointer to the USB PCD LPM Callback function
925   * @retval HAL status
926   */
HAL_PCD_RegisterLpmCallback(PCD_HandleTypeDef * hpcd,pPCD_LpmCallbackTypeDef pCallback)927 HAL_StatusTypeDef HAL_PCD_RegisterLpmCallback(PCD_HandleTypeDef *hpcd, pPCD_LpmCallbackTypeDef pCallback)
928 {
929   HAL_StatusTypeDef status = HAL_OK;
930 
931   if (pCallback == NULL)
932   {
933     /* Update the error code */
934     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
935 
936     return HAL_ERROR;
937   }
938 
939   /* Process locked */
940   __HAL_LOCK(hpcd);
941 
942   if (hpcd->State == HAL_PCD_STATE_READY)
943   {
944     hpcd->LPMCallback = pCallback;
945   }
946   else
947   {
948     /* Update the error code */
949     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
950 
951     /* Return error status */
952     status =  HAL_ERROR;
953   }
954 
955   /* Release Lock */
956   __HAL_UNLOCK(hpcd);
957 
958   return status;
959 }
960 
961 /**
962   * @brief  Unregister the USB PCD LPM Callback
963   *         USB LPM Callback is redirected to the weak HAL_PCDEx_LPM_Callback() predefined callback
964   * @param  hpcd PCD handle
965   * @retval HAL status
966   */
HAL_PCD_UnRegisterLpmCallback(PCD_HandleTypeDef * hpcd)967 HAL_StatusTypeDef HAL_PCD_UnRegisterLpmCallback(PCD_HandleTypeDef *hpcd)
968 {
969   HAL_StatusTypeDef status = HAL_OK;
970 
971   /* Process locked */
972   __HAL_LOCK(hpcd);
973 
974   if (hpcd->State == HAL_PCD_STATE_READY)
975   {
976     hpcd->LPMCallback = HAL_PCDEx_LPM_Callback; /* Legacy weak HAL_PCDEx_LPM_Callback  */
977   }
978   else
979   {
980     /* Update the error code */
981     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
982 
983     /* Return error status */
984     status =  HAL_ERROR;
985   }
986 
987   /* Release Lock */
988   __HAL_UNLOCK(hpcd);
989 
990   return status;
991 }
992 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
993 
994 /**
995   * @}
996   */
997 
998 /** @defgroup PCD_Exported_Functions_Group2 Input and Output operation functions
999   *  @brief   Data transfers functions
1000   *
1001 @verbatim
1002  ===============================================================================
1003                       ##### IO operation functions #####
1004  ===============================================================================
1005     [..]
1006     This subsection provides a set of functions allowing to manage the PCD data
1007     transfers.
1008 
1009 @endverbatim
1010   * @{
1011   */
1012 
1013 /**
1014   * @brief  Start the USB device
1015   * @param  hpcd PCD handle
1016   * @retval HAL status
1017   */
HAL_PCD_Start(PCD_HandleTypeDef * hpcd)1018 HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)
1019 {
1020 #if defined (STM32U575xx) || defined (STM32U585xx)
1021   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1022 #endif /* defined (STM32U575xx) || defined (STM32U585xx) */
1023 
1024   __HAL_LOCK(hpcd);
1025 #if defined (STM32U575xx) || defined (STM32U585xx)
1026   if (hpcd->Init.battery_charging_enable == 1U)
1027   {
1028     /* Enable USB Transceiver */
1029     USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
1030   }
1031 #endif /* defined (STM32U575xx) || defined (STM32U585xx) */
1032   __HAL_PCD_ENABLE(hpcd);
1033   (void)USB_DevConnect(hpcd->Instance);
1034   __HAL_UNLOCK(hpcd);
1035 
1036   return HAL_OK;
1037 }
1038 
1039 /**
1040   * @brief  Stop the USB device.
1041   * @param  hpcd PCD handle
1042   * @retval HAL status
1043   */
HAL_PCD_Stop(PCD_HandleTypeDef * hpcd)1044 HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
1045 {
1046 #if defined (STM32U575xx) || defined (STM32U585xx)
1047   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1048 #endif /* defined (STM32U575xx) || defined (STM32U585xx) */
1049 
1050   __HAL_LOCK(hpcd);
1051   __HAL_PCD_DISABLE(hpcd);
1052   (void)USB_DevDisconnect(hpcd->Instance);
1053 
1054 
1055 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
1056   (void)USB_FlushTxFifo(hpcd->Instance, 0x10U);
1057 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
1058 
1059 #if defined (STM32U575xx) || defined (STM32U585xx)
1060   if (hpcd->Init.battery_charging_enable == 1U)
1061   {
1062     /* Disable USB Transceiver */
1063     USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
1064   }
1065 #endif /* defined (STM32U575xx) || defined (STM32U585xx) */
1066 
1067   __HAL_UNLOCK(hpcd);
1068 
1069   return HAL_OK;
1070 }
1071 
1072 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
1073 /**
1074   * @brief  Handles PCD interrupt request.
1075   * @param  hpcd PCD handle
1076   * @retval HAL status
1077   */
HAL_PCD_IRQHandler(PCD_HandleTypeDef * hpcd)1078 void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
1079 {
1080   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1081   uint32_t USBx_BASE = (uint32_t)USBx;
1082   USB_OTG_EPTypeDef *ep;
1083   uint32_t i;
1084   uint32_t ep_intr;
1085   uint32_t epint;
1086   uint32_t epnum;
1087   uint32_t fifoemptymsk;
1088   uint32_t RegVal;
1089 
1090   /* ensure that we are in device mode */
1091   if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE)
1092   {
1093     /* avoid spurious interrupt */
1094     if (__HAL_PCD_IS_INVALID_INTERRUPT(hpcd))
1095     {
1096       return;
1097     }
1098 
1099     /* store current frame number */
1100     hpcd->FrameNumber = (USBx_DEVICE->DSTS & USB_OTG_DSTS_FNSOF_Msk) >> USB_OTG_DSTS_FNSOF_Pos;
1101 
1102     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS))
1103     {
1104       /* incorrect mode, acknowledge the interrupt */
1105       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS);
1106     }
1107 
1108     /* Handle RxQLevel Interrupt */
1109     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL))
1110     {
1111       USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
1112 
1113       RegVal = USBx->GRXSTSP;
1114 
1115       ep = &hpcd->OUT_ep[RegVal & USB_OTG_GRXSTSP_EPNUM];
1116 
1117       if (((RegVal & USB_OTG_GRXSTSP_PKTSTS) >> 17) ==  STS_DATA_UPDT)
1118       {
1119         if ((RegVal & USB_OTG_GRXSTSP_BCNT) != 0U)
1120         {
1121           (void)USB_ReadPacket(USBx, ep->xfer_buff,
1122                                (uint16_t)((RegVal & USB_OTG_GRXSTSP_BCNT) >> 4));
1123 
1124           ep->xfer_buff += (RegVal & USB_OTG_GRXSTSP_BCNT) >> 4;
1125           ep->xfer_count += (RegVal & USB_OTG_GRXSTSP_BCNT) >> 4;
1126         }
1127       }
1128       else if (((RegVal & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_SETUP_UPDT)
1129       {
1130         (void)USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8U);
1131         ep->xfer_count += (RegVal & USB_OTG_GRXSTSP_BCNT) >> 4;
1132       }
1133       else
1134       {
1135         /* ... */
1136       }
1137 
1138       USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
1139     }
1140 
1141     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT))
1142     {
1143       epnum = 0U;
1144 
1145       /* Read in the device interrupt bits */
1146       ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance);
1147 
1148       while (ep_intr != 0U)
1149       {
1150         if ((ep_intr & 0x1U) != 0U)
1151         {
1152           epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, (uint8_t)epnum);
1153 
1154           if ((epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC)
1155           {
1156             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC);
1157             (void)PCD_EP_OutXfrComplete_int(hpcd, epnum);
1158           }
1159 
1160           if ((epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP)
1161           {
1162             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP);
1163             /* Class B setup phase done for previous decoded setup */
1164             (void)PCD_EP_OutSetupPacket_int(hpcd, epnum);
1165           }
1166 
1167           if ((epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS)
1168           {
1169             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS);
1170           }
1171 
1172           /* Clear OUT Endpoint disable interrupt */
1173           if ((epint & USB_OTG_DOEPINT_EPDISD) == USB_OTG_DOEPINT_EPDISD)
1174           {
1175             if ((USBx->GINTSTS & USB_OTG_GINTSTS_BOUTNAKEFF) == USB_OTG_GINTSTS_BOUTNAKEFF)
1176             {
1177               USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGONAK;
1178             }
1179 
1180             ep = &hpcd->OUT_ep[epnum];
1181 
1182             if (ep->is_iso_incomplete == 1U)
1183             {
1184               ep->is_iso_incomplete = 0U;
1185 
1186 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1187               hpcd->ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum);
1188 #else
1189               HAL_PCD_ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum);
1190 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1191             }
1192 
1193             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_EPDISD);
1194           }
1195 
1196           /* Clear Status Phase Received interrupt */
1197           if ((epint & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR)
1198           {
1199             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
1200           }
1201 
1202           /* Clear OUT NAK interrupt */
1203           if ((epint & USB_OTG_DOEPINT_NAK) == USB_OTG_DOEPINT_NAK)
1204           {
1205             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_NAK);
1206           }
1207         }
1208         epnum++;
1209         ep_intr >>= 1U;
1210       }
1211     }
1212 
1213     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT))
1214     {
1215       /* Read in the device interrupt bits */
1216       ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance);
1217 
1218       epnum = 0U;
1219 
1220       while (ep_intr != 0U)
1221       {
1222         if ((ep_intr & 0x1U) != 0U) /* In ITR */
1223         {
1224           epint = USB_ReadDevInEPInterrupt(hpcd->Instance, (uint8_t)epnum);
1225 
1226           if ((epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC)
1227           {
1228             fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK));
1229             USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
1230 
1231             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC);
1232 
1233             if (hpcd->Init.dma_enable == 1U)
1234             {
1235               hpcd->IN_ep[epnum].xfer_buff += hpcd->IN_ep[epnum].maxpacket;
1236 
1237               /* this is ZLP, so prepare EP0 for next setup */
1238               if ((epnum == 0U) && (hpcd->IN_ep[epnum].xfer_len == 0U))
1239               {
1240                 /* prepare to rx more setup packets */
1241                 (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup);
1242               }
1243             }
1244 
1245 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1246             hpcd->DataInStageCallback(hpcd, (uint8_t)epnum);
1247 #else
1248             HAL_PCD_DataInStageCallback(hpcd, (uint8_t)epnum);
1249 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1250           }
1251           if ((epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC)
1252           {
1253             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC);
1254           }
1255           if ((epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE)
1256           {
1257             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE);
1258           }
1259           if ((epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE)
1260           {
1261             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE);
1262           }
1263           if ((epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD)
1264           {
1265             (void)USB_FlushTxFifo(USBx, epnum);
1266 
1267             ep = &hpcd->IN_ep[epnum];
1268 
1269             if (ep->is_iso_incomplete == 1U)
1270             {
1271               ep->is_iso_incomplete = 0U;
1272 
1273 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1274               hpcd->ISOINIncompleteCallback(hpcd, (uint8_t)epnum);
1275 #else
1276               HAL_PCD_ISOINIncompleteCallback(hpcd, (uint8_t)epnum);
1277 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1278             }
1279 
1280             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD);
1281           }
1282           if ((epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE)
1283           {
1284             (void)PCD_WriteEmptyTxFifo(hpcd, epnum);
1285           }
1286         }
1287         epnum++;
1288         ep_intr >>= 1U;
1289       }
1290     }
1291 
1292     /* Handle Resume Interrupt */
1293     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT))
1294     {
1295       /* Clear the Remote Wake-up Signaling */
1296       USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
1297 
1298       if (hpcd->LPM_State == LPM_L1)
1299       {
1300         hpcd->LPM_State = LPM_L0;
1301 
1302 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1303         hpcd->LPMCallback(hpcd, PCD_LPM_L0_ACTIVE);
1304 #else
1305         HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE);
1306 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1307       }
1308       else
1309       {
1310 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1311         hpcd->ResumeCallback(hpcd);
1312 #else
1313         HAL_PCD_ResumeCallback(hpcd);
1314 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1315       }
1316 
1317       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT);
1318     }
1319 
1320     /* Handle Suspend Interrupt */
1321     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP))
1322     {
1323       if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
1324       {
1325 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1326         hpcd->SuspendCallback(hpcd);
1327 #else
1328         HAL_PCD_SuspendCallback(hpcd);
1329 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1330       }
1331       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP);
1332     }
1333 
1334     /* Handle LPM Interrupt */
1335     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT))
1336     {
1337       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT);
1338 
1339       if (hpcd->LPM_State == LPM_L0)
1340       {
1341         hpcd->LPM_State = LPM_L1;
1342         hpcd->BESL = (hpcd->Instance->GLPMCFG & USB_OTG_GLPMCFG_BESL) >> 2U;
1343 
1344 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1345         hpcd->LPMCallback(hpcd, PCD_LPM_L1_ACTIVE);
1346 #else
1347         HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE);
1348 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1349       }
1350       else
1351       {
1352 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1353         hpcd->SuspendCallback(hpcd);
1354 #else
1355         HAL_PCD_SuspendCallback(hpcd);
1356 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1357       }
1358     }
1359 
1360     /* Handle Reset Interrupt */
1361     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST))
1362     {
1363       USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
1364       (void)USB_FlushTxFifo(hpcd->Instance, 0x10U);
1365 
1366       for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
1367       {
1368         USBx_INEP(i)->DIEPINT = 0xFB7FU;
1369         USBx_INEP(i)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
1370         USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
1371         USBx_OUTEP(i)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
1372         USBx_OUTEP(i)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
1373       }
1374       USBx_DEVICE->DAINTMSK |= 0x10001U;
1375 
1376       if (hpcd->Init.use_dedicated_ep1 != 0U)
1377       {
1378         USBx_DEVICE->DOUTEP1MSK |= USB_OTG_DOEPMSK_STUPM |
1379                                    USB_OTG_DOEPMSK_XFRCM |
1380                                    USB_OTG_DOEPMSK_EPDM;
1381 
1382         USBx_DEVICE->DINEP1MSK |= USB_OTG_DIEPMSK_TOM |
1383                                   USB_OTG_DIEPMSK_XFRCM |
1384                                   USB_OTG_DIEPMSK_EPDM;
1385       }
1386       else
1387       {
1388         USBx_DEVICE->DOEPMSK |= USB_OTG_DOEPMSK_STUPM |
1389                                 USB_OTG_DOEPMSK_XFRCM |
1390                                 USB_OTG_DOEPMSK_EPDM |
1391                                 USB_OTG_DOEPMSK_OTEPSPRM |
1392                                 USB_OTG_DOEPMSK_NAKM;
1393 
1394         USBx_DEVICE->DIEPMSK |= USB_OTG_DIEPMSK_TOM |
1395                                 USB_OTG_DIEPMSK_XFRCM |
1396                                 USB_OTG_DIEPMSK_EPDM;
1397       }
1398 
1399       /* Set Default Address to 0 */
1400       USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD;
1401 
1402       /* setup EP0 to receive SETUP packets */
1403       (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t)hpcd->Init.dma_enable,
1404                              (uint8_t *)hpcd->Setup);
1405 
1406       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST);
1407     }
1408 
1409     /* Handle Enumeration done Interrupt */
1410     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE))
1411     {
1412       (void)USB_ActivateSetup(hpcd->Instance);
1413       hpcd->Init.speed = USB_GetDevSpeed(hpcd->Instance);
1414 
1415       /* Set USB Turnaround time */
1416       (void)USB_SetTurnaroundTime(hpcd->Instance,
1417                                   HAL_RCC_GetHCLKFreq(),
1418                                   (uint8_t)hpcd->Init.speed);
1419 
1420 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1421       hpcd->ResetCallback(hpcd);
1422 #else
1423       HAL_PCD_ResetCallback(hpcd);
1424 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1425 
1426       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE);
1427     }
1428 
1429     /* Handle SOF Interrupt */
1430     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF))
1431     {
1432 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1433       hpcd->SOFCallback(hpcd);
1434 #else
1435       HAL_PCD_SOFCallback(hpcd);
1436 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1437 
1438       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF);
1439     }
1440 
1441     /* Handle Global OUT NAK effective Interrupt */
1442     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_BOUTNAKEFF))
1443     {
1444       USBx->GINTMSK &= ~USB_OTG_GINTMSK_GONAKEFFM;
1445 
1446       for (epnum = 1U; epnum < hpcd->Init.dev_endpoints; epnum++)
1447       {
1448         if (hpcd->OUT_ep[epnum].is_iso_incomplete == 1U)
1449         {
1450           /* Abort current transaction and disable the EP */
1451           (void)HAL_PCD_EP_Abort(hpcd, (uint8_t)epnum);
1452         }
1453       }
1454     }
1455 
1456     /* Handle Incomplete ISO IN Interrupt */
1457     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR))
1458     {
1459       for (epnum = 1U; epnum < hpcd->Init.dev_endpoints; epnum++)
1460       {
1461         RegVal = USBx_INEP(epnum)->DIEPCTL;
1462 
1463         if ((hpcd->IN_ep[epnum].type == EP_TYPE_ISOC) &&
1464             ((RegVal & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA))
1465         {
1466           hpcd->IN_ep[epnum].is_iso_incomplete = 1U;
1467 
1468           /* Abort current transaction and disable the EP */
1469           (void)HAL_PCD_EP_Abort(hpcd, (uint8_t)(epnum | 0x80U));
1470         }
1471       }
1472 
1473       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR);
1474     }
1475 
1476     /* Handle Incomplete ISO OUT Interrupt */
1477     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
1478     {
1479       for (epnum = 1U; epnum < hpcd->Init.dev_endpoints; epnum++)
1480       {
1481         RegVal = USBx_OUTEP(epnum)->DOEPCTL;
1482 
1483         if ((hpcd->OUT_ep[epnum].type == EP_TYPE_ISOC) &&
1484             ((RegVal & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA) &&
1485             ((RegVal & (0x1U << 16)) == (hpcd->FrameNumber & 0x1U)))
1486         {
1487           hpcd->OUT_ep[epnum].is_iso_incomplete = 1U;
1488 
1489           USBx->GINTMSK |= USB_OTG_GINTMSK_GONAKEFFM;
1490 
1491           if ((USBx->GINTSTS & USB_OTG_GINTSTS_BOUTNAKEFF) == 0U)
1492           {
1493             USBx_DEVICE->DCTL |= USB_OTG_DCTL_SGONAK;
1494             break;
1495           }
1496         }
1497       }
1498 
1499       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
1500     }
1501 
1502     /* Handle Connection event Interrupt */
1503     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT))
1504     {
1505 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1506       hpcd->ConnectCallback(hpcd);
1507 #else
1508       HAL_PCD_ConnectCallback(hpcd);
1509 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1510 
1511       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT);
1512     }
1513 
1514     /* Handle Disconnection event Interrupt */
1515     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT))
1516     {
1517       RegVal = hpcd->Instance->GOTGINT;
1518 
1519       if ((RegVal & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET)
1520       {
1521 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1522         hpcd->DisconnectCallback(hpcd);
1523 #else
1524         HAL_PCD_DisconnectCallback(hpcd);
1525 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1526       }
1527       hpcd->Instance->GOTGINT |= RegVal;
1528     }
1529   }
1530 }
1531 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
1532 
1533 #if defined (USB_DRD_FS)
1534 /**
1535   * @brief  This function handles PCD interrupt request.
1536   * @param  hpcd PCD handle
1537   * @retval HAL status
1538   */
HAL_PCD_IRQHandler(PCD_HandleTypeDef * hpcd)1539 void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
1540 {
1541   uint32_t wIstr = USB_ReadInterrupts(hpcd->Instance);
1542 
1543   if ((wIstr & USB_ISTR_CTR) == USB_ISTR_CTR)
1544   {
1545     /* servicing of the endpoint correct transfer interrupt */
1546     /* clear of the CTR flag into the sub */
1547     (void)PCD_EP_ISR_Handler(hpcd);
1548 
1549     return;
1550   }
1551 
1552   if ((wIstr & USB_ISTR_RESET) == USB_ISTR_RESET)
1553   {
1554     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET);
1555 
1556 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1557     hpcd->ResetCallback(hpcd);
1558 #else
1559     HAL_PCD_ResetCallback(hpcd);
1560 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1561 
1562     (void)HAL_PCD_SetAddress(hpcd, 0U);
1563 
1564     return;
1565   }
1566 
1567   if ((wIstr & USB_ISTR_PMAOVR) == USB_ISTR_PMAOVR)
1568   {
1569     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_PMAOVR);
1570 
1571     return;
1572   }
1573 
1574   if ((wIstr & USB_ISTR_ERR) == USB_ISTR_ERR)
1575   {
1576     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ERR);
1577 
1578     return;
1579   }
1580 
1581   if ((wIstr & USB_ISTR_WKUP) == USB_ISTR_WKUP)
1582   {
1583     hpcd->Instance->CNTR &= ~(USB_CNTR_SUSPRDY);
1584     hpcd->Instance->CNTR &= ~(USB_CNTR_SUSPEN);
1585 
1586     if (hpcd->LPM_State == LPM_L1)
1587     {
1588       hpcd->LPM_State = LPM_L0;
1589 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1590       hpcd->LPMCallback(hpcd, PCD_LPM_L0_ACTIVE);
1591 #else
1592       HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE);
1593 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1594     }
1595 
1596 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1597     hpcd->ResumeCallback(hpcd);
1598 #else
1599     HAL_PCD_ResumeCallback(hpcd);
1600 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1601 
1602     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP);
1603 
1604     return;
1605   }
1606 
1607   if ((wIstr & USB_ISTR_SUSP) == USB_ISTR_SUSP)
1608   {
1609     /* Force low-power mode in the macrocell */
1610     hpcd->Instance->CNTR |= USB_CNTR_SUSPEN;
1611 
1612     /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
1613     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SUSP);
1614 
1615     hpcd->Instance->CNTR |= USB_CNTR_SUSPRDY;
1616 
1617 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1618     hpcd->SuspendCallback(hpcd);
1619 #else
1620     HAL_PCD_SuspendCallback(hpcd);
1621 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1622 
1623     return;
1624   }
1625 
1626   /* Handle LPM Interrupt */
1627   if ((wIstr & USB_ISTR_L1REQ) == USB_ISTR_L1REQ)
1628   {
1629     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_L1REQ);
1630     if (hpcd->LPM_State == LPM_L0)
1631     {
1632       /* Force suspend and low-power mode before going to L1 state*/
1633       hpcd->Instance->CNTR |= USB_CNTR_SUSPRDY;
1634       hpcd->Instance->CNTR |= USB_CNTR_SUSPEN;
1635 
1636       hpcd->LPM_State = LPM_L1;
1637       hpcd->BESL = ((uint32_t)hpcd->Instance->LPMCSR & USB_LPMCSR_BESL) >> 2;
1638 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1639       hpcd->LPMCallback(hpcd, PCD_LPM_L1_ACTIVE);
1640 #else
1641       HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE);
1642 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1643     }
1644     else
1645     {
1646 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1647       hpcd->SuspendCallback(hpcd);
1648 #else
1649       HAL_PCD_SuspendCallback(hpcd);
1650 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1651     }
1652 
1653     return;
1654   }
1655 
1656   if ((wIstr & USB_ISTR_SOF) == USB_ISTR_SOF)
1657   {
1658     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SOF);
1659 
1660 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1661     hpcd->SOFCallback(hpcd);
1662 #else
1663     HAL_PCD_SOFCallback(hpcd);
1664 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1665 
1666     return;
1667   }
1668 
1669   if ((wIstr & USB_ISTR_ESOF) == USB_ISTR_ESOF)
1670   {
1671     /* clear ESOF flag in ISTR */
1672     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ESOF);
1673 
1674     return;
1675   }
1676 }
1677 #endif /* defined (USB_DRD_FS) */
1678 
1679 /**
1680   * @brief  Data OUT stage callback.
1681   * @param  hpcd PCD handle
1682   * @param  epnum endpoint number
1683   * @retval None
1684   */
HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef * hpcd,uint8_t epnum)1685 __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
1686 {
1687   /* Prevent unused argument(s) compilation warning */
1688   UNUSED(hpcd);
1689   UNUSED(epnum);
1690 
1691   /* NOTE : This function should not be modified, when the callback is needed,
1692             the HAL_PCD_DataOutStageCallback could be implemented in the user file
1693    */
1694 }
1695 
1696 /**
1697   * @brief  Data IN stage callback
1698   * @param  hpcd PCD handle
1699   * @param  epnum endpoint number
1700   * @retval None
1701   */
HAL_PCD_DataInStageCallback(PCD_HandleTypeDef * hpcd,uint8_t epnum)1702 __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
1703 {
1704   /* Prevent unused argument(s) compilation warning */
1705   UNUSED(hpcd);
1706   UNUSED(epnum);
1707 
1708   /* NOTE : This function should not be modified, when the callback is needed,
1709             the HAL_PCD_DataInStageCallback could be implemented in the user file
1710    */
1711 }
1712 /**
1713   * @brief  Setup stage callback
1714   * @param  hpcd PCD handle
1715   * @retval None
1716   */
HAL_PCD_SetupStageCallback(PCD_HandleTypeDef * hpcd)1717 __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
1718 {
1719   /* Prevent unused argument(s) compilation warning */
1720   UNUSED(hpcd);
1721 
1722   /* NOTE : This function should not be modified, when the callback is needed,
1723             the HAL_PCD_SetupStageCallback could be implemented in the user file
1724    */
1725 }
1726 
1727 /**
1728   * @brief  USB Start Of Frame callback.
1729   * @param  hpcd PCD handle
1730   * @retval None
1731   */
HAL_PCD_SOFCallback(PCD_HandleTypeDef * hpcd)1732 __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
1733 {
1734   /* Prevent unused argument(s) compilation warning */
1735   UNUSED(hpcd);
1736 
1737   /* NOTE : This function should not be modified, when the callback is needed,
1738             the HAL_PCD_SOFCallback could be implemented in the user file
1739    */
1740 }
1741 
1742 /**
1743   * @brief  USB Reset callback.
1744   * @param  hpcd PCD handle
1745   * @retval None
1746   */
HAL_PCD_ResetCallback(PCD_HandleTypeDef * hpcd)1747 __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
1748 {
1749   /* Prevent unused argument(s) compilation warning */
1750   UNUSED(hpcd);
1751 
1752   /* NOTE : This function should not be modified, when the callback is needed,
1753             the HAL_PCD_ResetCallback could be implemented in the user file
1754    */
1755 }
1756 
1757 /**
1758   * @brief  Suspend event callback.
1759   * @param  hpcd PCD handle
1760   * @retval None
1761   */
HAL_PCD_SuspendCallback(PCD_HandleTypeDef * hpcd)1762 __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
1763 {
1764   /* Prevent unused argument(s) compilation warning */
1765   UNUSED(hpcd);
1766 
1767   /* NOTE : This function should not be modified, when the callback is needed,
1768             the HAL_PCD_SuspendCallback could be implemented in the user file
1769    */
1770 }
1771 
1772 /**
1773   * @brief  Resume event callback.
1774   * @param  hpcd PCD handle
1775   * @retval None
1776   */
HAL_PCD_ResumeCallback(PCD_HandleTypeDef * hpcd)1777 __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
1778 {
1779   /* Prevent unused argument(s) compilation warning */
1780   UNUSED(hpcd);
1781 
1782   /* NOTE : This function should not be modified, when the callback is needed,
1783             the HAL_PCD_ResumeCallback could be implemented in the user file
1784    */
1785 }
1786 
1787 /**
1788   * @brief  Incomplete ISO OUT callback.
1789   * @param  hpcd PCD handle
1790   * @param  epnum endpoint number
1791   * @retval None
1792   */
HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef * hpcd,uint8_t epnum)1793 __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
1794 {
1795   /* Prevent unused argument(s) compilation warning */
1796   UNUSED(hpcd);
1797   UNUSED(epnum);
1798 
1799   /* NOTE : This function should not be modified, when the callback is needed,
1800             the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file
1801    */
1802 }
1803 
1804 /**
1805   * @brief  Incomplete ISO IN callback.
1806   * @param  hpcd PCD handle
1807   * @param  epnum endpoint number
1808   * @retval None
1809   */
HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef * hpcd,uint8_t epnum)1810 __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
1811 {
1812   /* Prevent unused argument(s) compilation warning */
1813   UNUSED(hpcd);
1814   UNUSED(epnum);
1815 
1816   /* NOTE : This function should not be modified, when the callback is needed,
1817             the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file
1818    */
1819 }
1820 
1821 /**
1822   * @brief  Connection event callback.
1823   * @param  hpcd PCD handle
1824   * @retval None
1825   */
HAL_PCD_ConnectCallback(PCD_HandleTypeDef * hpcd)1826 __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
1827 {
1828   /* Prevent unused argument(s) compilation warning */
1829   UNUSED(hpcd);
1830 
1831   /* NOTE : This function should not be modified, when the callback is needed,
1832             the HAL_PCD_ConnectCallback could be implemented in the user file
1833    */
1834 }
1835 
1836 /**
1837   * @brief  Disconnection event callback.
1838   * @param  hpcd PCD handle
1839   * @retval None
1840   */
HAL_PCD_DisconnectCallback(PCD_HandleTypeDef * hpcd)1841 __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
1842 {
1843   /* Prevent unused argument(s) compilation warning */
1844   UNUSED(hpcd);
1845 
1846   /* NOTE : This function should not be modified, when the callback is needed,
1847             the HAL_PCD_DisconnectCallback could be implemented in the user file
1848    */
1849 }
1850 
1851 /**
1852   * @}
1853   */
1854 
1855 /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
1856   *  @brief   management functions
1857   *
1858 @verbatim
1859  ===============================================================================
1860                       ##### Peripheral Control functions #####
1861  ===============================================================================
1862     [..]
1863     This subsection provides a set of functions allowing to control the PCD data
1864     transfers.
1865 
1866 @endverbatim
1867   * @{
1868   */
1869 
1870 /**
1871   * @brief  Connect the USB device
1872   * @param  hpcd PCD handle
1873   * @retval HAL status
1874   */
HAL_PCD_DevConnect(PCD_HandleTypeDef * hpcd)1875 HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd)
1876 {
1877 #if defined (STM32U575xx) || defined (STM32U585xx)
1878   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1879 #endif /* defined (STM32U575xx) || defined (STM32U585xx) */
1880 
1881   __HAL_LOCK(hpcd);
1882 
1883 #if defined (STM32U575xx) || defined (STM32U585xx)
1884   if (hpcd->Init.battery_charging_enable == 1U)
1885   {
1886     /* Enable USB Transceiver */
1887     USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
1888   }
1889 #endif /* defined (STM32U575xx) || defined (STM32U585xx) */
1890 
1891   (void)USB_DevConnect(hpcd->Instance);
1892   __HAL_UNLOCK(hpcd);
1893 
1894   return HAL_OK;
1895 }
1896 
1897 /**
1898   * @brief  Disconnect the USB device.
1899   * @param  hpcd PCD handle
1900   * @retval HAL status
1901   */
HAL_PCD_DevDisconnect(PCD_HandleTypeDef * hpcd)1902 HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd)
1903 {
1904 #if defined (STM32U575xx) || defined (STM32U585xx)
1905   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1906 #endif /* defined (STM32U575xx) || defined (STM32U585xx) */
1907 
1908   __HAL_LOCK(hpcd);
1909   (void)USB_DevDisconnect(hpcd->Instance);
1910 
1911 #if defined (STM32U575xx) || defined (STM32U585xx)
1912   if (hpcd->Init.battery_charging_enable == 1U)
1913   {
1914     /* Disable USB Transceiver */
1915     USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
1916   }
1917 #endif /* defined (STM32U575xx) || defined (STM32U585xx) */
1918 
1919   __HAL_UNLOCK(hpcd);
1920 
1921   return HAL_OK;
1922 }
1923 
1924 /**
1925   * @brief  Set the USB Device address.
1926   * @param  hpcd PCD handle
1927   * @param  address new device address
1928   * @retval HAL status
1929   */
HAL_PCD_SetAddress(PCD_HandleTypeDef * hpcd,uint8_t address)1930 HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)
1931 {
1932   __HAL_LOCK(hpcd);
1933   hpcd->USB_Address = address;
1934   (void)USB_SetDevAddress(hpcd->Instance, address);
1935   __HAL_UNLOCK(hpcd);
1936 
1937   return HAL_OK;
1938 }
1939 /**
1940   * @brief  Open and configure an endpoint.
1941   * @param  hpcd PCD handle
1942   * @param  ep_addr endpoint address
1943   * @param  ep_mps endpoint max packet size
1944   * @param  ep_type endpoint type
1945   * @retval HAL status
1946   */
HAL_PCD_EP_Open(PCD_HandleTypeDef * hpcd,uint8_t ep_addr,uint16_t ep_mps,uint8_t ep_type)1947 HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr,
1948                                   uint16_t ep_mps, uint8_t ep_type)
1949 {
1950   HAL_StatusTypeDef  ret = HAL_OK;
1951   PCD_EPTypeDef *ep;
1952 
1953   if ((ep_addr & 0x80U) == 0x80U)
1954   {
1955     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
1956     ep->is_in = 1U;
1957   }
1958   else
1959   {
1960     ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
1961     ep->is_in = 0U;
1962   }
1963 
1964   ep->num = ep_addr & EP_ADDR_MSK;
1965   ep->maxpacket = ep_mps;
1966   ep->type = ep_type;
1967 
1968 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
1969   if (ep->is_in != 0U)
1970   {
1971     /* Assign a Tx FIFO */
1972     ep->tx_fifo_num = ep->num;
1973   }
1974 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
1975 
1976   /* Set initial data PID. */
1977   if (ep_type == EP_TYPE_BULK)
1978   {
1979     ep->data_pid_start = 0U;
1980   }
1981 
1982   __HAL_LOCK(hpcd);
1983   (void)USB_ActivateEndpoint(hpcd->Instance, ep);
1984   __HAL_UNLOCK(hpcd);
1985 
1986   return ret;
1987 }
1988 
1989 /**
1990   * @brief  Deactivate an endpoint.
1991   * @param  hpcd PCD handle
1992   * @param  ep_addr endpoint address
1993   * @retval HAL status
1994   */
HAL_PCD_EP_Close(PCD_HandleTypeDef * hpcd,uint8_t ep_addr)1995 HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1996 {
1997   PCD_EPTypeDef *ep;
1998 
1999   if ((ep_addr & 0x80U) == 0x80U)
2000   {
2001     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
2002     ep->is_in = 1U;
2003   }
2004   else
2005   {
2006     ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
2007     ep->is_in = 0U;
2008   }
2009   ep->num = ep_addr & EP_ADDR_MSK;
2010 
2011   __HAL_LOCK(hpcd);
2012   (void)USB_DeactivateEndpoint(hpcd->Instance, ep);
2013   __HAL_UNLOCK(hpcd);
2014   return HAL_OK;
2015 }
2016 
2017 
2018 /**
2019   * @brief  Receive an amount of data.
2020   * @param  hpcd PCD handle
2021   * @param  ep_addr endpoint address
2022   * @param  pBuf pointer to the reception buffer
2023   * @param  len amount of data to be received
2024   * @retval HAL status
2025   */
HAL_PCD_EP_Receive(PCD_HandleTypeDef * hpcd,uint8_t ep_addr,uint8_t * pBuf,uint32_t len)2026 HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
2027 {
2028   PCD_EPTypeDef *ep;
2029 
2030   ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
2031 
2032   /*setup and start the Xfer */
2033   ep->xfer_buff = pBuf;
2034   ep->xfer_len = len;
2035   ep->xfer_count = 0U;
2036   ep->is_in = 0U;
2037   ep->num = ep_addr & EP_ADDR_MSK;
2038 
2039 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
2040   if (hpcd->Init.dma_enable == 1U)
2041   {
2042     ep->dma_addr = (uint32_t)pBuf;
2043   }
2044 
2045   (void)USB_EPStartXfer(hpcd->Instance, ep, (uint8_t)hpcd->Init.dma_enable);
2046 #else
2047   (void)USB_EPStartXfer(hpcd->Instance, ep);
2048 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2049 
2050   return HAL_OK;
2051 }
2052 
2053 /**
2054   * @brief  Get Received Data Size
2055   * @param  hpcd PCD handle
2056   * @param  ep_addr endpoint address
2057   * @retval Data Size
2058   */
HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef const * hpcd,uint8_t ep_addr)2059 uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef const *hpcd, uint8_t ep_addr)
2060 {
2061   return hpcd->OUT_ep[ep_addr & EP_ADDR_MSK].xfer_count;
2062 }
2063 /**
2064   * @brief  Send an amount of data
2065   * @param  hpcd PCD handle
2066   * @param  ep_addr endpoint address
2067   * @param  pBuf pointer to the transmission buffer
2068   * @param  len amount of data to be sent
2069   * @retval HAL status
2070   */
HAL_PCD_EP_Transmit(PCD_HandleTypeDef * hpcd,uint8_t ep_addr,uint8_t * pBuf,uint32_t len)2071 HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
2072 {
2073   PCD_EPTypeDef *ep;
2074 
2075   ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
2076 
2077   /*setup and start the Xfer */
2078   ep->xfer_buff = pBuf;
2079   ep->xfer_len = len;
2080 #if defined (USB_DRD_FS)
2081   ep->xfer_fill_db = 1U;
2082   ep->xfer_len_db = len;
2083 #endif /* defined (USB_DRD_FS) */
2084   ep->xfer_count = 0U;
2085   ep->is_in = 1U;
2086   ep->num = ep_addr & EP_ADDR_MSK;
2087 
2088 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
2089   if (hpcd->Init.dma_enable == 1U)
2090   {
2091     ep->dma_addr = (uint32_t)pBuf;
2092   }
2093 
2094   (void)USB_EPStartXfer(hpcd->Instance, ep, (uint8_t)hpcd->Init.dma_enable);
2095 #else
2096   (void)USB_EPStartXfer(hpcd->Instance, ep);
2097 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2098 
2099   return HAL_OK;
2100 }
2101 
2102 /**
2103   * @brief  Set a STALL condition over an endpoint
2104   * @param  hpcd PCD handle
2105   * @param  ep_addr endpoint address
2106   * @retval HAL status
2107   */
HAL_PCD_EP_SetStall(PCD_HandleTypeDef * hpcd,uint8_t ep_addr)2108 HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
2109 {
2110   PCD_EPTypeDef *ep;
2111 
2112   if (((uint32_t)ep_addr & EP_ADDR_MSK) > hpcd->Init.dev_endpoints)
2113   {
2114     return HAL_ERROR;
2115   }
2116 
2117   if ((0x80U & ep_addr) == 0x80U)
2118   {
2119     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
2120     ep->is_in = 1U;
2121   }
2122   else
2123   {
2124     ep = &hpcd->OUT_ep[ep_addr];
2125     ep->is_in = 0U;
2126   }
2127 
2128   ep->is_stall = 1U;
2129   ep->num = ep_addr & EP_ADDR_MSK;
2130 
2131   __HAL_LOCK(hpcd);
2132 
2133   (void)USB_EPSetStall(hpcd->Instance, ep);
2134 
2135 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
2136   if ((ep_addr & EP_ADDR_MSK) == 0U)
2137   {
2138     (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t)hpcd->Init.dma_enable, (uint8_t *)hpcd->Setup);
2139   }
2140 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2141 
2142   __HAL_UNLOCK(hpcd);
2143 
2144   return HAL_OK;
2145 }
2146 
2147 /**
2148   * @brief  Clear a STALL condition over in an endpoint
2149   * @param  hpcd PCD handle
2150   * @param  ep_addr endpoint address
2151   * @retval HAL status
2152   */
HAL_PCD_EP_ClrStall(PCD_HandleTypeDef * hpcd,uint8_t ep_addr)2153 HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
2154 {
2155   PCD_EPTypeDef *ep;
2156 
2157   if (((uint32_t)ep_addr & 0x0FU) > hpcd->Init.dev_endpoints)
2158   {
2159     return HAL_ERROR;
2160   }
2161 
2162   if ((0x80U & ep_addr) == 0x80U)
2163   {
2164     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
2165     ep->is_in = 1U;
2166   }
2167   else
2168   {
2169     ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
2170     ep->is_in = 0U;
2171   }
2172 
2173   ep->is_stall = 0U;
2174   ep->num = ep_addr & EP_ADDR_MSK;
2175 
2176   __HAL_LOCK(hpcd);
2177   (void)USB_EPClearStall(hpcd->Instance, ep);
2178   __HAL_UNLOCK(hpcd);
2179 
2180   return HAL_OK;
2181 }
2182 
2183 /**
2184    * @brief  Abort an USB EP transaction.
2185    * @param  hpcd PCD handle
2186    * @param  ep_addr endpoint address
2187    * @retval HAL status
2188    */
HAL_PCD_EP_Abort(PCD_HandleTypeDef * hpcd,uint8_t ep_addr)2189 HAL_StatusTypeDef HAL_PCD_EP_Abort(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
2190 {
2191   HAL_StatusTypeDef ret;
2192   PCD_EPTypeDef *ep;
2193 
2194   if ((0x80U & ep_addr) == 0x80U)
2195   {
2196     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
2197   }
2198   else
2199   {
2200     ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
2201   }
2202 
2203   /* Stop Xfer */
2204   ret = USB_EPStopXfer(hpcd->Instance, ep);
2205 
2206   return ret;
2207 }
2208 
2209 /**
2210   * @brief  Flush an endpoint
2211   * @param  hpcd PCD handle
2212   * @param  ep_addr endpoint address
2213   * @retval HAL status
2214   */
HAL_PCD_EP_Flush(PCD_HandleTypeDef * hpcd,uint8_t ep_addr)2215 HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
2216 {
2217   __HAL_LOCK(hpcd);
2218 
2219   if ((ep_addr & 0x80U) == 0x80U)
2220   {
2221     (void)USB_FlushTxFifo(hpcd->Instance, (uint32_t)ep_addr & EP_ADDR_MSK);
2222   }
2223   else
2224   {
2225     (void)USB_FlushRxFifo(hpcd->Instance);
2226   }
2227 
2228   __HAL_UNLOCK(hpcd);
2229 
2230   return HAL_OK;
2231 }
2232 
2233 /**
2234   * @brief  Activate remote wakeup signalling
2235   * @param  hpcd PCD handle
2236   * @retval HAL status
2237   */
HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef * hpcd)2238 HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
2239 {
2240   return (USB_ActivateRemoteWakeup(hpcd->Instance));
2241 }
2242 
2243 /**
2244   * @brief  De-activate remote wakeup signalling.
2245   * @param  hpcd PCD handle
2246   * @retval HAL status
2247   */
HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef * hpcd)2248 HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
2249 {
2250   return (USB_DeActivateRemoteWakeup(hpcd->Instance));
2251 }
2252 
2253 /**
2254   * @}
2255   */
2256 
2257 /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions
2258   *  @brief   Peripheral State functions
2259   *
2260 @verbatim
2261  ===============================================================================
2262                       ##### Peripheral State functions #####
2263  ===============================================================================
2264     [..]
2265     This subsection permits to get in run-time the status of the peripheral
2266     and the data flow.
2267 
2268 @endverbatim
2269   * @{
2270   */
2271 
2272 /**
2273   * @brief  Return the PCD handle state.
2274   * @param  hpcd PCD handle
2275   * @retval HAL state
2276   */
HAL_PCD_GetState(PCD_HandleTypeDef const * hpcd)2277 PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef const *hpcd)
2278 {
2279   return hpcd->State;
2280 }
2281 
2282 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
2283 /**
2284   * @brief  Set the USB Device high speed test mode.
2285   * @param  hpcd PCD handle
2286   * @param  testmode USB Device high speed test mode
2287   * @retval HAL status
2288   */
HAL_PCD_SetTestMode(PCD_HandleTypeDef * hpcd,uint8_t testmode)2289 HAL_StatusTypeDef HAL_PCD_SetTestMode(PCD_HandleTypeDef *hpcd, uint8_t testmode)
2290 {
2291   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
2292   uint32_t USBx_BASE = (uint32_t)USBx;
2293 
2294   switch (testmode)
2295   {
2296     case TEST_J:
2297     case TEST_K:
2298     case TEST_SE0_NAK:
2299     case TEST_PACKET:
2300     case TEST_FORCE_EN:
2301       USBx_DEVICE->DCTL |= (uint32_t)testmode << 4;
2302       break;
2303 
2304     default:
2305       break;
2306   }
2307 
2308   return HAL_OK;
2309 }
2310 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2311 /**
2312   * @}
2313   */
2314 
2315 /**
2316   * @}
2317   */
2318 
2319 /* Private functions ---------------------------------------------------------*/
2320 /** @addtogroup PCD_Private_Functions
2321   * @{
2322   */
2323 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
2324 /**
2325   * @brief  Check FIFO for the next packet to be loaded.
2326   * @param  hpcd PCD handle
2327   * @param  epnum endpoint number
2328   * @retval HAL status
2329   */
PCD_WriteEmptyTxFifo(PCD_HandleTypeDef * hpcd,uint32_t epnum)2330 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum)
2331 {
2332   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
2333   uint32_t USBx_BASE = (uint32_t)USBx;
2334   USB_OTG_EPTypeDef *ep;
2335   uint32_t len;
2336   uint32_t len32b;
2337   uint32_t fifoemptymsk;
2338 
2339   ep = &hpcd->IN_ep[epnum];
2340 
2341   if (ep->xfer_count > ep->xfer_len)
2342   {
2343     return HAL_ERROR;
2344   }
2345 
2346   len = ep->xfer_len - ep->xfer_count;
2347 
2348   if (len > ep->maxpacket)
2349   {
2350     len = ep->maxpacket;
2351   }
2352 
2353   len32b = (len + 3U) / 4U;
2354 
2355   while (((USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= len32b) &&
2356          (ep->xfer_count < ep->xfer_len) && (ep->xfer_len != 0U))
2357   {
2358     /* Write the FIFO */
2359     len = ep->xfer_len - ep->xfer_count;
2360 
2361     if (len > ep->maxpacket)
2362     {
2363       len = ep->maxpacket;
2364     }
2365     len32b = (len + 3U) / 4U;
2366 
2367     (void)USB_WritePacket(USBx, ep->xfer_buff, (uint8_t)epnum, (uint16_t)len,
2368                           (uint8_t)hpcd->Init.dma_enable);
2369 
2370     ep->xfer_buff  += len;
2371     ep->xfer_count += len;
2372   }
2373 
2374   if (ep->xfer_len <= ep->xfer_count)
2375   {
2376     fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK));
2377     USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
2378   }
2379 
2380   return HAL_OK;
2381 }
2382 
2383 
2384 /**
2385   * @brief  process EP OUT transfer complete interrupt.
2386   * @param  hpcd PCD handle
2387   * @param  epnum endpoint number
2388   * @retval HAL status
2389   */
PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef * hpcd,uint32_t epnum)2390 static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef *hpcd, uint32_t epnum)
2391 {
2392   USB_OTG_EPTypeDef *ep;
2393   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
2394   uint32_t USBx_BASE = (uint32_t)USBx;
2395   uint32_t gSNPSiD = *(__IO uint32_t *)(&USBx->CID + 0x1U);
2396   uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT;
2397 
2398   if (hpcd->Init.dma_enable == 1U)
2399   {
2400     if ((DoepintReg & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP) /* Class C */
2401     {
2402       /* StupPktRcvd = 1 this is a setup packet */
2403       if ((gSNPSiD > USB_OTG_CORE_ID_300A) &&
2404           ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX))
2405       {
2406         CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
2407       }
2408     }
2409     else if ((DoepintReg & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR) /* Class E */
2410     {
2411       CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
2412     }
2413     else if ((DoepintReg & (USB_OTG_DOEPINT_STUP | USB_OTG_DOEPINT_OTEPSPR)) == 0U)
2414     {
2415       /* StupPktRcvd = 1 this is a setup packet */
2416       if ((gSNPSiD > USB_OTG_CORE_ID_300A) &&
2417           ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX))
2418       {
2419         CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
2420       }
2421       else
2422       {
2423         ep = &hpcd->OUT_ep[epnum];
2424 
2425         /* out data packet received over EP */
2426         ep->xfer_count = ep->xfer_size - (USBx_OUTEP(epnum)->DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ);
2427 
2428         if (epnum == 0U)
2429         {
2430           if (ep->xfer_len == 0U)
2431           {
2432             /* this is ZLP, so prepare EP0 for next setup */
2433             (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup);
2434           }
2435           else
2436           {
2437             ep->xfer_buff += ep->xfer_count;
2438           }
2439         }
2440 
2441 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2442         hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
2443 #else
2444         HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
2445 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2446       }
2447     }
2448     else
2449     {
2450       /* ... */
2451     }
2452   }
2453   else
2454   {
2455     if (gSNPSiD == USB_OTG_CORE_ID_310A)
2456     {
2457       /* StupPktRcvd = 1 this is a setup packet */
2458       if ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX)
2459       {
2460         CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
2461       }
2462       else
2463       {
2464         if ((DoepintReg & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR)
2465         {
2466           CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
2467         }
2468 
2469 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2470         hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
2471 #else
2472         HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
2473 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2474       }
2475     }
2476     else
2477     {
2478       if ((epnum == 0U) && (hpcd->OUT_ep[epnum].xfer_len == 0U))
2479       {
2480         /* this is ZLP, so prepare EP0 for next setup */
2481         (void)USB_EP0_OutStart(hpcd->Instance, 0U, (uint8_t *)hpcd->Setup);
2482       }
2483 
2484 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2485       hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
2486 #else
2487       HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
2488 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2489     }
2490   }
2491 
2492   return HAL_OK;
2493 }
2494 
2495 
2496 /**
2497   * @brief  process EP OUT setup packet received interrupt.
2498   * @param  hpcd PCD handle
2499   * @param  epnum endpoint number
2500   * @retval HAL status
2501   */
PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef * hpcd,uint32_t epnum)2502 static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef *hpcd, uint32_t epnum)
2503 {
2504   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
2505   uint32_t USBx_BASE = (uint32_t)USBx;
2506   uint32_t gSNPSiD = *(__IO uint32_t *)(&USBx->CID + 0x1U);
2507   uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT;
2508 
2509   if ((gSNPSiD > USB_OTG_CORE_ID_300A) &&
2510       ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX))
2511   {
2512     CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
2513   }
2514 
2515   /* Inform the upper layer that a setup packet is available */
2516 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2517   hpcd->SetupStageCallback(hpcd);
2518 #else
2519   HAL_PCD_SetupStageCallback(hpcd);
2520 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2521 
2522   if ((gSNPSiD > USB_OTG_CORE_ID_300A) && (hpcd->Init.dma_enable == 1U))
2523   {
2524     (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup);
2525   }
2526 
2527   return HAL_OK;
2528 }
2529 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2530 
2531 #if defined (USB_DRD_FS)
2532 /**
2533   * @brief  This function handles PCD Endpoint interrupt request.
2534   * @param  hpcd PCD handle
2535   * @retval HAL status
2536   */
PCD_EP_ISR_Handler(PCD_HandleTypeDef * hpcd)2537 static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
2538 {
2539   PCD_EPTypeDef *ep;
2540   uint16_t count;
2541   uint16_t wIstr;
2542   uint16_t wEPVal;
2543   uint16_t TxPctSize;
2544   uint8_t epindex;
2545 
2546 #if (USE_USB_DOUBLE_BUFFER != 1U)
2547   count = 0U;
2548 #endif /* USE_USB_DOUBLE_BUFFER */
2549 
2550   /* stay in loop while pending interrupts */
2551   while ((hpcd->Instance->ISTR & USB_ISTR_CTR) != 0U)
2552   {
2553     wIstr = (uint16_t)hpcd->Instance->ISTR;
2554 
2555     /* extract highest priority endpoint number */
2556     epindex = (uint8_t)(wIstr & USB_ISTR_IDN);
2557 
2558     if (epindex == 0U)
2559     {
2560       /* Decode and service control endpoint interrupt */
2561 
2562       /* DIR bit = origin of the interrupt */
2563       if ((wIstr & USB_ISTR_DIR) == 0U)
2564       {
2565         /* DIR = 0 */
2566 
2567         /* DIR = 0 => IN  int */
2568         /* DIR = 0 implies that (EP_CTR_TX = 1) always */
2569         PCD_CLEAR_TX_EP_CTR(hpcd->Instance, PCD_ENDP0);
2570         ep = &hpcd->IN_ep[0];
2571 
2572         ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
2573         ep->xfer_buff += ep->xfer_count;
2574 
2575         /* TX COMPLETE */
2576 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2577         hpcd->DataInStageCallback(hpcd, 0U);
2578 #else
2579         HAL_PCD_DataInStageCallback(hpcd, 0U);
2580 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2581 
2582         if ((hpcd->USB_Address > 0U) && (ep->xfer_len == 0U))
2583         {
2584           hpcd->Instance->DADDR = ((uint16_t)hpcd->USB_Address | USB_DADDR_EF);
2585           hpcd->USB_Address = 0U;
2586         }
2587       }
2588       else
2589       {
2590         /* DIR = 1 */
2591 
2592         /* DIR = 1 & CTR_RX => SETUP or OUT int */
2593         /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */
2594         ep = &hpcd->OUT_ep[0];
2595         wEPVal = (uint16_t)PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0);
2596 
2597         if ((wEPVal & USB_EP_SETUP) != 0U)
2598         {
2599           /* Get SETUP Packet */
2600           ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
2601 
2602           USB_ReadPMA(hpcd->Instance, (uint8_t *)hpcd->Setup,
2603                       ep->pmaadress, (uint16_t)ep->xfer_count);
2604 
2605           /* SETUP bit kept frozen while CTR_RX = 1 */
2606           PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
2607 
2608           /* Process SETUP Packet*/
2609 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2610           hpcd->SetupStageCallback(hpcd);
2611 #else
2612           HAL_PCD_SetupStageCallback(hpcd);
2613 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2614         }
2615         else if ((wEPVal & USB_EP_VTRX) != 0U)
2616         {
2617           PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
2618 
2619           /* Get Control Data OUT Packet */
2620           ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
2621 
2622           if ((ep->xfer_count != 0U) && (ep->xfer_buff != 0U))
2623           {
2624             USB_ReadPMA(hpcd->Instance, ep->xfer_buff,
2625                         ep->pmaadress, (uint16_t)ep->xfer_count);
2626 
2627             ep->xfer_buff += ep->xfer_count;
2628 
2629             /* Process Control Data OUT Packet */
2630 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2631             hpcd->DataOutStageCallback(hpcd, 0U);
2632 #else
2633             HAL_PCD_DataOutStageCallback(hpcd, 0U);
2634 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2635           }
2636 
2637           wEPVal = (uint16_t)PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0);
2638 
2639           if (((wEPVal & USB_EP_SETUP) == 0U) && ((wEPVal & USB_EP_RX_STRX) != USB_EP_RX_VALID))
2640           {
2641             PCD_SET_EP_RX_CNT(hpcd->Instance, PCD_ENDP0, ep->maxpacket);
2642             PCD_SET_EP_RX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_RX_VALID);
2643           }
2644         }
2645       }
2646     }
2647     else
2648     {
2649       /* Decode and service non control endpoints interrupt */
2650       /* process related endpoint register */
2651       wEPVal = (uint16_t)PCD_GET_ENDPOINT(hpcd->Instance, epindex);
2652 
2653       if ((wEPVal & USB_EP_VTRX) != 0U)
2654       {
2655         /* clear int flag */
2656         PCD_CLEAR_RX_EP_CTR(hpcd->Instance, epindex);
2657         ep = &hpcd->OUT_ep[epindex];
2658 
2659         /* OUT Single Buffering */
2660         if (ep->doublebuffer == 0U)
2661         {
2662           count = (uint16_t)PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
2663 
2664           if (count != 0U)
2665           {
2666             USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, count);
2667           }
2668         }
2669 #if (USE_USB_DOUBLE_BUFFER == 1U)
2670         else
2671         {
2672           /* manage double buffer bulk out */
2673           if (ep->type == EP_TYPE_BULK)
2674           {
2675             count = HAL_PCD_EP_DB_Receive(hpcd, ep, wEPVal);
2676           }
2677           else /* manage double buffer iso out */
2678           {
2679             /* free EP OUT Buffer */
2680             PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 0U);
2681 
2682             if ((PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_RX) != 0U)
2683             {
2684               /* read from endpoint BUF0Addr buffer */
2685               count = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
2686 
2687               if (count != 0U)
2688               {
2689                 USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count);
2690               }
2691             }
2692             else
2693             {
2694               /* read from endpoint BUF1Addr buffer */
2695               count = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
2696 
2697               if (count != 0U)
2698               {
2699                 USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count);
2700               }
2701             }
2702           }
2703         }
2704 #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
2705 
2706         /* multi-packet on the NON control OUT endpoint */
2707         ep->xfer_count += count;
2708         ep->xfer_buff += count;
2709 
2710         if ((ep->xfer_len == 0U) || (count < ep->maxpacket))
2711         {
2712           /* RX COMPLETE */
2713 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2714           hpcd->DataOutStageCallback(hpcd, ep->num);
2715 #else
2716           HAL_PCD_DataOutStageCallback(hpcd, ep->num);
2717 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2718         }
2719         else
2720         {
2721           (void)USB_EPStartXfer(hpcd->Instance, ep);
2722         }
2723       }
2724 
2725       if ((wEPVal & USB_EP_VTTX) != 0U)
2726       {
2727         ep = &hpcd->IN_ep[epindex];
2728 
2729         /* clear int flag */
2730         PCD_CLEAR_TX_EP_CTR(hpcd->Instance, epindex);
2731 
2732         if (ep->type == EP_TYPE_ISOC)
2733         {
2734           ep->xfer_len = 0U;
2735 
2736 #if (USE_USB_DOUBLE_BUFFER == 1U)
2737           if (ep->doublebuffer != 0U)
2738           {
2739             if ((wEPVal & USB_EP_DTOG_TX) != 0U)
2740             {
2741               PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, 0U);
2742             }
2743             else
2744             {
2745               PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, 0U);
2746             }
2747           }
2748 #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
2749 
2750           /* TX COMPLETE */
2751 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2752           hpcd->DataInStageCallback(hpcd, ep->num);
2753 #else
2754           HAL_PCD_DataInStageCallback(hpcd, ep->num);
2755 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2756         }
2757         else
2758         {
2759           /* Manage Single Buffer Transaction */
2760           if ((wEPVal & USB_EP_KIND) == 0U)
2761           {
2762             /* multi-packet on the NON control IN endpoint */
2763             TxPctSize = (uint16_t)PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
2764 
2765             if (ep->xfer_len > TxPctSize)
2766             {
2767               ep->xfer_len -= TxPctSize;
2768             }
2769             else
2770             {
2771               ep->xfer_len = 0U;
2772             }
2773 
2774             /* Zero Length Packet? */
2775             if (ep->xfer_len == 0U)
2776             {
2777               /* TX COMPLETE */
2778 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2779               hpcd->DataInStageCallback(hpcd, ep->num);
2780 #else
2781               HAL_PCD_DataInStageCallback(hpcd, ep->num);
2782 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2783             }
2784             else
2785             {
2786               /* Transfer is not yet Done */
2787               ep->xfer_buff += TxPctSize;
2788               ep->xfer_count += TxPctSize;
2789               (void)USB_EPStartXfer(hpcd->Instance, ep);
2790             }
2791           }
2792 #if (USE_USB_DOUBLE_BUFFER == 1U)
2793           /* Double Buffer bulk IN (bulk transfer Len > Ep_Mps) */
2794           else
2795           {
2796             (void)HAL_PCD_EP_DB_Transmit(hpcd, ep, wEPVal);
2797           }
2798 #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
2799         }
2800       }
2801     }
2802   }
2803 
2804   return HAL_OK;
2805 }
2806 
2807 
2808 #if (USE_USB_DOUBLE_BUFFER == 1U)
2809 /**
2810   * @brief  Manage double buffer bulk out transaction from ISR
2811   * @param  hpcd PCD handle
2812   * @param  ep current endpoint handle
2813   * @param  wEPVal Last snapshot of EPRx register value taken in ISR
2814   * @retval HAL status
2815   */
HAL_PCD_EP_DB_Receive(PCD_HandleTypeDef * hpcd,PCD_EPTypeDef * ep,uint16_t wEPVal)2816 static uint16_t HAL_PCD_EP_DB_Receive(PCD_HandleTypeDef *hpcd,
2817                                       PCD_EPTypeDef *ep, uint16_t wEPVal)
2818 {
2819   uint16_t count;
2820 
2821   /* Manage Buffer0 OUT */
2822   if ((wEPVal & USB_EP_DTOG_RX) != 0U)
2823   {
2824     /* Get count of received Data on buffer0 */
2825     count = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
2826 
2827     if (ep->xfer_len >= count)
2828     {
2829       ep->xfer_len -= count;
2830     }
2831     else
2832     {
2833       ep->xfer_len = 0U;
2834     }
2835 
2836     if (ep->xfer_len == 0U)
2837     {
2838       /* set NAK to OUT endpoint since double buffer is enabled */
2839       PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_NAK);
2840     }
2841 
2842     /* Check if Buffer1 is in blocked state which requires to toggle */
2843     if ((wEPVal & USB_EP_DTOG_TX) != 0U)
2844     {
2845       PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 0U);
2846     }
2847 
2848     if (count != 0U)
2849     {
2850       USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count);
2851     }
2852   }
2853   /* Manage Buffer 1 DTOG_RX=0 */
2854   else
2855   {
2856     /* Get count of received data */
2857     count = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
2858 
2859     if (ep->xfer_len >= count)
2860     {
2861       ep->xfer_len -= count;
2862     }
2863     else
2864     {
2865       ep->xfer_len = 0U;
2866     }
2867 
2868     if (ep->xfer_len == 0U)
2869     {
2870       /* set NAK on the current endpoint */
2871       PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_NAK);
2872     }
2873 
2874     /*Need to FreeUser Buffer*/
2875     if ((wEPVal & USB_EP_DTOG_TX) == 0U)
2876     {
2877       PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 0U);
2878     }
2879 
2880     if (count != 0U)
2881     {
2882       USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count);
2883     }
2884   }
2885 
2886   return count;
2887 }
2888 
2889 
2890 /**
2891   * @brief  Manage double buffer bulk IN transaction from ISR
2892   * @param  hpcd PCD handle
2893   * @param  ep current endpoint handle
2894   * @param  wEPVal Last snapshot of EPRx register value taken in ISR
2895   * @retval HAL status
2896   */
HAL_PCD_EP_DB_Transmit(PCD_HandleTypeDef * hpcd,PCD_EPTypeDef * ep,uint16_t wEPVal)2897 static HAL_StatusTypeDef HAL_PCD_EP_DB_Transmit(PCD_HandleTypeDef *hpcd,
2898                                                 PCD_EPTypeDef *ep, uint16_t wEPVal)
2899 {
2900   uint32_t len;
2901   uint16_t TxPctSize;
2902 
2903   /* Data Buffer0 ACK received */
2904   if ((wEPVal & USB_EP_DTOG_TX) != 0U)
2905   {
2906     /* multi-packet on the NON control IN endpoint */
2907     TxPctSize = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
2908 
2909     if (ep->xfer_len > TxPctSize)
2910     {
2911       ep->xfer_len -= TxPctSize;
2912     }
2913     else
2914     {
2915       ep->xfer_len = 0U;
2916     }
2917 
2918     /* Transfer is completed */
2919     if (ep->xfer_len == 0U)
2920     {
2921       PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, 0U);
2922       PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, 0U);
2923 
2924       /* TX COMPLETE */
2925 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2926       hpcd->DataInStageCallback(hpcd, ep->num);
2927 #else
2928       HAL_PCD_DataInStageCallback(hpcd, ep->num);
2929 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2930 
2931       if ((wEPVal & USB_EP_DTOG_RX) != 0U)
2932       {
2933         PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 1U);
2934       }
2935     }
2936     else /* Transfer is not yet Done */
2937     {
2938       /* need to Free USB Buff */
2939       if ((wEPVal & USB_EP_DTOG_RX) != 0U)
2940       {
2941         PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 1U);
2942       }
2943 
2944       /* Still there is data to Fill in the next Buffer */
2945       if (ep->xfer_fill_db == 1U)
2946       {
2947         ep->xfer_buff += TxPctSize;
2948         ep->xfer_count += TxPctSize;
2949 
2950         /* Calculate the len of the new buffer to fill */
2951         if (ep->xfer_len_db >= ep->maxpacket)
2952         {
2953           len = ep->maxpacket;
2954           ep->xfer_len_db -= len;
2955         }
2956         else if (ep->xfer_len_db == 0U)
2957         {
2958           len = TxPctSize;
2959           ep->xfer_fill_db = 0U;
2960         }
2961         else
2962         {
2963           ep->xfer_fill_db = 0U;
2964           len = ep->xfer_len_db;
2965           ep->xfer_len_db = 0U;
2966         }
2967 
2968         /* Write remaining Data to Buffer */
2969         /* Set the Double buffer counter for pma buffer1 */
2970         PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, len);
2971 
2972         /* Copy user buffer to USB PMA */
2973         USB_WritePMA(hpcd->Instance, ep->xfer_buff,  ep->pmaaddr0, (uint16_t)len);
2974       }
2975     }
2976   }
2977   else /* Data Buffer1 ACK received */
2978   {
2979     /* multi-packet on the NON control IN endpoint */
2980     TxPctSize = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
2981 
2982     if (ep->xfer_len >= TxPctSize)
2983     {
2984       ep->xfer_len -= TxPctSize;
2985     }
2986     else
2987     {
2988       ep->xfer_len = 0U;
2989     }
2990 
2991     /* Transfer is completed */
2992     if (ep->xfer_len == 0U)
2993     {
2994       PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, 0U);
2995       PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, 0U);
2996 
2997       /* TX COMPLETE */
2998 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2999       hpcd->DataInStageCallback(hpcd, ep->num);
3000 #else
3001       HAL_PCD_DataInStageCallback(hpcd, ep->num);
3002 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
3003 
3004       /* need to Free USB Buff */
3005       if ((wEPVal & USB_EP_DTOG_RX) == 0U)
3006       {
3007         PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 1U);
3008       }
3009     }
3010     else /* Transfer is not yet Done */
3011     {
3012       /* need to Free USB Buff */
3013       if ((wEPVal & USB_EP_DTOG_RX) == 0U)
3014       {
3015         PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 1U);
3016       }
3017 
3018       /* Still there is data to Fill in the next Buffer */
3019       if (ep->xfer_fill_db == 1U)
3020       {
3021         ep->xfer_buff += TxPctSize;
3022         ep->xfer_count += TxPctSize;
3023 
3024         /* Calculate the len of the new buffer to fill */
3025         if (ep->xfer_len_db >= ep->maxpacket)
3026         {
3027           len = ep->maxpacket;
3028           ep->xfer_len_db -= len;
3029         }
3030         else if (ep->xfer_len_db == 0U)
3031         {
3032           len = TxPctSize;
3033           ep->xfer_fill_db = 0U;
3034         }
3035         else
3036         {
3037           len = ep->xfer_len_db;
3038           ep->xfer_len_db = 0U;
3039           ep->xfer_fill_db = 0;
3040         }
3041 
3042         /* Set the Double buffer counter for pmabuffer1 */
3043         PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, len);
3044 
3045         /* Copy the user buffer to USB PMA */
3046         USB_WritePMA(hpcd->Instance, ep->xfer_buff,  ep->pmaaddr1, (uint16_t)len);
3047       }
3048     }
3049   }
3050 
3051   /*enable endpoint IN*/
3052   PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_VALID);
3053 
3054   return HAL_OK;
3055 }
3056 #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
3057 
3058 #endif /* defined (USB_DRD_FS) */
3059 
3060 /**
3061   * @}
3062   */
3063 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) || defined (USB_DRD_FS) */
3064 #endif /* HAL_PCD_MODULE_ENABLED */
3065 
3066 /**
3067   * @}
3068   */
3069 
3070 /**
3071   * @}
3072   */
3073