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