STM32L486xx HAL User Manual
stm32l4xx_hal_pcd.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32l4xx_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_CLK_ENABLE(); For USB Device only FS peripheral
00030 
00031          (##) Initialize the related GPIO clocks
00032          (##) Configure PCD pin-out
00033          (##) Configure PCD NVIC interrupt
00034 
00035      (#)Associate the Upper USB device stack to the HAL PCD Driver:
00036          (##) hpcd.pData = pdev;
00037 
00038      (#)Enable PCD transmission and reception:
00039          (##) HAL_PCD_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 "stm32l4xx_hal.h"
00074 
00075 /** @addtogroup STM32L4xx_HAL_Driver
00076   * @{
00077   */
00078 
00079 /** @defgroup PCD PCD
00080   * @brief PCD HAL module driver
00081   * @{
00082   */
00083 
00084 #ifdef HAL_PCD_MODULE_ENABLED
00085 
00086 #if defined (USB) || defined (USB_OTG_FS) || defined (USB_OTG_HS)
00087 
00088 /* Private types -------------------------------------------------------------*/
00089 /* Private variables ---------------------------------------------------------*/
00090 /* Private constants ---------------------------------------------------------*/
00091 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
00092 /**
00093   * USB_OTG_CORE VERSION ID
00094   */
00095 #define USB_OTG_CORE_ID_300A          0x4F54300AU
00096 #define USB_OTG_CORE_ID_310A          0x4F54310AU
00097 #define USB_OTG_CORE_ID_320A          0x4F54320AU
00098 #endif /* USB_OTG_FS || USB_OTG_HS */
00099 /* Private macros ------------------------------------------------------------*/
00100 /** @defgroup PCD_Private_Macros PCD Private Macros
00101   * @{
00102   */
00103 #define PCD_MIN(a, b)  (((a) < (b)) ? (a) : (b))
00104 #define PCD_MAX(a, b)  (((a) > (b)) ? (a) : (b))
00105 /**
00106   * @}
00107   */
00108 
00109 /* Private functions prototypes ----------------------------------------------*/
00110 /** @defgroup PCD_Private_Functions PCD Private Functions
00111   * @{
00112   */
00113 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
00114 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum);
00115 #endif /* USB_OTG_FS || USB_OTG_HS */
00116 
00117 #if defined (USB)
00118 static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd);
00119 #endif /* USB */
00120 /**
00121   * @}
00122   */
00123 
00124 /* Exported functions --------------------------------------------------------*/
00125 /** @defgroup PCD_Exported_Functions PCD Exported Functions
00126   * @{
00127   */
00128 
00129 /** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
00130  *  @brief    Initialization and Configuration functions
00131  *
00132 @verbatim
00133  ===============================================================================
00134             ##### Initialization and de-initialization functions #####
00135  ===============================================================================
00136     [..]  This section provides functions allowing to:
00137 
00138 @endverbatim
00139   * @{
00140   */
00141 
00142 /**
00143   * @brief  Initializes the PCD according to the specified
00144   *         parameters in the PCD_InitTypeDef and initialize the associated handle.
00145   * @param  hpcd PCD handle
00146   * @retval HAL status
00147   */
00148 HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd)
00149 {
00150   uint8_t i;
00151 
00152   /* Check the PCD handle allocation */
00153   if (hpcd == NULL)
00154   {
00155     return HAL_ERROR;
00156   }
00157 
00158   /* Check the parameters */
00159   assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance));
00160 
00161   if (hpcd->State == HAL_PCD_STATE_RESET)
00162   {
00163     /* Allocate lock resource and initialize it */
00164     hpcd->Lock = HAL_UNLOCKED;
00165 
00166 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
00167     hpcd->SOFCallback = HAL_PCD_SOFCallback;
00168     hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
00169     hpcd->ResetCallback = HAL_PCD_ResetCallback;
00170     hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
00171     hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
00172     hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
00173     hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
00174     hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback;
00175     hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback;
00176     hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback;
00177     hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback;
00178     hpcd->LPMCallback = HAL_PCDEx_LPM_Callback;
00179     hpcd->BCDCallback = HAL_PCDEx_BCD_Callback;
00180 
00181     if (hpcd->MspInitCallback == NULL)
00182     {
00183       hpcd->MspInitCallback = HAL_PCD_MspInit;
00184     }
00185 
00186     /* Init the low level hardware */
00187     hpcd->MspInitCallback(hpcd);
00188 #else
00189     /* Init the low level hardware : GPIO, CLOCK, NVIC... */
00190     HAL_PCD_MspInit(hpcd);
00191 #endif /* (USE_HAL_PCD_REGISTER_CALLBACKS) */
00192   }
00193 
00194   hpcd->State = HAL_PCD_STATE_BUSY;
00195 
00196   /* Disable the Interrupts */
00197   __HAL_PCD_DISABLE(hpcd);
00198 
00199   /*Init the Core (common init.) */
00200   (void)USB_CoreInit(hpcd->Instance, hpcd->Init);
00201 
00202   /* Force Device Mode*/
00203   (void)USB_SetCurrentMode(hpcd->Instance, USB_DEVICE_MODE);
00204 
00205   /* Init endpoints structures */
00206   for (i = 0U; i < 15U; i++)
00207   {
00208     /* Init ep structure */
00209     hpcd->IN_ep[i].is_in = 1U;
00210     hpcd->IN_ep[i].num = i;
00211     hpcd->IN_ep[i].tx_fifo_num = i;
00212     /* Control until ep is activated */
00213     hpcd->IN_ep[i].type = EP_TYPE_CTRL;
00214     hpcd->IN_ep[i].maxpacket = 0U;
00215     hpcd->IN_ep[i].xfer_buff = 0U;
00216     hpcd->IN_ep[i].xfer_len = 0U;
00217   }
00218 
00219   for (i = 0U; i < 15U; i++)
00220   {
00221     hpcd->OUT_ep[i].is_in = 0U;
00222     hpcd->OUT_ep[i].num = i;
00223     /* Control until ep is activated */
00224     hpcd->OUT_ep[i].type = EP_TYPE_CTRL;
00225     hpcd->OUT_ep[i].maxpacket = 0U;
00226     hpcd->OUT_ep[i].xfer_buff = 0U;
00227     hpcd->OUT_ep[i].xfer_len = 0U;
00228   }
00229 
00230   /* Init Device */
00231   (void)USB_DevInit(hpcd->Instance, hpcd->Init);
00232 
00233   hpcd->USB_Address = 0U;
00234   hpcd->State = HAL_PCD_STATE_READY;
00235 
00236   /* Activate LPM */
00237   if (hpcd->Init.lpm_enable == 1U)
00238   {
00239     (void)HAL_PCDEx_ActivateLPM(hpcd);
00240   }
00241 
00242   /* Activate Battery charging */
00243   if (hpcd->Init.battery_charging_enable == 1U)
00244   {
00245     (void)HAL_PCDEx_ActivateBCD(hpcd);
00246   }
00247 
00248   (void)USB_DevDisconnect(hpcd->Instance);
00249 
00250   return HAL_OK;
00251 }
00252 
00253 /**
00254   * @brief  DeInitializes the PCD peripheral.
00255   * @param  hpcd PCD handle
00256   * @retval HAL status
00257   */
00258 HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
00259 {
00260   /* Check the PCD handle allocation */
00261   if (hpcd == NULL)
00262   {
00263     return HAL_ERROR;
00264   }
00265 
00266   hpcd->State = HAL_PCD_STATE_BUSY;
00267 
00268   /* Stop Device */
00269   (void)HAL_PCD_Stop(hpcd);
00270 
00271 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
00272   if (hpcd->MspDeInitCallback == NULL)
00273   {
00274     hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; /* Legacy weak MspDeInit  */
00275   }
00276 
00277   /* DeInit the low level hardware */
00278   hpcd->MspDeInitCallback(hpcd);
00279 #else
00280   /* DeInit the low level hardware: CLOCK, NVIC.*/
00281   HAL_PCD_MspDeInit(hpcd);
00282 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
00283 
00284   hpcd->State = HAL_PCD_STATE_RESET;
00285 
00286   return HAL_OK;
00287 }
00288 
00289 /**
00290   * @brief  Initializes the PCD MSP.
00291   * @param  hpcd PCD handle
00292   * @retval None
00293   */
00294 __weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
00295 {
00296   /* Prevent unused argument(s) compilation warning */
00297   UNUSED(hpcd);
00298 
00299   /* NOTE : This function should not be modified, when the callback is needed,
00300             the HAL_PCD_MspInit could be implemented in the user file
00301    */
00302 }
00303 
00304 /**
00305   * @brief  DeInitializes PCD MSP.
00306   * @param  hpcd PCD handle
00307   * @retval None
00308   */
00309 __weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
00310 {
00311   /* Prevent unused argument(s) compilation warning */
00312   UNUSED(hpcd);
00313 
00314   /* NOTE : This function should not be modified, when the callback is needed,
00315             the HAL_PCD_MspDeInit could be implemented in the user file
00316    */
00317 }
00318 
00319 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
00320 /**
00321   * @brief  Register a User USB PCD Callback
00322   *         To be used instead of the weak predefined callback
00323   * @param  hpcd USB PCD handle
00324   * @param  CallbackID ID of the callback to be registered
00325   *         This parameter can be one of the following values:
00326   *          @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
00327   *          @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
00328   *          @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
00329   *          @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
00330   *          @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
00331   *          @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
00332   *          @arg @ref HAL_PCD_DISCONNECT_CB_ID OTG PCD Disconnect callback ID
00333   *          @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
00334   *          @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
00335   * @param  pCallback pointer to the Callback function
00336   * @retval HAL status
00337   */
00338 HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID, pPCD_CallbackTypeDef pCallback)
00339 {
00340   HAL_StatusTypeDef status = HAL_OK;
00341 
00342   if (pCallback == NULL)
00343   {
00344     /* Update the error code */
00345     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
00346     return HAL_ERROR;
00347   }
00348   /* Process locked */
00349   __HAL_LOCK(hpcd);
00350 
00351   if (hpcd->State == HAL_PCD_STATE_READY)
00352   {
00353     switch (CallbackID)
00354     {
00355       case HAL_PCD_SOF_CB_ID :
00356         hpcd->SOFCallback = pCallback;
00357         break;
00358 
00359       case HAL_PCD_SETUPSTAGE_CB_ID :
00360         hpcd->SetupStageCallback = pCallback;
00361         break;
00362 
00363       case HAL_PCD_RESET_CB_ID :
00364         hpcd->ResetCallback = pCallback;
00365         break;
00366 
00367       case HAL_PCD_SUSPEND_CB_ID :
00368         hpcd->SuspendCallback = pCallback;
00369         break;
00370 
00371       case HAL_PCD_RESUME_CB_ID :
00372         hpcd->ResumeCallback = pCallback;
00373         break;
00374 
00375       case HAL_PCD_CONNECT_CB_ID :
00376         hpcd->ConnectCallback = pCallback;
00377         break;
00378 
00379       case HAL_PCD_DISCONNECT_CB_ID :
00380         hpcd->DisconnectCallback = pCallback;
00381         break;
00382 
00383       case HAL_PCD_MSPINIT_CB_ID :
00384         hpcd->MspInitCallback = pCallback;
00385         break;
00386 
00387       case HAL_PCD_MSPDEINIT_CB_ID :
00388         hpcd->MspDeInitCallback = pCallback;
00389         break;
00390 
00391       default :
00392         /* Update the error code */
00393         hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
00394         /* Return error status */
00395         status =  HAL_ERROR;
00396         break;
00397     }
00398   }
00399   else if (hpcd->State == HAL_PCD_STATE_RESET)
00400   {
00401     switch (CallbackID)
00402     {
00403       case HAL_PCD_MSPINIT_CB_ID :
00404         hpcd->MspInitCallback = pCallback;
00405         break;
00406 
00407       case HAL_PCD_MSPDEINIT_CB_ID :
00408         hpcd->MspDeInitCallback = pCallback;
00409         break;
00410 
00411       default :
00412         /* Update the error code */
00413         hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
00414         /* Return error status */
00415         status =  HAL_ERROR;
00416         break;
00417     }
00418   }
00419   else
00420   {
00421     /* Update the error code */
00422     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
00423     /* Return error status */
00424     status =  HAL_ERROR;
00425   }
00426 
00427   /* Release Lock */
00428   __HAL_UNLOCK(hpcd);
00429   return status;
00430 }
00431 
00432 /**
00433   * @brief  Unregister an USB PCD Callback
00434   *         USB PCD callabck is redirected to the weak predefined callback
00435   * @param  hpcd USB PCD handle
00436   * @param  CallbackID ID of the callback to be unregistered
00437   *         This parameter can be one of the following values:
00438   *          @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
00439   *          @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
00440   *          @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
00441   *          @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
00442   *          @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
00443   *          @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
00444   *          @arg @ref HAL_PCD_DISCONNECT_CB_ID OTG PCD Disconnect callback ID
00445   *          @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
00446   *          @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
00447   * @retval HAL status
00448   */
00449 HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID)
00450 {
00451   HAL_StatusTypeDef status = HAL_OK;
00452 
00453   /* Process locked */
00454   __HAL_LOCK(hpcd);
00455 
00456   /* Setup Legacy weak Callbacks  */
00457   if (hpcd->State == HAL_PCD_STATE_READY)
00458   {
00459     switch (CallbackID)
00460     {
00461       case HAL_PCD_SOF_CB_ID :
00462         hpcd->SOFCallback = HAL_PCD_SOFCallback;
00463         break;
00464 
00465       case HAL_PCD_SETUPSTAGE_CB_ID :
00466         hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
00467         break;
00468 
00469       case HAL_PCD_RESET_CB_ID :
00470         hpcd->ResetCallback = HAL_PCD_ResetCallback;
00471         break;
00472 
00473       case HAL_PCD_SUSPEND_CB_ID :
00474         hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
00475         break;
00476 
00477       case HAL_PCD_RESUME_CB_ID :
00478         hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
00479         break;
00480 
00481       case HAL_PCD_CONNECT_CB_ID :
00482         hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
00483         break;
00484 
00485       case HAL_PCD_DISCONNECT_CB_ID :
00486         hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
00487         break;
00488 
00489       case HAL_PCD_MSPINIT_CB_ID :
00490         hpcd->MspInitCallback = HAL_PCD_MspInit;
00491         break;
00492 
00493       case HAL_PCD_MSPDEINIT_CB_ID :
00494         hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
00495         break;
00496 
00497       default :
00498         /* Update the error code */
00499         hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
00500 
00501         /* Return error status */
00502         status =  HAL_ERROR;
00503         break;
00504     }
00505   }
00506   else if (hpcd->State == HAL_PCD_STATE_RESET)
00507   {
00508     switch (CallbackID)
00509     {
00510       case HAL_PCD_MSPINIT_CB_ID :
00511         hpcd->MspInitCallback = HAL_PCD_MspInit;
00512         break;
00513 
00514       case HAL_PCD_MSPDEINIT_CB_ID :
00515         hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
00516         break;
00517 
00518       default :
00519         /* Update the error code */
00520         hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
00521 
00522         /* Return error status */
00523         status =  HAL_ERROR;
00524         break;
00525     }
00526   }
00527   else
00528   {
00529     /* Update the error code */
00530     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
00531 
00532     /* Return error status */
00533     status =  HAL_ERROR;
00534   }
00535 
00536   /* Release Lock */
00537   __HAL_UNLOCK(hpcd);
00538   return status;
00539 }
00540 
00541 /**
00542   * @brief  Register USB PCD Data OUT Stage Callback
00543   *         To be used instead of the weak HAL_PCD_DataOutStageCallback() predefined callback
00544   * @param  hpcd PCD handle
00545   * @param  pCallback pointer to the USB PCD Data OUT Stage Callback function
00546   * @retval HAL status
00547   */
00548 HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd, pPCD_DataOutStageCallbackTypeDef pCallback)
00549 {
00550   HAL_StatusTypeDef status = HAL_OK;
00551 
00552   if (pCallback == NULL)
00553   {
00554     /* Update the error code */
00555     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
00556 
00557     return HAL_ERROR;
00558   }
00559 
00560   /* Process locked */
00561   __HAL_LOCK(hpcd);
00562 
00563   if (hpcd->State == HAL_PCD_STATE_READY)
00564   {
00565     hpcd->DataOutStageCallback = pCallback;
00566   }
00567   else
00568   {
00569     /* Update the error code */
00570     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
00571 
00572     /* Return error status */
00573     status =  HAL_ERROR;
00574   }
00575 
00576   /* Release Lock */
00577   __HAL_UNLOCK(hpcd);
00578 
00579   return status;
00580 }
00581 
00582 /**
00583   * @brief  UnRegister the USB PCD Data OUT Stage Callback
00584   *         USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataOutStageCallback() predefined callback
00585   * @param  hpcd PCD handle
00586   * @retval HAL status
00587   */
00588 HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd)
00589 {
00590   HAL_StatusTypeDef status = HAL_OK;
00591 
00592   /* Process locked */
00593   __HAL_LOCK(hpcd);
00594 
00595   if (hpcd->State == HAL_PCD_STATE_READY)
00596   {
00597     hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback; /* Legacy weak DataOutStageCallback  */
00598   }
00599   else
00600   {
00601     /* Update the error code */
00602     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
00603 
00604     /* Return error status */
00605     status =  HAL_ERROR;
00606   }
00607 
00608   /* Release Lock */
00609   __HAL_UNLOCK(hpcd);
00610 
00611   return status;
00612 }
00613 
00614 /**
00615   * @brief  Register USB PCD Data IN Stage Callback
00616   *         To be used instead of the weak HAL_PCD_DataInStageCallback() predefined callback
00617   * @param  hpcd PCD handle
00618   * @param  pCallback pointer to the USB PCD Data IN Stage Callback function
00619   * @retval HAL status
00620   */
00621 HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd, pPCD_DataInStageCallbackTypeDef pCallback)
00622 {
00623   HAL_StatusTypeDef status = HAL_OK;
00624 
00625   if (pCallback == NULL)
00626   {
00627     /* Update the error code */
00628     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
00629 
00630     return HAL_ERROR;
00631   }
00632 
00633   /* Process locked */
00634   __HAL_LOCK(hpcd);
00635 
00636   if (hpcd->State == HAL_PCD_STATE_READY)
00637   {
00638     hpcd->DataInStageCallback = pCallback;
00639   }
00640   else
00641   {
00642     /* Update the error code */
00643     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
00644 
00645     /* Return error status */
00646     status =  HAL_ERROR;
00647   }
00648 
00649   /* Release Lock */
00650   __HAL_UNLOCK(hpcd);
00651 
00652   return status;
00653 }
00654 
00655 /**
00656   * @brief  UnRegister the USB PCD Data IN Stage Callback
00657   *         USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataInStageCallback() predefined callback
00658   * @param  hpcd PCD handle
00659   * @retval HAL status
00660   */
00661 HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd)
00662 {
00663   HAL_StatusTypeDef status = HAL_OK;
00664 
00665   /* Process locked */
00666   __HAL_LOCK(hpcd);
00667 
00668   if (hpcd->State == HAL_PCD_STATE_READY)
00669   {
00670     hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback; /* Legacy weak DataInStageCallback  */
00671   }
00672   else
00673   {
00674     /* Update the error code */
00675     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
00676 
00677     /* Return error status */
00678     status =  HAL_ERROR;
00679   }
00680 
00681   /* Release Lock */
00682   __HAL_UNLOCK(hpcd);
00683 
00684   return status;
00685 }
00686 
00687 /**
00688   * @brief  Register USB PCD Iso OUT incomplete Callback
00689   *         To be used instead of the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
00690   * @param  hpcd PCD handle
00691   * @param  pCallback pointer to the USB PCD Iso OUT incomplete Callback function
00692   * @retval HAL status
00693   */
00694 HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd, pPCD_IsoOutIncpltCallbackTypeDef pCallback)
00695 {
00696   HAL_StatusTypeDef status = HAL_OK;
00697 
00698   if (pCallback == NULL)
00699   {
00700     /* Update the error code */
00701     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
00702 
00703     return HAL_ERROR;
00704   }
00705 
00706   /* Process locked */
00707   __HAL_LOCK(hpcd);
00708 
00709   if (hpcd->State == HAL_PCD_STATE_READY)
00710   {
00711     hpcd->ISOOUTIncompleteCallback = pCallback;
00712   }
00713   else
00714   {
00715     /* Update the error code */
00716     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
00717 
00718     /* Return error status */
00719     status =  HAL_ERROR;
00720   }
00721 
00722   /* Release Lock */
00723   __HAL_UNLOCK(hpcd);
00724 
00725   return status;
00726 }
00727 
00728 /**
00729   * @brief  UnRegister the USB PCD Iso OUT incomplete Callback
00730   *         USB PCD Iso OUT incomplete Callback is redirected to the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
00731   * @param  hpcd PCD handle
00732   * @retval HAL status
00733   */
00734 HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd)
00735 {
00736   HAL_StatusTypeDef status = HAL_OK;
00737 
00738   /* Process locked */
00739   __HAL_LOCK(hpcd);
00740 
00741   if (hpcd->State == HAL_PCD_STATE_READY)
00742   {
00743     hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback; /* Legacy weak ISOOUTIncompleteCallback  */
00744   }
00745   else
00746   {
00747     /* Update the error code */
00748     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
00749 
00750     /* Return error status */
00751     status =  HAL_ERROR;
00752   }
00753 
00754   /* Release Lock */
00755   __HAL_UNLOCK(hpcd);
00756 
00757   return status;
00758 }
00759 
00760 /**
00761   * @brief  Register USB PCD Iso IN incomplete Callback
00762   *         To be used instead of the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
00763   * @param  hpcd PCD handle
00764   * @param  pCallback pointer to the USB PCD Iso IN incomplete Callback function
00765   * @retval HAL status
00766   */
00767 HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd, pPCD_IsoInIncpltCallbackTypeDef pCallback)
00768 {
00769   HAL_StatusTypeDef status = HAL_OK;
00770 
00771   if (pCallback == NULL)
00772   {
00773     /* Update the error code */
00774     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
00775 
00776     return HAL_ERROR;
00777   }
00778 
00779   /* Process locked */
00780   __HAL_LOCK(hpcd);
00781 
00782   if (hpcd->State == HAL_PCD_STATE_READY)
00783   {
00784     hpcd->ISOINIncompleteCallback = pCallback;
00785   }
00786   else
00787   {
00788     /* Update the error code */
00789     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
00790 
00791     /* Return error status */
00792     status =  HAL_ERROR;
00793   }
00794 
00795   /* Release Lock */
00796   __HAL_UNLOCK(hpcd);
00797 
00798   return status;
00799 }
00800 
00801 /**
00802   * @brief  UnRegister the USB PCD Iso IN incomplete Callback
00803   *         USB PCD Iso IN incomplete Callback is redirected to the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
00804   * @param  hpcd PCD handle
00805   * @retval HAL status
00806   */
00807 HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd)
00808 {
00809   HAL_StatusTypeDef status = HAL_OK;
00810 
00811   /* Process locked */
00812   __HAL_LOCK(hpcd);
00813 
00814   if (hpcd->State == HAL_PCD_STATE_READY)
00815   {
00816     hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback; /* Legacy weak ISOINIncompleteCallback  */
00817   }
00818   else
00819   {
00820     /* Update the error code */
00821     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
00822 
00823     /* Return error status */
00824     status =  HAL_ERROR;
00825   }
00826 
00827   /* Release Lock */
00828   __HAL_UNLOCK(hpcd);
00829 
00830   return status;
00831 }
00832 
00833 /**
00834   * @brief  Register USB PCD BCD Callback
00835   *         To be used instead of the weak HAL_PCDEx_BCD_Callback() predefined callback
00836   * @param  hpcd PCD handle
00837   * @param  pCallback pointer to the USB PCD BCD Callback function
00838   * @retval HAL status
00839   */
00840 HAL_StatusTypeDef HAL_PCD_RegisterBcdCallback(PCD_HandleTypeDef *hpcd, pPCD_BcdCallbackTypeDef pCallback)
00841 {
00842   HAL_StatusTypeDef status = HAL_OK;
00843 
00844   if (pCallback == NULL)
00845   {
00846     /* Update the error code */
00847     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
00848 
00849     return HAL_ERROR;
00850   }
00851 
00852   /* Process locked */
00853   __HAL_LOCK(hpcd);
00854 
00855   if (hpcd->State == HAL_PCD_STATE_READY)
00856   {
00857     hpcd->BCDCallback = pCallback;
00858   }
00859   else
00860   {
00861     /* Update the error code */
00862     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
00863 
00864     /* Return error status */
00865     status =  HAL_ERROR;
00866   }
00867 
00868   /* Release Lock */
00869   __HAL_UNLOCK(hpcd);
00870 
00871   return status;
00872 }
00873 
00874 /**
00875   * @brief  UnRegister the USB PCD BCD Callback
00876   *         USB BCD Callback is redirected to the weak HAL_PCDEx_BCD_Callback() predefined callback
00877   * @param  hpcd PCD handle
00878   * @retval HAL status
00879   */
00880 HAL_StatusTypeDef HAL_PCD_UnRegisterBcdCallback(PCD_HandleTypeDef *hpcd)
00881 {
00882   HAL_StatusTypeDef status = HAL_OK;
00883 
00884   /* Process locked */
00885   __HAL_LOCK(hpcd);
00886 
00887   if (hpcd->State == HAL_PCD_STATE_READY)
00888   {
00889     hpcd->BCDCallback = HAL_PCDEx_BCD_Callback; /* Legacy weak HAL_PCDEx_BCD_Callback  */
00890   }
00891   else
00892   {
00893     /* Update the error code */
00894     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
00895 
00896     /* Return error status */
00897     status =  HAL_ERROR;
00898   }
00899 
00900   /* Release Lock */
00901   __HAL_UNLOCK(hpcd);
00902 
00903   return status;
00904 }
00905 
00906 /**
00907   * @brief  Register USB PCD LPM Callback
00908   *         To be used instead of the weak HAL_PCDEx_LPM_Callback() predefined callback
00909   * @param  hpcd PCD handle
00910   * @param  pCallback pointer to the USB PCD LPM Callback function
00911   * @retval HAL status
00912   */
00913 HAL_StatusTypeDef HAL_PCD_RegisterLpmCallback(PCD_HandleTypeDef *hpcd, pPCD_LpmCallbackTypeDef pCallback)
00914 {
00915   HAL_StatusTypeDef status = HAL_OK;
00916 
00917   if (pCallback == NULL)
00918   {
00919     /* Update the error code */
00920     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
00921 
00922     return HAL_ERROR;
00923   }
00924 
00925   /* Process locked */
00926   __HAL_LOCK(hpcd);
00927 
00928   if (hpcd->State == HAL_PCD_STATE_READY)
00929   {
00930     hpcd->LPMCallback = pCallback;
00931   }
00932   else
00933   {
00934     /* Update the error code */
00935     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
00936 
00937     /* Return error status */
00938     status =  HAL_ERROR;
00939   }
00940 
00941   /* Release Lock */
00942   __HAL_UNLOCK(hpcd);
00943 
00944   return status;
00945 }
00946 
00947 /**
00948   * @brief  UnRegister the USB PCD LPM Callback
00949   *         USB LPM Callback is redirected to the weak HAL_PCDEx_LPM_Callback() predefined callback
00950   * @param  hpcd PCD handle
00951   * @retval HAL status
00952   */
00953 HAL_StatusTypeDef HAL_PCD_UnRegisterLpmCallback(PCD_HandleTypeDef *hpcd)
00954 {
00955   HAL_StatusTypeDef status = HAL_OK;
00956 
00957   /* Process locked */
00958   __HAL_LOCK(hpcd);
00959 
00960   if (hpcd->State == HAL_PCD_STATE_READY)
00961   {
00962     hpcd->LPMCallback = HAL_PCDEx_LPM_Callback; /* Legacy weak HAL_PCDEx_LPM_Callback  */
00963   }
00964   else
00965   {
00966     /* Update the error code */
00967     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
00968 
00969     /* Return error status */
00970     status =  HAL_ERROR;
00971   }
00972 
00973   /* Release Lock */
00974   __HAL_UNLOCK(hpcd);
00975 
00976   return status;
00977 }
00978 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
00979 
00980 /**
00981   * @}
00982   */
00983 
00984 /** @defgroup PCD_Exported_Functions_Group2 Input and Output operation functions
00985  *  @brief   Data transfers functions
00986  *
00987 @verbatim
00988  ===============================================================================
00989                       ##### IO operation functions #####
00990  ===============================================================================
00991     [..]
00992     This subsection provides a set of functions allowing to manage the PCD data
00993     transfers.
00994 
00995 @endverbatim
00996   * @{
00997   */
00998 
00999 /**
01000   * @brief  Start the USB device
01001   * @param  hpcd PCD handle
01002   * @retval HAL status
01003   */
01004 HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)
01005 {
01006   __HAL_LOCK(hpcd);
01007   (void)USB_DevConnect(hpcd->Instance);
01008   __HAL_PCD_ENABLE(hpcd);
01009   __HAL_UNLOCK(hpcd);
01010   return HAL_OK;
01011 }
01012 
01013 /**
01014   * @brief  Stop the USB device.
01015   * @param  hpcd PCD handle
01016   * @retval HAL status
01017   */
01018 HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
01019 {
01020   __HAL_LOCK(hpcd);
01021   __HAL_PCD_DISABLE(hpcd);
01022   (void)USB_StopDevice(hpcd->Instance);
01023   (void)USB_DevDisconnect(hpcd->Instance);
01024   __HAL_UNLOCK(hpcd);
01025   return HAL_OK;
01026 }
01027 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
01028 /**
01029   * @brief  Handles PCD interrupt request.
01030   * @param  hpcd PCD handle
01031   * @retval HAL status
01032   */
01033 void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
01034 {
01035   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
01036   uint32_t USBx_BASE = (uint32_t)USBx;
01037   uint32_t TempReg = USBx_BASE + 0x40U;
01038   uint32_t gSNPSiD = *(uint32_t *) TempReg;
01039   uint32_t i, ep_intr, epint, epnum = 0U;
01040   uint32_t fifoemptymsk, temp;
01041   USB_OTG_EPTypeDef *ep;
01042   uint32_t hclk;
01043 
01044   /* ensure that we are in device mode */
01045   if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE)
01046   {
01047     /* avoid spurious interrupt */
01048     if (__HAL_PCD_IS_INVALID_INTERRUPT(hpcd))
01049     {
01050       return;
01051     }
01052 
01053     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS))
01054     {
01055       /* incorrect mode, acknowledge the interrupt */
01056       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS);
01057     }
01058 
01059     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT))
01060     {
01061       epnum = 0U;
01062 
01063       /* Read in the device interrupt bits */
01064       ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance);
01065 
01066       while (ep_intr != 0U)
01067       {
01068         if ((ep_intr & 0x1U) != 0U)
01069         {
01070           epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, (uint8_t)epnum);
01071 
01072           if ((epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC)
01073           {
01074             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC);
01075 
01076             if (gSNPSiD == USB_OTG_CORE_ID_310A)
01077             {
01078               if ((USBx_OUTEP(0U)->DOEPINT & (1U << 15)) != 0U)
01079               {
01080                 CLEAR_OUT_EP_INTR(epnum, (1U << 15));
01081               }
01082               else
01083               {
01084 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
01085                 hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
01086 #else
01087                 HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
01088 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
01089               }
01090             }
01091             else
01092             {
01093 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
01094               hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
01095 #else
01096               HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
01097 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
01098             }
01099           }
01100 
01101           if ((epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP)
01102           {
01103             if (gSNPSiD == USB_OTG_CORE_ID_310A)
01104             {
01105               if ((USBx_OUTEP(0U)->DOEPINT & (1U << 15)) != 0U)
01106               {
01107                 CLEAR_OUT_EP_INTR(epnum, (1U << 15));
01108               }
01109             }
01110             /* Inform the upper layer that a setup packet is available */
01111 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
01112             hpcd->SetupStageCallback(hpcd);
01113 #else
01114             HAL_PCD_SetupStageCallback(hpcd);
01115 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
01116 
01117             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP);
01118           }
01119 
01120           if ((epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS)
01121           {
01122             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS);
01123           }
01124 
01125 #ifdef USB_OTG_DOEPINT_OTEPSPR
01126           /* Clear Status Phase Received interrupt */
01127           if ((epint & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR)
01128           {
01129             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
01130           }
01131 #endif /* USB_OTG_DOEPINT_OTEPSPR */
01132         }
01133         epnum++;
01134         ep_intr >>= 1U;
01135       }
01136     }
01137 
01138     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT))
01139     {
01140       /* Read in the device interrupt bits */
01141       ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance);
01142 
01143       epnum = 0U;
01144 
01145       while (ep_intr != 0U)
01146       {
01147         if ((ep_intr & 0x1U) != 0U) /* In ITR */
01148         {
01149           epint = USB_ReadDevInEPInterrupt(hpcd->Instance, (uint8_t)epnum);
01150 
01151           if ((epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC)
01152           {
01153             fifoemptymsk = (uint32_t)(0x1UL << (epnum & 0xFU));
01154             USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
01155 
01156             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC);
01157 
01158 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
01159             hpcd->DataInStageCallback(hpcd, (uint8_t)epnum);
01160 #else
01161             HAL_PCD_DataInStageCallback(hpcd, (uint8_t)epnum);
01162 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
01163           }
01164           if ((epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC)
01165           {
01166             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC);
01167           }
01168           if ((epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE)
01169           {
01170             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE);
01171           }
01172           if ((epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE)
01173           {
01174             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE);
01175           }
01176           if ((epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD)
01177           {
01178             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD);
01179           }
01180           if ((epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE)
01181           {
01182             (void)PCD_WriteEmptyTxFifo(hpcd, epnum);
01183           }
01184         }
01185         epnum++;
01186         ep_intr >>= 1U;
01187       }
01188     }
01189 
01190     /* Handle Resume Interrupt */
01191     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT))
01192     {
01193       /* Clear the Remote Wake-up Signaling */
01194       USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
01195 
01196       if (hpcd->LPM_State == LPM_L1)
01197       {
01198         hpcd->LPM_State = LPM_L0;
01199 
01200 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
01201         hpcd->LPMCallback(hpcd, PCD_LPM_L0_ACTIVE);
01202 #else
01203         HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE);
01204 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
01205       }
01206       else
01207       {
01208 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
01209         hpcd->ResumeCallback(hpcd);
01210 #else
01211         HAL_PCD_ResumeCallback(hpcd);
01212 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
01213       }
01214 
01215       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT);
01216     }
01217 
01218     /* Handle Suspend Interrupt */
01219     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP))
01220     {
01221       if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
01222       {
01223 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
01224         hpcd->SuspendCallback(hpcd);
01225 #else
01226         HAL_PCD_SuspendCallback(hpcd);
01227 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
01228       }
01229       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP);
01230     }
01231 
01232     /* Handle LPM Interrupt */
01233     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT))
01234     {
01235       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT);
01236 
01237       if (hpcd->LPM_State == LPM_L0)
01238       {
01239         hpcd->LPM_State = LPM_L1;
01240         hpcd->BESL = (hpcd->Instance->GLPMCFG & USB_OTG_GLPMCFG_BESL) >> 2U;
01241 
01242 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
01243         hpcd->LPMCallback(hpcd, PCD_LPM_L1_ACTIVE);
01244 #else
01245         HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE);
01246 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
01247       }
01248       else
01249       {
01250 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
01251         hpcd->SuspendCallback(hpcd);
01252 #else
01253         HAL_PCD_SuspendCallback(hpcd);
01254 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
01255       }
01256     }
01257 
01258     /* Handle Reset Interrupt */
01259     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST))
01260     {
01261       USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
01262       (void)USB_FlushTxFifo(hpcd->Instance, 0x10U);
01263 
01264       for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
01265       {
01266         USBx_INEP(i)->DIEPINT = 0xFB7FU;
01267         USBx_INEP(i)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
01268         USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
01269         USBx_OUTEP(i)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
01270       }
01271       USBx_DEVICE->DAINTMSK |= 0x10001U;
01272 
01273       if (hpcd->Init.use_dedicated_ep1 != 0U)
01274       {
01275         USBx_DEVICE->DOUTEP1MSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM);
01276         USBx_DEVICE->DINEP1MSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM);
01277       }
01278       else
01279       {
01280 #ifdef USB_OTG_DOEPINT_OTEPSPR
01281         USBx_DEVICE->DOEPMSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM | USB_OTG_DOEPMSK_OTEPSPRM);
01282 #else
01283         USBx_DEVICE->DOEPMSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM);
01284 #endif /* USB_OTG_DOEPINT_OTEPSPR */
01285         USBx_DEVICE->DIEPMSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM);
01286       }
01287 
01288       /* Set Default Address to 0 */
01289       USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD;
01290 
01291       /* setup EP0 to receive SETUP packets */
01292       (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
01293 
01294       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST);
01295     }
01296 
01297     /* Handle Enumeration done Interrupt */
01298     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE))
01299     {
01300       (void)USB_ActivateSetup(hpcd->Instance);
01301       hpcd->Instance->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
01302         hpcd->Init.speed            = USB_OTG_SPEED_FULL;
01303         hpcd->Init.ep0_mps          = USB_OTG_FS_MAX_PACKET_SIZE;
01304 
01305         /* The USBTRD is configured according to the tables below, depending on AHB frequency
01306         used by application. In the low AHB frequency range it is used to stretch enough the USB response
01307         time to IN tokens, the USB turnaround time, so to compensate for the longer AHB read access
01308         latency to the Data FIFO */
01309 
01310         /* Get hclk frequency value */
01311         hclk = HAL_RCC_GetHCLKFreq();
01312 
01313         if ((hclk >= 14200000U) && (hclk < 15000000U))
01314         {
01315           /* hclk Clock Range between 14.2-15 MHz */
01316           hpcd->Instance->GUSBCFG |= (uint32_t)((0xFU << 10) & USB_OTG_GUSBCFG_TRDT);
01317         }
01318 
01319         else if ((hclk >= 15000000U) && (hclk < 16000000U))
01320         {
01321           /* hclk Clock Range between 15-16 MHz */
01322           hpcd->Instance->GUSBCFG |= (uint32_t)((0xEU << 10) & USB_OTG_GUSBCFG_TRDT);
01323         }
01324 
01325         else if ((hclk >= 16000000U) && (hclk < 17200000U))
01326         {
01327           /* hclk Clock Range between 16-17.2 MHz */
01328           hpcd->Instance->GUSBCFG |= (uint32_t)((0xDU << 10) & USB_OTG_GUSBCFG_TRDT);
01329         }
01330 
01331         else if ((hclk >= 17200000U) && (hclk < 18500000U))
01332         {
01333           /* hclk Clock Range between 17.2-18.5 MHz */
01334           hpcd->Instance->GUSBCFG |= (uint32_t)((0xCU << 10) & USB_OTG_GUSBCFG_TRDT);
01335         }
01336 
01337         else if ((hclk >= 18500000U) && (hclk < 20000000U))
01338         {
01339           /* hclk Clock Range between 18.5-20 MHz */
01340           hpcd->Instance->GUSBCFG |= (uint32_t)((0xBU << 10) & USB_OTG_GUSBCFG_TRDT);
01341         }
01342 
01343         else if ((hclk >= 20000000U) && (hclk < 21800000U))
01344         {
01345           /* hclk Clock Range between 20-21.8 MHz */
01346           hpcd->Instance->GUSBCFG |= (uint32_t)((0xAU << 10) & USB_OTG_GUSBCFG_TRDT);
01347         }
01348 
01349         else if ((hclk >= 21800000U) && (hclk < 24000000U))
01350         {
01351           /* hclk Clock Range between 21.8-24 MHz */
01352           hpcd->Instance->GUSBCFG |= (uint32_t)((0x9U << 10) & USB_OTG_GUSBCFG_TRDT);
01353         }
01354 
01355         else if ((hclk >= 24000000U) && (hclk < 27700000U))
01356         {
01357           /* hclk Clock Range between 24-27.7 MHz */
01358           hpcd->Instance->GUSBCFG |= (uint32_t)((0x8U << 10) & USB_OTG_GUSBCFG_TRDT);
01359         }
01360 
01361         else if ((hclk >= 27700000U) && (hclk < 32000000U))
01362         {
01363           /* hclk Clock Range between 27.7-32 MHz */
01364           hpcd->Instance->GUSBCFG |= (uint32_t)((0x7U << 10) & USB_OTG_GUSBCFG_TRDT);
01365         }
01366 
01367         else /* if(hclk >= 32000000) */
01368         {
01369           /* hclk Clock Range between 32-200 MHz */
01370           hpcd->Instance->GUSBCFG |= (uint32_t)((0x6U << 10) & USB_OTG_GUSBCFG_TRDT);
01371         }
01372 
01373 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
01374       hpcd->ResetCallback(hpcd);
01375 #else
01376       HAL_PCD_ResetCallback(hpcd);
01377 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
01378 
01379       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE);
01380     }
01381 
01382     /* Handle RxQLevel Interrupt */
01383     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL))
01384     {
01385       USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
01386 
01387       temp = USBx->GRXSTSP;
01388 
01389       ep = &hpcd->OUT_ep[temp & USB_OTG_GRXSTSP_EPNUM];
01390 
01391       if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) ==  STS_DATA_UPDT)
01392       {
01393         if ((temp & USB_OTG_GRXSTSP_BCNT) != 0U)
01394         {
01395           (void)USB_ReadPacket(USBx, ep->xfer_buff, (uint16_t)((temp & USB_OTG_GRXSTSP_BCNT) >> 4));
01396           ep->xfer_buff += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
01397           ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
01398         }
01399       }
01400       else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) ==  STS_SETUP_UPDT)
01401       {
01402         (void)USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8U);
01403         ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
01404       }
01405       else
01406       {
01407         /* ... */
01408       }
01409       USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
01410     }
01411 
01412     /* Handle SOF Interrupt */
01413     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF))
01414     {
01415 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
01416       hpcd->SOFCallback(hpcd);
01417 #else
01418       HAL_PCD_SOFCallback(hpcd);
01419 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
01420 
01421       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF);
01422     }
01423 
01424     /* Handle Incomplete ISO IN Interrupt */
01425     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR))
01426     {
01427 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
01428       hpcd->ISOINIncompleteCallback(hpcd, (uint8_t)epnum);
01429 #else
01430       HAL_PCD_ISOINIncompleteCallback(hpcd, (uint8_t)epnum);
01431 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
01432 
01433       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR);
01434     }
01435 
01436     /* Handle Incomplete ISO OUT Interrupt */
01437     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
01438     {
01439 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
01440       hpcd->ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum);
01441 #else
01442       HAL_PCD_ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum);
01443 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
01444 
01445       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
01446     }
01447 
01448     /* Handle Connection event Interrupt */
01449     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT))
01450     {
01451 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
01452       hpcd->ConnectCallback(hpcd);
01453 #else
01454       HAL_PCD_ConnectCallback(hpcd);
01455 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
01456 
01457       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT);
01458     }
01459 
01460     /* Handle Disconnection event Interrupt */
01461     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT))
01462     {
01463       temp = hpcd->Instance->GOTGINT;
01464 
01465       if ((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET)
01466       {
01467 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
01468         hpcd->DisconnectCallback(hpcd);
01469 #else
01470         HAL_PCD_DisconnectCallback(hpcd);
01471 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
01472       }
01473       hpcd->Instance->GOTGINT |= temp;
01474     }
01475   }
01476 }
01477 #endif /* USB_OTG_FS || USB_OTG_HS */
01478 
01479 #if defined (USB)
01480 /**
01481   * @brief  This function handles PCD interrupt request.
01482   * @param  hpcd PCD handle
01483   * @retval HAL status
01484   */
01485 void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
01486 {
01487   if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_CTR))
01488   {
01489     /* servicing of the endpoint correct transfer interrupt */
01490     /* clear of the CTR flag into the sub */
01491     (void)PCD_EP_ISR_Handler(hpcd);
01492   }
01493 
01494   if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_RESET))
01495   {
01496     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET);
01497 
01498 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
01499     hpcd->ResetCallback(hpcd);
01500 #else
01501     HAL_PCD_ResetCallback(hpcd);
01502 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
01503 
01504     (void)HAL_PCD_SetAddress(hpcd, 0U);
01505   }
01506 
01507   if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_PMAOVR))
01508   {
01509     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_PMAOVR);
01510   }
01511 
01512   if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_ERR))
01513   {
01514     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ERR);
01515   }
01516 
01517   if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_WKUP))
01518   {
01519     hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_LPMODE);
01520     hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_FSUSP);
01521 
01522     if (hpcd->LPM_State == LPM_L1)
01523     {
01524       hpcd->LPM_State = LPM_L0;
01525 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
01526       hpcd->LPMCallback(hpcd, PCD_LPM_L0_ACTIVE);
01527 #else
01528       HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE);
01529 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
01530     }
01531 
01532 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
01533     hpcd->ResumeCallback(hpcd);
01534 #else
01535     HAL_PCD_ResumeCallback(hpcd);
01536 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
01537 
01538     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP);
01539   }
01540 
01541   if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_SUSP))
01542   {
01543     /* Force low-power mode in the macrocell */
01544     hpcd->Instance->CNTR |= USB_CNTR_FSUSP;
01545 
01546     /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
01547     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SUSP);
01548 
01549     hpcd->Instance->CNTR |= USB_CNTR_LPMODE;
01550 
01551     if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_WKUP) == 0U)
01552     {
01553 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
01554       hpcd->SuspendCallback(hpcd);
01555 #else
01556       HAL_PCD_SuspendCallback(hpcd);
01557 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
01558     }
01559   }
01560 
01561   /* Handle LPM Interrupt */
01562   if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_L1REQ))
01563   {
01564     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_L1REQ);
01565     if (hpcd->LPM_State == LPM_L0)
01566     {
01567       /* Force suspend and low-power mode before going to L1 state*/
01568       hpcd->Instance->CNTR |= USB_CNTR_LPMODE;
01569       hpcd->Instance->CNTR |= USB_CNTR_FSUSP;
01570 
01571       hpcd->LPM_State = LPM_L1;
01572       hpcd->BESL = ((uint32_t)hpcd->Instance->LPMCSR & USB_LPMCSR_BESL) >> 2;
01573 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
01574       hpcd->LPMCallback(hpcd, PCD_LPM_L1_ACTIVE);
01575 #else
01576       HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE);
01577 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
01578     }
01579     else
01580     {
01581 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
01582       hpcd->SuspendCallback(hpcd);
01583 #else
01584       HAL_PCD_SuspendCallback(hpcd);
01585 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
01586     }
01587   }
01588 
01589   if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_SOF))
01590   {
01591     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SOF);
01592 
01593 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
01594     hpcd->SOFCallback(hpcd);
01595 #else
01596     HAL_PCD_SOFCallback(hpcd);
01597 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
01598   }
01599 
01600   if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_ESOF))
01601   {
01602     /* clear ESOF flag in ISTR */
01603     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ESOF);
01604   }
01605 }
01606 #endif /* USB */
01607 
01608 /**
01609   * @brief  Data OUT stage callback.
01610   * @param  hpcd PCD handle
01611   * @param  epnum endpoint number
01612   * @retval None
01613   */
01614 __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
01615 {
01616   /* Prevent unused argument(s) compilation warning */
01617   UNUSED(hpcd);
01618   UNUSED(epnum);
01619 
01620   /* NOTE : This function should not be modified, when the callback is needed,
01621             the HAL_PCD_DataOutStageCallback could be implemented in the user file
01622    */
01623 }
01624 
01625 /**
01626   * @brief  Data IN stage callback
01627   * @param  hpcd PCD handle
01628   * @param  epnum endpoint number
01629   * @retval None
01630   */
01631 __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
01632 {
01633   /* Prevent unused argument(s) compilation warning */
01634   UNUSED(hpcd);
01635   UNUSED(epnum);
01636 
01637   /* NOTE : This function should not be modified, when the callback is needed,
01638             the HAL_PCD_DataInStageCallback could be implemented in the user file
01639    */
01640 }
01641 /**
01642   * @brief  Setup stage callback
01643   * @param  hpcd PCD handle
01644   * @retval None
01645   */
01646 __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
01647 {
01648   /* Prevent unused argument(s) compilation warning */
01649   UNUSED(hpcd);
01650 
01651   /* NOTE : This function should not be modified, when the callback is needed,
01652             the HAL_PCD_SetupStageCallback could be implemented in the user file
01653    */
01654 }
01655 
01656 /**
01657   * @brief  USB Start Of Frame callback.
01658   * @param  hpcd PCD handle
01659   * @retval None
01660   */
01661 __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
01662 {
01663   /* Prevent unused argument(s) compilation warning */
01664   UNUSED(hpcd);
01665 
01666   /* NOTE : This function should not be modified, when the callback is needed,
01667             the HAL_PCD_SOFCallback could be implemented in the user file
01668    */
01669 }
01670 
01671 /**
01672   * @brief  USB Reset callback.
01673   * @param  hpcd PCD handle
01674   * @retval None
01675   */
01676 __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
01677 {
01678   /* Prevent unused argument(s) compilation warning */
01679   UNUSED(hpcd);
01680 
01681   /* NOTE : This function should not be modified, when the callback is needed,
01682             the HAL_PCD_ResetCallback could be implemented in the user file
01683    */
01684 }
01685 
01686 /**
01687   * @brief  Suspend event callback.
01688   * @param  hpcd PCD handle
01689   * @retval None
01690   */
01691 __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
01692 {
01693   /* Prevent unused argument(s) compilation warning */
01694   UNUSED(hpcd);
01695 
01696   /* NOTE : This function should not be modified, when the callback is needed,
01697             the HAL_PCD_SuspendCallback could be implemented in the user file
01698    */
01699 }
01700 
01701 /**
01702   * @brief  Resume event callback.
01703   * @param  hpcd PCD handle
01704   * @retval None
01705   */
01706 __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
01707 {
01708   /* Prevent unused argument(s) compilation warning */
01709   UNUSED(hpcd);
01710 
01711   /* NOTE : This function should not be modified, when the callback is needed,
01712             the HAL_PCD_ResumeCallback could be implemented in the user file
01713    */
01714 }
01715 
01716 /**
01717   * @brief  Incomplete ISO OUT callback.
01718   * @param  hpcd PCD handle
01719   * @param  epnum endpoint number
01720   * @retval None
01721   */
01722 __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
01723 {
01724   /* Prevent unused argument(s) compilation warning */
01725   UNUSED(hpcd);
01726   UNUSED(epnum);
01727 
01728   /* NOTE : This function should not be modified, when the callback is needed,
01729             the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file
01730    */
01731 }
01732 
01733 /**
01734   * @brief  Incomplete ISO IN callback.
01735   * @param  hpcd PCD handle
01736   * @param  epnum endpoint number
01737   * @retval None
01738   */
01739 __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
01740 {
01741   /* Prevent unused argument(s) compilation warning */
01742   UNUSED(hpcd);
01743   UNUSED(epnum);
01744 
01745   /* NOTE : This function should not be modified, when the callback is needed,
01746             the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file
01747    */
01748 }
01749 
01750 /**
01751   * @brief  Connection event callback.
01752   * @param  hpcd PCD handle
01753   * @retval None
01754   */
01755 __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
01756 {
01757   /* Prevent unused argument(s) compilation warning */
01758   UNUSED(hpcd);
01759 
01760   /* NOTE : This function should not be modified, when the callback is needed,
01761             the HAL_PCD_ConnectCallback could be implemented in the user file
01762    */
01763 }
01764 
01765 /**
01766   * @brief  Disconnection event callback.
01767   * @param  hpcd PCD handle
01768   * @retval None
01769   */
01770 __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
01771 {
01772   /* Prevent unused argument(s) compilation warning */
01773   UNUSED(hpcd);
01774 
01775   /* NOTE : This function should not be modified, when the callback is needed,
01776             the HAL_PCD_DisconnectCallback could be implemented in the user file
01777    */
01778 }
01779 
01780 /**
01781   * @}
01782   */
01783 
01784 /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
01785  *  @brief   management functions
01786  *
01787 @verbatim
01788  ===============================================================================
01789                       ##### Peripheral Control functions #####
01790  ===============================================================================
01791     [..]
01792     This subsection provides a set of functions allowing to control the PCD data
01793     transfers.
01794 
01795 @endverbatim
01796   * @{
01797   */
01798 
01799 /**
01800   * @brief  Connect the USB device
01801   * @param  hpcd PCD handle
01802   * @retval HAL status
01803   */
01804 HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd)
01805 {
01806   __HAL_LOCK(hpcd);
01807   (void)USB_DevConnect(hpcd->Instance);
01808   __HAL_UNLOCK(hpcd);
01809   return HAL_OK;
01810 }
01811 
01812 /**
01813   * @brief  Disconnect the USB device.
01814   * @param  hpcd PCD handle
01815   * @retval HAL status
01816   */
01817 HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd)
01818 {
01819   __HAL_LOCK(hpcd);
01820   (void)USB_DevDisconnect(hpcd->Instance);
01821   __HAL_UNLOCK(hpcd);
01822   return HAL_OK;
01823 }
01824 
01825 /**
01826   * @brief  Set the USB Device address.
01827   * @param  hpcd PCD handle
01828   * @param  address new device address
01829   * @retval HAL status
01830   */
01831 HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)
01832 {
01833   __HAL_LOCK(hpcd);
01834   hpcd->USB_Address = address;
01835   (void)USB_SetDevAddress(hpcd->Instance, address);
01836   __HAL_UNLOCK(hpcd);
01837   return HAL_OK;
01838 }
01839 /**
01840   * @brief  Open and configure an endpoint.
01841   * @param  hpcd PCD handle
01842   * @param  ep_addr endpoint address
01843   * @param  ep_mps endpoint max packet size
01844   * @param  ep_type endpoint type
01845   * @retval HAL status
01846   */
01847 HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type)
01848 {
01849   HAL_StatusTypeDef  ret = HAL_OK;
01850   PCD_EPTypeDef *ep;
01851 
01852   if ((ep_addr & 0x80U) == 0x80U)
01853   {
01854     ep = &hpcd->IN_ep[ep_addr & 0xFU];
01855     ep->is_in = 1U;
01856   }
01857   else
01858   {
01859     ep = &hpcd->OUT_ep[ep_addr & 0xFU];
01860     ep->is_in = 0U;
01861   }
01862 
01863   ep->num = ep_addr & 0xFU;
01864   ep->maxpacket = ep_mps;
01865   ep->type = ep_type;
01866 
01867   if (ep->is_in != 0U)
01868   {
01869     /* Assign a Tx FIFO */
01870     ep->tx_fifo_num = ep->num;
01871   }
01872   /* Set initial data PID. */
01873   if (ep_type == EP_TYPE_BULK)
01874   {
01875     ep->data_pid_start = 0U;
01876   }
01877 
01878   __HAL_LOCK(hpcd);
01879   (void)USB_ActivateEndpoint(hpcd->Instance, ep);
01880   __HAL_UNLOCK(hpcd);
01881 
01882   return ret;
01883 }
01884 
01885 /**
01886   * @brief  Deactivate an endpoint.
01887   * @param  hpcd PCD handle
01888   * @param  ep_addr endpoint address
01889   * @retval HAL status
01890   */
01891 HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
01892 {
01893   PCD_EPTypeDef *ep;
01894 
01895   if ((ep_addr & 0x80U) == 0x80U)
01896   {
01897     ep = &hpcd->IN_ep[ep_addr & 0xFU];
01898     ep->is_in = 1U;
01899   }
01900   else
01901   {
01902     ep = &hpcd->OUT_ep[ep_addr & 0xFU];
01903     ep->is_in = 0U;
01904   }
01905   ep->num   = ep_addr & 0xFU;
01906 
01907   __HAL_LOCK(hpcd);
01908   (void)USB_DeactivateEndpoint(hpcd->Instance, ep);
01909   __HAL_UNLOCK(hpcd);
01910   return HAL_OK;
01911 }
01912 
01913 
01914 /**
01915   * @brief  Receive an amount of data.
01916   * @param  hpcd PCD handle
01917   * @param  ep_addr endpoint address
01918   * @param  pBuf pointer to the reception buffer
01919   * @param  len amount of data to be received
01920   * @retval HAL status
01921   */
01922 HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
01923 {
01924   PCD_EPTypeDef *ep;
01925 
01926   ep = &hpcd->OUT_ep[ep_addr & 0xFU];
01927 
01928   /*setup and start the Xfer */
01929   ep->xfer_buff = pBuf;
01930   ep->xfer_len = len;
01931   ep->xfer_count = 0U;
01932   ep->is_in = 0U;
01933   ep->num = ep_addr & 0xFU;
01934 
01935   if ((ep_addr & 0xFU) == 0U)
01936   {
01937     (void)USB_EP0StartXfer(hpcd->Instance, ep);
01938   }
01939   else
01940   {
01941     (void)USB_EPStartXfer(hpcd->Instance, ep);
01942   }
01943 
01944   return HAL_OK;
01945 }
01946 
01947 /**
01948   * @brief  Get Received Data Size
01949   * @param  hpcd PCD handle
01950   * @param  ep_addr endpoint address
01951   * @retval Data Size
01952   */
01953 uint16_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
01954 {
01955   return (uint16_t)hpcd->OUT_ep[ep_addr & 0xFU].xfer_count;
01956 }
01957 /**
01958   * @brief  Send an amount of data
01959   * @param  hpcd PCD handle
01960   * @param  ep_addr endpoint address
01961   * @param  pBuf pointer to the transmission buffer
01962   * @param  len amount of data to be sent
01963   * @retval HAL status
01964   */
01965 HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
01966 {
01967   PCD_EPTypeDef *ep;
01968 
01969   ep = &hpcd->IN_ep[ep_addr & 0xFU];
01970 
01971   /*setup and start the Xfer */
01972   ep->xfer_buff = pBuf;
01973   ep->xfer_len = len;
01974   ep->xfer_count = 0U;
01975   ep->is_in = 1U;
01976   ep->num = ep_addr & 0xFU;
01977 
01978   if ((ep_addr & 0xFU) == 0U)
01979   {
01980     (void)USB_EP0StartXfer(hpcd->Instance, ep);
01981   }
01982   else
01983   {
01984     (void)USB_EPStartXfer(hpcd->Instance, ep);
01985   }
01986 
01987   return HAL_OK;
01988 }
01989 
01990 /**
01991   * @brief  Set a STALL condition over an endpoint
01992   * @param  hpcd PCD handle
01993   * @param  ep_addr endpoint address
01994   * @retval HAL status
01995   */
01996 HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
01997 {
01998   PCD_EPTypeDef *ep;
01999 
02000   if (((uint32_t)ep_addr & 0xFU) > hpcd->Init.dev_endpoints)
02001   {
02002     return HAL_ERROR;
02003   }
02004 
02005   if ((0x80U & ep_addr) == 0x80U)
02006   {
02007     ep = &hpcd->IN_ep[ep_addr & 0xFU];
02008     ep->is_in = 1U;
02009   }
02010   else
02011   {
02012     ep = &hpcd->OUT_ep[ep_addr];
02013     ep->is_in = 0U;
02014   }
02015 
02016   ep->is_stall = 1U;
02017   ep->num = ep_addr & 0xFU;
02018 
02019   __HAL_LOCK(hpcd);
02020 
02021   (void)USB_EPSetStall(hpcd->Instance, ep);
02022   if ((ep_addr & 0xFU) == 0U)
02023   {
02024     (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
02025   }
02026   __HAL_UNLOCK(hpcd);
02027 
02028   return HAL_OK;
02029 }
02030 
02031 /**
02032   * @brief  Clear a STALL condition over in an endpoint
02033   * @param  hpcd PCD handle
02034   * @param  ep_addr endpoint address
02035   * @retval HAL status
02036   */
02037 HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
02038 {
02039   PCD_EPTypeDef *ep;
02040 
02041   if (((uint32_t)ep_addr & 0x0FU) > hpcd->Init.dev_endpoints)
02042   {
02043     return HAL_ERROR;
02044   }
02045 
02046   if ((0x80U & ep_addr) == 0x80U)
02047   {
02048     ep = &hpcd->IN_ep[ep_addr & 0xFU];
02049     ep->is_in = 1U;
02050   }
02051   else
02052   {
02053     ep = &hpcd->OUT_ep[ep_addr & 0xFU];
02054     ep->is_in = 0U;
02055   }
02056 
02057   ep->is_stall = 0U;
02058   ep->num = ep_addr & 0xFU;
02059 
02060   __HAL_LOCK(hpcd);
02061   (void)USB_EPClearStall(hpcd->Instance, ep);
02062   __HAL_UNLOCK(hpcd);
02063 
02064   return HAL_OK;
02065 }
02066 
02067 /**
02068   * @brief  Flush an endpoint
02069   * @param  hpcd PCD handle
02070   * @param  ep_addr endpoint address
02071   * @retval HAL status
02072   */
02073 HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
02074 {
02075   __HAL_LOCK(hpcd);
02076 
02077   if ((ep_addr & 0x80U) == 0x80U)
02078   {
02079     (void)USB_FlushTxFifo(hpcd->Instance, (uint32_t)ep_addr & 0xFU);
02080   }
02081   else
02082   {
02083     (void)USB_FlushRxFifo(hpcd->Instance);
02084   }
02085 
02086   __HAL_UNLOCK(hpcd);
02087 
02088   return HAL_OK;
02089 }
02090 
02091 /**
02092   * @brief  Activate remote wakeup signalling
02093   * @param  hpcd PCD handle
02094   * @retval HAL status
02095   */
02096 HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
02097 {
02098   return (USB_ActivateRemoteWakeup(hpcd->Instance));
02099 }
02100 
02101 /**
02102   * @brief  De-activate remote wakeup signalling.
02103   * @param  hpcd PCD handle
02104   * @retval HAL status
02105   */
02106 HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
02107 {
02108   return (USB_DeActivateRemoteWakeup(hpcd->Instance));
02109 }
02110 
02111 /**
02112   * @}
02113   */
02114 
02115 /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions
02116  *  @brief   Peripheral State functions
02117  *
02118 @verbatim
02119  ===============================================================================
02120                       ##### Peripheral State functions #####
02121  ===============================================================================
02122     [..]
02123     This subsection permits to get in run-time the status of the peripheral
02124     and the data flow.
02125 
02126 @endverbatim
02127   * @{
02128   */
02129 
02130 /**
02131   * @brief  Return the PCD handle state.
02132   * @param  hpcd PCD handle
02133   * @retval HAL state
02134   */
02135 PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd)
02136 {
02137   return hpcd->State;
02138 }
02139 
02140 /**
02141   * @}
02142   */
02143 
02144 /**
02145   * @}
02146   */
02147 
02148 /* Private functions ---------------------------------------------------------*/
02149 /** @addtogroup PCD_Private_Functions
02150   * @{
02151   */
02152 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
02153 /**
02154   * @brief  Check FIFO for the next packet to be loaded.
02155   * @param  hpcd PCD handle
02156   * @param  epnum endpoint number
02157   * @retval HAL status
02158   */
02159 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum)
02160 {
02161   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
02162   uint32_t USBx_BASE = (uint32_t)USBx;
02163   USB_OTG_EPTypeDef *ep;
02164   uint32_t len;
02165   uint32_t len32b;
02166   uint32_t fifoemptymsk;
02167 
02168   ep = &hpcd->IN_ep[epnum];
02169 
02170   if (ep->xfer_count > ep->xfer_len)
02171   {
02172     return HAL_ERROR;
02173   }
02174 
02175   len = ep->xfer_len - ep->xfer_count;
02176 
02177   if (len > ep->maxpacket)
02178   {
02179     len = ep->maxpacket;
02180   }
02181 
02182   len32b = (len + 3U) / 4U;
02183 
02184   while (((USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) > len32b) &&
02185          (ep->xfer_count < ep->xfer_len) && (ep->xfer_len != 0U))
02186   {
02187     /* Write the FIFO */
02188     len = ep->xfer_len - ep->xfer_count;
02189 
02190     if (len > ep->maxpacket)
02191     {
02192       len = ep->maxpacket;
02193     }
02194     len32b = (len + 3U) / 4U;
02195 
02196     (void)USB_WritePacket(USBx, ep->xfer_buff, (uint8_t)epnum, (uint16_t)len);
02197 
02198     ep->xfer_buff  += len;
02199     ep->xfer_count += len;
02200   }
02201 
02202   if (ep->xfer_len <= ep->xfer_count)
02203   {
02204     fifoemptymsk = (uint32_t)(0x1UL << epnum);
02205     USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
02206   }
02207 
02208   return HAL_OK;
02209 }
02210 #endif /* USB_OTG_FS || USB_OTG_HS */
02211 
02212 #if defined (USB)
02213 /**
02214   * @brief  This function handles PCD Endpoint interrupt request.
02215   * @param  hpcd PCD handle
02216   * @retval HAL status
02217   */
02218 static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
02219 {
02220   PCD_EPTypeDef *ep;
02221   uint16_t count;
02222   uint16_t wIstr;
02223   uint16_t wEPVal;
02224   uint8_t epindex;
02225 
02226   /* stay in loop while pending interrupts */
02227   while ((hpcd->Instance->ISTR & USB_ISTR_CTR) != 0U)
02228   {
02229     wIstr = hpcd->Instance->ISTR;
02230     /* extract highest priority endpoint number */
02231     epindex = (uint8_t)(wIstr & USB_ISTR_EP_ID);
02232 
02233     if (epindex == 0U)
02234     {
02235       /* Decode and service control endpoint interrupt */
02236 
02237       /* DIR bit = origin of the interrupt */
02238       if ((wIstr & USB_ISTR_DIR) == 0U)
02239       {
02240         /* DIR = 0 */
02241 
02242         /* DIR = 0      => IN  int */
02243         /* DIR = 0 implies that (EP_CTR_TX = 1) always  */
02244         PCD_CLEAR_TX_EP_CTR(hpcd->Instance, PCD_ENDP0);
02245         ep = &hpcd->IN_ep[0];
02246 
02247         ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
02248         ep->xfer_buff += ep->xfer_count;
02249 
02250         /* TX COMPLETE */
02251 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
02252         hpcd->DataInStageCallback(hpcd, 0U);
02253 #else
02254         HAL_PCD_DataInStageCallback(hpcd, 0U);
02255 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
02256 
02257         if ((hpcd->USB_Address > 0U) && (ep->xfer_len == 0U))
02258         {
02259           hpcd->Instance->DADDR = ((uint16_t)hpcd->USB_Address | USB_DADDR_EF);
02260           hpcd->USB_Address = 0U;
02261         }
02262       }
02263       else
02264       {
02265         /* DIR = 1 */
02266 
02267         /* DIR = 1 & CTR_RX       => SETUP or OUT int */
02268         /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */
02269         ep = &hpcd->OUT_ep[0];
02270         wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0);
02271 
02272         if ((wEPVal & USB_EP_SETUP) != 0U)
02273         {
02274           /* Get SETUP Packet*/
02275           ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
02276           USB_ReadPMA(hpcd->Instance, (uint8_t *)hpcd->Setup, ep->pmaadress, (uint16_t)ep->xfer_count);
02277           /* SETUP bit kept frozen while CTR_RX = 1*/
02278           PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
02279 
02280           /* Process SETUP Packet*/
02281 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
02282           hpcd->SetupStageCallback(hpcd);
02283 #else
02284           HAL_PCD_SetupStageCallback(hpcd);
02285 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
02286         }
02287 
02288         else if ((wEPVal & USB_EP_CTR_RX) != 0U)
02289         {
02290           PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
02291           /* Get Control Data OUT Packet*/
02292           ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
02293 
02294           if (ep->xfer_count != 0U)
02295           {
02296             USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, (uint16_t)ep->xfer_count);
02297             ep->xfer_buff += ep->xfer_count;
02298           }
02299 
02300           /* Process Control Data OUT Packet*/
02301 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
02302           hpcd->DataOutStageCallback(hpcd, 0U);
02303 #else
02304           HAL_PCD_DataOutStageCallback(hpcd, 0U);
02305 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
02306 
02307           PCD_SET_EP_RX_CNT(hpcd->Instance, PCD_ENDP0, ep->maxpacket);
02308           PCD_SET_EP_RX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_RX_VALID);
02309         }
02310       }
02311     }
02312     else
02313     {
02314       /* Decode and service non control endpoints interrupt  */
02315 
02316       /* process related endpoint register */
02317       wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, epindex);
02318       if ((wEPVal & USB_EP_CTR_RX) != 0U)
02319       {
02320         /* clear int flag */
02321         PCD_CLEAR_RX_EP_CTR(hpcd->Instance, epindex);
02322         ep = &hpcd->OUT_ep[epindex];
02323 
02324         /* OUT double Buffering*/
02325         if (ep->doublebuffer == 0U)
02326         {
02327           count = (uint16_t)PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
02328           if (count != 0U)
02329           {
02330             USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, count);
02331           }
02332         }
02333         else
02334         {
02335           if ((PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_RX) != 0U)
02336           {
02337             /*read from endpoint BUF0Addr buffer*/
02338             count = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
02339             if (count != 0U)
02340             {
02341               USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count);
02342             }
02343           }
02344           else
02345           {
02346             /*read from endpoint BUF1Addr buffer*/
02347             count = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
02348             if (count != 0U)
02349             {
02350               USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count);
02351             }
02352           }
02353           PCD_FreeUserBuffer(hpcd->Instance, ep->num, PCD_EP_DBUF_OUT);
02354         }
02355         /*multi-packet on the NON control OUT endpoint*/
02356         ep->xfer_count += count;
02357         ep->xfer_buff += count;
02358 
02359         if ((ep->xfer_len == 0U) || (count < ep->maxpacket))
02360         {
02361           /* RX COMPLETE */
02362 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
02363           hpcd->DataOutStageCallback(hpcd, ep->num);
02364 #else
02365           HAL_PCD_DataOutStageCallback(hpcd, ep->num);
02366 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
02367         }
02368         else
02369         {
02370           (void)HAL_PCD_EP_Receive(hpcd, ep->num, ep->xfer_buff, ep->xfer_len);
02371         }
02372 
02373       } /* if((wEPVal & EP_CTR_RX) */
02374 
02375       if ((wEPVal & USB_EP_CTR_TX) != 0U)
02376       {
02377         ep = &hpcd->IN_ep[epindex];
02378 
02379         /* clear int flag */
02380         PCD_CLEAR_TX_EP_CTR(hpcd->Instance, epindex);
02381 
02382         /*multi-packet on the NON control IN endpoint*/
02383         ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
02384         ep->xfer_buff += ep->xfer_count;
02385 
02386         /* Zero Length Packet? */
02387         if (ep->xfer_len == 0U)
02388         {
02389           /* TX COMPLETE */
02390 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
02391           hpcd->DataInStageCallback(hpcd, ep->num);
02392 #else
02393           HAL_PCD_DataInStageCallback(hpcd, ep->num);
02394 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
02395         }
02396         else
02397         {
02398           (void)HAL_PCD_EP_Transmit(hpcd, ep->num, ep->xfer_buff, ep->xfer_len);
02399         }
02400       }
02401     }
02402   }
02403   return HAL_OK;
02404 }
02405 #endif /* USB */
02406 
02407 /**
02408   * @}
02409   */
02410 
02411 #endif /* defined (USB) || defined (USB_OTG_FS) || defined (USB_OTG_HS) */
02412 
02413 #endif /* HAL_PCD_MODULE_ENABLED */
02414 
02415 /**
02416   * @}
02417   */
02418 
02419 /**
02420   * @}
02421   */
02422 
02423 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/