TUKS MCU Introductory course / TUKS-COURSE-THERMOMETER

Fork of TUKS-COURSE-TIMER by TUKS MCU Introductory course

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32l4xx_hal_hcd.c Source File

stm32l4xx_hal_hcd.c

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