Subversion Repositories testOled

Rev

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