Subversion Repositories AFRtranscoder

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /**
  2.   ******************************************************************************
  3.   * @file    stm32f1xx_hal_pcd.c
  4.   * @author  MCD Application Team
  5.   * @brief   PCD HAL module driver.
  6.   *          This file provides firmware functions to manage the following
  7.   *          functionalities of the USB Peripheral Controller:
  8.   *           + Initialization and de-initialization functions
  9.   *           + IO operation functions
  10.   *           + Peripheral Control functions
  11.   *           + Peripheral State functions
  12.   *
  13.   ******************************************************************************
  14.   * @attention
  15.   *
  16.   * Copyright (c) 2016 STMicroelectronics.
  17.   * All rights reserved.
  18.   *
  19.   * This software is licensed under terms that can be found in the LICENSE file
  20.   * in the root directory of this software component.
  21.   * If no LICENSE file comes with this software, it is provided AS-IS.
  22.   *
  23.   ******************************************************************************
  24.   @verbatim
  25.   ==============================================================================
  26.                     ##### How to use this driver #####
  27.   ==============================================================================
  28.     [..]
  29.       The PCD HAL driver can be used as follows:
  30.  
  31.      (#) Declare a PCD_HandleTypeDef handle structure, for example:
  32.          PCD_HandleTypeDef  hpcd;
  33.  
  34.      (#) Fill parameters of Init structure in HCD handle
  35.  
  36.      (#) Call HAL_PCD_Init() API to initialize the PCD peripheral (Core, Device core, ...)
  37.  
  38.      (#) Initialize the PCD low level resources through the HAL_PCD_MspInit() API:
  39.          (##) Enable the PCD/USB Low Level interface clock using
  40.               (+++) __HAL_RCC_USB_CLK_ENABLE(); For USB Device FS peripheral
  41.               (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
  42.  
  43.          (##) Initialize the related GPIO clocks
  44.          (##) Configure PCD pin-out
  45.          (##) Configure PCD NVIC interrupt
  46.  
  47.      (#)Associate the Upper USB device stack to the HAL PCD Driver:
  48.          (##) hpcd.pData = pdev;
  49.  
  50.      (#)Enable PCD transmission and reception:
  51.          (##) HAL_PCD_Start();
  52.  
  53.   @endverbatim
  54.   ******************************************************************************
  55.   */
  56.  
  57. /* Includes ------------------------------------------------------------------*/
  58. #include "stm32f1xx_hal.h"
  59.  
  60. /** @addtogroup STM32F1xx_HAL_Driver
  61.   * @{
  62.   */
  63.  
  64. /** @defgroup PCD PCD
  65.   * @brief PCD HAL module driver
  66.   * @{
  67.   */
  68.  
  69. #ifdef HAL_PCD_MODULE_ENABLED
  70.  
  71. #if defined (USB) || defined (USB_OTG_FS)
  72.  
  73. /* Private types -------------------------------------------------------------*/
  74. /* Private variables ---------------------------------------------------------*/
  75. /* Private constants ---------------------------------------------------------*/
  76. /* Private macros ------------------------------------------------------------*/
  77. /** @defgroup PCD_Private_Macros PCD Private Macros
  78.   * @{
  79.   */
  80. #define PCD_MIN(a, b)  (((a) < (b)) ? (a) : (b))
  81. #define PCD_MAX(a, b)  (((a) > (b)) ? (a) : (b))
  82. /**
  83.   * @}
  84.   */
  85.  
  86. /* Private functions prototypes ----------------------------------------------*/
  87. /** @defgroup PCD_Private_Functions PCD Private Functions
  88.   * @{
  89.   */
  90. #if defined (USB_OTG_FS)
  91. static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum);
  92. static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef *hpcd, uint32_t epnum);
  93. static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef *hpcd, uint32_t epnum);
  94. #endif /* defined (USB_OTG_FS) */
  95.  
  96. #if defined (USB)
  97. static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd);
  98. #if (USE_USB_DOUBLE_BUFFER == 1U)
  99. static HAL_StatusTypeDef HAL_PCD_EP_DB_Transmit(PCD_HandleTypeDef *hpcd, PCD_EPTypeDef *ep, uint16_t wEPVal);
  100. static uint16_t HAL_PCD_EP_DB_Receive(PCD_HandleTypeDef *hpcd, PCD_EPTypeDef *ep, uint16_t wEPVal);
  101. #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
  102. #endif /* defined (USB) */
  103. /**
  104.   * @}
  105.   */
  106.  
  107. /* Exported functions --------------------------------------------------------*/
  108. /** @defgroup PCD_Exported_Functions PCD Exported Functions
  109.   * @{
  110.   */
  111.  
  112. /** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
  113.   *  @brief    Initialization and Configuration functions
  114.   *
  115. @verbatim
  116.  ===============================================================================
  117.             ##### Initialization and de-initialization functions #####
  118.  ===============================================================================
  119.     [..]  This section provides functions allowing to:
  120.  
  121. @endverbatim
  122.   * @{
  123.   */
  124.  
  125. /**
  126.   * @brief  Initializes the PCD according to the specified
  127.   *         parameters in the PCD_InitTypeDef and initialize the associated handle.
  128.   * @param  hpcd PCD handle
  129.   * @retval HAL status
  130.   */
  131. HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd)
  132. {
  133. #if defined (USB_OTG_FS)
  134.   USB_OTG_GlobalTypeDef *USBx;
  135. #endif /* defined (USB_OTG_FS) */
  136.   uint8_t i;
  137.  
  138.   /* Check the PCD handle allocation */
  139.   if (hpcd == NULL)
  140.   {
  141.     return HAL_ERROR;
  142.   }
  143.  
  144.   /* Check the parameters */
  145.   assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance));
  146.  
  147. #if defined (USB_OTG_FS)
  148.   USBx = hpcd->Instance;
  149. #endif /* defined (USB_OTG_FS) */
  150.  
  151.   if (hpcd->State == HAL_PCD_STATE_RESET)
  152.   {
  153.     /* Allocate lock resource and initialize it */
  154.     hpcd->Lock = HAL_UNLOCKED;
  155.  
  156. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  157.     hpcd->SOFCallback = HAL_PCD_SOFCallback;
  158.     hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
  159.     hpcd->ResetCallback = HAL_PCD_ResetCallback;
  160.     hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
  161.     hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
  162.     hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
  163.     hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
  164.     hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback;
  165.     hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback;
  166.     hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback;
  167.     hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback;
  168.  
  169.     if (hpcd->MspInitCallback == NULL)
  170.     {
  171.       hpcd->MspInitCallback = HAL_PCD_MspInit;
  172.     }
  173.  
  174.     /* Init the low level hardware */
  175.     hpcd->MspInitCallback(hpcd);
  176. #else
  177.     /* Init the low level hardware : GPIO, CLOCK, NVIC... */
  178.     HAL_PCD_MspInit(hpcd);
  179. #endif /* (USE_HAL_PCD_REGISTER_CALLBACKS) */
  180.   }
  181.  
  182.   hpcd->State = HAL_PCD_STATE_BUSY;
  183.  
  184. #if defined (USB_OTG_FS)
  185.   /* Disable DMA mode for FS instance */
  186.   if ((USBx->CID & (0x1U << 8)) == 0U)
  187.   {
  188.     hpcd->Init.dma_enable = 0U;
  189.   }
  190. #endif /* defined (USB_OTG_FS) */
  191.  
  192.   /* Disable the Interrupts */
  193.   __HAL_PCD_DISABLE(hpcd);
  194.  
  195.   /*Init the Core (common init.) */
  196.   if (USB_CoreInit(hpcd->Instance, hpcd->Init) != HAL_OK)
  197.   {
  198.     hpcd->State = HAL_PCD_STATE_ERROR;
  199.     return HAL_ERROR;
  200.   }
  201.  
  202.   /* Force Device Mode*/
  203.   (void)USB_SetCurrentMode(hpcd->Instance, USB_DEVICE_MODE);
  204.  
  205.   /* Init endpoints structures */
  206.   for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
  207.   {
  208.     /* Init ep structure */
  209.     hpcd->IN_ep[i].is_in = 1U;
  210.     hpcd->IN_ep[i].num = i;
  211. #if defined (USB_OTG_FS)
  212.     hpcd->IN_ep[i].tx_fifo_num = i;
  213. #endif /* defined (USB_OTG_FS) */
  214.     /* Control until ep is activated */
  215.     hpcd->IN_ep[i].type = EP_TYPE_CTRL;
  216.     hpcd->IN_ep[i].maxpacket = 0U;
  217.     hpcd->IN_ep[i].xfer_buff = 0U;
  218.     hpcd->IN_ep[i].xfer_len = 0U;
  219.   }
  220.  
  221.   for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
  222.   {
  223.     hpcd->OUT_ep[i].is_in = 0U;
  224.     hpcd->OUT_ep[i].num = i;
  225.     /* Control until ep is activated */
  226.     hpcd->OUT_ep[i].type = EP_TYPE_CTRL;
  227.     hpcd->OUT_ep[i].maxpacket = 0U;
  228.     hpcd->OUT_ep[i].xfer_buff = 0U;
  229.     hpcd->OUT_ep[i].xfer_len = 0U;
  230.   }
  231.  
  232.   /* Init Device */
  233.   if (USB_DevInit(hpcd->Instance, hpcd->Init) != HAL_OK)
  234.   {
  235.     hpcd->State = HAL_PCD_STATE_ERROR;
  236.     return HAL_ERROR;
  237.   }
  238.  
  239.   hpcd->USB_Address = 0U;
  240.   hpcd->State = HAL_PCD_STATE_READY;
  241.   (void)USB_DevDisconnect(hpcd->Instance);
  242.  
  243.   return HAL_OK;
  244. }
  245.  
  246. /**
  247.   * @brief  DeInitializes the PCD peripheral.
  248.   * @param  hpcd PCD handle
  249.   * @retval HAL status
  250.   */
  251. HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
  252. {
  253.   /* Check the PCD handle allocation */
  254.   if (hpcd == NULL)
  255.   {
  256.     return HAL_ERROR;
  257.   }
  258.  
  259.   hpcd->State = HAL_PCD_STATE_BUSY;
  260.  
  261.   /* Stop Device */
  262.   if (USB_StopDevice(hpcd->Instance) != HAL_OK)
  263.   {
  264.     return HAL_ERROR;
  265.   }
  266.  
  267. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  268.   if (hpcd->MspDeInitCallback == NULL)
  269.   {
  270.     hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; /* Legacy weak MspDeInit  */
  271.   }
  272.  
  273.   /* DeInit the low level hardware */
  274.   hpcd->MspDeInitCallback(hpcd);
  275. #else
  276.   /* DeInit the low level hardware: CLOCK, NVIC.*/
  277.   HAL_PCD_MspDeInit(hpcd);
  278. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  279.  
  280.   hpcd->State = HAL_PCD_STATE_RESET;
  281.  
  282.   return HAL_OK;
  283. }
  284.  
  285. /**
  286.   * @brief  Initializes the PCD MSP.
  287.   * @param  hpcd PCD handle
  288.   * @retval None
  289.   */
  290. __weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
  291. {
  292.   /* Prevent unused argument(s) compilation warning */
  293.   UNUSED(hpcd);
  294.  
  295.   /* NOTE : This function should not be modified, when the callback is needed,
  296.             the HAL_PCD_MspInit could be implemented in the user file
  297.    */
  298. }
  299.  
  300. /**
  301.   * @brief  DeInitializes PCD MSP.
  302.   * @param  hpcd PCD handle
  303.   * @retval None
  304.   */
  305. __weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
  306. {
  307.   /* Prevent unused argument(s) compilation warning */
  308.   UNUSED(hpcd);
  309.  
  310.   /* NOTE : This function should not be modified, when the callback is needed,
  311.             the HAL_PCD_MspDeInit could be implemented in the user file
  312.    */
  313. }
  314.  
  315. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  316. /**
  317.   * @brief  Register a User USB PCD Callback
  318.   *         To be used instead of the weak predefined callback
  319.   * @param  hpcd USB PCD handle
  320.   * @param  CallbackID ID of the callback to be registered
  321.   *         This parameter can be one of the following values:
  322.   *          @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
  323.   *          @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
  324.   *          @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
  325.   *          @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
  326.   *          @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
  327.   *          @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
  328.   *          @arg @ref HAL_PCD_DISCONNECT_CB_ID USB PCD Disconnect callback ID
  329.   *          @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
  330.   *          @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
  331.   * @param  pCallback pointer to the Callback function
  332.   * @retval HAL status
  333.   */
  334. HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd,
  335.                                            HAL_PCD_CallbackIDTypeDef CallbackID,
  336.                                            pPCD_CallbackTypeDef pCallback)
  337. {
  338.   HAL_StatusTypeDef status = HAL_OK;
  339.  
  340.   if (pCallback == NULL)
  341.   {
  342.     /* Update the error code */
  343.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  344.     return HAL_ERROR;
  345.   }
  346.   /* Process locked */
  347.   __HAL_LOCK(hpcd);
  348.  
  349.   if (hpcd->State == HAL_PCD_STATE_READY)
  350.   {
  351.     switch (CallbackID)
  352.     {
  353.       case HAL_PCD_SOF_CB_ID :
  354.         hpcd->SOFCallback = pCallback;
  355.         break;
  356.  
  357.       case HAL_PCD_SETUPSTAGE_CB_ID :
  358.         hpcd->SetupStageCallback = pCallback;
  359.         break;
  360.  
  361.       case HAL_PCD_RESET_CB_ID :
  362.         hpcd->ResetCallback = pCallback;
  363.         break;
  364.  
  365.       case HAL_PCD_SUSPEND_CB_ID :
  366.         hpcd->SuspendCallback = pCallback;
  367.         break;
  368.  
  369.       case HAL_PCD_RESUME_CB_ID :
  370.         hpcd->ResumeCallback = pCallback;
  371.         break;
  372.  
  373.       case HAL_PCD_CONNECT_CB_ID :
  374.         hpcd->ConnectCallback = pCallback;
  375.         break;
  376.  
  377.       case HAL_PCD_DISCONNECT_CB_ID :
  378.         hpcd->DisconnectCallback = pCallback;
  379.         break;
  380.  
  381.       case HAL_PCD_MSPINIT_CB_ID :
  382.         hpcd->MspInitCallback = pCallback;
  383.         break;
  384.  
  385.       case HAL_PCD_MSPDEINIT_CB_ID :
  386.         hpcd->MspDeInitCallback = pCallback;
  387.         break;
  388.  
  389.       default :
  390.         /* Update the error code */
  391.         hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  392.         /* Return error status */
  393.         status =  HAL_ERROR;
  394.         break;
  395.     }
  396.   }
  397.   else if (hpcd->State == HAL_PCD_STATE_RESET)
  398.   {
  399.     switch (CallbackID)
  400.     {
  401.       case HAL_PCD_MSPINIT_CB_ID :
  402.         hpcd->MspInitCallback = pCallback;
  403.         break;
  404.  
  405.       case HAL_PCD_MSPDEINIT_CB_ID :
  406.         hpcd->MspDeInitCallback = pCallback;
  407.         break;
  408.  
  409.       default :
  410.         /* Update the error code */
  411.         hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  412.         /* Return error status */
  413.         status =  HAL_ERROR;
  414.         break;
  415.     }
  416.   }
  417.   else
  418.   {
  419.     /* Update the error code */
  420.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  421.     /* Return error status */
  422.     status =  HAL_ERROR;
  423.   }
  424.  
  425.   /* Release Lock */
  426.   __HAL_UNLOCK(hpcd);
  427.   return status;
  428. }
  429.  
  430. /**
  431.   * @brief  Unregister an USB PCD Callback
  432.   *         USB PCD callback is redirected to the weak predefined callback
  433.   * @param  hpcd USB PCD handle
  434.   * @param  CallbackID ID of the callback to be unregistered
  435.   *         This parameter can be one of the following values:
  436.   *          @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
  437.   *          @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
  438.   *          @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
  439.   *          @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
  440.   *          @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
  441.   *          @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
  442.   *          @arg @ref HAL_PCD_DISCONNECT_CB_ID USB PCD Disconnect callback ID
  443.   *          @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
  444.   *          @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
  445.   * @retval HAL status
  446.   */
  447. HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID)
  448. {
  449.   HAL_StatusTypeDef status = HAL_OK;
  450.  
  451.   /* Process locked */
  452.   __HAL_LOCK(hpcd);
  453.  
  454.   /* Setup Legacy weak Callbacks  */
  455.   if (hpcd->State == HAL_PCD_STATE_READY)
  456.   {
  457.     switch (CallbackID)
  458.     {
  459.       case HAL_PCD_SOF_CB_ID :
  460.         hpcd->SOFCallback = HAL_PCD_SOFCallback;
  461.         break;
  462.  
  463.       case HAL_PCD_SETUPSTAGE_CB_ID :
  464.         hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
  465.         break;
  466.  
  467.       case HAL_PCD_RESET_CB_ID :
  468.         hpcd->ResetCallback = HAL_PCD_ResetCallback;
  469.         break;
  470.  
  471.       case HAL_PCD_SUSPEND_CB_ID :
  472.         hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
  473.         break;
  474.  
  475.       case HAL_PCD_RESUME_CB_ID :
  476.         hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
  477.         break;
  478.  
  479.       case HAL_PCD_CONNECT_CB_ID :
  480.         hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
  481.         break;
  482.  
  483.       case HAL_PCD_DISCONNECT_CB_ID :
  484.         hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
  485.         break;
  486.  
  487.       case HAL_PCD_MSPINIT_CB_ID :
  488.         hpcd->MspInitCallback = HAL_PCD_MspInit;
  489.         break;
  490.  
  491.       case HAL_PCD_MSPDEINIT_CB_ID :
  492.         hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
  493.         break;
  494.  
  495.       default :
  496.         /* Update the error code */
  497.         hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  498.  
  499.         /* Return error status */
  500.         status =  HAL_ERROR;
  501.         break;
  502.     }
  503.   }
  504.   else if (hpcd->State == HAL_PCD_STATE_RESET)
  505.   {
  506.     switch (CallbackID)
  507.     {
  508.       case HAL_PCD_MSPINIT_CB_ID :
  509.         hpcd->MspInitCallback = HAL_PCD_MspInit;
  510.         break;
  511.  
  512.       case HAL_PCD_MSPDEINIT_CB_ID :
  513.         hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
  514.         break;
  515.  
  516.       default :
  517.         /* Update the error code */
  518.         hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  519.  
  520.         /* Return error status */
  521.         status =  HAL_ERROR;
  522.         break;
  523.     }
  524.   }
  525.   else
  526.   {
  527.     /* Update the error code */
  528.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  529.  
  530.     /* Return error status */
  531.     status =  HAL_ERROR;
  532.   }
  533.  
  534.   /* Release Lock */
  535.   __HAL_UNLOCK(hpcd);
  536.   return status;
  537. }
  538.  
  539. /**
  540.   * @brief  Register USB PCD Data OUT Stage Callback
  541.   *         To be used instead of the weak HAL_PCD_DataOutStageCallback() predefined callback
  542.   * @param  hpcd PCD handle
  543.   * @param  pCallback pointer to the USB PCD Data OUT Stage Callback function
  544.   * @retval HAL status
  545.   */
  546. HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd,
  547.                                                        pPCD_DataOutStageCallbackTypeDef pCallback)
  548. {
  549.   HAL_StatusTypeDef status = HAL_OK;
  550.  
  551.   if (pCallback == NULL)
  552.   {
  553.     /* Update the error code */
  554.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  555.  
  556.     return HAL_ERROR;
  557.   }
  558.  
  559.   /* Process locked */
  560.   __HAL_LOCK(hpcd);
  561.  
  562.   if (hpcd->State == HAL_PCD_STATE_READY)
  563.   {
  564.     hpcd->DataOutStageCallback = pCallback;
  565.   }
  566.   else
  567.   {
  568.     /* Update the error code */
  569.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  570.  
  571.     /* Return error status */
  572.     status =  HAL_ERROR;
  573.   }
  574.  
  575.   /* Release Lock */
  576.   __HAL_UNLOCK(hpcd);
  577.  
  578.   return status;
  579. }
  580.  
  581. /**
  582.   * @brief  Unregister the USB PCD Data OUT Stage Callback
  583.   *         USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataOutStageCallback() predefined callback
  584.   * @param  hpcd PCD handle
  585.   * @retval HAL status
  586.   */
  587. HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd)
  588. {
  589.   HAL_StatusTypeDef status = HAL_OK;
  590.  
  591.   /* Process locked */
  592.   __HAL_LOCK(hpcd);
  593.  
  594.   if (hpcd->State == HAL_PCD_STATE_READY)
  595.   {
  596.     hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback; /* Legacy weak DataOutStageCallback  */
  597.   }
  598.   else
  599.   {
  600.     /* Update the error code */
  601.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  602.  
  603.     /* Return error status */
  604.     status =  HAL_ERROR;
  605.   }
  606.  
  607.   /* Release Lock */
  608.   __HAL_UNLOCK(hpcd);
  609.  
  610.   return status;
  611. }
  612.  
  613. /**
  614.   * @brief  Register USB PCD Data IN Stage Callback
  615.   *         To be used instead of the weak HAL_PCD_DataInStageCallback() predefined callback
  616.   * @param  hpcd PCD handle
  617.   * @param  pCallback pointer to the USB PCD Data IN Stage Callback function
  618.   * @retval HAL status
  619.   */
  620. HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd,
  621.                                                       pPCD_DataInStageCallbackTypeDef pCallback)
  622. {
  623.   HAL_StatusTypeDef status = HAL_OK;
  624.  
  625.   if (pCallback == NULL)
  626.   {
  627.     /* Update the error code */
  628.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  629.  
  630.     return HAL_ERROR;
  631.   }
  632.  
  633.   /* Process locked */
  634.   __HAL_LOCK(hpcd);
  635.  
  636.   if (hpcd->State == HAL_PCD_STATE_READY)
  637.   {
  638.     hpcd->DataInStageCallback = pCallback;
  639.   }
  640.   else
  641.   {
  642.     /* Update the error code */
  643.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  644.  
  645.     /* Return error status */
  646.     status =  HAL_ERROR;
  647.   }
  648.  
  649.   /* Release Lock */
  650.   __HAL_UNLOCK(hpcd);
  651.  
  652.   return status;
  653. }
  654.  
  655. /**
  656.   * @brief  Unregister the USB PCD Data IN Stage Callback
  657.   *         USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataInStageCallback() predefined callback
  658.   * @param  hpcd PCD handle
  659.   * @retval HAL status
  660.   */
  661. HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd)
  662. {
  663.   HAL_StatusTypeDef status = HAL_OK;
  664.  
  665.   /* Process locked */
  666.   __HAL_LOCK(hpcd);
  667.  
  668.   if (hpcd->State == HAL_PCD_STATE_READY)
  669.   {
  670.     hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback; /* Legacy weak DataInStageCallback  */
  671.   }
  672.   else
  673.   {
  674.     /* Update the error code */
  675.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  676.  
  677.     /* Return error status */
  678.     status =  HAL_ERROR;
  679.   }
  680.  
  681.   /* Release Lock */
  682.   __HAL_UNLOCK(hpcd);
  683.  
  684.   return status;
  685. }
  686.  
  687. /**
  688.   * @brief  Register USB PCD Iso OUT incomplete Callback
  689.   *         To be used instead of the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
  690.   * @param  hpcd PCD handle
  691.   * @param  pCallback pointer to the USB PCD Iso OUT incomplete Callback function
  692.   * @retval HAL status
  693.   */
  694. HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd,
  695.                                                        pPCD_IsoOutIncpltCallbackTypeDef pCallback)
  696. {
  697.   HAL_StatusTypeDef status = HAL_OK;
  698.  
  699.   if (pCallback == NULL)
  700.   {
  701.     /* Update the error code */
  702.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  703.  
  704.     return HAL_ERROR;
  705.   }
  706.  
  707.   /* Process locked */
  708.   __HAL_LOCK(hpcd);
  709.  
  710.   if (hpcd->State == HAL_PCD_STATE_READY)
  711.   {
  712.     hpcd->ISOOUTIncompleteCallback = pCallback;
  713.   }
  714.   else
  715.   {
  716.     /* Update the error code */
  717.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  718.  
  719.     /* Return error status */
  720.     status =  HAL_ERROR;
  721.   }
  722.  
  723.   /* Release Lock */
  724.   __HAL_UNLOCK(hpcd);
  725.  
  726.   return status;
  727. }
  728.  
  729. /**
  730.   * @brief  Unregister the USB PCD Iso OUT incomplete Callback
  731.   *         USB PCD Iso OUT incomplete Callback is redirected
  732.   *         to the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
  733.   * @param  hpcd PCD handle
  734.   * @retval HAL status
  735.   */
  736. HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd)
  737. {
  738.   HAL_StatusTypeDef status = HAL_OK;
  739.  
  740.   /* Process locked */
  741.   __HAL_LOCK(hpcd);
  742.  
  743.   if (hpcd->State == HAL_PCD_STATE_READY)
  744.   {
  745.     hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback; /* Legacy weak ISOOUTIncompleteCallback  */
  746.   }
  747.   else
  748.   {
  749.     /* Update the error code */
  750.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  751.  
  752.     /* Return error status */
  753.     status =  HAL_ERROR;
  754.   }
  755.  
  756.   /* Release Lock */
  757.   __HAL_UNLOCK(hpcd);
  758.  
  759.   return status;
  760. }
  761.  
  762. /**
  763.   * @brief  Register USB PCD Iso IN incomplete Callback
  764.   *         To be used instead of the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
  765.   * @param  hpcd PCD handle
  766.   * @param  pCallback pointer to the USB PCD Iso IN incomplete Callback function
  767.   * @retval HAL status
  768.   */
  769. HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd,
  770.                                                       pPCD_IsoInIncpltCallbackTypeDef pCallback)
  771. {
  772.   HAL_StatusTypeDef status = HAL_OK;
  773.  
  774.   if (pCallback == NULL)
  775.   {
  776.     /* Update the error code */
  777.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  778.  
  779.     return HAL_ERROR;
  780.   }
  781.  
  782.   /* Process locked */
  783.   __HAL_LOCK(hpcd);
  784.  
  785.   if (hpcd->State == HAL_PCD_STATE_READY)
  786.   {
  787.     hpcd->ISOINIncompleteCallback = pCallback;
  788.   }
  789.   else
  790.   {
  791.     /* Update the error code */
  792.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  793.  
  794.     /* Return error status */
  795.     status =  HAL_ERROR;
  796.   }
  797.  
  798.   /* Release Lock */
  799.   __HAL_UNLOCK(hpcd);
  800.  
  801.   return status;
  802. }
  803.  
  804. /**
  805.   * @brief  Unregister the USB PCD Iso IN incomplete Callback
  806.   *         USB PCD Iso IN incomplete Callback is redirected
  807.   *         to the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
  808.   * @param  hpcd PCD handle
  809.   * @retval HAL status
  810.   */
  811. HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd)
  812. {
  813.   HAL_StatusTypeDef status = HAL_OK;
  814.  
  815.   /* Process locked */
  816.   __HAL_LOCK(hpcd);
  817.  
  818.   if (hpcd->State == HAL_PCD_STATE_READY)
  819.   {
  820.     hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback; /* Legacy weak ISOINIncompleteCallback  */
  821.   }
  822.   else
  823.   {
  824.     /* Update the error code */
  825.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  826.  
  827.     /* Return error status */
  828.     status =  HAL_ERROR;
  829.   }
  830.  
  831.   /* Release Lock */
  832.   __HAL_UNLOCK(hpcd);
  833.  
  834.   return status;
  835. }
  836.  
  837. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  838.  
  839. /**
  840.   * @}
  841.   */
  842.  
  843. /** @defgroup PCD_Exported_Functions_Group2 Input and Output operation functions
  844.   *  @brief   Data transfers functions
  845.   *
  846. @verbatim
  847.  ===============================================================================
  848.                       ##### IO operation functions #####
  849.  ===============================================================================
  850.     [..]
  851.     This subsection provides a set of functions allowing to manage the PCD data
  852.     transfers.
  853.  
  854. @endverbatim
  855.   * @{
  856.   */
  857.  
  858. /**
  859.   * @brief  Start the USB device
  860.   * @param  hpcd PCD handle
  861.   * @retval HAL status
  862.   */
  863. HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)
  864. {
  865.   __HAL_LOCK(hpcd);
  866.   __HAL_PCD_ENABLE(hpcd);
  867.  
  868. #if defined (USB)
  869.   HAL_PCDEx_SetConnectionState(hpcd, 1U);
  870. #endif /* defined (USB) */
  871.  
  872.   (void)USB_DevConnect(hpcd->Instance);
  873.   __HAL_UNLOCK(hpcd);
  874.  
  875.   return HAL_OK;
  876. }
  877.  
  878. /**
  879.   * @brief  Stop the USB device.
  880.   * @param  hpcd PCD handle
  881.   * @retval HAL status
  882.   */
  883. HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
  884. {
  885.   __HAL_LOCK(hpcd);
  886.   __HAL_PCD_DISABLE(hpcd);
  887.  
  888. #if defined (USB)
  889.   HAL_PCDEx_SetConnectionState(hpcd, 0U);
  890. #endif /* defined (USB) */
  891.  
  892.   (void)USB_DevDisconnect(hpcd->Instance);
  893.  
  894. #if defined (USB_OTG_FS)
  895.   (void)USB_FlushTxFifo(hpcd->Instance, 0x10U);
  896. #endif /* defined (USB_OTG_FS) */
  897.  
  898.   __HAL_UNLOCK(hpcd);
  899.  
  900.   return HAL_OK;
  901. }
  902.  
  903. #if defined (USB_OTG_FS)
  904. /**
  905.   * @brief  Handles PCD interrupt request.
  906.   * @param  hpcd PCD handle
  907.   * @retval HAL status
  908.   */
  909. void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
  910. {
  911.   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
  912.   uint32_t USBx_BASE = (uint32_t)USBx;
  913.   USB_OTG_EPTypeDef *ep;
  914.   uint32_t i;
  915.   uint32_t ep_intr;
  916.   uint32_t epint;
  917.   uint32_t epnum;
  918.   uint32_t fifoemptymsk;
  919.   uint32_t RegVal;
  920.  
  921.   /* ensure that we are in device mode */
  922.   if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE)
  923.   {
  924.     /* avoid spurious interrupt */
  925.     if (__HAL_PCD_IS_INVALID_INTERRUPT(hpcd))
  926.     {
  927.       return;
  928.     }
  929.  
  930.     /* store current frame number */
  931.     hpcd->FrameNumber = (USBx_DEVICE->DSTS & USB_OTG_DSTS_FNSOF_Msk) >> USB_OTG_DSTS_FNSOF_Pos;
  932.  
  933.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS))
  934.     {
  935.       /* incorrect mode, acknowledge the interrupt */
  936.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS);
  937.     }
  938.  
  939.     /* Handle RxQLevel Interrupt */
  940.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL))
  941.     {
  942.       USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
  943.  
  944.       RegVal = USBx->GRXSTSP;
  945.  
  946.       ep = &hpcd->OUT_ep[RegVal & USB_OTG_GRXSTSP_EPNUM];
  947.  
  948.       if (((RegVal & USB_OTG_GRXSTSP_PKTSTS) >> 17) ==  STS_DATA_UPDT)
  949.       {
  950.         if ((RegVal & USB_OTG_GRXSTSP_BCNT) != 0U)
  951.         {
  952.           (void)USB_ReadPacket(USBx, ep->xfer_buff,
  953.                                (uint16_t)((RegVal & USB_OTG_GRXSTSP_BCNT) >> 4));
  954.  
  955.           ep->xfer_buff += (RegVal & USB_OTG_GRXSTSP_BCNT) >> 4;
  956.           ep->xfer_count += (RegVal & USB_OTG_GRXSTSP_BCNT) >> 4;
  957.         }
  958.       }
  959.       else if (((RegVal & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_SETUP_UPDT)
  960.       {
  961.         (void)USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8U);
  962.         ep->xfer_count += (RegVal & USB_OTG_GRXSTSP_BCNT) >> 4;
  963.       }
  964.       else
  965.       {
  966.         /* ... */
  967.       }
  968.  
  969.       USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
  970.     }
  971.  
  972.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT))
  973.     {
  974.       epnum = 0U;
  975.  
  976.       /* Read in the device interrupt bits */
  977.       ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance);
  978.  
  979.       while (ep_intr != 0U)
  980.       {
  981.         if ((ep_intr & 0x1U) != 0U)
  982.         {
  983.           epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, (uint8_t)epnum);
  984.  
  985.           if ((epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC)
  986.           {
  987.             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC);
  988.             (void)PCD_EP_OutXfrComplete_int(hpcd, epnum);
  989.           }
  990.  
  991.           if ((epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP)
  992.           {
  993.             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP);
  994.             /* Class B setup phase done for previous decoded setup */
  995.             (void)PCD_EP_OutSetupPacket_int(hpcd, epnum);
  996.           }
  997.  
  998.           if ((epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS)
  999.           {
  1000.             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS);
  1001.           }
  1002.  
  1003.           /* Clear OUT Endpoint disable interrupt */
  1004.           if ((epint & USB_OTG_DOEPINT_EPDISD) == USB_OTG_DOEPINT_EPDISD)
  1005.           {
  1006.             if ((USBx->GINTSTS & USB_OTG_GINTSTS_BOUTNAKEFF) == USB_OTG_GINTSTS_BOUTNAKEFF)
  1007.             {
  1008.               USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGONAK;
  1009.             }
  1010.  
  1011.             ep = &hpcd->OUT_ep[epnum];
  1012.  
  1013.             if (ep->is_iso_incomplete == 1U)
  1014.             {
  1015.               ep->is_iso_incomplete = 0U;
  1016.  
  1017. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1018.               hpcd->ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum);
  1019. #else
  1020.               HAL_PCD_ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum);
  1021. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1022.             }
  1023.  
  1024.             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_EPDISD);
  1025.           }
  1026.  
  1027.           /* Clear Status Phase Received interrupt */
  1028.           if ((epint & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR)
  1029.           {
  1030.             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
  1031.           }
  1032.  
  1033.           /* Clear OUT NAK interrupt */
  1034.           if ((epint & USB_OTG_DOEPINT_NAK) == USB_OTG_DOEPINT_NAK)
  1035.           {
  1036.             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_NAK);
  1037.           }
  1038.         }
  1039.         epnum++;
  1040.         ep_intr >>= 1U;
  1041.       }
  1042.     }
  1043.  
  1044.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT))
  1045.     {
  1046.       /* Read in the device interrupt bits */
  1047.       ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance);
  1048.  
  1049.       epnum = 0U;
  1050.  
  1051.       while (ep_intr != 0U)
  1052.       {
  1053.         if ((ep_intr & 0x1U) != 0U) /* In ITR */
  1054.         {
  1055.           epint = USB_ReadDevInEPInterrupt(hpcd->Instance, (uint8_t)epnum);
  1056.  
  1057.           if ((epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC)
  1058.           {
  1059.             fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK));
  1060.             USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
  1061.  
  1062.             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC);
  1063.  
  1064. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1065.             hpcd->DataInStageCallback(hpcd, (uint8_t)epnum);
  1066. #else
  1067.             HAL_PCD_DataInStageCallback(hpcd, (uint8_t)epnum);
  1068. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1069.           }
  1070.           if ((epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC)
  1071.           {
  1072.             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC);
  1073.           }
  1074.           if ((epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE)
  1075.           {
  1076.             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE);
  1077.           }
  1078.           if ((epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE)
  1079.           {
  1080.             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE);
  1081.           }
  1082.           if ((epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD)
  1083.           {
  1084.             (void)USB_FlushTxFifo(USBx, epnum);
  1085.  
  1086.             ep = &hpcd->IN_ep[epnum];
  1087.  
  1088.             if (ep->is_iso_incomplete == 1U)
  1089.             {
  1090.               ep->is_iso_incomplete = 0U;
  1091.  
  1092. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1093.               hpcd->ISOINIncompleteCallback(hpcd, (uint8_t)epnum);
  1094. #else
  1095.               HAL_PCD_ISOINIncompleteCallback(hpcd, (uint8_t)epnum);
  1096. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1097.             }
  1098.  
  1099.             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD);
  1100.           }
  1101.           if ((epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE)
  1102.           {
  1103.             (void)PCD_WriteEmptyTxFifo(hpcd, epnum);
  1104.           }
  1105.         }
  1106.         epnum++;
  1107.         ep_intr >>= 1U;
  1108.       }
  1109.     }
  1110.  
  1111.     /* Handle Resume Interrupt */
  1112.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT))
  1113.     {
  1114.       /* Clear the Remote Wake-up Signaling */
  1115.       USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
  1116.  
  1117. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1118.       hpcd->ResumeCallback(hpcd);
  1119. #else
  1120.       HAL_PCD_ResumeCallback(hpcd);
  1121. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1122.  
  1123.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT);
  1124.     }
  1125.  
  1126.     /* Handle Suspend Interrupt */
  1127.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP))
  1128.     {
  1129.       if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
  1130.       {
  1131. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1132.         hpcd->SuspendCallback(hpcd);
  1133. #else
  1134.         HAL_PCD_SuspendCallback(hpcd);
  1135. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1136.       }
  1137.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP);
  1138.     }
  1139.     /* Handle Reset Interrupt */
  1140.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST))
  1141.     {
  1142.       USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
  1143.       (void)USB_FlushTxFifo(hpcd->Instance, 0x10U);
  1144.  
  1145.       for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
  1146.       {
  1147.         USBx_INEP(i)->DIEPINT = 0xFB7FU;
  1148.         USBx_INEP(i)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
  1149.         USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
  1150.         USBx_OUTEP(i)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
  1151.         USBx_OUTEP(i)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
  1152.       }
  1153.       USBx_DEVICE->DAINTMSK |= 0x10001U;
  1154.  
  1155.       if (hpcd->Init.use_dedicated_ep1 != 0U)
  1156.       {
  1157.         USBx_DEVICE->DOUTEP1MSK |= USB_OTG_DOEPMSK_STUPM |
  1158.                                    USB_OTG_DOEPMSK_XFRCM |
  1159.                                    USB_OTG_DOEPMSK_EPDM;
  1160.  
  1161.         USBx_DEVICE->DINEP1MSK |= USB_OTG_DIEPMSK_TOM |
  1162.                                   USB_OTG_DIEPMSK_XFRCM |
  1163.                                   USB_OTG_DIEPMSK_EPDM;
  1164.       }
  1165.       else
  1166.       {
  1167.         USBx_DEVICE->DOEPMSK |= USB_OTG_DOEPMSK_STUPM |
  1168.                                 USB_OTG_DOEPMSK_XFRCM |
  1169.                                 USB_OTG_DOEPMSK_EPDM |
  1170.                                 USB_OTG_DOEPMSK_OTEPSPRM |
  1171.                                 USB_OTG_DOEPMSK_NAKM;
  1172.  
  1173.         USBx_DEVICE->DIEPMSK |= USB_OTG_DIEPMSK_TOM |
  1174.                                 USB_OTG_DIEPMSK_XFRCM |
  1175.                                 USB_OTG_DIEPMSK_EPDM;
  1176.       }
  1177.  
  1178.       /* Set Default Address to 0 */
  1179.       USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD;
  1180.  
  1181.       /* setup EP0 to receive SETUP packets */
  1182.       (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
  1183.  
  1184.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST);
  1185.     }
  1186.  
  1187.     /* Handle Enumeration done Interrupt */
  1188.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE))
  1189.     {
  1190.       (void)USB_ActivateSetup(hpcd->Instance);
  1191.       hpcd->Init.speed = USB_GetDevSpeed(hpcd->Instance);
  1192.  
  1193.       /* Set USB Turnaround time */
  1194.       (void)USB_SetTurnaroundTime(hpcd->Instance,
  1195.                                   HAL_RCC_GetHCLKFreq(),
  1196.                                   (uint8_t)hpcd->Init.speed);
  1197.  
  1198. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1199.       hpcd->ResetCallback(hpcd);
  1200. #else
  1201.       HAL_PCD_ResetCallback(hpcd);
  1202. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1203.  
  1204.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE);
  1205.     }
  1206.  
  1207.     /* Handle SOF Interrupt */
  1208.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF))
  1209.     {
  1210. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1211.       hpcd->SOFCallback(hpcd);
  1212. #else
  1213.       HAL_PCD_SOFCallback(hpcd);
  1214. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1215.  
  1216.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF);
  1217.     }
  1218.  
  1219.     /* Handle Global OUT NAK effective Interrupt */
  1220.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_BOUTNAKEFF))
  1221.     {
  1222.       USBx->GINTMSK &= ~USB_OTG_GINTMSK_GONAKEFFM;
  1223.  
  1224.       for (epnum = 1U; epnum < hpcd->Init.dev_endpoints; epnum++)
  1225.       {
  1226.         if (hpcd->OUT_ep[epnum].is_iso_incomplete == 1U)
  1227.         {
  1228.           /* Abort current transaction and disable the EP */
  1229.           (void)HAL_PCD_EP_Abort(hpcd, (uint8_t)epnum);
  1230.         }
  1231.       }
  1232.     }
  1233.  
  1234.     /* Handle Incomplete ISO IN Interrupt */
  1235.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR))
  1236.     {
  1237.       for (epnum = 1U; epnum < hpcd->Init.dev_endpoints; epnum++)
  1238.       {
  1239.         RegVal = USBx_INEP(epnum)->DIEPCTL;
  1240.  
  1241.         if ((hpcd->IN_ep[epnum].type == EP_TYPE_ISOC) &&
  1242.             ((RegVal & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA))
  1243.         {
  1244.           hpcd->IN_ep[epnum].is_iso_incomplete = 1U;
  1245.  
  1246.           /* Abort current transaction and disable the EP */
  1247.           (void)HAL_PCD_EP_Abort(hpcd, (uint8_t)(epnum | 0x80U));
  1248.         }
  1249.       }
  1250.  
  1251.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR);
  1252.     }
  1253.  
  1254.     /* Handle Incomplete ISO OUT Interrupt */
  1255.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
  1256.     {
  1257.       for (epnum = 1U; epnum < hpcd->Init.dev_endpoints; epnum++)
  1258.       {
  1259.         RegVal = USBx_OUTEP(epnum)->DOEPCTL;
  1260.  
  1261.         if ((hpcd->OUT_ep[epnum].type == EP_TYPE_ISOC) &&
  1262.             ((RegVal & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA) &&
  1263.             ((RegVal & (0x1U << 16)) == (hpcd->FrameNumber & 0x1U)))
  1264.         {
  1265.           hpcd->OUT_ep[epnum].is_iso_incomplete = 1U;
  1266.  
  1267.           USBx->GINTMSK |= USB_OTG_GINTMSK_GONAKEFFM;
  1268.  
  1269.           if ((USBx->GINTSTS & USB_OTG_GINTSTS_BOUTNAKEFF) == 0U)
  1270.           {
  1271.             USBx_DEVICE->DCTL |= USB_OTG_DCTL_SGONAK;
  1272.             break;
  1273.           }
  1274.         }
  1275.       }
  1276.  
  1277.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
  1278.     }
  1279.  
  1280.     /* Handle Connection event Interrupt */
  1281.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT))
  1282.     {
  1283. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1284.       hpcd->ConnectCallback(hpcd);
  1285. #else
  1286.       HAL_PCD_ConnectCallback(hpcd);
  1287. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1288.  
  1289.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT);
  1290.     }
  1291.  
  1292.     /* Handle Disconnection event Interrupt */
  1293.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT))
  1294.     {
  1295.       RegVal = hpcd->Instance->GOTGINT;
  1296.  
  1297.       if ((RegVal & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET)
  1298.       {
  1299. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1300.         hpcd->DisconnectCallback(hpcd);
  1301. #else
  1302.         HAL_PCD_DisconnectCallback(hpcd);
  1303. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1304.       }
  1305.       hpcd->Instance->GOTGINT |= RegVal;
  1306.     }
  1307.   }
  1308. }
  1309.  
  1310.  
  1311. /**
  1312.   * @brief  Handles PCD Wakeup interrupt request.
  1313.   * @param  hpcd PCD handle
  1314.   * @retval HAL status
  1315.   */
  1316. void HAL_PCD_WKUP_IRQHandler(PCD_HandleTypeDef *hpcd)
  1317. {
  1318.   /* Clear EXTI pending Bit */
  1319.   __HAL_USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG();
  1320. }
  1321. #endif /* defined (USB_OTG_FS) */
  1322.  
  1323. #if defined (USB)
  1324. /**
  1325.   * @brief  This function handles PCD interrupt request.
  1326.   * @param  hpcd PCD handle
  1327.   * @retval HAL status
  1328.   */
  1329. void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
  1330. {
  1331.   uint32_t wIstr = USB_ReadInterrupts(hpcd->Instance);
  1332.   uint16_t store_ep[8];
  1333.   uint8_t i;
  1334.  
  1335.   if ((wIstr & USB_ISTR_CTR) == USB_ISTR_CTR)
  1336.   {
  1337.     /* servicing of the endpoint correct transfer interrupt */
  1338.     /* clear of the CTR flag into the sub */
  1339.     (void)PCD_EP_ISR_Handler(hpcd);
  1340.  
  1341.     return;
  1342.   }
  1343.  
  1344.   if ((wIstr & USB_ISTR_RESET) == USB_ISTR_RESET)
  1345.   {
  1346.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET);
  1347.  
  1348. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1349.     hpcd->ResetCallback(hpcd);
  1350. #else
  1351.     HAL_PCD_ResetCallback(hpcd);
  1352. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1353.  
  1354.     (void)HAL_PCD_SetAddress(hpcd, 0U);
  1355.  
  1356.     return;
  1357.   }
  1358.  
  1359.   if ((wIstr & USB_ISTR_PMAOVR) == USB_ISTR_PMAOVR)
  1360.   {
  1361.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_PMAOVR);
  1362.  
  1363.     return;
  1364.   }
  1365.  
  1366.   if ((wIstr & USB_ISTR_ERR) == USB_ISTR_ERR)
  1367.   {
  1368.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ERR);
  1369.  
  1370.     return;
  1371.   }
  1372.  
  1373.   if ((wIstr & USB_ISTR_WKUP) == USB_ISTR_WKUP)
  1374.   {
  1375.     hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_LP_MODE);
  1376.     hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_FSUSP);
  1377.  
  1378. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1379.     hpcd->ResumeCallback(hpcd);
  1380. #else
  1381.     HAL_PCD_ResumeCallback(hpcd);
  1382. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1383.  
  1384.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP);
  1385.  
  1386.     return;
  1387.   }
  1388.  
  1389.   if ((wIstr & USB_ISTR_SUSP) == USB_ISTR_SUSP)
  1390.   {
  1391.     /* WA: To Clear Wakeup flag if raised with suspend signal */
  1392.  
  1393.     /* Store Endpoint registers */
  1394.     for (i = 0U; i < 8U; i++)
  1395.     {
  1396.       store_ep[i] = PCD_GET_ENDPOINT(hpcd->Instance, i);
  1397.     }
  1398.  
  1399.     /* FORCE RESET */
  1400.     hpcd->Instance->CNTR |= (uint16_t)(USB_CNTR_FRES);
  1401.  
  1402.     /* CLEAR RESET */
  1403.     hpcd->Instance->CNTR &= (uint16_t)(~USB_CNTR_FRES);
  1404.  
  1405.     /* wait for reset flag in ISTR */
  1406.     while ((hpcd->Instance->ISTR & USB_ISTR_RESET) == 0U)
  1407.     {
  1408.     }
  1409.  
  1410.     /* Clear Reset Flag */
  1411.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET);
  1412.  
  1413.     /* Restore Registre */
  1414.     for (i = 0U; i < 8U; i++)
  1415.     {
  1416.       PCD_SET_ENDPOINT(hpcd->Instance, i, store_ep[i]);
  1417.     }
  1418.  
  1419.     /* Force low-power mode in the macrocell */
  1420.     hpcd->Instance->CNTR |= (uint16_t)USB_CNTR_FSUSP;
  1421.  
  1422.     /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
  1423.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SUSP);
  1424.  
  1425.     hpcd->Instance->CNTR |= (uint16_t)USB_CNTR_LP_MODE;
  1426.  
  1427. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1428.     hpcd->SuspendCallback(hpcd);
  1429. #else
  1430.     HAL_PCD_SuspendCallback(hpcd);
  1431. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1432.  
  1433.     return;
  1434.   }
  1435.  
  1436.   if ((wIstr & USB_ISTR_SOF) == USB_ISTR_SOF)
  1437.   {
  1438.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SOF);
  1439.  
  1440. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1441.     hpcd->SOFCallback(hpcd);
  1442. #else
  1443.     HAL_PCD_SOFCallback(hpcd);
  1444. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1445.  
  1446.     return;
  1447.   }
  1448.  
  1449.   if ((wIstr & USB_ISTR_ESOF) == USB_ISTR_ESOF)
  1450.   {
  1451.     /* clear ESOF flag in ISTR */
  1452.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ESOF);
  1453.  
  1454.     return;
  1455.   }
  1456. }
  1457.  
  1458.  
  1459. /**
  1460.   * @brief  Handles PCD Wakeup interrupt request.
  1461.   * @param  hpcd PCD handle
  1462.   * @retval HAL status
  1463.   */
  1464. void HAL_PCD_WKUP_IRQHandler(PCD_HandleTypeDef *hpcd)
  1465. {
  1466.   /* Clear EXTI pending Bit */
  1467.   __HAL_USB_WAKEUP_EXTI_CLEAR_FLAG();
  1468. }
  1469. #endif /* defined (USB) */
  1470.  
  1471. /**
  1472.   * @brief  Data OUT stage callback.
  1473.   * @param  hpcd PCD handle
  1474.   * @param  epnum endpoint number
  1475.   * @retval None
  1476.   */
  1477. __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  1478. {
  1479.   /* Prevent unused argument(s) compilation warning */
  1480.   UNUSED(hpcd);
  1481.   UNUSED(epnum);
  1482.  
  1483.   /* NOTE : This function should not be modified, when the callback is needed,
  1484.             the HAL_PCD_DataOutStageCallback could be implemented in the user file
  1485.    */
  1486. }
  1487.  
  1488. /**
  1489.   * @brief  Data IN stage callback
  1490.   * @param  hpcd PCD handle
  1491.   * @param  epnum endpoint number
  1492.   * @retval None
  1493.   */
  1494. __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  1495. {
  1496.   /* Prevent unused argument(s) compilation warning */
  1497.   UNUSED(hpcd);
  1498.   UNUSED(epnum);
  1499.  
  1500.   /* NOTE : This function should not be modified, when the callback is needed,
  1501.             the HAL_PCD_DataInStageCallback could be implemented in the user file
  1502.    */
  1503. }
  1504. /**
  1505.   * @brief  Setup stage callback
  1506.   * @param  hpcd PCD handle
  1507.   * @retval None
  1508.   */
  1509. __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
  1510. {
  1511.   /* Prevent unused argument(s) compilation warning */
  1512.   UNUSED(hpcd);
  1513.  
  1514.   /* NOTE : This function should not be modified, when the callback is needed,
  1515.             the HAL_PCD_SetupStageCallback could be implemented in the user file
  1516.    */
  1517. }
  1518.  
  1519. /**
  1520.   * @brief  USB Start Of Frame callback.
  1521.   * @param  hpcd PCD handle
  1522.   * @retval None
  1523.   */
  1524. __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
  1525. {
  1526.   /* Prevent unused argument(s) compilation warning */
  1527.   UNUSED(hpcd);
  1528.  
  1529.   /* NOTE : This function should not be modified, when the callback is needed,
  1530.             the HAL_PCD_SOFCallback could be implemented in the user file
  1531.    */
  1532. }
  1533.  
  1534. /**
  1535.   * @brief  USB Reset callback.
  1536.   * @param  hpcd PCD handle
  1537.   * @retval None
  1538.   */
  1539. __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
  1540. {
  1541.   /* Prevent unused argument(s) compilation warning */
  1542.   UNUSED(hpcd);
  1543.  
  1544.   /* NOTE : This function should not be modified, when the callback is needed,
  1545.             the HAL_PCD_ResetCallback could be implemented in the user file
  1546.    */
  1547. }
  1548.  
  1549. /**
  1550.   * @brief  Suspend event callback.
  1551.   * @param  hpcd PCD handle
  1552.   * @retval None
  1553.   */
  1554. __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
  1555. {
  1556.   /* Prevent unused argument(s) compilation warning */
  1557.   UNUSED(hpcd);
  1558.  
  1559.   /* NOTE : This function should not be modified, when the callback is needed,
  1560.             the HAL_PCD_SuspendCallback could be implemented in the user file
  1561.    */
  1562. }
  1563.  
  1564. /**
  1565.   * @brief  Resume event callback.
  1566.   * @param  hpcd PCD handle
  1567.   * @retval None
  1568.   */
  1569. __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
  1570. {
  1571.   /* Prevent unused argument(s) compilation warning */
  1572.   UNUSED(hpcd);
  1573.  
  1574.   /* NOTE : This function should not be modified, when the callback is needed,
  1575.             the HAL_PCD_ResumeCallback could be implemented in the user file
  1576.    */
  1577. }
  1578.  
  1579. /**
  1580.   * @brief  Incomplete ISO OUT callback.
  1581.   * @param  hpcd PCD handle
  1582.   * @param  epnum endpoint number
  1583.   * @retval None
  1584.   */
  1585. __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  1586. {
  1587.   /* Prevent unused argument(s) compilation warning */
  1588.   UNUSED(hpcd);
  1589.   UNUSED(epnum);
  1590.  
  1591.   /* NOTE : This function should not be modified, when the callback is needed,
  1592.             the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file
  1593.    */
  1594. }
  1595.  
  1596. /**
  1597.   * @brief  Incomplete ISO IN callback.
  1598.   * @param  hpcd PCD handle
  1599.   * @param  epnum endpoint number
  1600.   * @retval None
  1601.   */
  1602. __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  1603. {
  1604.   /* Prevent unused argument(s) compilation warning */
  1605.   UNUSED(hpcd);
  1606.   UNUSED(epnum);
  1607.  
  1608.   /* NOTE : This function should not be modified, when the callback is needed,
  1609.             the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file
  1610.    */
  1611. }
  1612.  
  1613. /**
  1614.   * @brief  Connection event callback.
  1615.   * @param  hpcd PCD handle
  1616.   * @retval None
  1617.   */
  1618. __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
  1619. {
  1620.   /* Prevent unused argument(s) compilation warning */
  1621.   UNUSED(hpcd);
  1622.  
  1623.   /* NOTE : This function should not be modified, when the callback is needed,
  1624.             the HAL_PCD_ConnectCallback could be implemented in the user file
  1625.    */
  1626. }
  1627.  
  1628. /**
  1629.   * @brief  Disconnection event callback.
  1630.   * @param  hpcd PCD handle
  1631.   * @retval None
  1632.   */
  1633. __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
  1634. {
  1635.   /* Prevent unused argument(s) compilation warning */
  1636.   UNUSED(hpcd);
  1637.  
  1638.   /* NOTE : This function should not be modified, when the callback is needed,
  1639.             the HAL_PCD_DisconnectCallback could be implemented in the user file
  1640.    */
  1641. }
  1642.  
  1643. /**
  1644.   * @}
  1645.   */
  1646.  
  1647. /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
  1648.   *  @brief   management functions
  1649.   *
  1650. @verbatim
  1651.  ===============================================================================
  1652.                       ##### Peripheral Control functions #####
  1653.  ===============================================================================
  1654.     [..]
  1655.     This subsection provides a set of functions allowing to control the PCD data
  1656.     transfers.
  1657.  
  1658. @endverbatim
  1659.   * @{
  1660.   */
  1661.  
  1662. /**
  1663.   * @brief  Connect the USB device
  1664.   * @param  hpcd PCD handle
  1665.   * @retval HAL status
  1666.   */
  1667. HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd)
  1668. {
  1669.   __HAL_LOCK(hpcd);
  1670.  
  1671. #if defined (USB)
  1672.   HAL_PCDEx_SetConnectionState(hpcd, 1U);
  1673. #endif /* defined (USB) */
  1674.  
  1675.   (void)USB_DevConnect(hpcd->Instance);
  1676.   __HAL_UNLOCK(hpcd);
  1677.  
  1678.   return HAL_OK;
  1679. }
  1680.  
  1681. /**
  1682.   * @brief  Disconnect the USB device.
  1683.   * @param  hpcd PCD handle
  1684.   * @retval HAL status
  1685.   */
  1686. HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd)
  1687. {
  1688.   __HAL_LOCK(hpcd);
  1689.  
  1690. #if defined (USB)
  1691.   HAL_PCDEx_SetConnectionState(hpcd, 0U);
  1692. #endif /* defined (USB) */
  1693.  
  1694.   (void)USB_DevDisconnect(hpcd->Instance);
  1695.   __HAL_UNLOCK(hpcd);
  1696.  
  1697.   return HAL_OK;
  1698. }
  1699.  
  1700. /**
  1701.   * @brief  Set the USB Device address.
  1702.   * @param  hpcd PCD handle
  1703.   * @param  address new device address
  1704.   * @retval HAL status
  1705.   */
  1706. HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)
  1707. {
  1708.   __HAL_LOCK(hpcd);
  1709.   hpcd->USB_Address = address;
  1710.   (void)USB_SetDevAddress(hpcd->Instance, address);
  1711.   __HAL_UNLOCK(hpcd);
  1712.  
  1713.   return HAL_OK;
  1714. }
  1715. /**
  1716.   * @brief  Open and configure an endpoint.
  1717.   * @param  hpcd PCD handle
  1718.   * @param  ep_addr endpoint address
  1719.   * @param  ep_mps endpoint max packet size
  1720.   * @param  ep_type endpoint type
  1721.   * @retval HAL status
  1722.   */
  1723. HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr,
  1724.                                   uint16_t ep_mps, uint8_t ep_type)
  1725. {
  1726.   HAL_StatusTypeDef  ret = HAL_OK;
  1727.   PCD_EPTypeDef *ep;
  1728.  
  1729.   if ((ep_addr & 0x80U) == 0x80U)
  1730.   {
  1731.     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1732.     ep->is_in = 1U;
  1733.   }
  1734.   else
  1735.   {
  1736.     ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1737.     ep->is_in = 0U;
  1738.   }
  1739.  
  1740.   ep->num = ep_addr & EP_ADDR_MSK;
  1741.   ep->maxpacket = ep_mps;
  1742.   ep->type = ep_type;
  1743.  
  1744. #if defined (USB_OTG_FS)
  1745.   if (ep->is_in != 0U)
  1746.   {
  1747.     /* Assign a Tx FIFO */
  1748.     ep->tx_fifo_num = ep->num;
  1749.   }
  1750. #endif /* defined (USB_OTG_FS) */
  1751.  
  1752.   /* Set initial data PID. */
  1753.   if (ep_type == EP_TYPE_BULK)
  1754.   {
  1755.     ep->data_pid_start = 0U;
  1756.   }
  1757.  
  1758.   __HAL_LOCK(hpcd);
  1759.   (void)USB_ActivateEndpoint(hpcd->Instance, ep);
  1760.   __HAL_UNLOCK(hpcd);
  1761.  
  1762.   return ret;
  1763. }
  1764.  
  1765. /**
  1766.   * @brief  Deactivate an endpoint.
  1767.   * @param  hpcd PCD handle
  1768.   * @param  ep_addr endpoint address
  1769.   * @retval HAL status
  1770.   */
  1771. HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1772. {
  1773.   PCD_EPTypeDef *ep;
  1774.  
  1775.   if ((ep_addr & 0x80U) == 0x80U)
  1776.   {
  1777.     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1778.     ep->is_in = 1U;
  1779.   }
  1780.   else
  1781.   {
  1782.     ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1783.     ep->is_in = 0U;
  1784.   }
  1785.   ep->num = ep_addr & EP_ADDR_MSK;
  1786.  
  1787.   __HAL_LOCK(hpcd);
  1788.   (void)USB_DeactivateEndpoint(hpcd->Instance, ep);
  1789.   __HAL_UNLOCK(hpcd);
  1790.   return HAL_OK;
  1791. }
  1792.  
  1793.  
  1794. /**
  1795.   * @brief  Receive an amount of data.
  1796.   * @param  hpcd PCD handle
  1797.   * @param  ep_addr endpoint address
  1798.   * @param  pBuf pointer to the reception buffer
  1799.   * @param  len amount of data to be received
  1800.   * @retval HAL status
  1801.   */
  1802. HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
  1803. {
  1804.   PCD_EPTypeDef *ep;
  1805.  
  1806.   ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1807.  
  1808.   /*setup and start the Xfer */
  1809.   ep->xfer_buff = pBuf;
  1810.   ep->xfer_len = len;
  1811.   ep->xfer_count = 0U;
  1812.   ep->is_in = 0U;
  1813.   ep->num = ep_addr & EP_ADDR_MSK;
  1814.  
  1815.   (void)USB_EPStartXfer(hpcd->Instance, ep);
  1816.  
  1817.   return HAL_OK;
  1818. }
  1819.  
  1820. /**
  1821.   * @brief  Get Received Data Size
  1822.   * @param  hpcd PCD handle
  1823.   * @param  ep_addr endpoint address
  1824.   * @retval Data Size
  1825.   */
  1826. uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef const *hpcd, uint8_t ep_addr)
  1827. {
  1828.   return hpcd->OUT_ep[ep_addr & EP_ADDR_MSK].xfer_count;
  1829. }
  1830. /**
  1831.   * @brief  Send an amount of data
  1832.   * @param  hpcd PCD handle
  1833.   * @param  ep_addr endpoint address
  1834.   * @param  pBuf pointer to the transmission buffer
  1835.   * @param  len amount of data to be sent
  1836.   * @retval HAL status
  1837.   */
  1838. HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
  1839. {
  1840.   PCD_EPTypeDef *ep;
  1841.  
  1842.   ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1843.  
  1844.   /*setup and start the Xfer */
  1845.   ep->xfer_buff = pBuf;
  1846.   ep->xfer_len = len;
  1847. #if defined (USB)
  1848.   ep->xfer_fill_db = 1U;
  1849.   ep->xfer_len_db = len;
  1850. #endif /* defined (USB) */
  1851.   ep->xfer_count = 0U;
  1852.   ep->is_in = 1U;
  1853.   ep->num = ep_addr & EP_ADDR_MSK;
  1854.  
  1855.   (void)USB_EPStartXfer(hpcd->Instance, ep);
  1856.  
  1857.   return HAL_OK;
  1858. }
  1859.  
  1860. /**
  1861.   * @brief  Set a STALL condition over an endpoint
  1862.   * @param  hpcd PCD handle
  1863.   * @param  ep_addr endpoint address
  1864.   * @retval HAL status
  1865.   */
  1866. HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1867. {
  1868.   PCD_EPTypeDef *ep;
  1869.  
  1870.   if (((uint32_t)ep_addr & EP_ADDR_MSK) > hpcd->Init.dev_endpoints)
  1871.   {
  1872.     return HAL_ERROR;
  1873.   }
  1874.  
  1875.   if ((0x80U & ep_addr) == 0x80U)
  1876.   {
  1877.     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1878.     ep->is_in = 1U;
  1879.   }
  1880.   else
  1881.   {
  1882.     ep = &hpcd->OUT_ep[ep_addr];
  1883.     ep->is_in = 0U;
  1884.   }
  1885.  
  1886.   ep->is_stall = 1U;
  1887.   ep->num = ep_addr & EP_ADDR_MSK;
  1888.  
  1889.   __HAL_LOCK(hpcd);
  1890.  
  1891.   (void)USB_EPSetStall(hpcd->Instance, ep);
  1892.  
  1893.   if ((ep_addr & EP_ADDR_MSK) == 0U)
  1894.   {
  1895.     (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
  1896.   }
  1897.  
  1898.   __HAL_UNLOCK(hpcd);
  1899.  
  1900.   return HAL_OK;
  1901. }
  1902.  
  1903. /**
  1904.   * @brief  Clear a STALL condition over in an endpoint
  1905.   * @param  hpcd PCD handle
  1906.   * @param  ep_addr endpoint address
  1907.   * @retval HAL status
  1908.   */
  1909. HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1910. {
  1911.   PCD_EPTypeDef *ep;
  1912.  
  1913.   if (((uint32_t)ep_addr & 0x0FU) > hpcd->Init.dev_endpoints)
  1914.   {
  1915.     return HAL_ERROR;
  1916.   }
  1917.  
  1918.   if ((0x80U & ep_addr) == 0x80U)
  1919.   {
  1920.     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1921.     ep->is_in = 1U;
  1922.   }
  1923.   else
  1924.   {
  1925.     ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1926.     ep->is_in = 0U;
  1927.   }
  1928.  
  1929.   ep->is_stall = 0U;
  1930.   ep->num = ep_addr & EP_ADDR_MSK;
  1931.  
  1932.   __HAL_LOCK(hpcd);
  1933.   (void)USB_EPClearStall(hpcd->Instance, ep);
  1934.   __HAL_UNLOCK(hpcd);
  1935.  
  1936.   return HAL_OK;
  1937. }
  1938.  
  1939. /**
  1940.    * @brief  Abort an USB EP transaction.
  1941.    * @param  hpcd PCD handle
  1942.    * @param  ep_addr endpoint address
  1943.    * @retval HAL status
  1944.    */
  1945. HAL_StatusTypeDef HAL_PCD_EP_Abort(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1946. {
  1947.   HAL_StatusTypeDef ret;
  1948.   PCD_EPTypeDef *ep;
  1949.  
  1950.   if ((0x80U & ep_addr) == 0x80U)
  1951.   {
  1952.     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1953.   }
  1954.   else
  1955.   {
  1956.     ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1957.   }
  1958.  
  1959.   /* Stop Xfer */
  1960.   ret = USB_EPStopXfer(hpcd->Instance, ep);
  1961.  
  1962.   return ret;
  1963. }
  1964.  
  1965. /**
  1966.   * @brief  Flush an endpoint
  1967.   * @param  hpcd PCD handle
  1968.   * @param  ep_addr endpoint address
  1969.   * @retval HAL status
  1970.   */
  1971. HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1972. {
  1973.   __HAL_LOCK(hpcd);
  1974.  
  1975.   if ((ep_addr & 0x80U) == 0x80U)
  1976.   {
  1977.     (void)USB_FlushTxFifo(hpcd->Instance, (uint32_t)ep_addr & EP_ADDR_MSK);
  1978.   }
  1979.   else
  1980.   {
  1981.     (void)USB_FlushRxFifo(hpcd->Instance);
  1982.   }
  1983.  
  1984.   __HAL_UNLOCK(hpcd);
  1985.  
  1986.   return HAL_OK;
  1987. }
  1988.  
  1989. /**
  1990.   * @brief  Activate remote wakeup signalling
  1991.   * @param  hpcd PCD handle
  1992.   * @retval HAL status
  1993.   */
  1994. HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
  1995. {
  1996.   return (USB_ActivateRemoteWakeup(hpcd->Instance));
  1997. }
  1998.  
  1999. /**
  2000.   * @brief  De-activate remote wakeup signalling.
  2001.   * @param  hpcd PCD handle
  2002.   * @retval HAL status
  2003.   */
  2004. HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
  2005. {
  2006.   return (USB_DeActivateRemoteWakeup(hpcd->Instance));
  2007. }
  2008.  
  2009. /**
  2010.   * @}
  2011.   */
  2012.  
  2013. /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions
  2014.   *  @brief   Peripheral State functions
  2015.   *
  2016. @verbatim
  2017.  ===============================================================================
  2018.                       ##### Peripheral State functions #####
  2019.  ===============================================================================
  2020.     [..]
  2021.     This subsection permits to get in run-time the status of the peripheral
  2022.     and the data flow.
  2023.  
  2024. @endverbatim
  2025.   * @{
  2026.   */
  2027.  
  2028. /**
  2029.   * @brief  Return the PCD handle state.
  2030.   * @param  hpcd PCD handle
  2031.   * @retval HAL state
  2032.   */
  2033. PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef const *hpcd)
  2034. {
  2035.   return hpcd->State;
  2036. }
  2037.  
  2038. /**
  2039.   * @}
  2040.   */
  2041.  
  2042. /**
  2043.   * @}
  2044.   */
  2045.  
  2046. /* Private functions ---------------------------------------------------------*/
  2047. /** @addtogroup PCD_Private_Functions
  2048.   * @{
  2049.   */
  2050. #if defined (USB_OTG_FS)
  2051. /**
  2052.   * @brief  Check FIFO for the next packet to be loaded.
  2053.   * @param  hpcd PCD handle
  2054.   * @param  epnum endpoint number
  2055.   * @retval HAL status
  2056.   */
  2057. static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum)
  2058. {
  2059.   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
  2060.   uint32_t USBx_BASE = (uint32_t)USBx;
  2061.   USB_OTG_EPTypeDef *ep;
  2062.   uint32_t len;
  2063.   uint32_t len32b;
  2064.   uint32_t fifoemptymsk;
  2065.  
  2066.   ep = &hpcd->IN_ep[epnum];
  2067.  
  2068.   if (ep->xfer_count > ep->xfer_len)
  2069.   {
  2070.     return HAL_ERROR;
  2071.   }
  2072.  
  2073.   len = ep->xfer_len - ep->xfer_count;
  2074.  
  2075.   if (len > ep->maxpacket)
  2076.   {
  2077.     len = ep->maxpacket;
  2078.   }
  2079.  
  2080.   len32b = (len + 3U) / 4U;
  2081.  
  2082.   while (((USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= len32b) &&
  2083.          (ep->xfer_count < ep->xfer_len) && (ep->xfer_len != 0U))
  2084.   {
  2085.     /* Write the FIFO */
  2086.     len = ep->xfer_len - ep->xfer_count;
  2087.  
  2088.     if (len > ep->maxpacket)
  2089.     {
  2090.       len = ep->maxpacket;
  2091.     }
  2092.     len32b = (len + 3U) / 4U;
  2093.  
  2094.     (void)USB_WritePacket(USBx, ep->xfer_buff, (uint8_t)epnum, (uint16_t)len);
  2095.  
  2096.     ep->xfer_buff  += len;
  2097.     ep->xfer_count += len;
  2098.   }
  2099.  
  2100.   if (ep->xfer_len <= ep->xfer_count)
  2101.   {
  2102.     fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK));
  2103.     USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
  2104.   }
  2105.  
  2106.   return HAL_OK;
  2107. }
  2108.  
  2109.  
  2110. /**
  2111.   * @brief  process EP OUT transfer complete interrupt.
  2112.   * @param  hpcd PCD handle
  2113.   * @param  epnum endpoint number
  2114.   * @retval HAL status
  2115.   */
  2116. static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef *hpcd, uint32_t epnum)
  2117. {
  2118.   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
  2119.   uint32_t USBx_BASE = (uint32_t)USBx;
  2120.   uint32_t gSNPSiD = *(__IO uint32_t *)(&USBx->CID + 0x1U);
  2121.   uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT;
  2122.  
  2123.   if (gSNPSiD == USB_OTG_CORE_ID_310A)
  2124.   {
  2125.     /* StupPktRcvd = 1 this is a setup packet */
  2126.     if ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX)
  2127.     {
  2128.       CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
  2129.     }
  2130.     else
  2131.     {
  2132.       if ((DoepintReg & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR)
  2133.       {
  2134.         CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
  2135.       }
  2136.  
  2137. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  2138.       hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
  2139. #else
  2140.       HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
  2141. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  2142.     }
  2143.   }
  2144.   else
  2145.   {
  2146. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  2147.     hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
  2148. #else
  2149.     HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
  2150. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  2151.   }
  2152.  
  2153.   return HAL_OK;
  2154. }
  2155.  
  2156.  
  2157. /**
  2158.   * @brief  process EP OUT setup packet received interrupt.
  2159.   * @param  hpcd PCD handle
  2160.   * @param  epnum endpoint number
  2161.   * @retval HAL status
  2162.   */
  2163. static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef *hpcd, uint32_t epnum)
  2164. {
  2165.   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
  2166.   uint32_t USBx_BASE = (uint32_t)USBx;
  2167.   uint32_t gSNPSiD = *(__IO uint32_t *)(&USBx->CID + 0x1U);
  2168.   uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT;
  2169.  
  2170.   if ((gSNPSiD > USB_OTG_CORE_ID_300A) &&
  2171.       ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX))
  2172.   {
  2173.     CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
  2174.   }
  2175.  
  2176.   /* Inform the upper layer that a setup packet is available */
  2177. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  2178.   hpcd->SetupStageCallback(hpcd);
  2179. #else
  2180.   HAL_PCD_SetupStageCallback(hpcd);
  2181. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  2182.  
  2183.   return HAL_OK;
  2184. }
  2185. #endif /* defined (USB_OTG_FS) */
  2186.  
  2187. #if defined (USB)
  2188. /**
  2189.   * @brief  This function handles PCD Endpoint interrupt request.
  2190.   * @param  hpcd PCD handle
  2191.   * @retval HAL status
  2192.   */
  2193. static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
  2194. {
  2195.   PCD_EPTypeDef *ep;
  2196.   uint16_t count;
  2197.   uint16_t wIstr;
  2198.   uint16_t wEPVal;
  2199.   uint16_t TxPctSize;
  2200.   uint8_t epindex;
  2201.  
  2202. #if (USE_USB_DOUBLE_BUFFER != 1U)
  2203.   count = 0U;
  2204. #endif /* USE_USB_DOUBLE_BUFFER */
  2205.  
  2206.   /* stay in loop while pending interrupts */
  2207.   while ((hpcd->Instance->ISTR & USB_ISTR_CTR) != 0U)
  2208.   {
  2209.     wIstr = hpcd->Instance->ISTR;
  2210.  
  2211.     /* extract highest priority endpoint number */
  2212.     epindex = (uint8_t)(wIstr & USB_ISTR_EP_ID);
  2213.  
  2214.     if (epindex == 0U)
  2215.     {
  2216.       /* Decode and service control endpoint interrupt */
  2217.  
  2218.       /* DIR bit = origin of the interrupt */
  2219.       if ((wIstr & USB_ISTR_DIR) == 0U)
  2220.       {
  2221.         /* DIR = 0 */
  2222.  
  2223.         /* DIR = 0 => IN  int */
  2224.         /* DIR = 0 implies that (EP_CTR_TX = 1) always */
  2225.         PCD_CLEAR_TX_EP_CTR(hpcd->Instance, PCD_ENDP0);
  2226.         ep = &hpcd->IN_ep[0];
  2227.  
  2228.         ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
  2229.         ep->xfer_buff += ep->xfer_count;
  2230.  
  2231.         /* TX COMPLETE */
  2232. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  2233.         hpcd->DataInStageCallback(hpcd, 0U);
  2234. #else
  2235.         HAL_PCD_DataInStageCallback(hpcd, 0U);
  2236. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  2237.  
  2238.         if ((hpcd->USB_Address > 0U) && (ep->xfer_len == 0U))
  2239.         {
  2240.           hpcd->Instance->DADDR = ((uint16_t)hpcd->USB_Address | USB_DADDR_EF);
  2241.           hpcd->USB_Address = 0U;
  2242.         }
  2243.       }
  2244.       else
  2245.       {
  2246.         /* DIR = 1 */
  2247.  
  2248.         /* DIR = 1 & CTR_RX => SETUP or OUT int */
  2249.         /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */
  2250.         ep = &hpcd->OUT_ep[0];
  2251.         wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0);
  2252.  
  2253.         if ((wEPVal & USB_EP_SETUP) != 0U)
  2254.         {
  2255.           /* Get SETUP Packet */
  2256.           ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
  2257.  
  2258.           USB_ReadPMA(hpcd->Instance, (uint8_t *)hpcd->Setup,
  2259.                       ep->pmaadress, (uint16_t)ep->xfer_count);
  2260.  
  2261.           /* SETUP bit kept frozen while CTR_RX = 1 */
  2262.           PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
  2263.  
  2264.           /* Process SETUP Packet*/
  2265. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  2266.           hpcd->SetupStageCallback(hpcd);
  2267. #else
  2268.           HAL_PCD_SetupStageCallback(hpcd);
  2269. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  2270.         }
  2271.         else if ((wEPVal & USB_EP_CTR_RX) != 0U)
  2272.         {
  2273.           PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
  2274.  
  2275.           /* Get Control Data OUT Packet */
  2276.           ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
  2277.  
  2278.           if ((ep->xfer_count != 0U) && (ep->xfer_buff != 0U))
  2279.           {
  2280.             USB_ReadPMA(hpcd->Instance, ep->xfer_buff,
  2281.                         ep->pmaadress, (uint16_t)ep->xfer_count);
  2282.  
  2283.             ep->xfer_buff += ep->xfer_count;
  2284.  
  2285.             /* Process Control Data OUT Packet */
  2286. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  2287.             hpcd->DataOutStageCallback(hpcd, 0U);
  2288. #else
  2289.             HAL_PCD_DataOutStageCallback(hpcd, 0U);
  2290. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  2291.           }
  2292.  
  2293.           wEPVal = (uint16_t)PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0);
  2294.  
  2295.           if (((wEPVal & USB_EP_SETUP) == 0U) && ((wEPVal & USB_EP_RX_STRX) != USB_EP_RX_VALID))
  2296.           {
  2297.             PCD_SET_EP_RX_CNT(hpcd->Instance, PCD_ENDP0, ep->maxpacket);
  2298.             PCD_SET_EP_RX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_RX_VALID);
  2299.           }
  2300.         }
  2301.       }
  2302.     }
  2303.     else
  2304.     {
  2305.       /* Decode and service non control endpoints interrupt */
  2306.       /* process related endpoint register */
  2307.       wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, epindex);
  2308.  
  2309.       if ((wEPVal & USB_EP_CTR_RX) != 0U)
  2310.       {
  2311.         /* clear int flag */
  2312.         PCD_CLEAR_RX_EP_CTR(hpcd->Instance, epindex);
  2313.         ep = &hpcd->OUT_ep[epindex];
  2314.  
  2315.         /* OUT Single Buffering */
  2316.         if (ep->doublebuffer == 0U)
  2317.         {
  2318.           count = (uint16_t)PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
  2319.  
  2320.           if (count != 0U)
  2321.           {
  2322.             USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, count);
  2323.           }
  2324.         }
  2325. #if (USE_USB_DOUBLE_BUFFER == 1U)
  2326.         else
  2327.         {
  2328.           /* manage double buffer bulk out */
  2329.           if (ep->type == EP_TYPE_BULK)
  2330.           {
  2331.             count = HAL_PCD_EP_DB_Receive(hpcd, ep, wEPVal);
  2332.           }
  2333.           else /* manage double buffer iso out */
  2334.           {
  2335.             /* free EP OUT Buffer */
  2336.             PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 0U);
  2337.  
  2338.             if ((PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_RX) != 0U)
  2339.             {
  2340.               /* read from endpoint BUF0Addr buffer */
  2341.               count = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
  2342.  
  2343.               if (count != 0U)
  2344.               {
  2345.                 USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count);
  2346.               }
  2347.             }
  2348.             else
  2349.             {
  2350.               /* read from endpoint BUF1Addr buffer */
  2351.               count = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
  2352.  
  2353.               if (count != 0U)
  2354.               {
  2355.                 USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count);
  2356.               }
  2357.             }
  2358.           }
  2359.         }
  2360. #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
  2361.  
  2362.         /* multi-packet on the NON control OUT endpoint */
  2363.         ep->xfer_count += count;
  2364.         ep->xfer_buff += count;
  2365.  
  2366.         if ((ep->xfer_len == 0U) || (count < ep->maxpacket))
  2367.         {
  2368.           /* RX COMPLETE */
  2369. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  2370.           hpcd->DataOutStageCallback(hpcd, ep->num);
  2371. #else
  2372.           HAL_PCD_DataOutStageCallback(hpcd, ep->num);
  2373. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  2374.         }
  2375.         else
  2376.         {
  2377.           (void)USB_EPStartXfer(hpcd->Instance, ep);
  2378.         }
  2379.       }
  2380.  
  2381.       if ((wEPVal & USB_EP_CTR_TX) != 0U)
  2382.       {
  2383.         ep = &hpcd->IN_ep[epindex];
  2384.  
  2385.         /* clear int flag */
  2386.         PCD_CLEAR_TX_EP_CTR(hpcd->Instance, epindex);
  2387.  
  2388.         if (ep->type == EP_TYPE_ISOC)
  2389.         {
  2390.           ep->xfer_len = 0U;
  2391.  
  2392. #if (USE_USB_DOUBLE_BUFFER == 1U)
  2393.           if (ep->doublebuffer != 0U)
  2394.           {
  2395.             if ((wEPVal & USB_EP_DTOG_TX) != 0U)
  2396.             {
  2397.               PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, 0U);
  2398.             }
  2399.             else
  2400.             {
  2401.               PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, 0U);
  2402.             }
  2403.           }
  2404. #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
  2405.  
  2406.           /* TX COMPLETE */
  2407. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  2408.           hpcd->DataInStageCallback(hpcd, ep->num);
  2409. #else
  2410.           HAL_PCD_DataInStageCallback(hpcd, ep->num);
  2411. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  2412.         }
  2413.         else
  2414.         {
  2415.           /* Manage Single Buffer Transaction */
  2416.           if ((wEPVal & USB_EP_KIND) == 0U)
  2417.           {
  2418.             /* multi-packet on the NON control IN endpoint */
  2419.             TxPctSize = (uint16_t)PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
  2420.  
  2421.             if (ep->xfer_len > TxPctSize)
  2422.             {
  2423.               ep->xfer_len -= TxPctSize;
  2424.             }
  2425.             else
  2426.             {
  2427.               ep->xfer_len = 0U;
  2428.             }
  2429.  
  2430.             /* Zero Length Packet? */
  2431.             if (ep->xfer_len == 0U)
  2432.             {
  2433.               /* TX COMPLETE */
  2434. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  2435.               hpcd->DataInStageCallback(hpcd, ep->num);
  2436. #else
  2437.               HAL_PCD_DataInStageCallback(hpcd, ep->num);
  2438. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  2439.             }
  2440.             else
  2441.             {
  2442.               /* Transfer is not yet Done */
  2443.               ep->xfer_buff += TxPctSize;
  2444.               ep->xfer_count += TxPctSize;
  2445.               (void)USB_EPStartXfer(hpcd->Instance, ep);
  2446.             }
  2447.           }
  2448. #if (USE_USB_DOUBLE_BUFFER == 1U)
  2449.           /* Double Buffer bulk IN (bulk transfer Len > Ep_Mps) */
  2450.           else
  2451.           {
  2452.             (void)HAL_PCD_EP_DB_Transmit(hpcd, ep, wEPVal);
  2453.           }
  2454. #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
  2455.         }
  2456.       }
  2457.     }
  2458.   }
  2459.  
  2460.   return HAL_OK;
  2461. }
  2462.  
  2463.  
  2464. #if (USE_USB_DOUBLE_BUFFER == 1U)
  2465. /**
  2466.   * @brief  Manage double buffer bulk out transaction from ISR
  2467.   * @param  hpcd PCD handle
  2468.   * @param  ep current endpoint handle
  2469.   * @param  wEPVal Last snapshot of EPRx register value taken in ISR
  2470.   * @retval HAL status
  2471.   */
  2472. static uint16_t HAL_PCD_EP_DB_Receive(PCD_HandleTypeDef *hpcd,
  2473.                                       PCD_EPTypeDef *ep, uint16_t wEPVal)
  2474. {
  2475.   uint16_t count;
  2476.  
  2477.   /* Manage Buffer0 OUT */
  2478.   if ((wEPVal & USB_EP_DTOG_RX) != 0U)
  2479.   {
  2480.     /* Get count of received Data on buffer0 */
  2481.     count = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
  2482.  
  2483.     if (ep->xfer_len >= count)
  2484.     {
  2485.       ep->xfer_len -= count;
  2486.     }
  2487.     else
  2488.     {
  2489.       ep->xfer_len = 0U;
  2490.     }
  2491.  
  2492.     if (ep->xfer_len == 0U)
  2493.     {
  2494.       /* set NAK to OUT endpoint since double buffer is enabled */
  2495.       PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_NAK);
  2496.     }
  2497.  
  2498.     /* Check if Buffer1 is in blocked state which requires to toggle */
  2499.     if ((wEPVal & USB_EP_DTOG_TX) != 0U)
  2500.     {
  2501.       PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 0U);
  2502.     }
  2503.  
  2504.     if (count != 0U)
  2505.     {
  2506.       USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count);
  2507.     }
  2508.   }
  2509.   /* Manage Buffer 1 DTOG_RX=0 */
  2510.   else
  2511.   {
  2512.     /* Get count of received data */
  2513.     count = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
  2514.  
  2515.     if (ep->xfer_len >= count)
  2516.     {
  2517.       ep->xfer_len -= count;
  2518.     }
  2519.     else
  2520.     {
  2521.       ep->xfer_len = 0U;
  2522.     }
  2523.  
  2524.     if (ep->xfer_len == 0U)
  2525.     {
  2526.       /* set NAK on the current endpoint */
  2527.       PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_NAK);
  2528.     }
  2529.  
  2530.     /*Need to FreeUser Buffer*/
  2531.     if ((wEPVal & USB_EP_DTOG_TX) == 0U)
  2532.     {
  2533.       PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 0U);
  2534.     }
  2535.  
  2536.     if (count != 0U)
  2537.     {
  2538.       USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count);
  2539.     }
  2540.   }
  2541.  
  2542.   return count;
  2543. }
  2544.  
  2545.  
  2546. /**
  2547.   * @brief  Manage double buffer bulk IN transaction from ISR
  2548.   * @param  hpcd PCD handle
  2549.   * @param  ep current endpoint handle
  2550.   * @param  wEPVal Last snapshot of EPRx register value taken in ISR
  2551.   * @retval HAL status
  2552.   */
  2553. static HAL_StatusTypeDef HAL_PCD_EP_DB_Transmit(PCD_HandleTypeDef *hpcd,
  2554.                                                 PCD_EPTypeDef *ep, uint16_t wEPVal)
  2555. {
  2556.   uint32_t len;
  2557.   uint16_t TxPctSize;
  2558.  
  2559.   /* Data Buffer0 ACK received */
  2560.   if ((wEPVal & USB_EP_DTOG_TX) != 0U)
  2561.   {
  2562.     /* multi-packet on the NON control IN endpoint */
  2563.     TxPctSize = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
  2564.  
  2565.     if (ep->xfer_len > TxPctSize)
  2566.     {
  2567.       ep->xfer_len -= TxPctSize;
  2568.     }
  2569.     else
  2570.     {
  2571.       ep->xfer_len = 0U;
  2572.     }
  2573.  
  2574.     /* Transfer is completed */
  2575.     if (ep->xfer_len == 0U)
  2576.     {
  2577.       PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, 0U);
  2578.       PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, 0U);
  2579.  
  2580.       /* TX COMPLETE */
  2581. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  2582.       hpcd->DataInStageCallback(hpcd, ep->num);
  2583. #else
  2584.       HAL_PCD_DataInStageCallback(hpcd, ep->num);
  2585. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  2586.  
  2587.       if ((wEPVal & USB_EP_DTOG_RX) != 0U)
  2588.       {
  2589.         PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 1U);
  2590.       }
  2591.     }
  2592.     else /* Transfer is not yet Done */
  2593.     {
  2594.       /* need to Free USB Buff */
  2595.       if ((wEPVal & USB_EP_DTOG_RX) != 0U)
  2596.       {
  2597.         PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 1U);
  2598.       }
  2599.  
  2600.       /* Still there is data to Fill in the next Buffer */
  2601.       if (ep->xfer_fill_db == 1U)
  2602.       {
  2603.         ep->xfer_buff += TxPctSize;
  2604.         ep->xfer_count += TxPctSize;
  2605.  
  2606.         /* Calculate the len of the new buffer to fill */
  2607.         if (ep->xfer_len_db >= ep->maxpacket)
  2608.         {
  2609.           len = ep->maxpacket;
  2610.           ep->xfer_len_db -= len;
  2611.         }
  2612.         else if (ep->xfer_len_db == 0U)
  2613.         {
  2614.           len = TxPctSize;
  2615.           ep->xfer_fill_db = 0U;
  2616.         }
  2617.         else
  2618.         {
  2619.           ep->xfer_fill_db = 0U;
  2620.           len = ep->xfer_len_db;
  2621.           ep->xfer_len_db = 0U;
  2622.         }
  2623.  
  2624.         /* Write remaining Data to Buffer */
  2625.         /* Set the Double buffer counter for pma buffer1 */
  2626.         PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, len);
  2627.  
  2628.         /* Copy user buffer to USB PMA */
  2629.         USB_WritePMA(hpcd->Instance, ep->xfer_buff,  ep->pmaaddr0, (uint16_t)len);
  2630.       }
  2631.     }
  2632.   }
  2633.   else /* Data Buffer1 ACK received */
  2634.   {
  2635.     /* multi-packet on the NON control IN endpoint */
  2636.     TxPctSize = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
  2637.  
  2638.     if (ep->xfer_len >= TxPctSize)
  2639.     {
  2640.       ep->xfer_len -= TxPctSize;
  2641.     }
  2642.     else
  2643.     {
  2644.       ep->xfer_len = 0U;
  2645.     }
  2646.  
  2647.     /* Transfer is completed */
  2648.     if (ep->xfer_len == 0U)
  2649.     {
  2650.       PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, 0U);
  2651.       PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, 0U);
  2652.  
  2653.       /* TX COMPLETE */
  2654. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  2655.       hpcd->DataInStageCallback(hpcd, ep->num);
  2656. #else
  2657.       HAL_PCD_DataInStageCallback(hpcd, ep->num);
  2658. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  2659.  
  2660.       /* need to Free USB Buff */
  2661.       if ((wEPVal & USB_EP_DTOG_RX) == 0U)
  2662.       {
  2663.         PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 1U);
  2664.       }
  2665.     }
  2666.     else /* Transfer is not yet Done */
  2667.     {
  2668.       /* need to Free USB Buff */
  2669.       if ((wEPVal & USB_EP_DTOG_RX) == 0U)
  2670.       {
  2671.         PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 1U);
  2672.       }
  2673.  
  2674.       /* Still there is data to Fill in the next Buffer */
  2675.       if (ep->xfer_fill_db == 1U)
  2676.       {
  2677.         ep->xfer_buff += TxPctSize;
  2678.         ep->xfer_count += TxPctSize;
  2679.  
  2680.         /* Calculate the len of the new buffer to fill */
  2681.         if (ep->xfer_len_db >= ep->maxpacket)
  2682.         {
  2683.           len = ep->maxpacket;
  2684.           ep->xfer_len_db -= len;
  2685.         }
  2686.         else if (ep->xfer_len_db == 0U)
  2687.         {
  2688.           len = TxPctSize;
  2689.           ep->xfer_fill_db = 0U;
  2690.         }
  2691.         else
  2692.         {
  2693.           len = ep->xfer_len_db;
  2694.           ep->xfer_len_db = 0U;
  2695.           ep->xfer_fill_db = 0;
  2696.         }
  2697.  
  2698.         /* Set the Double buffer counter for pmabuffer1 */
  2699.         PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, len);
  2700.  
  2701.         /* Copy the user buffer to USB PMA */
  2702.         USB_WritePMA(hpcd->Instance, ep->xfer_buff,  ep->pmaaddr1, (uint16_t)len);
  2703.       }
  2704.     }
  2705.   }
  2706.  
  2707.   /*enable endpoint IN*/
  2708.   PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_VALID);
  2709.  
  2710.   return HAL_OK;
  2711. }
  2712. #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
  2713.  
  2714. #endif /* defined (USB) */
  2715.  
  2716. /**
  2717.   * @}
  2718.   */
  2719. #endif /* defined (USB) || defined (USB_OTG_FS) */
  2720. #endif /* HAL_PCD_MODULE_ENABLED */
  2721.  
  2722. /**
  2723.   * @}
  2724.   */
  2725.  
  2726. /**
  2727.   * @}
  2728.   */
  2729.