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