1 /**
2   ******************************************************************************
3   * @file    stm32h7rsxx_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) 2022 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_OTG_FS_CLK_ENABLE();
41               (+++) __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); (For High Speed Mode)
42 
43          (##) Initialize the related GPIO clocks
44          (##) Configure PCD pin-out
45          (##) Configure PCD NVIC interrupt
46 
47      (#)Associate the Upper USB device stack to the HAL PCD Driver:
48          (##) hpcd.pData = pdev;
49 
50      (#)Enable PCD transmission and reception:
51          (##) HAL_PCD_Start();
52 
53   @endverbatim
54   ******************************************************************************
55   */
56 
57 /* Includes ------------------------------------------------------------------*/
58 #include "stm32h7rsxx_hal.h"
59 
60 /** @addtogroup STM32H7RSxx_HAL_Driver
61   * @{
62   */
63 
64 /** @defgroup PCD PCD
65   * @brief PCD HAL module driver
66   * @{
67   */
68 
69 #ifdef HAL_PCD_MODULE_ENABLED
70 
71 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
72 
73 /* Private types -------------------------------------------------------------*/
74 /* Private variables ---------------------------------------------------------*/
75 /* Private constants ---------------------------------------------------------*/
76 /* Private macros ------------------------------------------------------------*/
77 /** @defgroup PCD_Private_Macros PCD Private Macros
78   * @{
79   */
80 #define PCD_MIN(a, b)  (((a) < (b)) ? (a) : (b))
81 #define PCD_MAX(a, b)  (((a) > (b)) ? (a) : (b))
82 /**
83   * @}
84   */
85 
86 /* Private functions prototypes ----------------------------------------------*/
87 /** @defgroup PCD_Private_Functions PCD Private Functions
88   * @{
89   */
90 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
91 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum);
92 static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef *hpcd, uint32_t epnum);
93 static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef *hpcd, uint32_t epnum);
94 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
95 /**
96   * @}
97   */
98 
99 /* Exported functions --------------------------------------------------------*/
100 /** @defgroup PCD_Exported_Functions PCD Exported Functions
101   * @{
102   */
103 
104 /** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
105   *  @brief    Initialization and Configuration functions
106   *
107 @verbatim
108  ===============================================================================
109             ##### Initialization and de-initialization functions #####
110  ===============================================================================
111     [..]  This section provides functions allowing to:
112 
113 @endverbatim
114   * @{
115   */
116 
117 /**
118   * @brief  Initializes the PCD according to the specified
119   *         parameters in the PCD_InitTypeDef and initialize the associated handle.
120   * @param  hpcd PCD handle
121   * @retval HAL status
122   */
HAL_PCD_Init(PCD_HandleTypeDef * hpcd)123 HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd)
124 {
125 #if defined (USB_OTG_FS)
126   const USB_OTG_GlobalTypeDef *USBx;
127 #endif /* defined (USB_OTG_FS) */
128   uint8_t i;
129 
130   /* Check the PCD handle allocation */
131   if (hpcd == NULL)
132   {
133     return HAL_ERROR;
134   }
135 
136   /* Check the parameters */
137   assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance));
138 
139 #if defined (USB_OTG_FS)
140   USBx = hpcd->Instance;
141 #endif /* defined (USB_OTG_FS) */
142 
143   if (hpcd->State == HAL_PCD_STATE_RESET)
144   {
145     /* Allocate lock resource and initialize it */
146     hpcd->Lock = HAL_UNLOCKED;
147 
148 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
149     hpcd->SOFCallback = HAL_PCD_SOFCallback;
150     hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
151     hpcd->ResetCallback = HAL_PCD_ResetCallback;
152     hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
153     hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
154     hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
155     hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
156     hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback;
157     hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback;
158     hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback;
159     hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback;
160     hpcd->LPMCallback = HAL_PCDEx_LPM_Callback;
161     hpcd->BCDCallback = HAL_PCDEx_BCD_Callback;
162 
163     if (hpcd->MspInitCallback == NULL)
164     {
165       hpcd->MspInitCallback = HAL_PCD_MspInit;
166     }
167 
168     /* Init the low level hardware */
169     hpcd->MspInitCallback(hpcd);
170 #else
171     /* Init the low level hardware : GPIO, CLOCK, NVIC... */
172     HAL_PCD_MspInit(hpcd);
173 #endif /* (USE_HAL_PCD_REGISTER_CALLBACKS) */
174   }
175 
176   hpcd->State = HAL_PCD_STATE_BUSY;
177 
178 #if defined (USB_OTG_FS)
179   /* Disable DMA mode for FS instance */
180   if (USBx == USB_OTG_FS)
181   {
182     hpcd->Init.dma_enable = 0U;
183   }
184 #endif /* defined (USB_OTG_FS) */
185 
186   /* Disable the Interrupts */
187   __HAL_PCD_DISABLE(hpcd);
188 
189   /*Init the Core (common init.) */
190   if (USB_CoreInit(hpcd->Instance, hpcd->Init) != HAL_OK)
191   {
192     hpcd->State = HAL_PCD_STATE_ERROR;
193     return HAL_ERROR;
194   }
195 
196   /* Force Device Mode */
197   if (USB_SetCurrentMode(hpcd->Instance, USB_DEVICE_MODE) != HAL_OK)
198   {
199     hpcd->State = HAL_PCD_STATE_ERROR;
200     return HAL_ERROR;
201   }
202 
203   /* Init endpoints structures */
204   for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
205   {
206     /* Init ep structure */
207     hpcd->IN_ep[i].is_in = 1U;
208     hpcd->IN_ep[i].num = i;
209     hpcd->IN_ep[i].tx_fifo_num = i;
210     /* Control until ep is activated */
211     hpcd->IN_ep[i].type = EP_TYPE_CTRL;
212     hpcd->IN_ep[i].maxpacket = 0U;
213     hpcd->IN_ep[i].xfer_buff = 0U;
214     hpcd->IN_ep[i].xfer_len = 0U;
215   }
216 
217   for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
218   {
219     hpcd->OUT_ep[i].is_in = 0U;
220     hpcd->OUT_ep[i].num = i;
221     /* Control until ep is activated */
222     hpcd->OUT_ep[i].type = EP_TYPE_CTRL;
223     hpcd->OUT_ep[i].maxpacket = 0U;
224     hpcd->OUT_ep[i].xfer_buff = 0U;
225     hpcd->OUT_ep[i].xfer_len = 0U;
226   }
227 
228   /* Init Device */
229   if (USB_DevInit(hpcd->Instance, hpcd->Init) != HAL_OK)
230   {
231     hpcd->State = HAL_PCD_STATE_ERROR;
232     return HAL_ERROR;
233   }
234 
235   hpcd->USB_Address = 0U;
236   hpcd->State = HAL_PCD_STATE_READY;
237 
238   /* Activate LPM */
239   if (hpcd->Init.lpm_enable == 1U)
240   {
241     (void)HAL_PCDEx_ActivateLPM(hpcd);
242   }
243 
244   (void)USB_DevDisconnect(hpcd->Instance);
245 
246   return HAL_OK;
247 }
248 
249 /**
250   * @brief  DeInitializes the PCD peripheral.
251   * @param  hpcd PCD handle
252   * @retval HAL status
253   */
HAL_PCD_DeInit(PCD_HandleTypeDef * hpcd)254 HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
255 {
256   /* Check the PCD handle allocation */
257   if (hpcd == NULL)
258   {
259     return HAL_ERROR;
260   }
261 
262   hpcd->State = HAL_PCD_STATE_BUSY;
263 
264   /* Stop Device */
265   if (USB_StopDevice(hpcd->Instance) != HAL_OK)
266   {
267     return HAL_ERROR;
268   }
269 
270 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
271   if (hpcd->MspDeInitCallback == NULL)
272   {
273     hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; /* Legacy weak MspDeInit  */
274   }
275 
276   /* DeInit the low level hardware */
277   hpcd->MspDeInitCallback(hpcd);
278 #else
279   /* DeInit the low level hardware: CLOCK, NVIC.*/
280   HAL_PCD_MspDeInit(hpcd);
281 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
282 
283   hpcd->State = HAL_PCD_STATE_RESET;
284 
285   return HAL_OK;
286 }
287 
288 /**
289   * @brief  Initializes the PCD MSP.
290   * @param  hpcd PCD handle
291   * @retval None
292   */
HAL_PCD_MspInit(PCD_HandleTypeDef * hpcd)293 __weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
294 {
295   /* Prevent unused argument(s) compilation warning */
296   UNUSED(hpcd);
297 
298   /* NOTE : This function should not be modified, when the callback is needed,
299             the HAL_PCD_MspInit could be implemented in the user file
300    */
301 }
302 
303 /**
304   * @brief  DeInitializes PCD MSP.
305   * @param  hpcd PCD handle
306   * @retval None
307   */
HAL_PCD_MspDeInit(PCD_HandleTypeDef * hpcd)308 __weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
309 {
310   /* Prevent unused argument(s) compilation warning */
311   UNUSED(hpcd);
312 
313   /* NOTE : This function should not be modified, when the callback is needed,
314             the HAL_PCD_MspDeInit could be implemented in the user file
315    */
316 }
317 
318 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
319 /**
320   * @brief  Register a User USB PCD Callback
321   *         To be used instead of the weak predefined callback
322   * @param  hpcd USB PCD handle
323   * @param  CallbackID ID of the callback to be registered
324   *         This parameter can be one of the following values:
325   *          @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
326   *          @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
327   *          @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
328   *          @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
329   *          @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
330   *          @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
331   *          @arg @ref HAL_PCD_DISCONNECT_CB_ID USB PCD Disconnect callback ID
332   *          @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
333   *          @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
334   * @param  pCallback pointer to the Callback function
335   * @retval HAL status
336   */
HAL_PCD_RegisterCallback(PCD_HandleTypeDef * hpcd,HAL_PCD_CallbackIDTypeDef CallbackID,pPCD_CallbackTypeDef pCallback)337 HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd,
338                                            HAL_PCD_CallbackIDTypeDef CallbackID,
339                                            pPCD_CallbackTypeDef pCallback)
340 {
341   HAL_StatusTypeDef status = HAL_OK;
342 
343   if (pCallback == NULL)
344   {
345     /* Update the error code */
346     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
347     return HAL_ERROR;
348   }
349   /* Process locked */
350   __HAL_LOCK(hpcd);
351 
352   if (hpcd->State == HAL_PCD_STATE_READY)
353   {
354     switch (CallbackID)
355     {
356       case HAL_PCD_SOF_CB_ID :
357         hpcd->SOFCallback = pCallback;
358         break;
359 
360       case HAL_PCD_SETUPSTAGE_CB_ID :
361         hpcd->SetupStageCallback = pCallback;
362         break;
363 
364       case HAL_PCD_RESET_CB_ID :
365         hpcd->ResetCallback = pCallback;
366         break;
367 
368       case HAL_PCD_SUSPEND_CB_ID :
369         hpcd->SuspendCallback = pCallback;
370         break;
371 
372       case HAL_PCD_RESUME_CB_ID :
373         hpcd->ResumeCallback = pCallback;
374         break;
375 
376       case HAL_PCD_CONNECT_CB_ID :
377         hpcd->ConnectCallback = pCallback;
378         break;
379 
380       case HAL_PCD_DISCONNECT_CB_ID :
381         hpcd->DisconnectCallback = pCallback;
382         break;
383 
384       case HAL_PCD_MSPINIT_CB_ID :
385         hpcd->MspInitCallback = pCallback;
386         break;
387 
388       case HAL_PCD_MSPDEINIT_CB_ID :
389         hpcd->MspDeInitCallback = pCallback;
390         break;
391 
392       default :
393         /* Update the error code */
394         hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
395         /* Return error status */
396         status =  HAL_ERROR;
397         break;
398     }
399   }
400   else if (hpcd->State == HAL_PCD_STATE_RESET)
401   {
402     switch (CallbackID)
403     {
404       case HAL_PCD_MSPINIT_CB_ID :
405         hpcd->MspInitCallback = pCallback;
406         break;
407 
408       case HAL_PCD_MSPDEINIT_CB_ID :
409         hpcd->MspDeInitCallback = pCallback;
410         break;
411 
412       default :
413         /* Update the error code */
414         hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
415         /* Return error status */
416         status =  HAL_ERROR;
417         break;
418     }
419   }
420   else
421   {
422     /* Update the error code */
423     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
424     /* Return error status */
425     status =  HAL_ERROR;
426   }
427 
428   /* Release Lock */
429   __HAL_UNLOCK(hpcd);
430   return status;
431 }
432 
433 /**
434   * @brief  Unregister an USB PCD Callback
435   *         USB PCD callback is redirected to the weak predefined callback
436   * @param  hpcd USB PCD handle
437   * @param  CallbackID ID of the callback to be unregistered
438   *         This parameter can be one of the following values:
439   *          @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
440   *          @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
441   *          @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
442   *          @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
443   *          @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
444   *          @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
445   *          @arg @ref HAL_PCD_DISCONNECT_CB_ID USB PCD Disconnect callback ID
446   *          @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
447   *          @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
448   * @retval HAL status
449   */
HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef * hpcd,HAL_PCD_CallbackIDTypeDef CallbackID)450 HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID)
451 {
452   HAL_StatusTypeDef status = HAL_OK;
453 
454   /* Process locked */
455   __HAL_LOCK(hpcd);
456 
457   /* Setup Legacy weak Callbacks  */
458   if (hpcd->State == HAL_PCD_STATE_READY)
459   {
460     switch (CallbackID)
461     {
462       case HAL_PCD_SOF_CB_ID :
463         hpcd->SOFCallback = HAL_PCD_SOFCallback;
464         break;
465 
466       case HAL_PCD_SETUPSTAGE_CB_ID :
467         hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
468         break;
469 
470       case HAL_PCD_RESET_CB_ID :
471         hpcd->ResetCallback = HAL_PCD_ResetCallback;
472         break;
473 
474       case HAL_PCD_SUSPEND_CB_ID :
475         hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
476         break;
477 
478       case HAL_PCD_RESUME_CB_ID :
479         hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
480         break;
481 
482       case HAL_PCD_CONNECT_CB_ID :
483         hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
484         break;
485 
486       case HAL_PCD_DISCONNECT_CB_ID :
487         hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
488         break;
489 
490       case HAL_PCD_MSPINIT_CB_ID :
491         hpcd->MspInitCallback = HAL_PCD_MspInit;
492         break;
493 
494       case HAL_PCD_MSPDEINIT_CB_ID :
495         hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
496         break;
497 
498       default :
499         /* Update the error code */
500         hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
501 
502         /* Return error status */
503         status =  HAL_ERROR;
504         break;
505     }
506   }
507   else if (hpcd->State == HAL_PCD_STATE_RESET)
508   {
509     switch (CallbackID)
510     {
511       case HAL_PCD_MSPINIT_CB_ID :
512         hpcd->MspInitCallback = HAL_PCD_MspInit;
513         break;
514 
515       case HAL_PCD_MSPDEINIT_CB_ID :
516         hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
517         break;
518 
519       default :
520         /* Update the error code */
521         hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
522 
523         /* Return error status */
524         status =  HAL_ERROR;
525         break;
526     }
527   }
528   else
529   {
530     /* Update the error code */
531     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
532 
533     /* Return error status */
534     status =  HAL_ERROR;
535   }
536 
537   /* Release Lock */
538   __HAL_UNLOCK(hpcd);
539   return status;
540 }
541 
542 /**
543   * @brief  Register USB PCD Data OUT Stage Callback
544   *         To be used instead of the weak HAL_PCD_DataOutStageCallback() predefined callback
545   * @param  hpcd PCD handle
546   * @param  pCallback pointer to the USB PCD Data OUT Stage Callback function
547   * @retval HAL status
548   */
HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef * hpcd,pPCD_DataOutStageCallbackTypeDef pCallback)549 HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd,
550                                                        pPCD_DataOutStageCallbackTypeDef pCallback)
551 {
552   HAL_StatusTypeDef status = HAL_OK;
553 
554   if (pCallback == NULL)
555   {
556     /* Update the error code */
557     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
558 
559     return HAL_ERROR;
560   }
561 
562   /* Process locked */
563   __HAL_LOCK(hpcd);
564 
565   if (hpcd->State == HAL_PCD_STATE_READY)
566   {
567     hpcd->DataOutStageCallback = pCallback;
568   }
569   else
570   {
571     /* Update the error code */
572     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
573 
574     /* Return error status */
575     status =  HAL_ERROR;
576   }
577 
578   /* Release Lock */
579   __HAL_UNLOCK(hpcd);
580 
581   return status;
582 }
583 
584 /**
585   * @brief  Unregister the USB PCD Data OUT Stage Callback
586   *         USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataOutStageCallback() predefined callback
587   * @param  hpcd PCD handle
588   * @retval HAL status
589   */
HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef * hpcd)590 HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd)
591 {
592   HAL_StatusTypeDef status = HAL_OK;
593 
594   /* Process locked */
595   __HAL_LOCK(hpcd);
596 
597   if (hpcd->State == HAL_PCD_STATE_READY)
598   {
599     hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback; /* Legacy weak DataOutStageCallback  */
600   }
601   else
602   {
603     /* Update the error code */
604     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
605 
606     /* Return error status */
607     status =  HAL_ERROR;
608   }
609 
610   /* Release Lock */
611   __HAL_UNLOCK(hpcd);
612 
613   return status;
614 }
615 
616 /**
617   * @brief  Register USB PCD Data IN Stage Callback
618   *         To be used instead of the weak HAL_PCD_DataInStageCallback() predefined callback
619   * @param  hpcd PCD handle
620   * @param  pCallback pointer to the USB PCD Data IN Stage Callback function
621   * @retval HAL status
622   */
HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef * hpcd,pPCD_DataInStageCallbackTypeDef pCallback)623 HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd,
624                                                       pPCD_DataInStageCallbackTypeDef pCallback)
625 {
626   HAL_StatusTypeDef status = HAL_OK;
627 
628   if (pCallback == NULL)
629   {
630     /* Update the error code */
631     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
632 
633     return HAL_ERROR;
634   }
635 
636   /* Process locked */
637   __HAL_LOCK(hpcd);
638 
639   if (hpcd->State == HAL_PCD_STATE_READY)
640   {
641     hpcd->DataInStageCallback = pCallback;
642   }
643   else
644   {
645     /* Update the error code */
646     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
647 
648     /* Return error status */
649     status =  HAL_ERROR;
650   }
651 
652   /* Release Lock */
653   __HAL_UNLOCK(hpcd);
654 
655   return status;
656 }
657 
658 /**
659   * @brief  Unregister the USB PCD Data IN Stage Callback
660   *         USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataInStageCallback() predefined callback
661   * @param  hpcd PCD handle
662   * @retval HAL status
663   */
HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef * hpcd)664 HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd)
665 {
666   HAL_StatusTypeDef status = HAL_OK;
667 
668   /* Process locked */
669   __HAL_LOCK(hpcd);
670 
671   if (hpcd->State == HAL_PCD_STATE_READY)
672   {
673     hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback; /* Legacy weak DataInStageCallback  */
674   }
675   else
676   {
677     /* Update the error code */
678     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
679 
680     /* Return error status */
681     status =  HAL_ERROR;
682   }
683 
684   /* Release Lock */
685   __HAL_UNLOCK(hpcd);
686 
687   return status;
688 }
689 
690 /**
691   * @brief  Register USB PCD Iso OUT incomplete Callback
692   *         To be used instead of the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
693   * @param  hpcd PCD handle
694   * @param  pCallback pointer to the USB PCD Iso OUT incomplete Callback function
695   * @retval HAL status
696   */
HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef * hpcd,pPCD_IsoOutIncpltCallbackTypeDef pCallback)697 HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd,
698                                                        pPCD_IsoOutIncpltCallbackTypeDef pCallback)
699 {
700   HAL_StatusTypeDef status = HAL_OK;
701 
702   if (pCallback == NULL)
703   {
704     /* Update the error code */
705     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
706 
707     return HAL_ERROR;
708   }
709 
710   /* Process locked */
711   __HAL_LOCK(hpcd);
712 
713   if (hpcd->State == HAL_PCD_STATE_READY)
714   {
715     hpcd->ISOOUTIncompleteCallback = pCallback;
716   }
717   else
718   {
719     /* Update the error code */
720     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
721 
722     /* Return error status */
723     status =  HAL_ERROR;
724   }
725 
726   /* Release Lock */
727   __HAL_UNLOCK(hpcd);
728 
729   return status;
730 }
731 
732 /**
733   * @brief  Unregister the USB PCD Iso OUT incomplete Callback
734   *         USB PCD Iso OUT incomplete Callback is redirected
735   *         to the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
736   * @param  hpcd PCD handle
737   * @retval HAL status
738   */
HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef * hpcd)739 HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd)
740 {
741   HAL_StatusTypeDef status = HAL_OK;
742 
743   /* Process locked */
744   __HAL_LOCK(hpcd);
745 
746   if (hpcd->State == HAL_PCD_STATE_READY)
747   {
748     hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback; /* Legacy weak ISOOUTIncompleteCallback  */
749   }
750   else
751   {
752     /* Update the error code */
753     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
754 
755     /* Return error status */
756     status =  HAL_ERROR;
757   }
758 
759   /* Release Lock */
760   __HAL_UNLOCK(hpcd);
761 
762   return status;
763 }
764 
765 /**
766   * @brief  Register USB PCD Iso IN incomplete Callback
767   *         To be used instead of the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
768   * @param  hpcd PCD handle
769   * @param  pCallback pointer to the USB PCD Iso IN incomplete Callback function
770   * @retval HAL status
771   */
HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef * hpcd,pPCD_IsoInIncpltCallbackTypeDef pCallback)772 HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd,
773                                                       pPCD_IsoInIncpltCallbackTypeDef pCallback)
774 {
775   HAL_StatusTypeDef status = HAL_OK;
776 
777   if (pCallback == NULL)
778   {
779     /* Update the error code */
780     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
781 
782     return HAL_ERROR;
783   }
784 
785   /* Process locked */
786   __HAL_LOCK(hpcd);
787 
788   if (hpcd->State == HAL_PCD_STATE_READY)
789   {
790     hpcd->ISOINIncompleteCallback = pCallback;
791   }
792   else
793   {
794     /* Update the error code */
795     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
796 
797     /* Return error status */
798     status =  HAL_ERROR;
799   }
800 
801   /* Release Lock */
802   __HAL_UNLOCK(hpcd);
803 
804   return status;
805 }
806 
807 /**
808   * @brief  Unregister the USB PCD Iso IN incomplete Callback
809   *         USB PCD Iso IN incomplete Callback is redirected
810   *         to the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
811   * @param  hpcd PCD handle
812   * @retval HAL status
813   */
HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef * hpcd)814 HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd)
815 {
816   HAL_StatusTypeDef status = HAL_OK;
817 
818   /* Process locked */
819   __HAL_LOCK(hpcd);
820 
821   if (hpcd->State == HAL_PCD_STATE_READY)
822   {
823     hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback; /* Legacy weak ISOINIncompleteCallback  */
824   }
825   else
826   {
827     /* Update the error code */
828     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
829 
830     /* Return error status */
831     status =  HAL_ERROR;
832   }
833 
834   /* Release Lock */
835   __HAL_UNLOCK(hpcd);
836 
837   return status;
838 }
839 
840 /**
841   * @brief  Register USB PCD BCD Callback
842   *         To be used instead of the weak HAL_PCDEx_BCD_Callback() predefined callback
843   * @param  hpcd PCD handle
844   * @param  pCallback pointer to the USB PCD BCD Callback function
845   * @retval HAL status
846   */
HAL_PCD_RegisterBcdCallback(PCD_HandleTypeDef * hpcd,pPCD_BcdCallbackTypeDef pCallback)847 HAL_StatusTypeDef HAL_PCD_RegisterBcdCallback(PCD_HandleTypeDef *hpcd, pPCD_BcdCallbackTypeDef pCallback)
848 {
849   HAL_StatusTypeDef status = HAL_OK;
850 
851   if (pCallback == NULL)
852   {
853     /* Update the error code */
854     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
855 
856     return HAL_ERROR;
857   }
858 
859   /* Process locked */
860   __HAL_LOCK(hpcd);
861 
862   if (hpcd->State == HAL_PCD_STATE_READY)
863   {
864     hpcd->BCDCallback = pCallback;
865   }
866   else
867   {
868     /* Update the error code */
869     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
870 
871     /* Return error status */
872     status =  HAL_ERROR;
873   }
874 
875   /* Release Lock */
876   __HAL_UNLOCK(hpcd);
877 
878   return status;
879 }
880 
881 /**
882   * @brief  Unregister the USB PCD BCD Callback
883   *         USB BCD Callback is redirected to the weak HAL_PCDEx_BCD_Callback() predefined callback
884   * @param  hpcd PCD handle
885   * @retval HAL status
886   */
HAL_PCD_UnRegisterBcdCallback(PCD_HandleTypeDef * hpcd)887 HAL_StatusTypeDef HAL_PCD_UnRegisterBcdCallback(PCD_HandleTypeDef *hpcd)
888 {
889   HAL_StatusTypeDef status = HAL_OK;
890 
891   /* Process locked */
892   __HAL_LOCK(hpcd);
893 
894   if (hpcd->State == HAL_PCD_STATE_READY)
895   {
896     hpcd->BCDCallback = HAL_PCDEx_BCD_Callback; /* Legacy weak HAL_PCDEx_BCD_Callback  */
897   }
898   else
899   {
900     /* Update the error code */
901     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
902 
903     /* Return error status */
904     status =  HAL_ERROR;
905   }
906 
907   /* Release Lock */
908   __HAL_UNLOCK(hpcd);
909 
910   return status;
911 }
912 
913 /**
914   * @brief  Register USB PCD LPM Callback
915   *         To be used instead of the weak HAL_PCDEx_LPM_Callback() predefined callback
916   * @param  hpcd PCD handle
917   * @param  pCallback pointer to the USB PCD LPM Callback function
918   * @retval HAL status
919   */
HAL_PCD_RegisterLpmCallback(PCD_HandleTypeDef * hpcd,pPCD_LpmCallbackTypeDef pCallback)920 HAL_StatusTypeDef HAL_PCD_RegisterLpmCallback(PCD_HandleTypeDef *hpcd, pPCD_LpmCallbackTypeDef pCallback)
921 {
922   HAL_StatusTypeDef status = HAL_OK;
923 
924   if (pCallback == NULL)
925   {
926     /* Update the error code */
927     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
928 
929     return HAL_ERROR;
930   }
931 
932   /* Process locked */
933   __HAL_LOCK(hpcd);
934 
935   if (hpcd->State == HAL_PCD_STATE_READY)
936   {
937     hpcd->LPMCallback = pCallback;
938   }
939   else
940   {
941     /* Update the error code */
942     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
943 
944     /* Return error status */
945     status =  HAL_ERROR;
946   }
947 
948   /* Release Lock */
949   __HAL_UNLOCK(hpcd);
950 
951   return status;
952 }
953 
954 /**
955   * @brief  Unregister the USB PCD LPM Callback
956   *         USB LPM Callback is redirected to the weak HAL_PCDEx_LPM_Callback() predefined callback
957   * @param  hpcd PCD handle
958   * @retval HAL status
959   */
HAL_PCD_UnRegisterLpmCallback(PCD_HandleTypeDef * hpcd)960 HAL_StatusTypeDef HAL_PCD_UnRegisterLpmCallback(PCD_HandleTypeDef *hpcd)
961 {
962   HAL_StatusTypeDef status = HAL_OK;
963 
964   /* Process locked */
965   __HAL_LOCK(hpcd);
966 
967   if (hpcd->State == HAL_PCD_STATE_READY)
968   {
969     hpcd->LPMCallback = HAL_PCDEx_LPM_Callback; /* Legacy weak HAL_PCDEx_LPM_Callback  */
970   }
971   else
972   {
973     /* Update the error code */
974     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
975 
976     /* Return error status */
977     status =  HAL_ERROR;
978   }
979 
980   /* Release Lock */
981   __HAL_UNLOCK(hpcd);
982 
983   return status;
984 }
985 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
986 
987 /**
988   * @}
989   */
990 
991 /** @defgroup PCD_Exported_Functions_Group2 Input and Output operation functions
992   *  @brief   Data transfers functions
993   *
994 @verbatim
995  ===============================================================================
996                       ##### IO operation functions #####
997  ===============================================================================
998     [..]
999     This subsection provides a set of functions allowing to manage the PCD data
1000     transfers.
1001 
1002 @endverbatim
1003   * @{
1004   */
1005 
1006 /**
1007   * @brief  Start the USB device
1008   * @param  hpcd PCD handle
1009   * @retval HAL status
1010   */
HAL_PCD_Start(PCD_HandleTypeDef * hpcd)1011 HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)
1012 {
1013   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1014 
1015   __HAL_LOCK(hpcd);
1016 
1017   if (((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) != 0U) &&
1018       (hpcd->Init.battery_charging_enable == 1U))
1019   {
1020     /* Enable USB Transceiver */
1021     USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
1022   }
1023 
1024   __HAL_PCD_ENABLE(hpcd);
1025   (void)USB_DevConnect(hpcd->Instance);
1026   __HAL_UNLOCK(hpcd);
1027 
1028   return HAL_OK;
1029 }
1030 
1031 /**
1032   * @brief  Stop the USB device.
1033   * @param  hpcd PCD handle
1034   * @retval HAL status
1035   */
HAL_PCD_Stop(PCD_HandleTypeDef * hpcd)1036 HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
1037 {
1038   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1039 
1040   __HAL_LOCK(hpcd);
1041   __HAL_PCD_DISABLE(hpcd);
1042   (void)USB_DevDisconnect(hpcd->Instance);
1043 
1044   (void)USB_FlushTxFifo(hpcd->Instance, 0x10U);
1045 
1046   if (((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) != 0U) &&
1047       (hpcd->Init.battery_charging_enable == 1U))
1048   {
1049     /* Disable USB Transceiver */
1050     USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
1051   }
1052 
1053   __HAL_UNLOCK(hpcd);
1054 
1055   return HAL_OK;
1056 }
1057 
1058 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
1059 /**
1060   * @brief  Handles PCD interrupt request.
1061   * @param  hpcd PCD handle
1062   * @retval HAL status
1063   */
HAL_PCD_IRQHandler(PCD_HandleTypeDef * hpcd)1064 void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
1065 {
1066   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1067   uint32_t USBx_BASE = (uint32_t)USBx;
1068   USB_OTG_EPTypeDef *ep;
1069   uint32_t i;
1070   uint32_t ep_intr;
1071   uint32_t epint;
1072   uint32_t epnum;
1073   uint32_t fifoemptymsk;
1074   uint32_t RegVal;
1075 
1076   /* ensure that we are in device mode */
1077   if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE)
1078   {
1079     /* avoid spurious interrupt */
1080     if (__HAL_PCD_IS_INVALID_INTERRUPT(hpcd))
1081     {
1082       return;
1083     }
1084 
1085     /* store current frame number */
1086     hpcd->FrameNumber = (USBx_DEVICE->DSTS & USB_OTG_DSTS_FNSOF_Msk) >> USB_OTG_DSTS_FNSOF_Pos;
1087 
1088     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS))
1089     {
1090       /* incorrect mode, acknowledge the interrupt */
1091       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS);
1092     }
1093 
1094     /* Handle RxQLevel Interrupt */
1095     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL))
1096     {
1097       USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
1098 
1099       RegVal = USBx->GRXSTSP;
1100 
1101       ep = &hpcd->OUT_ep[RegVal & USB_OTG_GRXSTSP_EPNUM];
1102 
1103       if (((RegVal & USB_OTG_GRXSTSP_PKTSTS) >> 17) ==  STS_DATA_UPDT)
1104       {
1105         if ((RegVal & USB_OTG_GRXSTSP_BCNT) != 0U)
1106         {
1107           (void)USB_ReadPacket(USBx, ep->xfer_buff,
1108                                (uint16_t)((RegVal & USB_OTG_GRXSTSP_BCNT) >> 4));
1109 
1110           ep->xfer_buff += (RegVal & USB_OTG_GRXSTSP_BCNT) >> 4;
1111           ep->xfer_count += (RegVal & USB_OTG_GRXSTSP_BCNT) >> 4;
1112         }
1113       }
1114       else if (((RegVal & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_SETUP_UPDT)
1115       {
1116         (void)USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8U);
1117         ep->xfer_count += (RegVal & USB_OTG_GRXSTSP_BCNT) >> 4;
1118       }
1119       else
1120       {
1121         /* ... */
1122       }
1123 
1124       USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
1125     }
1126 
1127     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT))
1128     {
1129       epnum = 0U;
1130 
1131       /* Read in the device interrupt bits */
1132       ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance);
1133 
1134       while (ep_intr != 0U)
1135       {
1136         if ((ep_intr & 0x1U) != 0U)
1137         {
1138           epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, (uint8_t)epnum);
1139 
1140           if ((epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC)
1141           {
1142             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC);
1143             (void)PCD_EP_OutXfrComplete_int(hpcd, epnum);
1144           }
1145 
1146           if ((epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP)
1147           {
1148             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP);
1149             /* Class B setup phase done for previous decoded setup */
1150             (void)PCD_EP_OutSetupPacket_int(hpcd, epnum);
1151           }
1152 
1153           if ((epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS)
1154           {
1155             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS);
1156           }
1157 
1158           /* Clear OUT Endpoint disable interrupt */
1159           if ((epint & USB_OTG_DOEPINT_EPDISD) == USB_OTG_DOEPINT_EPDISD)
1160           {
1161             if ((USBx->GINTSTS & USB_OTG_GINTSTS_BOUTNAKEFF) == USB_OTG_GINTSTS_BOUTNAKEFF)
1162             {
1163               USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGONAK;
1164             }
1165 
1166             ep = &hpcd->OUT_ep[epnum];
1167 
1168             if (ep->is_iso_incomplete == 1U)
1169             {
1170               ep->is_iso_incomplete = 0U;
1171 
1172 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1173               hpcd->ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum);
1174 #else
1175               HAL_PCD_ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum);
1176 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1177             }
1178 
1179             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_EPDISD);
1180           }
1181 
1182           /* Clear Status Phase Received interrupt */
1183           if ((epint & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR)
1184           {
1185             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
1186           }
1187 
1188           /* Clear OUT NAK interrupt */
1189           if ((epint & USB_OTG_DOEPINT_NAK) == USB_OTG_DOEPINT_NAK)
1190           {
1191             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_NAK);
1192           }
1193         }
1194         epnum++;
1195         ep_intr >>= 1U;
1196       }
1197     }
1198 
1199     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT))
1200     {
1201       /* Read in the device interrupt bits */
1202       ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance);
1203 
1204       epnum = 0U;
1205 
1206       while (ep_intr != 0U)
1207       {
1208         if ((ep_intr & 0x1U) != 0U) /* In ITR */
1209         {
1210           epint = USB_ReadDevInEPInterrupt(hpcd->Instance, (uint8_t)epnum);
1211 
1212           if ((epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC)
1213           {
1214             fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK));
1215             USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
1216 
1217             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC);
1218 
1219             if (hpcd->Init.dma_enable == 1U)
1220             {
1221               hpcd->IN_ep[epnum].xfer_buff += hpcd->IN_ep[epnum].maxpacket;
1222 
1223               /* this is ZLP, so prepare EP0 for next setup */
1224               if ((epnum == 0U) && (hpcd->IN_ep[epnum].xfer_len == 0U))
1225               {
1226                 /* prepare to rx more setup packets */
1227                 (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup);
1228               }
1229             }
1230 
1231 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1232             hpcd->DataInStageCallback(hpcd, (uint8_t)epnum);
1233 #else
1234             HAL_PCD_DataInStageCallback(hpcd, (uint8_t)epnum);
1235 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1236           }
1237           if ((epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC)
1238           {
1239             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC);
1240           }
1241           if ((epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE)
1242           {
1243             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE);
1244           }
1245           if ((epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE)
1246           {
1247             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE);
1248           }
1249           if ((epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD)
1250           {
1251             (void)USB_FlushTxFifo(USBx, epnum);
1252 
1253             ep = &hpcd->IN_ep[epnum];
1254 
1255             if (ep->is_iso_incomplete == 1U)
1256             {
1257               ep->is_iso_incomplete = 0U;
1258 
1259 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1260               hpcd->ISOINIncompleteCallback(hpcd, (uint8_t)epnum);
1261 #else
1262               HAL_PCD_ISOINIncompleteCallback(hpcd, (uint8_t)epnum);
1263 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1264             }
1265 
1266             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD);
1267           }
1268           if ((epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE)
1269           {
1270             (void)PCD_WriteEmptyTxFifo(hpcd, epnum);
1271           }
1272         }
1273         epnum++;
1274         ep_intr >>= 1U;
1275       }
1276     }
1277 
1278     /* Handle Resume Interrupt */
1279     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT))
1280     {
1281       /* Clear the Remote Wake-up Signaling */
1282       USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
1283 
1284       if (hpcd->LPM_State == LPM_L1)
1285       {
1286         hpcd->LPM_State = LPM_L0;
1287 
1288 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1289         hpcd->LPMCallback(hpcd, PCD_LPM_L0_ACTIVE);
1290 #else
1291         HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE);
1292 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1293       }
1294       else
1295       {
1296 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1297         hpcd->ResumeCallback(hpcd);
1298 #else
1299         HAL_PCD_ResumeCallback(hpcd);
1300 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1301       }
1302 
1303       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT);
1304     }
1305 
1306     /* Handle Suspend Interrupt */
1307     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP))
1308     {
1309       if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
1310       {
1311 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1312         hpcd->SuspendCallback(hpcd);
1313 #else
1314         HAL_PCD_SuspendCallback(hpcd);
1315 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1316       }
1317       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP);
1318     }
1319 
1320     /* Handle LPM Interrupt */
1321     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT))
1322     {
1323       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT);
1324 
1325       if (hpcd->LPM_State == LPM_L0)
1326       {
1327         hpcd->LPM_State = LPM_L1;
1328         hpcd->BESL = (hpcd->Instance->GLPMCFG & USB_OTG_GLPMCFG_BESL) >> 2U;
1329 
1330 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1331         hpcd->LPMCallback(hpcd, PCD_LPM_L1_ACTIVE);
1332 #else
1333         HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE);
1334 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1335       }
1336       else
1337       {
1338 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1339         hpcd->SuspendCallback(hpcd);
1340 #else
1341         HAL_PCD_SuspendCallback(hpcd);
1342 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1343       }
1344     }
1345 
1346     /* Handle Reset Interrupt */
1347     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST))
1348     {
1349       USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
1350       (void)USB_FlushTxFifo(hpcd->Instance, 0x10U);
1351 
1352       for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
1353       {
1354         USBx_INEP(i)->DIEPINT = 0xFB7FU;
1355         USBx_INEP(i)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
1356         USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
1357         USBx_OUTEP(i)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
1358         USBx_OUTEP(i)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
1359       }
1360       USBx_DEVICE->DAINTMSK |= 0x10001U;
1361 
1362       if (hpcd->Init.use_dedicated_ep1 != 0U)
1363       {
1364         USBx_DEVICE->DOUTEP1MSK |= USB_OTG_DOEPMSK_STUPM |
1365                                    USB_OTG_DOEPMSK_XFRCM |
1366                                    USB_OTG_DOEPMSK_EPDM;
1367 
1368         USBx_DEVICE->DINEP1MSK |= USB_OTG_DIEPMSK_TOM |
1369                                   USB_OTG_DIEPMSK_XFRCM |
1370                                   USB_OTG_DIEPMSK_EPDM;
1371       }
1372       else
1373       {
1374         USBx_DEVICE->DOEPMSK |= USB_OTG_DOEPMSK_STUPM |
1375                                 USB_OTG_DOEPMSK_XFRCM |
1376                                 USB_OTG_DOEPMSK_EPDM |
1377                                 USB_OTG_DOEPMSK_OTEPSPRM |
1378                                 USB_OTG_DOEPMSK_NAKM;
1379 
1380         USBx_DEVICE->DIEPMSK |= USB_OTG_DIEPMSK_TOM |
1381                                 USB_OTG_DIEPMSK_XFRCM |
1382                                 USB_OTG_DIEPMSK_EPDM;
1383       }
1384 
1385       /* Set Default Address to 0 */
1386       USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD;
1387 
1388       /* setup EP0 to receive SETUP packets */
1389       (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t)hpcd->Init.dma_enable,
1390                              (uint8_t *)hpcd->Setup);
1391 
1392       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST);
1393     }
1394 
1395     /* Handle Enumeration done Interrupt */
1396     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE))
1397     {
1398       (void)USB_ActivateSetup(hpcd->Instance);
1399       hpcd->Init.speed = USB_GetDevSpeed(hpcd->Instance);
1400 
1401       /* Set USB Turnaround time */
1402       (void)USB_SetTurnaroundTime(hpcd->Instance,
1403                                   HAL_RCC_GetHCLKFreq(),
1404                                   (uint8_t)hpcd->Init.speed);
1405 
1406 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1407       hpcd->ResetCallback(hpcd);
1408 #else
1409       HAL_PCD_ResetCallback(hpcd);
1410 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1411 
1412       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE);
1413     }
1414 
1415     /* Handle SOF Interrupt */
1416     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF))
1417     {
1418 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1419       hpcd->SOFCallback(hpcd);
1420 #else
1421       HAL_PCD_SOFCallback(hpcd);
1422 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1423 
1424       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF);
1425     }
1426 
1427     /* Handle Global OUT NAK effective Interrupt */
1428     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_BOUTNAKEFF))
1429     {
1430       USBx->GINTMSK &= ~USB_OTG_GINTMSK_GONAKEFFM;
1431 
1432       for (epnum = 1U; epnum < hpcd->Init.dev_endpoints; epnum++)
1433       {
1434         if (hpcd->OUT_ep[epnum].is_iso_incomplete == 1U)
1435         {
1436           /* Abort current transaction and disable the EP */
1437           (void)HAL_PCD_EP_Abort(hpcd, (uint8_t)epnum);
1438         }
1439       }
1440     }
1441 
1442     /* Handle Incomplete ISO IN Interrupt */
1443     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR))
1444     {
1445       for (epnum = 1U; epnum < hpcd->Init.dev_endpoints; epnum++)
1446       {
1447         RegVal = USBx_INEP(epnum)->DIEPCTL;
1448 
1449         if ((hpcd->IN_ep[epnum].type == EP_TYPE_ISOC) &&
1450             ((RegVal & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA))
1451         {
1452           hpcd->IN_ep[epnum].is_iso_incomplete = 1U;
1453 
1454           /* Abort current transaction and disable the EP */
1455           (void)HAL_PCD_EP_Abort(hpcd, (uint8_t)(epnum | 0x80U));
1456         }
1457       }
1458 
1459       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR);
1460     }
1461 
1462     /* Handle Incomplete ISO OUT Interrupt */
1463     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
1464     {
1465       for (epnum = 1U; epnum < hpcd->Init.dev_endpoints; epnum++)
1466       {
1467         RegVal = USBx_OUTEP(epnum)->DOEPCTL;
1468 
1469         if ((hpcd->OUT_ep[epnum].type == EP_TYPE_ISOC) &&
1470             ((RegVal & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA) &&
1471             ((RegVal & (0x1U << 16)) == (hpcd->FrameNumber & 0x1U)))
1472         {
1473           hpcd->OUT_ep[epnum].is_iso_incomplete = 1U;
1474 
1475           USBx->GINTMSK |= USB_OTG_GINTMSK_GONAKEFFM;
1476 
1477           if ((USBx->GINTSTS & USB_OTG_GINTSTS_BOUTNAKEFF) == 0U)
1478           {
1479             USBx_DEVICE->DCTL |= USB_OTG_DCTL_SGONAK;
1480             break;
1481           }
1482         }
1483       }
1484 
1485       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
1486     }
1487 
1488     /* Handle Connection event Interrupt */
1489     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT))
1490     {
1491 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1492       hpcd->ConnectCallback(hpcd);
1493 #else
1494       HAL_PCD_ConnectCallback(hpcd);
1495 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1496 
1497       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT);
1498     }
1499 
1500     /* Handle Disconnection event Interrupt */
1501     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT))
1502     {
1503       RegVal = hpcd->Instance->GOTGINT;
1504 
1505       if ((RegVal & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET)
1506       {
1507 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1508         hpcd->DisconnectCallback(hpcd);
1509 #else
1510         HAL_PCD_DisconnectCallback(hpcd);
1511 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1512       }
1513       hpcd->Instance->GOTGINT |= RegVal;
1514     }
1515   }
1516 }
1517 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
1518 
1519 
1520 /**
1521   * @brief  Data OUT stage callback.
1522   * @param  hpcd PCD handle
1523   * @param  epnum endpoint number
1524   * @retval None
1525   */
HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef * hpcd,uint8_t epnum)1526 __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
1527 {
1528   /* Prevent unused argument(s) compilation warning */
1529   UNUSED(hpcd);
1530   UNUSED(epnum);
1531 
1532   /* NOTE : This function should not be modified, when the callback is needed,
1533             the HAL_PCD_DataOutStageCallback could be implemented in the user file
1534    */
1535 }
1536 
1537 /**
1538   * @brief  Data IN stage callback
1539   * @param  hpcd PCD handle
1540   * @param  epnum endpoint number
1541   * @retval None
1542   */
HAL_PCD_DataInStageCallback(PCD_HandleTypeDef * hpcd,uint8_t epnum)1543 __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
1544 {
1545   /* Prevent unused argument(s) compilation warning */
1546   UNUSED(hpcd);
1547   UNUSED(epnum);
1548 
1549   /* NOTE : This function should not be modified, when the callback is needed,
1550             the HAL_PCD_DataInStageCallback could be implemented in the user file
1551    */
1552 }
1553 /**
1554   * @brief  Setup stage callback
1555   * @param  hpcd PCD handle
1556   * @retval None
1557   */
HAL_PCD_SetupStageCallback(PCD_HandleTypeDef * hpcd)1558 __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
1559 {
1560   /* Prevent unused argument(s) compilation warning */
1561   UNUSED(hpcd);
1562 
1563   /* NOTE : This function should not be modified, when the callback is needed,
1564             the HAL_PCD_SetupStageCallback could be implemented in the user file
1565    */
1566 }
1567 
1568 /**
1569   * @brief  USB Start Of Frame callback.
1570   * @param  hpcd PCD handle
1571   * @retval None
1572   */
HAL_PCD_SOFCallback(PCD_HandleTypeDef * hpcd)1573 __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
1574 {
1575   /* Prevent unused argument(s) compilation warning */
1576   UNUSED(hpcd);
1577 
1578   /* NOTE : This function should not be modified, when the callback is needed,
1579             the HAL_PCD_SOFCallback could be implemented in the user file
1580    */
1581 }
1582 
1583 /**
1584   * @brief  USB Reset callback.
1585   * @param  hpcd PCD handle
1586   * @retval None
1587   */
HAL_PCD_ResetCallback(PCD_HandleTypeDef * hpcd)1588 __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
1589 {
1590   /* Prevent unused argument(s) compilation warning */
1591   UNUSED(hpcd);
1592 
1593   /* NOTE : This function should not be modified, when the callback is needed,
1594             the HAL_PCD_ResetCallback could be implemented in the user file
1595    */
1596 }
1597 
1598 /**
1599   * @brief  Suspend event callback.
1600   * @param  hpcd PCD handle
1601   * @retval None
1602   */
HAL_PCD_SuspendCallback(PCD_HandleTypeDef * hpcd)1603 __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
1604 {
1605   /* Prevent unused argument(s) compilation warning */
1606   UNUSED(hpcd);
1607 
1608   /* NOTE : This function should not be modified, when the callback is needed,
1609             the HAL_PCD_SuspendCallback could be implemented in the user file
1610    */
1611 }
1612 
1613 /**
1614   * @brief  Resume event callback.
1615   * @param  hpcd PCD handle
1616   * @retval None
1617   */
HAL_PCD_ResumeCallback(PCD_HandleTypeDef * hpcd)1618 __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
1619 {
1620   /* Prevent unused argument(s) compilation warning */
1621   UNUSED(hpcd);
1622 
1623   /* NOTE : This function should not be modified, when the callback is needed,
1624             the HAL_PCD_ResumeCallback could be implemented in the user file
1625    */
1626 }
1627 
1628 /**
1629   * @brief  Incomplete ISO OUT callback.
1630   * @param  hpcd PCD handle
1631   * @param  epnum endpoint number
1632   * @retval None
1633   */
HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef * hpcd,uint8_t epnum)1634 __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
1635 {
1636   /* Prevent unused argument(s) compilation warning */
1637   UNUSED(hpcd);
1638   UNUSED(epnum);
1639 
1640   /* NOTE : This function should not be modified, when the callback is needed,
1641             the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file
1642    */
1643 }
1644 
1645 /**
1646   * @brief  Incomplete ISO IN callback.
1647   * @param  hpcd PCD handle
1648   * @param  epnum endpoint number
1649   * @retval None
1650   */
HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef * hpcd,uint8_t epnum)1651 __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
1652 {
1653   /* Prevent unused argument(s) compilation warning */
1654   UNUSED(hpcd);
1655   UNUSED(epnum);
1656 
1657   /* NOTE : This function should not be modified, when the callback is needed,
1658             the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file
1659    */
1660 }
1661 
1662 /**
1663   * @brief  Connection event callback.
1664   * @param  hpcd PCD handle
1665   * @retval None
1666   */
HAL_PCD_ConnectCallback(PCD_HandleTypeDef * hpcd)1667 __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
1668 {
1669   /* Prevent unused argument(s) compilation warning */
1670   UNUSED(hpcd);
1671 
1672   /* NOTE : This function should not be modified, when the callback is needed,
1673             the HAL_PCD_ConnectCallback could be implemented in the user file
1674    */
1675 }
1676 
1677 /**
1678   * @brief  Disconnection event callback.
1679   * @param  hpcd PCD handle
1680   * @retval None
1681   */
HAL_PCD_DisconnectCallback(PCD_HandleTypeDef * hpcd)1682 __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
1683 {
1684   /* Prevent unused argument(s) compilation warning */
1685   UNUSED(hpcd);
1686 
1687   /* NOTE : This function should not be modified, when the callback is needed,
1688             the HAL_PCD_DisconnectCallback could be implemented in the user file
1689    */
1690 }
1691 
1692 /**
1693   * @}
1694   */
1695 
1696 /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
1697   *  @brief   management functions
1698   *
1699 @verbatim
1700  ===============================================================================
1701                       ##### Peripheral Control functions #####
1702  ===============================================================================
1703     [..]
1704     This subsection provides a set of functions allowing to control the PCD data
1705     transfers.
1706 
1707 @endverbatim
1708   * @{
1709   */
1710 
1711 /**
1712   * @brief  Connect the USB device
1713   * @param  hpcd PCD handle
1714   * @retval HAL status
1715   */
HAL_PCD_DevConnect(PCD_HandleTypeDef * hpcd)1716 HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd)
1717 {
1718   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1719 
1720   __HAL_LOCK(hpcd);
1721 
1722   if (((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) != 0U) &&
1723       (hpcd->Init.battery_charging_enable == 1U))
1724   {
1725     /* Enable USB Transceiver */
1726     USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
1727   }
1728   (void)USB_DevConnect(hpcd->Instance);
1729   __HAL_UNLOCK(hpcd);
1730 
1731   return HAL_OK;
1732 }
1733 
1734 /**
1735   * @brief  Disconnect the USB device.
1736   * @param  hpcd PCD handle
1737   * @retval HAL status
1738   */
HAL_PCD_DevDisconnect(PCD_HandleTypeDef * hpcd)1739 HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd)
1740 {
1741   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1742 
1743   __HAL_LOCK(hpcd);
1744   (void)USB_DevDisconnect(hpcd->Instance);
1745 
1746   if (((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) != 0U) &&
1747       (hpcd->Init.battery_charging_enable == 1U))
1748   {
1749     /* Disable USB Transceiver */
1750     USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
1751   }
1752 
1753   __HAL_UNLOCK(hpcd);
1754 
1755   return HAL_OK;
1756 }
1757 
1758 /**
1759   * @brief  Set the USB Device address.
1760   * @param  hpcd PCD handle
1761   * @param  address new device address
1762   * @retval HAL status
1763   */
HAL_PCD_SetAddress(PCD_HandleTypeDef * hpcd,uint8_t address)1764 HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)
1765 {
1766   __HAL_LOCK(hpcd);
1767   hpcd->USB_Address = address;
1768   (void)USB_SetDevAddress(hpcd->Instance, address);
1769   __HAL_UNLOCK(hpcd);
1770 
1771   return HAL_OK;
1772 }
1773 /**
1774   * @brief  Open and configure an endpoint.
1775   * @param  hpcd PCD handle
1776   * @param  ep_addr endpoint address
1777   * @param  ep_mps endpoint max packet size
1778   * @param  ep_type endpoint type
1779   * @retval HAL status
1780   */
HAL_PCD_EP_Open(PCD_HandleTypeDef * hpcd,uint8_t ep_addr,uint16_t ep_mps,uint8_t ep_type)1781 HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr,
1782                                   uint16_t ep_mps, uint8_t ep_type)
1783 {
1784   HAL_StatusTypeDef  ret = HAL_OK;
1785   PCD_EPTypeDef *ep;
1786 
1787   if ((ep_addr & 0x80U) == 0x80U)
1788   {
1789     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
1790     ep->is_in = 1U;
1791   }
1792   else
1793   {
1794     ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
1795     ep->is_in = 0U;
1796   }
1797 
1798   ep->num = ep_addr & EP_ADDR_MSK;
1799   ep->maxpacket = ep_mps;
1800   ep->type = ep_type;
1801 
1802   if (ep->is_in != 0U)
1803   {
1804     /* Assign a Tx FIFO */
1805     ep->tx_fifo_num = ep->num;
1806   }
1807 
1808   /* Set initial data PID. */
1809   if (ep_type == EP_TYPE_BULK)
1810   {
1811     ep->data_pid_start = 0U;
1812   }
1813 
1814   __HAL_LOCK(hpcd);
1815   (void)USB_ActivateEndpoint(hpcd->Instance, ep);
1816   __HAL_UNLOCK(hpcd);
1817 
1818   return ret;
1819 }
1820 
1821 /**
1822   * @brief  Deactivate an endpoint.
1823   * @param  hpcd PCD handle
1824   * @param  ep_addr endpoint address
1825   * @retval HAL status
1826   */
HAL_PCD_EP_Close(PCD_HandleTypeDef * hpcd,uint8_t ep_addr)1827 HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1828 {
1829   PCD_EPTypeDef *ep;
1830 
1831   if ((ep_addr & 0x80U) == 0x80U)
1832   {
1833     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
1834     ep->is_in = 1U;
1835   }
1836   else
1837   {
1838     ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
1839     ep->is_in = 0U;
1840   }
1841   ep->num = ep_addr & EP_ADDR_MSK;
1842 
1843   __HAL_LOCK(hpcd);
1844   (void)USB_DeactivateEndpoint(hpcd->Instance, ep);
1845   __HAL_UNLOCK(hpcd);
1846   return HAL_OK;
1847 }
1848 
1849 
1850 /**
1851   * @brief  Receive an amount of data.
1852   * @param  hpcd PCD handle
1853   * @param  ep_addr endpoint address
1854   * @param  pBuf pointer to the reception buffer
1855   * @param  len amount of data to be received
1856   * @retval HAL status
1857   */
HAL_PCD_EP_Receive(PCD_HandleTypeDef * hpcd,uint8_t ep_addr,uint8_t * pBuf,uint32_t len)1858 HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
1859 {
1860   PCD_EPTypeDef *ep;
1861 
1862   ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
1863 
1864   /*setup and start the Xfer */
1865   ep->xfer_buff = pBuf;
1866   ep->xfer_len = len;
1867   ep->xfer_count = 0U;
1868   ep->is_in = 0U;
1869   ep->num = ep_addr & EP_ADDR_MSK;
1870 
1871   if (hpcd->Init.dma_enable == 1U)
1872   {
1873     ep->dma_addr = (uint32_t)pBuf;
1874   }
1875 
1876   (void)USB_EPStartXfer(hpcd->Instance, ep, (uint8_t)hpcd->Init.dma_enable);
1877 
1878   return HAL_OK;
1879 }
1880 
1881 /**
1882   * @brief  Get Received Data Size
1883   * @param  hpcd PCD handle
1884   * @param  ep_addr endpoint address
1885   * @retval Data Size
1886   */
HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef const * hpcd,uint8_t ep_addr)1887 uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef const *hpcd, uint8_t ep_addr)
1888 {
1889   return hpcd->OUT_ep[ep_addr & EP_ADDR_MSK].xfer_count;
1890 }
1891 /**
1892   * @brief  Send an amount of data
1893   * @param  hpcd PCD handle
1894   * @param  ep_addr endpoint address
1895   * @param  pBuf pointer to the transmission buffer
1896   * @param  len amount of data to be sent
1897   * @retval HAL status
1898   */
HAL_PCD_EP_Transmit(PCD_HandleTypeDef * hpcd,uint8_t ep_addr,uint8_t * pBuf,uint32_t len)1899 HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
1900 {
1901   PCD_EPTypeDef *ep;
1902 
1903   ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
1904 
1905   /*setup and start the Xfer */
1906   ep->xfer_buff = pBuf;
1907   ep->xfer_len = len;
1908   ep->xfer_count = 0U;
1909   ep->is_in = 1U;
1910   ep->num = ep_addr & EP_ADDR_MSK;
1911 
1912   if (hpcd->Init.dma_enable == 1U)
1913   {
1914     ep->dma_addr = (uint32_t)pBuf;
1915   }
1916 
1917   (void)USB_EPStartXfer(hpcd->Instance, ep, (uint8_t)hpcd->Init.dma_enable);
1918 
1919   return HAL_OK;
1920 }
1921 
1922 /**
1923   * @brief  Set a STALL condition over an endpoint
1924   * @param  hpcd PCD handle
1925   * @param  ep_addr endpoint address
1926   * @retval HAL status
1927   */
HAL_PCD_EP_SetStall(PCD_HandleTypeDef * hpcd,uint8_t ep_addr)1928 HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1929 {
1930   PCD_EPTypeDef *ep;
1931 
1932   if (((uint32_t)ep_addr & EP_ADDR_MSK) > hpcd->Init.dev_endpoints)
1933   {
1934     return HAL_ERROR;
1935   }
1936 
1937   if ((0x80U & ep_addr) == 0x80U)
1938   {
1939     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
1940     ep->is_in = 1U;
1941   }
1942   else
1943   {
1944     ep = &hpcd->OUT_ep[ep_addr];
1945     ep->is_in = 0U;
1946   }
1947 
1948   ep->is_stall = 1U;
1949   ep->num = ep_addr & EP_ADDR_MSK;
1950 
1951   __HAL_LOCK(hpcd);
1952 
1953   (void)USB_EPSetStall(hpcd->Instance, ep);
1954 
1955   if ((ep_addr & EP_ADDR_MSK) == 0U)
1956   {
1957     (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t)hpcd->Init.dma_enable, (uint8_t *)hpcd->Setup);
1958   }
1959 
1960   __HAL_UNLOCK(hpcd);
1961 
1962   return HAL_OK;
1963 }
1964 
1965 /**
1966   * @brief  Clear a STALL condition over in an endpoint
1967   * @param  hpcd PCD handle
1968   * @param  ep_addr endpoint address
1969   * @retval HAL status
1970   */
HAL_PCD_EP_ClrStall(PCD_HandleTypeDef * hpcd,uint8_t ep_addr)1971 HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1972 {
1973   PCD_EPTypeDef *ep;
1974 
1975   if (((uint32_t)ep_addr & 0x0FU) > hpcd->Init.dev_endpoints)
1976   {
1977     return HAL_ERROR;
1978   }
1979 
1980   if ((0x80U & ep_addr) == 0x80U)
1981   {
1982     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
1983     ep->is_in = 1U;
1984   }
1985   else
1986   {
1987     ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
1988     ep->is_in = 0U;
1989   }
1990 
1991   ep->is_stall = 0U;
1992   ep->num = ep_addr & EP_ADDR_MSK;
1993 
1994   __HAL_LOCK(hpcd);
1995   (void)USB_EPClearStall(hpcd->Instance, ep);
1996   __HAL_UNLOCK(hpcd);
1997 
1998   return HAL_OK;
1999 }
2000 
2001 /**
2002    * @brief  Abort an USB EP transaction.
2003    * @param  hpcd PCD handle
2004    * @param  ep_addr endpoint address
2005    * @retval HAL status
2006    */
HAL_PCD_EP_Abort(PCD_HandleTypeDef * hpcd,uint8_t ep_addr)2007 HAL_StatusTypeDef HAL_PCD_EP_Abort(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
2008 {
2009   HAL_StatusTypeDef ret;
2010   PCD_EPTypeDef *ep;
2011 
2012   if ((0x80U & ep_addr) == 0x80U)
2013   {
2014     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
2015   }
2016   else
2017   {
2018     ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
2019   }
2020 
2021   /* Stop Xfer */
2022   ret = USB_EPStopXfer(hpcd->Instance, ep);
2023 
2024   return ret;
2025 }
2026 
2027 /**
2028   * @brief  Flush an endpoint
2029   * @param  hpcd PCD handle
2030   * @param  ep_addr endpoint address
2031   * @retval HAL status
2032   */
HAL_PCD_EP_Flush(PCD_HandleTypeDef * hpcd,uint8_t ep_addr)2033 HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
2034 {
2035   __HAL_LOCK(hpcd);
2036 
2037   if ((ep_addr & 0x80U) == 0x80U)
2038   {
2039     (void)USB_FlushTxFifo(hpcd->Instance, (uint32_t)ep_addr & EP_ADDR_MSK);
2040   }
2041   else
2042   {
2043     (void)USB_FlushRxFifo(hpcd->Instance);
2044   }
2045 
2046   __HAL_UNLOCK(hpcd);
2047 
2048   return HAL_OK;
2049 }
2050 
2051 /**
2052   * @brief  Activate remote wakeup signalling
2053   * @param  hpcd PCD handle
2054   * @retval HAL status
2055   */
HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef * hpcd)2056 HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
2057 {
2058   return (USB_ActivateRemoteWakeup(hpcd->Instance));
2059 }
2060 
2061 /**
2062   * @brief  De-activate remote wakeup signalling.
2063   * @param  hpcd PCD handle
2064   * @retval HAL status
2065   */
HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef * hpcd)2066 HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
2067 {
2068   return (USB_DeActivateRemoteWakeup(hpcd->Instance));
2069 }
2070 
2071 /**
2072   * @}
2073   */
2074 
2075 /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions
2076   *  @brief   Peripheral State functions
2077   *
2078 @verbatim
2079  ===============================================================================
2080                       ##### Peripheral State functions #####
2081  ===============================================================================
2082     [..]
2083     This subsection permits to get in run-time the status of the peripheral
2084     and the data flow.
2085 
2086 @endverbatim
2087   * @{
2088   */
2089 
2090 /**
2091   * @brief  Return the PCD handle state.
2092   * @param  hpcd PCD handle
2093   * @retval HAL state
2094   */
HAL_PCD_GetState(PCD_HandleTypeDef const * hpcd)2095 PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef const *hpcd)
2096 {
2097   return hpcd->State;
2098 }
2099 
2100 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
2101 /**
2102   * @brief  Set the USB Device high speed test mode.
2103   * @param  hpcd PCD handle
2104   * @param  testmode USB Device high speed test mode
2105   * @retval HAL status
2106   */
HAL_PCD_SetTestMode(const PCD_HandleTypeDef * hpcd,uint8_t testmode)2107 HAL_StatusTypeDef HAL_PCD_SetTestMode(const PCD_HandleTypeDef *hpcd, uint8_t testmode)
2108 {
2109   const USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
2110   uint32_t USBx_BASE = (uint32_t)USBx;
2111 
2112   switch (testmode)
2113   {
2114     case TEST_J:
2115     case TEST_K:
2116     case TEST_SE0_NAK:
2117     case TEST_PACKET:
2118     case TEST_FORCE_EN:
2119       USBx_DEVICE->DCTL |= (uint32_t)testmode << 4;
2120       break;
2121 
2122     default:
2123       break;
2124   }
2125 
2126   return HAL_OK;
2127 }
2128 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2129 /**
2130   * @}
2131   */
2132 
2133 /**
2134   * @}
2135   */
2136 
2137 /* Private functions ---------------------------------------------------------*/
2138 /** @addtogroup PCD_Private_Functions
2139   * @{
2140   */
2141 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
2142 /**
2143   * @brief  Check FIFO for the next packet to be loaded.
2144   * @param  hpcd PCD handle
2145   * @param  epnum endpoint number
2146   * @retval HAL status
2147   */
PCD_WriteEmptyTxFifo(PCD_HandleTypeDef * hpcd,uint32_t epnum)2148 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum)
2149 {
2150   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
2151   uint32_t USBx_BASE = (uint32_t)USBx;
2152   USB_OTG_EPTypeDef *ep;
2153   uint32_t len;
2154   uint32_t len32b;
2155   uint32_t fifoemptymsk;
2156 
2157   ep = &hpcd->IN_ep[epnum];
2158 
2159   if (ep->xfer_count > ep->xfer_len)
2160   {
2161     return HAL_ERROR;
2162   }
2163 
2164   len = ep->xfer_len - ep->xfer_count;
2165 
2166   if (len > ep->maxpacket)
2167   {
2168     len = ep->maxpacket;
2169   }
2170 
2171   len32b = (len + 3U) / 4U;
2172 
2173   while (((USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= len32b) &&
2174          (ep->xfer_count < ep->xfer_len) && (ep->xfer_len != 0U))
2175   {
2176     /* Write the FIFO */
2177     len = ep->xfer_len - ep->xfer_count;
2178 
2179     if (len > ep->maxpacket)
2180     {
2181       len = ep->maxpacket;
2182     }
2183     len32b = (len + 3U) / 4U;
2184 
2185     (void)USB_WritePacket(USBx, ep->xfer_buff, (uint8_t)epnum, (uint16_t)len,
2186                           (uint8_t)hpcd->Init.dma_enable);
2187 
2188     ep->xfer_buff  += len;
2189     ep->xfer_count += len;
2190   }
2191 
2192   if (ep->xfer_len <= ep->xfer_count)
2193   {
2194     fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK));
2195     USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
2196   }
2197 
2198   return HAL_OK;
2199 }
2200 
2201 
2202 /**
2203   * @brief  process EP OUT transfer complete interrupt.
2204   * @param  hpcd PCD handle
2205   * @param  epnum endpoint number
2206   * @retval HAL status
2207   */
PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef * hpcd,uint32_t epnum)2208 static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef *hpcd, uint32_t epnum)
2209 {
2210   USB_OTG_EPTypeDef *ep;
2211   const USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
2212   uint32_t USBx_BASE = (uint32_t)USBx;
2213   uint32_t gSNPSiD = *(__IO const uint32_t *)(&USBx->CID + 0x1U);
2214   uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT;
2215 
2216   if (hpcd->Init.dma_enable == 1U)
2217   {
2218     if ((DoepintReg & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP) /* Class C */
2219     {
2220       /* StupPktRcvd = 1 this is a setup packet */
2221       if ((gSNPSiD > USB_OTG_CORE_ID_300A) &&
2222           ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX))
2223       {
2224         CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
2225       }
2226     }
2227     else if ((DoepintReg & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR) /* Class E */
2228     {
2229       CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
2230     }
2231     else if ((DoepintReg & (USB_OTG_DOEPINT_STUP | USB_OTG_DOEPINT_OTEPSPR)) == 0U)
2232     {
2233       /* StupPktRcvd = 1 this is a setup packet */
2234       if ((gSNPSiD > USB_OTG_CORE_ID_300A) &&
2235           ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX))
2236       {
2237         CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
2238       }
2239       else
2240       {
2241         ep = &hpcd->OUT_ep[epnum];
2242 
2243         /* out data packet received over EP */
2244         ep->xfer_count = ep->xfer_size - (USBx_OUTEP(epnum)->DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ);
2245 
2246         if (epnum == 0U)
2247         {
2248           if (ep->xfer_len == 0U)
2249           {
2250             /* this is ZLP, so prepare EP0 for next setup */
2251             (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup);
2252           }
2253           else
2254           {
2255             ep->xfer_buff += ep->xfer_count;
2256           }
2257         }
2258 
2259 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2260         hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
2261 #else
2262         HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
2263 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2264       }
2265     }
2266     else
2267     {
2268       /* ... */
2269     }
2270   }
2271   else
2272   {
2273     if (gSNPSiD == USB_OTG_CORE_ID_310A)
2274     {
2275       /* StupPktRcvd = 1 this is a setup packet */
2276       if ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX)
2277       {
2278         CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
2279       }
2280       else
2281       {
2282         if ((DoepintReg & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR)
2283         {
2284           CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
2285         }
2286 
2287 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2288         hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
2289 #else
2290         HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
2291 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2292       }
2293     }
2294     else
2295     {
2296       if ((epnum == 0U) && (hpcd->OUT_ep[epnum].xfer_len == 0U))
2297       {
2298         /* this is ZLP, so prepare EP0 for next setup */
2299         (void)USB_EP0_OutStart(hpcd->Instance, 0U, (uint8_t *)hpcd->Setup);
2300       }
2301 
2302 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2303       hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
2304 #else
2305       HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
2306 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2307     }
2308   }
2309 
2310   return HAL_OK;
2311 }
2312 
2313 
2314 /**
2315   * @brief  process EP OUT setup packet received interrupt.
2316   * @param  hpcd PCD handle
2317   * @param  epnum endpoint number
2318   * @retval HAL status
2319   */
PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef * hpcd,uint32_t epnum)2320 static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef *hpcd, uint32_t epnum)
2321 {
2322   const USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
2323   uint32_t USBx_BASE = (uint32_t)USBx;
2324   uint32_t gSNPSiD = *(__IO const uint32_t *)(&USBx->CID + 0x1U);
2325   uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT;
2326 
2327   if ((gSNPSiD > USB_OTG_CORE_ID_300A) &&
2328       ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX))
2329   {
2330     CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
2331   }
2332 
2333   /* Inform the upper layer that a setup packet is available */
2334 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2335   hpcd->SetupStageCallback(hpcd);
2336 #else
2337   HAL_PCD_SetupStageCallback(hpcd);
2338 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2339 
2340   if ((gSNPSiD > USB_OTG_CORE_ID_300A) && (hpcd->Init.dma_enable == 1U))
2341   {
2342     (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup);
2343   }
2344 
2345   return HAL_OK;
2346 }
2347 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2348 
2349 
2350 /**
2351   * @}
2352   */
2353 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2354 #endif /* HAL_PCD_MODULE_ENABLED */
2355 
2356 /**
2357   * @}
2358   */
2359 
2360 /**
2361   * @}
2362   */
2363