STM32F439xx HAL User Manual
stm32f4xx_hal_pcd.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f4xx_hal_pcd.c
00004   * @author  MCD Application Team
00005   * @brief   PCD 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       The PCD HAL driver can be used as follows:
00019 
00020      (#) Declare a PCD_HandleTypeDef handle structure, for example:
00021          PCD_HandleTypeDef  hpcd;
00022         
00023      (#) Fill parameters of Init structure in HCD handle
00024   
00025      (#) Call HAL_PCD_Init() API to initialize the PCD peripheral (Core, Device core, ...) 
00026 
00027      (#) Initialize the PCD low level resources through the HAL_PCD_MspInit() API:
00028          (##) Enable the PCD/USB Low Level interface clock using 
00029               (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
00030               (+++) __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); (For High Speed Mode)
00031            
00032          (##) Initialize the related GPIO clocks
00033          (##) Configure PCD pin-out
00034          (##) Configure PCD NVIC interrupt
00035     
00036      (#)Associate the Upper USB device stack to the HAL PCD Driver:
00037          (##) hpcd.pData = pdev;
00038 
00039      (#)Enable PCD transmission and reception:
00040          (##) HAL_PCD_Start();
00041 
00042   @endverbatim
00043   ******************************************************************************
00044   * @attention
00045   *
00046   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
00047   *
00048   * Redistribution and use in source and binary forms, with or without modification,
00049   * are permitted provided that the following conditions are met:
00050   *   1. Redistributions of source code must retain the above copyright notice,
00051   *      this list of conditions and the following disclaimer.
00052   *   2. Redistributions in binary form must reproduce the above copyright notice,
00053   *      this list of conditions and the following disclaimer in the documentation
00054   *      and/or other materials provided with the distribution.
00055   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00056   *      may be used to endorse or promote products derived from this software
00057   *      without specific prior written permission.
00058   *
00059   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00060   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00061   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00062   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00063   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00064   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00065   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00066   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00067   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00068   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00069   *
00070   ******************************************************************************
00071   */ 
00072 
00073 /* Includes ------------------------------------------------------------------*/
00074 #include "stm32f4xx_hal.h"
00075 
00076 /** @addtogroup STM32F4xx_HAL_Driver
00077   * @{
00078   */
00079 
00080 /** @defgroup PCD PCD
00081   * @brief PCD HAL module driver
00082   * @{
00083   */
00084 
00085 #ifdef HAL_PCD_MODULE_ENABLED
00086 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || \
00087     defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || \
00088     defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) || \
00089     defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || \
00090     defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
00091 /* Private types -------------------------------------------------------------*/
00092 /* Private variables ---------------------------------------------------------*/
00093 /* Private constants ---------------------------------------------------------*/
00094 /* Private macros ------------------------------------------------------------*/
00095 /** @defgroup PCD_Private_Macros PCD Private Macros
00096   * @{
00097   */ 
00098 #define PCD_MIN(a, b)  (((a) < (b)) ? (a) : (b))
00099 #define PCD_MAX(a, b)  (((a) > (b)) ? (a) : (b))
00100 /**
00101   * @}
00102   */
00103 
00104 /* Private functions prototypes ----------------------------------------------*/
00105 /** @defgroup PCD_Private_Functions PCD Private Functions
00106   * @{
00107   */
00108 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum);
00109 /**
00110   * @}
00111   */
00112 
00113 /* Exported functions --------------------------------------------------------*/
00114 /** @defgroup PCD_Exported_Functions PCD Exported Functions
00115   * @{
00116   */
00117 
00118 /** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions 
00119  *  @brief    Initialization and Configuration functions 
00120  *
00121 @verbatim 
00122  ===============================================================================
00123             ##### Initialization and de-initialization functions #####
00124  ===============================================================================
00125     [..]  This section provides functions allowing to:
00126  
00127 @endverbatim
00128   * @{
00129   */
00130 
00131 /**
00132   * @brief  Initializes the PCD according to the specified
00133   *         parameters in the PCD_InitTypeDef and initialize the associated handle.
00134   * @param  hpcd PCD handle
00135   * @retval HAL status
00136   */
00137 HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd)
00138 { 
00139   uint32_t i = 0U;
00140   
00141   /* Check the PCD handle allocation */
00142   if(hpcd == NULL)
00143   {
00144     return HAL_ERROR;
00145   }
00146   
00147   /* Check the parameters */
00148   assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance));
00149 
00150   hpcd->State = HAL_PCD_STATE_BUSY;
00151   
00152   /* Init the low level hardware : GPIO, CLOCK, NVIC... */
00153   HAL_PCD_MspInit(hpcd);
00154 
00155   /* Disable the Interrupts */
00156  __HAL_PCD_DISABLE(hpcd);
00157  
00158  /*Init the Core (common init.) */
00159  USB_CoreInit(hpcd->Instance, hpcd->Init);
00160  
00161  /* Force Device Mode*/
00162  USB_SetCurrentMode(hpcd->Instance , USB_OTG_DEVICE_MODE);
00163  
00164  /* Init endpoints structures */
00165  for (i = 0U; i < 15U; i++)
00166  {
00167    /* Init ep structure */
00168    hpcd->IN_ep[i].is_in = 1U;
00169    hpcd->IN_ep[i].num = i;
00170    hpcd->IN_ep[i].tx_fifo_num = i;
00171    /* Control until ep is activated */
00172    hpcd->IN_ep[i].type = EP_TYPE_CTRL;
00173    hpcd->IN_ep[i].maxpacket = 0U;
00174    hpcd->IN_ep[i].xfer_buff = 0U;
00175    hpcd->IN_ep[i].xfer_len = 0U;
00176  }
00177  
00178  for (i = 0U; i < 15U; i++)
00179  {
00180    hpcd->OUT_ep[i].is_in = 0U;
00181    hpcd->OUT_ep[i].num = i;
00182    hpcd->IN_ep[i].tx_fifo_num = i;
00183    /* Control until ep is activated */
00184    hpcd->OUT_ep[i].type = EP_TYPE_CTRL;
00185    hpcd->OUT_ep[i].maxpacket = 0U;
00186    hpcd->OUT_ep[i].xfer_buff = 0U;
00187    hpcd->OUT_ep[i].xfer_len = 0U;
00188    
00189    hpcd->Instance->DIEPTXF[i] = 0U;
00190  }
00191  
00192  /* Init Device */
00193  USB_DevInit(hpcd->Instance, hpcd->Init);
00194  
00195  hpcd->State= HAL_PCD_STATE_READY;
00196  
00197 #ifdef USB_OTG_GLPMCFG_LPMEN
00198  /* Activate LPM */
00199  if (hpcd->Init.lpm_enable == 1U)
00200  {
00201    HAL_PCDEx_ActivateLPM(hpcd);
00202  }
00203 #endif /* USB_OTG_GLPMCFG_LPMEN */
00204  
00205 #ifdef USB_OTG_GCCFG_BCDEN
00206  /* Activate Battery charging */
00207  if (hpcd->Init.battery_charging_enable == 1U)
00208  {
00209    HAL_PCDEx_ActivateBCD(hpcd);
00210  }
00211 #endif /* USB_OTG_GCCFG_BCDEN */
00212  
00213  USB_DevDisconnect (hpcd->Instance);  
00214  return HAL_OK;
00215 }
00216 
00217 /**
00218   * @brief  DeInitializes the PCD peripheral. 
00219   * @param  hpcd PCD handle
00220   * @retval HAL status
00221   */
00222 HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
00223 {
00224   /* Check the PCD handle allocation */
00225   if(hpcd == NULL)
00226   {
00227     return HAL_ERROR;
00228   }
00229 
00230   hpcd->State = HAL_PCD_STATE_BUSY;
00231   
00232   /* Stop Device */
00233   HAL_PCD_Stop(hpcd);
00234     
00235   /* DeInit the low level hardware */
00236   HAL_PCD_MspDeInit(hpcd);
00237   
00238   hpcd->State = HAL_PCD_STATE_RESET; 
00239   
00240   return HAL_OK;
00241 }
00242 
00243 /**
00244   * @brief  Initializes the PCD MSP.
00245   * @param  hpcd PCD handle
00246   * @retval None
00247   */
00248 __weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
00249 {
00250   /* Prevent unused argument(s) compilation warning */
00251   UNUSED(hpcd);
00252   /* NOTE : This function Should not be modified, when the callback is needed,
00253             the HAL_PCD_MspInit could be implemented in the user file
00254    */
00255 }
00256 
00257 /**
00258   * @brief  DeInitializes PCD MSP.
00259   * @param  hpcd PCD handle
00260   * @retval None
00261   */
00262 __weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
00263 {
00264   /* Prevent unused argument(s) compilation warning */
00265   UNUSED(hpcd);
00266   /* NOTE : This function Should not be modified, when the callback is needed,
00267             the HAL_PCD_MspDeInit could be implemented in the user file
00268    */
00269 }
00270 
00271 /**
00272   * @}
00273   */
00274 
00275 /** @defgroup PCD_Exported_Functions_Group2 Input and Output operation functions 
00276  *  @brief   Data transfers functions 
00277  *
00278 @verbatim 
00279  ===============================================================================
00280                       ##### IO operation functions #####
00281  ===============================================================================  
00282     [..]
00283     This subsection provides a set of functions allowing to manage the PCD data 
00284     transfers.
00285 
00286 @endverbatim
00287   * @{
00288   */
00289   
00290 /**
00291   * @brief  Start The USB OTG Device.
00292   * @param  hpcd PCD handle
00293   * @retval HAL status
00294   */
00295 HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)
00296 { 
00297   __HAL_LOCK(hpcd); 
00298   USB_DevConnect (hpcd->Instance);  
00299   __HAL_PCD_ENABLE(hpcd);
00300   __HAL_UNLOCK(hpcd); 
00301   return HAL_OK;
00302 }
00303 
00304 /**
00305   * @brief  Stop The USB OTG Device.
00306   * @param  hpcd PCD handle
00307   * @retval HAL status
00308   */
00309 HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
00310 { 
00311   __HAL_LOCK(hpcd); 
00312   __HAL_PCD_DISABLE(hpcd);
00313   USB_StopDevice(hpcd->Instance);
00314   USB_DevDisconnect(hpcd->Instance);
00315   __HAL_UNLOCK(hpcd); 
00316   return HAL_OK;
00317 }
00318 
00319 /**
00320   * @brief  Handles PCD interrupt request.
00321   * @param  hpcd PCD handle
00322   * @retval HAL status
00323   */
00324 void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
00325 {
00326   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
00327   uint32_t i = 0U, ep_intr = 0U, epint = 0U, epnum = 0U;
00328   uint32_t fifoemptymsk = 0U, temp = 0U;
00329   USB_OTG_EPTypeDef *ep;
00330   uint32_t hclk = 180000000U;
00331   
00332   /* ensure that we are in device mode */
00333   if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE)
00334   {    
00335     /* avoid spurious interrupt */
00336     if(__HAL_PCD_IS_INVALID_INTERRUPT(hpcd)) 
00337     {
00338       return;
00339     }
00340     
00341     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS))
00342     {
00343      /* incorrect mode, acknowledge the interrupt */
00344       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS);
00345     }
00346     
00347     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT))
00348     {
00349       epnum = 0U;
00350       
00351       /* Read in the device interrupt bits */
00352       ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance);
00353       
00354       while ( ep_intr )
00355       {
00356         if (ep_intr & 0x1U)
00357         {
00358           epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, epnum);
00359           
00360           if(( epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC)
00361           {
00362             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC);
00363             
00364             if(hpcd->Init.dma_enable == 1U)
00365             {
00366               hpcd->OUT_ep[epnum].xfer_count = hpcd->OUT_ep[epnum].maxpacket- (USBx_OUTEP(epnum)->DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ); 
00367               hpcd->OUT_ep[epnum].xfer_buff += hpcd->OUT_ep[epnum].maxpacket;            
00368             }
00369             
00370             HAL_PCD_DataOutStageCallback(hpcd, epnum);
00371             if(hpcd->Init.dma_enable == 1U)
00372             {
00373               if((epnum == 0U) && (hpcd->OUT_ep[epnum].xfer_len == 0U))
00374               {
00375                  /* this is ZLP, so prepare EP0 for next setup */
00376                 USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup);
00377               }              
00378             }
00379           }
00380           
00381           if(( epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP)
00382           {
00383             /* Inform the upper layer that a setup packet is available */
00384             HAL_PCD_SetupStageCallback(hpcd);
00385             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP);
00386           }
00387           
00388           if(( epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS)
00389           {
00390             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS);
00391           }
00392 
00393 #ifdef USB_OTG_DOEPINT_OTEPSPR 
00394           /* Clear Status Phase Received interrupt */
00395           if(( epint & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR)
00396           {
00397             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
00398           }
00399 #endif /* USB_OTG_DOEPINT_OTEPSPR */
00400         }
00401         epnum++;
00402         ep_intr >>= 1U;
00403       }
00404     }
00405     
00406     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT))
00407     {
00408       /* Read in the device interrupt bits */
00409       ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance);
00410       
00411       epnum = 0U;
00412       
00413       while ( ep_intr )
00414       {
00415         if (ep_intr & 0x1U) /* In ITR */
00416         {
00417           epint = USB_ReadDevInEPInterrupt(hpcd->Instance, epnum);
00418 
00419            if(( epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC)
00420           {
00421             fifoemptymsk = 0x1U << epnum;
00422             USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
00423             
00424             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC);
00425             
00426             if (hpcd->Init.dma_enable == 1U)
00427             {
00428               hpcd->IN_ep[epnum].xfer_buff += hpcd->IN_ep[epnum].maxpacket; 
00429             }
00430                                       
00431             HAL_PCD_DataInStageCallback(hpcd, epnum);
00432 
00433             if (hpcd->Init.dma_enable == 1U)
00434             {
00435               /* this is ZLP, so prepare EP0 for next setup */
00436               if((epnum == 0U) && (hpcd->IN_ep[epnum].xfer_len == 0U))
00437               {
00438                 /* prepare to rx more setup packets */
00439                 USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup);
00440               }
00441             }           
00442           }
00443            if(( epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC)
00444           {
00445             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC);
00446           }
00447           if(( epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE)
00448           {
00449             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE);
00450           }
00451           if(( epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE)
00452           {
00453             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE);
00454           }
00455           if(( epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD)
00456           {
00457             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD);
00458           }       
00459           if(( epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE)
00460           {
00461             PCD_WriteEmptyTxFifo(hpcd , epnum);
00462           }
00463         }
00464         epnum++;
00465         ep_intr >>= 1U;
00466       }
00467     }
00468     
00469     /* Handle Resume Interrupt */
00470     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT))
00471     {    
00472       /* Clear the Remote Wake-up Signaling */
00473       USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
00474 
00475 #ifdef USB_OTG_GLPMCFG_LPMEN
00476       if(hpcd->LPM_State == LPM_L1)
00477       {
00478         hpcd->LPM_State = LPM_L0;
00479         HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE);
00480       }
00481       else
00482 #endif /* USB_OTG_GLPMCFG_LPMEN */
00483       {
00484         HAL_PCD_ResumeCallback(hpcd);
00485       }
00486       
00487       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT);
00488     }
00489     
00490     /* Handle Suspend Interrupt */
00491     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP))
00492     {
00493       if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
00494       {
00495         
00496         HAL_PCD_SuspendCallback(hpcd);
00497       }
00498       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP);
00499     }
00500 
00501 #ifdef USB_OTG_GLPMCFG_LPMEN
00502     /* Handle LPM Interrupt */ 
00503     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT))
00504     {
00505       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT);      
00506       if( hpcd->LPM_State == LPM_L0)
00507       {
00508         hpcd->LPM_State = LPM_L1;
00509         hpcd->BESL = (hpcd->Instance->GLPMCFG & USB_OTG_GLPMCFG_BESL) >> 2U;
00510         HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE);
00511       }
00512       else
00513       {
00514         HAL_PCD_SuspendCallback(hpcd);
00515       }
00516     }
00517 #endif /* USB_OTG_GLPMCFG_LPMEN */
00518 
00519     /* Handle Reset Interrupt */
00520     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST))
00521     {
00522       USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG; 
00523       USB_FlushTxFifo(hpcd->Instance , 0x10U);
00524       
00525       for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
00526       {
00527         USBx_INEP(i)->DIEPINT = 0xFFU;
00528         USBx_OUTEP(i)->DOEPINT = 0xFFU;
00529       }
00530       USBx_DEVICE->DAINT = 0xFFFFFFFFU;
00531       USBx_DEVICE->DAINTMSK |= 0x10001U;
00532       
00533       if(hpcd->Init.use_dedicated_ep1)
00534       {
00535         USBx_DEVICE->DOUTEP1MSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM); 
00536         USBx_DEVICE->DINEP1MSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM);  
00537       }
00538       else
00539       {
00540 #ifdef USB_OTG_DOEPINT_OTEPSPR
00541         USBx_DEVICE->DOEPMSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM | USB_OTG_DOEPMSK_OTEPSPRM);
00542 #else
00543         USBx_DEVICE->DOEPMSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM);
00544 #endif /* USB_OTG_DOEPINT_OTEPSPR */
00545         USBx_DEVICE->DIEPMSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM);
00546       }
00547       
00548       /* Set Default Address to 0 */
00549       USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD;
00550       
00551       /* setup EP0 to receive SETUP packets */
00552       USB_EP0_OutStart(hpcd->Instance, hpcd->Init.dma_enable, (uint8_t *)hpcd->Setup);
00553         
00554       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST);
00555     }
00556     
00557     /* Handle Enumeration done Interrupt */
00558     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE))
00559     {
00560       USB_ActivateSetup(hpcd->Instance);
00561       hpcd->Instance->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
00562       
00563       if ( USB_GetDevSpeed(hpcd->Instance) == USB_OTG_SPEED_HIGH)
00564       {
00565         hpcd->Init.speed            = USB_OTG_SPEED_HIGH;
00566         hpcd->Init.ep0_mps          = USB_OTG_HS_MAX_PACKET_SIZE ;    
00567         hpcd->Instance->GUSBCFG |= (uint32_t)((USBD_HS_TRDT_VALUE << 10U) & USB_OTG_GUSBCFG_TRDT);
00568       }
00569       else
00570       {
00571         hpcd->Init.speed            = USB_OTG_SPEED_FULL;
00572         hpcd->Init.ep0_mps          = USB_OTG_FS_MAX_PACKET_SIZE ;  
00573         
00574         /* The USBTRD is configured according to the tables below, depending on AHB frequency 
00575         used by application. In the low AHB frequency range it is used to stretch enough the USB response 
00576         time to IN tokens, the USB turnaround time, so to compensate for the longer AHB read access 
00577         latency to the Data FIFO */
00578         
00579         /* Get hclk frequency value */
00580         hclk = HAL_RCC_GetHCLKFreq();
00581         
00582         if((hclk >= 14200000U)&&(hclk < 15000000U))
00583         {
00584           /* hclk Clock Range between 14.2-15 MHz */
00585           hpcd->Instance->GUSBCFG |= (uint32_t)((0xFU << 10U) & USB_OTG_GUSBCFG_TRDT);
00586         }
00587         
00588         else if((hclk >= 15000000U)&&(hclk < 16000000U))
00589         {
00590           /* hclk Clock Range between 15-16 MHz */
00591           hpcd->Instance->GUSBCFG |= (uint32_t)((0xEU << 10U) & USB_OTG_GUSBCFG_TRDT);
00592         }
00593         
00594         else if((hclk >= 16000000U)&&(hclk < 17200000U))
00595         {
00596           /* hclk Clock Range between 16-17.2 MHz */
00597           hpcd->Instance->GUSBCFG |= (uint32_t)((0xDU << 10U) & USB_OTG_GUSBCFG_TRDT);
00598         }
00599         
00600         else if((hclk >= 17200000U)&&(hclk < 18500000U))
00601         {
00602           /* hclk Clock Range between 17.2-18.5 MHz */
00603           hpcd->Instance->GUSBCFG |= (uint32_t)((0xCU << 10U) & USB_OTG_GUSBCFG_TRDT);
00604         }
00605         
00606         else if((hclk >= 18500000U)&&(hclk < 20000000U))
00607         {
00608           /* hclk Clock Range between 18.5-20 MHz */
00609           hpcd->Instance->GUSBCFG |= (uint32_t)((0xBU << 10U) & USB_OTG_GUSBCFG_TRDT);
00610         }
00611         
00612         else if((hclk >= 20000000U)&&(hclk < 21800000U))
00613         {
00614           /* hclk Clock Range between 20-21.8 MHz */
00615           hpcd->Instance->GUSBCFG |= (uint32_t)((0xAU << 10U) & USB_OTG_GUSBCFG_TRDT);
00616         }
00617         
00618         else if((hclk >= 21800000U)&&(hclk < 24000000U))
00619         {
00620           /* hclk Clock Range between 21.8-24 MHz */
00621           hpcd->Instance->GUSBCFG |= (uint32_t)((0x9U << 10U) & USB_OTG_GUSBCFG_TRDT);
00622         }
00623         
00624         else if((hclk >= 24000000U)&&(hclk < 27700000U))
00625         {
00626           /* hclk Clock Range between 24-27.7 MHz */
00627           hpcd->Instance->GUSBCFG |= (uint32_t)((0x8U << 10U) & USB_OTG_GUSBCFG_TRDT);
00628         }
00629         
00630         else if((hclk >= 27700000U)&&(hclk < 32000000U))
00631         {
00632           /* hclk Clock Range between 27.7-32 MHz */
00633           hpcd->Instance->GUSBCFG |= (uint32_t)((0x7U << 10U) & USB_OTG_GUSBCFG_TRDT);
00634         }
00635         
00636         else /* if(hclk >= 32000000) */
00637         {
00638           /* hclk Clock Range between 32-180 MHz */
00639           hpcd->Instance->GUSBCFG |= (uint32_t)((0x6U << 10U) & USB_OTG_GUSBCFG_TRDT);
00640         }  
00641       }
00642       
00643       HAL_PCD_ResetCallback(hpcd);
00644       
00645       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE);
00646     }
00647 
00648     /* Handle RxQLevel Interrupt */
00649     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL))
00650     {
00651       USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
00652       
00653       temp = USBx->GRXSTSP;
00654       
00655       ep = &hpcd->OUT_ep[temp & USB_OTG_GRXSTSP_EPNUM];
00656       
00657       if(((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17U) ==  STS_DATA_UPDT)
00658       {
00659         if((temp & USB_OTG_GRXSTSP_BCNT) != 0U)
00660         {
00661           USB_ReadPacket(USBx, ep->xfer_buff, (temp & USB_OTG_GRXSTSP_BCNT) >> 4U);
00662           ep->xfer_buff += (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
00663           ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
00664         }
00665       }
00666       else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17U) ==  STS_SETUP_UPDT)
00667       {
00668         USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8U);
00669         ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
00670       }
00671       USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
00672     }
00673     
00674     /* Handle SOF Interrupt */
00675     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF))
00676     {
00677       HAL_PCD_SOFCallback(hpcd);
00678       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF);
00679     }
00680     
00681     /* Handle Incomplete ISO IN Interrupt */
00682     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR))
00683     {
00684       HAL_PCD_ISOINIncompleteCallback(hpcd, epnum);
00685       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR);
00686     } 
00687     
00688     /* Handle Incomplete ISO OUT Interrupt */
00689     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
00690     {
00691       HAL_PCD_ISOOUTIncompleteCallback(hpcd, epnum);
00692       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
00693     } 
00694     
00695     /* Handle Connection event Interrupt */
00696     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT))
00697     {
00698       HAL_PCD_ConnectCallback(hpcd);
00699       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT);
00700     } 
00701     
00702     /* Handle Disconnection event Interrupt */
00703     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT))
00704     {
00705       temp = hpcd->Instance->GOTGINT;
00706       
00707       if((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET)
00708       {
00709         HAL_PCD_DisconnectCallback(hpcd);
00710       }
00711       hpcd->Instance->GOTGINT |= temp;
00712     }
00713   }
00714 }
00715 
00716 /**
00717   * @brief  Data OUT stage callback.
00718   * @param  hpcd PCD handle
00719   * @param  epnum endpoint number  
00720   * @retval None
00721   */
00722  __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
00723 {
00724   /* Prevent unused argument(s) compilation warning */
00725   UNUSED(hpcd);
00726   UNUSED(epnum);
00727   /* NOTE : This function Should not be modified, when the callback is needed,
00728             the HAL_PCD_DataOutStageCallback could be implemented in the user file
00729    */ 
00730 }
00731 
00732 /**
00733   * @brief  Data IN stage callback.
00734   * @param  hpcd PCD handle
00735   * @param  epnum endpoint number
00736   * @retval None
00737   */
00738  __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
00739 {
00740   /* Prevent unused argument(s) compilation warning */
00741   UNUSED(hpcd);
00742   UNUSED(epnum);
00743   /* NOTE : This function Should not be modified, when the callback is needed,
00744             the HAL_PCD_DataInStageCallback could be implemented in the user file
00745    */ 
00746 }
00747 /**
00748   * @brief  Setup stage callback.
00749   * @param  hpcd PCD handle
00750   * @retval None
00751   */
00752  __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
00753 {
00754   /* Prevent unused argument(s) compilation warning */
00755   UNUSED(hpcd);
00756   /* NOTE : This function Should not be modified, when the callback is needed,
00757             the HAL_PCD_SetupStageCallback could be implemented in the user file
00758    */ 
00759 }
00760 
00761 /**
00762   * @brief  USB Start Of Frame callback.
00763   * @param  hpcd PCD handle
00764   * @retval None
00765   */
00766  __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
00767 {
00768   /* Prevent unused argument(s) compilation warning */
00769   UNUSED(hpcd);
00770   /* NOTE : This function Should not be modified, when the callback is needed,
00771             the HAL_PCD_SOFCallback could be implemented in the user file
00772    */ 
00773 }
00774 
00775 /**
00776   * @brief  USB Reset callback.
00777   * @param  hpcd PCD handle
00778   * @retval None
00779   */
00780  __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
00781 {
00782   /* Prevent unused argument(s) compilation warning */
00783   UNUSED(hpcd);
00784   /* NOTE : This function Should not be modified, when the callback is needed,
00785             the HAL_PCD_ResetCallback could be implemented in the user file
00786    */ 
00787 }
00788 
00789 /**
00790   * @brief  Suspend event callback.
00791   * @param  hpcd PCD handle
00792   * @retval None
00793   */
00794  __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
00795 {
00796   /* Prevent unused argument(s) compilation warning */
00797   UNUSED(hpcd);
00798   /* NOTE : This function Should not be modified, when the callback is needed,
00799             the HAL_PCD_SuspendCallback could be implemented in the user file
00800    */ 
00801 }
00802 
00803 /**
00804   * @brief  Resume event callback.
00805   * @param  hpcd PCD handle
00806   * @retval None
00807   */
00808  __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
00809 {
00810   /* Prevent unused argument(s) compilation warning */
00811   UNUSED(hpcd);
00812   /* NOTE : This function Should not be modified, when the callback is needed,
00813             the HAL_PCD_ResumeCallback could be implemented in the user file
00814    */ 
00815 }
00816 
00817 /**
00818   * @brief  Incomplete ISO OUT callback.
00819   * @param  hpcd PCD handle
00820   * @param  epnum endpoint number
00821   * @retval None
00822   */
00823  __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
00824 {
00825   /* Prevent unused argument(s) compilation warning */
00826   UNUSED(hpcd);
00827   UNUSED(epnum);
00828   /* NOTE : This function Should not be modified, when the callback is needed,
00829             the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file
00830    */ 
00831 }
00832 
00833 /**
00834   * @brief  Incomplete ISO IN callback.
00835   * @param  hpcd PCD handle
00836   * @param  epnum endpoint number  
00837   * @retval None
00838   */
00839  __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
00840 {
00841   /* Prevent unused argument(s) compilation warning */
00842   UNUSED(hpcd);
00843   UNUSED(epnum);
00844   /* NOTE : This function Should not be modified, when the callback is needed,
00845             the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file
00846    */ 
00847 }
00848 
00849 /**
00850   * @brief  Connection event callback.
00851   * @param  hpcd PCD handle
00852   * @retval None
00853   */
00854  __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
00855 {
00856   /* Prevent unused argument(s) compilation warning */
00857   UNUSED(hpcd);
00858   /* NOTE : This function Should not be modified, when the callback is needed,
00859             the HAL_PCD_ConnectCallback could be implemented in the user file
00860    */ 
00861 }
00862 
00863 /**
00864   * @brief  Disconnection event callback.
00865   * @param  hpcd PCD handle
00866   * @retval None
00867   */
00868  __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
00869 {
00870   /* Prevent unused argument(s) compilation warning */
00871   UNUSED(hpcd);
00872   /* NOTE : This function Should not be modified, when the callback is needed,
00873             the HAL_PCD_DisconnectCallback could be implemented in the user file
00874    */ 
00875 }
00876 
00877 /**
00878   * @}
00879   */
00880 
00881 /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
00882  *  @brief   management functions
00883  *
00884 @verbatim 
00885  ===============================================================================
00886                       ##### Peripheral Control functions #####
00887  ===============================================================================  
00888     [..]
00889     This subsection provides a set of functions allowing to control the PCD data 
00890     transfers.
00891 
00892 @endverbatim
00893   * @{
00894   */
00895 
00896 /**
00897   * @brief  Connect the USB device.
00898   * @param  hpcd PCD handle
00899   * @retval HAL status
00900   */
00901 HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd)
00902 {
00903   __HAL_LOCK(hpcd); 
00904   USB_DevConnect(hpcd->Instance);
00905   __HAL_UNLOCK(hpcd); 
00906   return HAL_OK;
00907 }
00908 
00909 /**
00910   * @brief  Disconnect the USB device.
00911   * @param  hpcd PCD handle
00912   * @retval HAL status
00913   */
00914 HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd)
00915 {
00916   __HAL_LOCK(hpcd); 
00917   USB_DevDisconnect(hpcd->Instance);
00918   __HAL_UNLOCK(hpcd); 
00919   return HAL_OK;
00920 }
00921 
00922 /**
00923   * @brief  Set the USB Device address. 
00924   * @param  hpcd PCD handle
00925   * @param  address new device address
00926   * @retval HAL status
00927   */
00928 HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)
00929 {
00930   __HAL_LOCK(hpcd); 
00931   USB_SetDevAddress(hpcd->Instance, address);
00932   __HAL_UNLOCK(hpcd);   
00933   return HAL_OK;
00934 }
00935 /**
00936   * @brief  Open and configure an endpoint.
00937   * @param  hpcd PCD handle
00938   * @param  ep_addr endpoint address
00939   * @param  ep_mps endpoint max packet size
00940   * @param  ep_type endpoint type   
00941   * @retval HAL status
00942   */
00943 HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type)
00944 {
00945   HAL_StatusTypeDef  ret = HAL_OK;
00946   USB_OTG_EPTypeDef *ep;
00947   
00948   if ((ep_addr & 0x80) == 0x80)
00949   {
00950     ep = &hpcd->IN_ep[ep_addr & 0x7F];
00951   }
00952   else
00953   {
00954     ep = &hpcd->OUT_ep[ep_addr & 0x7F];
00955   }
00956   ep->num   = ep_addr & 0x7F;
00957   
00958   ep->is_in = (0x80 & ep_addr) != 0;
00959   ep->maxpacket = ep_mps;
00960   ep->type = ep_type;
00961   if (ep->is_in)
00962   {
00963     /* Assign a Tx FIFO */
00964     ep->tx_fifo_num = ep->num;
00965   }
00966   /* Set initial data PID. */
00967   if (ep_type == EP_TYPE_BULK )
00968   {
00969     ep->data_pid_start = 0U;
00970   }
00971   
00972   __HAL_LOCK(hpcd); 
00973   USB_ActivateEndpoint(hpcd->Instance , ep);
00974   __HAL_UNLOCK(hpcd);   
00975   return ret;
00976 }
00977 
00978 
00979 /**
00980   * @brief  Deactivate an endpoint.
00981   * @param  hpcd PCD handle
00982   * @param  ep_addr endpoint address
00983   * @retval HAL status
00984   */
00985 HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
00986 {  
00987   USB_OTG_EPTypeDef *ep;
00988   
00989   if ((ep_addr & 0x80) == 0x80)
00990   {
00991     ep = &hpcd->IN_ep[ep_addr & 0x7F];
00992   }
00993   else
00994   {
00995     ep = &hpcd->OUT_ep[ep_addr & 0x7F];
00996   }
00997   ep->num   = ep_addr & 0x7F;
00998   
00999   ep->is_in = (0x80 & ep_addr) != 0;
01000   
01001   __HAL_LOCK(hpcd); 
01002   USB_DeactivateEndpoint(hpcd->Instance , ep);
01003   __HAL_UNLOCK(hpcd);   
01004   return HAL_OK;
01005 }
01006 
01007 
01008 /**
01009   * @brief  Receive an amount of data.  
01010   * @param  hpcd PCD handle
01011   * @param  ep_addr endpoint address
01012   * @param  pBuf pointer to the reception buffer   
01013   * @param  len amount of data to be received
01014   * @retval HAL status
01015   */
01016 HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
01017 {
01018   USB_OTG_EPTypeDef *ep;
01019   
01020   ep = &hpcd->OUT_ep[ep_addr & 0x7F];
01021   
01022   /*setup and start the Xfer */
01023   ep->xfer_buff = pBuf;  
01024   ep->xfer_len = len;
01025   ep->xfer_count = 0U;
01026   ep->is_in = 0U;
01027   ep->num = ep_addr & 0x7F;
01028   
01029   if (hpcd->Init.dma_enable == 1U)
01030   {
01031     ep->dma_addr = (uint32_t)pBuf;  
01032   }
01033   
01034   if ((ep_addr & 0x7F) == 0)
01035   {
01036     USB_EP0StartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable);
01037   }
01038   else
01039   {
01040     USB_EPStartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable);
01041   }
01042   
01043   return HAL_OK;
01044 }
01045 
01046 /**
01047   * @brief  Get Received Data Size.
01048   * @param  hpcd PCD handle
01049   * @param  ep_addr endpoint address
01050   * @retval Data Size
01051   */
01052 uint16_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
01053 {
01054   return hpcd->OUT_ep[ep_addr & 0xF].xfer_count;
01055 }
01056 /**
01057   * @brief  Send an amount of data.  
01058   * @param  hpcd PCD handle
01059   * @param  ep_addr endpoint address
01060   * @param  pBuf pointer to the transmission buffer   
01061   * @param  len amount of data to be sent
01062   * @retval HAL status
01063   */
01064 HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
01065 {
01066   USB_OTG_EPTypeDef *ep;
01067   
01068   ep = &hpcd->IN_ep[ep_addr & 0x7F];
01069   
01070   /*setup and start the Xfer */
01071   ep->xfer_buff = pBuf;  
01072   ep->xfer_len = len;
01073   ep->xfer_count = 0U;
01074   ep->is_in = 1U;
01075   ep->num = ep_addr & 0x7F;
01076   
01077   if (hpcd->Init.dma_enable == 1U)
01078   {
01079     ep->dma_addr = (uint32_t)pBuf;  
01080   }
01081   
01082   if ((ep_addr & 0x7F) == 0)
01083   {
01084     USB_EP0StartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable);
01085   }
01086   else
01087   {
01088     USB_EPStartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable);
01089   }
01090   
01091   return HAL_OK;
01092 }
01093 
01094 /**
01095   * @brief  Set a STALL condition over an endpoint.
01096   * @param  hpcd PCD handle
01097   * @param  ep_addr endpoint address
01098   * @retval HAL status
01099   */
01100 HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
01101 {
01102   USB_OTG_EPTypeDef *ep;
01103   
01104   if ((0x80 & ep_addr) == 0x80)
01105   {
01106     ep = &hpcd->IN_ep[ep_addr & 0x7F];
01107   }
01108   else
01109   {
01110     ep = &hpcd->OUT_ep[ep_addr];
01111   }
01112   
01113   ep->is_stall = 1U;
01114   ep->num   = ep_addr & 0x7F;
01115   ep->is_in = ((ep_addr & 0x80) == 0x80);
01116   
01117   
01118   __HAL_LOCK(hpcd); 
01119   USB_EPSetStall(hpcd->Instance , ep);
01120   if((ep_addr & 0x7F) == 0)
01121   {
01122     USB_EP0_OutStart(hpcd->Instance, hpcd->Init.dma_enable, (uint8_t *)hpcd->Setup);
01123   }
01124   __HAL_UNLOCK(hpcd); 
01125   
01126   return HAL_OK;
01127 }
01128 
01129 /**
01130   * @brief  Clear a STALL condition over in an endpoint.
01131   * @param  hpcd PCD handle
01132   * @param  ep_addr endpoint address
01133   * @retval HAL status
01134   */
01135 HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
01136 {
01137   USB_OTG_EPTypeDef *ep;
01138   
01139   if ((0x80 & ep_addr) == 0x80)
01140   {
01141     ep = &hpcd->IN_ep[ep_addr & 0x7F];
01142   }
01143   else
01144   {
01145     ep = &hpcd->OUT_ep[ep_addr];
01146   }
01147   
01148   ep->is_stall = 0U;
01149   ep->num   = ep_addr & 0x7F;
01150   ep->is_in = ((ep_addr & 0x80) == 0x80);
01151   
01152   __HAL_LOCK(hpcd); 
01153   USB_EPClearStall(hpcd->Instance , ep);
01154   __HAL_UNLOCK(hpcd); 
01155     
01156   return HAL_OK;
01157 }
01158 
01159 /**
01160   * @brief  Flush an endpoint.
01161   * @param  hpcd PCD handle
01162   * @param  ep_addr endpoint address
01163   * @retval HAL status
01164   */
01165 HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
01166 {
01167   __HAL_LOCK(hpcd); 
01168   
01169   if ((ep_addr & 0x80) == 0x80)
01170   {
01171     USB_FlushTxFifo(hpcd->Instance, ep_addr & 0x7F);
01172   }
01173   else
01174   {
01175     USB_FlushRxFifo(hpcd->Instance);
01176   }
01177   
01178   __HAL_UNLOCK(hpcd); 
01179     
01180   return HAL_OK;
01181 }
01182 
01183 /**
01184   * @brief  Activate remote wakeup signalling.
01185   * @param  hpcd PCD handle
01186   * @retval HAL status
01187   */
01188 HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
01189 {
01190   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;  
01191     
01192   if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
01193   {
01194     /* Activate Remote wakeup signaling */
01195     USBx_DEVICE->DCTL |= USB_OTG_DCTL_RWUSIG;
01196   }
01197   return HAL_OK;  
01198 }
01199 
01200 /**
01201   * @brief  De-activate remote wakeup signalling.
01202   * @param  hpcd PCD handle
01203   * @retval HAL status
01204   */
01205 HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
01206 {
01207   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;  
01208   
01209   /* De-activate Remote wakeup signaling */
01210   USBx_DEVICE->DCTL &= ~(USB_OTG_DCTL_RWUSIG);
01211   return HAL_OK;  
01212 }
01213 /**
01214   * @}
01215   */
01216   
01217 /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions 
01218  *  @brief   Peripheral State functions
01219  *
01220 @verbatim  
01221  ===============================================================================
01222                       ##### Peripheral State functions #####
01223  ===============================================================================  
01224     [..]
01225     This subsection permits to get in run-time the status of the peripheral 
01226     and the data flow.
01227 
01228 @endverbatim
01229   * @{
01230   */
01231 
01232 /**
01233   * @brief  Return the PCD handle state.
01234   * @param  hpcd PCD handle
01235   * @retval HAL state
01236   */
01237 PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd)
01238 {
01239   return hpcd->State;
01240 }
01241 /**
01242   * @}
01243   */
01244 
01245 /**
01246   * @}
01247   */
01248 
01249 /* Private functions ---------------------------------------------------------*/
01250 /** @addtogroup PCD_Private_Functions
01251   * @{
01252   */
01253 
01254 /**
01255   * @brief  Check FIFO for the next packet to be loaded.
01256   * @param  hpcd PCD handle
01257   * @param  epnum  endpoint number   
01258   * @retval HAL status
01259   */
01260 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum)
01261 {
01262   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;  
01263   USB_OTG_EPTypeDef *ep;
01264   int32_t len = 0U;
01265   uint32_t len32b;
01266   uint32_t fifoemptymsk = 0U;
01267 
01268   ep = &hpcd->IN_ep[epnum];
01269   len = ep->xfer_len - ep->xfer_count;
01270   
01271   if (len > ep->maxpacket)
01272   {
01273     len = ep->maxpacket;
01274   }
01275   
01276   
01277   len32b = (len + 3U) / 4U;
01278  
01279   while  (((USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) > len32b) &&
01280           (ep->xfer_count < ep->xfer_len) &&
01281             (ep->xfer_len != 0U))
01282   {
01283     /* Write the FIFO */
01284     len = ep->xfer_len - ep->xfer_count;
01285     
01286     if (len > ep->maxpacket)
01287     {
01288       len = ep->maxpacket;
01289     }
01290     len32b = (len + 3U) / 4U;
01291     
01292     USB_WritePacket(USBx, ep->xfer_buff, epnum, len, hpcd->Init.dma_enable); 
01293     
01294     ep->xfer_buff  += len;
01295     ep->xfer_count += len;
01296   }
01297   
01298   if(len <= 0U)
01299   {
01300     fifoemptymsk = 0x1U << epnum;
01301     USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
01302     
01303   }
01304   
01305   return HAL_OK;  
01306 }
01307 
01308 /**
01309   * @}
01310   */
01311 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx ||
01312           STM32F401xC || STM32F401xE || STM32F411xE || STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Rx ||
01313           STM32F412Vx || STM32F412Cx || STM32F413xx || STM32F423xx */
01314 #endif /* HAL_PCD_MODULE_ENABLED */
01315 /**
01316   * @}
01317   */
01318 
01319 /**
01320   * @}
01321   */
01322 
01323 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/