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