STM32F103xB HAL User Manual
stm32f1xx_hal_hcd.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f1xx_hal_hcd.c
00004   * @author  MCD Application Team
00005   * @brief   HCD HAL module driver.
00006   *          This file provides firmware functions to manage the following
00007   *          functionalities of the USB Peripheral Controller:
00008   *           + Initialization and de-initialization functions
00009   *           + IO operation functions
00010   *           + Peripheral Control functions
00011   *           + Peripheral State functions
00012   *
00013   @verbatim
00014   ==============================================================================
00015                     ##### How to use this driver #####
00016   ==============================================================================
00017   [..]
00018     (#)Declare a HCD_HandleTypeDef handle structure, for example:
00019        HCD_HandleTypeDef  hhcd;
00020 
00021     (#)Fill parameters of Init structure in HCD handle
00022 
00023     (#)Call HAL_HCD_Init() API to initialize the HCD peripheral (Core, Host core, ...)
00024 
00025     (#)Initialize the HCD low level resources through the HAL_HCD_MspInit() API:
00026         (##) Enable the HCD/USB Low Level interface clock using the following macros
00027              (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
00028         (##) Initialize the related GPIO clocks
00029         (##) Configure HCD pin-out
00030         (##) Configure HCD NVIC interrupt
00031 
00032     (#)Associate the Upper USB Host stack to the HAL HCD Driver:
00033         (##) hhcd.pData = phost;
00034 
00035     (#)Enable HCD transmission and reception:
00036         (##) HAL_HCD_Start();
00037 
00038   @endverbatim
00039   ******************************************************************************
00040   * @attention
00041   *
00042   * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
00043   * All rights reserved.</center></h2>
00044   *
00045   * This software component is licensed by ST under BSD 3-Clause license,
00046   * the "License"; You may not use this file except in compliance with the
00047   * License. You may obtain a copy of the License at:
00048   *                        opensource.org/licenses/BSD-3-Clause
00049   *
00050   ******************************************************************************
00051   */
00052 
00053 /* Includes ------------------------------------------------------------------*/
00054 #include "stm32f1xx_hal.h"
00055 
00056 /** @addtogroup STM32F1xx_HAL_Driver
00057   * @{
00058   */
00059 
00060 #ifdef HAL_HCD_MODULE_ENABLED
00061 #if defined (USB_OTG_FS)
00062 
00063 /** @defgroup HCD HCD
00064   * @brief HCD HAL module driver
00065   * @{
00066   */
00067 
00068 /* Private typedef -----------------------------------------------------------*/
00069 /* Private define ------------------------------------------------------------*/
00070 /* Private macro -------------------------------------------------------------*/
00071 /* Private variables ---------------------------------------------------------*/
00072 /* Private function prototypes -----------------------------------------------*/
00073 /** @defgroup HCD_Private_Functions HCD Private Functions
00074   * @{
00075   */
00076 static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
00077 static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
00078 static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd);
00079 static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd);
00080 /**
00081   * @}
00082   */
00083 
00084 /* Exported functions --------------------------------------------------------*/
00085 /** @defgroup HCD_Exported_Functions HCD Exported Functions
00086   * @{
00087   */
00088 
00089 /** @defgroup HCD_Exported_Functions_Group1 Initialization and de-initialization functions
00090   *  @brief    Initialization and Configuration functions
00091   *
00092 @verbatim
00093  ===============================================================================
00094           ##### Initialization and de-initialization functions #####
00095  ===============================================================================
00096     [..]  This section provides functions allowing to:
00097 
00098 @endverbatim
00099   * @{
00100   */
00101 
00102 /**
00103   * @brief  Initialize the host driver.
00104   * @param  hhcd HCD handle
00105   * @retval HAL status
00106   */
00107 HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd)
00108 {
00109   USB_OTG_GlobalTypeDef *USBx;
00110 
00111   /* Check the HCD handle allocation */
00112   if (hhcd == NULL)
00113   {
00114     return HAL_ERROR;
00115   }
00116 
00117   /* Check the parameters */
00118   assert_param(IS_HCD_ALL_INSTANCE(hhcd->Instance));
00119 
00120   USBx = hhcd->Instance;
00121 
00122   if (hhcd->State == HAL_HCD_STATE_RESET)
00123   {
00124     /* Allocate lock resource and initialize it */
00125     hhcd->Lock = HAL_UNLOCKED;
00126 
00127 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
00128     hhcd->SOFCallback = HAL_HCD_SOF_Callback;
00129     hhcd->ConnectCallback = HAL_HCD_Connect_Callback;
00130     hhcd->DisconnectCallback = HAL_HCD_Disconnect_Callback;
00131     hhcd->PortEnabledCallback = HAL_HCD_PortEnabled_Callback;
00132     hhcd->PortDisabledCallback = HAL_HCD_PortDisabled_Callback;
00133     hhcd->HC_NotifyURBChangeCallback = HAL_HCD_HC_NotifyURBChange_Callback;
00134 
00135     if (hhcd->MspInitCallback == NULL)
00136     {
00137       hhcd->MspInitCallback = HAL_HCD_MspInit;
00138     }
00139 
00140     /* Init the low level hardware */
00141     hhcd->MspInitCallback(hhcd);
00142 #else
00143     /* Init the low level hardware : GPIO, CLOCK, NVIC... */
00144     HAL_HCD_MspInit(hhcd);
00145 #endif /* (USE_HAL_HCD_REGISTER_CALLBACKS) */
00146   }
00147 
00148   hhcd->State = HAL_HCD_STATE_BUSY;
00149 
00150   /* Disable DMA mode for FS instance */
00151   if ((USBx->CID & (0x1U << 8)) == 0U)
00152   {
00153     hhcd->Init.dma_enable = 0U;
00154   }
00155 
00156   /* Disable the Interrupts */
00157   __HAL_HCD_DISABLE(hhcd);
00158 
00159   /* Init the Core (common init.) */
00160   (void)USB_CoreInit(hhcd->Instance, hhcd->Init);
00161 
00162   /* Force Host Mode*/
00163   (void)USB_SetCurrentMode(hhcd->Instance, USB_HOST_MODE);
00164 
00165   /* Init Host */
00166   (void)USB_HostInit(hhcd->Instance, hhcd->Init);
00167 
00168   hhcd->State = HAL_HCD_STATE_READY;
00169 
00170   return HAL_OK;
00171 }
00172 
00173 /**
00174   * @brief  Initialize a host channel.
00175   * @param  hhcd HCD handle
00176   * @param  ch_num Channel number.
00177   *         This parameter can be a value from 1 to 15
00178   * @param  epnum Endpoint number.
00179   *          This parameter can be a value from 1 to 15
00180   * @param  dev_address Current device address
00181   *          This parameter can be a value from 0 to 255
00182   * @param  speed Current device speed.
00183   *          This parameter can be one of these values:
00184   *            HCD_DEVICE_SPEED_FULL: Full speed mode,
00185   *            HCD_DEVICE_SPEED_LOW: Low speed mode
00186   * @param  ep_type Endpoint Type.
00187   *          This parameter can be one of these values:
00188   *            EP_TYPE_CTRL: Control type,
00189   *            EP_TYPE_ISOC: Isochronous type,
00190   *            EP_TYPE_BULK: Bulk type,
00191   *            EP_TYPE_INTR: Interrupt type
00192   * @param  mps Max Packet Size.
00193   *          This parameter can be a value from 0 to32K
00194   * @retval HAL status
00195   */
00196 HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd,
00197                                   uint8_t ch_num,
00198                                   uint8_t epnum,
00199                                   uint8_t dev_address,
00200                                   uint8_t speed,
00201                                   uint8_t ep_type,
00202                                   uint16_t mps)
00203 {
00204   HAL_StatusTypeDef status;
00205 
00206   __HAL_LOCK(hhcd);
00207   hhcd->hc[ch_num].do_ping = 0U;
00208   hhcd->hc[ch_num].dev_addr = dev_address;
00209   hhcd->hc[ch_num].max_packet = mps;
00210   hhcd->hc[ch_num].ch_num = ch_num;
00211   hhcd->hc[ch_num].ep_type = ep_type;
00212   hhcd->hc[ch_num].ep_num = epnum & 0x7FU;
00213 
00214   if ((epnum & 0x80U) == 0x80U)
00215   {
00216     hhcd->hc[ch_num].ep_is_in = 1U;
00217   }
00218   else
00219   {
00220     hhcd->hc[ch_num].ep_is_in = 0U;
00221   }
00222 
00223   hhcd->hc[ch_num].speed = speed;
00224 
00225   status =  USB_HC_Init(hhcd->Instance,
00226                         ch_num,
00227                         epnum,
00228                         dev_address,
00229                         speed,
00230                         ep_type,
00231                         mps);
00232   __HAL_UNLOCK(hhcd);
00233 
00234   return status;
00235 }
00236 
00237 /**
00238   * @brief  Halt a host channel.
00239   * @param  hhcd HCD handle
00240   * @param  ch_num Channel number.
00241   *         This parameter can be a value from 1 to 15
00242   * @retval HAL status
00243   */
00244 HAL_StatusTypeDef HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd, uint8_t ch_num)
00245 {
00246   HAL_StatusTypeDef status = HAL_OK;
00247 
00248   __HAL_LOCK(hhcd);
00249   (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
00250   __HAL_UNLOCK(hhcd);
00251 
00252   return status;
00253 }
00254 
00255 /**
00256   * @brief  DeInitialize the host driver.
00257   * @param  hhcd HCD handle
00258   * @retval HAL status
00259   */
00260 HAL_StatusTypeDef HAL_HCD_DeInit(HCD_HandleTypeDef *hhcd)
00261 {
00262   /* Check the HCD handle allocation */
00263   if (hhcd == NULL)
00264   {
00265     return HAL_ERROR;
00266   }
00267 
00268   hhcd->State = HAL_HCD_STATE_BUSY;
00269 
00270 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
00271   if (hhcd->MspDeInitCallback == NULL)
00272   {
00273     hhcd->MspDeInitCallback = HAL_HCD_MspDeInit; /* Legacy weak MspDeInit  */
00274   }
00275 
00276   /* DeInit the low level hardware */
00277   hhcd->MspDeInitCallback(hhcd);
00278 #else
00279   /* DeInit the low level hardware: CLOCK, NVIC.*/
00280   HAL_HCD_MspDeInit(hhcd);
00281 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
00282 
00283   __HAL_HCD_DISABLE(hhcd);
00284 
00285   hhcd->State = HAL_HCD_STATE_RESET;
00286 
00287   return HAL_OK;
00288 }
00289 
00290 /**
00291   * @brief  Initialize the HCD MSP.
00292   * @param  hhcd HCD handle
00293   * @retval None
00294   */
00295 __weak void  HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd)
00296 {
00297   /* Prevent unused argument(s) compilation warning */
00298   UNUSED(hhcd);
00299 
00300   /* NOTE : This function should not be modified, when the callback is needed,
00301             the HAL_HCD_MspInit could be implemented in the user file
00302    */
00303 }
00304 
00305 /**
00306   * @brief  DeInitialize the HCD MSP.
00307   * @param  hhcd HCD handle
00308   * @retval None
00309   */
00310 __weak void  HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd)
00311 {
00312   /* Prevent unused argument(s) compilation warning */
00313   UNUSED(hhcd);
00314 
00315   /* NOTE : This function should not be modified, when the callback is needed,
00316             the HAL_HCD_MspDeInit could be implemented in the user file
00317    */
00318 }
00319 
00320 /**
00321   * @}
00322   */
00323 
00324 /** @defgroup HCD_Exported_Functions_Group2 Input and Output operation functions
00325   *  @brief   HCD IO operation functions
00326   *
00327 @verbatim
00328  ===============================================================================
00329                       ##### IO operation functions #####
00330  ===============================================================================
00331  [..] This subsection provides a set of functions allowing to manage the USB Host Data
00332     Transfer
00333 
00334 @endverbatim
00335   * @{
00336   */
00337 
00338 /**
00339   * @brief  Submit a new URB for processing.
00340   * @param  hhcd HCD handle
00341   * @param  ch_num Channel number.
00342   *         This parameter can be a value from 1 to 15
00343   * @param  direction Channel number.
00344   *          This parameter can be one of these values:
00345   *           0 : Output / 1 : Input
00346   * @param  ep_type Endpoint Type.
00347   *          This parameter can be one of these values:
00348   *            EP_TYPE_CTRL: Control type/
00349   *            EP_TYPE_ISOC: Isochronous type/
00350   *            EP_TYPE_BULK: Bulk type/
00351   *            EP_TYPE_INTR: Interrupt type/
00352   * @param  token Endpoint Type.
00353   *          This parameter can be one of these values:
00354   *            0: HC_PID_SETUP / 1: HC_PID_DATA1
00355   * @param  pbuff pointer to URB data
00356   * @param  length Length of URB data
00357   * @param  do_ping activate do ping protocol (for high speed only).
00358   *          This parameter can be one of these values:
00359   *           0 : do ping inactive / 1 : do ping active
00360   * @retval HAL status
00361   */
00362 HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd,
00363                                            uint8_t ch_num,
00364                                            uint8_t direction,
00365                                            uint8_t ep_type,
00366                                            uint8_t token,
00367                                            uint8_t *pbuff,
00368                                            uint16_t length,
00369                                            uint8_t do_ping)
00370 {
00371   hhcd->hc[ch_num].ep_is_in = direction;
00372   hhcd->hc[ch_num].ep_type  = ep_type;
00373 
00374   if (token == 0U)
00375   {
00376     hhcd->hc[ch_num].data_pid = HC_PID_SETUP;
00377     hhcd->hc[ch_num].do_ping = do_ping;
00378   }
00379   else
00380   {
00381     hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
00382   }
00383 
00384   /* Manage Data Toggle */
00385   switch (ep_type)
00386   {
00387     case EP_TYPE_CTRL:
00388       if ((token == 1U) && (direction == 0U)) /*send data */
00389       {
00390         if (length == 0U)
00391         {
00392           /* For Status OUT stage, Length==0, Status Out PID = 1 */
00393           hhcd->hc[ch_num].toggle_out = 1U;
00394         }
00395 
00396         /* Set the Data Toggle bit as per the Flag */
00397         if (hhcd->hc[ch_num].toggle_out == 0U)
00398         {
00399           /* Put the PID 0 */
00400           hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
00401         }
00402         else
00403         {
00404           /* Put the PID 1 */
00405           hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
00406         }
00407       }
00408       break;
00409 
00410     case EP_TYPE_BULK:
00411       if (direction == 0U)
00412       {
00413         /* Set the Data Toggle bit as per the Flag */
00414         if (hhcd->hc[ch_num].toggle_out == 0U)
00415         {
00416           /* Put the PID 0 */
00417           hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
00418         }
00419         else
00420         {
00421           /* Put the PID 1 */
00422           hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
00423         }
00424       }
00425       else
00426       {
00427         if (hhcd->hc[ch_num].toggle_in == 0U)
00428         {
00429           hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
00430         }
00431         else
00432         {
00433           hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
00434         }
00435       }
00436 
00437       break;
00438     case EP_TYPE_INTR:
00439       if (direction == 0U)
00440       {
00441         /* Set the Data Toggle bit as per the Flag */
00442         if (hhcd->hc[ch_num].toggle_out == 0U)
00443         {
00444           /* Put the PID 0 */
00445           hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
00446         }
00447         else
00448         {
00449           /* Put the PID 1 */
00450           hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
00451         }
00452       }
00453       else
00454       {
00455         if (hhcd->hc[ch_num].toggle_in == 0U)
00456         {
00457           hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
00458         }
00459         else
00460         {
00461           hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
00462         }
00463       }
00464       break;
00465 
00466     case EP_TYPE_ISOC:
00467       hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
00468       break;
00469 
00470     default:
00471       break;
00472   }
00473 
00474   hhcd->hc[ch_num].xfer_buff = pbuff;
00475   hhcd->hc[ch_num].xfer_len  = length;
00476   hhcd->hc[ch_num].urb_state = URB_IDLE;
00477   hhcd->hc[ch_num].xfer_count = 0U;
00478   hhcd->hc[ch_num].ch_num = ch_num;
00479   hhcd->hc[ch_num].state = HC_IDLE;
00480 
00481   return USB_HC_StartXfer(hhcd->Instance, &hhcd->hc[ch_num]);
00482 }
00483 
00484 /**
00485   * @brief  Handle HCD interrupt request.
00486   * @param  hhcd HCD handle
00487   * @retval None
00488   */
00489 void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd)
00490 {
00491   USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
00492   uint32_t USBx_BASE = (uint32_t)USBx;
00493   uint32_t i;
00494   uint32_t interrupt;
00495 
00496   /* Ensure that we are in device mode */
00497   if (USB_GetMode(hhcd->Instance) == USB_OTG_MODE_HOST)
00498   {
00499     /* Avoid spurious interrupt */
00500     if (__HAL_HCD_IS_INVALID_INTERRUPT(hhcd))
00501     {
00502       return;
00503     }
00504 
00505     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
00506     {
00507       /* Incorrect mode, acknowledge the interrupt */
00508       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
00509     }
00510 
00511     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR))
00512     {
00513       /* Incorrect mode, acknowledge the interrupt */
00514       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR);
00515     }
00516 
00517     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE))
00518     {
00519       /* Incorrect mode, acknowledge the interrupt */
00520       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE);
00521     }
00522 
00523     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_MMIS))
00524     {
00525       /* Incorrect mode, acknowledge the interrupt */
00526       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_MMIS);
00527     }
00528 
00529     /* Handle Host Disconnect Interrupts */
00530     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT))
00531     {
00532       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT);
00533 
00534       if ((USBx_HPRT0 & USB_OTG_HPRT_PCSTS) == 0U)
00535       {
00536         /* Handle Host Port Disconnect Interrupt */
00537 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
00538         hhcd->DisconnectCallback(hhcd);
00539 #else
00540         HAL_HCD_Disconnect_Callback(hhcd);
00541 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
00542 
00543         (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_48_MHZ);
00544       }
00545     }
00546 
00547     /* Handle Host Port Interrupts */
00548     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HPRTINT))
00549     {
00550       HCD_Port_IRQHandler(hhcd);
00551     }
00552 
00553     /* Handle Host SOF Interrupt */
00554     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_SOF))
00555     {
00556 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
00557       hhcd->SOFCallback(hhcd);
00558 #else
00559       HAL_HCD_SOF_Callback(hhcd);
00560 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
00561 
00562       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_SOF);
00563     }
00564 
00565     /* Handle Rx Queue Level Interrupts */
00566     if ((__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_RXFLVL)) != 0U)
00567     {
00568       USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
00569 
00570       HCD_RXQLVL_IRQHandler(hhcd);
00571 
00572       USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
00573     }
00574 
00575     /* Handle Host channel Interrupt */
00576     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HCINT))
00577     {
00578       interrupt = USB_HC_ReadInterrupt(hhcd->Instance);
00579       for (i = 0U; i < hhcd->Init.Host_channels; i++)
00580       {
00581         if ((interrupt & (1UL << (i & 0xFU))) != 0U)
00582         {
00583           if ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_EPDIR) == USB_OTG_HCCHAR_EPDIR)
00584           {
00585             HCD_HC_IN_IRQHandler(hhcd, (uint8_t)i);
00586           }
00587           else
00588           {
00589             HCD_HC_OUT_IRQHandler(hhcd, (uint8_t)i);
00590           }
00591         }
00592       }
00593       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_HCINT);
00594     }
00595   }
00596 }
00597 
00598 
00599 /**
00600   * @brief  Handles HCD Wakeup interrupt request.
00601   * @param  hhcd HCD handle
00602   * @retval HAL status
00603   */
00604 void HAL_HCD_WKUP_IRQHandler(HCD_HandleTypeDef *hhcd)
00605 {
00606   UNUSED(hhcd);
00607 }
00608 
00609 
00610 /**
00611   * @brief  SOF callback.
00612   * @param  hhcd HCD handle
00613   * @retval None
00614   */
00615 __weak void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd)
00616 {
00617   /* Prevent unused argument(s) compilation warning */
00618   UNUSED(hhcd);
00619 
00620   /* NOTE : This function should not be modified, when the callback is needed,
00621             the HAL_HCD_SOF_Callback could be implemented in the user file
00622    */
00623 }
00624 
00625 /**
00626   * @brief Connection Event callback.
00627   * @param  hhcd HCD handle
00628   * @retval None
00629   */
00630 __weak void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
00631 {
00632   /* Prevent unused argument(s) compilation warning */
00633   UNUSED(hhcd);
00634 
00635   /* NOTE : This function should not be modified, when the callback is needed,
00636             the HAL_HCD_Connect_Callback could be implemented in the user file
00637    */
00638 }
00639 
00640 /**
00641   * @brief  Disconnection Event callback.
00642   * @param  hhcd HCD handle
00643   * @retval None
00644   */
00645 __weak void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
00646 {
00647   /* Prevent unused argument(s) compilation warning */
00648   UNUSED(hhcd);
00649 
00650   /* NOTE : This function should not be modified, when the callback is needed,
00651             the HAL_HCD_Disconnect_Callback could be implemented in the user file
00652    */
00653 }
00654 
00655 /**
00656   * @brief  Port Enabled  Event callback.
00657   * @param  hhcd HCD handle
00658   * @retval None
00659   */
00660 __weak void HAL_HCD_PortEnabled_Callback(HCD_HandleTypeDef *hhcd)
00661 {
00662   /* Prevent unused argument(s) compilation warning */
00663   UNUSED(hhcd);
00664 
00665   /* NOTE : This function should not be modified, when the callback is needed,
00666             the HAL_HCD_Disconnect_Callback could be implemented in the user file
00667    */
00668 }
00669 
00670 /**
00671   * @brief  Port Disabled  Event callback.
00672   * @param  hhcd HCD handle
00673   * @retval None
00674   */
00675 __weak void HAL_HCD_PortDisabled_Callback(HCD_HandleTypeDef *hhcd)
00676 {
00677   /* Prevent unused argument(s) compilation warning */
00678   UNUSED(hhcd);
00679 
00680   /* NOTE : This function should not be modified, when the callback is needed,
00681             the HAL_HCD_Disconnect_Callback could be implemented in the user file
00682    */
00683 }
00684 
00685 /**
00686   * @brief  Notify URB state change callback.
00687   * @param  hhcd HCD handle
00688   * @param  chnum Channel number.
00689   *         This parameter can be a value from 1 to 15
00690   * @param  urb_state:
00691   *          This parameter can be one of these values:
00692   *            URB_IDLE/
00693   *            URB_DONE/
00694   *            URB_NOTREADY/
00695   *            URB_NYET/
00696   *            URB_ERROR/
00697   *            URB_STALL/
00698   * @retval None
00699   */
00700 __weak void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state)
00701 {
00702   /* Prevent unused argument(s) compilation warning */
00703   UNUSED(hhcd);
00704   UNUSED(chnum);
00705   UNUSED(urb_state);
00706 
00707   /* NOTE : This function should not be modified, when the callback is needed,
00708             the HAL_HCD_HC_NotifyURBChange_Callback could be implemented in the user file
00709    */
00710 }
00711 
00712 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
00713 /**
00714   * @brief  Register a User USB HCD Callback
00715   *         To be used instead of the weak predefined callback
00716   * @param  hhcd USB HCD handle
00717   * @param  CallbackID ID of the callback to be registered
00718   *         This parameter can be one of the following values:
00719   *          @arg @ref HAL_HCD_SOF_CB_ID USB HCD SOF callback ID
00720   *          @arg @ref HAL_HCD_CONNECT_CB_ID USB HCD Connect callback ID
00721   *          @arg @ref HAL_HCD_DISCONNECT_CB_ID OTG HCD Disconnect callback ID
00722   *          @arg @ref HAL_HCD_PORT_ENABLED_CB_ID USB HCD Port Enable callback ID
00723   *          @arg @ref HAL_HCD_PORT_DISABLED_CB_ID USB HCD Port Disable callback ID
00724   *          @arg @ref HAL_HCD_MSPINIT_CB_ID MspDeInit callback ID
00725   *          @arg @ref HAL_HCD_MSPDEINIT_CB_ID MspDeInit callback ID
00726   * @param  pCallback pointer to the Callback function
00727   * @retval HAL status
00728   */
00729 HAL_StatusTypeDef HAL_HCD_RegisterCallback(HCD_HandleTypeDef *hhcd,
00730                                            HAL_HCD_CallbackIDTypeDef CallbackID,
00731                                            pHCD_CallbackTypeDef pCallback)
00732 {
00733   HAL_StatusTypeDef status = HAL_OK;
00734 
00735   if (pCallback == NULL)
00736   {
00737     /* Update the error code */
00738     hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
00739     return HAL_ERROR;
00740   }
00741   /* Process locked */
00742   __HAL_LOCK(hhcd);
00743 
00744   if (hhcd->State == HAL_HCD_STATE_READY)
00745   {
00746     switch (CallbackID)
00747     {
00748       case HAL_HCD_SOF_CB_ID :
00749         hhcd->SOFCallback = pCallback;
00750         break;
00751 
00752       case HAL_HCD_CONNECT_CB_ID :
00753         hhcd->ConnectCallback = pCallback;
00754         break;
00755 
00756       case HAL_HCD_DISCONNECT_CB_ID :
00757         hhcd->DisconnectCallback = pCallback;
00758         break;
00759 
00760       case HAL_HCD_PORT_ENABLED_CB_ID :
00761         hhcd->PortEnabledCallback = pCallback;
00762         break;
00763 
00764       case HAL_HCD_PORT_DISABLED_CB_ID :
00765         hhcd->PortDisabledCallback = pCallback;
00766         break;
00767 
00768       case HAL_HCD_MSPINIT_CB_ID :
00769         hhcd->MspInitCallback = pCallback;
00770         break;
00771 
00772       case HAL_HCD_MSPDEINIT_CB_ID :
00773         hhcd->MspDeInitCallback = pCallback;
00774         break;
00775 
00776       default :
00777         /* Update the error code */
00778         hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
00779         /* Return error status */
00780         status =  HAL_ERROR;
00781         break;
00782     }
00783   }
00784   else if (hhcd->State == HAL_HCD_STATE_RESET)
00785   {
00786     switch (CallbackID)
00787     {
00788       case HAL_HCD_MSPINIT_CB_ID :
00789         hhcd->MspInitCallback = pCallback;
00790         break;
00791 
00792       case HAL_HCD_MSPDEINIT_CB_ID :
00793         hhcd->MspDeInitCallback = pCallback;
00794         break;
00795 
00796       default :
00797         /* Update the error code */
00798         hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
00799         /* Return error status */
00800         status =  HAL_ERROR;
00801         break;
00802     }
00803   }
00804   else
00805   {
00806     /* Update the error code */
00807     hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
00808     /* Return error status */
00809     status =  HAL_ERROR;
00810   }
00811 
00812   /* Release Lock */
00813   __HAL_UNLOCK(hhcd);
00814   return status;
00815 }
00816 
00817 /**
00818   * @brief  Unregister an USB HCD Callback
00819   *         USB HCD callback is redirected to the weak predefined callback
00820   * @param  hhcd USB HCD handle
00821   * @param  CallbackID ID of the callback to be unregistered
00822   *         This parameter can be one of the following values:
00823   *          @arg @ref HAL_HCD_SOF_CB_ID USB HCD SOF callback ID
00824   *          @arg @ref HAL_HCD_CONNECT_CB_ID USB HCD Connect callback ID
00825   *          @arg @ref HAL_HCD_DISCONNECT_CB_ID OTG HCD Disconnect callback ID
00826   *          @arg @ref HAL_HCD_PORT_ENABLED_CB_ID USB HCD Port Enabled callback ID
00827   *          @arg @ref HAL_HCD_PORT_DISABLED_CB_ID USB HCD Port Disabled callback ID
00828   *          @arg @ref HAL_HCD_MSPINIT_CB_ID MspDeInit callback ID
00829   *          @arg @ref HAL_HCD_MSPDEINIT_CB_ID MspDeInit callback ID
00830   * @retval HAL status
00831   */
00832 HAL_StatusTypeDef HAL_HCD_UnRegisterCallback(HCD_HandleTypeDef *hhcd, HAL_HCD_CallbackIDTypeDef CallbackID)
00833 {
00834   HAL_StatusTypeDef status = HAL_OK;
00835 
00836   /* Process locked */
00837   __HAL_LOCK(hhcd);
00838 
00839   /* Setup Legacy weak Callbacks  */
00840   if (hhcd->State == HAL_HCD_STATE_READY)
00841   {
00842     switch (CallbackID)
00843     {
00844       case HAL_HCD_SOF_CB_ID :
00845         hhcd->SOFCallback = HAL_HCD_SOF_Callback;
00846         break;
00847 
00848       case HAL_HCD_CONNECT_CB_ID :
00849         hhcd->ConnectCallback = HAL_HCD_Connect_Callback;
00850         break;
00851 
00852       case HAL_HCD_DISCONNECT_CB_ID :
00853         hhcd->DisconnectCallback = HAL_HCD_Disconnect_Callback;
00854         break;
00855 
00856       case HAL_HCD_PORT_ENABLED_CB_ID :
00857         hhcd->PortEnabledCallback = HAL_HCD_PortEnabled_Callback;
00858         break;
00859 
00860       case HAL_HCD_PORT_DISABLED_CB_ID :
00861         hhcd->PortDisabledCallback = HAL_HCD_PortDisabled_Callback;
00862         break;
00863 
00864       case HAL_HCD_MSPINIT_CB_ID :
00865         hhcd->MspInitCallback = HAL_HCD_MspInit;
00866         break;
00867 
00868       case HAL_HCD_MSPDEINIT_CB_ID :
00869         hhcd->MspDeInitCallback = HAL_HCD_MspDeInit;
00870         break;
00871 
00872       default :
00873         /* Update the error code */
00874         hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
00875 
00876         /* Return error status */
00877         status =  HAL_ERROR;
00878         break;
00879     }
00880   }
00881   else if (hhcd->State == HAL_HCD_STATE_RESET)
00882   {
00883     switch (CallbackID)
00884     {
00885       case HAL_HCD_MSPINIT_CB_ID :
00886         hhcd->MspInitCallback = HAL_HCD_MspInit;
00887         break;
00888 
00889       case HAL_HCD_MSPDEINIT_CB_ID :
00890         hhcd->MspDeInitCallback = HAL_HCD_MspDeInit;
00891         break;
00892 
00893       default :
00894         /* Update the error code */
00895         hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
00896 
00897         /* Return error status */
00898         status =  HAL_ERROR;
00899         break;
00900     }
00901   }
00902   else
00903   {
00904     /* Update the error code */
00905     hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
00906 
00907     /* Return error status */
00908     status =  HAL_ERROR;
00909   }
00910 
00911   /* Release Lock */
00912   __HAL_UNLOCK(hhcd);
00913   return status;
00914 }
00915 
00916 /**
00917   * @brief  Register USB HCD Host Channel Notify URB Change Callback
00918   *         To be used instead of the weak HAL_HCD_HC_NotifyURBChange_Callback() predefined callback
00919   * @param  hhcd HCD handle
00920   * @param  pCallback pointer to the USB HCD Host Channel Notify URB Change Callback function
00921   * @retval HAL status
00922   */
00923 HAL_StatusTypeDef HAL_HCD_RegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd,
00924                                                              pHCD_HC_NotifyURBChangeCallbackTypeDef pCallback)
00925 {
00926   HAL_StatusTypeDef status = HAL_OK;
00927 
00928   if (pCallback == NULL)
00929   {
00930     /* Update the error code */
00931     hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
00932 
00933     return HAL_ERROR;
00934   }
00935 
00936   /* Process locked */
00937   __HAL_LOCK(hhcd);
00938 
00939   if (hhcd->State == HAL_HCD_STATE_READY)
00940   {
00941     hhcd->HC_NotifyURBChangeCallback = pCallback;
00942   }
00943   else
00944   {
00945     /* Update the error code */
00946     hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
00947 
00948     /* Return error status */
00949     status =  HAL_ERROR;
00950   }
00951 
00952   /* Release Lock */
00953   __HAL_UNLOCK(hhcd);
00954 
00955   return status;
00956 }
00957 
00958 /**
00959   * @brief  Unregister the USB HCD Host Channel Notify URB Change Callback
00960   *         USB HCD Host Channel Notify URB Change Callback is redirected
00961   *         to the weak HAL_HCD_HC_NotifyURBChange_Callback() predefined callback
00962   * @param  hhcd HCD handle
00963   * @retval HAL status
00964   */
00965 HAL_StatusTypeDef HAL_HCD_UnRegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd)
00966 {
00967   HAL_StatusTypeDef status = HAL_OK;
00968 
00969   /* Process locked */
00970   __HAL_LOCK(hhcd);
00971 
00972   if (hhcd->State == HAL_HCD_STATE_READY)
00973   {
00974     hhcd->HC_NotifyURBChangeCallback = HAL_HCD_HC_NotifyURBChange_Callback; /* Legacy weak DataOutStageCallback  */
00975   }
00976   else
00977   {
00978     /* Update the error code */
00979     hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
00980 
00981     /* Return error status */
00982     status =  HAL_ERROR;
00983   }
00984 
00985   /* Release Lock */
00986   __HAL_UNLOCK(hhcd);
00987 
00988   return status;
00989 }
00990 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
00991 
00992 /**
00993   * @}
00994   */
00995 
00996 /** @defgroup HCD_Exported_Functions_Group3 Peripheral Control functions
00997   *  @brief   Management functions
00998   *
00999 @verbatim
01000  ===============================================================================
01001                       ##### Peripheral Control functions #####
01002  ===============================================================================
01003     [..]
01004     This subsection provides a set of functions allowing to control the HCD data
01005     transfers.
01006 
01007 @endverbatim
01008   * @{
01009   */
01010 
01011 /**
01012   * @brief  Start the host driver.
01013   * @param  hhcd HCD handle
01014   * @retval HAL status
01015   */
01016 HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd)
01017 {
01018   __HAL_LOCK(hhcd);
01019   /* Enable port power */
01020   (void)USB_DriveVbus(hhcd->Instance, 1U);
01021 
01022   /* Enable global interrupt */
01023   __HAL_HCD_ENABLE(hhcd);
01024   __HAL_UNLOCK(hhcd);
01025 
01026   return HAL_OK;
01027 }
01028 
01029 /**
01030   * @brief  Stop the host driver.
01031   * @param  hhcd HCD handle
01032   * @retval HAL status
01033   */
01034 
01035 HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd)
01036 {
01037   __HAL_LOCK(hhcd);
01038   (void)USB_StopHost(hhcd->Instance);
01039   __HAL_UNLOCK(hhcd);
01040 
01041   return HAL_OK;
01042 }
01043 
01044 /**
01045   * @brief  Reset the host port.
01046   * @param  hhcd HCD handle
01047   * @retval HAL status
01048   */
01049 HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd)
01050 {
01051   return (USB_ResetPort(hhcd->Instance));
01052 }
01053 
01054 /**
01055   * @}
01056   */
01057 
01058 /** @defgroup HCD_Exported_Functions_Group4 Peripheral State functions
01059   *  @brief   Peripheral State functions
01060   *
01061 @verbatim
01062  ===============================================================================
01063                       ##### Peripheral State functions #####
01064  ===============================================================================
01065     [..]
01066     This subsection permits to get in run-time the status of the peripheral
01067     and the data flow.
01068 
01069 @endverbatim
01070   * @{
01071   */
01072 
01073 /**
01074   * @brief  Return the HCD handle state.
01075   * @param  hhcd HCD handle
01076   * @retval HAL state
01077   */
01078 HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef *hhcd)
01079 {
01080   return hhcd->State;
01081 }
01082 
01083 /**
01084   * @brief  Return  URB state for a channel.
01085   * @param  hhcd HCD handle
01086   * @param  chnum Channel number.
01087   *         This parameter can be a value from 1 to 15
01088   * @retval URB state.
01089   *          This parameter can be one of these values:
01090   *            URB_IDLE/
01091   *            URB_DONE/
01092   *            URB_NOTREADY/
01093   *            URB_NYET/
01094   *            URB_ERROR/
01095   *            URB_STALL
01096   */
01097 HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef *hhcd, uint8_t chnum)
01098 {
01099   return hhcd->hc[chnum].urb_state;
01100 }
01101 
01102 
01103 /**
01104   * @brief  Return the last host transfer size.
01105   * @param  hhcd HCD handle
01106   * @param  chnum Channel number.
01107   *         This parameter can be a value from 1 to 15
01108   * @retval last transfer size in byte
01109   */
01110 uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef *hhcd, uint8_t chnum)
01111 {
01112   return hhcd->hc[chnum].xfer_count;
01113 }
01114 
01115 /**
01116   * @brief  Return the Host Channel state.
01117   * @param  hhcd HCD handle
01118   * @param  chnum Channel number.
01119   *         This parameter can be a value from 1 to 15
01120   * @retval Host channel state
01121   *          This parameter can be one of these values:
01122   *            HC_IDLE/
01123   *            HC_XFRC/
01124   *            HC_HALTED/
01125   *            HC_NYET/
01126   *            HC_NAK/
01127   *            HC_STALL/
01128   *            HC_XACTERR/
01129   *            HC_BBLERR/
01130   *            HC_DATATGLERR
01131   */
01132 HCD_HCStateTypeDef  HAL_HCD_HC_GetState(HCD_HandleTypeDef *hhcd, uint8_t chnum)
01133 {
01134   return hhcd->hc[chnum].state;
01135 }
01136 
01137 /**
01138   * @brief  Return the current Host frame number.
01139   * @param  hhcd HCD handle
01140   * @retval Current Host frame number
01141   */
01142 uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd)
01143 {
01144   return (USB_GetCurrentFrame(hhcd->Instance));
01145 }
01146 
01147 /**
01148   * @brief  Return the Host enumeration speed.
01149   * @param  hhcd HCD handle
01150   * @retval Enumeration speed
01151   */
01152 uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd)
01153 {
01154   return (USB_GetHostSpeed(hhcd->Instance));
01155 }
01156 
01157 /**
01158   * @}
01159   */
01160 
01161 /**
01162   * @}
01163   */
01164 
01165 /** @addtogroup HCD_Private_Functions
01166   * @{
01167   */
01168 /**
01169   * @brief  Handle Host Channel IN interrupt requests.
01170   * @param  hhcd HCD handle
01171   * @param  chnum Channel number.
01172   *         This parameter can be a value from 1 to 15
01173   * @retval none
01174   */
01175 static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
01176 {
01177   USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
01178   uint32_t USBx_BASE = (uint32_t)USBx;
01179   uint32_t ch_num = (uint32_t)chnum;
01180 
01181   uint32_t tmpreg;
01182 
01183   if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_AHBERR) == USB_OTG_HCINT_AHBERR)
01184   {
01185     __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_AHBERR);
01186     __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
01187   }
01188   else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_BBERR) == USB_OTG_HCINT_BBERR)
01189   {
01190     __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_BBERR);
01191     hhcd->hc[ch_num].state = HC_BBLERR;
01192     __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
01193     (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
01194   }
01195   else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_ACK) == USB_OTG_HCINT_ACK)
01196   {
01197     __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_ACK);
01198   }
01199   else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_STALL) == USB_OTG_HCINT_STALL)
01200   {
01201     __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
01202     hhcd->hc[ch_num].state = HC_STALL;
01203     __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
01204     __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_STALL);
01205     (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
01206   }
01207   else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_DTERR) == USB_OTG_HCINT_DTERR)
01208   {
01209     __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
01210     hhcd->hc[ch_num].state = HC_DATATGLERR;
01211     __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
01212     __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_DTERR);
01213     (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
01214   }
01215   else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_TXERR) == USB_OTG_HCINT_TXERR)
01216   {
01217     __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
01218     hhcd->hc[ch_num].state = HC_XACTERR;
01219     (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
01220     __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_TXERR);
01221   }
01222   else
01223   {
01224     /* ... */
01225   }
01226 
01227   if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_FRMOR) == USB_OTG_HCINT_FRMOR)
01228   {
01229     __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
01230     (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
01231     __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_FRMOR);
01232   }
01233   else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_XFRC) == USB_OTG_HCINT_XFRC)
01234   {
01235     hhcd->hc[ch_num].state = HC_XFRC;
01236     hhcd->hc[ch_num].ErrCnt = 0U;
01237     __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_XFRC);
01238 
01239     if ((hhcd->hc[ch_num].ep_type == EP_TYPE_CTRL) ||
01240         (hhcd->hc[ch_num].ep_type == EP_TYPE_BULK))
01241     {
01242       __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
01243       (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
01244       __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
01245     }
01246     else if (hhcd->hc[ch_num].ep_type == EP_TYPE_INTR)
01247     {
01248       USBx_HC(ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
01249       hhcd->hc[ch_num].urb_state = URB_DONE;
01250 
01251 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
01252       hhcd->HC_NotifyURBChangeCallback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
01253 #else
01254       HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
01255 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
01256     }
01257     else if (hhcd->hc[ch_num].ep_type == EP_TYPE_ISOC)
01258     {
01259       hhcd->hc[ch_num].urb_state = URB_DONE;
01260       hhcd->hc[ch_num].toggle_in ^= 1U;
01261 
01262 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
01263       hhcd->HC_NotifyURBChangeCallback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
01264 #else
01265       HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
01266 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
01267     }
01268     else
01269     {
01270       /* ... */
01271     }
01272 
01273     if (hhcd->Init.dma_enable == 1U)
01274     {
01275       if (((hhcd->hc[ch_num].XferSize / hhcd->hc[ch_num].max_packet) & 1U) != 0U)
01276       {
01277         hhcd->hc[ch_num].toggle_in ^= 1U;
01278       }
01279     }
01280     else
01281     {
01282       hhcd->hc[ch_num].toggle_in ^= 1U;
01283     }
01284   }
01285   else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_CHH) == USB_OTG_HCINT_CHH)
01286   {
01287     __HAL_HCD_MASK_HALT_HC_INT(ch_num);
01288 
01289     if (hhcd->hc[ch_num].state == HC_XFRC)
01290     {
01291       hhcd->hc[ch_num].urb_state = URB_DONE;
01292     }
01293     else if (hhcd->hc[ch_num].state == HC_STALL)
01294     {
01295       hhcd->hc[ch_num].urb_state = URB_STALL;
01296     }
01297     else if ((hhcd->hc[ch_num].state == HC_XACTERR) ||
01298              (hhcd->hc[ch_num].state == HC_DATATGLERR))
01299     {
01300       hhcd->hc[ch_num].ErrCnt++;
01301       if (hhcd->hc[ch_num].ErrCnt > 2U)
01302       {
01303         hhcd->hc[ch_num].ErrCnt = 0U;
01304         hhcd->hc[ch_num].urb_state = URB_ERROR;
01305       }
01306       else
01307       {
01308         hhcd->hc[ch_num].urb_state = URB_NOTREADY;
01309 
01310         /* re-activate the channel */
01311         tmpreg = USBx_HC(ch_num)->HCCHAR;
01312         tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
01313         tmpreg |= USB_OTG_HCCHAR_CHENA;
01314         USBx_HC(ch_num)->HCCHAR = tmpreg;
01315       }
01316     }
01317     else if (hhcd->hc[ch_num].state == HC_NAK)
01318     {
01319       hhcd->hc[ch_num].urb_state  = URB_NOTREADY;
01320 
01321       /* re-activate the channel */
01322       tmpreg = USBx_HC(ch_num)->HCCHAR;
01323       tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
01324       tmpreg |= USB_OTG_HCCHAR_CHENA;
01325       USBx_HC(ch_num)->HCCHAR = tmpreg;
01326     }
01327     else if (hhcd->hc[ch_num].state == HC_BBLERR)
01328     {
01329       hhcd->hc[ch_num].ErrCnt++;
01330       hhcd->hc[ch_num].urb_state = URB_ERROR;
01331     }
01332     else
01333     {
01334       /* ... */
01335     }
01336     __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_CHH);
01337     HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
01338   }
01339   else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_NAK) == USB_OTG_HCINT_NAK)
01340   {
01341     if (hhcd->hc[ch_num].ep_type == EP_TYPE_INTR)
01342     {
01343       hhcd->hc[ch_num].ErrCnt = 0U;
01344       __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
01345       (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
01346     }
01347     else if ((hhcd->hc[ch_num].ep_type == EP_TYPE_CTRL) ||
01348              (hhcd->hc[ch_num].ep_type == EP_TYPE_BULK))
01349     {
01350       hhcd->hc[ch_num].ErrCnt = 0U;
01351       hhcd->hc[ch_num].state = HC_NAK;
01352       __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
01353       (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
01354     }
01355     else
01356     {
01357       /* ... */
01358     }
01359     __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
01360   }
01361   else
01362   {
01363     /* ... */
01364   }
01365 }
01366 
01367 /**
01368   * @brief  Handle Host Channel OUT interrupt requests.
01369   * @param  hhcd HCD handle
01370   * @param  chnum Channel number.
01371   *         This parameter can be a value from 1 to 15
01372   * @retval none
01373   */
01374 static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
01375 {
01376   USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
01377   uint32_t USBx_BASE = (uint32_t)USBx;
01378   uint32_t ch_num = (uint32_t)chnum;
01379   uint32_t tmpreg;
01380   uint32_t num_packets;
01381 
01382   if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_AHBERR) == USB_OTG_HCINT_AHBERR)
01383   {
01384     __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_AHBERR);
01385     __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
01386   }
01387   else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_ACK) == USB_OTG_HCINT_ACK)
01388   {
01389     __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_ACK);
01390 
01391     if (hhcd->hc[ch_num].do_ping == 1U)
01392     {
01393       hhcd->hc[ch_num].do_ping = 0U;
01394       hhcd->hc[ch_num].urb_state  = URB_NOTREADY;
01395       __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
01396       (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
01397     }
01398   }
01399   else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_FRMOR) == USB_OTG_HCINT_FRMOR)
01400   {
01401     __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
01402     (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
01403     __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_FRMOR);
01404   }
01405   else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_XFRC) == USB_OTG_HCINT_XFRC)
01406   {
01407     hhcd->hc[ch_num].ErrCnt = 0U;
01408 
01409     /* transaction completed with NYET state, update do ping state */
01410     if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_NYET) == USB_OTG_HCINT_NYET)
01411     {
01412       hhcd->hc[ch_num].do_ping = 1U;
01413       __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NYET);
01414     }
01415     __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
01416     (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
01417     __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_XFRC);
01418     hhcd->hc[ch_num].state = HC_XFRC;
01419   }
01420   else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_NYET) == USB_OTG_HCINT_NYET)
01421   {
01422     hhcd->hc[ch_num].state = HC_NYET;
01423     hhcd->hc[ch_num].do_ping = 1U;
01424     hhcd->hc[ch_num].ErrCnt = 0U;
01425     __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
01426     (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
01427     __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NYET);
01428   }
01429   else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_STALL) == USB_OTG_HCINT_STALL)
01430   {
01431     __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_STALL);
01432     __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
01433     (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
01434     hhcd->hc[ch_num].state = HC_STALL;
01435   }
01436   else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_NAK) == USB_OTG_HCINT_NAK)
01437   {
01438     hhcd->hc[ch_num].ErrCnt = 0U;
01439     hhcd->hc[ch_num].state = HC_NAK;
01440 
01441     __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
01442     (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
01443     __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
01444   }
01445   else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_TXERR) == USB_OTG_HCINT_TXERR)
01446   {
01447     hhcd->hc[ch_num].state = HC_XACTERR;
01448     __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
01449     (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
01450     __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_TXERR);
01451   }
01452   else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_DTERR) == USB_OTG_HCINT_DTERR)
01453   {
01454     __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
01455     (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
01456     __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
01457     __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_DTERR);
01458     hhcd->hc[ch_num].state = HC_DATATGLERR;
01459   }
01460   else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_CHH) == USB_OTG_HCINT_CHH)
01461   {
01462     __HAL_HCD_MASK_HALT_HC_INT(ch_num);
01463 
01464     if (hhcd->hc[ch_num].state == HC_XFRC)
01465     {
01466       hhcd->hc[ch_num].urb_state  = URB_DONE;
01467       if ((hhcd->hc[ch_num].ep_type == EP_TYPE_BULK) ||
01468           (hhcd->hc[ch_num].ep_type == EP_TYPE_INTR))
01469       {
01470         if (hhcd->Init.dma_enable == 0U)
01471         {
01472           hhcd->hc[ch_num].toggle_out ^= 1U;
01473         }
01474 
01475         if ((hhcd->Init.dma_enable == 1U) && (hhcd->hc[ch_num].xfer_len > 0U))
01476         {
01477           num_packets = (hhcd->hc[ch_num].xfer_len + hhcd->hc[ch_num].max_packet - 1U) / hhcd->hc[ch_num].max_packet;
01478 
01479           if ((num_packets & 1U) != 0U)
01480           {
01481             hhcd->hc[ch_num].toggle_out ^= 1U;
01482           }
01483         }
01484       }
01485     }
01486     else if (hhcd->hc[ch_num].state == HC_NAK)
01487     {
01488       hhcd->hc[ch_num].urb_state = URB_NOTREADY;
01489     }
01490     else if (hhcd->hc[ch_num].state == HC_NYET)
01491     {
01492       hhcd->hc[ch_num].urb_state  = URB_NOTREADY;
01493     }
01494     else if (hhcd->hc[ch_num].state == HC_STALL)
01495     {
01496       hhcd->hc[ch_num].urb_state  = URB_STALL;
01497     }
01498     else if ((hhcd->hc[ch_num].state == HC_XACTERR) ||
01499              (hhcd->hc[ch_num].state == HC_DATATGLERR))
01500     {
01501       hhcd->hc[ch_num].ErrCnt++;
01502       if (hhcd->hc[ch_num].ErrCnt > 2U)
01503       {
01504         hhcd->hc[ch_num].ErrCnt = 0U;
01505         hhcd->hc[ch_num].urb_state = URB_ERROR;
01506       }
01507       else
01508       {
01509         hhcd->hc[ch_num].urb_state = URB_NOTREADY;
01510 
01511         /* re-activate the channel  */
01512         tmpreg = USBx_HC(ch_num)->HCCHAR;
01513         tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
01514         tmpreg |= USB_OTG_HCCHAR_CHENA;
01515         USBx_HC(ch_num)->HCCHAR = tmpreg;
01516       }
01517     }
01518     else
01519     {
01520       /* ... */
01521     }
01522 
01523     __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_CHH);
01524     HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
01525   }
01526   else
01527   {
01528     /* ... */
01529   }
01530 }
01531 
01532 /**
01533   * @brief  Handle Rx Queue Level interrupt requests.
01534   * @param  hhcd HCD handle
01535   * @retval none
01536   */
01537 static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd)
01538 {
01539   USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
01540   uint32_t USBx_BASE = (uint32_t)USBx;
01541   uint32_t pktsts;
01542   uint32_t pktcnt;
01543   uint32_t GrxstspReg;
01544   uint32_t xferSizePktCnt;
01545   uint32_t tmpreg;
01546   uint32_t ch_num;
01547 
01548   GrxstspReg = hhcd->Instance->GRXSTSP;
01549   ch_num = GrxstspReg & USB_OTG_GRXSTSP_EPNUM;
01550   pktsts = (GrxstspReg & USB_OTG_GRXSTSP_PKTSTS) >> 17;
01551   pktcnt = (GrxstspReg & USB_OTG_GRXSTSP_BCNT) >> 4;
01552 
01553   switch (pktsts)
01554   {
01555     case GRXSTS_PKTSTS_IN:
01556       /* Read the data into the host buffer. */
01557       if ((pktcnt > 0U) && (hhcd->hc[ch_num].xfer_buff != (void *)0))
01558       {
01559         if ((hhcd->hc[ch_num].xfer_count + pktcnt) <= hhcd->hc[ch_num].xfer_len)
01560         {
01561           (void)USB_ReadPacket(hhcd->Instance,
01562                                hhcd->hc[ch_num].xfer_buff, (uint16_t)pktcnt);
01563 
01564           /* manage multiple Xfer */
01565           hhcd->hc[ch_num].xfer_buff += pktcnt;
01566           hhcd->hc[ch_num].xfer_count += pktcnt;
01567 
01568           /* get transfer size packet count */
01569           xferSizePktCnt = (USBx_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) >> 19;
01570 
01571           if ((hhcd->hc[ch_num].max_packet == pktcnt) && (xferSizePktCnt > 0U))
01572           {
01573             /* re-activate the channel when more packets are expected */
01574             tmpreg = USBx_HC(ch_num)->HCCHAR;
01575             tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
01576             tmpreg |= USB_OTG_HCCHAR_CHENA;
01577             USBx_HC(ch_num)->HCCHAR = tmpreg;
01578             hhcd->hc[ch_num].toggle_in ^= 1U;
01579           }
01580         }
01581         else
01582         {
01583           hhcd->hc[ch_num].urb_state = URB_ERROR;
01584         }
01585       }
01586       break;
01587 
01588     case GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
01589       break;
01590 
01591     case GRXSTS_PKTSTS_IN_XFER_COMP:
01592     case GRXSTS_PKTSTS_CH_HALTED:
01593     default:
01594       break;
01595   }
01596 }
01597 
01598 /**
01599   * @brief  Handle Host Port interrupt requests.
01600   * @param  hhcd HCD handle
01601   * @retval None
01602   */
01603 static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd)
01604 {
01605   USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
01606   uint32_t USBx_BASE = (uint32_t)USBx;
01607   __IO uint32_t hprt0;
01608   __IO uint32_t hprt0_dup;
01609 
01610   /* Handle Host Port Interrupts */
01611   hprt0 = USBx_HPRT0;
01612   hprt0_dup = USBx_HPRT0;
01613 
01614   hprt0_dup &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET | \
01615                  USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
01616 
01617   /* Check whether Port Connect detected */
01618   if ((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET)
01619   {
01620     if ((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS)
01621     {
01622 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
01623       hhcd->ConnectCallback(hhcd);
01624 #else
01625       HAL_HCD_Connect_Callback(hhcd);
01626 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
01627     }
01628     hprt0_dup |= USB_OTG_HPRT_PCDET;
01629   }
01630 
01631   /* Check whether Port Enable Changed */
01632   if ((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG)
01633   {
01634     hprt0_dup |= USB_OTG_HPRT_PENCHNG;
01635 
01636     if ((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA)
01637     {
01638       if (hhcd->Init.phy_itface  == USB_OTG_EMBEDDED_PHY)
01639       {
01640         if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17))
01641         {
01642           (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_6_MHZ);
01643         }
01644         else
01645         {
01646           (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_48_MHZ);
01647         }
01648       }
01649       else
01650       {
01651         if (hhcd->Init.speed == HCD_SPEED_FULL)
01652         {
01653           USBx_HOST->HFIR = 60000U;
01654         }
01655       }
01656 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
01657       hhcd->PortEnabledCallback(hhcd);
01658 #else
01659       HAL_HCD_PortEnabled_Callback(hhcd);
01660 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
01661 
01662     }
01663     else
01664     {
01665 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
01666       hhcd->PortDisabledCallback(hhcd);
01667 #else
01668       HAL_HCD_PortDisabled_Callback(hhcd);
01669 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
01670     }
01671   }
01672 
01673   /* Check for an overcurrent */
01674   if ((hprt0 & USB_OTG_HPRT_POCCHNG) == USB_OTG_HPRT_POCCHNG)
01675   {
01676     hprt0_dup |= USB_OTG_HPRT_POCCHNG;
01677   }
01678 
01679   /* Clear Port Interrupts */
01680   USBx_HPRT0 = hprt0_dup;
01681 }
01682 
01683 /**
01684   * @}
01685   */
01686 
01687 /**
01688   * @}
01689   */
01690 
01691 #endif /* defined (USB_OTG_FS) */
01692 #endif /* HAL_HCD_MODULE_ENABLED */
01693 
01694 /**
01695   * @}
01696   */
01697 
01698 /**
01699   * @}
01700   */
01701 
01702 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/