Back to home page

LXR

 
 

    


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

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_hal_hcd.c
0004   * @author  MCD Application Team
0005   * @brief   HCD 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     (#)Declare a HCD_HandleTypeDef handle structure, for example:
0030        HCD_HandleTypeDef  hhcd;
0031 
0032     (#)Fill parameters of Init structure in HCD handle
0033 
0034     (#)Call HAL_HCD_Init() API to initialize the HCD peripheral (Core, Host core, ...)
0035 
0036     (#)Initialize the HCD low level resources through the HAL_HCD_MspInit() API:
0037         (##) Enable the HCD/USB Low Level interface clock using the following macros
0038              (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
0039              (+++) __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); (For High Speed Mode)
0040              (+++) __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE(); (For High Speed Mode)
0041 
0042         (##) Initialize the related GPIO clocks
0043         (##) Configure HCD pin-out
0044         (##) Configure HCD NVIC interrupt
0045 
0046     (#)Associate the Upper USB Host stack to the HAL HCD Driver:
0047         (##) hhcd.pData = phost;
0048 
0049     (#)Enable HCD transmission and reception:
0050         (##) HAL_HCD_Start();
0051 
0052   @endverbatim
0053   ******************************************************************************
0054   */
0055 
0056 /* Includes ------------------------------------------------------------------*/
0057 #include "stm32h7xx_hal.h"
0058 
0059 /** @addtogroup STM32H7xx_HAL_Driver
0060   * @{
0061   */
0062 
0063 #ifdef HAL_HCD_MODULE_ENABLED
0064 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
0065 
0066 /** @defgroup HCD HCD
0067   * @ingroup RTEMSBSPsARMSTM32H7
0068   * @brief HCD HAL module driver
0069   * @{
0070   */
0071 
0072 /* Private typedef -----------------------------------------------------------*/
0073 /* Private define ------------------------------------------------------------*/
0074 /* Private macro -------------------------------------------------------------*/
0075 /* Private variables ---------------------------------------------------------*/
0076 /* Private function prototypes -----------------------------------------------*/
0077 /** @defgroup HCD_Private_Functions HCD Private Functions
0078   * @ingroup RTEMSBSPsARMSTM32H7
0079   * @{
0080   */
0081 static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
0082 static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
0083 static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd);
0084 static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd);
0085 /**
0086   * @}
0087   */
0088 
0089 /* Exported functions --------------------------------------------------------*/
0090 /** @defgroup HCD_Exported_Functions HCD Exported Functions
0091   * @ingroup RTEMSBSPsARMSTM32H7
0092   * @{
0093   */
0094 
0095 /** @defgroup HCD_Exported_Functions_Group1 Initialization and de-initialization functions
0096   * @ingroup RTEMSBSPsARMSTM32H7
0097   *  @brief    Initialization and Configuration functions
0098   *
0099 @verbatim
0100  ===============================================================================
0101           ##### Initialization and de-initialization functions #####
0102  ===============================================================================
0103     [..]  This section provides functions allowing to:
0104 
0105 @endverbatim
0106   * @{
0107   */
0108 
0109 /**
0110   * @brief  Initialize the host driver.
0111   * @param  hhcd HCD handle
0112   * @retval HAL status
0113   */
0114 HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd)
0115 {
0116   /* Check the HCD handle allocation */
0117   if (hhcd == NULL)
0118   {
0119     return HAL_ERROR;
0120   }
0121 
0122   /* Check the parameters */
0123   assert_param(IS_HCD_ALL_INSTANCE(hhcd->Instance));
0124 
0125   if (hhcd->State == HAL_HCD_STATE_RESET)
0126   {
0127     /* Allocate lock resource and initialize it */
0128     hhcd->Lock = HAL_UNLOCKED;
0129 
0130 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
0131     hhcd->SOFCallback = HAL_HCD_SOF_Callback;
0132     hhcd->ConnectCallback = HAL_HCD_Connect_Callback;
0133     hhcd->DisconnectCallback = HAL_HCD_Disconnect_Callback;
0134     hhcd->PortEnabledCallback = HAL_HCD_PortEnabled_Callback;
0135     hhcd->PortDisabledCallback = HAL_HCD_PortDisabled_Callback;
0136     hhcd->HC_NotifyURBChangeCallback = HAL_HCD_HC_NotifyURBChange_Callback;
0137 
0138     if (hhcd->MspInitCallback == NULL)
0139     {
0140       hhcd->MspInitCallback = HAL_HCD_MspInit;
0141     }
0142 
0143     /* Init the low level hardware */
0144     hhcd->MspInitCallback(hhcd);
0145 #else
0146     /* Init the low level hardware : GPIO, CLOCK, NVIC... */
0147     HAL_HCD_MspInit(hhcd);
0148 #endif /* (USE_HAL_HCD_REGISTER_CALLBACKS) */
0149   }
0150 
0151   hhcd->State = HAL_HCD_STATE_BUSY;
0152 
0153   /* Disable the Interrupts */
0154   __HAL_HCD_DISABLE(hhcd);
0155 
0156   /* Init the Core (common init.) */
0157   if (USB_CoreInit(hhcd->Instance, hhcd->Init) != HAL_OK)
0158   {
0159     hhcd->State = HAL_HCD_STATE_ERROR;
0160     return HAL_ERROR;
0161   }
0162 
0163   /* Force Host Mode */
0164   if (USB_SetCurrentMode(hhcd->Instance, USB_HOST_MODE) != HAL_OK)
0165   {
0166     hhcd->State = HAL_HCD_STATE_ERROR;
0167     return HAL_ERROR;
0168   }
0169 
0170   /* Init Host */
0171   if (USB_HostInit(hhcd->Instance, hhcd->Init) != HAL_OK)
0172   {
0173     hhcd->State = HAL_HCD_STATE_ERROR;
0174     return HAL_ERROR;
0175   }
0176 
0177   hhcd->State = HAL_HCD_STATE_READY;
0178 
0179   return HAL_OK;
0180 }
0181 
0182 /**
0183   * @brief  Initialize a host channel.
0184   * @param  hhcd HCD handle
0185   * @param  ch_num Channel number.
0186   *         This parameter can be a value from 1 to 15
0187   * @param  epnum Endpoint number.
0188   *          This parameter can be a value from 1 to 15
0189   * @param  dev_address Current device address
0190   *          This parameter can be a value from 0 to 255
0191   * @param  speed Current device speed.
0192   *          This parameter can be one of these values:
0193   *            HCD_DEVICE_SPEED_HIGH: High speed mode,
0194   *            HCD_DEVICE_SPEED_FULL: Full speed mode,
0195   *            HCD_DEVICE_SPEED_LOW: Low speed mode
0196   * @param  ep_type Endpoint Type.
0197   *          This parameter can be one of these values:
0198   *            EP_TYPE_CTRL: Control type,
0199   *            EP_TYPE_ISOC: Isochronous type,
0200   *            EP_TYPE_BULK: Bulk type,
0201   *            EP_TYPE_INTR: Interrupt type
0202   * @param  mps Max Packet Size.
0203   *          This parameter can be a value from 0 to32K
0204   * @retval HAL status
0205   */
0206 HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd, uint8_t ch_num, uint8_t epnum,
0207                                   uint8_t dev_address, uint8_t speed, uint8_t ep_type, uint16_t mps)
0208 {
0209   HAL_StatusTypeDef status;
0210   uint32_t HostCoreSpeed;
0211   uint32_t HCcharMps = mps;
0212 
0213   __HAL_LOCK(hhcd);
0214   hhcd->hc[ch_num].do_ping = 0U;
0215   hhcd->hc[ch_num].dev_addr = dev_address;
0216   hhcd->hc[ch_num].ch_num = ch_num;
0217   hhcd->hc[ch_num].ep_type = ep_type;
0218   hhcd->hc[ch_num].ep_num = epnum & 0x7FU;
0219 
0220   (void)HAL_HCD_HC_ClearHubInfo(hhcd, ch_num);
0221 
0222   if ((epnum & 0x80U) == 0x80U)
0223   {
0224     hhcd->hc[ch_num].ep_is_in = 1U;
0225   }
0226   else
0227   {
0228     hhcd->hc[ch_num].ep_is_in = 0U;
0229   }
0230 
0231   HostCoreSpeed = USB_GetHostSpeed(hhcd->Instance);
0232 
0233   if (ep_type == EP_TYPE_ISOC)
0234   {
0235     /* FS device plugged to HS HUB */
0236     if ((speed == HCD_DEVICE_SPEED_FULL) && (HostCoreSpeed == HPRT0_PRTSPD_HIGH_SPEED))
0237     {
0238       if (HCcharMps > ISO_SPLT_MPS)
0239       {
0240         /* ISO Max Packet Size for Split mode */
0241         HCcharMps = ISO_SPLT_MPS;
0242       }
0243     }
0244   }
0245 
0246   hhcd->hc[ch_num].speed = speed;
0247   hhcd->hc[ch_num].max_packet = (uint16_t)HCcharMps;
0248 
0249   status =  USB_HC_Init(hhcd->Instance, ch_num, epnum,
0250                         dev_address, speed, ep_type, (uint16_t)HCcharMps);
0251 
0252   __HAL_UNLOCK(hhcd);
0253 
0254   return status;
0255 }
0256 
0257 /**
0258   * @brief  Halt a host channel.
0259   * @param  hhcd HCD handle
0260   * @param  ch_num Channel number.
0261   *         This parameter can be a value from 1 to 15
0262   * @retval HAL status
0263   */
0264 HAL_StatusTypeDef HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd, uint8_t ch_num)
0265 {
0266   HAL_StatusTypeDef status = HAL_OK;
0267 
0268   __HAL_LOCK(hhcd);
0269   (void)USB_HC_Halt(hhcd->Instance, ch_num);
0270   __HAL_UNLOCK(hhcd);
0271 
0272   return status;
0273 }
0274 
0275 /**
0276   * @brief  DeInitialize the host driver.
0277   * @param  hhcd HCD handle
0278   * @retval HAL status
0279   */
0280 HAL_StatusTypeDef HAL_HCD_DeInit(HCD_HandleTypeDef *hhcd)
0281 {
0282   /* Check the HCD handle allocation */
0283   if (hhcd == NULL)
0284   {
0285     return HAL_ERROR;
0286   }
0287 
0288   hhcd->State = HAL_HCD_STATE_BUSY;
0289 
0290 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
0291   if (hhcd->MspDeInitCallback == NULL)
0292   {
0293     hhcd->MspDeInitCallback = HAL_HCD_MspDeInit; /* Legacy weak MspDeInit  */
0294   }
0295 
0296   /* DeInit the low level hardware */
0297   hhcd->MspDeInitCallback(hhcd);
0298 #else
0299   /* DeInit the low level hardware: CLOCK, NVIC.*/
0300   HAL_HCD_MspDeInit(hhcd);
0301 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
0302 
0303   __HAL_HCD_DISABLE(hhcd);
0304 
0305   hhcd->State = HAL_HCD_STATE_RESET;
0306 
0307   return HAL_OK;
0308 }
0309 
0310 /**
0311   * @brief  Initialize the HCD MSP.
0312   * @param  hhcd HCD handle
0313   * @retval None
0314   */
0315 __weak void  HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd)
0316 {
0317   /* Prevent unused argument(s) compilation warning */
0318   UNUSED(hhcd);
0319 
0320   /* NOTE : This function should not be modified, when the callback is needed,
0321             the HAL_HCD_MspInit could be implemented in the user file
0322    */
0323 }
0324 
0325 /**
0326   * @brief  DeInitialize the HCD MSP.
0327   * @param  hhcd HCD handle
0328   * @retval None
0329   */
0330 __weak void  HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd)
0331 {
0332   /* Prevent unused argument(s) compilation warning */
0333   UNUSED(hhcd);
0334 
0335   /* NOTE : This function should not be modified, when the callback is needed,
0336             the HAL_HCD_MspDeInit could be implemented in the user file
0337    */
0338 }
0339 
0340 /**
0341   * @}
0342   */
0343 
0344 /** @defgroup HCD_Exported_Functions_Group2 Input and Output operation functions
0345   * @ingroup RTEMSBSPsARMSTM32H7
0346   *  @brief   HCD IO operation functions
0347   *
0348 @verbatim
0349  ===============================================================================
0350                       ##### IO operation functions #####
0351  ===============================================================================
0352  [..] This subsection provides a set of functions allowing to manage the USB Host Data
0353     Transfer
0354 
0355 @endverbatim
0356   * @{
0357   */
0358 
0359 /**
0360   * @brief  Submit a new URB for processing.
0361   * @param  hhcd HCD handle
0362   * @param  ch_num Channel number.
0363   *         This parameter can be a value from 1 to 15
0364   * @param  direction Channel number.
0365   *          This parameter can be one of these values:
0366   *           0 : Output / 1 : Input
0367   * @param  ep_type Endpoint Type.
0368   *          This parameter can be one of these values:
0369   *            EP_TYPE_CTRL: Control type/
0370   *            EP_TYPE_ISOC: Isochronous type/
0371   *            EP_TYPE_BULK: Bulk type/
0372   *            EP_TYPE_INTR: Interrupt type/
0373   * @param  token Endpoint Type.
0374   *          This parameter can be one of these values:
0375   *            0: HC_PID_SETUP / 1: HC_PID_DATA1
0376   * @param  pbuff pointer to URB data
0377   * @param  length Length of URB data
0378   * @param  do_ping activate do ping protocol (for high speed only).
0379   *          This parameter can be one of these values:
0380   *           0 : do ping inactive / 1 : do ping active
0381   * @retval HAL status
0382   */
0383 HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd,
0384                                            uint8_t ch_num,
0385                                            uint8_t direction,
0386                                            uint8_t ep_type,
0387                                            uint8_t token,
0388                                            uint8_t *pbuff,
0389                                            uint16_t length,
0390                                            uint8_t do_ping)
0391 {
0392   hhcd->hc[ch_num].ep_is_in = direction;
0393   hhcd->hc[ch_num].ep_type  = ep_type;
0394 
0395   if (token == 0U)
0396   {
0397     hhcd->hc[ch_num].data_pid = HC_PID_SETUP;
0398     hhcd->hc[ch_num].do_ping = do_ping;
0399   }
0400   else
0401   {
0402     hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
0403   }
0404 
0405   /* Manage Data Toggle */
0406   switch (ep_type)
0407   {
0408     case EP_TYPE_CTRL:
0409       if (token == 1U) /* send data */
0410       {
0411         if (direction == 0U)
0412         {
0413           if (length == 0U)
0414           {
0415             /* For Status OUT stage, Length == 0U, Status Out PID = 1 */
0416             hhcd->hc[ch_num].toggle_out = 1U;
0417           }
0418 
0419           /* Set the Data Toggle bit as per the Flag */
0420           if (hhcd->hc[ch_num].toggle_out == 0U)
0421           {
0422             /* Put the PID 0 */
0423             hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
0424           }
0425           else
0426           {
0427             /* Put the PID 1 */
0428             hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
0429           }
0430         }
0431         else
0432         {
0433           if (hhcd->hc[ch_num].do_ssplit == 1U)
0434           {
0435             if (hhcd->hc[ch_num].toggle_in == 0U)
0436             {
0437               hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
0438             }
0439             else
0440             {
0441               hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
0442             }
0443           }
0444         }
0445       }
0446       break;
0447 
0448     case EP_TYPE_BULK:
0449       if (direction == 0U)
0450       {
0451         /* Set the Data Toggle bit as per the Flag */
0452         if (hhcd->hc[ch_num].toggle_out == 0U)
0453         {
0454           /* Put the PID 0 */
0455           hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
0456         }
0457         else
0458         {
0459           /* Put the PID 1 */
0460           hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
0461         }
0462       }
0463       else
0464       {
0465         if (hhcd->hc[ch_num].toggle_in == 0U)
0466         {
0467           hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
0468         }
0469         else
0470         {
0471           hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
0472         }
0473       }
0474 
0475       break;
0476     case EP_TYPE_INTR:
0477       if (direction == 0U)
0478       {
0479         /* Set the Data Toggle bit as per the Flag */
0480         if (hhcd->hc[ch_num].toggle_out == 0U)
0481         {
0482           /* Put the PID 0 */
0483           hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
0484         }
0485         else
0486         {
0487           /* Put the PID 1 */
0488           hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
0489         }
0490       }
0491       else
0492       {
0493         if (hhcd->hc[ch_num].toggle_in == 0U)
0494         {
0495           hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
0496         }
0497         else
0498         {
0499           hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
0500         }
0501       }
0502       break;
0503 
0504     case EP_TYPE_ISOC:
0505       hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
0506       break;
0507 
0508     default:
0509       break;
0510   }
0511 
0512   hhcd->hc[ch_num].xfer_buff = pbuff;
0513   hhcd->hc[ch_num].xfer_len  = length;
0514   hhcd->hc[ch_num].urb_state = URB_IDLE;
0515   hhcd->hc[ch_num].xfer_count = 0U;
0516   hhcd->hc[ch_num].ch_num = ch_num;
0517   hhcd->hc[ch_num].state = HC_IDLE;
0518 
0519   return USB_HC_StartXfer(hhcd->Instance, &hhcd->hc[ch_num], (uint8_t)hhcd->Init.dma_enable);
0520 }
0521 
0522 /**
0523   * @brief  Handle HCD interrupt request.
0524   * @param  hhcd HCD handle
0525   * @retval None
0526   */
0527 void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd)
0528 {
0529   USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
0530   uint32_t USBx_BASE = (uint32_t)USBx;
0531   uint32_t i;
0532   uint32_t interrupt;
0533 
0534   /* Ensure that we are in device mode */
0535   if (USB_GetMode(hhcd->Instance) == USB_OTG_MODE_HOST)
0536   {
0537     /* Avoid spurious interrupt */
0538     if (__HAL_HCD_IS_INVALID_INTERRUPT(hhcd))
0539     {
0540       return;
0541     }
0542 
0543     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
0544     {
0545       /* Incorrect mode, acknowledge the interrupt */
0546       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
0547     }
0548 
0549     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR))
0550     {
0551       /* Incorrect mode, acknowledge the interrupt */
0552       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR);
0553     }
0554 
0555     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE))
0556     {
0557       /* Incorrect mode, acknowledge the interrupt */
0558       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE);
0559     }
0560 
0561     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_MMIS))
0562     {
0563       /* Incorrect mode, acknowledge the interrupt */
0564       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_MMIS);
0565     }
0566 
0567     /* Handle Host Disconnect Interrupts */
0568     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT))
0569     {
0570       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT);
0571 
0572       if ((USBx_HPRT0 & USB_OTG_HPRT_PCSTS) == 0U)
0573       {
0574         /* Flush USB Fifo */
0575         (void)USB_FlushTxFifo(USBx, 0x10U);
0576         (void)USB_FlushRxFifo(USBx);
0577 
0578         if (hhcd->Init.phy_itface == USB_OTG_EMBEDDED_PHY)
0579         {
0580           /* Restore FS Clock */
0581           (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_48_MHZ);
0582         }
0583 
0584         /* Handle Host Port Disconnect Interrupt */
0585 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
0586         hhcd->DisconnectCallback(hhcd);
0587 #else
0588         HAL_HCD_Disconnect_Callback(hhcd);
0589 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
0590       }
0591     }
0592 
0593     /* Handle Host Port Interrupts */
0594     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HPRTINT))
0595     {
0596       HCD_Port_IRQHandler(hhcd);
0597     }
0598 
0599     /* Handle Host SOF Interrupt */
0600     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_SOF))
0601     {
0602 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
0603       hhcd->SOFCallback(hhcd);
0604 #else
0605       HAL_HCD_SOF_Callback(hhcd);
0606 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
0607 
0608       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_SOF);
0609     }
0610 
0611     /* Handle Host channel Interrupt */
0612     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HCINT))
0613     {
0614       interrupt = USB_HC_ReadInterrupt(hhcd->Instance);
0615       for (i = 0U; i < hhcd->Init.Host_channels; i++)
0616       {
0617         if ((interrupt & (1UL << (i & 0xFU))) != 0U)
0618         {
0619           if ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_EPDIR) == USB_OTG_HCCHAR_EPDIR)
0620           {
0621             HCD_HC_IN_IRQHandler(hhcd, (uint8_t)i);
0622           }
0623           else
0624           {
0625             HCD_HC_OUT_IRQHandler(hhcd, (uint8_t)i);
0626           }
0627         }
0628       }
0629       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_HCINT);
0630     }
0631 
0632     /* Handle Rx Queue Level Interrupts */
0633     if ((__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_RXFLVL)) != 0U)
0634     {
0635       USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
0636 
0637       HCD_RXQLVL_IRQHandler(hhcd);
0638 
0639       USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
0640     }
0641   }
0642 }
0643 
0644 
0645 /**
0646   * @brief  SOF callback.
0647   * @param  hhcd HCD handle
0648   * @retval None
0649   */
0650 __weak void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd)
0651 {
0652   /* Prevent unused argument(s) compilation warning */
0653   UNUSED(hhcd);
0654 
0655   /* NOTE : This function should not be modified, when the callback is needed,
0656             the HAL_HCD_SOF_Callback could be implemented in the user file
0657    */
0658 }
0659 
0660 /**
0661   * @brief Connection Event callback.
0662   * @param  hhcd HCD handle
0663   * @retval None
0664   */
0665 __weak void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
0666 {
0667   /* Prevent unused argument(s) compilation warning */
0668   UNUSED(hhcd);
0669 
0670   /* NOTE : This function should not be modified, when the callback is needed,
0671             the HAL_HCD_Connect_Callback could be implemented in the user file
0672    */
0673 }
0674 
0675 /**
0676   * @brief  Disconnection Event callback.
0677   * @param  hhcd HCD handle
0678   * @retval None
0679   */
0680 __weak void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
0681 {
0682   /* Prevent unused argument(s) compilation warning */
0683   UNUSED(hhcd);
0684 
0685   /* NOTE : This function should not be modified, when the callback is needed,
0686             the HAL_HCD_Disconnect_Callback could be implemented in the user file
0687    */
0688 }
0689 
0690 /**
0691   * @brief  Port Enabled  Event callback.
0692   * @param  hhcd HCD handle
0693   * @retval None
0694   */
0695 __weak void HAL_HCD_PortEnabled_Callback(HCD_HandleTypeDef *hhcd)
0696 {
0697   /* Prevent unused argument(s) compilation warning */
0698   UNUSED(hhcd);
0699 
0700   /* NOTE : This function should not be modified, when the callback is needed,
0701             the HAL_HCD_Disconnect_Callback could be implemented in the user file
0702    */
0703 }
0704 
0705 /**
0706   * @brief  Port Disabled  Event callback.
0707   * @param  hhcd HCD handle
0708   * @retval None
0709   */
0710 __weak void HAL_HCD_PortDisabled_Callback(HCD_HandleTypeDef *hhcd)
0711 {
0712   /* Prevent unused argument(s) compilation warning */
0713   UNUSED(hhcd);
0714 
0715   /* NOTE : This function should not be modified, when the callback is needed,
0716             the HAL_HCD_Disconnect_Callback could be implemented in the user file
0717    */
0718 }
0719 
0720 /**
0721   * @brief  Notify URB state change callback.
0722   * @param  hhcd HCD handle
0723   * @param  chnum Channel number.
0724   *         This parameter can be a value from 1 to 15
0725   * @param  urb_state:
0726   *          This parameter can be one of these values:
0727   *            URB_IDLE/
0728   *            URB_DONE/
0729   *            URB_NOTREADY/
0730   *            URB_NYET/
0731   *            URB_ERROR/
0732   *            URB_STALL/
0733   * @retval None
0734   */
0735 __weak void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state)
0736 {
0737   /* Prevent unused argument(s) compilation warning */
0738   UNUSED(hhcd);
0739   UNUSED(chnum);
0740   UNUSED(urb_state);
0741 
0742   /* NOTE : This function should not be modified, when the callback is needed,
0743             the HAL_HCD_HC_NotifyURBChange_Callback could be implemented in the user file
0744    */
0745 }
0746 
0747 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
0748 /**
0749   * @brief  Register a User USB HCD Callback
0750   *         To be used instead of the weak predefined callback
0751   * @param  hhcd USB HCD handle
0752   * @param  CallbackID ID of the callback to be registered
0753   *         This parameter can be one of the following values:
0754   *          @arg @ref HAL_HCD_SOF_CB_ID USB HCD SOF callback ID
0755   *          @arg @ref HAL_HCD_CONNECT_CB_ID USB HCD Connect callback ID
0756   *          @arg @ref HAL_HCD_DISCONNECT_CB_ID OTG HCD Disconnect callback ID
0757   *          @arg @ref HAL_HCD_PORT_ENABLED_CB_ID USB HCD Port Enable callback ID
0758   *          @arg @ref HAL_HCD_PORT_DISABLED_CB_ID USB HCD Port Disable callback ID
0759   *          @arg @ref HAL_HCD_MSPINIT_CB_ID MspDeInit callback ID
0760   *          @arg @ref HAL_HCD_MSPDEINIT_CB_ID MspDeInit callback ID
0761   * @param  pCallback pointer to the Callback function
0762   * @retval HAL status
0763   */
0764 HAL_StatusTypeDef HAL_HCD_RegisterCallback(HCD_HandleTypeDef *hhcd,
0765                                            HAL_HCD_CallbackIDTypeDef CallbackID,
0766                                            pHCD_CallbackTypeDef pCallback)
0767 {
0768   HAL_StatusTypeDef status = HAL_OK;
0769 
0770   if (pCallback == NULL)
0771   {
0772     /* Update the error code */
0773     hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
0774     return HAL_ERROR;
0775   }
0776   /* Process locked */
0777   __HAL_LOCK(hhcd);
0778 
0779   if (hhcd->State == HAL_HCD_STATE_READY)
0780   {
0781     switch (CallbackID)
0782     {
0783       case HAL_HCD_SOF_CB_ID :
0784         hhcd->SOFCallback = pCallback;
0785         break;
0786 
0787       case HAL_HCD_CONNECT_CB_ID :
0788         hhcd->ConnectCallback = pCallback;
0789         break;
0790 
0791       case HAL_HCD_DISCONNECT_CB_ID :
0792         hhcd->DisconnectCallback = pCallback;
0793         break;
0794 
0795       case HAL_HCD_PORT_ENABLED_CB_ID :
0796         hhcd->PortEnabledCallback = pCallback;
0797         break;
0798 
0799       case HAL_HCD_PORT_DISABLED_CB_ID :
0800         hhcd->PortDisabledCallback = pCallback;
0801         break;
0802 
0803       case HAL_HCD_MSPINIT_CB_ID :
0804         hhcd->MspInitCallback = pCallback;
0805         break;
0806 
0807       case HAL_HCD_MSPDEINIT_CB_ID :
0808         hhcd->MspDeInitCallback = pCallback;
0809         break;
0810 
0811       default :
0812         /* Update the error code */
0813         hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
0814         /* Return error status */
0815         status =  HAL_ERROR;
0816         break;
0817     }
0818   }
0819   else if (hhcd->State == HAL_HCD_STATE_RESET)
0820   {
0821     switch (CallbackID)
0822     {
0823       case HAL_HCD_MSPINIT_CB_ID :
0824         hhcd->MspInitCallback = pCallback;
0825         break;
0826 
0827       case HAL_HCD_MSPDEINIT_CB_ID :
0828         hhcd->MspDeInitCallback = pCallback;
0829         break;
0830 
0831       default :
0832         /* Update the error code */
0833         hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
0834         /* Return error status */
0835         status =  HAL_ERROR;
0836         break;
0837     }
0838   }
0839   else
0840   {
0841     /* Update the error code */
0842     hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
0843     /* Return error status */
0844     status =  HAL_ERROR;
0845   }
0846 
0847   /* Release Lock */
0848   __HAL_UNLOCK(hhcd);
0849   return status;
0850 }
0851 
0852 /**
0853   * @brief  Unregister an USB HCD Callback
0854   *         USB HCD callback is redirected to the weak predefined callback
0855   * @param  hhcd USB HCD handle
0856   * @param  CallbackID ID of the callback to be unregistered
0857   *         This parameter can be one of the following values:
0858   *          @arg @ref HAL_HCD_SOF_CB_ID USB HCD SOF callback ID
0859   *          @arg @ref HAL_HCD_CONNECT_CB_ID USB HCD Connect callback ID
0860   *          @arg @ref HAL_HCD_DISCONNECT_CB_ID OTG HCD Disconnect callback ID
0861   *          @arg @ref HAL_HCD_PORT_ENABLED_CB_ID USB HCD Port Enabled callback ID
0862   *          @arg @ref HAL_HCD_PORT_DISABLED_CB_ID USB HCD Port Disabled callback ID
0863   *          @arg @ref HAL_HCD_MSPINIT_CB_ID MspDeInit callback ID
0864   *          @arg @ref HAL_HCD_MSPDEINIT_CB_ID MspDeInit callback ID
0865   * @retval HAL status
0866   */
0867 HAL_StatusTypeDef HAL_HCD_UnRegisterCallback(HCD_HandleTypeDef *hhcd, HAL_HCD_CallbackIDTypeDef CallbackID)
0868 {
0869   HAL_StatusTypeDef status = HAL_OK;
0870 
0871   /* Process locked */
0872   __HAL_LOCK(hhcd);
0873 
0874   /* Setup Legacy weak Callbacks  */
0875   if (hhcd->State == HAL_HCD_STATE_READY)
0876   {
0877     switch (CallbackID)
0878     {
0879       case HAL_HCD_SOF_CB_ID :
0880         hhcd->SOFCallback = HAL_HCD_SOF_Callback;
0881         break;
0882 
0883       case HAL_HCD_CONNECT_CB_ID :
0884         hhcd->ConnectCallback = HAL_HCD_Connect_Callback;
0885         break;
0886 
0887       case HAL_HCD_DISCONNECT_CB_ID :
0888         hhcd->DisconnectCallback = HAL_HCD_Disconnect_Callback;
0889         break;
0890 
0891       case HAL_HCD_PORT_ENABLED_CB_ID :
0892         hhcd->PortEnabledCallback = HAL_HCD_PortEnabled_Callback;
0893         break;
0894 
0895       case HAL_HCD_PORT_DISABLED_CB_ID :
0896         hhcd->PortDisabledCallback = HAL_HCD_PortDisabled_Callback;
0897         break;
0898 
0899       case HAL_HCD_MSPINIT_CB_ID :
0900         hhcd->MspInitCallback = HAL_HCD_MspInit;
0901         break;
0902 
0903       case HAL_HCD_MSPDEINIT_CB_ID :
0904         hhcd->MspDeInitCallback = HAL_HCD_MspDeInit;
0905         break;
0906 
0907       default :
0908         /* Update the error code */
0909         hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
0910 
0911         /* Return error status */
0912         status =  HAL_ERROR;
0913         break;
0914     }
0915   }
0916   else if (hhcd->State == HAL_HCD_STATE_RESET)
0917   {
0918     switch (CallbackID)
0919     {
0920       case HAL_HCD_MSPINIT_CB_ID :
0921         hhcd->MspInitCallback = HAL_HCD_MspInit;
0922         break;
0923 
0924       case HAL_HCD_MSPDEINIT_CB_ID :
0925         hhcd->MspDeInitCallback = HAL_HCD_MspDeInit;
0926         break;
0927 
0928       default :
0929         /* Update the error code */
0930         hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
0931 
0932         /* Return error status */
0933         status =  HAL_ERROR;
0934         break;
0935     }
0936   }
0937   else
0938   {
0939     /* Update the error code */
0940     hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
0941 
0942     /* Return error status */
0943     status =  HAL_ERROR;
0944   }
0945 
0946   /* Release Lock */
0947   __HAL_UNLOCK(hhcd);
0948   return status;
0949 }
0950 
0951 /**
0952   * @brief  Register USB HCD Host Channel Notify URB Change Callback
0953   *         To be used instead of the weak HAL_HCD_HC_NotifyURBChange_Callback() predefined callback
0954   * @param  hhcd HCD handle
0955   * @param  pCallback pointer to the USB HCD Host Channel Notify URB Change Callback function
0956   * @retval HAL status
0957   */
0958 HAL_StatusTypeDef HAL_HCD_RegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd,
0959                                                              pHCD_HC_NotifyURBChangeCallbackTypeDef pCallback)
0960 {
0961   HAL_StatusTypeDef status = HAL_OK;
0962 
0963   if (pCallback == NULL)
0964   {
0965     /* Update the error code */
0966     hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
0967 
0968     return HAL_ERROR;
0969   }
0970 
0971   /* Process locked */
0972   __HAL_LOCK(hhcd);
0973 
0974   if (hhcd->State == HAL_HCD_STATE_READY)
0975   {
0976     hhcd->HC_NotifyURBChangeCallback = pCallback;
0977   }
0978   else
0979   {
0980     /* Update the error code */
0981     hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
0982 
0983     /* Return error status */
0984     status =  HAL_ERROR;
0985   }
0986 
0987   /* Release Lock */
0988   __HAL_UNLOCK(hhcd);
0989 
0990   return status;
0991 }
0992 
0993 /**
0994   * @brief  Unregister the USB HCD Host Channel Notify URB Change Callback
0995   *         USB HCD Host Channel Notify URB Change Callback is redirected
0996   *         to the weak HAL_HCD_HC_NotifyURBChange_Callback() predefined callback
0997   * @param  hhcd HCD handle
0998   * @retval HAL status
0999   */
1000 HAL_StatusTypeDef HAL_HCD_UnRegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd)
1001 {
1002   HAL_StatusTypeDef status = HAL_OK;
1003 
1004   /* Process locked */
1005   __HAL_LOCK(hhcd);
1006 
1007   if (hhcd->State == HAL_HCD_STATE_READY)
1008   {
1009     hhcd->HC_NotifyURBChangeCallback = HAL_HCD_HC_NotifyURBChange_Callback; /* Legacy weak DataOutStageCallback  */
1010   }
1011   else
1012   {
1013     /* Update the error code */
1014     hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
1015 
1016     /* Return error status */
1017     status =  HAL_ERROR;
1018   }
1019 
1020   /* Release Lock */
1021   __HAL_UNLOCK(hhcd);
1022 
1023   return status;
1024 }
1025 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1026 
1027 /**
1028   * @}
1029   */
1030 
1031 /** @defgroup HCD_Exported_Functions_Group3 Peripheral Control functions
1032   * @ingroup RTEMSBSPsARMSTM32H7
1033   *  @brief   Management functions
1034   *
1035 @verbatim
1036  ===============================================================================
1037                       ##### Peripheral Control functions #####
1038  ===============================================================================
1039     [..]
1040     This subsection provides a set of functions allowing to control the HCD data
1041     transfers.
1042 
1043 @endverbatim
1044   * @{
1045   */
1046 
1047 /**
1048   * @brief  Start the host driver.
1049   * @param  hhcd HCD handle
1050   * @retval HAL status
1051   */
1052 HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd)
1053 {
1054   __HAL_LOCK(hhcd);
1055   /* Enable port power */
1056   (void)USB_DriveVbus(hhcd->Instance, 1U);
1057 
1058   /* Enable global interrupt */
1059   __HAL_HCD_ENABLE(hhcd);
1060   __HAL_UNLOCK(hhcd);
1061 
1062   return HAL_OK;
1063 }
1064 
1065 /**
1066   * @brief  Stop the host driver.
1067   * @param  hhcd HCD handle
1068   * @retval HAL status
1069   */
1070 
1071 HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd)
1072 {
1073   __HAL_LOCK(hhcd);
1074   (void)USB_StopHost(hhcd->Instance);
1075   __HAL_UNLOCK(hhcd);
1076 
1077   return HAL_OK;
1078 }
1079 
1080 /**
1081   * @brief  Reset the host port.
1082   * @param  hhcd HCD handle
1083   * @retval HAL status
1084   */
1085 HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd)
1086 {
1087   return (USB_ResetPort(hhcd->Instance));
1088 }
1089 
1090 /**
1091   * @}
1092   */
1093 
1094 /** @defgroup HCD_Exported_Functions_Group4 Peripheral State functions
1095   * @ingroup RTEMSBSPsARMSTM32H7
1096   *  @brief   Peripheral State functions
1097   *
1098 @verbatim
1099  ===============================================================================
1100                       ##### Peripheral State functions #####
1101  ===============================================================================
1102     [..]
1103     This subsection permits to get in run-time the status of the peripheral
1104     and the data flow.
1105 
1106 @endverbatim
1107   * @{
1108   */
1109 
1110 /**
1111   * @brief  Return the HCD handle state.
1112   * @param  hhcd HCD handle
1113   * @retval HAL state
1114   */
1115 HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef const *hhcd)
1116 {
1117   return hhcd->State;
1118 }
1119 
1120 /**
1121   * @brief  Return  URB state for a channel.
1122   * @param  hhcd HCD handle
1123   * @param  chnum Channel number.
1124   *         This parameter can be a value from 1 to 15
1125   * @retval URB state.
1126   *          This parameter can be one of these values:
1127   *            URB_IDLE/
1128   *            URB_DONE/
1129   *            URB_NOTREADY/
1130   *            URB_NYET/
1131   *            URB_ERROR/
1132   *            URB_STALL
1133   */
1134 HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef const *hhcd, uint8_t chnum)
1135 {
1136   return hhcd->hc[chnum].urb_state;
1137 }
1138 
1139 
1140 /**
1141   * @brief  Return the last host transfer size.
1142   * @param  hhcd HCD handle
1143   * @param  chnum Channel number.
1144   *         This parameter can be a value from 1 to 15
1145   * @retval last transfer size in byte
1146   */
1147 uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef const *hhcd, uint8_t chnum)
1148 {
1149   return hhcd->hc[chnum].xfer_count;
1150 }
1151 
1152 /**
1153   * @brief  Return the Host Channel state.
1154   * @param  hhcd HCD handle
1155   * @param  chnum Channel number.
1156   *         This parameter can be a value from 1 to 15
1157   * @retval Host channel state
1158   *          This parameter can be one of these values:
1159   *            HC_IDLE/
1160   *            HC_XFRC/
1161   *            HC_HALTED/
1162   *            HC_NYET/
1163   *            HC_NAK/
1164   *            HC_STALL/
1165   *            HC_XACTERR/
1166   *            HC_BBLERR/
1167   *            HC_DATATGLERR
1168   */
1169 HCD_HCStateTypeDef  HAL_HCD_HC_GetState(HCD_HandleTypeDef const *hhcd, uint8_t chnum)
1170 {
1171   return hhcd->hc[chnum].state;
1172 }
1173 
1174 /**
1175   * @brief  Return the current Host frame number.
1176   * @param  hhcd HCD handle
1177   * @retval Current Host frame number
1178   */
1179 uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd)
1180 {
1181   return (USB_GetCurrentFrame(hhcd->Instance));
1182 }
1183 
1184 /**
1185   * @brief  Return the Host enumeration speed.
1186   * @param  hhcd HCD handle
1187   * @retval Enumeration speed
1188   */
1189 uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd)
1190 {
1191   return (USB_GetHostSpeed(hhcd->Instance));
1192 }
1193 
1194 /**
1195   * @brief  Set host channel Hub information.
1196   * @param  hhcd HCD handle
1197   * @param  ch_num Channel number.
1198   *         This parameter can be a value from 1 to 15
1199   * @param  addr Hub address
1200   * @param  PortNbr Hub port number
1201   * @retval HAL status
1202   */
1203 HAL_StatusTypeDef HAL_HCD_HC_SetHubInfo(HCD_HandleTypeDef *hhcd, uint8_t ch_num,
1204                                         uint8_t addr, uint8_t PortNbr)
1205 {
1206   uint32_t HostCoreSpeed = USB_GetHostSpeed(hhcd->Instance);
1207 
1208   /* LS/FS device plugged to HS HUB */
1209   if ((hhcd->hc[ch_num].speed != HCD_DEVICE_SPEED_HIGH) && (HostCoreSpeed == HPRT0_PRTSPD_HIGH_SPEED))
1210   {
1211     hhcd->hc[ch_num].do_ssplit = 1U;
1212 
1213     if ((hhcd->hc[ch_num].ep_type == EP_TYPE_CTRL) && (hhcd->hc[ch_num].ep_is_in != 0U))
1214     {
1215       hhcd->hc[ch_num].toggle_in = 1U;
1216     }
1217   }
1218 
1219   hhcd->hc[ch_num].hub_addr = addr;
1220   hhcd->hc[ch_num].hub_port_nbr = PortNbr;
1221 
1222   return HAL_OK;
1223 }
1224 
1225 
1226 /**
1227   * @brief  Clear host channel hub information.
1228   * @param  hhcd HCD handle
1229   * @param  ch_num Channel number.
1230   *         This parameter can be a value from 1 to 15
1231   * @retval HAL status
1232   */
1233 HAL_StatusTypeDef HAL_HCD_HC_ClearHubInfo(HCD_HandleTypeDef *hhcd, uint8_t ch_num)
1234 {
1235   hhcd->hc[ch_num].do_ssplit = 0U;
1236   hhcd->hc[ch_num].do_csplit = 0U;
1237   hhcd->hc[ch_num].hub_addr = 0U;
1238   hhcd->hc[ch_num].hub_port_nbr = 0U;
1239 
1240   return HAL_OK;
1241 }
1242 /**
1243   * @}
1244   */
1245 
1246 /**
1247   * @}
1248   */
1249 
1250 /** @addtogroup HCD_Private_Functions
1251   * @{
1252   */
1253 /**
1254   * @brief  Handle Host Channel IN interrupt requests.
1255   * @param  hhcd HCD handle
1256   * @param  chnum Channel number.
1257   *         This parameter can be a value from 1 to 15
1258   * @retval none
1259   */
1260 static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
1261 {
1262   const USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
1263   uint32_t USBx_BASE = (uint32_t)USBx;
1264   uint32_t tmpreg;
1265 
1266   if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_AHBERR))
1267   {
1268     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR);
1269     hhcd->hc[chnum].state = HC_XACTERR;
1270     (void)USB_HC_Halt(hhcd->Instance, chnum);
1271   }
1272   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_BBERR))
1273   {
1274     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_BBERR);
1275     hhcd->hc[chnum].state = HC_BBLERR;
1276     (void)USB_HC_Halt(hhcd->Instance, chnum);
1277   }
1278   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_STALL))
1279   {
1280     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL);
1281     hhcd->hc[chnum].state = HC_STALL;
1282     (void)USB_HC_Halt(hhcd->Instance, chnum);
1283   }
1284   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_DTERR))
1285   {
1286     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR);
1287     hhcd->hc[chnum].state = HC_DATATGLERR;
1288     (void)USB_HC_Halt(hhcd->Instance, chnum);
1289   }
1290   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_TXERR))
1291   {
1292     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR);
1293     hhcd->hc[chnum].state = HC_XACTERR;
1294     (void)USB_HC_Halt(hhcd->Instance, chnum);
1295   }
1296   else
1297   {
1298     /* ... */
1299   }
1300 
1301   if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_FRMOR))
1302   {
1303     (void)USB_HC_Halt(hhcd->Instance, chnum);
1304     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR);
1305   }
1306   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_XFRC))
1307   {
1308     /* Clear any pending ACK IT */
1309     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
1310 
1311     if (hhcd->hc[chnum].do_csplit == 1U)
1312     {
1313       hhcd->hc[chnum].do_csplit = 0U;
1314       __HAL_HCD_CLEAR_HC_CSPLT(chnum);
1315     }
1316 
1317     if (hhcd->Init.dma_enable != 0U)
1318     {
1319       hhcd->hc[chnum].xfer_count = hhcd->hc[chnum].XferSize - (USBx_HC(chnum)->HCTSIZ & USB_OTG_HCTSIZ_XFRSIZ);
1320     }
1321 
1322     hhcd->hc[chnum].state = HC_XFRC;
1323     hhcd->hc[chnum].ErrCnt = 0U;
1324     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC);
1325 
1326     if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) ||
1327         (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
1328     {
1329       (void)USB_HC_Halt(hhcd->Instance, chnum);
1330       __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
1331     }
1332     else if ((hhcd->hc[chnum].ep_type == EP_TYPE_INTR) ||
1333              (hhcd->hc[chnum].ep_type == EP_TYPE_ISOC))
1334     {
1335       USBx_HC(chnum)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
1336       hhcd->hc[chnum].urb_state = URB_DONE;
1337 
1338 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1339       hhcd->HC_NotifyURBChangeCallback(hhcd, chnum, hhcd->hc[chnum].urb_state);
1340 #else
1341       HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
1342 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1343     }
1344     else
1345     {
1346       /* ... */
1347     }
1348 
1349     if (hhcd->Init.dma_enable == 1U)
1350     {
1351       if ((((hhcd->hc[chnum].xfer_count + hhcd->hc[chnum].max_packet - 1U) / hhcd->hc[chnum].max_packet) & 1U) != 0U)
1352       {
1353         hhcd->hc[chnum].toggle_in ^= 1U;
1354       }
1355     }
1356     else
1357     {
1358       hhcd->hc[chnum].toggle_in ^= 1U;
1359     }
1360   }
1361   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_ACK))
1362   {
1363     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
1364 
1365     if (hhcd->hc[chnum].do_ssplit == 1U)
1366     {
1367       hhcd->hc[chnum].do_csplit = 1U;
1368       hhcd->hc[chnum].state = HC_ACK;
1369 
1370       (void)USB_HC_Halt(hhcd->Instance, chnum);
1371     }
1372   }
1373   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_CHH))
1374   {
1375     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
1376 
1377     if (hhcd->hc[chnum].state == HC_XFRC)
1378     {
1379       hhcd->hc[chnum].state = HC_HALTED;
1380       hhcd->hc[chnum].urb_state = URB_DONE;
1381     }
1382     else if (hhcd->hc[chnum].state == HC_STALL)
1383     {
1384       hhcd->hc[chnum].state = HC_HALTED;
1385       hhcd->hc[chnum].urb_state = URB_STALL;
1386     }
1387     else if ((hhcd->hc[chnum].state == HC_XACTERR) ||
1388              (hhcd->hc[chnum].state == HC_DATATGLERR))
1389     {
1390       hhcd->hc[chnum].state = HC_HALTED;
1391       hhcd->hc[chnum].ErrCnt++;
1392       if (hhcd->hc[chnum].ErrCnt > 2U)
1393       {
1394         hhcd->hc[chnum].ErrCnt = 0U;
1395 
1396         if (hhcd->hc[chnum].do_ssplit == 1U)
1397         {
1398           hhcd->hc[chnum].do_csplit = 0U;
1399           hhcd->hc[chnum].ep_ss_schedule = 0U;
1400           __HAL_HCD_CLEAR_HC_CSPLT(chnum);
1401         }
1402 
1403         hhcd->hc[chnum].urb_state = URB_ERROR;
1404       }
1405       else
1406       {
1407         hhcd->hc[chnum].urb_state = URB_NOTREADY;
1408 
1409         if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) ||
1410             (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
1411         {
1412           /* re-activate the channel */
1413           tmpreg = USBx_HC(chnum)->HCCHAR;
1414           tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1415           tmpreg |= USB_OTG_HCCHAR_CHENA;
1416           USBx_HC(chnum)->HCCHAR = tmpreg;
1417         }
1418       }
1419     }
1420     else if (hhcd->hc[chnum].state == HC_NYET)
1421     {
1422       hhcd->hc[chnum].state = HC_HALTED;
1423 
1424       if (hhcd->hc[chnum].do_csplit == 1U)
1425       {
1426         if (hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
1427         {
1428           hhcd->hc[chnum].NyetErrCnt++;
1429           if (hhcd->hc[chnum].NyetErrCnt > 2U)
1430           {
1431             hhcd->hc[chnum].NyetErrCnt = 0U;
1432             hhcd->hc[chnum].do_csplit = 0U;
1433 
1434             if (hhcd->hc[chnum].ErrCnt < 3U)
1435             {
1436               hhcd->hc[chnum].ep_ss_schedule = 1U;
1437             }
1438             __HAL_HCD_CLEAR_HC_CSPLT(chnum);
1439             hhcd->hc[chnum].urb_state = URB_ERROR;
1440           }
1441           else
1442           {
1443             hhcd->hc[chnum].urb_state = URB_NOTREADY;
1444           }
1445         }
1446         else
1447         {
1448           hhcd->hc[chnum].urb_state = URB_NOTREADY;
1449         }
1450 
1451         if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) ||
1452             (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
1453         {
1454           /* re-activate the channel */
1455           tmpreg = USBx_HC(chnum)->HCCHAR;
1456           tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1457           tmpreg |= USB_OTG_HCCHAR_CHENA;
1458           USBx_HC(chnum)->HCCHAR = tmpreg;
1459         }
1460       }
1461     }
1462     else if (hhcd->hc[chnum].state == HC_ACK)
1463     {
1464       hhcd->hc[chnum].state = HC_HALTED;
1465 
1466       if (hhcd->hc[chnum].do_csplit == 1U)
1467       {
1468         hhcd->hc[chnum].urb_state = URB_NOTREADY;
1469 
1470         /* Set Complete split and re-activate the channel */
1471         USBx_HC(chnum)->HCSPLT |= USB_OTG_HCSPLT_COMPLSPLT;
1472         USBx_HC(chnum)->HCINTMSK |= USB_OTG_HCINTMSK_NYET;
1473         USBx_HC(chnum)->HCINTMSK &= ~USB_OTG_HCINT_ACK;
1474 
1475         if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) ||
1476             (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
1477         {
1478           /* re-activate the channel */
1479           tmpreg = USBx_HC(chnum)->HCCHAR;
1480           tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1481           tmpreg |= USB_OTG_HCCHAR_CHENA;
1482           USBx_HC(chnum)->HCCHAR = tmpreg;
1483         }
1484       }
1485     }
1486     else if (hhcd->hc[chnum].state == HC_NAK)
1487     {
1488       hhcd->hc[chnum].state = HC_HALTED;
1489       hhcd->hc[chnum].urb_state = URB_NOTREADY;
1490 
1491       if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) ||
1492           (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
1493       {
1494         /* re-activate the channel */
1495         tmpreg = USBx_HC(chnum)->HCCHAR;
1496         tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1497         tmpreg |= USB_OTG_HCCHAR_CHENA;
1498         USBx_HC(chnum)->HCCHAR = tmpreg;
1499       }
1500     }
1501     else if (hhcd->hc[chnum].state == HC_BBLERR)
1502     {
1503       hhcd->hc[chnum].state = HC_HALTED;
1504       hhcd->hc[chnum].ErrCnt++;
1505       hhcd->hc[chnum].urb_state = URB_ERROR;
1506     }
1507     else
1508     {
1509       if (hhcd->hc[chnum].state == HC_HALTED)
1510       {
1511         return;
1512       }
1513     }
1514 
1515 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1516     hhcd->HC_NotifyURBChangeCallback(hhcd, chnum, hhcd->hc[chnum].urb_state);
1517 #else
1518     HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
1519 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1520   }
1521   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_NYET))
1522   {
1523     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NYET);
1524     hhcd->hc[chnum].state = HC_NYET;
1525 
1526     if (hhcd->hc[chnum].do_ssplit == 0U)
1527     {
1528       hhcd->hc[chnum].ErrCnt = 0U;
1529     }
1530 
1531     (void)USB_HC_Halt(hhcd->Instance, chnum);
1532   }
1533   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_NAK))
1534   {
1535     if (hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
1536     {
1537       hhcd->hc[chnum].ErrCnt = 0U;
1538       hhcd->hc[chnum].state = HC_NAK;
1539       (void)USB_HC_Halt(hhcd->Instance, chnum);
1540     }
1541     else if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) ||
1542              (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
1543     {
1544       hhcd->hc[chnum].ErrCnt = 0U;
1545 
1546       if ((hhcd->Init.dma_enable == 0U) || (hhcd->hc[chnum].do_csplit == 1U))
1547       {
1548         hhcd->hc[chnum].state = HC_NAK;
1549         (void)USB_HC_Halt(hhcd->Instance, chnum);
1550       }
1551     }
1552     else
1553     {
1554       /* ... */
1555     }
1556 
1557     if (hhcd->hc[chnum].do_csplit == 1U)
1558     {
1559       hhcd->hc[chnum].do_csplit = 0U;
1560       __HAL_HCD_CLEAR_HC_CSPLT(chnum);
1561       __HAL_HCD_UNMASK_ACK_HC_INT(chnum);
1562     }
1563 
1564     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
1565   }
1566   else
1567   {
1568     /* ... */
1569   }
1570 }
1571 
1572 /**
1573   * @brief  Handle Host Channel OUT interrupt requests.
1574   * @param  hhcd HCD handle
1575   * @param  chnum Channel number.
1576   *         This parameter can be a value from 1 to 15
1577   * @retval none
1578   */
1579 static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
1580 {
1581   const USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
1582   uint32_t USBx_BASE = (uint32_t)USBx;
1583   uint32_t tmpreg;
1584   uint32_t num_packets;
1585 
1586   if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_AHBERR))
1587   {
1588     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR);
1589     hhcd->hc[chnum].state = HC_XACTERR;
1590     (void)USB_HC_Halt(hhcd->Instance, chnum);
1591   }
1592   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_ACK))
1593   {
1594     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
1595 
1596     if (hhcd->hc[chnum].do_ping == 1U)
1597     {
1598       hhcd->hc[chnum].do_ping = 0U;
1599       hhcd->hc[chnum].urb_state = URB_NOTREADY;
1600       hhcd->hc[chnum].state = HC_ACK;
1601       (void)USB_HC_Halt(hhcd->Instance, chnum);
1602     }
1603 
1604     if ((hhcd->hc[chnum].do_ssplit == 1U) && (hhcd->hc[chnum].do_csplit == 0U))
1605     {
1606       if (hhcd->hc[chnum].ep_type != EP_TYPE_ISOC)
1607       {
1608         hhcd->hc[chnum].do_csplit = 1U;
1609       }
1610 
1611       hhcd->hc[chnum].state = HC_ACK;
1612       (void)USB_HC_Halt(hhcd->Instance, chnum);
1613 
1614       /* reset error_count */
1615       hhcd->hc[chnum].ErrCnt = 0U;
1616     }
1617   }
1618   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_FRMOR))
1619   {
1620     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR);
1621     (void)USB_HC_Halt(hhcd->Instance, chnum);
1622   }
1623   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_XFRC))
1624   {
1625     hhcd->hc[chnum].ErrCnt = 0U;
1626 
1627     /* transaction completed with NYET state, update do ping state */
1628     if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_NYET))
1629     {
1630       hhcd->hc[chnum].do_ping = 1U;
1631       __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NYET);
1632     }
1633 
1634     if (hhcd->hc[chnum].do_csplit != 0U)
1635     {
1636       hhcd->hc[chnum].do_csplit = 0U;
1637       __HAL_HCD_CLEAR_HC_CSPLT(chnum);
1638     }
1639 
1640     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC);
1641     hhcd->hc[chnum].state = HC_XFRC;
1642     (void)USB_HC_Halt(hhcd->Instance, chnum);
1643   }
1644   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_NYET))
1645   {
1646     hhcd->hc[chnum].state = HC_NYET;
1647 
1648     if (hhcd->hc[chnum].do_ssplit == 0U)
1649     {
1650       hhcd->hc[chnum].do_ping = 1U;
1651     }
1652 
1653     hhcd->hc[chnum].ErrCnt = 0U;
1654     (void)USB_HC_Halt(hhcd->Instance, chnum);
1655     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NYET);
1656   }
1657   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_STALL))
1658   {
1659     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL);
1660     hhcd->hc[chnum].state = HC_STALL;
1661     (void)USB_HC_Halt(hhcd->Instance, chnum);
1662   }
1663   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_NAK))
1664   {
1665     hhcd->hc[chnum].ErrCnt = 0U;
1666     hhcd->hc[chnum].state = HC_NAK;
1667 
1668     if (hhcd->hc[chnum].do_ping == 0U)
1669     {
1670       if (hhcd->hc[chnum].speed == HCD_DEVICE_SPEED_HIGH)
1671       {
1672         hhcd->hc[chnum].do_ping = 1U;
1673       }
1674     }
1675 
1676     (void)USB_HC_Halt(hhcd->Instance, chnum);
1677     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
1678   }
1679   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_TXERR))
1680   {
1681     if (hhcd->Init.dma_enable == 0U)
1682     {
1683       hhcd->hc[chnum].state = HC_XACTERR;
1684       (void)USB_HC_Halt(hhcd->Instance, chnum);
1685     }
1686     else
1687     {
1688       hhcd->hc[chnum].ErrCnt++;
1689       if (hhcd->hc[chnum].ErrCnt > 2U)
1690       {
1691         hhcd->hc[chnum].ErrCnt = 0U;
1692         hhcd->hc[chnum].urb_state = URB_ERROR;
1693 
1694 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1695         hhcd->HC_NotifyURBChangeCallback(hhcd, chnum, hhcd->hc[chnum].urb_state);
1696 #else
1697         HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
1698 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1699       }
1700       else
1701       {
1702         hhcd->hc[chnum].urb_state = URB_NOTREADY;
1703       }
1704     }
1705     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR);
1706   }
1707   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_DTERR))
1708   {
1709     hhcd->hc[chnum].state = HC_DATATGLERR;
1710     (void)USB_HC_Halt(hhcd->Instance, chnum);
1711     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR);
1712   }
1713   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_CHH))
1714   {
1715     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
1716 
1717     if (hhcd->hc[chnum].state == HC_XFRC)
1718     {
1719       hhcd->hc[chnum].state = HC_HALTED;
1720       hhcd->hc[chnum].urb_state = URB_DONE;
1721 
1722       if ((hhcd->hc[chnum].ep_type == EP_TYPE_BULK) ||
1723           (hhcd->hc[chnum].ep_type == EP_TYPE_INTR))
1724       {
1725         if (hhcd->Init.dma_enable == 0U)
1726         {
1727           hhcd->hc[chnum].toggle_out ^= 1U;
1728         }
1729 
1730         if ((hhcd->Init.dma_enable == 1U) && (hhcd->hc[chnum].xfer_len > 0U))
1731         {
1732           num_packets = (hhcd->hc[chnum].xfer_len + hhcd->hc[chnum].max_packet - 1U) / hhcd->hc[chnum].max_packet;
1733 
1734           if ((num_packets & 1U) != 0U)
1735           {
1736             hhcd->hc[chnum].toggle_out ^= 1U;
1737           }
1738         }
1739       }
1740     }
1741     else if (hhcd->hc[chnum].state == HC_ACK)
1742     {
1743       hhcd->hc[chnum].state = HC_HALTED;
1744 
1745       if (hhcd->hc[chnum].do_csplit == 1U)
1746       {
1747         hhcd->hc[chnum].urb_state = URB_NOTREADY;
1748       }
1749     }
1750     else if (hhcd->hc[chnum].state == HC_NAK)
1751     {
1752       hhcd->hc[chnum].state = HC_HALTED;
1753       hhcd->hc[chnum].urb_state = URB_NOTREADY;
1754 
1755       if (hhcd->hc[chnum].do_csplit == 1U)
1756       {
1757         hhcd->hc[chnum].do_csplit = 0U;
1758         __HAL_HCD_CLEAR_HC_CSPLT(chnum);
1759       }
1760     }
1761     else if (hhcd->hc[chnum].state == HC_NYET)
1762     {
1763       hhcd->hc[chnum].state = HC_HALTED;
1764       hhcd->hc[chnum].urb_state  = URB_NOTREADY;
1765     }
1766     else if (hhcd->hc[chnum].state == HC_STALL)
1767     {
1768       hhcd->hc[chnum].state = HC_HALTED;
1769       hhcd->hc[chnum].urb_state  = URB_STALL;
1770     }
1771     else if ((hhcd->hc[chnum].state == HC_XACTERR) ||
1772              (hhcd->hc[chnum].state == HC_DATATGLERR))
1773     {
1774       hhcd->hc[chnum].state = HC_HALTED;
1775       hhcd->hc[chnum].ErrCnt++;
1776       if (hhcd->hc[chnum].ErrCnt > 2U)
1777       {
1778         hhcd->hc[chnum].ErrCnt = 0U;
1779         hhcd->hc[chnum].urb_state = URB_ERROR;
1780       }
1781       else
1782       {
1783         hhcd->hc[chnum].urb_state = URB_NOTREADY;
1784 
1785         /* re-activate the channel  */
1786         tmpreg = USBx_HC(chnum)->HCCHAR;
1787         tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1788         tmpreg |= USB_OTG_HCCHAR_CHENA;
1789         USBx_HC(chnum)->HCCHAR = tmpreg;
1790       }
1791     }
1792     else
1793     {
1794       return;
1795     }
1796 
1797 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1798     hhcd->HC_NotifyURBChangeCallback(hhcd, chnum, hhcd->hc[chnum].urb_state);
1799 #else
1800     HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
1801 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1802   }
1803   else
1804   {
1805     return;
1806   }
1807 }
1808 
1809 /**
1810   * @brief  Handle Rx Queue Level interrupt requests.
1811   * @param  hhcd HCD handle
1812   * @retval none
1813   */
1814 static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd)
1815 {
1816   const USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
1817   uint32_t USBx_BASE = (uint32_t)USBx;
1818   uint32_t pktsts;
1819   uint32_t pktcnt;
1820   uint32_t GrxstspReg;
1821   uint32_t xferSizePktCnt;
1822   uint32_t tmpreg;
1823   uint32_t chnum;
1824 
1825   GrxstspReg = hhcd->Instance->GRXSTSP;
1826   chnum = GrxstspReg & USB_OTG_GRXSTSP_EPNUM;
1827   pktsts = (GrxstspReg & USB_OTG_GRXSTSP_PKTSTS) >> 17;
1828   pktcnt = (GrxstspReg & USB_OTG_GRXSTSP_BCNT) >> 4;
1829 
1830   switch (pktsts)
1831   {
1832     case GRXSTS_PKTSTS_IN:
1833       /* Read the data into the host buffer. */
1834       if ((pktcnt > 0U) && (hhcd->hc[chnum].xfer_buff != (void *)0))
1835       {
1836         if ((hhcd->hc[chnum].xfer_count + pktcnt) <= hhcd->hc[chnum].xfer_len)
1837         {
1838           (void)USB_ReadPacket(hhcd->Instance,
1839                                hhcd->hc[chnum].xfer_buff, (uint16_t)pktcnt);
1840 
1841           /* manage multiple Xfer */
1842           hhcd->hc[chnum].xfer_buff += pktcnt;
1843           hhcd->hc[chnum].xfer_count += pktcnt;
1844 
1845           /* get transfer size packet count */
1846           xferSizePktCnt = (USBx_HC(chnum)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) >> 19;
1847 
1848           if ((hhcd->hc[chnum].max_packet == pktcnt) && (xferSizePktCnt > 0U))
1849           {
1850             /* re-activate the channel when more packets are expected */
1851             tmpreg = USBx_HC(chnum)->HCCHAR;
1852             tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1853             tmpreg |= USB_OTG_HCCHAR_CHENA;
1854             USBx_HC(chnum)->HCCHAR = tmpreg;
1855             hhcd->hc[chnum].toggle_in ^= 1U;
1856           }
1857         }
1858         else
1859         {
1860           hhcd->hc[chnum].urb_state = URB_ERROR;
1861         }
1862       }
1863       break;
1864 
1865     case GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
1866       break;
1867 
1868     case GRXSTS_PKTSTS_IN_XFER_COMP:
1869     case GRXSTS_PKTSTS_CH_HALTED:
1870     default:
1871       break;
1872   }
1873 }
1874 
1875 /**
1876   * @brief  Handle Host Port interrupt requests.
1877   * @param  hhcd HCD handle
1878   * @retval None
1879   */
1880 static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd)
1881 {
1882   const USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
1883   uint32_t USBx_BASE = (uint32_t)USBx;
1884   __IO uint32_t hprt0;
1885   __IO uint32_t hprt0_dup;
1886 
1887   /* Handle Host Port Interrupts */
1888   hprt0 = USBx_HPRT0;
1889   hprt0_dup = USBx_HPRT0;
1890 
1891   hprt0_dup &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET | \
1892                  USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
1893 
1894   /* Check whether Port Connect detected */
1895   if ((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET)
1896   {
1897     if ((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS)
1898     {
1899 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1900       hhcd->ConnectCallback(hhcd);
1901 #else
1902       HAL_HCD_Connect_Callback(hhcd);
1903 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1904     }
1905     hprt0_dup |= USB_OTG_HPRT_PCDET;
1906   }
1907 
1908   /* Check whether Port Enable Changed */
1909   if ((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG)
1910   {
1911     hprt0_dup |= USB_OTG_HPRT_PENCHNG;
1912 
1913     if ((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA)
1914     {
1915       if (hhcd->Init.phy_itface == USB_OTG_EMBEDDED_PHY)
1916       {
1917         if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17))
1918         {
1919           (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_6_MHZ);
1920         }
1921         else
1922         {
1923           (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_48_MHZ);
1924         }
1925       }
1926       else
1927       {
1928         if (hhcd->Init.speed == HCD_SPEED_FULL)
1929         {
1930           USBx_HOST->HFIR = HFIR_60_MHZ;
1931         }
1932       }
1933 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1934       hhcd->PortEnabledCallback(hhcd);
1935 #else
1936       HAL_HCD_PortEnabled_Callback(hhcd);
1937 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1938 
1939     }
1940     else
1941     {
1942 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1943       hhcd->PortDisabledCallback(hhcd);
1944 #else
1945       HAL_HCD_PortDisabled_Callback(hhcd);
1946 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1947     }
1948   }
1949 
1950   /* Check for an overcurrent */
1951   if ((hprt0 & USB_OTG_HPRT_POCCHNG) == USB_OTG_HPRT_POCCHNG)
1952   {
1953     hprt0_dup |= USB_OTG_HPRT_POCCHNG;
1954   }
1955 
1956   /* Clear Port Interrupts */
1957   USBx_HPRT0 = hprt0_dup;
1958 }
1959 
1960 /**
1961   * @}
1962   */
1963 
1964 /**
1965   * @}
1966   */
1967 
1968 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
1969 #endif /* HAL_HCD_MODULE_ENABLED */
1970 
1971 /**
1972   * @}
1973   */
1974 
1975 /**
1976   * @}
1977   */