STM32F439xx HAL User Manual
stm32f4xx_hal_hcd.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f4xx_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              (+++) __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); (For High Speed Mode)
00029              (+++) __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE(); (For High Speed Mode)
00030            
00031         (##) Initialize the related GPIO clocks
00032         (##) Configure HCD pin-out
00033         (##) Configure HCD NVIC interrupt
00034     
00035     (#)Associate the Upper USB Host stack to the HAL HCD Driver:
00036         (##) hhcd.pData = phost;
00037 
00038     (#)Enable HCD transmission and reception:
00039         (##) HAL_HCD_Start();
00040 
00041   @endverbatim
00042   ******************************************************************************
00043   * @attention
00044   *
00045   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
00046   *
00047   * Redistribution and use in source and binary forms, with or without modification,
00048   * are permitted provided that the following conditions are met:
00049   *   1. Redistributions of source code must retain the above copyright notice,
00050   *      this list of conditions and the following disclaimer.
00051   *   2. Redistributions in binary form must reproduce the above copyright notice,
00052   *      this list of conditions and the following disclaimer in the documentation
00053   *      and/or other materials provided with the distribution.
00054   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00055   *      may be used to endorse or promote products derived from this software
00056   *      without specific prior written permission.
00057   *
00058   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00059   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00060   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00061   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00062   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00063   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00064   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00065   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00066   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00067   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00068   *
00069   ******************************************************************************
00070   */ 
00071 
00072 /* Includes ------------------------------------------------------------------*/
00073 #include "stm32f4xx_hal.h"
00074 
00075 /** @addtogroup STM32F4xx_HAL_Driver
00076   * @{
00077   */
00078 
00079 /** @defgroup HCD HCD 
00080   * @brief HCD HAL module driver
00081   * @{
00082   */
00083 
00084 #ifdef HAL_HCD_MODULE_ENABLED
00085 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || \
00086     defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || \
00087     defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) || \
00088     defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || \
00089     defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
00090 /* Private typedef -----------------------------------------------------------*/
00091 /* Private define ------------------------------------------------------------*/
00092 /* Private macro -------------------------------------------------------------*/
00093 /* Private variables ---------------------------------------------------------*/
00094 /* Private function prototypes -----------------------------------------------*/
00095 /** @defgroup HCD_Private_Functions HCD Private Functions
00096   * @{
00097   */
00098 static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
00099 static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum); 
00100 static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd);
00101 static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd);
00102 /**
00103   * @}
00104   */
00105 
00106 /* Exported functions --------------------------------------------------------*/
00107 /** @defgroup HCD_Exported_Functions HCD Exported Functions
00108   * @{
00109   */
00110 
00111 /** @defgroup HCD_Exported_Functions_Group1 Initialization and de-initialization functions 
00112  *  @brief    Initialization and Configuration functions 
00113  *
00114 @verbatim     
00115  ===============================================================================
00116           ##### Initialization and de-initialization functions #####
00117  ===============================================================================
00118     [..]  This section provides functions allowing to:
00119  
00120 @endverbatim
00121   * @{
00122   */
00123 
00124 /**
00125   * @brief  Initialize the host driver.
00126   * @param  hhcd HCD handle
00127   * @retval HAL status
00128   */
00129 HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd)
00130 { 
00131   /* Check the HCD handle allocation */
00132   if(hhcd == NULL)
00133   {
00134     return HAL_ERROR;
00135   }
00136   
00137   /* Check the parameters */
00138   assert_param(IS_HCD_ALL_INSTANCE(hhcd->Instance));
00139   
00140   hhcd->State = HAL_HCD_STATE_BUSY;
00141   
00142   /* Init the low level hardware : GPIO, CLOCK, NVIC... */
00143   HAL_HCD_MspInit(hhcd);
00144   
00145   /* Disable the Interrupts */
00146   __HAL_HCD_DISABLE(hhcd);
00147   
00148   /* Init the Core (common init.) */
00149   USB_CoreInit(hhcd->Instance, hhcd->Init);
00150   
00151   /* Force Host Mode*/
00152   USB_SetCurrentMode(hhcd->Instance , USB_OTG_HOST_MODE);
00153   
00154   /* Init Host */
00155   USB_HostInit(hhcd->Instance, hhcd->Init);
00156   
00157   hhcd->State= HAL_HCD_STATE_READY;
00158   
00159   return HAL_OK;
00160 }
00161 
00162 /**
00163   * @brief  Initialize a host channel.
00164   * @param  hhcd HCD handle
00165   * @param  ch_num Channel number.
00166   *         This parameter can be a value from 1 to 15
00167   * @param  epnum Endpoint number.
00168   *          This parameter can be a value from 1 to 15
00169   * @param  dev_address  Current device address
00170   *          This parameter can be a value from 0 to 255
00171   * @param  speed Current device speed.
00172   *          This parameter can be one of these values:
00173   *            HCD_SPEED_HIGH: High speed mode,
00174   *            HCD_SPEED_FULL: Full speed mode,
00175   *            HCD_SPEED_LOW: Low speed mode
00176   * @param  ep_type Endpoint Type.
00177   *          This parameter can be one of these values:
00178   *            EP_TYPE_CTRL: Control type,
00179   *            EP_TYPE_ISOC: Isochronous type,
00180   *            EP_TYPE_BULK: Bulk type,
00181   *            EP_TYPE_INTR: Interrupt type
00182   * @param  mps Max Packet Size.
00183   *          This parameter can be a value from 0 to32K
00184   * @retval HAL status
00185   */
00186 HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd,  
00187                                   uint8_t ch_num,
00188                                   uint8_t epnum,
00189                                   uint8_t dev_address,
00190                                   uint8_t speed,
00191                                   uint8_t ep_type,
00192                                   uint16_t mps)
00193 {
00194   HAL_StatusTypeDef status = HAL_OK;
00195   
00196   __HAL_LOCK(hhcd); 
00197   
00198   hhcd->hc[ch_num].dev_addr = dev_address;
00199   hhcd->hc[ch_num].max_packet = mps;
00200   hhcd->hc[ch_num].ch_num = ch_num;
00201   hhcd->hc[ch_num].ep_type = ep_type;
00202   hhcd->hc[ch_num].ep_num = epnum & 0x7F;
00203   hhcd->hc[ch_num].ep_is_in = ((epnum & 0x80) == 0x80);
00204   hhcd->hc[ch_num].speed = speed;
00205   
00206   status =  USB_HC_Init(hhcd->Instance, 
00207                         ch_num,
00208                         epnum,
00209                         dev_address,
00210                         speed,
00211                         ep_type,
00212                         mps);
00213   __HAL_UNLOCK(hhcd); 
00214   
00215   return status;
00216 }
00217 
00218 /**
00219   * @brief  Halt a host channel.
00220   * @param  hhcd HCD handle
00221   * @param  ch_num Channel number.
00222   *         This parameter can be a value from 1 to 15
00223   * @retval HAL status
00224   */
00225 HAL_StatusTypeDef HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd, uint8_t ch_num)
00226 {
00227   HAL_StatusTypeDef status = HAL_OK;
00228   
00229   __HAL_LOCK(hhcd);   
00230   USB_HC_Halt(hhcd->Instance, ch_num);   
00231   __HAL_UNLOCK(hhcd);
00232   
00233   return status;
00234 }
00235 
00236 /**
00237   * @brief  DeInitialize the host driver.
00238   * @param  hhcd HCD handle
00239   * @retval HAL status
00240   */
00241 HAL_StatusTypeDef HAL_HCD_DeInit(HCD_HandleTypeDef *hhcd)
00242 {
00243   /* Check the HCD handle allocation */
00244   if(hhcd == NULL)
00245   {
00246     return HAL_ERROR;
00247   }
00248   
00249   hhcd->State = HAL_HCD_STATE_BUSY;
00250   
00251   /* DeInit the low level hardware */
00252   HAL_HCD_MspDeInit(hhcd);
00253   
00254   __HAL_HCD_DISABLE(hhcd);
00255   
00256   hhcd->State = HAL_HCD_STATE_RESET; 
00257   
00258   return HAL_OK;
00259 }
00260 
00261 /**
00262   * @brief  Initialize the HCD MSP.
00263   * @param  hhcd HCD handle
00264   * @retval None
00265   */
00266 __weak void  HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd)
00267 {
00268   /* Prevent unused argument(s) compilation warning */
00269   UNUSED(hhcd);
00270   /* NOTE : This function Should not be modified, when the callback is needed,
00271             the HAL_PCD_MspInit could be implemented in the user file
00272    */
00273 }
00274 
00275 /**
00276   * @brief  DeInitialize the HCD MSP.
00277   * @param  hhcd HCD handle
00278   * @retval None
00279   */
00280 __weak void  HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd)
00281 {
00282   /* Prevent unused argument(s) compilation warning */
00283   UNUSED(hhcd);
00284   /* NOTE : This function Should not be modified, when the callback is needed,
00285             the HAL_PCD_MspDeInit could be implemented in the user file
00286    */
00287 }
00288 
00289 /**
00290   * @}
00291   */
00292 
00293 /** @defgroup HCD_Exported_Functions_Group2 Input and Output operation functions
00294   *  @brief   HCD IO operation functions
00295   *
00296 @verbatim
00297  ===============================================================================
00298                       ##### IO operation functions #####
00299  ===============================================================================
00300  [..] This subsection provides a set of functions allowing to manage the USB Host Data 
00301     Transfer
00302        
00303 @endverbatim
00304   * @{
00305   */
00306   
00307 /**                                
00308   * @brief  Submit a new URB for processing. 
00309   * @param  hhcd HCD handle
00310   * @param  ch_num Channel number.
00311   *         This parameter can be a value from 1 to 15
00312   * @param  direction Channel number.
00313   *          This parameter can be one of these values:
00314   *           0 : Output / 1 : Input
00315   * @param  ep_type Endpoint Type.
00316   *          This parameter can be one of these values:
00317   *            EP_TYPE_CTRL: Control type/
00318   *            EP_TYPE_ISOC: Isochronous type/
00319   *            EP_TYPE_BULK: Bulk type/
00320   *            EP_TYPE_INTR: Interrupt type/
00321   * @param  token Endpoint Type.
00322   *          This parameter can be one of these values:
00323   *            0: HC_PID_SETUP / 1: HC_PID_DATA1
00324   * @param  pbuff pointer to URB data
00325   * @param  length Length of URB data
00326   * @param  do_ping activate do ping protocol (for high speed only).
00327   *          This parameter can be one of these values:
00328   *           0 : do ping inactive / 1 : do ping active 
00329   * @retval HAL status
00330   */
00331 HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd,
00332                                            uint8_t ch_num, 
00333                                            uint8_t direction,
00334                                            uint8_t ep_type,  
00335                                            uint8_t token, 
00336                                            uint8_t* pbuff, 
00337                                            uint16_t length,
00338                                            uint8_t do_ping) 
00339 {
00340   hhcd->hc[ch_num].ep_is_in = direction;
00341   hhcd->hc[ch_num].ep_type  = ep_type; 
00342   
00343   if(token == 0)
00344   {
00345     hhcd->hc[ch_num].data_pid = HC_PID_SETUP;
00346   }
00347   else
00348   {
00349     hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
00350   }
00351   
00352   /* Manage Data Toggle */
00353   switch(ep_type)
00354   {
00355   case EP_TYPE_CTRL:
00356     if((token == 1) && (direction == 0)) /*send data */
00357     {
00358       if (length == 0)
00359       { /* For Status OUT stage, Length==0, Status Out PID = 1 */
00360         hhcd->hc[ch_num].toggle_out = 1;
00361       }
00362       
00363       /* Set the Data Toggle bit as per the Flag */
00364       if (hhcd->hc[ch_num].toggle_out == 0)
00365       { /* Put the PID 0 */
00366         hhcd->hc[ch_num].data_pid = HC_PID_DATA0;    
00367       }
00368       else
00369       { /* Put the PID 1 */
00370         hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
00371       }
00372       if(hhcd->hc[ch_num].urb_state  != URB_NOTREADY)
00373       {
00374         hhcd->hc[ch_num].do_ping = do_ping;
00375       }
00376     }
00377     break;
00378   
00379   case EP_TYPE_BULK:
00380     if(direction == 0)
00381     {
00382       /* Set the Data Toggle bit as per the Flag */
00383       if ( hhcd->hc[ch_num].toggle_out == 0)
00384       { /* Put the PID 0 */
00385         hhcd->hc[ch_num].data_pid = HC_PID_DATA0;    
00386       }
00387       else
00388       { /* Put the PID 1 */
00389         hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
00390       }
00391       if(hhcd->hc[ch_num].urb_state  != URB_NOTREADY)
00392       {
00393         hhcd->hc[ch_num].do_ping = do_ping;
00394       }
00395     }
00396     else
00397     {
00398       if( hhcd->hc[ch_num].toggle_in == 0)
00399       {
00400         hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
00401       }
00402       else
00403       {
00404         hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
00405       }
00406     }
00407     
00408     break;
00409   case EP_TYPE_INTR:
00410     if(direction == 0)
00411     {
00412       /* Set the Data Toggle bit as per the Flag */
00413       if ( hhcd->hc[ch_num].toggle_out == 0)
00414       { /* Put the PID 0 */
00415         hhcd->hc[ch_num].data_pid = HC_PID_DATA0;    
00416       }
00417       else
00418       { /* Put the PID 1 */
00419         hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
00420       }
00421     }
00422     else
00423     {
00424       if( hhcd->hc[ch_num].toggle_in == 0)
00425       {
00426         hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
00427       }
00428       else
00429       {
00430         hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
00431       }
00432     }
00433     break;
00434     
00435   case EP_TYPE_ISOC: 
00436     hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
00437     break;  
00438   }
00439   
00440   hhcd->hc[ch_num].xfer_buff = pbuff;
00441   hhcd->hc[ch_num].xfer_len  = length;
00442   hhcd->hc[ch_num].urb_state = URB_IDLE;  
00443   hhcd->hc[ch_num].xfer_count = 0;
00444   hhcd->hc[ch_num].ch_num = ch_num;
00445   hhcd->hc[ch_num].state = HC_IDLE;
00446   
00447   return USB_HC_StartXfer(hhcd->Instance, &(hhcd->hc[ch_num]), hhcd->Init.dma_enable);
00448 }
00449 
00450 /**
00451   * @brief  Handle HCD interrupt request.
00452   * @param  hhcd HCD handle
00453   * @retval None
00454   */
00455 void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd)
00456 {
00457   USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
00458   uint32_t i = 0U , interrupt = 0U;
00459   
00460   /* Ensure that we are in device mode */
00461   if (USB_GetMode(hhcd->Instance) == USB_OTG_MODE_HOST)
00462   {
00463     /* Avoid spurious interrupt */
00464     if(__HAL_HCD_IS_INVALID_INTERRUPT(hhcd)) 
00465     {
00466       return;
00467     }
00468     
00469     if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
00470     {
00471       /* Incorrect mode, acknowledge the interrupt */
00472       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
00473     }
00474     
00475     if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR))
00476     {
00477       /* Incorrect mode, acknowledge the interrupt */
00478       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR);
00479     }
00480     
00481     if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE))
00482     {
00483       /* Incorrect mode, acknowledge the interrupt */
00484       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE);
00485     }   
00486     
00487     if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_MMIS))
00488     {
00489       /* Incorrect mode, acknowledge the interrupt */
00490       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_MMIS);
00491     }     
00492     
00493     /* Handle Host Disconnect Interrupts */
00494     if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT))
00495     {
00496       
00497       /* Cleanup HPRT */
00498       USBx_HPRT0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
00499         USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
00500       
00501       /* Handle Host Port Interrupts */
00502       HAL_HCD_Disconnect_Callback(hhcd);
00503       USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_48_MHZ );
00504       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT);
00505     }
00506     
00507     /* Handle Host Port Interrupts */
00508     if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HPRTINT))
00509     {
00510       HCD_Port_IRQHandler (hhcd);
00511     }
00512     
00513     /* Handle Host SOF Interrupts */
00514     if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_SOF))
00515     {
00516       HAL_HCD_SOF_Callback(hhcd);
00517       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_SOF);
00518     }
00519     
00520     /* Handle Host channel Interrupts */
00521     if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HCINT))
00522     {
00523       interrupt = USB_HC_ReadInterrupt(hhcd->Instance);
00524       for (i = 0U; i < hhcd->Init.Host_channels; i++)
00525       {
00526         if (interrupt & (1U << i))
00527         {
00528           if ((USBx_HC(i)->HCCHAR) &  USB_OTG_HCCHAR_EPDIR)
00529           {
00530             HCD_HC_IN_IRQHandler(hhcd, i);
00531           }
00532           else
00533           {
00534             HCD_HC_OUT_IRQHandler (hhcd, i);
00535           }
00536         }
00537       }
00538       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_HCINT);
00539     } 
00540     
00541     /* Handle Rx Queue Level Interrupts */
00542     if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_RXFLVL))
00543     {
00544       USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
00545       
00546       HCD_RXQLVL_IRQHandler (hhcd);
00547       
00548       USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
00549     }
00550   }
00551 }
00552 
00553 /**
00554   * @brief  SOF callback.
00555   * @param  hhcd HCD handle
00556   * @retval None
00557   */
00558 __weak void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd)
00559 {
00560   /* Prevent unused argument(s) compilation warning */
00561   UNUSED(hhcd);
00562   /* NOTE : This function Should not be modified, when the callback is needed,
00563             the HAL_HCD_SOF_Callback could be implemented in the user file
00564    */
00565 }
00566 
00567 /**
00568   * @brief Connection Event callback.
00569   * @param  hhcd HCD handle
00570   * @retval None
00571   */
00572 __weak void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
00573 {
00574   /* Prevent unused argument(s) compilation warning */
00575   UNUSED(hhcd);
00576   /* NOTE : This function Should not be modified, when the callback is needed,
00577             the HAL_HCD_Connect_Callback could be implemented in the user file
00578    */
00579 }
00580 
00581 /**
00582   * @brief  Disconnection Event callback.
00583   * @param  hhcd HCD handle
00584   * @retval None
00585   */
00586 __weak void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
00587 {
00588   /* Prevent unused argument(s) compilation warning */
00589   UNUSED(hhcd);
00590   /* NOTE : This function Should not be modified, when the callback is needed,
00591             the HAL_HCD_Disconnect_Callback could be implemented in the user file
00592    */
00593 } 
00594 
00595 /**
00596   * @brief  Notify URB state change callback.
00597   * @param  hhcd HCD handle
00598   * @param  chnum Channel number.
00599   *         This parameter can be a value from 1 to 15
00600   * @param  urb_state:
00601   *          This parameter can be one of these values:
00602   *            URB_IDLE/
00603   *            URB_DONE/
00604   *            URB_NOTREADY/
00605   *            URB_NYET/
00606   *            URB_ERROR/
00607   *            URB_STALL/
00608   * @retval None
00609   */
00610 __weak void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state)
00611 {
00612   /* Prevent unused argument(s) compilation warning */
00613   UNUSED(hhcd);
00614   UNUSED(chnum);
00615   UNUSED(urb_state);
00616   /* NOTE : This function Should not be modified, when the callback is needed,
00617             the HAL_HCD_HC_NotifyURBChange_Callback could be implemented in the user file
00618    */
00619 }
00620 
00621 /**
00622   * @}
00623   */
00624 
00625 /** @defgroup HCD_Exported_Functions_Group3 Peripheral Control functions 
00626  *  @brief   Management functions 
00627  *
00628 @verbatim 
00629  ===============================================================================
00630                       ##### Peripheral Control functions #####
00631  ===============================================================================  
00632     [..]
00633     This subsection provides a set of functions allowing to control the HCD data 
00634     transfers.
00635 
00636 @endverbatim
00637   * @{
00638   */
00639 
00640 /**
00641   * @brief  Start the host driver.
00642   * @param  hhcd HCD handle
00643   * @retval HAL status
00644   */
00645 HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd)
00646 { 
00647   __HAL_LOCK(hhcd); 
00648   __HAL_HCD_ENABLE(hhcd);
00649   USB_DriveVbus(hhcd->Instance, 1U);  
00650   __HAL_UNLOCK(hhcd); 
00651   return HAL_OK;
00652 }
00653 
00654 /**
00655   * @brief  Stop the host driver.
00656   * @param  hhcd HCD handle
00657   * @retval HAL status
00658   */
00659 
00660 HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd)
00661 { 
00662   __HAL_LOCK(hhcd); 
00663   USB_StopHost(hhcd->Instance);
00664   __HAL_UNLOCK(hhcd); 
00665   return HAL_OK;
00666 }
00667 
00668 /**
00669   * @brief  Reset the host port.
00670   * @param  hhcd HCD handle
00671   * @retval HAL status
00672   */
00673 HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd)
00674 {
00675   return (USB_ResetPort(hhcd->Instance));
00676 }
00677 
00678 /**
00679   * @}
00680   */
00681 
00682 /** @defgroup HCD_Exported_Functions_Group4 Peripheral State functions 
00683  *  @brief   Peripheral State functions 
00684  *
00685 @verbatim 
00686  ===============================================================================
00687                       ##### Peripheral State functions #####
00688  ===============================================================================  
00689     [..]
00690     This subsection permits to get in run-time the status of the peripheral 
00691     and the data flow.
00692 
00693 @endverbatim
00694   * @{
00695   */
00696 
00697 /**
00698   * @brief  Return the HCD handle state.
00699   * @param  hhcd HCD handle
00700   * @retval HAL state
00701   */
00702 HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef *hhcd)
00703 {
00704   return hhcd->State;
00705 }
00706 
00707 /**
00708   * @brief  Return  URB state for a channel.
00709   * @param  hhcd HCD handle
00710   * @param  chnum Channel number.
00711   *         This parameter can be a value from 1 to 15
00712   * @retval URB state.
00713   *          This parameter can be one of these values:
00714   *            URB_IDLE/
00715   *            URB_DONE/
00716   *            URB_NOTREADY/
00717   *            URB_NYET/ 
00718   *            URB_ERROR/  
00719   *            URB_STALL      
00720   */
00721 HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef *hhcd, uint8_t chnum)
00722 {
00723   return hhcd->hc[chnum].urb_state;
00724 }
00725 
00726 
00727 /**
00728   * @brief  Return the last host transfer size.
00729   * @param  hhcd HCD handle
00730   * @param  chnum Channel number.
00731   *         This parameter can be a value from 1 to 15
00732   * @retval last transfer size in byte
00733   */
00734 uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef *hhcd, uint8_t chnum)
00735 {
00736   return hhcd->hc[chnum].xfer_count; 
00737 }
00738   
00739 /**
00740   * @brief  Return the Host Channel state.
00741   * @param  hhcd HCD handle
00742   * @param  chnum Channel number.
00743   *         This parameter can be a value from 1 to 15
00744   * @retval Host channel state
00745   *          This parameter can be one of these values:
00746   *            HC_IDLE/
00747   *            HC_XFRC/
00748   *            HC_HALTED/
00749   *            HC_NYET/ 
00750   *            HC_NAK/  
00751   *            HC_STALL/ 
00752   *            HC_XACTERR/  
00753   *            HC_BBLERR/  
00754   *            HC_DATATGLERR    
00755   */
00756 HCD_HCStateTypeDef  HAL_HCD_HC_GetState(HCD_HandleTypeDef *hhcd, uint8_t chnum)
00757 {
00758   return hhcd->hc[chnum].state;
00759 }
00760 
00761 /**
00762   * @brief  Return the current Host frame number.
00763   * @param  hhcd HCD handle
00764   * @retval Current Host frame number
00765   */
00766 uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd)
00767 {
00768   return (USB_GetCurrentFrame(hhcd->Instance));
00769 }
00770 
00771 /**
00772   * @brief  Return the Host enumeration speed.
00773   * @param  hhcd HCD handle
00774   * @retval Enumeration speed
00775   */
00776 uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd)
00777 {
00778   return (USB_GetHostSpeed(hhcd->Instance));
00779 }
00780 
00781 /**
00782   * @}
00783   */
00784 
00785 /**
00786   * @}
00787   */
00788 
00789 /** @addtogroup HCD_Private_Functions
00790   * @{
00791   */
00792 /**
00793   * @brief  Handle Host Channel IN interrupt requests.
00794   * @param  hhcd HCD handle
00795   * @param  chnum Channel number.
00796   *         This parameter can be a value from 1 to 15
00797   * @retval None
00798   */
00799 static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
00800 {
00801   USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
00802   uint32_t tmpreg = 0U;
00803   
00804   if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_AHBERR)
00805   {
00806     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR);
00807     __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
00808   }  
00809   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_ACK)
00810   {
00811     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
00812   }
00813   
00814   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_STALL)  
00815   {
00816     __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
00817     hhcd->hc[chnum].state = HC_STALL;
00818     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
00819     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL);    
00820     USB_HC_Halt(hhcd->Instance, chnum);    
00821   }
00822   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_DTERR)
00823   {
00824     __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
00825     USB_HC_Halt(hhcd->Instance, chnum);  
00826     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);    
00827     hhcd->hc[chnum].state = HC_DATATGLERR;
00828     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR);
00829   }    
00830   
00831   if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_FRMOR)
00832   {
00833     __HAL_HCD_UNMASK_HALT_HC_INT(chnum); 
00834     USB_HC_Halt(hhcd->Instance, chnum);  
00835     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR);
00836   }
00837   
00838   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_XFRC)
00839   {
00840     
00841     if (hhcd->Init.dma_enable)
00842     {
00843       hhcd->hc[chnum].xfer_count = hhcd->hc[chnum].xfer_len - \
00844         (USBx_HC(chnum)->HCTSIZ & USB_OTG_HCTSIZ_XFRSIZ);
00845     }
00846     
00847     hhcd->hc[chnum].state = HC_XFRC;
00848     hhcd->hc[chnum].ErrCnt = 0U;
00849     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC);
00850     
00851     
00852     if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL)||
00853         (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
00854     {
00855       __HAL_HCD_UNMASK_HALT_HC_INT(chnum); 
00856       USB_HC_Halt(hhcd->Instance, chnum); 
00857       __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
00858       
00859     }
00860     else if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
00861     {
00862       USBx_HC(chnum)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
00863       hhcd->hc[chnum].urb_state = URB_DONE; 
00864       HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
00865     }
00866     hhcd->hc[chnum].toggle_in ^= 1U;
00867     
00868   }
00869   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_CHH)
00870   {
00871     __HAL_HCD_MASK_HALT_HC_INT(chnum); 
00872     
00873     if(hhcd->hc[chnum].state == HC_XFRC)
00874     {
00875       hhcd->hc[chnum].urb_state  = URB_DONE;      
00876     }
00877     
00878     else if (hhcd->hc[chnum].state == HC_STALL) 
00879     {
00880       hhcd->hc[chnum].urb_state  = URB_STALL;
00881     }   
00882     
00883     else if((hhcd->hc[chnum].state == HC_XACTERR) ||
00884             (hhcd->hc[chnum].state == HC_DATATGLERR))
00885     {
00886       if(hhcd->hc[chnum].ErrCnt++ > 3U)
00887       {      
00888         hhcd->hc[chnum].ErrCnt = 0U;
00889         hhcd->hc[chnum].urb_state = URB_ERROR;
00890       }
00891       else
00892       {
00893         hhcd->hc[chnum].urb_state = URB_NOTREADY;
00894       }
00895       
00896       /* re-activate the channel  */
00897       tmpreg = USBx_HC(chnum)->HCCHAR;
00898       tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
00899       tmpreg |= USB_OTG_HCCHAR_CHENA;
00900       USBx_HC(chnum)->HCCHAR = tmpreg;
00901     }
00902     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
00903     HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
00904   }  
00905   
00906   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_TXERR)
00907   {
00908     __HAL_HCD_UNMASK_HALT_HC_INT(chnum); 
00909     hhcd->hc[chnum].ErrCnt++;
00910     hhcd->hc[chnum].state = HC_XACTERR;
00911     USB_HC_Halt(hhcd->Instance, chnum);     
00912     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR);
00913   }
00914   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_NAK)
00915   {  
00916     if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
00917     {
00918       __HAL_HCD_UNMASK_HALT_HC_INT(chnum); 
00919       USB_HC_Halt(hhcd->Instance, chnum);  
00920     }
00921     
00922      /* Clear the NAK flag before re-enabling the channel for new IN request */
00923     hhcd->hc[chnum].state = HC_NAK;
00924     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
00925     
00926     if  ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL)||
00927               (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
00928     {
00929       /* re-activate the channel */
00930       tmpreg = USBx_HC(chnum)->HCCHAR;
00931       tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
00932       tmpreg |= USB_OTG_HCCHAR_CHENA;
00933       USBx_HC(chnum)->HCCHAR = tmpreg;
00934     }
00935   }
00936 }
00937 
00938 /**
00939   * @brief  Handle Host Channel OUT interrupt requests.
00940   * @param  hhcd HCD handle
00941   * @param  chnum Channel number.
00942   *         This parameter can be a value from 1 to 15
00943   * @retval None
00944   */
00945 static void HCD_HC_OUT_IRQHandler  (HCD_HandleTypeDef *hhcd, uint8_t chnum)
00946 {
00947   USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
00948   
00949   if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_AHBERR)
00950   {
00951     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR);
00952     __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
00953   }  
00954   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_ACK)
00955   {
00956     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
00957     
00958     if( hhcd->hc[chnum].do_ping == 1U)
00959     {
00960       hhcd->hc[chnum].state = HC_NYET;     
00961       __HAL_HCD_UNMASK_HALT_HC_INT(chnum); 
00962       USB_HC_Halt(hhcd->Instance, chnum); 
00963       hhcd->hc[chnum].urb_state  = URB_NOTREADY;
00964     }
00965   }
00966   
00967   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_NYET)
00968   {
00969     hhcd->hc[chnum].state = HC_NYET;
00970     hhcd->hc[chnum].ErrCnt= 0U;    
00971     __HAL_HCD_UNMASK_HALT_HC_INT(chnum); 
00972     USB_HC_Halt(hhcd->Instance, chnum);      
00973     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NYET);
00974     
00975   }  
00976   
00977   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_FRMOR)
00978   {
00979     __HAL_HCD_UNMASK_HALT_HC_INT(chnum); 
00980     USB_HC_Halt(hhcd->Instance, chnum);  
00981     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR);
00982   }
00983   
00984   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_XFRC)
00985   {
00986       hhcd->hc[chnum].ErrCnt = 0U;  
00987     __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
00988     USB_HC_Halt(hhcd->Instance, chnum);   
00989     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC);
00990     hhcd->hc[chnum].state = HC_XFRC;
00991 
00992   }  
00993 
00994   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_STALL)  
00995   {
00996     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL);  
00997     __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
00998     USB_HC_Halt(hhcd->Instance, chnum);   
00999     hhcd->hc[chnum].state = HC_STALL;    
01000   }
01001 
01002   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_NAK)
01003   {  
01004     hhcd->hc[chnum].ErrCnt = 0U;  
01005     __HAL_HCD_UNMASK_HALT_HC_INT(chnum); 
01006     USB_HC_Halt(hhcd->Instance, chnum);   
01007     hhcd->hc[chnum].state = HC_NAK;
01008     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
01009   }
01010 
01011   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_TXERR)
01012   {
01013     __HAL_HCD_UNMASK_HALT_HC_INT(chnum); 
01014     USB_HC_Halt(hhcd->Instance, chnum);      
01015     hhcd->hc[chnum].state = HC_XACTERR;  
01016      __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR);
01017   }
01018   
01019   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_DTERR)
01020   {
01021     __HAL_HCD_UNMASK_HALT_HC_INT(chnum); 
01022     USB_HC_Halt(hhcd->Instance, chnum);      
01023     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
01024     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR);    
01025     hhcd->hc[chnum].state = HC_DATATGLERR;
01026   }
01027   
01028   
01029   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_CHH)
01030   {
01031     __HAL_HCD_MASK_HALT_HC_INT(chnum); 
01032     
01033     if(hhcd->hc[chnum].state == HC_XFRC)
01034     {
01035       hhcd->hc[chnum].urb_state  = URB_DONE;
01036       if (hhcd->hc[chnum].ep_type == EP_TYPE_BULK)
01037       {
01038         hhcd->hc[chnum].toggle_out ^= 1U; 
01039       }      
01040     }
01041     else if (hhcd->hc[chnum].state == HC_NAK) 
01042     {
01043       hhcd->hc[chnum].urb_state  = URB_NOTREADY;
01044     }  
01045     
01046     else if (hhcd->hc[chnum].state == HC_NYET) 
01047     {
01048       hhcd->hc[chnum].urb_state  = URB_NOTREADY;
01049       hhcd->hc[chnum].do_ping = 0U;
01050     }   
01051     
01052     else if (hhcd->hc[chnum].state == HC_STALL) 
01053     {
01054       hhcd->hc[chnum].urb_state  = URB_STALL;
01055     } 
01056     
01057     else if((hhcd->hc[chnum].state == HC_XACTERR) ||
01058             (hhcd->hc[chnum].state == HC_DATATGLERR))
01059     {
01060       if(hhcd->hc[chnum].ErrCnt++ > 3U)
01061       {      
01062         hhcd->hc[chnum].ErrCnt = 0U;
01063         hhcd->hc[chnum].urb_state = URB_ERROR;
01064       }
01065       else
01066       {
01067         hhcd->hc[chnum].urb_state = URB_NOTREADY;
01068       }
01069     }
01070     
01071     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
01072     HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);  
01073   }
01074 } 
01075 
01076 /**
01077   * @brief  Handle Rx Queue Level interrupt requests.
01078   * @param  hhcd HCD handle
01079   * @retval None
01080   */
01081 static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd)
01082 {
01083   USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;  
01084   uint8_t  channelnum = 0;  
01085   uint32_t pktsts;
01086   uint32_t pktcnt; 
01087   uint32_t temp = 0U;
01088   uint32_t tmpreg = 0U;
01089   
01090   temp = hhcd->Instance->GRXSTSP;
01091   channelnum = temp &  USB_OTG_GRXSTSP_EPNUM;  
01092   pktsts = (temp &  USB_OTG_GRXSTSP_PKTSTS) >> 17U;
01093   pktcnt = (temp &  USB_OTG_GRXSTSP_BCNT) >> 4U;
01094   
01095   switch (pktsts)
01096   {
01097   case GRXSTS_PKTSTS_IN:
01098     /* Read the data into the host buffer. */
01099     if ((pktcnt > 0U) && (hhcd->hc[channelnum].xfer_buff != (void  *)0))
01100     {  
01101       
01102       USB_ReadPacket(hhcd->Instance, hhcd->hc[channelnum].xfer_buff, pktcnt);
01103       
01104       /*manage multiple Xfer */
01105       hhcd->hc[channelnum].xfer_buff += pktcnt;           
01106       hhcd->hc[channelnum].xfer_count  += pktcnt;
01107       
01108       if((USBx_HC(channelnum)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) > 0)
01109       {
01110         /* re-activate the channel when more packets are expected */
01111         tmpreg = USBx_HC(channelnum)->HCCHAR;
01112         tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
01113         tmpreg |= USB_OTG_HCCHAR_CHENA;
01114         USBx_HC(channelnum)->HCCHAR = tmpreg;
01115         hhcd->hc[channelnum].toggle_in ^= 1;
01116       }
01117     }
01118     break;
01119     
01120   case GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
01121     break;
01122   case GRXSTS_PKTSTS_IN_XFER_COMP:
01123   case GRXSTS_PKTSTS_CH_HALTED:
01124   default:
01125     break;
01126   }
01127 }
01128 
01129 /**
01130   * @brief  Handle Host Port interrupt requests.
01131   * @param  hhcd HCD handle
01132   * @retval None
01133   */
01134 static void HCD_Port_IRQHandler  (HCD_HandleTypeDef *hhcd)
01135 {
01136   USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;  
01137   __IO uint32_t hprt0, hprt0_dup;
01138   
01139   /* Handle Host Port Interrupts */
01140   hprt0 = USBx_HPRT0;
01141   hprt0_dup = USBx_HPRT0;
01142   
01143   hprt0_dup &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
01144                  USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
01145   
01146   /* Check whether Port Connect Detected */
01147   if((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET)
01148   {  
01149     if((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS)
01150     {
01151       USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT);
01152       HAL_HCD_Connect_Callback(hhcd);
01153     }
01154     hprt0_dup  |= USB_OTG_HPRT_PCDET;
01155     
01156   }
01157   
01158   /* Check whether Port Enable Changed */
01159   if((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG)
01160   {
01161     hprt0_dup |= USB_OTG_HPRT_PENCHNG;
01162     
01163     if((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA)
01164     {    
01165       if(hhcd->Init.phy_itface  == USB_OTG_EMBEDDED_PHY)
01166       {
01167         if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17U))
01168         {
01169           USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_6_MHZ );
01170         }
01171         else
01172         {
01173           USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_48_MHZ );
01174         }
01175       }
01176       else
01177       {
01178         if(hhcd->Init.speed == HCD_SPEED_FULL)
01179         {
01180           USBx_HOST->HFIR = 60000U;
01181         }
01182       }
01183       
01184       HAL_HCD_Connect_Callback(hhcd);
01185     }
01186     else
01187     {
01188       /* Clean up HPRT */
01189       USBx_HPRT0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
01190         USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
01191       
01192       USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT); 
01193     }    
01194   }
01195   
01196   /* Check for an over current */
01197   if((hprt0 & USB_OTG_HPRT_POCCHNG) == USB_OTG_HPRT_POCCHNG)
01198   {
01199     hprt0_dup |= USB_OTG_HPRT_POCCHNG;
01200   }
01201 
01202   /* Clear Port Interrupts */
01203   USBx_HPRT0 = hprt0_dup;
01204 }
01205 
01206 /**
01207   * @}
01208   */
01209 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx ||
01210           STM32F401xC || STM32F401xE || STM32F411xE || STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Rx ||
01211           STM32F412Vx || STM32F412Cx || defined(STM32F413xx) || defined(STM32F423xx) */
01212 #endif /* HAL_HCD_MODULE_ENABLED */
01213 /**
01214   * @}
01215   */
01216 
01217 /**
01218   * @}
01219   */
01220 
01221 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/