Subversion Repositories LedShow

Rev

Rev 2 | 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 to the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
  727.   * @param  hpcd PCD handle
  728.   * @retval HAL status
  729.   */
  730. HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd)
  731. {
  732.   HAL_StatusTypeDef status = HAL_OK;
  733.  
  734.   /* Process locked */
  735.   __HAL_LOCK(hpcd);
  736.  
  737.   if (hpcd->State == HAL_PCD_STATE_READY)
  738.   {
  739.     hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback; /* Legacy weak ISOOUTIncompleteCallback  */
  740.   }
  741.   else
  742.   {
  743.     /* Update the error code */
  744.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  745.  
  746.     /* Return error status */
  747.     status =  HAL_ERROR;
  748.   }
  749.  
  750.   /* Release Lock */
  751.   __HAL_UNLOCK(hpcd);
  752.  
  753.   return status;
  754. }
  755.  
  756. /**
  757.   * @brief  Register USB PCD Iso IN incomplete Callback
  758.   *         To be used instead of the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
  759.   * @param  hpcd PCD handle
  760.   * @param  pCallback pointer to the USB PCD Iso IN incomplete Callback function
  761.   * @retval HAL status
  762.   */
  763. HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd,
  764.                                                       pPCD_IsoInIncpltCallbackTypeDef pCallback)
  765. {
  766.   HAL_StatusTypeDef status = HAL_OK;
  767.  
  768.   if (pCallback == NULL)
  769.   {
  770.     /* Update the error code */
  771.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  772.  
  773.     return HAL_ERROR;
  774.   }
  775.  
  776.   /* Process locked */
  777.   __HAL_LOCK(hpcd);
  778.  
  779.   if (hpcd->State == HAL_PCD_STATE_READY)
  780.   {
  781.     hpcd->ISOINIncompleteCallback = pCallback;
  782.   }
  783.   else
  784.   {
  785.     /* Update the error code */
  786.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  787.  
  788.     /* Return error status */
  789.     status =  HAL_ERROR;
  790.   }
  791.  
  792.   /* Release Lock */
  793.   __HAL_UNLOCK(hpcd);
  794.  
  795.   return status;
  796. }
  797.  
  798. /**
  799.   * @brief  Unregister the USB PCD Iso IN incomplete Callback
  800.   *         USB PCD Iso IN incomplete Callback is redirected to the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
  801.   * @param  hpcd PCD handle
  802.   * @retval HAL status
  803.   */
  804. HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd)
  805. {
  806.   HAL_StatusTypeDef status = HAL_OK;
  807.  
  808.   /* Process locked */
  809.   __HAL_LOCK(hpcd);
  810.  
  811.   if (hpcd->State == HAL_PCD_STATE_READY)
  812.   {
  813.     hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback; /* Legacy weak ISOINIncompleteCallback  */
  814.   }
  815.   else
  816.   {
  817.     /* Update the error code */
  818.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  819.  
  820.     /* Return error status */
  821.     status =  HAL_ERROR;
  822.   }
  823.  
  824.   /* Release Lock */
  825.   __HAL_UNLOCK(hpcd);
  826.  
  827.   return status;
  828. }
  829.  
  830. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  831.  
  832. /**
  833.   * @}
  834.   */
  835.  
  836. /** @defgroup PCD_Exported_Functions_Group2 Input and Output operation functions
  837.   *  @brief   Data transfers functions
  838.   *
  839. @verbatim
  840.  ===============================================================================
  841.                       ##### IO operation functions #####
  842.  ===============================================================================
  843.     [..]
  844.     This subsection provides a set of functions allowing to manage the PCD data
  845.     transfers.
  846.  
  847. @endverbatim
  848.   * @{
  849.   */
  850.  
  851. /**
  852.   * @brief  Start the USB device
  853.   * @param  hpcd PCD handle
  854.   * @retval HAL status
  855.   */
  856. HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)
  857. {
  858.   __HAL_LOCK(hpcd);
  859.   __HAL_PCD_ENABLE(hpcd);
  860.  
  861. #if defined (USB)
  862.   HAL_PCDEx_SetConnectionState(hpcd, 1U);
  863. #endif /* defined (USB) */
  864.  
  865.   (void)USB_DevConnect(hpcd->Instance);
  866.   __HAL_UNLOCK(hpcd);
  867.  
  868.   return HAL_OK;
  869. }
  870.  
  871. /**
  872.   * @brief  Stop the USB device.
  873.   * @param  hpcd PCD handle
  874.   * @retval HAL status
  875.   */
  876. HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
  877. {
  878.   __HAL_LOCK(hpcd);
  879.   __HAL_PCD_DISABLE(hpcd);
  880.  
  881. #if defined (USB)
  882.   HAL_PCDEx_SetConnectionState(hpcd, 0U);
  883. #endif /* defined (USB) */
  884.  
  885.   (void)USB_DevDisconnect(hpcd->Instance);
  886.  
  887. #if defined (USB_OTG_FS)
  888.   (void)USB_FlushTxFifo(hpcd->Instance, 0x10U);
  889. #endif /* defined (USB_OTG_FS) */
  890.  
  891.   __HAL_UNLOCK(hpcd);
  892.  
  893.   return HAL_OK;
  894. }
  895.  
  896. #if defined (USB_OTG_FS)
  897. /**
  898.   * @brief  Handles PCD interrupt request.
  899.   * @param  hpcd PCD handle
  900.   * @retval HAL status
  901.   */
  902. void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
  903. {
  904.   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
  905.   uint32_t USBx_BASE = (uint32_t)USBx;
  906.   uint32_t i, ep_intr, epint, epnum;
  907.   uint32_t fifoemptymsk, temp;
  908.   USB_OTG_EPTypeDef *ep;
  909.  
  910.   /* ensure that we are in device mode */
  911.   if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE)
  912.   {
  913.     /* avoid spurious interrupt */
  914.     if (__HAL_PCD_IS_INVALID_INTERRUPT(hpcd))
  915.     {
  916.       return;
  917.     }
  918.  
  919.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS))
  920.     {
  921.       /* incorrect mode, acknowledge the interrupt */
  922.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS);
  923.     }
  924.  
  925.     /* Handle RxQLevel Interrupt */
  926.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL))
  927.     {
  928.       USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
  929.  
  930.       temp = USBx->GRXSTSP;
  931.  
  932.       ep = &hpcd->OUT_ep[temp & USB_OTG_GRXSTSP_EPNUM];
  933.  
  934.       if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) ==  STS_DATA_UPDT)
  935.       {
  936.         if ((temp & USB_OTG_GRXSTSP_BCNT) != 0U)
  937.         {
  938.           (void)USB_ReadPacket(USBx, ep->xfer_buff,
  939.                                (uint16_t)((temp & USB_OTG_GRXSTSP_BCNT) >> 4));
  940.  
  941.           ep->xfer_buff += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
  942.           ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
  943.         }
  944.       }
  945.       else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) ==  STS_SETUP_UPDT)
  946.       {
  947.         (void)USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8U);
  948.         ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
  949.       }
  950.       else
  951.       {
  952.         /* ... */
  953.       }
  954.       USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
  955.     }
  956.  
  957.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT))
  958.     {
  959.       epnum = 0U;
  960.  
  961.       /* Read in the device interrupt bits */
  962.       ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance);
  963.  
  964.       while (ep_intr != 0U)
  965.       {
  966.         if ((ep_intr & 0x1U) != 0U)
  967.         {
  968.           epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, (uint8_t)epnum);
  969.  
  970.           if ((epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC)
  971.           {
  972.             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC);
  973.             (void)PCD_EP_OutXfrComplete_int(hpcd, epnum);
  974.           }
  975.  
  976.           if ((epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP)
  977.           {
  978.             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP);
  979.             /* Class B setup phase done for previous decoded setup */
  980.             (void)PCD_EP_OutSetupPacket_int(hpcd, epnum);
  981.           }
  982.  
  983.           if ((epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS)
  984.           {
  985.             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS);
  986.           }
  987.  
  988.           /* Clear Status Phase Received interrupt */
  989.           if ((epint & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR)
  990.           {
  991.             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
  992.           }
  993.  
  994.           /* Clear OUT NAK interrupt */
  995.           if ((epint & USB_OTG_DOEPINT_NAK) == USB_OTG_DOEPINT_NAK)
  996.           {
  997.             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_NAK);
  998.           }
  999.         }
  1000.         epnum++;
  1001.         ep_intr >>= 1U;
  1002.       }
  1003.     }
  1004.  
  1005.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT))
  1006.     {
  1007.       /* Read in the device interrupt bits */
  1008.       ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance);
  1009.  
  1010.       epnum = 0U;
  1011.  
  1012.       while (ep_intr != 0U)
  1013.       {
  1014.         if ((ep_intr & 0x1U) != 0U) /* In ITR */
  1015.         {
  1016.           epint = USB_ReadDevInEPInterrupt(hpcd->Instance, (uint8_t)epnum);
  1017.  
  1018.           if ((epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC)
  1019.           {
  1020.             fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK));
  1021.             USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
  1022.  
  1023.             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC);
  1024.  
  1025. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1026.             hpcd->DataInStageCallback(hpcd, (uint8_t)epnum);
  1027. #else
  1028.             HAL_PCD_DataInStageCallback(hpcd, (uint8_t)epnum);
  1029. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1030.           }
  1031.           if ((epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC)
  1032.           {
  1033.             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC);
  1034.           }
  1035.           if ((epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE)
  1036.           {
  1037.             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE);
  1038.           }
  1039.           if ((epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE)
  1040.           {
  1041.             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE);
  1042.           }
  1043.           if ((epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD)
  1044.           {
  1045.             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD);
  1046.           }
  1047.           if ((epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE)
  1048.           {
  1049.             (void)PCD_WriteEmptyTxFifo(hpcd, epnum);
  1050.           }
  1051.         }
  1052.         epnum++;
  1053.         ep_intr >>= 1U;
  1054.       }
  1055.     }
  1056.  
  1057.     /* Handle Resume Interrupt */
  1058.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT))
  1059.     {
  1060.       /* Clear the Remote Wake-up Signaling */
  1061.       USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
  1062.  
  1063. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1064.       hpcd->ResumeCallback(hpcd);
  1065. #else
  1066.       HAL_PCD_ResumeCallback(hpcd);
  1067. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1068.  
  1069.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT);
  1070.     }
  1071.  
  1072.     /* Handle Suspend Interrupt */
  1073.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP))
  1074.     {
  1075.       if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
  1076.       {
  1077. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1078.         hpcd->SuspendCallback(hpcd);
  1079. #else
  1080.         HAL_PCD_SuspendCallback(hpcd);
  1081. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1082.       }
  1083.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP);
  1084.     }
  1085.     /* Handle Reset Interrupt */
  1086.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST))
  1087.     {
  1088.       USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
  1089.       (void)USB_FlushTxFifo(hpcd->Instance, 0x10U);
  1090.  
  1091.       for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
  1092.       {
  1093.         USBx_INEP(i)->DIEPINT = 0xFB7FU;
  1094.         USBx_INEP(i)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
  1095.         USBx_INEP(i)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
  1096.         USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
  1097.         USBx_OUTEP(i)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
  1098.         USBx_OUTEP(i)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
  1099.       }
  1100.       USBx_DEVICE->DAINTMSK |= 0x10001U;
  1101.  
  1102.       if (hpcd->Init.use_dedicated_ep1 != 0U)
  1103.       {
  1104.         USBx_DEVICE->DOUTEP1MSK |= USB_OTG_DOEPMSK_STUPM |
  1105.                                    USB_OTG_DOEPMSK_XFRCM |
  1106.                                    USB_OTG_DOEPMSK_EPDM;
  1107.  
  1108.         USBx_DEVICE->DINEP1MSK |= USB_OTG_DIEPMSK_TOM |
  1109.                                   USB_OTG_DIEPMSK_XFRCM |
  1110.                                   USB_OTG_DIEPMSK_EPDM;
  1111.       }
  1112.       else
  1113.       {
  1114.         USBx_DEVICE->DOEPMSK |= USB_OTG_DOEPMSK_STUPM |
  1115.                                 USB_OTG_DOEPMSK_XFRCM |
  1116.                                 USB_OTG_DOEPMSK_EPDM |
  1117.                                 USB_OTG_DOEPMSK_OTEPSPRM |
  1118.                                 USB_OTG_DOEPMSK_NAKM;
  1119.  
  1120.         USBx_DEVICE->DIEPMSK |= USB_OTG_DIEPMSK_TOM |
  1121.                                 USB_OTG_DIEPMSK_XFRCM |
  1122.                                 USB_OTG_DIEPMSK_EPDM;
  1123.       }
  1124.  
  1125.       /* Set Default Address to 0 */
  1126.       USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD;
  1127.  
  1128.       /* setup EP0 to receive SETUP packets */
  1129.       (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
  1130.  
  1131.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST);
  1132.     }
  1133.  
  1134.     /* Handle Enumeration done Interrupt */
  1135.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE))
  1136.     {
  1137.       (void)USB_ActivateSetup(hpcd->Instance);
  1138.       hpcd->Init.speed = USB_GetDevSpeed(hpcd->Instance);
  1139.  
  1140.       /* Set USB Turnaround time */
  1141.       (void)USB_SetTurnaroundTime(hpcd->Instance,
  1142.                                   HAL_RCC_GetHCLKFreq(),
  1143.                                   (uint8_t)hpcd->Init.speed);
  1144.  
  1145. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1146.       hpcd->ResetCallback(hpcd);
  1147. #else
  1148.       HAL_PCD_ResetCallback(hpcd);
  1149. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1150.  
  1151.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE);
  1152.     }
  1153.  
  1154.     /* Handle SOF Interrupt */
  1155.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF))
  1156.     {
  1157. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1158.       hpcd->SOFCallback(hpcd);
  1159. #else
  1160.       HAL_PCD_SOFCallback(hpcd);
  1161. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1162.  
  1163.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF);
  1164.     }
  1165.  
  1166.     /* Handle Incomplete ISO IN Interrupt */
  1167.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR))
  1168.     {
  1169.       /* Keep application checking the corresponding Iso IN endpoint
  1170.       causing the incomplete Interrupt */
  1171.       epnum = 0U;
  1172.  
  1173. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1174.       hpcd->ISOINIncompleteCallback(hpcd, (uint8_t)epnum);
  1175. #else
  1176.       HAL_PCD_ISOINIncompleteCallback(hpcd, (uint8_t)epnum);
  1177. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1178.  
  1179.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR);
  1180.     }
  1181.  
  1182.     /* Handle Incomplete ISO OUT Interrupt */
  1183.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
  1184.     {
  1185.       /* Keep application checking the corresponding Iso OUT endpoint
  1186.       causing the incomplete Interrupt */
  1187.       epnum = 0U;
  1188.  
  1189. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1190.       hpcd->ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum);
  1191. #else
  1192.       HAL_PCD_ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum);
  1193. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1194.  
  1195.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
  1196.     }
  1197.  
  1198.     /* Handle Connection event Interrupt */
  1199.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT))
  1200.     {
  1201. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1202.       hpcd->ConnectCallback(hpcd);
  1203. #else
  1204.       HAL_PCD_ConnectCallback(hpcd);
  1205. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1206.  
  1207.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT);
  1208.     }
  1209.  
  1210.     /* Handle Disconnection event Interrupt */
  1211.     if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT))
  1212.     {
  1213.       temp = hpcd->Instance->GOTGINT;
  1214.  
  1215.       if ((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET)
  1216.       {
  1217. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1218.         hpcd->DisconnectCallback(hpcd);
  1219. #else
  1220.         HAL_PCD_DisconnectCallback(hpcd);
  1221. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1222.       }
  1223.       hpcd->Instance->GOTGINT |= temp;
  1224.     }
  1225.   }
  1226. }
  1227.  
  1228.  
  1229. /**
  1230.   * @brief  Handles PCD Wakeup interrupt request.
  1231.   * @param  hpcd PCD handle
  1232.   * @retval HAL status
  1233.   */
  1234. void HAL_PCD_WKUP_IRQHandler(PCD_HandleTypeDef *hpcd)
  1235. {
  1236.   /* Clear EXTI pending Bit */
  1237.   __HAL_USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG();
  1238. }
  1239. #endif /* defined (USB_OTG_FS) */
  1240.  
  1241. #if defined (USB)
  1242. /**
  1243.   * @brief  This function handles PCD interrupt request.
  1244.   * @param  hpcd PCD handle
  1245.   * @retval HAL status
  1246.   */
  1247. void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
  1248. {
  1249.   uint16_t store_ep[8];
  1250.   uint8_t i;
  1251.  
  1252.   if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_CTR))
  1253.   {
  1254.     /* servicing of the endpoint correct transfer interrupt */
  1255.     /* clear of the CTR flag into the sub */
  1256.     (void)PCD_EP_ISR_Handler(hpcd);
  1257.   }
  1258.  
  1259.   if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_RESET))
  1260.   {
  1261.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET);
  1262.  
  1263. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1264.     hpcd->ResetCallback(hpcd);
  1265. #else
  1266.     HAL_PCD_ResetCallback(hpcd);
  1267. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1268.  
  1269.     (void)HAL_PCD_SetAddress(hpcd, 0U);
  1270.   }
  1271.  
  1272.   if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_PMAOVR))
  1273.   {
  1274.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_PMAOVR);
  1275.   }
  1276.  
  1277.   if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_ERR))
  1278.   {
  1279.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ERR);
  1280.   }
  1281.  
  1282.   if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_WKUP))
  1283.   {
  1284.     hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_LP_MODE);
  1285.     hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_FSUSP);
  1286.  
  1287. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1288.     hpcd->ResumeCallback(hpcd);
  1289. #else
  1290.     HAL_PCD_ResumeCallback(hpcd);
  1291. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1292.  
  1293.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP);
  1294.   }
  1295.  
  1296.   if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_SUSP))
  1297.   {
  1298.     /* WA: To Clear Wakeup flag if raised with suspend signal */
  1299.  
  1300.     /* Store Endpoint register */
  1301.     for (i = 0U; i < 8U; i++)
  1302.     {
  1303.       store_ep[i] = PCD_GET_ENDPOINT(hpcd->Instance, i);
  1304.     }
  1305.  
  1306.     /* FORCE RESET */
  1307.     hpcd->Instance->CNTR |= (uint16_t)(USB_CNTR_FRES);
  1308.  
  1309.     /* CLEAR RESET */
  1310.     hpcd->Instance->CNTR &= (uint16_t)(~USB_CNTR_FRES);
  1311.  
  1312.     /* wait for reset flag in ISTR */
  1313.     while ((hpcd->Instance->ISTR & USB_ISTR_RESET) == 0U)
  1314.     {
  1315.     }
  1316.  
  1317.     /* Clear Reset Flag */
  1318.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET);
  1319.  
  1320.     /* Restore Registre */
  1321.     for (i = 0U; i < 8U; i++)
  1322.     {
  1323.       PCD_SET_ENDPOINT(hpcd->Instance, i, store_ep[i]);
  1324.     }
  1325.  
  1326.     /* Force low-power mode in the macrocell */
  1327.     hpcd->Instance->CNTR |= (uint16_t)USB_CNTR_FSUSP;
  1328.  
  1329.     /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
  1330.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SUSP);
  1331.  
  1332.     hpcd->Instance->CNTR |= (uint16_t)USB_CNTR_LP_MODE;
  1333.  
  1334. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1335.     hpcd->SuspendCallback(hpcd);
  1336. #else
  1337.     HAL_PCD_SuspendCallback(hpcd);
  1338. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1339.   }
  1340.  
  1341.   if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_SOF))
  1342.   {
  1343.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SOF);
  1344.  
  1345. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1346.     hpcd->SOFCallback(hpcd);
  1347. #else
  1348.     HAL_PCD_SOFCallback(hpcd);
  1349. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1350.   }
  1351.  
  1352.   if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_ESOF))
  1353.   {
  1354.     /* clear ESOF flag in ISTR */
  1355.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ESOF);
  1356.   }
  1357. }
  1358.  
  1359.  
  1360. /**
  1361.   * @brief  Handles PCD Wakeup interrupt request.
  1362.   * @param  hpcd PCD handle
  1363.   * @retval HAL status
  1364.   */
  1365. void HAL_PCD_WKUP_IRQHandler(PCD_HandleTypeDef *hpcd)
  1366. {
  1367.   /* Clear EXTI pending Bit */
  1368.   __HAL_USB_WAKEUP_EXTI_CLEAR_FLAG();
  1369. }
  1370. #endif /* defined (USB) */
  1371.  
  1372. /**
  1373.   * @brief  Data OUT stage callback.
  1374.   * @param  hpcd PCD handle
  1375.   * @param  epnum endpoint number
  1376.   * @retval None
  1377.   */
  1378. __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  1379. {
  1380.   /* Prevent unused argument(s) compilation warning */
  1381.   UNUSED(hpcd);
  1382.   UNUSED(epnum);
  1383.  
  1384.   /* NOTE : This function should not be modified, when the callback is needed,
  1385.             the HAL_PCD_DataOutStageCallback could be implemented in the user file
  1386.    */
  1387. }
  1388.  
  1389. /**
  1390.   * @brief  Data IN stage callback
  1391.   * @param  hpcd PCD handle
  1392.   * @param  epnum endpoint number
  1393.   * @retval None
  1394.   */
  1395. __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  1396. {
  1397.   /* Prevent unused argument(s) compilation warning */
  1398.   UNUSED(hpcd);
  1399.   UNUSED(epnum);
  1400.  
  1401.   /* NOTE : This function should not be modified, when the callback is needed,
  1402.             the HAL_PCD_DataInStageCallback could be implemented in the user file
  1403.    */
  1404. }
  1405. /**
  1406.   * @brief  Setup stage callback
  1407.   * @param  hpcd PCD handle
  1408.   * @retval None
  1409.   */
  1410. __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
  1411. {
  1412.   /* Prevent unused argument(s) compilation warning */
  1413.   UNUSED(hpcd);
  1414.  
  1415.   /* NOTE : This function should not be modified, when the callback is needed,
  1416.             the HAL_PCD_SetupStageCallback could be implemented in the user file
  1417.    */
  1418. }
  1419.  
  1420. /**
  1421.   * @brief  USB Start Of Frame callback.
  1422.   * @param  hpcd PCD handle
  1423.   * @retval None
  1424.   */
  1425. __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
  1426. {
  1427.   /* Prevent unused argument(s) compilation warning */
  1428.   UNUSED(hpcd);
  1429.  
  1430.   /* NOTE : This function should not be modified, when the callback is needed,
  1431.             the HAL_PCD_SOFCallback could be implemented in the user file
  1432.    */
  1433. }
  1434.  
  1435. /**
  1436.   * @brief  USB Reset callback.
  1437.   * @param  hpcd PCD handle
  1438.   * @retval None
  1439.   */
  1440. __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
  1441. {
  1442.   /* Prevent unused argument(s) compilation warning */
  1443.   UNUSED(hpcd);
  1444.  
  1445.   /* NOTE : This function should not be modified, when the callback is needed,
  1446.             the HAL_PCD_ResetCallback could be implemented in the user file
  1447.    */
  1448. }
  1449.  
  1450. /**
  1451.   * @brief  Suspend event callback.
  1452.   * @param  hpcd PCD handle
  1453.   * @retval None
  1454.   */
  1455. __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
  1456. {
  1457.   /* Prevent unused argument(s) compilation warning */
  1458.   UNUSED(hpcd);
  1459.  
  1460.   /* NOTE : This function should not be modified, when the callback is needed,
  1461.             the HAL_PCD_SuspendCallback could be implemented in the user file
  1462.    */
  1463. }
  1464.  
  1465. /**
  1466.   * @brief  Resume event callback.
  1467.   * @param  hpcd PCD handle
  1468.   * @retval None
  1469.   */
  1470. __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
  1471. {
  1472.   /* Prevent unused argument(s) compilation warning */
  1473.   UNUSED(hpcd);
  1474.  
  1475.   /* NOTE : This function should not be modified, when the callback is needed,
  1476.             the HAL_PCD_ResumeCallback could be implemented in the user file
  1477.    */
  1478. }
  1479.  
  1480. /**
  1481.   * @brief  Incomplete ISO OUT callback.
  1482.   * @param  hpcd PCD handle
  1483.   * @param  epnum endpoint number
  1484.   * @retval None
  1485.   */
  1486. __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  1487. {
  1488.   /* Prevent unused argument(s) compilation warning */
  1489.   UNUSED(hpcd);
  1490.   UNUSED(epnum);
  1491.  
  1492.   /* NOTE : This function should not be modified, when the callback is needed,
  1493.             the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file
  1494.    */
  1495. }
  1496.  
  1497. /**
  1498.   * @brief  Incomplete ISO IN callback.
  1499.   * @param  hpcd PCD handle
  1500.   * @param  epnum endpoint number
  1501.   * @retval None
  1502.   */
  1503. __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  1504. {
  1505.   /* Prevent unused argument(s) compilation warning */
  1506.   UNUSED(hpcd);
  1507.   UNUSED(epnum);
  1508.  
  1509.   /* NOTE : This function should not be modified, when the callback is needed,
  1510.             the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file
  1511.    */
  1512. }
  1513.  
  1514. /**
  1515.   * @brief  Connection event callback.
  1516.   * @param  hpcd PCD handle
  1517.   * @retval None
  1518.   */
  1519. __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
  1520. {
  1521.   /* Prevent unused argument(s) compilation warning */
  1522.   UNUSED(hpcd);
  1523.  
  1524.   /* NOTE : This function should not be modified, when the callback is needed,
  1525.             the HAL_PCD_ConnectCallback could be implemented in the user file
  1526.    */
  1527. }
  1528.  
  1529. /**
  1530.   * @brief  Disconnection event callback.
  1531.   * @param  hpcd PCD handle
  1532.   * @retval None
  1533.   */
  1534. __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
  1535. {
  1536.   /* Prevent unused argument(s) compilation warning */
  1537.   UNUSED(hpcd);
  1538.  
  1539.   /* NOTE : This function should not be modified, when the callback is needed,
  1540.             the HAL_PCD_DisconnectCallback could be implemented in the user file
  1541.    */
  1542. }
  1543.  
  1544. /**
  1545.   * @}
  1546.   */
  1547.  
  1548. /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
  1549.   *  @brief   management functions
  1550.   *
  1551. @verbatim
  1552.  ===============================================================================
  1553.                       ##### Peripheral Control functions #####
  1554.  ===============================================================================
  1555.     [..]
  1556.     This subsection provides a set of functions allowing to control the PCD data
  1557.     transfers.
  1558.  
  1559. @endverbatim
  1560.   * @{
  1561.   */
  1562.  
  1563. /**
  1564.   * @brief  Connect the USB device
  1565.   * @param  hpcd PCD handle
  1566.   * @retval HAL status
  1567.   */
  1568. HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd)
  1569. {
  1570.   __HAL_LOCK(hpcd);
  1571.  
  1572. #if defined (USB)
  1573.   HAL_PCDEx_SetConnectionState(hpcd, 1U);
  1574. #endif /* defined (USB) */
  1575.  
  1576.   (void)USB_DevConnect(hpcd->Instance);
  1577.   __HAL_UNLOCK(hpcd);
  1578.  
  1579.   return HAL_OK;
  1580. }
  1581.  
  1582. /**
  1583.   * @brief  Disconnect the USB device.
  1584.   * @param  hpcd PCD handle
  1585.   * @retval HAL status
  1586.   */
  1587. HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd)
  1588. {
  1589.   __HAL_LOCK(hpcd);
  1590.  
  1591. #if defined (USB)
  1592.   HAL_PCDEx_SetConnectionState(hpcd, 0U);
  1593. #endif /* defined (USB) */
  1594.  
  1595.   (void)USB_DevDisconnect(hpcd->Instance);
  1596.   __HAL_UNLOCK(hpcd);
  1597.  
  1598.   return HAL_OK;
  1599. }
  1600.  
  1601. /**
  1602.   * @brief  Set the USB Device address.
  1603.   * @param  hpcd PCD handle
  1604.   * @param  address new device address
  1605.   * @retval HAL status
  1606.   */
  1607. HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)
  1608. {
  1609.   __HAL_LOCK(hpcd);
  1610.   hpcd->USB_Address = address;
  1611.   (void)USB_SetDevAddress(hpcd->Instance, address);
  1612.   __HAL_UNLOCK(hpcd);
  1613.  
  1614.   return HAL_OK;
  1615. }
  1616. /**
  1617.   * @brief  Open and configure an endpoint.
  1618.   * @param  hpcd PCD handle
  1619.   * @param  ep_addr endpoint address
  1620.   * @param  ep_mps endpoint max packet size
  1621.   * @param  ep_type endpoint type
  1622.   * @retval HAL status
  1623.   */
  1624. HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr,
  1625.                                   uint16_t ep_mps, uint8_t ep_type)
  1626. {
  1627.   HAL_StatusTypeDef  ret = HAL_OK;
  1628.   PCD_EPTypeDef *ep;
  1629.  
  1630.   if ((ep_addr & 0x80U) == 0x80U)
  1631.   {
  1632.     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1633.     ep->is_in = 1U;
  1634.   }
  1635.   else
  1636.   {
  1637.     ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1638.     ep->is_in = 0U;
  1639.   }
  1640.  
  1641.   ep->num = ep_addr & EP_ADDR_MSK;
  1642.   ep->maxpacket = ep_mps;
  1643.   ep->type = ep_type;
  1644.  
  1645.   if (ep->is_in != 0U)
  1646.   {
  1647.     /* Assign a Tx FIFO */
  1648.     ep->tx_fifo_num = ep->num;
  1649.   }
  1650.   /* Set initial data PID. */
  1651.   if (ep_type == EP_TYPE_BULK)
  1652.   {
  1653.     ep->data_pid_start = 0U;
  1654.   }
  1655.  
  1656.   __HAL_LOCK(hpcd);
  1657.   (void)USB_ActivateEndpoint(hpcd->Instance, ep);
  1658.   __HAL_UNLOCK(hpcd);
  1659.  
  1660.   return ret;
  1661. }
  1662.  
  1663. /**
  1664.   * @brief  Deactivate an endpoint.
  1665.   * @param  hpcd PCD handle
  1666.   * @param  ep_addr endpoint address
  1667.   * @retval HAL status
  1668.   */
  1669. HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1670. {
  1671.   PCD_EPTypeDef *ep;
  1672.  
  1673.   if ((ep_addr & 0x80U) == 0x80U)
  1674.   {
  1675.     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1676.     ep->is_in = 1U;
  1677.   }
  1678.   else
  1679.   {
  1680.     ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1681.     ep->is_in = 0U;
  1682.   }
  1683.   ep->num   = ep_addr & EP_ADDR_MSK;
  1684.  
  1685.   __HAL_LOCK(hpcd);
  1686.   (void)USB_DeactivateEndpoint(hpcd->Instance, ep);
  1687.   __HAL_UNLOCK(hpcd);
  1688.   return HAL_OK;
  1689. }
  1690.  
  1691.  
  1692. /**
  1693.   * @brief  Receive an amount of data.
  1694.   * @param  hpcd PCD handle
  1695.   * @param  ep_addr endpoint address
  1696.   * @param  pBuf pointer to the reception buffer
  1697.   * @param  len amount of data to be received
  1698.   * @retval HAL status
  1699.   */
  1700. HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
  1701. {
  1702.   PCD_EPTypeDef *ep;
  1703.  
  1704.   ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1705.  
  1706.   /*setup and start the Xfer */
  1707.   ep->xfer_buff = pBuf;
  1708.   ep->xfer_len = len;
  1709.   ep->xfer_count = 0U;
  1710.   ep->is_in = 0U;
  1711.   ep->num = ep_addr & EP_ADDR_MSK;
  1712.  
  1713.   if ((ep_addr & EP_ADDR_MSK) == 0U)
  1714.   {
  1715.     (void)USB_EP0StartXfer(hpcd->Instance, ep);
  1716.   }
  1717.   else
  1718.   {
  1719.     (void)USB_EPStartXfer(hpcd->Instance, ep);
  1720.   }
  1721.  
  1722.   return HAL_OK;
  1723. }
  1724.  
  1725. /**
  1726.   * @brief  Get Received Data Size
  1727.   * @param  hpcd PCD handle
  1728.   * @param  ep_addr endpoint address
  1729.   * @retval Data Size
  1730.   */
  1731. uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1732. {
  1733.   return hpcd->OUT_ep[ep_addr & EP_ADDR_MSK].xfer_count;
  1734. }
  1735. /**
  1736.   * @brief  Send an amount of data
  1737.   * @param  hpcd PCD handle
  1738.   * @param  ep_addr endpoint address
  1739.   * @param  pBuf pointer to the transmission buffer
  1740.   * @param  len amount of data to be sent
  1741.   * @retval HAL status
  1742.   */
  1743. HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
  1744. {
  1745.   PCD_EPTypeDef *ep;
  1746.  
  1747.   ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1748.  
  1749.   /*setup and start the Xfer */
  1750.   ep->xfer_buff = pBuf;
  1751.   ep->xfer_len = len;
  1752. #if defined (USB)
  1753.   ep->xfer_fill_db = 1U;
  1754.   ep->xfer_len_db = len;
  1755. #endif /* defined (USB) */
  1756.   ep->xfer_count = 0U;
  1757.   ep->is_in = 1U;
  1758.   ep->num = ep_addr & EP_ADDR_MSK;
  1759.  
  1760.   if ((ep_addr & EP_ADDR_MSK) == 0U)
  1761.   {
  1762.     (void)USB_EP0StartXfer(hpcd->Instance, ep);
  1763.   }
  1764.   else
  1765.   {
  1766.     (void)USB_EPStartXfer(hpcd->Instance, ep);
  1767.   }
  1768.  
  1769.   return HAL_OK;
  1770. }
  1771.  
  1772. /**
  1773.   * @brief  Set a STALL condition over an endpoint
  1774.   * @param  hpcd PCD handle
  1775.   * @param  ep_addr endpoint address
  1776.   * @retval HAL status
  1777.   */
  1778. HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1779. {
  1780.   PCD_EPTypeDef *ep;
  1781.  
  1782.   if (((uint32_t)ep_addr & EP_ADDR_MSK) > hpcd->Init.dev_endpoints)
  1783.   {
  1784.     return HAL_ERROR;
  1785.   }
  1786.  
  1787.   if ((0x80U & ep_addr) == 0x80U)
  1788.   {
  1789.     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1790.     ep->is_in = 1U;
  1791.   }
  1792.   else
  1793.   {
  1794.     ep = &hpcd->OUT_ep[ep_addr];
  1795.     ep->is_in = 0U;
  1796.   }
  1797.  
  1798.   ep->is_stall = 1U;
  1799.   ep->num = ep_addr & EP_ADDR_MSK;
  1800.  
  1801.   __HAL_LOCK(hpcd);
  1802.  
  1803.   (void)USB_EPSetStall(hpcd->Instance, ep);
  1804.  
  1805.   if ((ep_addr & EP_ADDR_MSK) == 0U)
  1806.   {
  1807.     (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
  1808.   }
  1809.  
  1810.   __HAL_UNLOCK(hpcd);
  1811.  
  1812.   return HAL_OK;
  1813. }
  1814.  
  1815. /**
  1816.   * @brief  Clear a STALL condition over in an endpoint
  1817.   * @param  hpcd PCD handle
  1818.   * @param  ep_addr endpoint address
  1819.   * @retval HAL status
  1820.   */
  1821. HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1822. {
  1823.   PCD_EPTypeDef *ep;
  1824.  
  1825.   if (((uint32_t)ep_addr & 0x0FU) > hpcd->Init.dev_endpoints)
  1826.   {
  1827.     return HAL_ERROR;
  1828.   }
  1829.  
  1830.   if ((0x80U & ep_addr) == 0x80U)
  1831.   {
  1832.     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1833.     ep->is_in = 1U;
  1834.   }
  1835.   else
  1836.   {
  1837.     ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1838.     ep->is_in = 0U;
  1839.   }
  1840.  
  1841.   ep->is_stall = 0U;
  1842.   ep->num = ep_addr & EP_ADDR_MSK;
  1843.  
  1844.   __HAL_LOCK(hpcd);
  1845.   (void)USB_EPClearStall(hpcd->Instance, ep);
  1846.   __HAL_UNLOCK(hpcd);
  1847.  
  1848.   return HAL_OK;
  1849. }
  1850.  
  1851. /**
  1852.   * @brief  Flush an endpoint
  1853.   * @param  hpcd PCD handle
  1854.   * @param  ep_addr endpoint address
  1855.   * @retval HAL status
  1856.   */
  1857. HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1858. {
  1859.   __HAL_LOCK(hpcd);
  1860.  
  1861.   if ((ep_addr & 0x80U) == 0x80U)
  1862.   {
  1863.     (void)USB_FlushTxFifo(hpcd->Instance, (uint32_t)ep_addr & EP_ADDR_MSK);
  1864.   }
  1865.   else
  1866.   {
  1867.     (void)USB_FlushRxFifo(hpcd->Instance);
  1868.   }
  1869.  
  1870.   __HAL_UNLOCK(hpcd);
  1871.  
  1872.   return HAL_OK;
  1873. }
  1874.  
  1875. /**
  1876.   * @brief  Activate remote wakeup signalling
  1877.   * @param  hpcd PCD handle
  1878.   * @retval HAL status
  1879.   */
  1880. HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
  1881. {
  1882.   return (USB_ActivateRemoteWakeup(hpcd->Instance));
  1883. }
  1884.  
  1885. /**
  1886.   * @brief  De-activate remote wakeup signalling.
  1887.   * @param  hpcd PCD handle
  1888.   * @retval HAL status
  1889.   */
  1890. HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
  1891. {
  1892.   return (USB_DeActivateRemoteWakeup(hpcd->Instance));
  1893. }
  1894.  
  1895. /**
  1896.   * @}
  1897.   */
  1898.  
  1899. /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions
  1900.   *  @brief   Peripheral State functions
  1901.   *
  1902. @verbatim
  1903.  ===============================================================================
  1904.                       ##### Peripheral State functions #####
  1905.  ===============================================================================
  1906.     [..]
  1907.     This subsection permits to get in run-time the status of the peripheral
  1908.     and the data flow.
  1909.  
  1910. @endverbatim
  1911.   * @{
  1912.   */
  1913.  
  1914. /**
  1915.   * @brief  Return the PCD handle state.
  1916.   * @param  hpcd PCD handle
  1917.   * @retval HAL state
  1918.   */
  1919. PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd)
  1920. {
  1921.   return hpcd->State;
  1922. }
  1923.  
  1924. /**
  1925.   * @}
  1926.   */
  1927.  
  1928. /**
  1929.   * @}
  1930.   */
  1931.  
  1932. /* Private functions ---------------------------------------------------------*/
  1933. /** @addtogroup PCD_Private_Functions
  1934.   * @{
  1935.   */
  1936. #if defined (USB_OTG_FS)
  1937. /**
  1938.   * @brief  Check FIFO for the next packet to be loaded.
  1939.   * @param  hpcd PCD handle
  1940.   * @param  epnum endpoint number
  1941.   * @retval HAL status
  1942.   */
  1943. static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum)
  1944. {
  1945.   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
  1946.   uint32_t USBx_BASE = (uint32_t)USBx;
  1947.   USB_OTG_EPTypeDef *ep;
  1948.   uint32_t len;
  1949.   uint32_t len32b;
  1950.   uint32_t fifoemptymsk;
  1951.  
  1952.   ep = &hpcd->IN_ep[epnum];
  1953.  
  1954.   if (ep->xfer_count > ep->xfer_len)
  1955.   {
  1956.     return HAL_ERROR;
  1957.   }
  1958.  
  1959.   len = ep->xfer_len - ep->xfer_count;
  1960.  
  1961.   if (len > ep->maxpacket)
  1962.   {
  1963.     len = ep->maxpacket;
  1964.   }
  1965.  
  1966.   len32b = (len + 3U) / 4U;
  1967.  
  1968.   while (((USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= len32b) &&
  1969.          (ep->xfer_count < ep->xfer_len) && (ep->xfer_len != 0U))
  1970.   {
  1971.     /* Write the FIFO */
  1972.     len = ep->xfer_len - ep->xfer_count;
  1973.  
  1974.     if (len > ep->maxpacket)
  1975.     {
  1976.       len = ep->maxpacket;
  1977.     }
  1978.     len32b = (len + 3U) / 4U;
  1979.  
  1980.     (void)USB_WritePacket(USBx, ep->xfer_buff, (uint8_t)epnum, (uint16_t)len);
  1981.  
  1982.     ep->xfer_buff  += len;
  1983.     ep->xfer_count += len;
  1984.   }
  1985.  
  1986.   if (ep->xfer_len <= ep->xfer_count)
  1987.   {
  1988.     fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK));
  1989.     USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
  1990.   }
  1991.  
  1992.   return HAL_OK;
  1993. }
  1994.  
  1995.  
  1996. /**
  1997.   * @brief  process EP OUT transfer complete interrupt.
  1998.   * @param  hpcd PCD handle
  1999.   * @param  epnum endpoint number
  2000.   * @retval HAL status
  2001.   */
  2002. static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef *hpcd, uint32_t epnum)
  2003. {
  2004.   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
  2005.   uint32_t USBx_BASE = (uint32_t)USBx;
  2006.   uint32_t gSNPSiD = *(__IO uint32_t *)(&USBx->CID + 0x1U);
  2007.   uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT;
  2008.  
  2009.   if (gSNPSiD == USB_OTG_CORE_ID_310A)
  2010.   {
  2011.     /* StupPktRcvd = 1 this is a setup packet */
  2012.     if ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX)
  2013.     {
  2014.       CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
  2015.     }
  2016.     else
  2017.     {
  2018.       if ((DoepintReg & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR)
  2019.       {
  2020.         CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
  2021.       }
  2022.  
  2023. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  2024.       hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
  2025. #else
  2026.       HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
  2027. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  2028.     }
  2029.   }
  2030.   else
  2031.   {
  2032. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  2033.     hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
  2034. #else
  2035.     HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
  2036. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  2037.   }
  2038.  
  2039.   return HAL_OK;
  2040. }
  2041.  
  2042.  
  2043. /**
  2044.   * @brief  process EP OUT setup packet received interrupt.
  2045.   * @param  hpcd PCD handle
  2046.   * @param  epnum endpoint number
  2047.   * @retval HAL status
  2048.   */
  2049. static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef *hpcd, uint32_t epnum)
  2050. {
  2051.   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
  2052.   uint32_t USBx_BASE = (uint32_t)USBx;
  2053.   uint32_t gSNPSiD = *(__IO uint32_t *)(&USBx->CID + 0x1U);
  2054.   uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT;
  2055.  
  2056.   if ((gSNPSiD > USB_OTG_CORE_ID_300A) &&
  2057.       ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX))
  2058.   {
  2059.     CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
  2060.   }
  2061.  
  2062.   /* Inform the upper layer that a setup packet is available */
  2063. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  2064.   hpcd->SetupStageCallback(hpcd);
  2065. #else
  2066.   HAL_PCD_SetupStageCallback(hpcd);
  2067. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  2068.  
  2069.   return HAL_OK;
  2070. }
  2071. #endif /* defined (USB_OTG_FS) */
  2072.  
  2073. #if defined (USB)
  2074. /**
  2075.   * @brief  This function handles PCD Endpoint interrupt request.
  2076.   * @param  hpcd PCD handle
  2077.   * @retval HAL status
  2078.   */
  2079. static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
  2080. {
  2081.   PCD_EPTypeDef *ep;
  2082.   uint16_t count, wIstr, wEPVal, TxByteNbre;
  2083.   uint8_t epindex;
  2084.  
  2085.   /* stay in loop while pending interrupts */
  2086.   while ((hpcd->Instance->ISTR & USB_ISTR_CTR) != 0U)
  2087.   {
  2088.     wIstr = hpcd->Instance->ISTR;
  2089.  
  2090.     /* extract highest priority endpoint number */
  2091.     epindex = (uint8_t)(wIstr & USB_ISTR_EP_ID);
  2092.  
  2093.     if (epindex == 0U)
  2094.     {
  2095.       /* Decode and service control endpoint interrupt */
  2096.  
  2097.       /* DIR bit = origin of the interrupt */
  2098.       if ((wIstr & USB_ISTR_DIR) == 0U)
  2099.       {
  2100.         /* DIR = 0 */
  2101.  
  2102.         /* DIR = 0 => IN  int */
  2103.         /* DIR = 0 implies that (EP_CTR_TX = 1) always */
  2104.         PCD_CLEAR_TX_EP_CTR(hpcd->Instance, PCD_ENDP0);
  2105.         ep = &hpcd->IN_ep[0];
  2106.  
  2107.         ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
  2108.         ep->xfer_buff += ep->xfer_count;
  2109.  
  2110.         /* TX COMPLETE */
  2111. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  2112.         hpcd->DataInStageCallback(hpcd, 0U);
  2113. #else
  2114.         HAL_PCD_DataInStageCallback(hpcd, 0U);
  2115. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  2116.  
  2117.         if ((hpcd->USB_Address > 0U) && (ep->xfer_len == 0U))
  2118.         {
  2119.           hpcd->Instance->DADDR = ((uint16_t)hpcd->USB_Address | USB_DADDR_EF);
  2120.           hpcd->USB_Address = 0U;
  2121.         }
  2122.       }
  2123.       else
  2124.       {
  2125.         /* DIR = 1 */
  2126.  
  2127.         /* DIR = 1 & CTR_RX => SETUP or OUT int */
  2128.         /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */
  2129.         ep = &hpcd->OUT_ep[0];
  2130.         wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0);
  2131.  
  2132.         if ((wEPVal & USB_EP_SETUP) != 0U)
  2133.         {
  2134.           /* Get SETUP Packet */
  2135.           ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
  2136.  
  2137.           USB_ReadPMA(hpcd->Instance, (uint8_t *)hpcd->Setup,
  2138.                       ep->pmaadress, (uint16_t)ep->xfer_count);
  2139.  
  2140.           /* SETUP bit kept frozen while CTR_RX = 1 */
  2141.           PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
  2142.  
  2143.           /* Process SETUP Packet*/
  2144. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  2145.           hpcd->SetupStageCallback(hpcd);
  2146. #else
  2147.           HAL_PCD_SetupStageCallback(hpcd);
  2148. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  2149.         }
  2150.         else if ((wEPVal & USB_EP_CTR_RX) != 0U)
  2151.         {
  2152.           PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
  2153.  
  2154.           /* Get Control Data OUT Packet */
  2155.           ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
  2156.  
  2157.           if ((ep->xfer_count != 0U) && (ep->xfer_buff != 0U))
  2158.           {
  2159.             USB_ReadPMA(hpcd->Instance, ep->xfer_buff,
  2160.                         ep->pmaadress, (uint16_t)ep->xfer_count);
  2161.  
  2162.             ep->xfer_buff += ep->xfer_count;
  2163.  
  2164.             /* Process Control Data OUT Packet */
  2165. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  2166.             hpcd->DataOutStageCallback(hpcd, 0U);
  2167. #else
  2168.             HAL_PCD_DataOutStageCallback(hpcd, 0U);
  2169. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  2170.           }
  2171.  
  2172.           PCD_SET_EP_RX_CNT(hpcd->Instance, PCD_ENDP0, ep->maxpacket);
  2173.           PCD_SET_EP_RX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_RX_VALID);
  2174.         }
  2175.       }
  2176.     }
  2177.     else
  2178.     {
  2179.       /* Decode and service non control endpoints interrupt */
  2180.       /* process related endpoint register */
  2181.       wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, epindex);
  2182.  
  2183.       if ((wEPVal & USB_EP_CTR_RX) != 0U)
  2184.       {
  2185.         /* clear int flag */
  2186.         PCD_CLEAR_RX_EP_CTR(hpcd->Instance, epindex);
  2187.         ep = &hpcd->OUT_ep[epindex];
  2188.  
  2189.         /* OUT Single Buffering */
  2190.         if (ep->doublebuffer == 0U)
  2191.         {
  2192.           count = (uint16_t)PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
  2193.  
  2194.           if (count != 0U)
  2195.           {
  2196.             USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, count);
  2197.           }
  2198.         }
  2199.         else
  2200.         {
  2201.           /* manage double buffer bulk out */
  2202.           if (ep->type == EP_TYPE_BULK)
  2203.           {
  2204.             count = HAL_PCD_EP_DB_Receive(hpcd, ep, wEPVal);
  2205.           }
  2206.           else /* manage double buffer iso out */
  2207.           {
  2208.             /* free EP OUT Buffer */
  2209.             PCD_FreeUserBuffer(hpcd->Instance, ep->num, 0U);
  2210.  
  2211.             if ((PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_RX) != 0U)
  2212.             {
  2213.               /* read from endpoint BUF0Addr buffer */
  2214.               count = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
  2215.  
  2216.               if (count != 0U)
  2217.               {
  2218.                 USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count);
  2219.               }
  2220.             }
  2221.             else
  2222.             {
  2223.               /* read from endpoint BUF1Addr buffer */
  2224.               count = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
  2225.  
  2226.               if (count != 0U)
  2227.               {
  2228.                 USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count);
  2229.               }
  2230.             }
  2231.           }
  2232.         }
  2233.         /* multi-packet on the NON control OUT endpoint */
  2234.         ep->xfer_count += count;
  2235.         ep->xfer_buff += count;
  2236.  
  2237.         if ((ep->xfer_len == 0U) || (count < ep->maxpacket))
  2238.         {
  2239.           /* RX COMPLETE */
  2240. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  2241.           hpcd->DataOutStageCallback(hpcd, ep->num);
  2242. #else
  2243.           HAL_PCD_DataOutStageCallback(hpcd, ep->num);
  2244. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  2245.         }
  2246.         else
  2247.         {
  2248.           (void) USB_EPStartXfer(hpcd->Instance, ep);
  2249.         }
  2250.  
  2251.       }
  2252.  
  2253.       if ((wEPVal & USB_EP_CTR_TX) != 0U)
  2254.       {
  2255.         ep = &hpcd->IN_ep[epindex];
  2256.  
  2257.         /* clear int flag */
  2258.         PCD_CLEAR_TX_EP_CTR(hpcd->Instance, epindex);
  2259.  
  2260.         /* Manage all non bulk transaction or Bulk Single Buffer Transaction */
  2261.         if ((ep->type != EP_TYPE_BULK) ||
  2262.             ((ep->type == EP_TYPE_BULK) && ((wEPVal & USB_EP_KIND) == 0U)))
  2263.         {
  2264.           /* multi-packet on the NON control IN endpoint */
  2265.           TxByteNbre = (uint16_t)PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
  2266.  
  2267.           if (ep->xfer_len > TxByteNbre)
  2268.           {
  2269.             ep->xfer_len -= TxByteNbre;
  2270.           }
  2271.           else
  2272.           {
  2273.             ep->xfer_len = 0U;
  2274.           }
  2275.  
  2276.           /* Zero Length Packet? */
  2277.           if (ep->xfer_len == 0U)
  2278.           {
  2279.             /* TX COMPLETE */
  2280. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  2281.             hpcd->DataInStageCallback(hpcd, ep->num);
  2282. #else
  2283.             HAL_PCD_DataInStageCallback(hpcd, ep->num);
  2284. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  2285.           }
  2286.           else
  2287.           {
  2288.             /* Transfer is not yet Done */
  2289.             ep->xfer_buff += TxByteNbre;
  2290.             ep->xfer_count += TxByteNbre;
  2291.             (void)USB_EPStartXfer(hpcd->Instance, ep);
  2292.           }
  2293.         }
  2294.         /* bulk in double buffer enable in case of transferLen> Ep_Mps */
  2295.         else
  2296.         {
  2297.           (void)HAL_PCD_EP_DB_Transmit(hpcd, ep, wEPVal);
  2298.         }
  2299.       }
  2300.     }
  2301.   }
  2302.  
  2303.   return HAL_OK;
  2304. }
  2305.  
  2306.  
  2307. /**
  2308.   * @brief  Manage double buffer bulk out transaction from ISR
  2309.   * @param  hpcd PCD handle
  2310.   * @param  ep current endpoint handle
  2311.   * @param  wEPVal Last snapshot of EPRx register value taken in ISR
  2312.   * @retval HAL status
  2313.   */
  2314. static uint16_t HAL_PCD_EP_DB_Receive(PCD_HandleTypeDef *hpcd,
  2315.                                       PCD_EPTypeDef *ep, uint16_t wEPVal)
  2316. {
  2317.   uint16_t count;
  2318.  
  2319.   /* Manage Buffer0 OUT */
  2320.   if ((wEPVal & USB_EP_DTOG_RX) != 0U)
  2321.   {
  2322.     /* Get count of received Data on buffer0 */
  2323.     count = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
  2324.  
  2325.     if (ep->xfer_len >= count)
  2326.     {
  2327.       ep->xfer_len -= count;
  2328.     }
  2329.     else
  2330.     {
  2331.       ep->xfer_len = 0U;
  2332.     }
  2333.  
  2334.     if (ep->xfer_len == 0U)
  2335.     {
  2336.       /* set NAK to OUT endpoint since double buffer is enabled */
  2337.       PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_NAK);
  2338.     }
  2339.  
  2340.     /* Check if Buffer1 is in blocked sate which requires to toggle */
  2341.     if ((wEPVal & USB_EP_DTOG_TX) != 0U)
  2342.     {
  2343.       PCD_FreeUserBuffer(hpcd->Instance, ep->num, 0U);
  2344.     }
  2345.  
  2346.     if (count != 0U)
  2347.     {
  2348.       USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count);
  2349.     }
  2350.   }
  2351.   /* Manage Buffer 1 DTOG_RX=0 */
  2352.   else
  2353.   {
  2354.     /* Get count of received data */
  2355.     count = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
  2356.  
  2357.     if (ep->xfer_len >= count)
  2358.     {
  2359.       ep->xfer_len -= count;
  2360.     }
  2361.     else
  2362.     {
  2363.       ep->xfer_len = 0U;
  2364.     }
  2365.  
  2366.     if (ep->xfer_len == 0U)
  2367.     {
  2368.       /* set NAK on the current endpoint */
  2369.       PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_NAK);
  2370.     }
  2371.  
  2372.     /*Need to FreeUser Buffer*/
  2373.     if ((wEPVal & USB_EP_DTOG_TX) == 0U)
  2374.     {
  2375.       PCD_FreeUserBuffer(hpcd->Instance, ep->num, 0U);
  2376.     }
  2377.  
  2378.     if (count != 0U)
  2379.     {
  2380.       USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count);
  2381.     }
  2382.   }
  2383.  
  2384.   return count;
  2385. }
  2386.  
  2387.  
  2388. /**
  2389.   * @brief  Manage double buffer bulk IN transaction from ISR
  2390.   * @param  hpcd PCD handle
  2391.   * @param  ep current endpoint handle
  2392.   * @param  wEPVal Last snapshot of EPRx register value taken in ISR
  2393.   * @retval HAL status
  2394.   */
  2395. static HAL_StatusTypeDef HAL_PCD_EP_DB_Transmit(PCD_HandleTypeDef *hpcd,
  2396.                                                 PCD_EPTypeDef *ep, uint16_t wEPVal)
  2397. {
  2398.   uint32_t len;
  2399.   uint16_t TxByteNbre;
  2400.  
  2401.   /* Data Buffer0 ACK received */
  2402.   if ((wEPVal & USB_EP_DTOG_TX) != 0U)
  2403.   {
  2404.     /* multi-packet on the NON control IN endpoint */
  2405.     TxByteNbre = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
  2406.  
  2407.     if (ep->xfer_len > TxByteNbre)
  2408.     {
  2409.       ep->xfer_len -= TxByteNbre;
  2410.     }
  2411.     else
  2412.     {
  2413.       ep->xfer_len = 0U;
  2414.     }
  2415.     /* Transfer is completed */
  2416.     if (ep->xfer_len == 0U)
  2417.     {
  2418.       /* TX COMPLETE */
  2419. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  2420.       hpcd->DataInStageCallback(hpcd, ep->num);
  2421. #else
  2422.       HAL_PCD_DataInStageCallback(hpcd, ep->num);
  2423. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  2424.  
  2425.       if ((wEPVal & USB_EP_DTOG_RX) != 0U)
  2426.       {
  2427.         PCD_FreeUserBuffer(hpcd->Instance, ep->num, 1U);
  2428.       }
  2429.     }
  2430.     else /* Transfer is not yet Done */
  2431.     {
  2432.       /* need to Free USB Buff */
  2433.       if ((wEPVal & USB_EP_DTOG_RX) != 0U)
  2434.       {
  2435.         PCD_FreeUserBuffer(hpcd->Instance, ep->num, 1U);
  2436.       }
  2437.  
  2438.       /* Still there is data to Fill in the next Buffer */
  2439.       if (ep->xfer_fill_db == 1U)
  2440.       {
  2441.         ep->xfer_buff += TxByteNbre;
  2442.         ep->xfer_count += TxByteNbre;
  2443.  
  2444.         /* Calculate the len of the new buffer to fill */
  2445.         if (ep->xfer_len_db >= ep->maxpacket)
  2446.         {
  2447.           len = ep->maxpacket;
  2448.           ep->xfer_len_db -= len;
  2449.         }
  2450.         else if (ep->xfer_len_db == 0U)
  2451.         {
  2452.           len = TxByteNbre;
  2453.           ep->xfer_fill_db = 0U;
  2454.         }
  2455.         else
  2456.         {
  2457.           ep->xfer_fill_db = 0U;
  2458.           len = ep->xfer_len_db;
  2459.           ep->xfer_len_db = 0U;
  2460.         }
  2461.  
  2462.         /* Write remaining Data to Buffer */
  2463.         /* Set the Double buffer counter for pma buffer1 */
  2464.         PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, len);
  2465.  
  2466.         /* Copy user buffer to USB PMA */
  2467.         USB_WritePMA(hpcd->Instance, ep->xfer_buff,  ep->pmaaddr0, (uint16_t)len);
  2468.       }
  2469.     }
  2470.   }
  2471.   else /* Data Buffer1 ACK received */
  2472.   {
  2473.     /* multi-packet on the NON control IN endpoint */
  2474.     TxByteNbre = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
  2475.  
  2476.     if (ep->xfer_len >= TxByteNbre)
  2477.     {
  2478.       ep->xfer_len -= TxByteNbre;
  2479.     }
  2480.     else
  2481.     {
  2482.       ep->xfer_len = 0U;
  2483.     }
  2484.  
  2485.     /* Transfer is completed */
  2486.     if (ep->xfer_len == 0U)
  2487.     {
  2488.       /* TX COMPLETE */
  2489. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  2490.       hpcd->DataInStageCallback(hpcd, ep->num);
  2491. #else
  2492.       HAL_PCD_DataInStageCallback(hpcd, ep->num);
  2493. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  2494.  
  2495.       /*need to Free USB Buff*/
  2496.       if ((wEPVal & USB_EP_DTOG_RX) == 0U)
  2497.       {
  2498.         PCD_FreeUserBuffer(hpcd->Instance, ep->num, 1U);
  2499.       }
  2500.     }
  2501.     else /* Transfer is not yet Done */
  2502.     {
  2503.       /* need to Free USB Buff */
  2504.       if ((wEPVal & USB_EP_DTOG_RX) == 0U)
  2505.       {
  2506.         PCD_FreeUserBuffer(hpcd->Instance, ep->num, 1U);
  2507.       }
  2508.  
  2509.       /* Still there is data to Fill in the next Buffer */
  2510.       if (ep->xfer_fill_db == 1U)
  2511.       {
  2512.         ep->xfer_buff += TxByteNbre;
  2513.         ep->xfer_count += TxByteNbre;
  2514.  
  2515.         /* Calculate the len of the new buffer to fill */
  2516.         if (ep->xfer_len_db >= ep->maxpacket)
  2517.         {
  2518.           len = ep->maxpacket;
  2519.           ep->xfer_len_db -= len;
  2520.         }
  2521.         else if (ep->xfer_len_db == 0U)
  2522.         {
  2523.           len = TxByteNbre;
  2524.           ep->xfer_fill_db = 0U;
  2525.         }
  2526.         else
  2527.         {
  2528.           len = ep->xfer_len_db;
  2529.           ep->xfer_len_db = 0U;
  2530.           ep->xfer_fill_db = 0;
  2531.         }
  2532.  
  2533.         /* Set the Double buffer counter for pmabuffer1 */
  2534.         PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, len);
  2535.  
  2536.         /* Copy the user buffer to USB PMA */
  2537.         USB_WritePMA(hpcd->Instance, ep->xfer_buff,  ep->pmaaddr1, (uint16_t)len);
  2538.       }
  2539.     }
  2540.   }
  2541.  
  2542.   /*enable endpoint IN*/
  2543.   PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_VALID);
  2544.  
  2545.   return HAL_OK;
  2546. }
  2547.  
  2548. #endif /* defined (USB) */
  2549.  
  2550. /**
  2551.   * @}
  2552.   */
  2553. #endif /* defined (USB) || defined (USB_OTG_FS) */
  2554. #endif /* HAL_PCD_MODULE_ENABLED */
  2555.  
  2556. /**
  2557.   * @}
  2558.   */
  2559.  
  2560. /**
  2561.   * @}
  2562.   */
  2563.  
  2564. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
  2565.