Subversion Repositories canSerial

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /**
  2.   ******************************************************************************
  3.   * @file    stm32f1xx_hal_hcd.c
  4.   * @author  MCD Application Team
  5.   * @brief   HCD HAL module driver.
  6.   *          This file provides firmware functions to manage the following
  7.   *          functionalities of the USB Peripheral Controller:
  8.   *           + Initialization and de-initialization functions
  9.   *           + IO operation functions
  10.   *           + Peripheral Control functions
  11.   *           + Peripheral State functions
  12.   *
  13.   ******************************************************************************
  14.   * @attention
  15.   *
  16.   * Copyright (c) 2016 STMicroelectronics.
  17.   * All rights reserved.
  18.   *
  19.   * This software is licensed under terms that can be found in the LICENSE file
  20.   * in the root directory of this software component.
  21.   * If no LICENSE file comes with this software, it is provided AS-IS.
  22.   *
  23.   ******************************************************************************
  24.   @verbatim
  25.   ==============================================================================
  26.                     ##### How to use this driver #####
  27.   ==============================================================================
  28.   [..]
  29.     (#)Declare a HCD_HandleTypeDef handle structure, for example:
  30.        HCD_HandleTypeDef  hhcd;
  31.  
  32.     (#)Fill parameters of Init structure in HCD handle
  33.  
  34.     (#)Call HAL_HCD_Init() API to initialize the HCD peripheral (Core, Host core, ...)
  35.  
  36.     (#)Initialize the HCD low level resources through the HAL_HCD_MspInit() API:
  37.         (##) Enable the HCD/USB Low Level interface clock using the following macros
  38.              (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
  39.         (##) Initialize the related GPIO clocks
  40.         (##) Configure HCD pin-out
  41.         (##) Configure HCD NVIC interrupt
  42.  
  43.     (#)Associate the Upper USB Host stack to the HAL HCD Driver:
  44.         (##) hhcd.pData = phost;
  45.  
  46.     (#)Enable HCD transmission and reception:
  47.         (##) HAL_HCD_Start();
  48.  
  49.   @endverbatim
  50.   ******************************************************************************
  51.   */
  52.  
  53. /* Includes ------------------------------------------------------------------*/
  54. #include "stm32f1xx_hal.h"
  55.  
  56. /** @addtogroup STM32F1xx_HAL_Driver
  57.   * @{
  58.   */
  59.  
  60. #ifdef HAL_HCD_MODULE_ENABLED
  61. #if defined (USB_OTG_FS)
  62.  
  63. /** @defgroup HCD HCD
  64.   * @brief HCD HAL module driver
  65.   * @{
  66.   */
  67.  
  68. /* Private typedef -----------------------------------------------------------*/
  69. /* Private define ------------------------------------------------------------*/
  70. /* Private macro -------------------------------------------------------------*/
  71. /* Private variables ---------------------------------------------------------*/
  72. /* Private function prototypes -----------------------------------------------*/
  73. /** @defgroup HCD_Private_Functions HCD Private Functions
  74.   * @{
  75.   */
  76. static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
  77. static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
  78. static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd);
  79. static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd);
  80. /**
  81.   * @}
  82.   */
  83.  
  84. /* Exported functions --------------------------------------------------------*/
  85. /** @defgroup HCD_Exported_Functions HCD Exported Functions
  86.   * @{
  87.   */
  88.  
  89. /** @defgroup HCD_Exported_Functions_Group1 Initialization and de-initialization functions
  90.   *  @brief    Initialization and Configuration functions
  91.   *
  92. @verbatim
  93.  ===============================================================================
  94.           ##### Initialization and de-initialization functions #####
  95.  ===============================================================================
  96.     [..]  This section provides functions allowing to:
  97.  
  98. @endverbatim
  99.   * @{
  100.   */
  101.  
  102. /**
  103.   * @brief  Initialize the host driver.
  104.   * @param  hhcd HCD handle
  105.   * @retval HAL status
  106.   */
  107. HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd)
  108. {
  109.   USB_OTG_GlobalTypeDef *USBx;
  110.  
  111.   /* Check the HCD handle allocation */
  112.   if (hhcd == NULL)
  113.   {
  114.     return HAL_ERROR;
  115.   }
  116.  
  117.   /* Check the parameters */
  118.   assert_param(IS_HCD_ALL_INSTANCE(hhcd->Instance));
  119.  
  120.   USBx = hhcd->Instance;
  121.  
  122.   if (hhcd->State == HAL_HCD_STATE_RESET)
  123.   {
  124.     /* Allocate lock resource and initialize it */
  125.     hhcd->Lock = HAL_UNLOCKED;
  126.  
  127. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  128.     hhcd->SOFCallback = HAL_HCD_SOF_Callback;
  129.     hhcd->ConnectCallback = HAL_HCD_Connect_Callback;
  130.     hhcd->DisconnectCallback = HAL_HCD_Disconnect_Callback;
  131.     hhcd->PortEnabledCallback = HAL_HCD_PortEnabled_Callback;
  132.     hhcd->PortDisabledCallback = HAL_HCD_PortDisabled_Callback;
  133.     hhcd->HC_NotifyURBChangeCallback = HAL_HCD_HC_NotifyURBChange_Callback;
  134.  
  135.     if (hhcd->MspInitCallback == NULL)
  136.     {
  137.       hhcd->MspInitCallback = HAL_HCD_MspInit;
  138.     }
  139.  
  140.     /* Init the low level hardware */
  141.     hhcd->MspInitCallback(hhcd);
  142. #else
  143.     /* Init the low level hardware : GPIO, CLOCK, NVIC... */
  144.     HAL_HCD_MspInit(hhcd);
  145. #endif /* (USE_HAL_HCD_REGISTER_CALLBACKS) */
  146.   }
  147.  
  148.   hhcd->State = HAL_HCD_STATE_BUSY;
  149.  
  150.   /* Disable DMA mode for FS instance */
  151.   if ((USBx->CID & (0x1U << 8)) == 0U)
  152.   {
  153.     hhcd->Init.dma_enable = 0U;
  154.   }
  155.  
  156.   /* Disable the Interrupts */
  157.   __HAL_HCD_DISABLE(hhcd);
  158.  
  159.   /* Init the Core (common init.) */
  160.   (void)USB_CoreInit(hhcd->Instance, hhcd->Init);
  161.  
  162.   /* Force Host Mode*/
  163.   (void)USB_SetCurrentMode(hhcd->Instance, USB_HOST_MODE);
  164.  
  165.   /* Init Host */
  166.   (void)USB_HostInit(hhcd->Instance, hhcd->Init);
  167.  
  168.   hhcd->State = HAL_HCD_STATE_READY;
  169.  
  170.   return HAL_OK;
  171. }
  172.  
  173. /**
  174.   * @brief  Initialize a host channel.
  175.   * @param  hhcd HCD handle
  176.   * @param  ch_num Channel number.
  177.   *         This parameter can be a value from 1 to 15
  178.   * @param  epnum Endpoint number.
  179.   *          This parameter can be a value from 1 to 15
  180.   * @param  dev_address Current device address
  181.   *          This parameter can be a value from 0 to 255
  182.   * @param  speed Current device speed.
  183.   *          This parameter can be one of these values:
  184.   *            HCD_DEVICE_SPEED_FULL: Full speed mode,
  185.   *            HCD_DEVICE_SPEED_LOW: Low speed mode
  186.   * @param  ep_type Endpoint Type.
  187.   *          This parameter can be one of these values:
  188.   *            EP_TYPE_CTRL: Control type,
  189.   *            EP_TYPE_ISOC: Isochronous type,
  190.   *            EP_TYPE_BULK: Bulk type,
  191.   *            EP_TYPE_INTR: Interrupt type
  192.   * @param  mps Max Packet Size.
  193.   *          This parameter can be a value from 0 to32K
  194.   * @retval HAL status
  195.   */
  196. HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd, uint8_t ch_num, uint8_t epnum,
  197.                                   uint8_t dev_address, uint8_t speed, uint8_t ep_type, uint16_t mps)
  198. {
  199.   HAL_StatusTypeDef status;
  200.   uint32_t HCcharMps = mps;
  201.  
  202.   __HAL_LOCK(hhcd);
  203.   hhcd->hc[ch_num].do_ping = 0U;
  204.   hhcd->hc[ch_num].dev_addr = dev_address;
  205.   hhcd->hc[ch_num].ch_num = ch_num;
  206.   hhcd->hc[ch_num].ep_type = ep_type;
  207.   hhcd->hc[ch_num].ep_num = epnum & 0x7FU;
  208.  
  209.   (void)HAL_HCD_HC_ClearHubInfo(hhcd, ch_num);
  210.  
  211.   if ((epnum & 0x80U) == 0x80U)
  212.   {
  213.     hhcd->hc[ch_num].ep_is_in = 1U;
  214.   }
  215.   else
  216.   {
  217.     hhcd->hc[ch_num].ep_is_in = 0U;
  218.   }
  219.  
  220.   hhcd->hc[ch_num].speed = speed;
  221.   hhcd->hc[ch_num].max_packet = (uint16_t)HCcharMps;
  222.  
  223.   status =  USB_HC_Init(hhcd->Instance, ch_num, epnum,
  224.                         dev_address, speed, ep_type, (uint16_t)HCcharMps);
  225.  
  226.   __HAL_UNLOCK(hhcd);
  227.  
  228.   return status;
  229. }
  230.  
  231. /**
  232.   * @brief  Halt a host channel.
  233.   * @param  hhcd HCD handle
  234.   * @param  ch_num Channel number.
  235.   *         This parameter can be a value from 1 to 15
  236.   * @retval HAL status
  237.   */
  238. HAL_StatusTypeDef HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd, uint8_t ch_num)
  239. {
  240.   HAL_StatusTypeDef status = HAL_OK;
  241.  
  242.   __HAL_LOCK(hhcd);
  243.   (void)USB_HC_Halt(hhcd->Instance, ch_num);
  244.   __HAL_UNLOCK(hhcd);
  245.  
  246.   return status;
  247. }
  248.  
  249. /**
  250.   * @brief  DeInitialize the host driver.
  251.   * @param  hhcd HCD handle
  252.   * @retval HAL status
  253.   */
  254. HAL_StatusTypeDef HAL_HCD_DeInit(HCD_HandleTypeDef *hhcd)
  255. {
  256.   /* Check the HCD handle allocation */
  257.   if (hhcd == NULL)
  258.   {
  259.     return HAL_ERROR;
  260.   }
  261.  
  262.   hhcd->State = HAL_HCD_STATE_BUSY;
  263.  
  264. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  265.   if (hhcd->MspDeInitCallback == NULL)
  266.   {
  267.     hhcd->MspDeInitCallback = HAL_HCD_MspDeInit; /* Legacy weak MspDeInit  */
  268.   }
  269.  
  270.   /* DeInit the low level hardware */
  271.   hhcd->MspDeInitCallback(hhcd);
  272. #else
  273.   /* DeInit the low level hardware: CLOCK, NVIC.*/
  274.   HAL_HCD_MspDeInit(hhcd);
  275. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  276.  
  277.   __HAL_HCD_DISABLE(hhcd);
  278.  
  279.   hhcd->State = HAL_HCD_STATE_RESET;
  280.  
  281.   return HAL_OK;
  282. }
  283.  
  284. /**
  285.   * @brief  Initialize the HCD MSP.
  286.   * @param  hhcd HCD handle
  287.   * @retval None
  288.   */
  289. __weak void  HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd)
  290. {
  291.   /* Prevent unused argument(s) compilation warning */
  292.   UNUSED(hhcd);
  293.  
  294.   /* NOTE : This function should not be modified, when the callback is needed,
  295.             the HAL_HCD_MspInit could be implemented in the user file
  296.    */
  297. }
  298.  
  299. /**
  300.   * @brief  DeInitialize the HCD MSP.
  301.   * @param  hhcd HCD handle
  302.   * @retval None
  303.   */
  304. __weak void  HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd)
  305. {
  306.   /* Prevent unused argument(s) compilation warning */
  307.   UNUSED(hhcd);
  308.  
  309.   /* NOTE : This function should not be modified, when the callback is needed,
  310.             the HAL_HCD_MspDeInit could be implemented in the user file
  311.    */
  312. }
  313.  
  314. /**
  315.   * @}
  316.   */
  317.  
  318. /** @defgroup HCD_Exported_Functions_Group2 Input and Output operation functions
  319.   *  @brief   HCD IO operation functions
  320.   *
  321. @verbatim
  322.  ===============================================================================
  323.                       ##### IO operation functions #####
  324.  ===============================================================================
  325.  [..] This subsection provides a set of functions allowing to manage the USB Host Data
  326.     Transfer
  327.  
  328. @endverbatim
  329.   * @{
  330.   */
  331.  
  332. /**
  333.   * @brief  Submit a new URB for processing.
  334.   * @param  hhcd HCD handle
  335.   * @param  ch_num Channel number.
  336.   *         This parameter can be a value from 1 to 15
  337.   * @param  direction Channel number.
  338.   *          This parameter can be one of these values:
  339.   *           0 : Output / 1 : Input
  340.   * @param  ep_type Endpoint Type.
  341.   *          This parameter can be one of these values:
  342.   *            EP_TYPE_CTRL: Control type/
  343.   *            EP_TYPE_ISOC: Isochronous type/
  344.   *            EP_TYPE_BULK: Bulk type/
  345.   *            EP_TYPE_INTR: Interrupt type/
  346.   * @param  token Endpoint Type.
  347.   *          This parameter can be one of these values:
  348.   *            0: HC_PID_SETUP / 1: HC_PID_DATA1
  349.   * @param  pbuff pointer to URB data
  350.   * @param  length Length of URB data
  351.   * @param  do_ping activate do ping protocol (for high speed only).
  352.   *          This parameter can be one of these values:
  353.   *           0 : do ping inactive / 1 : do ping active
  354.   * @retval HAL status
  355.   */
  356. HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd,
  357.                                            uint8_t ch_num,
  358.                                            uint8_t direction,
  359.                                            uint8_t ep_type,
  360.                                            uint8_t token,
  361.                                            uint8_t *pbuff,
  362.                                            uint16_t length,
  363.                                            uint8_t do_ping)
  364. {
  365.   hhcd->hc[ch_num].ep_is_in = direction;
  366.   hhcd->hc[ch_num].ep_type  = ep_type;
  367.  
  368.   if (token == 0U)
  369.   {
  370.     hhcd->hc[ch_num].data_pid = HC_PID_SETUP;
  371.     hhcd->hc[ch_num].do_ping = do_ping;
  372.   }
  373.   else
  374.   {
  375.     hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
  376.   }
  377.  
  378.   /* Manage Data Toggle */
  379.   switch (ep_type)
  380.   {
  381.     case EP_TYPE_CTRL:
  382.       if (token == 1U) /* send data */
  383.       {
  384.         if (direction == 0U)
  385.         {
  386.           if (length == 0U)
  387.           {
  388.             /* For Status OUT stage, Length == 0U, Status Out PID = 1 */
  389.             hhcd->hc[ch_num].toggle_out = 1U;
  390.           }
  391.  
  392.           /* Set the Data Toggle bit as per the Flag */
  393.           if (hhcd->hc[ch_num].toggle_out == 0U)
  394.           {
  395.             /* Put the PID 0 */
  396.             hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  397.           }
  398.           else
  399.           {
  400.             /* Put the PID 1 */
  401.             hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
  402.           }
  403.         }
  404.       }
  405.       break;
  406.  
  407.     case EP_TYPE_BULK:
  408.       if (direction == 0U)
  409.       {
  410.         /* Set the Data Toggle bit as per the Flag */
  411.         if (hhcd->hc[ch_num].toggle_out == 0U)
  412.         {
  413.           /* Put the PID 0 */
  414.           hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  415.         }
  416.         else
  417.         {
  418.           /* Put the PID 1 */
  419.           hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
  420.         }
  421.       }
  422.       else
  423.       {
  424.         if (hhcd->hc[ch_num].toggle_in == 0U)
  425.         {
  426.           hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  427.         }
  428.         else
  429.         {
  430.           hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
  431.         }
  432.       }
  433.  
  434.       break;
  435.     case EP_TYPE_INTR:
  436.       if (direction == 0U)
  437.       {
  438.         /* Set the Data Toggle bit as per the Flag */
  439.         if (hhcd->hc[ch_num].toggle_out == 0U)
  440.         {
  441.           /* Put the PID 0 */
  442.           hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  443.         }
  444.         else
  445.         {
  446.           /* Put the PID 1 */
  447.           hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
  448.         }
  449.       }
  450.       else
  451.       {
  452.         if (hhcd->hc[ch_num].toggle_in == 0U)
  453.         {
  454.           hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  455.         }
  456.         else
  457.         {
  458.           hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
  459.         }
  460.       }
  461.       break;
  462.  
  463.     case EP_TYPE_ISOC:
  464.       hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  465.       break;
  466.  
  467.     default:
  468.       break;
  469.   }
  470.  
  471.   hhcd->hc[ch_num].xfer_buff = pbuff;
  472.   hhcd->hc[ch_num].xfer_len  = length;
  473.   hhcd->hc[ch_num].urb_state = URB_IDLE;
  474.   hhcd->hc[ch_num].xfer_count = 0U;
  475.   hhcd->hc[ch_num].ch_num = ch_num;
  476.   hhcd->hc[ch_num].state = HC_IDLE;
  477.  
  478.   return USB_HC_StartXfer(hhcd->Instance, &hhcd->hc[ch_num]);
  479. }
  480.  
  481. /**
  482.   * @brief  Handle HCD interrupt request.
  483.   * @param  hhcd HCD handle
  484.   * @retval None
  485.   */
  486. void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd)
  487. {
  488.   USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
  489.   uint32_t USBx_BASE = (uint32_t)USBx;
  490.   uint32_t i;
  491.   uint32_t interrupt;
  492.  
  493.   /* Ensure that we are in device mode */
  494.   if (USB_GetMode(hhcd->Instance) == USB_OTG_MODE_HOST)
  495.   {
  496.     /* Avoid spurious interrupt */
  497.     if (__HAL_HCD_IS_INVALID_INTERRUPT(hhcd))
  498.     {
  499.       return;
  500.     }
  501.  
  502.     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
  503.     {
  504.       /* Incorrect mode, acknowledge the interrupt */
  505.       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
  506.     }
  507.  
  508.     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR))
  509.     {
  510.       /* Incorrect mode, acknowledge the interrupt */
  511.       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR);
  512.     }
  513.  
  514.     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE))
  515.     {
  516.       /* Incorrect mode, acknowledge the interrupt */
  517.       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE);
  518.     }
  519.  
  520.     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_MMIS))
  521.     {
  522.       /* Incorrect mode, acknowledge the interrupt */
  523.       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_MMIS);
  524.     }
  525.  
  526.     /* Handle Host Disconnect Interrupts */
  527.     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT))
  528.     {
  529.       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT);
  530.  
  531.       if ((USBx_HPRT0 & USB_OTG_HPRT_PCSTS) == 0U)
  532.       {
  533.         /* Flush USB Fifo */
  534.         (void)USB_FlushTxFifo(USBx, 0x10U);
  535.         (void)USB_FlushRxFifo(USBx);
  536.  
  537.         if (hhcd->Init.phy_itface == USB_OTG_EMBEDDED_PHY)
  538.         {
  539.           /* Restore FS Clock */
  540.           (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_48_MHZ);
  541.         }
  542.  
  543.         /* Handle Host Port Disconnect Interrupt */
  544. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  545.         hhcd->DisconnectCallback(hhcd);
  546. #else
  547.         HAL_HCD_Disconnect_Callback(hhcd);
  548. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  549.       }
  550.     }
  551.  
  552.     /* Handle Host Port Interrupts */
  553.     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HPRTINT))
  554.     {
  555.       HCD_Port_IRQHandler(hhcd);
  556.     }
  557.  
  558.     /* Handle Host SOF Interrupt */
  559.     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_SOF))
  560.     {
  561. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  562.       hhcd->SOFCallback(hhcd);
  563. #else
  564.       HAL_HCD_SOF_Callback(hhcd);
  565. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  566.  
  567.       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_SOF);
  568.     }
  569.  
  570.     /* Handle Host channel Interrupt */
  571.     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HCINT))
  572.     {
  573.       interrupt = USB_HC_ReadInterrupt(hhcd->Instance);
  574.       for (i = 0U; i < hhcd->Init.Host_channels; i++)
  575.       {
  576.         if ((interrupt & (1UL << (i & 0xFU))) != 0U)
  577.         {
  578.           if ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_EPDIR) == USB_OTG_HCCHAR_EPDIR)
  579.           {
  580.             HCD_HC_IN_IRQHandler(hhcd, (uint8_t)i);
  581.           }
  582.           else
  583.           {
  584.             HCD_HC_OUT_IRQHandler(hhcd, (uint8_t)i);
  585.           }
  586.         }
  587.       }
  588.       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_HCINT);
  589.     }
  590.  
  591.     /* Handle Rx Queue Level Interrupts */
  592.     if ((__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_RXFLVL)) != 0U)
  593.     {
  594.       USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
  595.  
  596.       HCD_RXQLVL_IRQHandler(hhcd);
  597.  
  598.       USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
  599.     }
  600.   }
  601. }
  602.  
  603.  
  604. /**
  605.   * @brief  Handles HCD Wakeup interrupt request.
  606.   * @param  hhcd HCD handle
  607.   * @retval HAL status
  608.   */
  609. void HAL_HCD_WKUP_IRQHandler(HCD_HandleTypeDef *hhcd)
  610. {
  611.   UNUSED(hhcd);
  612. }
  613.  
  614.  
  615. /**
  616.   * @brief  SOF callback.
  617.   * @param  hhcd HCD handle
  618.   * @retval None
  619.   */
  620. __weak void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd)
  621. {
  622.   /* Prevent unused argument(s) compilation warning */
  623.   UNUSED(hhcd);
  624.  
  625.   /* NOTE : This function should not be modified, when the callback is needed,
  626.             the HAL_HCD_SOF_Callback could be implemented in the user file
  627.    */
  628. }
  629.  
  630. /**
  631.   * @brief Connection Event callback.
  632.   * @param  hhcd HCD handle
  633.   * @retval None
  634.   */
  635. __weak void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
  636. {
  637.   /* Prevent unused argument(s) compilation warning */
  638.   UNUSED(hhcd);
  639.  
  640.   /* NOTE : This function should not be modified, when the callback is needed,
  641.             the HAL_HCD_Connect_Callback could be implemented in the user file
  642.    */
  643. }
  644.  
  645. /**
  646.   * @brief  Disconnection Event callback.
  647.   * @param  hhcd HCD handle
  648.   * @retval None
  649.   */
  650. __weak void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
  651. {
  652.   /* Prevent unused argument(s) compilation warning */
  653.   UNUSED(hhcd);
  654.  
  655.   /* NOTE : This function should not be modified, when the callback is needed,
  656.             the HAL_HCD_Disconnect_Callback could be implemented in the user file
  657.    */
  658. }
  659.  
  660. /**
  661.   * @brief  Port Enabled  Event callback.
  662.   * @param  hhcd HCD handle
  663.   * @retval None
  664.   */
  665. __weak void HAL_HCD_PortEnabled_Callback(HCD_HandleTypeDef *hhcd)
  666. {
  667.   /* Prevent unused argument(s) compilation warning */
  668.   UNUSED(hhcd);
  669.  
  670.   /* NOTE : This function should not be modified, when the callback is needed,
  671.             the HAL_HCD_Disconnect_Callback could be implemented in the user file
  672.    */
  673. }
  674.  
  675. /**
  676.   * @brief  Port Disabled  Event callback.
  677.   * @param  hhcd HCD handle
  678.   * @retval None
  679.   */
  680. __weak void HAL_HCD_PortDisabled_Callback(HCD_HandleTypeDef *hhcd)
  681. {
  682.   /* Prevent unused argument(s) compilation warning */
  683.   UNUSED(hhcd);
  684.  
  685.   /* NOTE : This function should not be modified, when the callback is needed,
  686.             the HAL_HCD_Disconnect_Callback could be implemented in the user file
  687.    */
  688. }
  689.  
  690. /**
  691.   * @brief  Notify URB state change callback.
  692.   * @param  hhcd HCD handle
  693.   * @param  chnum Channel number.
  694.   *         This parameter can be a value from 1 to 15
  695.   * @param  urb_state:
  696.   *          This parameter can be one of these values:
  697.   *            URB_IDLE/
  698.   *            URB_DONE/
  699.   *            URB_NOTREADY/
  700.   *            URB_NYET/
  701.   *            URB_ERROR/
  702.   *            URB_STALL/
  703.   * @retval None
  704.   */
  705. __weak void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state)
  706. {
  707.   /* Prevent unused argument(s) compilation warning */
  708.   UNUSED(hhcd);
  709.   UNUSED(chnum);
  710.   UNUSED(urb_state);
  711.  
  712.   /* NOTE : This function should not be modified, when the callback is needed,
  713.             the HAL_HCD_HC_NotifyURBChange_Callback could be implemented in the user file
  714.    */
  715. }
  716.  
  717. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  718. /**
  719.   * @brief  Register a User USB HCD Callback
  720.   *         To be used instead of the weak predefined callback
  721.   * @param  hhcd USB HCD handle
  722.   * @param  CallbackID ID of the callback to be registered
  723.   *         This parameter can be one of the following values:
  724.   *          @arg @ref HAL_HCD_SOF_CB_ID USB HCD SOF callback ID
  725.   *          @arg @ref HAL_HCD_CONNECT_CB_ID USB HCD Connect callback ID
  726.   *          @arg @ref HAL_HCD_DISCONNECT_CB_ID OTG HCD Disconnect callback ID
  727.   *          @arg @ref HAL_HCD_PORT_ENABLED_CB_ID USB HCD Port Enable callback ID
  728.   *          @arg @ref HAL_HCD_PORT_DISABLED_CB_ID USB HCD Port Disable callback ID
  729.   *          @arg @ref HAL_HCD_MSPINIT_CB_ID MspDeInit callback ID
  730.   *          @arg @ref HAL_HCD_MSPDEINIT_CB_ID MspDeInit callback ID
  731.   * @param  pCallback pointer to the Callback function
  732.   * @retval HAL status
  733.   */
  734. HAL_StatusTypeDef HAL_HCD_RegisterCallback(HCD_HandleTypeDef *hhcd,
  735.                                            HAL_HCD_CallbackIDTypeDef CallbackID,
  736.                                            pHCD_CallbackTypeDef pCallback)
  737. {
  738.   HAL_StatusTypeDef status = HAL_OK;
  739.  
  740.   if (pCallback == NULL)
  741.   {
  742.     /* Update the error code */
  743.     hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  744.     return HAL_ERROR;
  745.   }
  746.   /* Process locked */
  747.   __HAL_LOCK(hhcd);
  748.  
  749.   if (hhcd->State == HAL_HCD_STATE_READY)
  750.   {
  751.     switch (CallbackID)
  752.     {
  753.       case HAL_HCD_SOF_CB_ID :
  754.         hhcd->SOFCallback = pCallback;
  755.         break;
  756.  
  757.       case HAL_HCD_CONNECT_CB_ID :
  758.         hhcd->ConnectCallback = pCallback;
  759.         break;
  760.  
  761.       case HAL_HCD_DISCONNECT_CB_ID :
  762.         hhcd->DisconnectCallback = pCallback;
  763.         break;
  764.  
  765.       case HAL_HCD_PORT_ENABLED_CB_ID :
  766.         hhcd->PortEnabledCallback = pCallback;
  767.         break;
  768.  
  769.       case HAL_HCD_PORT_DISABLED_CB_ID :
  770.         hhcd->PortDisabledCallback = pCallback;
  771.         break;
  772.  
  773.       case HAL_HCD_MSPINIT_CB_ID :
  774.         hhcd->MspInitCallback = pCallback;
  775.         break;
  776.  
  777.       case HAL_HCD_MSPDEINIT_CB_ID :
  778.         hhcd->MspDeInitCallback = pCallback;
  779.         break;
  780.  
  781.       default :
  782.         /* Update the error code */
  783.         hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  784.         /* Return error status */
  785.         status =  HAL_ERROR;
  786.         break;
  787.     }
  788.   }
  789.   else if (hhcd->State == HAL_HCD_STATE_RESET)
  790.   {
  791.     switch (CallbackID)
  792.     {
  793.       case HAL_HCD_MSPINIT_CB_ID :
  794.         hhcd->MspInitCallback = pCallback;
  795.         break;
  796.  
  797.       case HAL_HCD_MSPDEINIT_CB_ID :
  798.         hhcd->MspDeInitCallback = pCallback;
  799.         break;
  800.  
  801.       default :
  802.         /* Update the error code */
  803.         hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  804.         /* Return error status */
  805.         status =  HAL_ERROR;
  806.         break;
  807.     }
  808.   }
  809.   else
  810.   {
  811.     /* Update the error code */
  812.     hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  813.     /* Return error status */
  814.     status =  HAL_ERROR;
  815.   }
  816.  
  817.   /* Release Lock */
  818.   __HAL_UNLOCK(hhcd);
  819.   return status;
  820. }
  821.  
  822. /**
  823.   * @brief  Unregister an USB HCD Callback
  824.   *         USB HCD callback is redirected to the weak predefined callback
  825.   * @param  hhcd USB HCD handle
  826.   * @param  CallbackID ID of the callback to be unregistered
  827.   *         This parameter can be one of the following values:
  828.   *          @arg @ref HAL_HCD_SOF_CB_ID USB HCD SOF callback ID
  829.   *          @arg @ref HAL_HCD_CONNECT_CB_ID USB HCD Connect callback ID
  830.   *          @arg @ref HAL_HCD_DISCONNECT_CB_ID OTG HCD Disconnect callback ID
  831.   *          @arg @ref HAL_HCD_PORT_ENABLED_CB_ID USB HCD Port Enabled callback ID
  832.   *          @arg @ref HAL_HCD_PORT_DISABLED_CB_ID USB HCD Port Disabled callback ID
  833.   *          @arg @ref HAL_HCD_MSPINIT_CB_ID MspDeInit callback ID
  834.   *          @arg @ref HAL_HCD_MSPDEINIT_CB_ID MspDeInit callback ID
  835.   * @retval HAL status
  836.   */
  837. HAL_StatusTypeDef HAL_HCD_UnRegisterCallback(HCD_HandleTypeDef *hhcd, HAL_HCD_CallbackIDTypeDef CallbackID)
  838. {
  839.   HAL_StatusTypeDef status = HAL_OK;
  840.  
  841.   /* Process locked */
  842.   __HAL_LOCK(hhcd);
  843.  
  844.   /* Setup Legacy weak Callbacks  */
  845.   if (hhcd->State == HAL_HCD_STATE_READY)
  846.   {
  847.     switch (CallbackID)
  848.     {
  849.       case HAL_HCD_SOF_CB_ID :
  850.         hhcd->SOFCallback = HAL_HCD_SOF_Callback;
  851.         break;
  852.  
  853.       case HAL_HCD_CONNECT_CB_ID :
  854.         hhcd->ConnectCallback = HAL_HCD_Connect_Callback;
  855.         break;
  856.  
  857.       case HAL_HCD_DISCONNECT_CB_ID :
  858.         hhcd->DisconnectCallback = HAL_HCD_Disconnect_Callback;
  859.         break;
  860.  
  861.       case HAL_HCD_PORT_ENABLED_CB_ID :
  862.         hhcd->PortEnabledCallback = HAL_HCD_PortEnabled_Callback;
  863.         break;
  864.  
  865.       case HAL_HCD_PORT_DISABLED_CB_ID :
  866.         hhcd->PortDisabledCallback = HAL_HCD_PortDisabled_Callback;
  867.         break;
  868.  
  869.       case HAL_HCD_MSPINIT_CB_ID :
  870.         hhcd->MspInitCallback = HAL_HCD_MspInit;
  871.         break;
  872.  
  873.       case HAL_HCD_MSPDEINIT_CB_ID :
  874.         hhcd->MspDeInitCallback = HAL_HCD_MspDeInit;
  875.         break;
  876.  
  877.       default :
  878.         /* Update the error code */
  879.         hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  880.  
  881.         /* Return error status */
  882.         status =  HAL_ERROR;
  883.         break;
  884.     }
  885.   }
  886.   else if (hhcd->State == HAL_HCD_STATE_RESET)
  887.   {
  888.     switch (CallbackID)
  889.     {
  890.       case HAL_HCD_MSPINIT_CB_ID :
  891.         hhcd->MspInitCallback = HAL_HCD_MspInit;
  892.         break;
  893.  
  894.       case HAL_HCD_MSPDEINIT_CB_ID :
  895.         hhcd->MspDeInitCallback = HAL_HCD_MspDeInit;
  896.         break;
  897.  
  898.       default :
  899.         /* Update the error code */
  900.         hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  901.  
  902.         /* Return error status */
  903.         status =  HAL_ERROR;
  904.         break;
  905.     }
  906.   }
  907.   else
  908.   {
  909.     /* Update the error code */
  910.     hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  911.  
  912.     /* Return error status */
  913.     status =  HAL_ERROR;
  914.   }
  915.  
  916.   /* Release Lock */
  917.   __HAL_UNLOCK(hhcd);
  918.   return status;
  919. }
  920.  
  921. /**
  922.   * @brief  Register USB HCD Host Channel Notify URB Change Callback
  923.   *         To be used instead of the weak HAL_HCD_HC_NotifyURBChange_Callback() predefined callback
  924.   * @param  hhcd HCD handle
  925.   * @param  pCallback pointer to the USB HCD Host Channel Notify URB Change Callback function
  926.   * @retval HAL status
  927.   */
  928. HAL_StatusTypeDef HAL_HCD_RegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd,
  929.                                                              pHCD_HC_NotifyURBChangeCallbackTypeDef pCallback)
  930. {
  931.   HAL_StatusTypeDef status = HAL_OK;
  932.  
  933.   if (pCallback == NULL)
  934.   {
  935.     /* Update the error code */
  936.     hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  937.  
  938.     return HAL_ERROR;
  939.   }
  940.  
  941.   /* Process locked */
  942.   __HAL_LOCK(hhcd);
  943.  
  944.   if (hhcd->State == HAL_HCD_STATE_READY)
  945.   {
  946.     hhcd->HC_NotifyURBChangeCallback = pCallback;
  947.   }
  948.   else
  949.   {
  950.     /* Update the error code */
  951.     hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  952.  
  953.     /* Return error status */
  954.     status =  HAL_ERROR;
  955.   }
  956.  
  957.   /* Release Lock */
  958.   __HAL_UNLOCK(hhcd);
  959.  
  960.   return status;
  961. }
  962.  
  963. /**
  964.   * @brief  Unregister the USB HCD Host Channel Notify URB Change Callback
  965.   *         USB HCD Host Channel Notify URB Change Callback is redirected
  966.   *         to the weak HAL_HCD_HC_NotifyURBChange_Callback() predefined callback
  967.   * @param  hhcd HCD handle
  968.   * @retval HAL status
  969.   */
  970. HAL_StatusTypeDef HAL_HCD_UnRegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd)
  971. {
  972.   HAL_StatusTypeDef status = HAL_OK;
  973.  
  974.   /* Process locked */
  975.   __HAL_LOCK(hhcd);
  976.  
  977.   if (hhcd->State == HAL_HCD_STATE_READY)
  978.   {
  979.     hhcd->HC_NotifyURBChangeCallback = HAL_HCD_HC_NotifyURBChange_Callback; /* Legacy weak DataOutStageCallback  */
  980.   }
  981.   else
  982.   {
  983.     /* Update the error code */
  984.     hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
  985.  
  986.     /* Return error status */
  987.     status =  HAL_ERROR;
  988.   }
  989.  
  990.   /* Release Lock */
  991.   __HAL_UNLOCK(hhcd);
  992.  
  993.   return status;
  994. }
  995. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  996.  
  997. /**
  998.   * @}
  999.   */
  1000.  
  1001. /** @defgroup HCD_Exported_Functions_Group3 Peripheral Control functions
  1002.   *  @brief   Management functions
  1003.   *
  1004. @verbatim
  1005.  ===============================================================================
  1006.                       ##### Peripheral Control functions #####
  1007.  ===============================================================================
  1008.     [..]
  1009.     This subsection provides a set of functions allowing to control the HCD data
  1010.     transfers.
  1011.  
  1012. @endverbatim
  1013.   * @{
  1014.   */
  1015.  
  1016. /**
  1017.   * @brief  Start the host driver.
  1018.   * @param  hhcd HCD handle
  1019.   * @retval HAL status
  1020.   */
  1021. HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd)
  1022. {
  1023.   __HAL_LOCK(hhcd);
  1024.   /* Enable port power */
  1025.   (void)USB_DriveVbus(hhcd->Instance, 1U);
  1026.  
  1027.   /* Enable global interrupt */
  1028.   __HAL_HCD_ENABLE(hhcd);
  1029.   __HAL_UNLOCK(hhcd);
  1030.  
  1031.   return HAL_OK;
  1032. }
  1033.  
  1034. /**
  1035.   * @brief  Stop the host driver.
  1036.   * @param  hhcd HCD handle
  1037.   * @retval HAL status
  1038.   */
  1039.  
  1040. HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd)
  1041. {
  1042.   __HAL_LOCK(hhcd);
  1043.   (void)USB_StopHost(hhcd->Instance);
  1044.   __HAL_UNLOCK(hhcd);
  1045.  
  1046.   return HAL_OK;
  1047. }
  1048.  
  1049. /**
  1050.   * @brief  Reset the host port.
  1051.   * @param  hhcd HCD handle
  1052.   * @retval HAL status
  1053.   */
  1054. HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd)
  1055. {
  1056.   return (USB_ResetPort(hhcd->Instance));
  1057. }
  1058.  
  1059. /**
  1060.   * @}
  1061.   */
  1062.  
  1063. /** @defgroup HCD_Exported_Functions_Group4 Peripheral State functions
  1064.   *  @brief   Peripheral State functions
  1065.   *
  1066. @verbatim
  1067.  ===============================================================================
  1068.                       ##### Peripheral State functions #####
  1069.  ===============================================================================
  1070.     [..]
  1071.     This subsection permits to get in run-time the status of the peripheral
  1072.     and the data flow.
  1073.  
  1074. @endverbatim
  1075.   * @{
  1076.   */
  1077.  
  1078. /**
  1079.   * @brief  Return the HCD handle state.
  1080.   * @param  hhcd HCD handle
  1081.   * @retval HAL state
  1082.   */
  1083. HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef const *hhcd)
  1084. {
  1085.   return hhcd->State;
  1086. }
  1087.  
  1088. /**
  1089.   * @brief  Return  URB state for a channel.
  1090.   * @param  hhcd HCD handle
  1091.   * @param  chnum Channel number.
  1092.   *         This parameter can be a value from 1 to 15
  1093.   * @retval URB state.
  1094.   *          This parameter can be one of these values:
  1095.   *            URB_IDLE/
  1096.   *            URB_DONE/
  1097.   *            URB_NOTREADY/
  1098.   *            URB_NYET/
  1099.   *            URB_ERROR/
  1100.   *            URB_STALL
  1101.   */
  1102. HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef const *hhcd, uint8_t chnum)
  1103. {
  1104.   return hhcd->hc[chnum].urb_state;
  1105. }
  1106.  
  1107.  
  1108. /**
  1109.   * @brief  Return the last host transfer size.
  1110.   * @param  hhcd HCD handle
  1111.   * @param  chnum Channel number.
  1112.   *         This parameter can be a value from 1 to 15
  1113.   * @retval last transfer size in byte
  1114.   */
  1115. uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef const *hhcd, uint8_t chnum)
  1116. {
  1117.   return hhcd->hc[chnum].xfer_count;
  1118. }
  1119.  
  1120. /**
  1121.   * @brief  Return the Host Channel state.
  1122.   * @param  hhcd HCD handle
  1123.   * @param  chnum Channel number.
  1124.   *         This parameter can be a value from 1 to 15
  1125.   * @retval Host channel state
  1126.   *          This parameter can be one of these values:
  1127.   *            HC_IDLE/
  1128.   *            HC_XFRC/
  1129.   *            HC_HALTED/
  1130.   *            HC_NYET/
  1131.   *            HC_NAK/
  1132.   *            HC_STALL/
  1133.   *            HC_XACTERR/
  1134.   *            HC_BBLERR/
  1135.   *            HC_DATATGLERR
  1136.   */
  1137. HCD_HCStateTypeDef  HAL_HCD_HC_GetState(HCD_HandleTypeDef const *hhcd, uint8_t chnum)
  1138. {
  1139.   return hhcd->hc[chnum].state;
  1140. }
  1141.  
  1142. /**
  1143.   * @brief  Return the current Host frame number.
  1144.   * @param  hhcd HCD handle
  1145.   * @retval Current Host frame number
  1146.   */
  1147. uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd)
  1148. {
  1149.   return (USB_GetCurrentFrame(hhcd->Instance));
  1150. }
  1151.  
  1152. /**
  1153.   * @brief  Return the Host enumeration speed.
  1154.   * @param  hhcd HCD handle
  1155.   * @retval Enumeration speed
  1156.   */
  1157. uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd)
  1158. {
  1159.   return (USB_GetHostSpeed(hhcd->Instance));
  1160. }
  1161.  
  1162. /**
  1163.   * @brief  Set host channel Hub information.
  1164.   * @param  hhcd HCD handle
  1165.   * @param  ch_num Channel number.
  1166.   *         This parameter can be a value from 1 to 15
  1167.   * @param  addr Hub address
  1168.   * @param  PortNbr Hub port number
  1169.   * @retval HAL status
  1170.   */
  1171. HAL_StatusTypeDef HAL_HCD_HC_SetHubInfo(HCD_HandleTypeDef *hhcd, uint8_t ch_num,
  1172.                                         uint8_t addr, uint8_t PortNbr)
  1173. {
  1174.   hhcd->hc[ch_num].hub_addr = addr;
  1175.   hhcd->hc[ch_num].hub_port_nbr = PortNbr;
  1176.  
  1177.   return HAL_OK;
  1178. }
  1179.  
  1180.  
  1181. /**
  1182.   * @brief  Clear host channel hub information.
  1183.   * @param  hhcd HCD handle
  1184.   * @param  ch_num Channel number.
  1185.   *         This parameter can be a value from 1 to 15
  1186.   * @retval HAL status
  1187.   */
  1188. HAL_StatusTypeDef HAL_HCD_HC_ClearHubInfo(HCD_HandleTypeDef *hhcd, uint8_t ch_num)
  1189. {
  1190.   hhcd->hc[ch_num].hub_addr = 0U;
  1191.   hhcd->hc[ch_num].hub_port_nbr = 0U;
  1192.  
  1193.   return HAL_OK;
  1194. }
  1195. /**
  1196.   * @}
  1197.   */
  1198.  
  1199. /**
  1200.   * @}
  1201.   */
  1202.  
  1203. /** @addtogroup HCD_Private_Functions
  1204.   * @{
  1205.   */
  1206. /**
  1207.   * @brief  Handle Host Channel IN interrupt requests.
  1208.   * @param  hhcd HCD handle
  1209.   * @param  chnum Channel number.
  1210.   *         This parameter can be a value from 1 to 15
  1211.   * @retval none
  1212.   */
  1213. static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
  1214. {
  1215.   USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
  1216.   uint32_t USBx_BASE = (uint32_t)USBx;
  1217.   uint32_t tmpreg;
  1218.  
  1219.   if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_AHBERR))
  1220.   {
  1221.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR);
  1222.     hhcd->hc[chnum].state = HC_XACTERR;
  1223.     (void)USB_HC_Halt(hhcd->Instance, chnum);
  1224.   }
  1225.   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_BBERR))
  1226.   {
  1227.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_BBERR);
  1228.     hhcd->hc[chnum].state = HC_BBLERR;
  1229.     (void)USB_HC_Halt(hhcd->Instance, chnum);
  1230.   }
  1231.   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_STALL))
  1232.   {
  1233.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL);
  1234.     hhcd->hc[chnum].state = HC_STALL;
  1235.     (void)USB_HC_Halt(hhcd->Instance, chnum);
  1236.   }
  1237.   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_DTERR))
  1238.   {
  1239.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR);
  1240.     hhcd->hc[chnum].state = HC_DATATGLERR;
  1241.     (void)USB_HC_Halt(hhcd->Instance, chnum);
  1242.   }
  1243.   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_TXERR))
  1244.   {
  1245.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR);
  1246.     hhcd->hc[chnum].state = HC_XACTERR;
  1247.     (void)USB_HC_Halt(hhcd->Instance, chnum);
  1248.   }
  1249.   else
  1250.   {
  1251.     /* ... */
  1252.   }
  1253.  
  1254.   if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_FRMOR))
  1255.   {
  1256.     (void)USB_HC_Halt(hhcd->Instance, chnum);
  1257.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR);
  1258.   }
  1259.   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_XFRC))
  1260.   {
  1261.     hhcd->hc[chnum].state = HC_XFRC;
  1262.     hhcd->hc[chnum].ErrCnt = 0U;
  1263.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC);
  1264.  
  1265.     if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) ||
  1266.         (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
  1267.     {
  1268.       (void)USB_HC_Halt(hhcd->Instance, chnum);
  1269.       __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
  1270.     }
  1271.     else if ((hhcd->hc[chnum].ep_type == EP_TYPE_INTR) ||
  1272.              (hhcd->hc[chnum].ep_type == EP_TYPE_ISOC))
  1273.     {
  1274.       USBx_HC(chnum)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
  1275.       hhcd->hc[chnum].urb_state = URB_DONE;
  1276.  
  1277. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  1278.       hhcd->HC_NotifyURBChangeCallback(hhcd, chnum, hhcd->hc[chnum].urb_state);
  1279. #else
  1280.       HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
  1281. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  1282.     }
  1283.     else
  1284.     {
  1285.       /* ... */
  1286.     }
  1287.  
  1288.     if (hhcd->Init.dma_enable == 1U)
  1289.     {
  1290.       if ((((hhcd->hc[chnum].xfer_count + hhcd->hc[chnum].max_packet - 1U) / hhcd->hc[chnum].max_packet) & 1U) != 0U)
  1291.       {
  1292.         hhcd->hc[chnum].toggle_in ^= 1U;
  1293.       }
  1294.     }
  1295.     else
  1296.     {
  1297.       hhcd->hc[chnum].toggle_in ^= 1U;
  1298.     }
  1299.   }
  1300.   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_ACK))
  1301.   {
  1302.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
  1303.   }
  1304.   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_CHH))
  1305.   {
  1306.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
  1307.  
  1308.     if (hhcd->hc[chnum].state == HC_XFRC)
  1309.     {
  1310.       hhcd->hc[chnum].state = HC_HALTED;
  1311.       hhcd->hc[chnum].urb_state = URB_DONE;
  1312.     }
  1313.     else if (hhcd->hc[chnum].state == HC_STALL)
  1314.     {
  1315.       hhcd->hc[chnum].state = HC_HALTED;
  1316.       hhcd->hc[chnum].urb_state = URB_STALL;
  1317.     }
  1318.     else if ((hhcd->hc[chnum].state == HC_XACTERR) ||
  1319.              (hhcd->hc[chnum].state == HC_DATATGLERR))
  1320.     {
  1321.       hhcd->hc[chnum].state = HC_HALTED;
  1322.       hhcd->hc[chnum].ErrCnt++;
  1323.       if (hhcd->hc[chnum].ErrCnt > 2U)
  1324.       {
  1325.         hhcd->hc[chnum].ErrCnt = 0U;
  1326.         hhcd->hc[chnum].urb_state = URB_ERROR;
  1327.       }
  1328.       else
  1329.       {
  1330.         hhcd->hc[chnum].urb_state = URB_NOTREADY;
  1331.  
  1332.         if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) ||
  1333.             (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
  1334.         {
  1335.           /* re-activate the channel */
  1336.           tmpreg = USBx_HC(chnum)->HCCHAR;
  1337.           tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  1338.           tmpreg |= USB_OTG_HCCHAR_CHENA;
  1339.           USBx_HC(chnum)->HCCHAR = tmpreg;
  1340.         }
  1341.       }
  1342.     }
  1343.     else if (hhcd->hc[chnum].state == HC_NYET)
  1344.     {
  1345.       hhcd->hc[chnum].state = HC_HALTED;
  1346.     }
  1347.     else if (hhcd->hc[chnum].state == HC_ACK)
  1348.     {
  1349.       hhcd->hc[chnum].state = HC_HALTED;
  1350.     }
  1351.     else if (hhcd->hc[chnum].state == HC_NAK)
  1352.     {
  1353.       hhcd->hc[chnum].state = HC_HALTED;
  1354.       hhcd->hc[chnum].urb_state = URB_NOTREADY;
  1355.  
  1356.       if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) ||
  1357.           (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
  1358.       {
  1359.         /* re-activate the channel */
  1360.         tmpreg = USBx_HC(chnum)->HCCHAR;
  1361.         tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  1362.         tmpreg |= USB_OTG_HCCHAR_CHENA;
  1363.         USBx_HC(chnum)->HCCHAR = tmpreg;
  1364.       }
  1365.     }
  1366.     else if (hhcd->hc[chnum].state == HC_BBLERR)
  1367.     {
  1368.       hhcd->hc[chnum].state = HC_HALTED;
  1369.       hhcd->hc[chnum].ErrCnt++;
  1370.       hhcd->hc[chnum].urb_state = URB_ERROR;
  1371.     }
  1372.     else
  1373.     {
  1374.       if (hhcd->hc[chnum].state == HC_HALTED)
  1375.       {
  1376.         return;
  1377.       }
  1378.     }
  1379.  
  1380. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  1381.     hhcd->HC_NotifyURBChangeCallback(hhcd, chnum, hhcd->hc[chnum].urb_state);
  1382. #else
  1383.     HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
  1384. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  1385.   }
  1386.   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_NYET))
  1387.   {
  1388.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NYET);
  1389.     hhcd->hc[chnum].state = HC_NYET;
  1390.     hhcd->hc[chnum].ErrCnt = 0U;
  1391.  
  1392.     (void)USB_HC_Halt(hhcd->Instance, chnum);
  1393.   }
  1394.   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_NAK))
  1395.   {
  1396.     if (hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
  1397.     {
  1398.       hhcd->hc[chnum].ErrCnt = 0U;
  1399.       hhcd->hc[chnum].state = HC_NAK;
  1400.       (void)USB_HC_Halt(hhcd->Instance, chnum);
  1401.     }
  1402.     else if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) ||
  1403.              (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
  1404.     {
  1405.       hhcd->hc[chnum].ErrCnt = 0U;
  1406.       hhcd->hc[chnum].state = HC_NAK;
  1407.       (void)USB_HC_Halt(hhcd->Instance, chnum);
  1408.     }
  1409.     else
  1410.     {
  1411.       /* ... */
  1412.     }
  1413.  
  1414.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
  1415.   }
  1416.   else
  1417.   {
  1418.     /* ... */
  1419.   }
  1420. }
  1421.  
  1422. /**
  1423.   * @brief  Handle Host Channel OUT interrupt requests.
  1424.   * @param  hhcd HCD handle
  1425.   * @param  chnum Channel number.
  1426.   *         This parameter can be a value from 1 to 15
  1427.   * @retval none
  1428.   */
  1429. static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
  1430. {
  1431.   USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
  1432.   uint32_t USBx_BASE = (uint32_t)USBx;
  1433.   uint32_t tmpreg;
  1434.   uint32_t num_packets;
  1435.  
  1436.   if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_AHBERR))
  1437.   {
  1438.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR);
  1439.     hhcd->hc[chnum].state = HC_XACTERR;
  1440.     (void)USB_HC_Halt(hhcd->Instance, chnum);
  1441.   }
  1442.   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_ACK))
  1443.   {
  1444.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
  1445.   }
  1446.   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_FRMOR))
  1447.   {
  1448.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR);
  1449.     (void)USB_HC_Halt(hhcd->Instance, chnum);
  1450.   }
  1451.   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_XFRC))
  1452.   {
  1453.     hhcd->hc[chnum].ErrCnt = 0U;
  1454.  
  1455.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC);
  1456.     hhcd->hc[chnum].state = HC_XFRC;
  1457.     (void)USB_HC_Halt(hhcd->Instance, chnum);
  1458.   }
  1459.   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_STALL))
  1460.   {
  1461.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL);
  1462.     hhcd->hc[chnum].state = HC_STALL;
  1463.     (void)USB_HC_Halt(hhcd->Instance, chnum);
  1464.   }
  1465.   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_NAK))
  1466.   {
  1467.     hhcd->hc[chnum].ErrCnt = 0U;
  1468.     hhcd->hc[chnum].state = HC_NAK;
  1469.  
  1470.     (void)USB_HC_Halt(hhcd->Instance, chnum);
  1471.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
  1472.   }
  1473.   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_TXERR))
  1474.   {
  1475.     hhcd->hc[chnum].state = HC_XACTERR;
  1476.     (void)USB_HC_Halt(hhcd->Instance, chnum);
  1477.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR);
  1478.   }
  1479.   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_DTERR))
  1480.   {
  1481.     hhcd->hc[chnum].state = HC_DATATGLERR;
  1482.     (void)USB_HC_Halt(hhcd->Instance, chnum);
  1483.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR);
  1484.   }
  1485.   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_CHH))
  1486.   {
  1487.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
  1488.  
  1489.     if (hhcd->hc[chnum].state == HC_XFRC)
  1490.     {
  1491.       hhcd->hc[chnum].state = HC_HALTED;
  1492.       hhcd->hc[chnum].urb_state = URB_DONE;
  1493.  
  1494.       if ((hhcd->hc[chnum].ep_type == EP_TYPE_BULK) ||
  1495.           (hhcd->hc[chnum].ep_type == EP_TYPE_INTR))
  1496.       {
  1497.         if (hhcd->Init.dma_enable == 0U)
  1498.         {
  1499.           hhcd->hc[chnum].toggle_out ^= 1U;
  1500.         }
  1501.  
  1502.         if ((hhcd->Init.dma_enable == 1U) && (hhcd->hc[chnum].xfer_len > 0U))
  1503.         {
  1504.           num_packets = (hhcd->hc[chnum].xfer_len + hhcd->hc[chnum].max_packet - 1U) / hhcd->hc[chnum].max_packet;
  1505.  
  1506.           if ((num_packets & 1U) != 0U)
  1507.           {
  1508.             hhcd->hc[chnum].toggle_out ^= 1U;
  1509.           }
  1510.         }
  1511.       }
  1512.     }
  1513.     else if (hhcd->hc[chnum].state == HC_ACK)
  1514.     {
  1515.       hhcd->hc[chnum].state = HC_HALTED;
  1516.     }
  1517.     else if (hhcd->hc[chnum].state == HC_NAK)
  1518.     {
  1519.       hhcd->hc[chnum].state = HC_HALTED;
  1520.       hhcd->hc[chnum].urb_state = URB_NOTREADY;
  1521.     }
  1522.     else if (hhcd->hc[chnum].state == HC_STALL)
  1523.     {
  1524.       hhcd->hc[chnum].state = HC_HALTED;
  1525.       hhcd->hc[chnum].urb_state  = URB_STALL;
  1526.     }
  1527.     else if ((hhcd->hc[chnum].state == HC_XACTERR) ||
  1528.              (hhcd->hc[chnum].state == HC_DATATGLERR))
  1529.     {
  1530.       hhcd->hc[chnum].state = HC_HALTED;
  1531.       hhcd->hc[chnum].ErrCnt++;
  1532.       if (hhcd->hc[chnum].ErrCnt > 2U)
  1533.       {
  1534.         hhcd->hc[chnum].ErrCnt = 0U;
  1535.         hhcd->hc[chnum].urb_state = URB_ERROR;
  1536.       }
  1537.       else
  1538.       {
  1539.         hhcd->hc[chnum].urb_state = URB_NOTREADY;
  1540.  
  1541.         /* re-activate the channel  */
  1542.         tmpreg = USBx_HC(chnum)->HCCHAR;
  1543.         tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  1544.         tmpreg |= USB_OTG_HCCHAR_CHENA;
  1545.         USBx_HC(chnum)->HCCHAR = tmpreg;
  1546.       }
  1547.     }
  1548.     else
  1549.     {
  1550.       return;
  1551.     }
  1552.  
  1553. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  1554.     hhcd->HC_NotifyURBChangeCallback(hhcd, chnum, hhcd->hc[chnum].urb_state);
  1555. #else
  1556.     HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
  1557. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  1558.   }
  1559.   else
  1560.   {
  1561.     return;
  1562.   }
  1563. }
  1564.  
  1565. /**
  1566.   * @brief  Handle Rx Queue Level interrupt requests.
  1567.   * @param  hhcd HCD handle
  1568.   * @retval none
  1569.   */
  1570. static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd)
  1571. {
  1572.   USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
  1573.   uint32_t USBx_BASE = (uint32_t)USBx;
  1574.   uint32_t pktsts;
  1575.   uint32_t pktcnt;
  1576.   uint32_t GrxstspReg;
  1577.   uint32_t xferSizePktCnt;
  1578.   uint32_t tmpreg;
  1579.   uint32_t chnum;
  1580.  
  1581.   GrxstspReg = hhcd->Instance->GRXSTSP;
  1582.   chnum = GrxstspReg & USB_OTG_GRXSTSP_EPNUM;
  1583.   pktsts = (GrxstspReg & USB_OTG_GRXSTSP_PKTSTS) >> 17;
  1584.   pktcnt = (GrxstspReg & USB_OTG_GRXSTSP_BCNT) >> 4;
  1585.  
  1586.   switch (pktsts)
  1587.   {
  1588.     case GRXSTS_PKTSTS_IN:
  1589.       /* Read the data into the host buffer. */
  1590.       if ((pktcnt > 0U) && (hhcd->hc[chnum].xfer_buff != (void *)0))
  1591.       {
  1592.         if ((hhcd->hc[chnum].xfer_count + pktcnt) <= hhcd->hc[chnum].xfer_len)
  1593.         {
  1594.           (void)USB_ReadPacket(hhcd->Instance,
  1595.                                hhcd->hc[chnum].xfer_buff, (uint16_t)pktcnt);
  1596.  
  1597.           /* manage multiple Xfer */
  1598.           hhcd->hc[chnum].xfer_buff += pktcnt;
  1599.           hhcd->hc[chnum].xfer_count += pktcnt;
  1600.  
  1601.           /* get transfer size packet count */
  1602.           xferSizePktCnt = (USBx_HC(chnum)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) >> 19;
  1603.  
  1604.           if ((hhcd->hc[chnum].max_packet == pktcnt) && (xferSizePktCnt > 0U))
  1605.           {
  1606.             /* re-activate the channel when more packets are expected */
  1607.             tmpreg = USBx_HC(chnum)->HCCHAR;
  1608.             tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  1609.             tmpreg |= USB_OTG_HCCHAR_CHENA;
  1610.             USBx_HC(chnum)->HCCHAR = tmpreg;
  1611.             hhcd->hc[chnum].toggle_in ^= 1U;
  1612.           }
  1613.         }
  1614.         else
  1615.         {
  1616.           hhcd->hc[chnum].urb_state = URB_ERROR;
  1617.         }
  1618.       }
  1619.       break;
  1620.  
  1621.     case GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
  1622.       break;
  1623.  
  1624.     case GRXSTS_PKTSTS_IN_XFER_COMP:
  1625.     case GRXSTS_PKTSTS_CH_HALTED:
  1626.     default:
  1627.       break;
  1628.   }
  1629. }
  1630.  
  1631. /**
  1632.   * @brief  Handle Host Port interrupt requests.
  1633.   * @param  hhcd HCD handle
  1634.   * @retval None
  1635.   */
  1636. static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd)
  1637. {
  1638.   USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
  1639.   uint32_t USBx_BASE = (uint32_t)USBx;
  1640.   __IO uint32_t hprt0;
  1641.   __IO uint32_t hprt0_dup;
  1642.  
  1643.   /* Handle Host Port Interrupts */
  1644.   hprt0 = USBx_HPRT0;
  1645.   hprt0_dup = USBx_HPRT0;
  1646.  
  1647.   hprt0_dup &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET | \
  1648.                  USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
  1649.  
  1650.   /* Check whether Port Connect detected */
  1651.   if ((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET)
  1652.   {
  1653.     if ((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS)
  1654.     {
  1655. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  1656.       hhcd->ConnectCallback(hhcd);
  1657. #else
  1658.       HAL_HCD_Connect_Callback(hhcd);
  1659. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  1660.     }
  1661.     hprt0_dup |= USB_OTG_HPRT_PCDET;
  1662.   }
  1663.  
  1664.   /* Check whether Port Enable Changed */
  1665.   if ((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG)
  1666.   {
  1667.     hprt0_dup |= USB_OTG_HPRT_PENCHNG;
  1668.  
  1669.     if ((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA)
  1670.     {
  1671.       if (hhcd->Init.phy_itface == USB_OTG_EMBEDDED_PHY)
  1672.       {
  1673.         if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17))
  1674.         {
  1675.           (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_6_MHZ);
  1676.         }
  1677.         else
  1678.         {
  1679.           (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_48_MHZ);
  1680.         }
  1681.       }
  1682.       else
  1683.       {
  1684.         if (hhcd->Init.speed == HCD_SPEED_FULL)
  1685.         {
  1686.           USBx_HOST->HFIR = HFIR_60_MHZ;
  1687.         }
  1688.       }
  1689. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  1690.       hhcd->PortEnabledCallback(hhcd);
  1691. #else
  1692.       HAL_HCD_PortEnabled_Callback(hhcd);
  1693. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  1694.  
  1695.     }
  1696.     else
  1697.     {
  1698. #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
  1699.       hhcd->PortDisabledCallback(hhcd);
  1700. #else
  1701.       HAL_HCD_PortDisabled_Callback(hhcd);
  1702. #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
  1703.     }
  1704.   }
  1705.  
  1706.   /* Check for an overcurrent */
  1707.   if ((hprt0 & USB_OTG_HPRT_POCCHNG) == USB_OTG_HPRT_POCCHNG)
  1708.   {
  1709.     hprt0_dup |= USB_OTG_HPRT_POCCHNG;
  1710.   }
  1711.  
  1712.   /* Clear Port Interrupts */
  1713.   USBx_HPRT0 = hprt0_dup;
  1714. }
  1715.  
  1716. /**
  1717.   * @}
  1718.   */
  1719.  
  1720. /**
  1721.   * @}
  1722.   */
  1723.  
  1724. #endif /* defined (USB_OTG_FS) */
  1725. #endif /* HAL_HCD_MODULE_ENABLED */
  1726.  
  1727. /**
  1728.   * @}
  1729.   */
  1730.  
  1731. /**
  1732.   * @}
  1733.   */
  1734.