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