Create release.yml
[betaflight.git] / lib / main / STM32H7 / Drivers / STM32H7xx_HAL_Driver / Src / stm32h7xx_hal_pcd.c
blob031f01fd604b97f99a8d77c82935821ef5479565
1 /**
2 ******************************************************************************
3 * @file stm32h7xx_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
13 @verbatim
14 ==============================================================================
15 ##### How to use this driver #####
16 ==============================================================================
17 [..]
18 The PCD HAL driver can be used as follows:
20 (#) Declare a PCD_HandleTypeDef handle structure, for example:
21 PCD_HandleTypeDef hpcd;
23 (#) Fill parameters of Init structure in HCD handle
25 (#) Call HAL_PCD_Init() API to initialize the PCD peripheral (Core, Device core, ...)
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_OTG_FS_CLK_ENABLE();
30 (+++) __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); (For High Speed Mode)
32 (##) Initialize the related GPIO clocks
33 (##) Configure PCD pin-out
34 (##) Configure PCD NVIC interrupt
36 (#)Associate the Upper USB device stack to the HAL PCD Driver:
37 (##) hpcd.pData = pdev;
39 (#)Enable PCD transmission and reception:
40 (##) HAL_PCD_Start();
42 @endverbatim
43 ******************************************************************************
44 * @attention
46 * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
47 * All rights reserved.</center></h2>
49 * This software component is licensed by ST under BSD 3-Clause license,
50 * the "License"; You may not use this file except in compliance with the
51 * License. You may obtain a copy of the License at:
52 * opensource.org/licenses/BSD-3-Clause
54 ******************************************************************************
57 /* Includes ------------------------------------------------------------------*/
58 #include "stm32h7xx_hal.h"
60 /** @addtogroup STM32H7xx_HAL_Driver
61 * @{
64 /** @defgroup PCD PCD
65 * @brief PCD HAL module driver
66 * @{
69 #ifdef HAL_PCD_MODULE_ENABLED
71 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
73 /* Private types -------------------------------------------------------------*/
74 /* Private variables ---------------------------------------------------------*/
75 /* Private constants ---------------------------------------------------------*/
76 /* Private macros ------------------------------------------------------------*/
77 /** @defgroup PCD_Private_Macros PCD Private Macros
78 * @{
80 #define PCD_MIN(a, b) (((a) < (b)) ? (a) : (b))
81 #define PCD_MAX(a, b) (((a) > (b)) ? (a) : (b))
82 /**
83 * @}
86 /* Private functions prototypes ----------------------------------------------*/
87 /** @defgroup PCD_Private_Functions PCD Private Functions
88 * @{
90 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
91 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum);
92 static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef *hpcd, uint32_t epnum);
93 static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef *hpcd, uint32_t epnum);
94 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
95 /**
96 * @}
99 /* Exported functions --------------------------------------------------------*/
100 /** @defgroup PCD_Exported_Functions PCD Exported Functions
101 * @{
104 /** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
105 * @brief Initialization and Configuration functions
107 @verbatim
108 ===============================================================================
109 ##### Initialization and de-initialization functions #####
110 ===============================================================================
111 [..] This section provides functions allowing to:
113 @endverbatim
114 * @{
118 * @brief Initializes the PCD according to the specified
119 * parameters in the PCD_InitTypeDef and initialize the associated handle.
120 * @param hpcd PCD handle
121 * @retval HAL status
123 HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd)
125 USB_OTG_GlobalTypeDef *USBx;
126 uint8_t i;
128 /* Check the PCD handle allocation */
129 if (hpcd == NULL)
131 return HAL_ERROR;
134 /* Check the parameters */
135 assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance));
137 USBx = hpcd->Instance;
139 if (hpcd->State == HAL_PCD_STATE_RESET)
141 /* Allocate lock resource and initialize it */
142 hpcd->Lock = HAL_UNLOCKED;
144 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
145 hpcd->SOFCallback = HAL_PCD_SOFCallback;
146 hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
147 hpcd->ResetCallback = HAL_PCD_ResetCallback;
148 hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
149 hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
150 hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
151 hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
152 hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback;
153 hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback;
154 hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback;
155 hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback;
156 hpcd->LPMCallback = HAL_PCDEx_LPM_Callback;
157 hpcd->BCDCallback = HAL_PCDEx_BCD_Callback;
159 if (hpcd->MspInitCallback == NULL)
161 hpcd->MspInitCallback = HAL_PCD_MspInit;
164 /* Init the low level hardware */
165 hpcd->MspInitCallback(hpcd);
166 #else
167 /* Init the low level hardware : GPIO, CLOCK, NVIC... */
168 HAL_PCD_MspInit(hpcd);
169 #endif /* (USE_HAL_PCD_REGISTER_CALLBACKS) */
172 hpcd->State = HAL_PCD_STATE_BUSY;
174 /* Disable DMA mode for FS instance */
175 if ((USBx->CID & (0x1U << 8)) == 0U)
177 hpcd->Init.dma_enable = 0U;
180 /* Disable the Interrupts */
181 __HAL_PCD_DISABLE(hpcd);
183 /*Init the Core (common init.) */
184 if (USB_CoreInit(hpcd->Instance, hpcd->Init) != HAL_OK)
186 hpcd->State = HAL_PCD_STATE_ERROR;
187 return HAL_ERROR;
190 /* Force Device Mode*/
191 (void)USB_SetCurrentMode(hpcd->Instance, USB_DEVICE_MODE);
193 /* Init endpoints structures */
194 for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
196 /* Init ep structure */
197 hpcd->IN_ep[i].is_in = 1U;
198 hpcd->IN_ep[i].num = i;
199 hpcd->IN_ep[i].tx_fifo_num = i;
200 /* Control until ep is activated */
201 hpcd->IN_ep[i].type = EP_TYPE_CTRL;
202 hpcd->IN_ep[i].maxpacket = 0U;
203 hpcd->IN_ep[i].xfer_buff = 0U;
204 hpcd->IN_ep[i].xfer_len = 0U;
207 for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
209 hpcd->OUT_ep[i].is_in = 0U;
210 hpcd->OUT_ep[i].num = i;
211 /* Control until ep is activated */
212 hpcd->OUT_ep[i].type = EP_TYPE_CTRL;
213 hpcd->OUT_ep[i].maxpacket = 0U;
214 hpcd->OUT_ep[i].xfer_buff = 0U;
215 hpcd->OUT_ep[i].xfer_len = 0U;
218 /* Init Device */
219 if (USB_DevInit(hpcd->Instance, hpcd->Init) != HAL_OK)
221 hpcd->State = HAL_PCD_STATE_ERROR;
222 return HAL_ERROR;
225 hpcd->USB_Address = 0U;
226 hpcd->State = HAL_PCD_STATE_READY;
228 /* Activate LPM */
229 if (hpcd->Init.lpm_enable == 1U)
231 (void)HAL_PCDEx_ActivateLPM(hpcd);
234 (void)USB_DevDisconnect(hpcd->Instance);
236 return HAL_OK;
240 * @brief DeInitializes the PCD peripheral.
241 * @param hpcd PCD handle
242 * @retval HAL status
244 HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
246 /* Check the PCD handle allocation */
247 if (hpcd == NULL)
249 return HAL_ERROR;
252 hpcd->State = HAL_PCD_STATE_BUSY;
254 /* Stop Device */
255 (void)HAL_PCD_Stop(hpcd);
257 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
258 if (hpcd->MspDeInitCallback == NULL)
260 hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; /* Legacy weak MspDeInit */
263 /* DeInit the low level hardware */
264 hpcd->MspDeInitCallback(hpcd);
265 #else
266 /* DeInit the low level hardware: CLOCK, NVIC.*/
267 HAL_PCD_MspDeInit(hpcd);
268 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
270 hpcd->State = HAL_PCD_STATE_RESET;
272 return HAL_OK;
276 * @brief Initializes the PCD MSP.
277 * @param hpcd PCD handle
278 * @retval None
280 __weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
282 /* Prevent unused argument(s) compilation warning */
283 UNUSED(hpcd);
285 /* NOTE : This function should not be modified, when the callback is needed,
286 the HAL_PCD_MspInit could be implemented in the user file
291 * @brief DeInitializes PCD MSP.
292 * @param hpcd PCD handle
293 * @retval None
295 __weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
297 /* Prevent unused argument(s) compilation warning */
298 UNUSED(hpcd);
300 /* NOTE : This function should not be modified, when the callback is needed,
301 the HAL_PCD_MspDeInit could be implemented in the user file
305 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
307 * @brief Register a User USB PCD Callback
308 * To be used instead of the weak predefined callback
309 * @param hpcd USB PCD handle
310 * @param CallbackID ID of the callback to be registered
311 * This parameter can be one of the following values:
312 * @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
313 * @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
314 * @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
315 * @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
316 * @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
317 * @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
318 * @arg @ref HAL_PCD_DISCONNECT_CB_ID OTG PCD Disconnect callback ID
319 * @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
320 * @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
321 * @param pCallback pointer to the Callback function
322 * @retval HAL status
324 HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID, pPCD_CallbackTypeDef pCallback)
326 HAL_StatusTypeDef status = HAL_OK;
328 if (pCallback == NULL)
330 /* Update the error code */
331 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
332 return HAL_ERROR;
334 /* Process locked */
335 __HAL_LOCK(hpcd);
337 if (hpcd->State == HAL_PCD_STATE_READY)
339 switch (CallbackID)
341 case HAL_PCD_SOF_CB_ID :
342 hpcd->SOFCallback = pCallback;
343 break;
345 case HAL_PCD_SETUPSTAGE_CB_ID :
346 hpcd->SetupStageCallback = pCallback;
347 break;
349 case HAL_PCD_RESET_CB_ID :
350 hpcd->ResetCallback = pCallback;
351 break;
353 case HAL_PCD_SUSPEND_CB_ID :
354 hpcd->SuspendCallback = pCallback;
355 break;
357 case HAL_PCD_RESUME_CB_ID :
358 hpcd->ResumeCallback = pCallback;
359 break;
361 case HAL_PCD_CONNECT_CB_ID :
362 hpcd->ConnectCallback = pCallback;
363 break;
365 case HAL_PCD_DISCONNECT_CB_ID :
366 hpcd->DisconnectCallback = pCallback;
367 break;
369 case HAL_PCD_MSPINIT_CB_ID :
370 hpcd->MspInitCallback = pCallback;
371 break;
373 case HAL_PCD_MSPDEINIT_CB_ID :
374 hpcd->MspDeInitCallback = pCallback;
375 break;
377 default :
378 /* Update the error code */
379 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
380 /* Return error status */
381 status = HAL_ERROR;
382 break;
385 else if (hpcd->State == HAL_PCD_STATE_RESET)
387 switch (CallbackID)
389 case HAL_PCD_MSPINIT_CB_ID :
390 hpcd->MspInitCallback = pCallback;
391 break;
393 case HAL_PCD_MSPDEINIT_CB_ID :
394 hpcd->MspDeInitCallback = pCallback;
395 break;
397 default :
398 /* Update the error code */
399 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
400 /* Return error status */
401 status = HAL_ERROR;
402 break;
405 else
407 /* Update the error code */
408 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
409 /* Return error status */
410 status = HAL_ERROR;
413 /* Release Lock */
414 __HAL_UNLOCK(hpcd);
415 return status;
419 * @brief Unregister an USB PCD Callback
420 * USB PCD callabck is redirected to the weak predefined callback
421 * @param hpcd USB PCD handle
422 * @param CallbackID ID of the callback to be unregistered
423 * This parameter can be one of the following values:
424 * @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
425 * @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
426 * @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
427 * @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
428 * @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
429 * @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
430 * @arg @ref HAL_PCD_DISCONNECT_CB_ID OTG PCD Disconnect callback ID
431 * @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
432 * @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
433 * @retval HAL status
435 HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID)
437 HAL_StatusTypeDef status = HAL_OK;
439 /* Process locked */
440 __HAL_LOCK(hpcd);
442 /* Setup Legacy weak Callbacks */
443 if (hpcd->State == HAL_PCD_STATE_READY)
445 switch (CallbackID)
447 case HAL_PCD_SOF_CB_ID :
448 hpcd->SOFCallback = HAL_PCD_SOFCallback;
449 break;
451 case HAL_PCD_SETUPSTAGE_CB_ID :
452 hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
453 break;
455 case HAL_PCD_RESET_CB_ID :
456 hpcd->ResetCallback = HAL_PCD_ResetCallback;
457 break;
459 case HAL_PCD_SUSPEND_CB_ID :
460 hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
461 break;
463 case HAL_PCD_RESUME_CB_ID :
464 hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
465 break;
467 case HAL_PCD_CONNECT_CB_ID :
468 hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
469 break;
471 case HAL_PCD_DISCONNECT_CB_ID :
472 hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
473 break;
475 case HAL_PCD_MSPINIT_CB_ID :
476 hpcd->MspInitCallback = HAL_PCD_MspInit;
477 break;
479 case HAL_PCD_MSPDEINIT_CB_ID :
480 hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
481 break;
483 default :
484 /* Update the error code */
485 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
487 /* Return error status */
488 status = HAL_ERROR;
489 break;
492 else if (hpcd->State == HAL_PCD_STATE_RESET)
494 switch (CallbackID)
496 case HAL_PCD_MSPINIT_CB_ID :
497 hpcd->MspInitCallback = HAL_PCD_MspInit;
498 break;
500 case HAL_PCD_MSPDEINIT_CB_ID :
501 hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
502 break;
504 default :
505 /* Update the error code */
506 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
508 /* Return error status */
509 status = HAL_ERROR;
510 break;
513 else
515 /* Update the error code */
516 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
518 /* Return error status */
519 status = HAL_ERROR;
522 /* Release Lock */
523 __HAL_UNLOCK(hpcd);
524 return status;
528 * @brief Register USB PCD Data OUT Stage Callback
529 * To be used instead of the weak HAL_PCD_DataOutStageCallback() predefined callback
530 * @param hpcd PCD handle
531 * @param pCallback pointer to the USB PCD Data OUT Stage Callback function
532 * @retval HAL status
534 HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd, pPCD_DataOutStageCallbackTypeDef pCallback)
536 HAL_StatusTypeDef status = HAL_OK;
538 if (pCallback == NULL)
540 /* Update the error code */
541 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
543 return HAL_ERROR;
546 /* Process locked */
547 __HAL_LOCK(hpcd);
549 if (hpcd->State == HAL_PCD_STATE_READY)
551 hpcd->DataOutStageCallback = pCallback;
553 else
555 /* Update the error code */
556 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
558 /* Return error status */
559 status = HAL_ERROR;
562 /* Release Lock */
563 __HAL_UNLOCK(hpcd);
565 return status;
569 * @brief UnRegister the USB PCD Data OUT Stage Callback
570 * USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataOutStageCallback() predefined callback
571 * @param hpcd PCD handle
572 * @retval HAL status
574 HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd)
576 HAL_StatusTypeDef status = HAL_OK;
578 /* Process locked */
579 __HAL_LOCK(hpcd);
581 if (hpcd->State == HAL_PCD_STATE_READY)
583 hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback; /* Legacy weak DataOutStageCallback */
585 else
587 /* Update the error code */
588 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
590 /* Return error status */
591 status = HAL_ERROR;
594 /* Release Lock */
595 __HAL_UNLOCK(hpcd);
597 return status;
601 * @brief Register USB PCD Data IN Stage Callback
602 * To be used instead of the weak HAL_PCD_DataInStageCallback() predefined callback
603 * @param hpcd PCD handle
604 * @param pCallback pointer to the USB PCD Data IN Stage Callback function
605 * @retval HAL status
607 HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd, pPCD_DataInStageCallbackTypeDef pCallback)
609 HAL_StatusTypeDef status = HAL_OK;
611 if (pCallback == NULL)
613 /* Update the error code */
614 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
616 return HAL_ERROR;
619 /* Process locked */
620 __HAL_LOCK(hpcd);
622 if (hpcd->State == HAL_PCD_STATE_READY)
624 hpcd->DataInStageCallback = pCallback;
626 else
628 /* Update the error code */
629 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
631 /* Return error status */
632 status = HAL_ERROR;
635 /* Release Lock */
636 __HAL_UNLOCK(hpcd);
638 return status;
642 * @brief UnRegister the USB PCD Data IN Stage Callback
643 * USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataInStageCallback() predefined callback
644 * @param hpcd PCD handle
645 * @retval HAL status
647 HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd)
649 HAL_StatusTypeDef status = HAL_OK;
651 /* Process locked */
652 __HAL_LOCK(hpcd);
654 if (hpcd->State == HAL_PCD_STATE_READY)
656 hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback; /* Legacy weak DataInStageCallback */
658 else
660 /* Update the error code */
661 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
663 /* Return error status */
664 status = HAL_ERROR;
667 /* Release Lock */
668 __HAL_UNLOCK(hpcd);
670 return status;
674 * @brief Register USB PCD Iso OUT incomplete Callback
675 * To be used instead of the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
676 * @param hpcd PCD handle
677 * @param pCallback pointer to the USB PCD Iso OUT incomplete Callback function
678 * @retval HAL status
680 HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd, pPCD_IsoOutIncpltCallbackTypeDef pCallback)
682 HAL_StatusTypeDef status = HAL_OK;
684 if (pCallback == NULL)
686 /* Update the error code */
687 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
689 return HAL_ERROR;
692 /* Process locked */
693 __HAL_LOCK(hpcd);
695 if (hpcd->State == HAL_PCD_STATE_READY)
697 hpcd->ISOOUTIncompleteCallback = pCallback;
699 else
701 /* Update the error code */
702 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
704 /* Return error status */
705 status = HAL_ERROR;
708 /* Release Lock */
709 __HAL_UNLOCK(hpcd);
711 return status;
715 * @brief UnRegister the USB PCD Iso OUT incomplete Callback
716 * USB PCD Iso OUT incomplete Callback is redirected to the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
717 * @param hpcd PCD handle
718 * @retval HAL status
720 HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd)
722 HAL_StatusTypeDef status = HAL_OK;
724 /* Process locked */
725 __HAL_LOCK(hpcd);
727 if (hpcd->State == HAL_PCD_STATE_READY)
729 hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback; /* Legacy weak ISOOUTIncompleteCallback */
731 else
733 /* Update the error code */
734 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
736 /* Return error status */
737 status = HAL_ERROR;
740 /* Release Lock */
741 __HAL_UNLOCK(hpcd);
743 return status;
747 * @brief Register USB PCD Iso IN incomplete Callback
748 * To be used instead of the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
749 * @param hpcd PCD handle
750 * @param pCallback pointer to the USB PCD Iso IN incomplete Callback function
751 * @retval HAL status
753 HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd, pPCD_IsoInIncpltCallbackTypeDef pCallback)
755 HAL_StatusTypeDef status = HAL_OK;
757 if (pCallback == NULL)
759 /* Update the error code */
760 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
762 return HAL_ERROR;
765 /* Process locked */
766 __HAL_LOCK(hpcd);
768 if (hpcd->State == HAL_PCD_STATE_READY)
770 hpcd->ISOINIncompleteCallback = pCallback;
772 else
774 /* Update the error code */
775 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
777 /* Return error status */
778 status = HAL_ERROR;
781 /* Release Lock */
782 __HAL_UNLOCK(hpcd);
784 return status;
788 * @brief UnRegister the USB PCD Iso IN incomplete Callback
789 * USB PCD Iso IN incomplete Callback is redirected to the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
790 * @param hpcd PCD handle
791 * @retval HAL status
793 HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd)
795 HAL_StatusTypeDef status = HAL_OK;
797 /* Process locked */
798 __HAL_LOCK(hpcd);
800 if (hpcd->State == HAL_PCD_STATE_READY)
802 hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback; /* Legacy weak ISOINIncompleteCallback */
804 else
806 /* Update the error code */
807 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
809 /* Return error status */
810 status = HAL_ERROR;
813 /* Release Lock */
814 __HAL_UNLOCK(hpcd);
816 return status;
820 * @brief Register USB PCD BCD Callback
821 * To be used instead of the weak HAL_PCDEx_BCD_Callback() predefined callback
822 * @param hpcd PCD handle
823 * @param pCallback pointer to the USB PCD BCD Callback function
824 * @retval HAL status
826 HAL_StatusTypeDef HAL_PCD_RegisterBcdCallback(PCD_HandleTypeDef *hpcd, pPCD_BcdCallbackTypeDef pCallback)
828 HAL_StatusTypeDef status = HAL_OK;
830 if (pCallback == NULL)
832 /* Update the error code */
833 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
835 return HAL_ERROR;
838 /* Process locked */
839 __HAL_LOCK(hpcd);
841 if (hpcd->State == HAL_PCD_STATE_READY)
843 hpcd->BCDCallback = pCallback;
845 else
847 /* Update the error code */
848 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
850 /* Return error status */
851 status = HAL_ERROR;
854 /* Release Lock */
855 __HAL_UNLOCK(hpcd);
857 return status;
861 * @brief UnRegister the USB PCD BCD Callback
862 * USB BCD Callback is redirected to the weak HAL_PCDEx_BCD_Callback() predefined callback
863 * @param hpcd PCD handle
864 * @retval HAL status
866 HAL_StatusTypeDef HAL_PCD_UnRegisterBcdCallback(PCD_HandleTypeDef *hpcd)
868 HAL_StatusTypeDef status = HAL_OK;
870 /* Process locked */
871 __HAL_LOCK(hpcd);
873 if (hpcd->State == HAL_PCD_STATE_READY)
875 hpcd->BCDCallback = HAL_PCDEx_BCD_Callback; /* Legacy weak HAL_PCDEx_BCD_Callback */
877 else
879 /* Update the error code */
880 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
882 /* Return error status */
883 status = HAL_ERROR;
886 /* Release Lock */
887 __HAL_UNLOCK(hpcd);
889 return status;
893 * @brief Register USB PCD LPM Callback
894 * To be used instead of the weak HAL_PCDEx_LPM_Callback() predefined callback
895 * @param hpcd PCD handle
896 * @param pCallback pointer to the USB PCD LPM Callback function
897 * @retval HAL status
899 HAL_StatusTypeDef HAL_PCD_RegisterLpmCallback(PCD_HandleTypeDef *hpcd, pPCD_LpmCallbackTypeDef pCallback)
901 HAL_StatusTypeDef status = HAL_OK;
903 if (pCallback == NULL)
905 /* Update the error code */
906 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
908 return HAL_ERROR;
911 /* Process locked */
912 __HAL_LOCK(hpcd);
914 if (hpcd->State == HAL_PCD_STATE_READY)
916 hpcd->LPMCallback = pCallback;
918 else
920 /* Update the error code */
921 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
923 /* Return error status */
924 status = HAL_ERROR;
927 /* Release Lock */
928 __HAL_UNLOCK(hpcd);
930 return status;
934 * @brief UnRegister the USB PCD LPM Callback
935 * USB LPM Callback is redirected to the weak HAL_PCDEx_LPM_Callback() predefined callback
936 * @param hpcd PCD handle
937 * @retval HAL status
939 HAL_StatusTypeDef HAL_PCD_UnRegisterLpmCallback(PCD_HandleTypeDef *hpcd)
941 HAL_StatusTypeDef status = HAL_OK;
943 /* Process locked */
944 __HAL_LOCK(hpcd);
946 if (hpcd->State == HAL_PCD_STATE_READY)
948 hpcd->LPMCallback = HAL_PCDEx_LPM_Callback; /* Legacy weak HAL_PCDEx_LPM_Callback */
950 else
952 /* Update the error code */
953 hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
955 /* Return error status */
956 status = HAL_ERROR;
959 /* Release Lock */
960 __HAL_UNLOCK(hpcd);
962 return status;
964 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
967 * @}
970 /** @defgroup PCD_Exported_Functions_Group2 Input and Output operation functions
971 * @brief Data transfers functions
973 @verbatim
974 ===============================================================================
975 ##### IO operation functions #####
976 ===============================================================================
977 [..]
978 This subsection provides a set of functions allowing to manage the PCD data
979 transfers.
981 @endverbatim
982 * @{
986 * @brief Start the USB device
987 * @param hpcd PCD handle
988 * @retval HAL status
990 HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)
992 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
993 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
994 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
996 __HAL_LOCK(hpcd);
997 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
998 if ((hpcd->Init.battery_charging_enable == 1U) &&
999 (hpcd->Init.phy_itface != USB_OTG_ULPI_PHY))
1001 /* Enable USB Transceiver */
1002 USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
1004 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
1005 (void)USB_DevConnect(hpcd->Instance);
1006 __HAL_PCD_ENABLE(hpcd);
1007 __HAL_UNLOCK(hpcd);
1008 return HAL_OK;
1012 * @brief Stop the USB device.
1013 * @param hpcd PCD handle
1014 * @retval HAL status
1016 HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
1018 __HAL_LOCK(hpcd);
1019 __HAL_PCD_DISABLE(hpcd);
1021 if (USB_StopDevice(hpcd->Instance) != HAL_OK)
1023 __HAL_UNLOCK(hpcd);
1024 return HAL_ERROR;
1027 (void)USB_DevDisconnect(hpcd->Instance);
1028 __HAL_UNLOCK(hpcd);
1030 return HAL_OK;
1032 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
1034 * @brief Handles PCD interrupt request.
1035 * @param hpcd PCD handle
1036 * @retval HAL status
1038 void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
1040 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1041 uint32_t USBx_BASE = (uint32_t)USBx;
1042 uint32_t i, ep_intr, epint, epnum;
1043 uint32_t fifoemptymsk, temp;
1044 USB_OTG_EPTypeDef *ep;
1046 /* ensure that we are in device mode */
1047 if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE)
1049 /* avoid spurious interrupt */
1050 if (__HAL_PCD_IS_INVALID_INTERRUPT(hpcd))
1052 return;
1055 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS))
1057 /* incorrect mode, acknowledge the interrupt */
1058 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS);
1061 /* Handle RxQLevel Interrupt */
1062 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL))
1064 USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
1066 temp = USBx->GRXSTSP;
1068 ep = &hpcd->OUT_ep[temp & USB_OTG_GRXSTSP_EPNUM];
1070 if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_DATA_UPDT)
1072 if ((temp & USB_OTG_GRXSTSP_BCNT) != 0U)
1074 (void)USB_ReadPacket(USBx, ep->xfer_buff,
1075 (uint16_t)((temp & USB_OTG_GRXSTSP_BCNT) >> 4));
1077 ep->xfer_buff += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
1078 ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
1081 else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_SETUP_UPDT)
1083 (void)USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8U);
1084 ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
1086 else
1088 /* ... */
1090 USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
1093 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT))
1095 epnum = 0U;
1097 /* Read in the device interrupt bits */
1098 ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance);
1100 while (ep_intr != 0U)
1102 if ((ep_intr & 0x1U) != 0U)
1104 epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, (uint8_t)epnum);
1106 if ((epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC)
1108 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC);
1109 (void)PCD_EP_OutXfrComplete_int(hpcd, epnum);
1112 if ((epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP)
1114 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP);
1115 /* Class B setup phase done for previous decoded setup */
1116 (void)PCD_EP_OutSetupPacket_int(hpcd, epnum);
1119 if ((epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS)
1121 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS);
1124 /* Clear Status Phase Received interrupt */
1125 if ((epint & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR)
1127 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
1130 /* Clear OUT NAK interrupt */
1131 if ((epint & USB_OTG_DOEPINT_NAK) == USB_OTG_DOEPINT_NAK)
1133 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_NAK);
1136 epnum++;
1137 ep_intr >>= 1U;
1141 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT))
1143 /* Read in the device interrupt bits */
1144 ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance);
1146 epnum = 0U;
1148 while (ep_intr != 0U)
1150 if ((ep_intr & 0x1U) != 0U) /* In ITR */
1152 epint = USB_ReadDevInEPInterrupt(hpcd->Instance, (uint8_t)epnum);
1154 if ((epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC)
1156 fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK));
1157 USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
1159 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC);
1161 if (hpcd->Init.dma_enable == 1U)
1163 hpcd->IN_ep[epnum].xfer_buff += hpcd->IN_ep[epnum].maxpacket;
1165 /* this is ZLP, so prepare EP0 for next setup */
1166 if ((epnum == 0U) && (hpcd->IN_ep[epnum].xfer_len == 0U))
1168 /* prepare to rx more setup packets */
1169 (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup);
1173 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1174 hpcd->DataInStageCallback(hpcd, (uint8_t)epnum);
1175 #else
1176 HAL_PCD_DataInStageCallback(hpcd, (uint8_t)epnum);
1177 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1179 if ((epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC)
1181 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC);
1183 if ((epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE)
1185 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE);
1187 if ((epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE)
1189 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE);
1191 if ((epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD)
1193 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD);
1195 if ((epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE)
1197 (void)PCD_WriteEmptyTxFifo(hpcd, epnum);
1200 epnum++;
1201 ep_intr >>= 1U;
1205 /* Handle Resume Interrupt */
1206 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT))
1208 /* Clear the Remote Wake-up Signaling */
1209 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
1211 if (hpcd->LPM_State == LPM_L1)
1213 hpcd->LPM_State = LPM_L0;
1215 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1216 hpcd->LPMCallback(hpcd, PCD_LPM_L0_ACTIVE);
1217 #else
1218 HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE);
1219 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1221 else
1223 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1224 hpcd->ResumeCallback(hpcd);
1225 #else
1226 HAL_PCD_ResumeCallback(hpcd);
1227 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1230 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT);
1233 /* Handle Suspend Interrupt */
1234 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP))
1236 if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
1238 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1239 hpcd->SuspendCallback(hpcd);
1240 #else
1241 HAL_PCD_SuspendCallback(hpcd);
1242 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1244 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP);
1247 /* Handle LPM Interrupt */
1248 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT))
1250 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT);
1252 if (hpcd->LPM_State == LPM_L0)
1254 hpcd->LPM_State = LPM_L1;
1255 hpcd->BESL = (hpcd->Instance->GLPMCFG & USB_OTG_GLPMCFG_BESL) >> 2U;
1257 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1258 hpcd->LPMCallback(hpcd, PCD_LPM_L1_ACTIVE);
1259 #else
1260 HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE);
1261 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1263 else
1265 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1266 hpcd->SuspendCallback(hpcd);
1267 #else
1268 HAL_PCD_SuspendCallback(hpcd);
1269 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1273 /* Handle Reset Interrupt */
1274 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST))
1276 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
1277 (void)USB_FlushTxFifo(hpcd->Instance, 0x10U);
1279 for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
1281 USBx_INEP(i)->DIEPINT = 0xFB7FU;
1282 USBx_INEP(i)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
1283 USBx_INEP(i)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
1284 USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
1285 USBx_OUTEP(i)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
1286 USBx_OUTEP(i)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
1288 USBx_DEVICE->DAINTMSK |= 0x10001U;
1290 if (hpcd->Init.use_dedicated_ep1 != 0U)
1292 USBx_DEVICE->DOUTEP1MSK |= USB_OTG_DOEPMSK_STUPM |
1293 USB_OTG_DOEPMSK_XFRCM |
1294 USB_OTG_DOEPMSK_EPDM;
1296 USBx_DEVICE->DINEP1MSK |= USB_OTG_DIEPMSK_TOM |
1297 USB_OTG_DIEPMSK_XFRCM |
1298 USB_OTG_DIEPMSK_EPDM;
1300 else
1302 USBx_DEVICE->DOEPMSK |= USB_OTG_DOEPMSK_STUPM |
1303 USB_OTG_DOEPMSK_XFRCM |
1304 USB_OTG_DOEPMSK_EPDM |
1305 USB_OTG_DOEPMSK_OTEPSPRM |
1306 USB_OTG_DOEPMSK_NAKM;
1308 USBx_DEVICE->DIEPMSK |= USB_OTG_DIEPMSK_TOM |
1309 USB_OTG_DIEPMSK_XFRCM |
1310 USB_OTG_DIEPMSK_EPDM;
1313 /* Set Default Address to 0 */
1314 USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD;
1316 /* setup EP0 to receive SETUP packets */
1317 (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t)hpcd->Init.dma_enable,
1318 (uint8_t *)hpcd->Setup);
1320 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST);
1323 /* Handle Enumeration done Interrupt */
1324 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE))
1326 (void)USB_ActivateSetup(hpcd->Instance);
1327 hpcd->Init.speed = USB_GetDevSpeed(hpcd->Instance);
1329 /* Set USB Turnaround time */
1330 (void)USB_SetTurnaroundTime(hpcd->Instance,
1331 HAL_RCC_GetHCLKFreq(),
1332 (uint8_t)hpcd->Init.speed);
1334 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1335 hpcd->ResetCallback(hpcd);
1336 #else
1337 HAL_PCD_ResetCallback(hpcd);
1338 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1340 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE);
1343 /* Handle SOF Interrupt */
1344 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF))
1346 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1347 hpcd->SOFCallback(hpcd);
1348 #else
1349 HAL_PCD_SOFCallback(hpcd);
1350 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1352 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF);
1355 /* Handle Incomplete ISO IN Interrupt */
1356 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR))
1358 /* Keep application checking the corresponding Iso IN endpoint
1359 causing the incomplete Interrupt */
1360 epnum = 0U;
1362 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1363 hpcd->ISOINIncompleteCallback(hpcd, (uint8_t)epnum);
1364 #else
1365 HAL_PCD_ISOINIncompleteCallback(hpcd, (uint8_t)epnum);
1366 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1368 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR);
1371 /* Handle Incomplete ISO OUT Interrupt */
1372 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
1374 /* Keep application checking the corresponding Iso OUT endpoint
1375 causing the incomplete Interrupt */
1376 epnum = 0U;
1378 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1379 hpcd->ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum);
1380 #else
1381 HAL_PCD_ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum);
1382 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1384 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
1387 /* Handle Connection event Interrupt */
1388 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT))
1390 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1391 hpcd->ConnectCallback(hpcd);
1392 #else
1393 HAL_PCD_ConnectCallback(hpcd);
1394 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1396 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT);
1399 /* Handle Disconnection event Interrupt */
1400 if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT))
1402 temp = hpcd->Instance->GOTGINT;
1404 if ((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET)
1406 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1407 hpcd->DisconnectCallback(hpcd);
1408 #else
1409 HAL_PCD_DisconnectCallback(hpcd);
1410 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1412 hpcd->Instance->GOTGINT |= temp;
1416 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
1420 * @brief Data OUT stage callback.
1421 * @param hpcd PCD handle
1422 * @param epnum endpoint number
1423 * @retval None
1425 __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
1427 /* Prevent unused argument(s) compilation warning */
1428 UNUSED(hpcd);
1429 UNUSED(epnum);
1431 /* NOTE : This function should not be modified, when the callback is needed,
1432 the HAL_PCD_DataOutStageCallback could be implemented in the user file
1437 * @brief Data IN stage callback
1438 * @param hpcd PCD handle
1439 * @param epnum endpoint number
1440 * @retval None
1442 __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
1444 /* Prevent unused argument(s) compilation warning */
1445 UNUSED(hpcd);
1446 UNUSED(epnum);
1448 /* NOTE : This function should not be modified, when the callback is needed,
1449 the HAL_PCD_DataInStageCallback could be implemented in the user file
1453 * @brief Setup stage callback
1454 * @param hpcd PCD handle
1455 * @retval None
1457 __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
1459 /* Prevent unused argument(s) compilation warning */
1460 UNUSED(hpcd);
1462 /* NOTE : This function should not be modified, when the callback is needed,
1463 the HAL_PCD_SetupStageCallback could be implemented in the user file
1468 * @brief USB Start Of Frame callback.
1469 * @param hpcd PCD handle
1470 * @retval None
1472 __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
1474 /* Prevent unused argument(s) compilation warning */
1475 UNUSED(hpcd);
1477 /* NOTE : This function should not be modified, when the callback is needed,
1478 the HAL_PCD_SOFCallback could be implemented in the user file
1483 * @brief USB Reset callback.
1484 * @param hpcd PCD handle
1485 * @retval None
1487 __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
1489 /* Prevent unused argument(s) compilation warning */
1490 UNUSED(hpcd);
1492 /* NOTE : This function should not be modified, when the callback is needed,
1493 the HAL_PCD_ResetCallback could be implemented in the user file
1498 * @brief Suspend event callback.
1499 * @param hpcd PCD handle
1500 * @retval None
1502 __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
1504 /* Prevent unused argument(s) compilation warning */
1505 UNUSED(hpcd);
1507 /* NOTE : This function should not be modified, when the callback is needed,
1508 the HAL_PCD_SuspendCallback could be implemented in the user file
1513 * @brief Resume event callback.
1514 * @param hpcd PCD handle
1515 * @retval None
1517 __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
1519 /* Prevent unused argument(s) compilation warning */
1520 UNUSED(hpcd);
1522 /* NOTE : This function should not be modified, when the callback is needed,
1523 the HAL_PCD_ResumeCallback could be implemented in the user file
1528 * @brief Incomplete ISO OUT callback.
1529 * @param hpcd PCD handle
1530 * @param epnum endpoint number
1531 * @retval None
1533 __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
1535 /* Prevent unused argument(s) compilation warning */
1536 UNUSED(hpcd);
1537 UNUSED(epnum);
1539 /* NOTE : This function should not be modified, when the callback is needed,
1540 the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file
1545 * @brief Incomplete ISO IN callback.
1546 * @param hpcd PCD handle
1547 * @param epnum endpoint number
1548 * @retval None
1550 __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
1552 /* Prevent unused argument(s) compilation warning */
1553 UNUSED(hpcd);
1554 UNUSED(epnum);
1556 /* NOTE : This function should not be modified, when the callback is needed,
1557 the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file
1562 * @brief Connection event callback.
1563 * @param hpcd PCD handle
1564 * @retval None
1566 __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
1568 /* Prevent unused argument(s) compilation warning */
1569 UNUSED(hpcd);
1571 /* NOTE : This function should not be modified, when the callback is needed,
1572 the HAL_PCD_ConnectCallback could be implemented in the user file
1577 * @brief Disconnection event callback.
1578 * @param hpcd PCD handle
1579 * @retval None
1581 __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
1583 /* Prevent unused argument(s) compilation warning */
1584 UNUSED(hpcd);
1586 /* NOTE : This function should not be modified, when the callback is needed,
1587 the HAL_PCD_DisconnectCallback could be implemented in the user file
1592 * @}
1595 /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
1596 * @brief management functions
1598 @verbatim
1599 ===============================================================================
1600 ##### Peripheral Control functions #####
1601 ===============================================================================
1602 [..]
1603 This subsection provides a set of functions allowing to control the PCD data
1604 transfers.
1606 @endverbatim
1607 * @{
1611 * @brief Connect the USB device
1612 * @param hpcd PCD handle
1613 * @retval HAL status
1615 HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd)
1617 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
1618 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1619 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
1621 __HAL_LOCK(hpcd);
1622 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
1623 if ((hpcd->Init.battery_charging_enable == 1U) &&
1624 (hpcd->Init.phy_itface != USB_OTG_ULPI_PHY))
1626 /* Enable USB Transceiver */
1627 USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
1629 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
1630 (void)USB_DevConnect(hpcd->Instance);
1631 __HAL_UNLOCK(hpcd);
1632 return HAL_OK;
1636 * @brief Disconnect the USB device.
1637 * @param hpcd PCD handle
1638 * @retval HAL status
1640 HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd)
1642 __HAL_LOCK(hpcd);
1643 (void)USB_DevDisconnect(hpcd->Instance);
1644 __HAL_UNLOCK(hpcd);
1645 return HAL_OK;
1649 * @brief Set the USB Device address.
1650 * @param hpcd PCD handle
1651 * @param address new device address
1652 * @retval HAL status
1654 HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)
1656 __HAL_LOCK(hpcd);
1657 hpcd->USB_Address = address;
1658 (void)USB_SetDevAddress(hpcd->Instance, address);
1659 __HAL_UNLOCK(hpcd);
1660 return HAL_OK;
1663 * @brief Open and configure an endpoint.
1664 * @param hpcd PCD handle
1665 * @param ep_addr endpoint address
1666 * @param ep_mps endpoint max packet size
1667 * @param ep_type endpoint type
1668 * @retval HAL status
1670 HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type)
1672 HAL_StatusTypeDef ret = HAL_OK;
1673 PCD_EPTypeDef *ep;
1675 if ((ep_addr & 0x80U) == 0x80U)
1677 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
1678 ep->is_in = 1U;
1680 else
1682 ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
1683 ep->is_in = 0U;
1686 ep->num = ep_addr & EP_ADDR_MSK;
1687 ep->maxpacket = ep_mps;
1688 ep->type = ep_type;
1690 if (ep->is_in != 0U)
1692 /* Assign a Tx FIFO */
1693 ep->tx_fifo_num = ep->num;
1695 /* Set initial data PID. */
1696 if (ep_type == EP_TYPE_BULK)
1698 ep->data_pid_start = 0U;
1701 __HAL_LOCK(hpcd);
1702 (void)USB_ActivateEndpoint(hpcd->Instance, ep);
1703 __HAL_UNLOCK(hpcd);
1705 return ret;
1709 * @brief Deactivate an endpoint.
1710 * @param hpcd PCD handle
1711 * @param ep_addr endpoint address
1712 * @retval HAL status
1714 HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1716 PCD_EPTypeDef *ep;
1718 if ((ep_addr & 0x80U) == 0x80U)
1720 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
1721 ep->is_in = 1U;
1723 else
1725 ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
1726 ep->is_in = 0U;
1728 ep->num = ep_addr & EP_ADDR_MSK;
1730 __HAL_LOCK(hpcd);
1731 (void)USB_DeactivateEndpoint(hpcd->Instance, ep);
1732 __HAL_UNLOCK(hpcd);
1733 return HAL_OK;
1738 * @brief Receive an amount of data.
1739 * @param hpcd PCD handle
1740 * @param ep_addr endpoint address
1741 * @param pBuf pointer to the reception buffer
1742 * @param len amount of data to be received
1743 * @retval HAL status
1745 HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
1747 PCD_EPTypeDef *ep;
1749 ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
1751 /*setup and start the Xfer */
1752 ep->xfer_buff = pBuf;
1753 ep->xfer_len = len;
1754 ep->xfer_count = 0U;
1755 ep->is_in = 0U;
1756 ep->num = ep_addr & EP_ADDR_MSK;
1758 if (hpcd->Init.dma_enable == 1U)
1760 ep->dma_addr = (uint32_t)pBuf;
1763 if ((ep_addr & EP_ADDR_MSK) == 0U)
1765 (void)USB_EP0StartXfer(hpcd->Instance, ep, (uint8_t)hpcd->Init.dma_enable);
1767 else
1769 (void)USB_EPStartXfer(hpcd->Instance, ep, (uint8_t)hpcd->Init.dma_enable);
1772 return HAL_OK;
1776 * @brief Get Received Data Size
1777 * @param hpcd PCD handle
1778 * @param ep_addr endpoint address
1779 * @retval Data Size
1781 uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1783 return hpcd->OUT_ep[ep_addr & EP_ADDR_MSK].xfer_count;
1786 * @brief Send an amount of data
1787 * @param hpcd PCD handle
1788 * @param ep_addr endpoint address
1789 * @param pBuf pointer to the transmission buffer
1790 * @param len amount of data to be sent
1791 * @retval HAL status
1793 HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
1795 PCD_EPTypeDef *ep;
1797 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
1799 /*setup and start the Xfer */
1800 ep->xfer_buff = pBuf;
1801 ep->xfer_len = len;
1802 ep->xfer_count = 0U;
1803 ep->is_in = 1U;
1804 ep->num = ep_addr & EP_ADDR_MSK;
1806 if (hpcd->Init.dma_enable == 1U)
1808 ep->dma_addr = (uint32_t)pBuf;
1811 if ((ep_addr & EP_ADDR_MSK) == 0U)
1813 (void)USB_EP0StartXfer(hpcd->Instance, ep, (uint8_t)hpcd->Init.dma_enable);
1815 else
1817 (void)USB_EPStartXfer(hpcd->Instance, ep, (uint8_t)hpcd->Init.dma_enable);
1820 return HAL_OK;
1824 * @brief Set a STALL condition over an endpoint
1825 * @param hpcd PCD handle
1826 * @param ep_addr endpoint address
1827 * @retval HAL status
1829 HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1831 PCD_EPTypeDef *ep;
1833 if (((uint32_t)ep_addr & EP_ADDR_MSK) > hpcd->Init.dev_endpoints)
1835 return HAL_ERROR;
1838 if ((0x80U & ep_addr) == 0x80U)
1840 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
1841 ep->is_in = 1U;
1843 else
1845 ep = &hpcd->OUT_ep[ep_addr];
1846 ep->is_in = 0U;
1849 ep->is_stall = 1U;
1850 ep->num = ep_addr & EP_ADDR_MSK;
1852 __HAL_LOCK(hpcd);
1854 (void)USB_EPSetStall(hpcd->Instance, ep);
1855 if ((ep_addr & EP_ADDR_MSK) == 0U)
1857 (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t)hpcd->Init.dma_enable, (uint8_t *)hpcd->Setup);
1859 __HAL_UNLOCK(hpcd);
1861 return HAL_OK;
1865 * @brief Clear a STALL condition over in an endpoint
1866 * @param hpcd PCD handle
1867 * @param ep_addr endpoint address
1868 * @retval HAL status
1870 HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1872 PCD_EPTypeDef *ep;
1874 if (((uint32_t)ep_addr & 0x0FU) > hpcd->Init.dev_endpoints)
1876 return HAL_ERROR;
1879 if ((0x80U & ep_addr) == 0x80U)
1881 ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
1882 ep->is_in = 1U;
1884 else
1886 ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
1887 ep->is_in = 0U;
1890 ep->is_stall = 0U;
1891 ep->num = ep_addr & EP_ADDR_MSK;
1893 __HAL_LOCK(hpcd);
1894 (void)USB_EPClearStall(hpcd->Instance, ep);
1895 __HAL_UNLOCK(hpcd);
1897 return HAL_OK;
1901 * @brief Flush an endpoint
1902 * @param hpcd PCD handle
1903 * @param ep_addr endpoint address
1904 * @retval HAL status
1906 HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1908 __HAL_LOCK(hpcd);
1910 if ((ep_addr & 0x80U) == 0x80U)
1912 (void)USB_FlushTxFifo(hpcd->Instance, (uint32_t)ep_addr & EP_ADDR_MSK);
1914 else
1916 (void)USB_FlushRxFifo(hpcd->Instance);
1919 __HAL_UNLOCK(hpcd);
1921 return HAL_OK;
1925 * @brief Activate remote wakeup signalling
1926 * @param hpcd PCD handle
1927 * @retval HAL status
1929 HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
1931 return (USB_ActivateRemoteWakeup(hpcd->Instance));
1935 * @brief De-activate remote wakeup signalling.
1936 * @param hpcd PCD handle
1937 * @retval HAL status
1939 HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
1941 return (USB_DeActivateRemoteWakeup(hpcd->Instance));
1945 * @}
1948 /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions
1949 * @brief Peripheral State functions
1951 @verbatim
1952 ===============================================================================
1953 ##### Peripheral State functions #####
1954 ===============================================================================
1955 [..]
1956 This subsection permits to get in run-time the status of the peripheral
1957 and the data flow.
1959 @endverbatim
1960 * @{
1964 * @brief Return the PCD handle state.
1965 * @param hpcd PCD handle
1966 * @retval HAL state
1968 PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd)
1970 return hpcd->State;
1974 * @}
1978 * @}
1981 /* Private functions ---------------------------------------------------------*/
1982 /** @addtogroup PCD_Private_Functions
1983 * @{
1985 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
1987 * @brief Check FIFO for the next packet to be loaded.
1988 * @param hpcd PCD handle
1989 * @param epnum endpoint number
1990 * @retval HAL status
1992 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum)
1994 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1995 uint32_t USBx_BASE = (uint32_t)USBx;
1996 USB_OTG_EPTypeDef *ep;
1997 uint32_t len;
1998 uint32_t len32b;
1999 uint32_t fifoemptymsk;
2001 ep = &hpcd->IN_ep[epnum];
2003 if (ep->xfer_count > ep->xfer_len)
2005 return HAL_ERROR;
2008 len = ep->xfer_len - ep->xfer_count;
2010 if (len > ep->maxpacket)
2012 len = ep->maxpacket;
2015 len32b = (len + 3U) / 4U;
2017 while (((USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= len32b) &&
2018 (ep->xfer_count < ep->xfer_len) && (ep->xfer_len != 0U))
2020 /* Write the FIFO */
2021 len = ep->xfer_len - ep->xfer_count;
2023 if (len > ep->maxpacket)
2025 len = ep->maxpacket;
2027 len32b = (len + 3U) / 4U;
2029 (void)USB_WritePacket(USBx, ep->xfer_buff, (uint8_t)epnum, (uint16_t)len,
2030 (uint8_t)hpcd->Init.dma_enable);
2032 ep->xfer_buff += len;
2033 ep->xfer_count += len;
2036 if (ep->xfer_len <= ep->xfer_count)
2038 fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK));
2039 USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
2042 return HAL_OK;
2047 * @brief process EP OUT transfer complete interrupt.
2048 * @param hpcd PCD handle
2049 * @param epnum endpoint number
2050 * @retval HAL status
2052 static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef *hpcd, uint32_t epnum)
2054 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
2055 uint32_t USBx_BASE = (uint32_t)USBx;
2056 uint32_t gSNPSiD = *(__IO uint32_t *)(&USBx->CID + 0x1U);
2057 uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT;
2059 if (hpcd->Init.dma_enable == 1U)
2061 if ((DoepintReg & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP) /* Class C */
2063 /* StupPktRcvd = 1 this is a setup packet */
2064 if ((gSNPSiD > USB_OTG_CORE_ID_300A) &&
2065 ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX))
2067 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
2070 else if ((DoepintReg & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR) /* Class E */
2072 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
2074 else if ((DoepintReg & (USB_OTG_DOEPINT_STUP | USB_OTG_DOEPINT_OTEPSPR)) == 0U)
2076 /* StupPktRcvd = 1 this is a setup packet */
2077 if ((gSNPSiD > USB_OTG_CORE_ID_300A) &&
2078 ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX))
2080 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
2082 else
2084 /* out data packet received over EP0 */
2085 hpcd->OUT_ep[epnum].xfer_count =
2086 hpcd->OUT_ep[epnum].maxpacket -
2087 (USBx_OUTEP(epnum)->DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ);
2089 hpcd->OUT_ep[epnum].xfer_buff += hpcd->OUT_ep[epnum].maxpacket;
2091 if ((epnum == 0U) && (hpcd->OUT_ep[epnum].xfer_len == 0U))
2093 /* this is ZLP, so prepare EP0 for next setup */
2094 (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup);
2096 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2097 hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
2098 #else
2099 HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
2100 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2103 else
2105 /* ... */
2108 else
2110 if (gSNPSiD == USB_OTG_CORE_ID_310A)
2112 /* StupPktRcvd = 1 this is a setup packet */
2113 if ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX)
2115 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
2117 else
2119 if ((DoepintReg & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR)
2121 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
2124 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2125 hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
2126 #else
2127 HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
2128 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2131 else
2133 if ((epnum == 0U) && (hpcd->OUT_ep[epnum].xfer_len == 0U))
2135 /* this is ZLP, so prepare EP0 for next setup */
2136 (void)USB_EP0_OutStart(hpcd->Instance, 0U, (uint8_t *)hpcd->Setup);
2139 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2140 hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
2141 #else
2142 HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
2143 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2147 return HAL_OK;
2152 * @brief process EP OUT setup packet received interrupt.
2153 * @param hpcd PCD handle
2154 * @param epnum endpoint number
2155 * @retval HAL status
2157 static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef *hpcd, uint32_t epnum)
2159 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
2160 uint32_t USBx_BASE = (uint32_t)USBx;
2161 uint32_t gSNPSiD = *(__IO uint32_t *)(&USBx->CID + 0x1U);
2162 uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT;
2164 if ((gSNPSiD > USB_OTG_CORE_ID_300A) &&
2165 ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX))
2167 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
2170 /* Inform the upper layer that a setup packet is available */
2171 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2172 hpcd->SetupStageCallback(hpcd);
2173 #else
2174 HAL_PCD_SetupStageCallback(hpcd);
2175 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2177 if ((gSNPSiD > USB_OTG_CORE_ID_300A) && (hpcd->Init.dma_enable == 1U))
2179 (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup);
2182 return HAL_OK;
2184 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2188 * @}
2190 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2191 #endif /* HAL_PCD_MODULE_ENABLED */
2194 * @}
2198 * @}
2201 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/