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