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