Subversion Repositories canSerial

Rev

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