Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:08

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_hal_pcd.c
0004   * @author  MCD Application Team
0005   * @brief   PCD HAL module driver.
0006   *          This file provides firmware functions to manage the following
0007   *          functionalities of the USB Peripheral Controller:
0008   *           + Initialization and de-initialization functions
0009   *           + IO operation functions
0010   *           + Peripheral Control functions
0011   *           + Peripheral State functions
0012   *
0013   ******************************************************************************
0014   * @attention
0015   *
0016   * Copyright (c) 2017 STMicroelectronics.
0017   * All rights reserved.
0018   *
0019   * This software is licensed under terms that can be found in the LICENSE file
0020   * in the root directory of this software component.
0021   * If no LICENSE file comes with this software, it is provided AS-IS.
0022   *
0023   ******************************************************************************
0024   @verbatim
0025   ==============================================================================
0026                     ##### How to use this driver #####
0027   ==============================================================================
0028     [..]
0029       The PCD HAL driver can be used as follows:
0030 
0031      (#) Declare a PCD_HandleTypeDef handle structure, for example:
0032          PCD_HandleTypeDef  hpcd;
0033 
0034      (#) Fill parameters of Init structure in HCD handle
0035 
0036      (#) Call HAL_PCD_Init() API to initialize the PCD peripheral (Core, Device core, ...)
0037 
0038      (#) Initialize the PCD low level resources through the HAL_PCD_MspInit() API:
0039          (##) Enable the PCD/USB Low Level interface clock using
0040               (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
0041               (+++) __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); (For High Speed Mode)
0042 
0043          (##) Initialize the related GPIO clocks
0044          (##) Configure PCD pin-out
0045          (##) Configure PCD NVIC interrupt
0046 
0047      (#)Associate the Upper USB device stack to the HAL PCD Driver:
0048          (##) hpcd.pData = pdev;
0049 
0050      (#)Enable PCD transmission and reception:
0051          (##) HAL_PCD_Start();
0052 
0053   @endverbatim
0054   ******************************************************************************
0055   */
0056 
0057 /* Includes ------------------------------------------------------------------*/
0058 #include "stm32h7xx_hal.h"
0059 
0060 /** @addtogroup STM32H7xx_HAL_Driver
0061   * @{
0062   */
0063 
0064 /** @defgroup PCD PCD
0065   * @ingroup RTEMSBSPsARMSTM32H7
0066   * @brief PCD HAL module driver
0067   * @{
0068   */
0069 
0070 #ifdef HAL_PCD_MODULE_ENABLED
0071 
0072 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
0073 
0074 /* Private types -------------------------------------------------------------*/
0075 /* Private variables ---------------------------------------------------------*/
0076 /* Private constants ---------------------------------------------------------*/
0077 /* Private macros ------------------------------------------------------------*/
0078 /** @defgroup PCD_Private_Macros PCD Private Macros
0079   * @ingroup RTEMSBSPsARMSTM32H7
0080   * @{
0081   */
0082 #define PCD_MIN(a, b)  (((a) < (b)) ? (a) : (b))
0083 #define PCD_MAX(a, b)  (((a) > (b)) ? (a) : (b))
0084 /**
0085   * @}
0086   */
0087 
0088 /* Private functions prototypes ----------------------------------------------*/
0089 /** @defgroup PCD_Private_Functions PCD Private Functions
0090   * @ingroup RTEMSBSPsARMSTM32H7
0091   * @{
0092   */
0093 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
0094 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum);
0095 static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef *hpcd, uint32_t epnum);
0096 static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef *hpcd, uint32_t epnum);
0097 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
0098 /**
0099   * @}
0100   */
0101 
0102 /* Exported functions --------------------------------------------------------*/
0103 /** @defgroup PCD_Exported_Functions PCD Exported Functions
0104   * @ingroup RTEMSBSPsARMSTM32H7
0105   * @{
0106   */
0107 
0108 /** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
0109   * @ingroup RTEMSBSPsARMSTM32H7
0110   *  @brief    Initialization and Configuration functions
0111   *
0112 @verbatim
0113  ===============================================================================
0114             ##### Initialization and de-initialization functions #####
0115  ===============================================================================
0116     [..]  This section provides functions allowing to:
0117 
0118 @endverbatim
0119   * @{
0120   */
0121 
0122 /**
0123   * @brief  Initializes the PCD according to the specified
0124   *         parameters in the PCD_InitTypeDef and initialize the associated handle.
0125   * @param  hpcd PCD handle
0126   * @retval HAL status
0127   */
0128 HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd)
0129 {
0130   uint8_t i;
0131 
0132   /* Check the PCD handle allocation */
0133   if (hpcd == NULL)
0134   {
0135     return HAL_ERROR;
0136   }
0137 
0138   /* Check the parameters */
0139   assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance));
0140 
0141   if (hpcd->State == HAL_PCD_STATE_RESET)
0142   {
0143     /* Allocate lock resource and initialize it */
0144     hpcd->Lock = HAL_UNLOCKED;
0145 
0146 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
0147     hpcd->SOFCallback = HAL_PCD_SOFCallback;
0148     hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
0149     hpcd->ResetCallback = HAL_PCD_ResetCallback;
0150     hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
0151     hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
0152     hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
0153     hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
0154     hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback;
0155     hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback;
0156     hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback;
0157     hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback;
0158     hpcd->LPMCallback = HAL_PCDEx_LPM_Callback;
0159     hpcd->BCDCallback = HAL_PCDEx_BCD_Callback;
0160 
0161     if (hpcd->MspInitCallback == NULL)
0162     {
0163       hpcd->MspInitCallback = HAL_PCD_MspInit;
0164     }
0165 
0166     /* Init the low level hardware */
0167     hpcd->MspInitCallback(hpcd);
0168 #else
0169     /* Init the low level hardware : GPIO, CLOCK, NVIC... */
0170     HAL_PCD_MspInit(hpcd);
0171 #endif /* (USE_HAL_PCD_REGISTER_CALLBACKS) */
0172   }
0173 
0174   hpcd->State = HAL_PCD_STATE_BUSY;
0175 
0176   /* Disable the Interrupts */
0177   __HAL_PCD_DISABLE(hpcd);
0178 
0179   /*Init the Core (common init.) */
0180   if (USB_CoreInit(hpcd->Instance, hpcd->Init) != HAL_OK)
0181   {
0182     hpcd->State = HAL_PCD_STATE_ERROR;
0183     return HAL_ERROR;
0184   }
0185 
0186   /* Force Device Mode */
0187   if (USB_SetCurrentMode(hpcd->Instance, USB_DEVICE_MODE) != HAL_OK)
0188   {
0189     hpcd->State = HAL_PCD_STATE_ERROR;
0190     return HAL_ERROR;
0191   }
0192 
0193   /* Init endpoints structures */
0194   for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
0195   {
0196     /* Init ep structure */
0197     hpcd->IN_ep[i].is_in = 1U;
0198     hpcd->IN_ep[i].num = i;
0199     hpcd->IN_ep[i].tx_fifo_num = i;
0200     /* Control until ep is activated */
0201     hpcd->IN_ep[i].type = EP_TYPE_CTRL;
0202     hpcd->IN_ep[i].maxpacket = 0U;
0203     hpcd->IN_ep[i].xfer_buff = 0U;
0204     hpcd->IN_ep[i].xfer_len = 0U;
0205   }
0206 
0207   for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
0208   {
0209     hpcd->OUT_ep[i].is_in = 0U;
0210     hpcd->OUT_ep[i].num = i;
0211     /* Control until ep is activated */
0212     hpcd->OUT_ep[i].type = EP_TYPE_CTRL;
0213     hpcd->OUT_ep[i].maxpacket = 0U;
0214     hpcd->OUT_ep[i].xfer_buff = 0U;
0215     hpcd->OUT_ep[i].xfer_len = 0U;
0216   }
0217 
0218   /* Init Device */
0219   if (USB_DevInit(hpcd->Instance, hpcd->Init) != HAL_OK)
0220   {
0221     hpcd->State = HAL_PCD_STATE_ERROR;
0222     return HAL_ERROR;
0223   }
0224 
0225   hpcd->USB_Address = 0U;
0226   hpcd->State = HAL_PCD_STATE_READY;
0227 
0228   /* Activate LPM */
0229   if (hpcd->Init.lpm_enable == 1U)
0230   {
0231     (void)HAL_PCDEx_ActivateLPM(hpcd);
0232   }
0233 
0234   (void)USB_DevDisconnect(hpcd->Instance);
0235 
0236   return HAL_OK;
0237 }
0238 
0239 /**
0240   * @brief  DeInitializes the PCD peripheral.
0241   * @param  hpcd PCD handle
0242   * @retval HAL status
0243   */
0244 HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
0245 {
0246   /* Check the PCD handle allocation */
0247   if (hpcd == NULL)
0248   {
0249     return HAL_ERROR;
0250   }
0251 
0252   hpcd->State = HAL_PCD_STATE_BUSY;
0253 
0254   /* Stop Device */
0255   if (USB_StopDevice(hpcd->Instance) != HAL_OK)
0256   {
0257     return HAL_ERROR;
0258   }
0259 
0260 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
0261   if (hpcd->MspDeInitCallback == NULL)
0262   {
0263     hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; /* Legacy weak MspDeInit  */
0264   }
0265 
0266   /* DeInit the low level hardware */
0267   hpcd->MspDeInitCallback(hpcd);
0268 #else
0269   /* DeInit the low level hardware: CLOCK, NVIC.*/
0270   HAL_PCD_MspDeInit(hpcd);
0271 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
0272 
0273   hpcd->State = HAL_PCD_STATE_RESET;
0274 
0275   return HAL_OK;
0276 }
0277 
0278 /**
0279   * @brief  Initializes the PCD MSP.
0280   * @param  hpcd PCD handle
0281   * @retval None
0282   */
0283 __weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
0284 {
0285   /* Prevent unused argument(s) compilation warning */
0286   UNUSED(hpcd);
0287 
0288   /* NOTE : This function should not be modified, when the callback is needed,
0289             the HAL_PCD_MspInit could be implemented in the user file
0290    */
0291 }
0292 
0293 /**
0294   * @brief  DeInitializes PCD MSP.
0295   * @param  hpcd PCD handle
0296   * @retval None
0297   */
0298 __weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
0299 {
0300   /* Prevent unused argument(s) compilation warning */
0301   UNUSED(hpcd);
0302 
0303   /* NOTE : This function should not be modified, when the callback is needed,
0304             the HAL_PCD_MspDeInit could be implemented in the user file
0305    */
0306 }
0307 
0308 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
0309 /**
0310   * @brief  Register a User USB PCD Callback
0311   *         To be used instead of the weak predefined callback
0312   * @param  hpcd USB PCD handle
0313   * @param  CallbackID ID of the callback to be registered
0314   *         This parameter can be one of the following values:
0315   *          @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
0316   *          @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
0317   *          @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
0318   *          @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
0319   *          @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
0320   *          @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
0321   *          @arg @ref HAL_PCD_DISCONNECT_CB_ID USB PCD Disconnect callback ID
0322   *          @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
0323   *          @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
0324   * @param  pCallback pointer to the Callback function
0325   * @retval HAL status
0326   */
0327 HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd,
0328                                            HAL_PCD_CallbackIDTypeDef CallbackID,
0329                                            pPCD_CallbackTypeDef pCallback)
0330 {
0331   HAL_StatusTypeDef status = HAL_OK;
0332 
0333   if (pCallback == NULL)
0334   {
0335     /* Update the error code */
0336     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
0337     return HAL_ERROR;
0338   }
0339   /* Process locked */
0340   __HAL_LOCK(hpcd);
0341 
0342   if (hpcd->State == HAL_PCD_STATE_READY)
0343   {
0344     switch (CallbackID)
0345     {
0346       case HAL_PCD_SOF_CB_ID :
0347         hpcd->SOFCallback = pCallback;
0348         break;
0349 
0350       case HAL_PCD_SETUPSTAGE_CB_ID :
0351         hpcd->SetupStageCallback = pCallback;
0352         break;
0353 
0354       case HAL_PCD_RESET_CB_ID :
0355         hpcd->ResetCallback = pCallback;
0356         break;
0357 
0358       case HAL_PCD_SUSPEND_CB_ID :
0359         hpcd->SuspendCallback = pCallback;
0360         break;
0361 
0362       case HAL_PCD_RESUME_CB_ID :
0363         hpcd->ResumeCallback = pCallback;
0364         break;
0365 
0366       case HAL_PCD_CONNECT_CB_ID :
0367         hpcd->ConnectCallback = pCallback;
0368         break;
0369 
0370       case HAL_PCD_DISCONNECT_CB_ID :
0371         hpcd->DisconnectCallback = pCallback;
0372         break;
0373 
0374       case HAL_PCD_MSPINIT_CB_ID :
0375         hpcd->MspInitCallback = pCallback;
0376         break;
0377 
0378       case HAL_PCD_MSPDEINIT_CB_ID :
0379         hpcd->MspDeInitCallback = pCallback;
0380         break;
0381 
0382       default :
0383         /* Update the error code */
0384         hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
0385         /* Return error status */
0386         status =  HAL_ERROR;
0387         break;
0388     }
0389   }
0390   else if (hpcd->State == HAL_PCD_STATE_RESET)
0391   {
0392     switch (CallbackID)
0393     {
0394       case HAL_PCD_MSPINIT_CB_ID :
0395         hpcd->MspInitCallback = pCallback;
0396         break;
0397 
0398       case HAL_PCD_MSPDEINIT_CB_ID :
0399         hpcd->MspDeInitCallback = pCallback;
0400         break;
0401 
0402       default :
0403         /* Update the error code */
0404         hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
0405         /* Return error status */
0406         status =  HAL_ERROR;
0407         break;
0408     }
0409   }
0410   else
0411   {
0412     /* Update the error code */
0413     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
0414     /* Return error status */
0415     status =  HAL_ERROR;
0416   }
0417 
0418   /* Release Lock */
0419   __HAL_UNLOCK(hpcd);
0420   return status;
0421 }
0422 
0423 /**
0424   * @brief  Unregister an USB PCD Callback
0425   *         USB PCD callback is redirected to the weak predefined callback
0426   * @param  hpcd USB PCD handle
0427   * @param  CallbackID ID of the callback to be unregistered
0428   *         This parameter can be one of the following values:
0429   *          @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
0430   *          @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
0431   *          @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
0432   *          @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
0433   *          @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
0434   *          @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
0435   *          @arg @ref HAL_PCD_DISCONNECT_CB_ID USB PCD Disconnect callback ID
0436   *          @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
0437   *          @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
0438   * @retval HAL status
0439   */
0440 HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID)
0441 {
0442   HAL_StatusTypeDef status = HAL_OK;
0443 
0444   /* Process locked */
0445   __HAL_LOCK(hpcd);
0446 
0447   /* Setup Legacy weak Callbacks  */
0448   if (hpcd->State == HAL_PCD_STATE_READY)
0449   {
0450     switch (CallbackID)
0451     {
0452       case HAL_PCD_SOF_CB_ID :
0453         hpcd->SOFCallback = HAL_PCD_SOFCallback;
0454         break;
0455 
0456       case HAL_PCD_SETUPSTAGE_CB_ID :
0457         hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
0458         break;
0459 
0460       case HAL_PCD_RESET_CB_ID :
0461         hpcd->ResetCallback = HAL_PCD_ResetCallback;
0462         break;
0463 
0464       case HAL_PCD_SUSPEND_CB_ID :
0465         hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
0466         break;
0467 
0468       case HAL_PCD_RESUME_CB_ID :
0469         hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
0470         break;
0471 
0472       case HAL_PCD_CONNECT_CB_ID :
0473         hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
0474         break;
0475 
0476       case HAL_PCD_DISCONNECT_CB_ID :
0477         hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
0478         break;
0479 
0480       case HAL_PCD_MSPINIT_CB_ID :
0481         hpcd->MspInitCallback = HAL_PCD_MspInit;
0482         break;
0483 
0484       case HAL_PCD_MSPDEINIT_CB_ID :
0485         hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
0486         break;
0487 
0488       default :
0489         /* Update the error code */
0490         hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
0491 
0492         /* Return error status */
0493         status =  HAL_ERROR;
0494         break;
0495     }
0496   }
0497   else if (hpcd->State == HAL_PCD_STATE_RESET)
0498   {
0499     switch (CallbackID)
0500     {
0501       case HAL_PCD_MSPINIT_CB_ID :
0502         hpcd->MspInitCallback = HAL_PCD_MspInit;
0503         break;
0504 
0505       case HAL_PCD_MSPDEINIT_CB_ID :
0506         hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
0507         break;
0508 
0509       default :
0510         /* Update the error code */
0511         hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
0512 
0513         /* Return error status */
0514         status =  HAL_ERROR;
0515         break;
0516     }
0517   }
0518   else
0519   {
0520     /* Update the error code */
0521     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
0522 
0523     /* Return error status */
0524     status =  HAL_ERROR;
0525   }
0526 
0527   /* Release Lock */
0528   __HAL_UNLOCK(hpcd);
0529   return status;
0530 }
0531 
0532 /**
0533   * @brief  Register USB PCD Data OUT Stage Callback
0534   *         To be used instead of the weak HAL_PCD_DataOutStageCallback() predefined callback
0535   * @param  hpcd PCD handle
0536   * @param  pCallback pointer to the USB PCD Data OUT Stage Callback function
0537   * @retval HAL status
0538   */
0539 HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd,
0540                                                        pPCD_DataOutStageCallbackTypeDef pCallback)
0541 {
0542   HAL_StatusTypeDef status = HAL_OK;
0543 
0544   if (pCallback == NULL)
0545   {
0546     /* Update the error code */
0547     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
0548 
0549     return HAL_ERROR;
0550   }
0551 
0552   /* Process locked */
0553   __HAL_LOCK(hpcd);
0554 
0555   if (hpcd->State == HAL_PCD_STATE_READY)
0556   {
0557     hpcd->DataOutStageCallback = pCallback;
0558   }
0559   else
0560   {
0561     /* Update the error code */
0562     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
0563 
0564     /* Return error status */
0565     status =  HAL_ERROR;
0566   }
0567 
0568   /* Release Lock */
0569   __HAL_UNLOCK(hpcd);
0570 
0571   return status;
0572 }
0573 
0574 /**
0575   * @brief  Unregister the USB PCD Data OUT Stage Callback
0576   *         USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataOutStageCallback() predefined callback
0577   * @param  hpcd PCD handle
0578   * @retval HAL status
0579   */
0580 HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd)
0581 {
0582   HAL_StatusTypeDef status = HAL_OK;
0583 
0584   /* Process locked */
0585   __HAL_LOCK(hpcd);
0586 
0587   if (hpcd->State == HAL_PCD_STATE_READY)
0588   {
0589     hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback; /* Legacy weak DataOutStageCallback  */
0590   }
0591   else
0592   {
0593     /* Update the error code */
0594     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
0595 
0596     /* Return error status */
0597     status =  HAL_ERROR;
0598   }
0599 
0600   /* Release Lock */
0601   __HAL_UNLOCK(hpcd);
0602 
0603   return status;
0604 }
0605 
0606 /**
0607   * @brief  Register USB PCD Data IN Stage Callback
0608   *         To be used instead of the weak HAL_PCD_DataInStageCallback() predefined callback
0609   * @param  hpcd PCD handle
0610   * @param  pCallback pointer to the USB PCD Data IN Stage Callback function
0611   * @retval HAL status
0612   */
0613 HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd,
0614                                                       pPCD_DataInStageCallbackTypeDef pCallback)
0615 {
0616   HAL_StatusTypeDef status = HAL_OK;
0617 
0618   if (pCallback == NULL)
0619   {
0620     /* Update the error code */
0621     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
0622 
0623     return HAL_ERROR;
0624   }
0625 
0626   /* Process locked */
0627   __HAL_LOCK(hpcd);
0628 
0629   if (hpcd->State == HAL_PCD_STATE_READY)
0630   {
0631     hpcd->DataInStageCallback = pCallback;
0632   }
0633   else
0634   {
0635     /* Update the error code */
0636     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
0637 
0638     /* Return error status */
0639     status =  HAL_ERROR;
0640   }
0641 
0642   /* Release Lock */
0643   __HAL_UNLOCK(hpcd);
0644 
0645   return status;
0646 }
0647 
0648 /**
0649   * @brief  Unregister the USB PCD Data IN Stage Callback
0650   *         USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataInStageCallback() predefined callback
0651   * @param  hpcd PCD handle
0652   * @retval HAL status
0653   */
0654 HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd)
0655 {
0656   HAL_StatusTypeDef status = HAL_OK;
0657 
0658   /* Process locked */
0659   __HAL_LOCK(hpcd);
0660 
0661   if (hpcd->State == HAL_PCD_STATE_READY)
0662   {
0663     hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback; /* Legacy weak DataInStageCallback  */
0664   }
0665   else
0666   {
0667     /* Update the error code */
0668     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
0669 
0670     /* Return error status */
0671     status =  HAL_ERROR;
0672   }
0673 
0674   /* Release Lock */
0675   __HAL_UNLOCK(hpcd);
0676 
0677   return status;
0678 }
0679 
0680 /**
0681   * @brief  Register USB PCD Iso OUT incomplete Callback
0682   *         To be used instead of the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
0683   * @param  hpcd PCD handle
0684   * @param  pCallback pointer to the USB PCD Iso OUT incomplete Callback function
0685   * @retval HAL status
0686   */
0687 HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd,
0688                                                        pPCD_IsoOutIncpltCallbackTypeDef pCallback)
0689 {
0690   HAL_StatusTypeDef status = HAL_OK;
0691 
0692   if (pCallback == NULL)
0693   {
0694     /* Update the error code */
0695     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
0696 
0697     return HAL_ERROR;
0698   }
0699 
0700   /* Process locked */
0701   __HAL_LOCK(hpcd);
0702 
0703   if (hpcd->State == HAL_PCD_STATE_READY)
0704   {
0705     hpcd->ISOOUTIncompleteCallback = pCallback;
0706   }
0707   else
0708   {
0709     /* Update the error code */
0710     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
0711 
0712     /* Return error status */
0713     status =  HAL_ERROR;
0714   }
0715 
0716   /* Release Lock */
0717   __HAL_UNLOCK(hpcd);
0718 
0719   return status;
0720 }
0721 
0722 /**
0723   * @brief  Unregister the USB PCD Iso OUT incomplete Callback
0724   *         USB PCD Iso OUT incomplete Callback is redirected
0725   *         to the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
0726   * @param  hpcd PCD handle
0727   * @retval HAL status
0728   */
0729 HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd)
0730 {
0731   HAL_StatusTypeDef status = HAL_OK;
0732 
0733   /* Process locked */
0734   __HAL_LOCK(hpcd);
0735 
0736   if (hpcd->State == HAL_PCD_STATE_READY)
0737   {
0738     hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback; /* Legacy weak ISOOUTIncompleteCallback  */
0739   }
0740   else
0741   {
0742     /* Update the error code */
0743     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
0744 
0745     /* Return error status */
0746     status =  HAL_ERROR;
0747   }
0748 
0749   /* Release Lock */
0750   __HAL_UNLOCK(hpcd);
0751 
0752   return status;
0753 }
0754 
0755 /**
0756   * @brief  Register USB PCD Iso IN incomplete Callback
0757   *         To be used instead of the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
0758   * @param  hpcd PCD handle
0759   * @param  pCallback pointer to the USB PCD Iso IN incomplete Callback function
0760   * @retval HAL status
0761   */
0762 HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd,
0763                                                       pPCD_IsoInIncpltCallbackTypeDef pCallback)
0764 {
0765   HAL_StatusTypeDef status = HAL_OK;
0766 
0767   if (pCallback == NULL)
0768   {
0769     /* Update the error code */
0770     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
0771 
0772     return HAL_ERROR;
0773   }
0774 
0775   /* Process locked */
0776   __HAL_LOCK(hpcd);
0777 
0778   if (hpcd->State == HAL_PCD_STATE_READY)
0779   {
0780     hpcd->ISOINIncompleteCallback = pCallback;
0781   }
0782   else
0783   {
0784     /* Update the error code */
0785     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
0786 
0787     /* Return error status */
0788     status =  HAL_ERROR;
0789   }
0790 
0791   /* Release Lock */
0792   __HAL_UNLOCK(hpcd);
0793 
0794   return status;
0795 }
0796 
0797 /**
0798   * @brief  Unregister the USB PCD Iso IN incomplete Callback
0799   *         USB PCD Iso IN incomplete Callback is redirected
0800   *         to the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
0801   * @param  hpcd PCD handle
0802   * @retval HAL status
0803   */
0804 HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd)
0805 {
0806   HAL_StatusTypeDef status = HAL_OK;
0807 
0808   /* Process locked */
0809   __HAL_LOCK(hpcd);
0810 
0811   if (hpcd->State == HAL_PCD_STATE_READY)
0812   {
0813     hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback; /* Legacy weak ISOINIncompleteCallback  */
0814   }
0815   else
0816   {
0817     /* Update the error code */
0818     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
0819 
0820     /* Return error status */
0821     status =  HAL_ERROR;
0822   }
0823 
0824   /* Release Lock */
0825   __HAL_UNLOCK(hpcd);
0826 
0827   return status;
0828 }
0829 
0830 /**
0831   * @brief  Register USB PCD BCD Callback
0832   *         To be used instead of the weak HAL_PCDEx_BCD_Callback() predefined callback
0833   * @param  hpcd PCD handle
0834   * @param  pCallback pointer to the USB PCD BCD Callback function
0835   * @retval HAL status
0836   */
0837 HAL_StatusTypeDef HAL_PCD_RegisterBcdCallback(PCD_HandleTypeDef *hpcd, pPCD_BcdCallbackTypeDef pCallback)
0838 {
0839   HAL_StatusTypeDef status = HAL_OK;
0840 
0841   if (pCallback == NULL)
0842   {
0843     /* Update the error code */
0844     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
0845 
0846     return HAL_ERROR;
0847   }
0848 
0849   /* Process locked */
0850   __HAL_LOCK(hpcd);
0851 
0852   if (hpcd->State == HAL_PCD_STATE_READY)
0853   {
0854     hpcd->BCDCallback = pCallback;
0855   }
0856   else
0857   {
0858     /* Update the error code */
0859     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
0860 
0861     /* Return error status */
0862     status =  HAL_ERROR;
0863   }
0864 
0865   /* Release Lock */
0866   __HAL_UNLOCK(hpcd);
0867 
0868   return status;
0869 }
0870 
0871 /**
0872   * @brief  Unregister the USB PCD BCD Callback
0873   *         USB BCD Callback is redirected to the weak HAL_PCDEx_BCD_Callback() predefined callback
0874   * @param  hpcd PCD handle
0875   * @retval HAL status
0876   */
0877 HAL_StatusTypeDef HAL_PCD_UnRegisterBcdCallback(PCD_HandleTypeDef *hpcd)
0878 {
0879   HAL_StatusTypeDef status = HAL_OK;
0880 
0881   /* Process locked */
0882   __HAL_LOCK(hpcd);
0883 
0884   if (hpcd->State == HAL_PCD_STATE_READY)
0885   {
0886     hpcd->BCDCallback = HAL_PCDEx_BCD_Callback; /* Legacy weak HAL_PCDEx_BCD_Callback  */
0887   }
0888   else
0889   {
0890     /* Update the error code */
0891     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
0892 
0893     /* Return error status */
0894     status =  HAL_ERROR;
0895   }
0896 
0897   /* Release Lock */
0898   __HAL_UNLOCK(hpcd);
0899 
0900   return status;
0901 }
0902 
0903 /**
0904   * @brief  Register USB PCD LPM Callback
0905   *         To be used instead of the weak HAL_PCDEx_LPM_Callback() predefined callback
0906   * @param  hpcd PCD handle
0907   * @param  pCallback pointer to the USB PCD LPM Callback function
0908   * @retval HAL status
0909   */
0910 HAL_StatusTypeDef HAL_PCD_RegisterLpmCallback(PCD_HandleTypeDef *hpcd, pPCD_LpmCallbackTypeDef pCallback)
0911 {
0912   HAL_StatusTypeDef status = HAL_OK;
0913 
0914   if (pCallback == NULL)
0915   {
0916     /* Update the error code */
0917     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
0918 
0919     return HAL_ERROR;
0920   }
0921 
0922   /* Process locked */
0923   __HAL_LOCK(hpcd);
0924 
0925   if (hpcd->State == HAL_PCD_STATE_READY)
0926   {
0927     hpcd->LPMCallback = pCallback;
0928   }
0929   else
0930   {
0931     /* Update the error code */
0932     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
0933 
0934     /* Return error status */
0935     status =  HAL_ERROR;
0936   }
0937 
0938   /* Release Lock */
0939   __HAL_UNLOCK(hpcd);
0940 
0941   return status;
0942 }
0943 
0944 /**
0945   * @brief  Unregister the USB PCD LPM Callback
0946   *         USB LPM Callback is redirected to the weak HAL_PCDEx_LPM_Callback() predefined callback
0947   * @param  hpcd PCD handle
0948   * @retval HAL status
0949   */
0950 HAL_StatusTypeDef HAL_PCD_UnRegisterLpmCallback(PCD_HandleTypeDef *hpcd)
0951 {
0952   HAL_StatusTypeDef status = HAL_OK;
0953 
0954   /* Process locked */
0955   __HAL_LOCK(hpcd);
0956 
0957   if (hpcd->State == HAL_PCD_STATE_READY)
0958   {
0959     hpcd->LPMCallback = HAL_PCDEx_LPM_Callback; /* Legacy weak HAL_PCDEx_LPM_Callback  */
0960   }
0961   else
0962   {
0963     /* Update the error code */
0964     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
0965 
0966     /* Return error status */
0967     status =  HAL_ERROR;
0968   }
0969 
0970   /* Release Lock */
0971   __HAL_UNLOCK(hpcd);
0972 
0973   return status;
0974 }
0975 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
0976 
0977 /**
0978   * @}
0979   */
0980 
0981 /** @defgroup PCD_Exported_Functions_Group2 Input and Output operation functions
0982   * @ingroup RTEMSBSPsARMSTM32H7
0983   *  @brief   Data transfers functions
0984   *
0985 @verbatim
0986  ===============================================================================
0987                       ##### IO operation functions #####
0988  ===============================================================================
0989     [..]
0990     This subsection provides a set of functions allowing to manage the PCD data
0991     transfers.
0992 
0993 @endverbatim
0994   * @{
0995   */
0996 
0997 /**
0998   * @brief  Start the USB device
0999   * @param  hpcd PCD handle
1000   * @retval HAL status
1001   */
1002 HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)
1003 {
1004   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1005 
1006   __HAL_LOCK(hpcd);
1007 
1008   if (((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) != 0U) &&
1009       (hpcd->Init.battery_charging_enable == 1U))
1010   {
1011     /* Enable USB Transceiver */
1012     USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
1013   }
1014 
1015   __HAL_PCD_ENABLE(hpcd);
1016   (void)USB_DevConnect(hpcd->Instance);
1017   __HAL_UNLOCK(hpcd);
1018 
1019   return HAL_OK;
1020 }
1021 
1022 /**
1023   * @brief  Stop the USB device.
1024   * @param  hpcd PCD handle
1025   * @retval HAL status
1026   */
1027 HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
1028 {
1029   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1030 
1031   __HAL_LOCK(hpcd);
1032   __HAL_PCD_DISABLE(hpcd);
1033   (void)USB_DevDisconnect(hpcd->Instance);
1034 
1035   (void)USB_FlushTxFifo(hpcd->Instance, 0x10U);
1036 
1037   if (((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) != 0U) &&
1038       (hpcd->Init.battery_charging_enable == 1U))
1039   {
1040     /* Disable USB Transceiver */
1041     USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
1042   }
1043 
1044   __HAL_UNLOCK(hpcd);
1045 
1046   return HAL_OK;
1047 }
1048 
1049 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
1050 /**
1051   * @brief  Handles PCD interrupt request.
1052   * @param  hpcd PCD handle
1053   * @retval HAL status
1054   */
1055 void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
1056 {
1057   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1058   uint32_t USBx_BASE = (uint32_t)USBx;
1059   USB_OTG_EPTypeDef *ep;
1060   uint32_t i;
1061   uint32_t ep_intr;
1062   uint32_t epint;
1063   uint32_t epnum;
1064   uint32_t fifoemptymsk;
1065   uint32_t RegVal;
1066 
1067   /* ensure that we are in device mode */
1068   if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE)
1069   {
1070     /* avoid spurious interrupt */
1071     if (__HAL_PCD_IS_INVALID_INTERRUPT(hpcd))
1072     {
1073       return;
1074     }
1075 
1076     /* store current frame number */
1077     hpcd->FrameNumber = (USBx_DEVICE->DSTS & USB_OTG_DSTS_FNSOF_Msk) >> USB_OTG_DSTS_FNSOF_Pos;
1078 
1079     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS))
1080     {
1081       /* incorrect mode, acknowledge the interrupt */
1082       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS);
1083     }
1084 
1085     /* Handle RxQLevel Interrupt */
1086     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL))
1087     {
1088       USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
1089 
1090       RegVal = USBx->GRXSTSP;
1091 
1092       ep = &hpcd->OUT_ep[RegVal & USB_OTG_GRXSTSP_EPNUM];
1093 
1094       if (((RegVal & USB_OTG_GRXSTSP_PKTSTS) >> 17) ==  STS_DATA_UPDT)
1095       {
1096         if ((RegVal & USB_OTG_GRXSTSP_BCNT) != 0U)
1097         {
1098           (void)USB_ReadPacket(USBx, ep->xfer_buff,
1099                                (uint16_t)((RegVal & USB_OTG_GRXSTSP_BCNT) >> 4));
1100 
1101           ep->xfer_buff += (RegVal & USB_OTG_GRXSTSP_BCNT) >> 4;
1102           ep->xfer_count += (RegVal & USB_OTG_GRXSTSP_BCNT) >> 4;
1103         }
1104       }
1105       else if (((RegVal & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_SETUP_UPDT)
1106       {
1107         (void)USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8U);
1108         ep->xfer_count += (RegVal & USB_OTG_GRXSTSP_BCNT) >> 4;
1109       }
1110       else
1111       {
1112         /* ... */
1113       }
1114 
1115       USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
1116     }
1117 
1118     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT))
1119     {
1120       epnum = 0U;
1121 
1122       /* Read in the device interrupt bits */
1123       ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance);
1124 
1125       while (ep_intr != 0U)
1126       {
1127         if ((ep_intr & 0x1U) != 0U)
1128         {
1129           epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, (uint8_t)epnum);
1130 
1131           if ((epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC)
1132           {
1133             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC);
1134             (void)PCD_EP_OutXfrComplete_int(hpcd, epnum);
1135           }
1136 
1137           if ((epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP)
1138           {
1139             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP);
1140             /* Class B setup phase done for previous decoded setup */
1141             (void)PCD_EP_OutSetupPacket_int(hpcd, epnum);
1142           }
1143 
1144           if ((epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS)
1145           {
1146             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS);
1147           }
1148 
1149           /* Clear OUT Endpoint disable interrupt */
1150           if ((epint & USB_OTG_DOEPINT_EPDISD) == USB_OTG_DOEPINT_EPDISD)
1151           {
1152             if ((USBx->GINTSTS & USB_OTG_GINTSTS_BOUTNAKEFF) == USB_OTG_GINTSTS_BOUTNAKEFF)
1153             {
1154               USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGONAK;
1155             }
1156 
1157             ep = &hpcd->OUT_ep[epnum];
1158 
1159             if (ep->is_iso_incomplete == 1U)
1160             {
1161               ep->is_iso_incomplete = 0U;
1162 
1163 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1164               hpcd->ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum);
1165 #else
1166               HAL_PCD_ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum);
1167 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1168             }
1169 
1170             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_EPDISD);
1171           }
1172 
1173           /* Clear Status Phase Received interrupt */
1174           if ((epint & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR)
1175           {
1176             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
1177           }
1178 
1179           /* Clear OUT NAK interrupt */
1180           if ((epint & USB_OTG_DOEPINT_NAK) == USB_OTG_DOEPINT_NAK)
1181           {
1182             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_NAK);
1183           }
1184         }
1185         epnum++;
1186         ep_intr >>= 1U;
1187       }
1188     }
1189 
1190     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT))
1191     {
1192       /* Read in the device interrupt bits */
1193       ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance);
1194 
1195       epnum = 0U;
1196 
1197       while (ep_intr != 0U)
1198       {
1199         if ((ep_intr & 0x1U) != 0U) /* In ITR */
1200         {
1201           epint = USB_ReadDevInEPInterrupt(hpcd->Instance, (uint8_t)epnum);
1202 
1203           if ((epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC)
1204           {
1205             fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK));
1206             USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
1207 
1208             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC);
1209 
1210             if (hpcd->Init.dma_enable == 1U)
1211             {
1212               hpcd->IN_ep[epnum].xfer_buff += hpcd->IN_ep[epnum].maxpacket;
1213 
1214               /* this is ZLP, so prepare EP0 for next setup */
1215               if ((epnum == 0U) && (hpcd->IN_ep[epnum].xfer_len == 0U))
1216               {
1217                 /* prepare to rx more setup packets */
1218                 (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup);
1219               }
1220             }
1221 
1222 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1223             hpcd->DataInStageCallback(hpcd, (uint8_t)epnum);
1224 #else
1225             HAL_PCD_DataInStageCallback(hpcd, (uint8_t)epnum);
1226 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1227           }
1228           if ((epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC)
1229           {
1230             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC);
1231           }
1232           if ((epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE)
1233           {
1234             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE);
1235           }
1236           if ((epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE)
1237           {
1238             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE);
1239           }
1240           if ((epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD)
1241           {
1242             (void)USB_FlushTxFifo(USBx, epnum);
1243 
1244             ep = &hpcd->IN_ep[epnum];
1245 
1246             if (ep->is_iso_incomplete == 1U)
1247             {
1248               ep->is_iso_incomplete = 0U;
1249 
1250 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1251               hpcd->ISOINIncompleteCallback(hpcd, (uint8_t)epnum);
1252 #else
1253               HAL_PCD_ISOINIncompleteCallback(hpcd, (uint8_t)epnum);
1254 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1255             }
1256 
1257             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD);
1258           }
1259           if ((epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE)
1260           {
1261             (void)PCD_WriteEmptyTxFifo(hpcd, epnum);
1262           }
1263         }
1264         epnum++;
1265         ep_intr >>= 1U;
1266       }
1267     }
1268 
1269     /* Handle Resume Interrupt */
1270     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT))
1271     {
1272       /* Clear the Remote Wake-up Signaling */
1273       USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
1274 
1275       if (hpcd->LPM_State == LPM_L1)
1276       {
1277         hpcd->LPM_State = LPM_L0;
1278 
1279 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1280         hpcd->LPMCallback(hpcd, PCD_LPM_L0_ACTIVE);
1281 #else
1282         HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE);
1283 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1284       }
1285       else
1286       {
1287 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1288         hpcd->ResumeCallback(hpcd);
1289 #else
1290         HAL_PCD_ResumeCallback(hpcd);
1291 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1292       }
1293 
1294       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT);
1295     }
1296 
1297     /* Handle Suspend Interrupt */
1298     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP))
1299     {
1300       if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
1301       {
1302 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1303         hpcd->SuspendCallback(hpcd);
1304 #else
1305         HAL_PCD_SuspendCallback(hpcd);
1306 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1307       }
1308       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP);
1309     }
1310 
1311     /* Handle LPM Interrupt */
1312     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT))
1313     {
1314       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT);
1315 
1316       if (hpcd->LPM_State == LPM_L0)
1317       {
1318         hpcd->LPM_State = LPM_L1;
1319         hpcd->BESL = (hpcd->Instance->GLPMCFG & USB_OTG_GLPMCFG_BESL) >> 2U;
1320 
1321 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1322         hpcd->LPMCallback(hpcd, PCD_LPM_L1_ACTIVE);
1323 #else
1324         HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE);
1325 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1326       }
1327       else
1328       {
1329 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1330         hpcd->SuspendCallback(hpcd);
1331 #else
1332         HAL_PCD_SuspendCallback(hpcd);
1333 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1334       }
1335     }
1336 
1337     /* Handle Reset Interrupt */
1338     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST))
1339     {
1340       USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
1341       (void)USB_FlushTxFifo(hpcd->Instance, 0x10U);
1342 
1343       for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
1344       {
1345         USBx_INEP(i)->DIEPINT = 0xFB7FU;
1346         USBx_INEP(i)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
1347         USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
1348         USBx_OUTEP(i)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
1349         USBx_OUTEP(i)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
1350       }
1351       USBx_DEVICE->DAINTMSK |= 0x10001U;
1352 
1353       if (hpcd->Init.use_dedicated_ep1 != 0U)
1354       {
1355         USBx_DEVICE->DOUTEP1MSK |= USB_OTG_DOEPMSK_STUPM |
1356                                    USB_OTG_DOEPMSK_XFRCM |
1357                                    USB_OTG_DOEPMSK_EPDM;
1358 
1359         USBx_DEVICE->DINEP1MSK |= USB_OTG_DIEPMSK_TOM |
1360                                   USB_OTG_DIEPMSK_XFRCM |
1361                                   USB_OTG_DIEPMSK_EPDM;
1362       }
1363       else
1364       {
1365         USBx_DEVICE->DOEPMSK |= USB_OTG_DOEPMSK_STUPM |
1366                                 USB_OTG_DOEPMSK_XFRCM |
1367                                 USB_OTG_DOEPMSK_EPDM |
1368                                 USB_OTG_DOEPMSK_OTEPSPRM |
1369                                 USB_OTG_DOEPMSK_NAKM;
1370 
1371         USBx_DEVICE->DIEPMSK |= USB_OTG_DIEPMSK_TOM |
1372                                 USB_OTG_DIEPMSK_XFRCM |
1373                                 USB_OTG_DIEPMSK_EPDM;
1374       }
1375 
1376       /* Set Default Address to 0 */
1377       USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD;
1378 
1379       /* setup EP0 to receive SETUP packets */
1380       (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t)hpcd->Init.dma_enable,
1381                              (uint8_t *)hpcd->Setup);
1382 
1383       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST);
1384     }
1385 
1386     /* Handle Enumeration done Interrupt */
1387     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE))
1388     {
1389       (void)USB_ActivateSetup(hpcd->Instance);
1390       hpcd->Init.speed = USB_GetDevSpeed(hpcd->Instance);
1391 
1392       /* Set USB Turnaround time */
1393       (void)USB_SetTurnaroundTime(hpcd->Instance,
1394                                   HAL_RCC_GetHCLKFreq(),
1395                                   (uint8_t)hpcd->Init.speed);
1396 
1397 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1398       hpcd->ResetCallback(hpcd);
1399 #else
1400       HAL_PCD_ResetCallback(hpcd);
1401 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1402 
1403       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE);
1404     }
1405 
1406     /* Handle SOF Interrupt */
1407     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF))
1408     {
1409 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1410       hpcd->SOFCallback(hpcd);
1411 #else
1412       HAL_PCD_SOFCallback(hpcd);
1413 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1414 
1415       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF);
1416     }
1417 
1418     /* Handle Global OUT NAK effective Interrupt */
1419     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_BOUTNAKEFF))
1420     {
1421       USBx->GINTMSK &= ~USB_OTG_GINTMSK_GONAKEFFM;
1422 
1423       for (epnum = 1U; epnum < hpcd->Init.dev_endpoints; epnum++)
1424       {
1425         if (hpcd->OUT_ep[epnum].is_iso_incomplete == 1U)
1426         {
1427           /* Abort current transaction and disable the EP */
1428           (void)HAL_PCD_EP_Abort(hpcd, (uint8_t)epnum);
1429         }
1430       }
1431     }
1432 
1433     /* Handle Incomplete ISO IN Interrupt */
1434     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR))
1435     {
1436       for (epnum = 1U; epnum < hpcd->Init.dev_endpoints; epnum++)
1437       {
1438         RegVal = USBx_INEP(epnum)->DIEPCTL;
1439 
1440         if ((hpcd->IN_ep[epnum].type == EP_TYPE_ISOC) &&
1441             ((RegVal & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA))
1442         {
1443           hpcd->IN_ep[epnum].is_iso_incomplete = 1U;
1444 
1445           /* Abort current transaction and disable the EP */
1446           (void)HAL_PCD_EP_Abort(hpcd, (uint8_t)(epnum | 0x80U));
1447         }
1448       }
1449 
1450       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR);
1451     }
1452 
1453     /* Handle Incomplete ISO OUT Interrupt */
1454     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
1455     {
1456       for (epnum = 1U; epnum < hpcd->Init.dev_endpoints; epnum++)
1457       {
1458         RegVal = USBx_OUTEP(epnum)->DOEPCTL;
1459 
1460         if ((hpcd->OUT_ep[epnum].type == EP_TYPE_ISOC) &&
1461             ((RegVal & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA) &&
1462             ((RegVal & (0x1U << 16)) == (hpcd->FrameNumber & 0x1U)))
1463         {
1464           hpcd->OUT_ep[epnum].is_iso_incomplete = 1U;
1465 
1466           USBx->GINTMSK |= USB_OTG_GINTMSK_GONAKEFFM;
1467 
1468           if ((USBx->GINTSTS & USB_OTG_GINTSTS_BOUTNAKEFF) == 0U)
1469           {
1470             USBx_DEVICE->DCTL |= USB_OTG_DCTL_SGONAK;
1471             break;
1472           }
1473         }
1474       }
1475 
1476       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
1477     }
1478 
1479     /* Handle Connection event Interrupt */
1480     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT))
1481     {
1482 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1483       hpcd->ConnectCallback(hpcd);
1484 #else
1485       HAL_PCD_ConnectCallback(hpcd);
1486 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1487 
1488       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT);
1489     }
1490 
1491     /* Handle Disconnection event Interrupt */
1492     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT))
1493     {
1494       RegVal = hpcd->Instance->GOTGINT;
1495 
1496       if ((RegVal & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET)
1497       {
1498 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
1499         hpcd->DisconnectCallback(hpcd);
1500 #else
1501         HAL_PCD_DisconnectCallback(hpcd);
1502 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
1503       }
1504       hpcd->Instance->GOTGINT |= RegVal;
1505     }
1506   }
1507 }
1508 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
1509 
1510 
1511 /**
1512   * @brief  Data OUT stage callback.
1513   * @param  hpcd PCD handle
1514   * @param  epnum endpoint number
1515   * @retval None
1516   */
1517 __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
1518 {
1519   /* Prevent unused argument(s) compilation warning */
1520   UNUSED(hpcd);
1521   UNUSED(epnum);
1522 
1523   /* NOTE : This function should not be modified, when the callback is needed,
1524             the HAL_PCD_DataOutStageCallback could be implemented in the user file
1525    */
1526 }
1527 
1528 /**
1529   * @brief  Data IN stage callback
1530   * @param  hpcd PCD handle
1531   * @param  epnum endpoint number
1532   * @retval None
1533   */
1534 __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
1535 {
1536   /* Prevent unused argument(s) compilation warning */
1537   UNUSED(hpcd);
1538   UNUSED(epnum);
1539 
1540   /* NOTE : This function should not be modified, when the callback is needed,
1541             the HAL_PCD_DataInStageCallback could be implemented in the user file
1542    */
1543 }
1544 /**
1545   * @brief  Setup stage callback
1546   * @param  hpcd PCD handle
1547   * @retval None
1548   */
1549 __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
1550 {
1551   /* Prevent unused argument(s) compilation warning */
1552   UNUSED(hpcd);
1553 
1554   /* NOTE : This function should not be modified, when the callback is needed,
1555             the HAL_PCD_SetupStageCallback could be implemented in the user file
1556    */
1557 }
1558 
1559 /**
1560   * @brief  USB Start Of Frame callback.
1561   * @param  hpcd PCD handle
1562   * @retval None
1563   */
1564 __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
1565 {
1566   /* Prevent unused argument(s) compilation warning */
1567   UNUSED(hpcd);
1568 
1569   /* NOTE : This function should not be modified, when the callback is needed,
1570             the HAL_PCD_SOFCallback could be implemented in the user file
1571    */
1572 }
1573 
1574 /**
1575   * @brief  USB Reset callback.
1576   * @param  hpcd PCD handle
1577   * @retval None
1578   */
1579 __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
1580 {
1581   /* Prevent unused argument(s) compilation warning */
1582   UNUSED(hpcd);
1583 
1584   /* NOTE : This function should not be modified, when the callback is needed,
1585             the HAL_PCD_ResetCallback could be implemented in the user file
1586    */
1587 }
1588 
1589 /**
1590   * @brief  Suspend event callback.
1591   * @param  hpcd PCD handle
1592   * @retval None
1593   */
1594 __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
1595 {
1596   /* Prevent unused argument(s) compilation warning */
1597   UNUSED(hpcd);
1598 
1599   /* NOTE : This function should not be modified, when the callback is needed,
1600             the HAL_PCD_SuspendCallback could be implemented in the user file
1601    */
1602 }
1603 
1604 /**
1605   * @brief  Resume event callback.
1606   * @param  hpcd PCD handle
1607   * @retval None
1608   */
1609 __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
1610 {
1611   /* Prevent unused argument(s) compilation warning */
1612   UNUSED(hpcd);
1613 
1614   /* NOTE : This function should not be modified, when the callback is needed,
1615             the HAL_PCD_ResumeCallback could be implemented in the user file
1616    */
1617 }
1618 
1619 /**
1620   * @brief  Incomplete ISO OUT callback.
1621   * @param  hpcd PCD handle
1622   * @param  epnum endpoint number
1623   * @retval None
1624   */
1625 __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
1626 {
1627   /* Prevent unused argument(s) compilation warning */
1628   UNUSED(hpcd);
1629   UNUSED(epnum);
1630 
1631   /* NOTE : This function should not be modified, when the callback is needed,
1632             the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file
1633    */
1634 }
1635 
1636 /**
1637   * @brief  Incomplete ISO IN callback.
1638   * @param  hpcd PCD handle
1639   * @param  epnum endpoint number
1640   * @retval None
1641   */
1642 __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
1643 {
1644   /* Prevent unused argument(s) compilation warning */
1645   UNUSED(hpcd);
1646   UNUSED(epnum);
1647 
1648   /* NOTE : This function should not be modified, when the callback is needed,
1649             the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file
1650    */
1651 }
1652 
1653 /**
1654   * @brief  Connection event callback.
1655   * @param  hpcd PCD handle
1656   * @retval None
1657   */
1658 __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
1659 {
1660   /* Prevent unused argument(s) compilation warning */
1661   UNUSED(hpcd);
1662 
1663   /* NOTE : This function should not be modified, when the callback is needed,
1664             the HAL_PCD_ConnectCallback could be implemented in the user file
1665    */
1666 }
1667 
1668 /**
1669   * @brief  Disconnection event callback.
1670   * @param  hpcd PCD handle
1671   * @retval None
1672   */
1673 __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
1674 {
1675   /* Prevent unused argument(s) compilation warning */
1676   UNUSED(hpcd);
1677 
1678   /* NOTE : This function should not be modified, when the callback is needed,
1679             the HAL_PCD_DisconnectCallback could be implemented in the user file
1680    */
1681 }
1682 
1683 /**
1684   * @}
1685   */
1686 
1687 /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
1688   * @ingroup RTEMSBSPsARMSTM32H7
1689   *  @brief   management functions
1690   *
1691 @verbatim
1692  ===============================================================================
1693                       ##### Peripheral Control functions #####
1694  ===============================================================================
1695     [..]
1696     This subsection provides a set of functions allowing to control the PCD data
1697     transfers.
1698 
1699 @endverbatim
1700   * @{
1701   */
1702 
1703 /**
1704   * @brief  Connect the USB device
1705   * @param  hpcd PCD handle
1706   * @retval HAL status
1707   */
1708 HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd)
1709 {
1710   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1711 
1712   __HAL_LOCK(hpcd);
1713 
1714   if (((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) != 0U) &&
1715       (hpcd->Init.battery_charging_enable == 1U))
1716   {
1717     /* Enable USB Transceiver */
1718     USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
1719   }
1720   (void)USB_DevConnect(hpcd->Instance);
1721   __HAL_UNLOCK(hpcd);
1722 
1723   return HAL_OK;
1724 }
1725 
1726 /**
1727   * @brief  Disconnect the USB device.
1728   * @param  hpcd PCD handle
1729   * @retval HAL status
1730   */
1731 HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd)
1732 {
1733   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1734 
1735   __HAL_LOCK(hpcd);
1736   (void)USB_DevDisconnect(hpcd->Instance);
1737 
1738   if (((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) != 0U) &&
1739       (hpcd->Init.battery_charging_enable == 1U))
1740   {
1741     /* Disable USB Transceiver */
1742     USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
1743   }
1744 
1745   __HAL_UNLOCK(hpcd);
1746 
1747   return HAL_OK;
1748 }
1749 
1750 /**
1751   * @brief  Set the USB Device address.
1752   * @param  hpcd PCD handle
1753   * @param  address new device address
1754   * @retval HAL status
1755   */
1756 HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)
1757 {
1758   __HAL_LOCK(hpcd);
1759   hpcd->USB_Address = address;
1760   (void)USB_SetDevAddress(hpcd->Instance, address);
1761   __HAL_UNLOCK(hpcd);
1762 
1763   return HAL_OK;
1764 }
1765 /**
1766   * @brief  Open and configure an endpoint.
1767   * @param  hpcd PCD handle
1768   * @param  ep_addr endpoint address
1769   * @param  ep_mps endpoint max packet size
1770   * @param  ep_type endpoint type
1771   * @retval HAL status
1772   */
1773 HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr,
1774                                   uint16_t ep_mps, uint8_t ep_type)
1775 {
1776   HAL_StatusTypeDef  ret = HAL_OK;
1777   PCD_EPTypeDef *ep;
1778 
1779   if ((ep_addr & 0x80U) == 0x80U)
1780   {
1781     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
1782     ep->is_in = 1U;
1783   }
1784   else
1785   {
1786     ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
1787     ep->is_in = 0U;
1788   }
1789 
1790   ep->num = ep_addr & EP_ADDR_MSK;
1791   ep->maxpacket = ep_mps;
1792   ep->type = ep_type;
1793 
1794   if (ep->is_in != 0U)
1795   {
1796     /* Assign a Tx FIFO */
1797     ep->tx_fifo_num = ep->num;
1798   }
1799 
1800   /* Set initial data PID. */
1801   if (ep_type == EP_TYPE_BULK)
1802   {
1803     ep->data_pid_start = 0U;
1804   }
1805 
1806   __HAL_LOCK(hpcd);
1807   (void)USB_ActivateEndpoint(hpcd->Instance, ep);
1808   __HAL_UNLOCK(hpcd);
1809 
1810   return ret;
1811 }
1812 
1813 /**
1814   * @brief  Deactivate an endpoint.
1815   * @param  hpcd PCD handle
1816   * @param  ep_addr endpoint address
1817   * @retval HAL status
1818   */
1819 HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1820 {
1821   PCD_EPTypeDef *ep;
1822 
1823   if ((ep_addr & 0x80U) == 0x80U)
1824   {
1825     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
1826     ep->is_in = 1U;
1827   }
1828   else
1829   {
1830     ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
1831     ep->is_in = 0U;
1832   }
1833   ep->num = ep_addr & EP_ADDR_MSK;
1834 
1835   __HAL_LOCK(hpcd);
1836   (void)USB_DeactivateEndpoint(hpcd->Instance, ep);
1837   __HAL_UNLOCK(hpcd);
1838   return HAL_OK;
1839 }
1840 
1841 
1842 /**
1843   * @brief  Receive an amount of data.
1844   * @param  hpcd PCD handle
1845   * @param  ep_addr endpoint address
1846   * @param  pBuf pointer to the reception buffer
1847   * @param  len amount of data to be received
1848   * @retval HAL status
1849   */
1850 HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
1851 {
1852   PCD_EPTypeDef *ep;
1853 
1854   ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
1855 
1856   /*setup and start the Xfer */
1857   ep->xfer_buff = pBuf;
1858   ep->xfer_len = len;
1859   ep->xfer_count = 0U;
1860   ep->is_in = 0U;
1861   ep->num = ep_addr & EP_ADDR_MSK;
1862 
1863   if (hpcd->Init.dma_enable == 1U)
1864   {
1865     ep->dma_addr = (uint32_t)pBuf;
1866   }
1867 
1868   (void)USB_EPStartXfer(hpcd->Instance, ep, (uint8_t)hpcd->Init.dma_enable);
1869 
1870   return HAL_OK;
1871 }
1872 
1873 /**
1874   * @brief  Get Received Data Size
1875   * @param  hpcd PCD handle
1876   * @param  ep_addr endpoint address
1877   * @retval Data Size
1878   */
1879 uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef const *hpcd, uint8_t ep_addr)
1880 {
1881   return hpcd->OUT_ep[ep_addr & EP_ADDR_MSK].xfer_count;
1882 }
1883 /**
1884   * @brief  Send an amount of data
1885   * @param  hpcd PCD handle
1886   * @param  ep_addr endpoint address
1887   * @param  pBuf pointer to the transmission buffer
1888   * @param  len amount of data to be sent
1889   * @retval HAL status
1890   */
1891 HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
1892 {
1893   PCD_EPTypeDef *ep;
1894 
1895   ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
1896 
1897   /*setup and start the Xfer */
1898   ep->xfer_buff = pBuf;
1899   ep->xfer_len = len;
1900   ep->xfer_count = 0U;
1901   ep->is_in = 1U;
1902   ep->num = ep_addr & EP_ADDR_MSK;
1903 
1904   if (hpcd->Init.dma_enable == 1U)
1905   {
1906     ep->dma_addr = (uint32_t)pBuf;
1907   }
1908 
1909   (void)USB_EPStartXfer(hpcd->Instance, ep, (uint8_t)hpcd->Init.dma_enable);
1910 
1911   return HAL_OK;
1912 }
1913 
1914 /**
1915   * @brief  Set a STALL condition over an endpoint
1916   * @param  hpcd PCD handle
1917   * @param  ep_addr endpoint address
1918   * @retval HAL status
1919   */
1920 HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1921 {
1922   PCD_EPTypeDef *ep;
1923 
1924   if (((uint32_t)ep_addr & EP_ADDR_MSK) > hpcd->Init.dev_endpoints)
1925   {
1926     return HAL_ERROR;
1927   }
1928 
1929   if ((0x80U & ep_addr) == 0x80U)
1930   {
1931     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
1932     ep->is_in = 1U;
1933   }
1934   else
1935   {
1936     ep = &hpcd->OUT_ep[ep_addr];
1937     ep->is_in = 0U;
1938   }
1939 
1940   ep->is_stall = 1U;
1941   ep->num = ep_addr & EP_ADDR_MSK;
1942 
1943   __HAL_LOCK(hpcd);
1944 
1945   (void)USB_EPSetStall(hpcd->Instance, ep);
1946 
1947   if ((ep_addr & EP_ADDR_MSK) == 0U)
1948   {
1949     (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t)hpcd->Init.dma_enable, (uint8_t *)hpcd->Setup);
1950   }
1951 
1952   __HAL_UNLOCK(hpcd);
1953 
1954   return HAL_OK;
1955 }
1956 
1957 /**
1958   * @brief  Clear a STALL condition over in an endpoint
1959   * @param  hpcd PCD handle
1960   * @param  ep_addr endpoint address
1961   * @retval HAL status
1962   */
1963 HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1964 {
1965   PCD_EPTypeDef *ep;
1966 
1967   if (((uint32_t)ep_addr & 0x0FU) > hpcd->Init.dev_endpoints)
1968   {
1969     return HAL_ERROR;
1970   }
1971 
1972   if ((0x80U & ep_addr) == 0x80U)
1973   {
1974     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
1975     ep->is_in = 1U;
1976   }
1977   else
1978   {
1979     ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
1980     ep->is_in = 0U;
1981   }
1982 
1983   ep->is_stall = 0U;
1984   ep->num = ep_addr & EP_ADDR_MSK;
1985 
1986   __HAL_LOCK(hpcd);
1987   (void)USB_EPClearStall(hpcd->Instance, ep);
1988   __HAL_UNLOCK(hpcd);
1989 
1990   return HAL_OK;
1991 }
1992 
1993 /**
1994    * @brief  Abort an USB EP transaction.
1995    * @param  hpcd PCD handle
1996    * @param  ep_addr endpoint address
1997    * @retval HAL status
1998    */
1999 HAL_StatusTypeDef HAL_PCD_EP_Abort(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
2000 {
2001   HAL_StatusTypeDef ret;
2002   PCD_EPTypeDef *ep;
2003 
2004   if ((0x80U & ep_addr) == 0x80U)
2005   {
2006     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
2007   }
2008   else
2009   {
2010     ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
2011   }
2012 
2013   /* Stop Xfer */
2014   ret = USB_EPStopXfer(hpcd->Instance, ep);
2015 
2016   return ret;
2017 }
2018 
2019 /**
2020   * @brief  Flush an endpoint
2021   * @param  hpcd PCD handle
2022   * @param  ep_addr endpoint address
2023   * @retval HAL status
2024   */
2025 HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
2026 {
2027   __HAL_LOCK(hpcd);
2028 
2029   if ((ep_addr & 0x80U) == 0x80U)
2030   {
2031     (void)USB_FlushTxFifo(hpcd->Instance, (uint32_t)ep_addr & EP_ADDR_MSK);
2032   }
2033   else
2034   {
2035     (void)USB_FlushRxFifo(hpcd->Instance);
2036   }
2037 
2038   __HAL_UNLOCK(hpcd);
2039 
2040   return HAL_OK;
2041 }
2042 
2043 /**
2044   * @brief  Activate remote wakeup signalling
2045   * @param  hpcd PCD handle
2046   * @retval HAL status
2047   */
2048 HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
2049 {
2050   return (USB_ActivateRemoteWakeup(hpcd->Instance));
2051 }
2052 
2053 /**
2054   * @brief  De-activate remote wakeup signalling.
2055   * @param  hpcd PCD handle
2056   * @retval HAL status
2057   */
2058 HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
2059 {
2060   return (USB_DeActivateRemoteWakeup(hpcd->Instance));
2061 }
2062 
2063 /**
2064   * @}
2065   */
2066 
2067 /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions
2068   * @ingroup RTEMSBSPsARMSTM32H7
2069   *  @brief   Peripheral State functions
2070   *
2071 @verbatim
2072  ===============================================================================
2073                       ##### Peripheral State functions #####
2074  ===============================================================================
2075     [..]
2076     This subsection permits to get in run-time the status of the peripheral
2077     and the data flow.
2078 
2079 @endverbatim
2080   * @{
2081   */
2082 
2083 /**
2084   * @brief  Return the PCD handle state.
2085   * @param  hpcd PCD handle
2086   * @retval HAL state
2087   */
2088 PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef const *hpcd)
2089 {
2090   return hpcd->State;
2091 }
2092 
2093 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
2094 /**
2095   * @brief  Set the USB Device high speed test mode.
2096   * @param  hpcd PCD handle
2097   * @param  testmode USB Device high speed test mode
2098   * @retval HAL status
2099   */
2100 HAL_StatusTypeDef HAL_PCD_SetTestMode(const PCD_HandleTypeDef *hpcd, uint8_t testmode)
2101 {
2102   const USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
2103   uint32_t USBx_BASE = (uint32_t)USBx;
2104 
2105   switch (testmode)
2106   {
2107     case TEST_J:
2108     case TEST_K:
2109     case TEST_SE0_NAK:
2110     case TEST_PACKET:
2111     case TEST_FORCE_EN:
2112       USBx_DEVICE->DCTL |= (uint32_t)testmode << 4;
2113       break;
2114 
2115     default:
2116       break;
2117   }
2118 
2119   return HAL_OK;
2120 }
2121 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2122 /**
2123   * @}
2124   */
2125 
2126 /**
2127   * @}
2128   */
2129 
2130 /* Private functions ---------------------------------------------------------*/
2131 /** @addtogroup PCD_Private_Functions
2132   * @{
2133   */
2134 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
2135 /**
2136   * @brief  Check FIFO for the next packet to be loaded.
2137   * @param  hpcd PCD handle
2138   * @param  epnum endpoint number
2139   * @retval HAL status
2140   */
2141 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum)
2142 {
2143   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
2144   uint32_t USBx_BASE = (uint32_t)USBx;
2145   USB_OTG_EPTypeDef *ep;
2146   uint32_t len;
2147   uint32_t len32b;
2148   uint32_t fifoemptymsk;
2149 
2150   ep = &hpcd->IN_ep[epnum];
2151 
2152   if (ep->xfer_count > ep->xfer_len)
2153   {
2154     return HAL_ERROR;
2155   }
2156 
2157   len = ep->xfer_len - ep->xfer_count;
2158 
2159   if (len > ep->maxpacket)
2160   {
2161     len = ep->maxpacket;
2162   }
2163 
2164   len32b = (len + 3U) / 4U;
2165 
2166   while (((USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= len32b) &&
2167          (ep->xfer_count < ep->xfer_len) && (ep->xfer_len != 0U))
2168   {
2169     /* Write the FIFO */
2170     len = ep->xfer_len - ep->xfer_count;
2171 
2172     if (len > ep->maxpacket)
2173     {
2174       len = ep->maxpacket;
2175     }
2176     len32b = (len + 3U) / 4U;
2177 
2178     (void)USB_WritePacket(USBx, ep->xfer_buff, (uint8_t)epnum, (uint16_t)len,
2179                           (uint8_t)hpcd->Init.dma_enable);
2180 
2181     ep->xfer_buff  += len;
2182     ep->xfer_count += len;
2183   }
2184 
2185   if (ep->xfer_len <= ep->xfer_count)
2186   {
2187     fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK));
2188     USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
2189   }
2190 
2191   return HAL_OK;
2192 }
2193 
2194 
2195 /**
2196   * @brief  process EP OUT transfer complete interrupt.
2197   * @param  hpcd PCD handle
2198   * @param  epnum endpoint number
2199   * @retval HAL status
2200   */
2201 static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef *hpcd, uint32_t epnum)
2202 {
2203   USB_OTG_EPTypeDef *ep;
2204   const USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
2205   uint32_t USBx_BASE = (uint32_t)USBx;
2206   uint32_t gSNPSiD = *(__IO const uint32_t *)(&USBx->CID + 0x1U);
2207   uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT;
2208 
2209   if (hpcd->Init.dma_enable == 1U)
2210   {
2211     if ((DoepintReg & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP) /* Class C */
2212     {
2213       /* StupPktRcvd = 1 this is a setup packet */
2214       if ((gSNPSiD > USB_OTG_CORE_ID_300A) &&
2215           ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX))
2216       {
2217         CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
2218       }
2219     }
2220     else if ((DoepintReg & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR) /* Class E */
2221     {
2222       CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
2223     }
2224     else if ((DoepintReg & (USB_OTG_DOEPINT_STUP | USB_OTG_DOEPINT_OTEPSPR)) == 0U)
2225     {
2226       /* StupPktRcvd = 1 this is a setup packet */
2227       if ((gSNPSiD > USB_OTG_CORE_ID_300A) &&
2228           ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX))
2229       {
2230         CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
2231       }
2232       else
2233       {
2234         ep = &hpcd->OUT_ep[epnum];
2235 
2236         /* out data packet received over EP */
2237         ep->xfer_count = ep->xfer_size - (USBx_OUTEP(epnum)->DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ);
2238 
2239         if (epnum == 0U)
2240         {
2241           if (ep->xfer_len == 0U)
2242           {
2243             /* this is ZLP, so prepare EP0 for next setup */
2244             (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup);
2245           }
2246           else
2247           {
2248             ep->xfer_buff += ep->xfer_count;
2249           }
2250         }
2251 
2252 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2253         hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
2254 #else
2255         HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
2256 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2257       }
2258     }
2259     else
2260     {
2261       /* ... */
2262     }
2263   }
2264   else
2265   {
2266     if (gSNPSiD == USB_OTG_CORE_ID_310A)
2267     {
2268       /* StupPktRcvd = 1 this is a setup packet */
2269       if ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX)
2270       {
2271         CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
2272       }
2273       else
2274       {
2275         if ((DoepintReg & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR)
2276         {
2277           CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
2278         }
2279 
2280 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2281         hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
2282 #else
2283         HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
2284 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2285       }
2286     }
2287     else
2288     {
2289       if ((epnum == 0U) && (hpcd->OUT_ep[epnum].xfer_len == 0U))
2290       {
2291         /* this is ZLP, so prepare EP0 for next setup */
2292         (void)USB_EP0_OutStart(hpcd->Instance, 0U, (uint8_t *)hpcd->Setup);
2293       }
2294 
2295 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2296       hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
2297 #else
2298       HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
2299 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2300     }
2301   }
2302 
2303   return HAL_OK;
2304 }
2305 
2306 
2307 /**
2308   * @brief  process EP OUT setup packet received interrupt.
2309   * @param  hpcd PCD handle
2310   * @param  epnum endpoint number
2311   * @retval HAL status
2312   */
2313 static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef *hpcd, uint32_t epnum)
2314 {
2315   const USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
2316   uint32_t USBx_BASE = (uint32_t)USBx;
2317   uint32_t gSNPSiD = *(__IO const uint32_t *)(&USBx->CID + 0x1U);
2318   uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT;
2319 
2320   if ((gSNPSiD > USB_OTG_CORE_ID_300A) &&
2321       ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX))
2322   {
2323     CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
2324   }
2325 
2326   /* Inform the upper layer that a setup packet is available */
2327 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
2328   hpcd->SetupStageCallback(hpcd);
2329 #else
2330   HAL_PCD_SetupStageCallback(hpcd);
2331 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
2332 
2333   if ((gSNPSiD > USB_OTG_CORE_ID_300A) && (hpcd->Init.dma_enable == 1U))
2334   {
2335     (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup);
2336   }
2337 
2338   return HAL_OK;
2339 }
2340 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2341 
2342 
2343 /**
2344   * @}
2345   */
2346 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2347 #endif /* HAL_PCD_MODULE_ENABLED */
2348 
2349 /**
2350   * @}
2351   */
2352 
2353 /**
2354   * @}
2355   */