Subversion Repositories FuelGauge

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /**
  2.   ******************************************************************************
  3.   * @file    stm32f0xx_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 "stm32f0xx_hal.h"
  58.  
  59. /** @addtogroup STM32F0xx_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)
  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.  
  90. static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd);
  91.  
  92. /**
  93.   * @}
  94.   */
  95.  
  96. /* Exported functions --------------------------------------------------------*/
  97. /** @defgroup PCD_Exported_Functions PCD Exported Functions
  98.   * @{
  99.   */
  100.  
  101. /** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
  102.  *  @brief    Initialization and Configuration functions
  103.  *
  104. @verbatim
  105.  ===============================================================================
  106.             ##### Initialization and de-initialization functions #####
  107.  ===============================================================================
  108.     [..]  This section provides functions allowing to:
  109.  
  110. @endverbatim
  111.   * @{
  112.   */
  113.  
  114. /**
  115.   * @brief  Initializes the PCD according to the specified
  116.   *         parameters in the PCD_InitTypeDef and initialize the associated handle.
  117.   * @param  hpcd PCD handle
  118.   * @retval HAL status
  119.   */
  120. HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd)
  121. {
  122.   uint8_t i;
  123.  
  124.   /* Check the PCD handle allocation */
  125.   if (hpcd == NULL)
  126.   {
  127.     return HAL_ERROR;
  128.   }
  129.  
  130.   /* Check the parameters */
  131.   assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance));
  132.  
  133.   if (hpcd->State == HAL_PCD_STATE_RESET)
  134.   {
  135.     /* Allocate lock resource and initialize it */
  136.     hpcd->Lock = HAL_UNLOCKED;
  137.  
  138. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  139.     hpcd->SOFCallback = HAL_PCD_SOFCallback;
  140.     hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
  141.     hpcd->ResetCallback = HAL_PCD_ResetCallback;
  142.     hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
  143.     hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
  144.     hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
  145.     hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
  146.     hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback;
  147.     hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback;
  148.     hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback;
  149.     hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback;
  150.     hpcd->LPMCallback = HAL_PCDEx_LPM_Callback;
  151.     hpcd->BCDCallback = HAL_PCDEx_BCD_Callback;
  152.  
  153.     if (hpcd->MspInitCallback == NULL)
  154.     {
  155.       hpcd->MspInitCallback = HAL_PCD_MspInit;
  156.     }
  157.  
  158.     /* Init the low level hardware */
  159.     hpcd->MspInitCallback(hpcd);
  160. #else
  161.     /* Init the low level hardware : GPIO, CLOCK, NVIC... */
  162.     HAL_PCD_MspInit(hpcd);
  163. #endif /* (USE_HAL_PCD_REGISTER_CALLBACKS) */
  164.   }
  165.  
  166.   hpcd->State = HAL_PCD_STATE_BUSY;
  167.  
  168.   /* Disable the Interrupts */
  169.   __HAL_PCD_DISABLE(hpcd);
  170.  
  171.   /* Init endpoints structures */
  172.   for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
  173.   {
  174.     /* Init ep structure */
  175.     hpcd->IN_ep[i].is_in = 1U;
  176.     hpcd->IN_ep[i].num = i;
  177.     hpcd->IN_ep[i].tx_fifo_num = i;
  178.     /* Control until ep is activated */
  179.     hpcd->IN_ep[i].type = EP_TYPE_CTRL;
  180.     hpcd->IN_ep[i].maxpacket = 0U;
  181.     hpcd->IN_ep[i].xfer_buff = 0U;
  182.     hpcd->IN_ep[i].xfer_len = 0U;
  183.   }
  184.  
  185.   for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
  186.   {
  187.     hpcd->OUT_ep[i].is_in = 0U;
  188.     hpcd->OUT_ep[i].num = i;
  189.     /* Control until ep is activated */
  190.     hpcd->OUT_ep[i].type = EP_TYPE_CTRL;
  191.     hpcd->OUT_ep[i].maxpacket = 0U;
  192.     hpcd->OUT_ep[i].xfer_buff = 0U;
  193.     hpcd->OUT_ep[i].xfer_len = 0U;
  194.   }
  195.  
  196.   /* Init Device */
  197.   (void)USB_DevInit(hpcd->Instance, hpcd->Init);
  198.  
  199.   hpcd->USB_Address = 0U;
  200.   hpcd->State = HAL_PCD_STATE_READY;
  201.  
  202.   /* Activate LPM */
  203.   if (hpcd->Init.lpm_enable == 1U)
  204.   {
  205.     (void)HAL_PCDEx_ActivateLPM(hpcd);
  206.   }
  207.  
  208.   return HAL_OK;
  209. }
  210.  
  211. /**
  212.   * @brief  DeInitializes the PCD peripheral.
  213.   * @param  hpcd PCD handle
  214.   * @retval HAL status
  215.   */
  216. HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
  217. {
  218.   /* Check the PCD handle allocation */
  219.   if (hpcd == NULL)
  220.   {
  221.     return HAL_ERROR;
  222.   }
  223.  
  224.   hpcd->State = HAL_PCD_STATE_BUSY;
  225.  
  226.   /* Stop Device */
  227.   (void)HAL_PCD_Stop(hpcd);
  228.  
  229. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  230.   if (hpcd->MspDeInitCallback == NULL)
  231.   {
  232.     hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; /* Legacy weak MspDeInit  */
  233.   }
  234.  
  235.   /* DeInit the low level hardware */
  236.   hpcd->MspDeInitCallback(hpcd);
  237. #else
  238.   /* DeInit the low level hardware: CLOCK, NVIC.*/
  239.   HAL_PCD_MspDeInit(hpcd);
  240. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  241.  
  242.   hpcd->State = HAL_PCD_STATE_RESET;
  243.  
  244.   return HAL_OK;
  245. }
  246.  
  247. /**
  248.   * @brief  Initializes the PCD MSP.
  249.   * @param  hpcd PCD handle
  250.   * @retval None
  251.   */
  252. __weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
  253. {
  254.   /* Prevent unused argument(s) compilation warning */
  255.   UNUSED(hpcd);
  256.  
  257.   /* NOTE : This function should not be modified, when the callback is needed,
  258.             the HAL_PCD_MspInit could be implemented in the user file
  259.    */
  260. }
  261.  
  262. /**
  263.   * @brief  DeInitializes PCD MSP.
  264.   * @param  hpcd PCD handle
  265.   * @retval None
  266.   */
  267. __weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
  268. {
  269.   /* Prevent unused argument(s) compilation warning */
  270.   UNUSED(hpcd);
  271.  
  272.   /* NOTE : This function should not be modified, when the callback is needed,
  273.             the HAL_PCD_MspDeInit could be implemented in the user file
  274.    */
  275. }
  276.  
  277. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  278. /**
  279.   * @brief  Register a User USB PCD Callback
  280.   *         To be used instead of the weak predefined callback
  281.   * @param  hpcd USB PCD handle
  282.   * @param  CallbackID ID of the callback to be registered
  283.   *         This parameter can be one of the following values:
  284.   *          @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
  285.   *          @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
  286.   *          @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
  287.   *          @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
  288.   *          @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
  289.   *          @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
  290.   *          @arg @ref HAL_PCD_DISCONNECT_CB_ID OTG PCD Disconnect callback ID
  291.   *          @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
  292.   *          @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
  293.   * @param  pCallback pointer to the Callback function
  294.   * @retval HAL status
  295.   */
  296. HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID, pPCD_CallbackTypeDef pCallback)
  297. {
  298.   HAL_StatusTypeDef status = HAL_OK;
  299.  
  300.   if (pCallback == NULL)
  301.   {
  302.     /* Update the error code */
  303.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  304.     return HAL_ERROR;
  305.   }
  306.   /* Process locked */
  307.   __HAL_LOCK(hpcd);
  308.  
  309.   if (hpcd->State == HAL_PCD_STATE_READY)
  310.   {
  311.     switch (CallbackID)
  312.     {
  313.       case HAL_PCD_SOF_CB_ID :
  314.         hpcd->SOFCallback = pCallback;
  315.         break;
  316.  
  317.       case HAL_PCD_SETUPSTAGE_CB_ID :
  318.         hpcd->SetupStageCallback = pCallback;
  319.         break;
  320.  
  321.       case HAL_PCD_RESET_CB_ID :
  322.         hpcd->ResetCallback = pCallback;
  323.         break;
  324.  
  325.       case HAL_PCD_SUSPEND_CB_ID :
  326.         hpcd->SuspendCallback = pCallback;
  327.         break;
  328.  
  329.       case HAL_PCD_RESUME_CB_ID :
  330.         hpcd->ResumeCallback = pCallback;
  331.         break;
  332.  
  333.       case HAL_PCD_CONNECT_CB_ID :
  334.         hpcd->ConnectCallback = pCallback;
  335.         break;
  336.  
  337.       case HAL_PCD_DISCONNECT_CB_ID :
  338.         hpcd->DisconnectCallback = pCallback;
  339.         break;
  340.  
  341.       case HAL_PCD_MSPINIT_CB_ID :
  342.         hpcd->MspInitCallback = pCallback;
  343.         break;
  344.  
  345.       case HAL_PCD_MSPDEINIT_CB_ID :
  346.         hpcd->MspDeInitCallback = pCallback;
  347.         break;
  348.  
  349.       default :
  350.         /* Update the error code */
  351.         hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  352.         /* Return error status */
  353.         status =  HAL_ERROR;
  354.         break;
  355.     }
  356.   }
  357.   else if (hpcd->State == HAL_PCD_STATE_RESET)
  358.   {
  359.     switch (CallbackID)
  360.     {
  361.       case HAL_PCD_MSPINIT_CB_ID :
  362.         hpcd->MspInitCallback = pCallback;
  363.         break;
  364.  
  365.       case HAL_PCD_MSPDEINIT_CB_ID :
  366.         hpcd->MspDeInitCallback = pCallback;
  367.         break;
  368.  
  369.       default :
  370.         /* Update the error code */
  371.         hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  372.         /* Return error status */
  373.         status =  HAL_ERROR;
  374.         break;
  375.     }
  376.   }
  377.   else
  378.   {
  379.     /* Update the error code */
  380.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  381.     /* Return error status */
  382.     status =  HAL_ERROR;
  383.   }
  384.  
  385.   /* Release Lock */
  386.   __HAL_UNLOCK(hpcd);
  387.   return status;
  388. }
  389.  
  390. /**
  391.   * @brief  Unregister an USB PCD Callback
  392.   *         USB PCD callabck is redirected to the weak predefined callback
  393.   * @param  hpcd USB PCD handle
  394.   * @param  CallbackID ID of the callback to be unregistered
  395.   *         This parameter can be one of the following values:
  396.   *          @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
  397.   *          @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
  398.   *          @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
  399.   *          @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
  400.   *          @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
  401.   *          @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
  402.   *          @arg @ref HAL_PCD_DISCONNECT_CB_ID OTG PCD Disconnect callback ID
  403.   *          @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
  404.   *          @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
  405.   * @retval HAL status
  406.   */
  407. HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID)
  408. {
  409.   HAL_StatusTypeDef status = HAL_OK;
  410.  
  411.   /* Process locked */
  412.   __HAL_LOCK(hpcd);
  413.  
  414.   /* Setup Legacy weak Callbacks  */
  415.   if (hpcd->State == HAL_PCD_STATE_READY)
  416.   {
  417.     switch (CallbackID)
  418.     {
  419.       case HAL_PCD_SOF_CB_ID :
  420.         hpcd->SOFCallback = HAL_PCD_SOFCallback;
  421.         break;
  422.  
  423.       case HAL_PCD_SETUPSTAGE_CB_ID :
  424.         hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
  425.         break;
  426.  
  427.       case HAL_PCD_RESET_CB_ID :
  428.         hpcd->ResetCallback = HAL_PCD_ResetCallback;
  429.         break;
  430.  
  431.       case HAL_PCD_SUSPEND_CB_ID :
  432.         hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
  433.         break;
  434.  
  435.       case HAL_PCD_RESUME_CB_ID :
  436.         hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
  437.         break;
  438.  
  439.       case HAL_PCD_CONNECT_CB_ID :
  440.         hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
  441.         break;
  442.  
  443.       case HAL_PCD_DISCONNECT_CB_ID :
  444.         hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
  445.         break;
  446.  
  447.       case HAL_PCD_MSPINIT_CB_ID :
  448.         hpcd->MspInitCallback = HAL_PCD_MspInit;
  449.         break;
  450.  
  451.       case HAL_PCD_MSPDEINIT_CB_ID :
  452.         hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
  453.         break;
  454.  
  455.       default :
  456.         /* Update the error code */
  457.         hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  458.  
  459.         /* Return error status */
  460.         status =  HAL_ERROR;
  461.         break;
  462.     }
  463.   }
  464.   else if (hpcd->State == HAL_PCD_STATE_RESET)
  465.   {
  466.     switch (CallbackID)
  467.     {
  468.       case HAL_PCD_MSPINIT_CB_ID :
  469.         hpcd->MspInitCallback = HAL_PCD_MspInit;
  470.         break;
  471.  
  472.       case HAL_PCD_MSPDEINIT_CB_ID :
  473.         hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
  474.         break;
  475.  
  476.       default :
  477.         /* Update the error code */
  478.         hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  479.  
  480.         /* Return error status */
  481.         status =  HAL_ERROR;
  482.         break;
  483.     }
  484.   }
  485.   else
  486.   {
  487.     /* Update the error code */
  488.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  489.  
  490.     /* Return error status */
  491.     status =  HAL_ERROR;
  492.   }
  493.  
  494.   /* Release Lock */
  495.   __HAL_UNLOCK(hpcd);
  496.   return status;
  497. }
  498.  
  499. /**
  500.   * @brief  Register USB PCD Data OUT Stage Callback
  501.   *         To be used instead of the weak HAL_PCD_DataOutStageCallback() predefined callback
  502.   * @param  hpcd PCD handle
  503.   * @param  pCallback pointer to the USB PCD Data OUT Stage Callback function
  504.   * @retval HAL status
  505.   */
  506. HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd, pPCD_DataOutStageCallbackTypeDef pCallback)
  507. {
  508.   HAL_StatusTypeDef status = HAL_OK;
  509.  
  510.   if (pCallback == NULL)
  511.   {
  512.     /* Update the error code */
  513.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  514.  
  515.     return HAL_ERROR;
  516.   }
  517.  
  518.   /* Process locked */
  519.   __HAL_LOCK(hpcd);
  520.  
  521.   if (hpcd->State == HAL_PCD_STATE_READY)
  522.   {
  523.     hpcd->DataOutStageCallback = pCallback;
  524.   }
  525.   else
  526.   {
  527.     /* Update the error code */
  528.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  529.  
  530.     /* Return error status */
  531.     status =  HAL_ERROR;
  532.   }
  533.  
  534.   /* Release Lock */
  535.   __HAL_UNLOCK(hpcd);
  536.  
  537.   return status;
  538. }
  539.  
  540. /**
  541.   * @brief  UnRegister the USB PCD Data OUT Stage Callback
  542.   *         USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataOutStageCallback() predefined callback
  543.   * @param  hpcd PCD handle
  544.   * @retval HAL status
  545.   */
  546. HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd)
  547. {
  548.   HAL_StatusTypeDef status = HAL_OK;
  549.  
  550.   /* Process locked */
  551.   __HAL_LOCK(hpcd);
  552.  
  553.   if (hpcd->State == HAL_PCD_STATE_READY)
  554.   {
  555.     hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback; /* Legacy weak DataOutStageCallback  */
  556.   }
  557.   else
  558.   {
  559.     /* Update the error code */
  560.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  561.  
  562.     /* Return error status */
  563.     status =  HAL_ERROR;
  564.   }
  565.  
  566.   /* Release Lock */
  567.   __HAL_UNLOCK(hpcd);
  568.  
  569.   return status;
  570. }
  571.  
  572. /**
  573.   * @brief  Register USB PCD Data IN Stage Callback
  574.   *         To be used instead of the weak HAL_PCD_DataInStageCallback() predefined callback
  575.   * @param  hpcd PCD handle
  576.   * @param  pCallback pointer to the USB PCD Data IN Stage Callback function
  577.   * @retval HAL status
  578.   */
  579. HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd, pPCD_DataInStageCallbackTypeDef pCallback)
  580. {
  581.   HAL_StatusTypeDef status = HAL_OK;
  582.  
  583.   if (pCallback == NULL)
  584.   {
  585.     /* Update the error code */
  586.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  587.  
  588.     return HAL_ERROR;
  589.   }
  590.  
  591.   /* Process locked */
  592.   __HAL_LOCK(hpcd);
  593.  
  594.   if (hpcd->State == HAL_PCD_STATE_READY)
  595.   {
  596.     hpcd->DataInStageCallback = pCallback;
  597.   }
  598.   else
  599.   {
  600.     /* Update the error code */
  601.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  602.  
  603.     /* Return error status */
  604.     status =  HAL_ERROR;
  605.   }
  606.  
  607.   /* Release Lock */
  608.   __HAL_UNLOCK(hpcd);
  609.  
  610.   return status;
  611. }
  612.  
  613. /**
  614.   * @brief  UnRegister the USB PCD Data IN Stage Callback
  615.   *         USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataInStageCallback() predefined callback
  616.   * @param  hpcd PCD handle
  617.   * @retval HAL status
  618.   */
  619. HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd)
  620. {
  621.   HAL_StatusTypeDef status = HAL_OK;
  622.  
  623.   /* Process locked */
  624.   __HAL_LOCK(hpcd);
  625.  
  626.   if (hpcd->State == HAL_PCD_STATE_READY)
  627.   {
  628.     hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback; /* Legacy weak DataInStageCallback  */
  629.   }
  630.   else
  631.   {
  632.     /* Update the error code */
  633.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  634.  
  635.     /* Return error status */
  636.     status =  HAL_ERROR;
  637.   }
  638.  
  639.   /* Release Lock */
  640.   __HAL_UNLOCK(hpcd);
  641.  
  642.   return status;
  643. }
  644.  
  645. /**
  646.   * @brief  Register USB PCD Iso OUT incomplete Callback
  647.   *         To be used instead of the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
  648.   * @param  hpcd PCD handle
  649.   * @param  pCallback pointer to the USB PCD Iso OUT incomplete Callback function
  650.   * @retval HAL status
  651.   */
  652. HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd, pPCD_IsoOutIncpltCallbackTypeDef pCallback)
  653. {
  654.   HAL_StatusTypeDef status = HAL_OK;
  655.  
  656.   if (pCallback == NULL)
  657.   {
  658.     /* Update the error code */
  659.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  660.  
  661.     return HAL_ERROR;
  662.   }
  663.  
  664.   /* Process locked */
  665.   __HAL_LOCK(hpcd);
  666.  
  667.   if (hpcd->State == HAL_PCD_STATE_READY)
  668.   {
  669.     hpcd->ISOOUTIncompleteCallback = pCallback;
  670.   }
  671.   else
  672.   {
  673.     /* Update the error code */
  674.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  675.  
  676.     /* Return error status */
  677.     status =  HAL_ERROR;
  678.   }
  679.  
  680.   /* Release Lock */
  681.   __HAL_UNLOCK(hpcd);
  682.  
  683.   return status;
  684. }
  685.  
  686. /**
  687.   * @brief  UnRegister the USB PCD Iso OUT incomplete Callback
  688.   *         USB PCD Iso OUT incomplete Callback is redirected to the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
  689.   * @param  hpcd PCD handle
  690.   * @retval HAL status
  691.   */
  692. HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd)
  693. {
  694.   HAL_StatusTypeDef status = HAL_OK;
  695.  
  696.   /* Process locked */
  697.   __HAL_LOCK(hpcd);
  698.  
  699.   if (hpcd->State == HAL_PCD_STATE_READY)
  700.   {
  701.     hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback; /* Legacy weak ISOOUTIncompleteCallback  */
  702.   }
  703.   else
  704.   {
  705.     /* Update the error code */
  706.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  707.  
  708.     /* Return error status */
  709.     status =  HAL_ERROR;
  710.   }
  711.  
  712.   /* Release Lock */
  713.   __HAL_UNLOCK(hpcd);
  714.  
  715.   return status;
  716. }
  717.  
  718. /**
  719.   * @brief  Register USB PCD Iso IN incomplete Callback
  720.   *         To be used instead of the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
  721.   * @param  hpcd PCD handle
  722.   * @param  pCallback pointer to the USB PCD Iso IN incomplete Callback function
  723.   * @retval HAL status
  724.   */
  725. HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd, pPCD_IsoInIncpltCallbackTypeDef pCallback)
  726. {
  727.   HAL_StatusTypeDef status = HAL_OK;
  728.  
  729.   if (pCallback == NULL)
  730.   {
  731.     /* Update the error code */
  732.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  733.  
  734.     return HAL_ERROR;
  735.   }
  736.  
  737.   /* Process locked */
  738.   __HAL_LOCK(hpcd);
  739.  
  740.   if (hpcd->State == HAL_PCD_STATE_READY)
  741.   {
  742.     hpcd->ISOINIncompleteCallback = pCallback;
  743.   }
  744.   else
  745.   {
  746.     /* Update the error code */
  747.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  748.  
  749.     /* Return error status */
  750.     status =  HAL_ERROR;
  751.   }
  752.  
  753.   /* Release Lock */
  754.   __HAL_UNLOCK(hpcd);
  755.  
  756.   return status;
  757. }
  758.  
  759. /**
  760.   * @brief  UnRegister the USB PCD Iso IN incomplete Callback
  761.   *         USB PCD Iso IN incomplete Callback is redirected to the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
  762.   * @param  hpcd PCD handle
  763.   * @retval HAL status
  764.   */
  765. HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd)
  766. {
  767.   HAL_StatusTypeDef status = HAL_OK;
  768.  
  769.   /* Process locked */
  770.   __HAL_LOCK(hpcd);
  771.  
  772.   if (hpcd->State == HAL_PCD_STATE_READY)
  773.   {
  774.     hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback; /* Legacy weak ISOINIncompleteCallback  */
  775.   }
  776.   else
  777.   {
  778.     /* Update the error code */
  779.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  780.  
  781.     /* Return error status */
  782.     status =  HAL_ERROR;
  783.   }
  784.  
  785.   /* Release Lock */
  786.   __HAL_UNLOCK(hpcd);
  787.  
  788.   return status;
  789. }
  790.  
  791. /**
  792.   * @brief  Register USB PCD BCD Callback
  793.   *         To be used instead of the weak HAL_PCDEx_BCD_Callback() predefined callback
  794.   * @param  hpcd PCD handle
  795.   * @param  pCallback pointer to the USB PCD BCD Callback function
  796.   * @retval HAL status
  797.   */
  798. HAL_StatusTypeDef HAL_PCD_RegisterBcdCallback(PCD_HandleTypeDef *hpcd, pPCD_BcdCallbackTypeDef pCallback)
  799. {
  800.   HAL_StatusTypeDef status = HAL_OK;
  801.  
  802.   if (pCallback == NULL)
  803.   {
  804.     /* Update the error code */
  805.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  806.  
  807.     return HAL_ERROR;
  808.   }
  809.  
  810.   /* Process locked */
  811.   __HAL_LOCK(hpcd);
  812.  
  813.   if (hpcd->State == HAL_PCD_STATE_READY)
  814.   {
  815.     hpcd->BCDCallback = pCallback;
  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. /**
  833.   * @brief  UnRegister the USB PCD BCD Callback
  834.   *         USB BCD Callback is redirected to the weak HAL_PCDEx_BCD_Callback() predefined callback
  835.   * @param  hpcd PCD handle
  836.   * @retval HAL status
  837.   */
  838. HAL_StatusTypeDef HAL_PCD_UnRegisterBcdCallback(PCD_HandleTypeDef *hpcd)
  839. {
  840.   HAL_StatusTypeDef status = HAL_OK;
  841.  
  842.   /* Process locked */
  843.   __HAL_LOCK(hpcd);
  844.  
  845.   if (hpcd->State == HAL_PCD_STATE_READY)
  846.   {
  847.     hpcd->BCDCallback = HAL_PCDEx_BCD_Callback; /* Legacy weak HAL_PCDEx_BCD_Callback  */
  848.   }
  849.   else
  850.   {
  851.     /* Update the error code */
  852.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  853.  
  854.     /* Return error status */
  855.     status =  HAL_ERROR;
  856.   }
  857.  
  858.   /* Release Lock */
  859.   __HAL_UNLOCK(hpcd);
  860.  
  861.   return status;
  862. }
  863.  
  864. /**
  865.   * @brief  Register USB PCD LPM Callback
  866.   *         To be used instead of the weak HAL_PCDEx_LPM_Callback() predefined callback
  867.   * @param  hpcd PCD handle
  868.   * @param  pCallback pointer to the USB PCD LPM Callback function
  869.   * @retval HAL status
  870.   */
  871. HAL_StatusTypeDef HAL_PCD_RegisterLpmCallback(PCD_HandleTypeDef *hpcd, pPCD_LpmCallbackTypeDef pCallback)
  872. {
  873.   HAL_StatusTypeDef status = HAL_OK;
  874.  
  875.   if (pCallback == NULL)
  876.   {
  877.     /* Update the error code */
  878.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  879.  
  880.     return HAL_ERROR;
  881.   }
  882.  
  883.   /* Process locked */
  884.   __HAL_LOCK(hpcd);
  885.  
  886.   if (hpcd->State == HAL_PCD_STATE_READY)
  887.   {
  888.     hpcd->LPMCallback = pCallback;
  889.   }
  890.   else
  891.   {
  892.     /* Update the error code */
  893.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  894.  
  895.     /* Return error status */
  896.     status =  HAL_ERROR;
  897.   }
  898.  
  899.   /* Release Lock */
  900.   __HAL_UNLOCK(hpcd);
  901.  
  902.   return status;
  903. }
  904.  
  905. /**
  906.   * @brief  UnRegister the USB PCD LPM Callback
  907.   *         USB LPM Callback is redirected to the weak HAL_PCDEx_LPM_Callback() predefined callback
  908.   * @param  hpcd PCD handle
  909.   * @retval HAL status
  910.   */
  911. HAL_StatusTypeDef HAL_PCD_UnRegisterLpmCallback(PCD_HandleTypeDef *hpcd)
  912. {
  913.   HAL_StatusTypeDef status = HAL_OK;
  914.  
  915.   /* Process locked */
  916.   __HAL_LOCK(hpcd);
  917.  
  918.   if (hpcd->State == HAL_PCD_STATE_READY)
  919.   {
  920.     hpcd->LPMCallback = HAL_PCDEx_LPM_Callback; /* Legacy weak HAL_PCDEx_LPM_Callback  */
  921.   }
  922.   else
  923.   {
  924.     /* Update the error code */
  925.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  926.  
  927.     /* Return error status */
  928.     status =  HAL_ERROR;
  929.   }
  930.  
  931.   /* Release Lock */
  932.   __HAL_UNLOCK(hpcd);
  933.  
  934.   return status;
  935. }
  936. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  937.  
  938. /**
  939.   * @}
  940.   */
  941.  
  942. /** @defgroup PCD_Exported_Functions_Group2 Input and Output operation functions
  943.  *  @brief   Data transfers functions
  944.  *
  945. @verbatim
  946.  ===============================================================================
  947.                       ##### IO operation functions #####
  948.  ===============================================================================
  949.     [..]
  950.     This subsection provides a set of functions allowing to manage the PCD data
  951.     transfers.
  952.  
  953. @endverbatim
  954.   * @{
  955.   */
  956.  
  957. /**
  958.   * @brief  Start the USB device
  959.   * @param  hpcd PCD handle
  960.   * @retval HAL status
  961.   */
  962. HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)
  963. {
  964.   __HAL_LOCK(hpcd);
  965.   (void)USB_DevConnect(hpcd->Instance);
  966.   __HAL_PCD_ENABLE(hpcd);
  967.   __HAL_UNLOCK(hpcd);
  968.   return HAL_OK;
  969. }
  970.  
  971. /**
  972.   * @brief  Stop the USB device.
  973.   * @param  hpcd PCD handle
  974.   * @retval HAL status
  975.   */
  976. HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
  977. {
  978.   __HAL_LOCK(hpcd);
  979.   __HAL_PCD_DISABLE(hpcd);
  980.  
  981.   (void)USB_StopDevice(hpcd->Instance);
  982.  
  983.   __HAL_UNLOCK(hpcd);
  984.  
  985.   return HAL_OK;
  986. }
  987.  
  988.  
  989. /**
  990.   * @brief  This function handles PCD interrupt request.
  991.   * @param  hpcd PCD handle
  992.   * @retval HAL status
  993.   */
  994. void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
  995. {
  996.   if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_CTR))
  997.   {
  998.     /* servicing of the endpoint correct transfer interrupt */
  999.     /* clear of the CTR flag into the sub */
  1000.     (void)PCD_EP_ISR_Handler(hpcd);
  1001.   }
  1002.  
  1003.   if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_RESET))
  1004.   {
  1005.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET);
  1006.  
  1007. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1008.     hpcd->ResetCallback(hpcd);
  1009. #else
  1010.     HAL_PCD_ResetCallback(hpcd);
  1011. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1012.  
  1013.     (void)HAL_PCD_SetAddress(hpcd, 0U);
  1014.   }
  1015.  
  1016.   if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_PMAOVR))
  1017.   {
  1018.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_PMAOVR);
  1019.   }
  1020.  
  1021.   if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_ERR))
  1022.   {
  1023.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ERR);
  1024.   }
  1025.  
  1026.   if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_WKUP))
  1027.   {
  1028.     hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_LPMODE);
  1029.     hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_FSUSP);
  1030.  
  1031.     if (hpcd->LPM_State == LPM_L1)
  1032.     {
  1033.       hpcd->LPM_State = LPM_L0;
  1034. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1035.       hpcd->LPMCallback(hpcd, PCD_LPM_L0_ACTIVE);
  1036. #else
  1037.       HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE);
  1038. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1039.     }
  1040.  
  1041. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1042.     hpcd->ResumeCallback(hpcd);
  1043. #else
  1044.     HAL_PCD_ResumeCallback(hpcd);
  1045. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1046.  
  1047.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP);
  1048.   }
  1049.  
  1050.   if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_SUSP))
  1051.   {
  1052.     /* Force low-power mode in the macrocell */
  1053.     hpcd->Instance->CNTR |= USB_CNTR_FSUSP;
  1054.  
  1055.     /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
  1056.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SUSP);
  1057.  
  1058.     hpcd->Instance->CNTR |= USB_CNTR_LPMODE;
  1059.  
  1060.     if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_WKUP) == 0U)
  1061.     {
  1062. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1063.       hpcd->SuspendCallback(hpcd);
  1064. #else
  1065.       HAL_PCD_SuspendCallback(hpcd);
  1066. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1067.     }
  1068.   }
  1069.  
  1070.   /* Handle LPM Interrupt */
  1071.   if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_L1REQ))
  1072.   {
  1073.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_L1REQ);
  1074.     if (hpcd->LPM_State == LPM_L0)
  1075.     {
  1076.       /* Force suspend and low-power mode before going to L1 state*/
  1077.       hpcd->Instance->CNTR |= USB_CNTR_LPMODE;
  1078.       hpcd->Instance->CNTR |= USB_CNTR_FSUSP;
  1079.  
  1080.       hpcd->LPM_State = LPM_L1;
  1081.       hpcd->BESL = ((uint32_t)hpcd->Instance->LPMCSR & USB_LPMCSR_BESL) >> 2;
  1082. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1083.       hpcd->LPMCallback(hpcd, PCD_LPM_L1_ACTIVE);
  1084. #else
  1085.       HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE);
  1086. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1087.     }
  1088.     else
  1089.     {
  1090. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1091.       hpcd->SuspendCallback(hpcd);
  1092. #else
  1093.       HAL_PCD_SuspendCallback(hpcd);
  1094. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1095.     }
  1096.   }
  1097.  
  1098.   if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_SOF))
  1099.   {
  1100.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SOF);
  1101.  
  1102. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1103.     hpcd->SOFCallback(hpcd);
  1104. #else
  1105.     HAL_PCD_SOFCallback(hpcd);
  1106. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1107.   }
  1108.  
  1109.   if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_ESOF))
  1110.   {
  1111.     /* clear ESOF flag in ISTR */
  1112.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ESOF);
  1113.   }
  1114. }
  1115.  
  1116.  
  1117. /**
  1118.   * @brief  Data OUT stage callback.
  1119.   * @param  hpcd PCD handle
  1120.   * @param  epnum endpoint number
  1121.   * @retval None
  1122.   */
  1123. __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  1124. {
  1125.   /* Prevent unused argument(s) compilation warning */
  1126.   UNUSED(hpcd);
  1127.   UNUSED(epnum);
  1128.  
  1129.   /* NOTE : This function should not be modified, when the callback is needed,
  1130.             the HAL_PCD_DataOutStageCallback could be implemented in the user file
  1131.    */
  1132. }
  1133.  
  1134. /**
  1135.   * @brief  Data IN stage callback
  1136.   * @param  hpcd PCD handle
  1137.   * @param  epnum endpoint number
  1138.   * @retval None
  1139.   */
  1140. __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  1141. {
  1142.   /* Prevent unused argument(s) compilation warning */
  1143.   UNUSED(hpcd);
  1144.   UNUSED(epnum);
  1145.  
  1146.   /* NOTE : This function should not be modified, when the callback is needed,
  1147.             the HAL_PCD_DataInStageCallback could be implemented in the user file
  1148.    */
  1149. }
  1150. /**
  1151.   * @brief  Setup stage callback
  1152.   * @param  hpcd PCD handle
  1153.   * @retval None
  1154.   */
  1155. __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
  1156. {
  1157.   /* Prevent unused argument(s) compilation warning */
  1158.   UNUSED(hpcd);
  1159.  
  1160.   /* NOTE : This function should not be modified, when the callback is needed,
  1161.             the HAL_PCD_SetupStageCallback could be implemented in the user file
  1162.    */
  1163. }
  1164.  
  1165. /**
  1166.   * @brief  USB Start Of Frame callback.
  1167.   * @param  hpcd PCD handle
  1168.   * @retval None
  1169.   */
  1170. __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
  1171. {
  1172.   /* Prevent unused argument(s) compilation warning */
  1173.   UNUSED(hpcd);
  1174.  
  1175.   /* NOTE : This function should not be modified, when the callback is needed,
  1176.             the HAL_PCD_SOFCallback could be implemented in the user file
  1177.    */
  1178. }
  1179.  
  1180. /**
  1181.   * @brief  USB Reset callback.
  1182.   * @param  hpcd PCD handle
  1183.   * @retval None
  1184.   */
  1185. __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
  1186. {
  1187.   /* Prevent unused argument(s) compilation warning */
  1188.   UNUSED(hpcd);
  1189.  
  1190.   /* NOTE : This function should not be modified, when the callback is needed,
  1191.             the HAL_PCD_ResetCallback could be implemented in the user file
  1192.    */
  1193. }
  1194.  
  1195. /**
  1196.   * @brief  Suspend event callback.
  1197.   * @param  hpcd PCD handle
  1198.   * @retval None
  1199.   */
  1200. __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
  1201. {
  1202.   /* Prevent unused argument(s) compilation warning */
  1203.   UNUSED(hpcd);
  1204.  
  1205.   /* NOTE : This function should not be modified, when the callback is needed,
  1206.             the HAL_PCD_SuspendCallback could be implemented in the user file
  1207.    */
  1208. }
  1209.  
  1210. /**
  1211.   * @brief  Resume event callback.
  1212.   * @param  hpcd PCD handle
  1213.   * @retval None
  1214.   */
  1215. __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
  1216. {
  1217.   /* Prevent unused argument(s) compilation warning */
  1218.   UNUSED(hpcd);
  1219.  
  1220.   /* NOTE : This function should not be modified, when the callback is needed,
  1221.             the HAL_PCD_ResumeCallback could be implemented in the user file
  1222.    */
  1223. }
  1224.  
  1225. /**
  1226.   * @brief  Incomplete ISO OUT callback.
  1227.   * @param  hpcd PCD handle
  1228.   * @param  epnum endpoint number
  1229.   * @retval None
  1230.   */
  1231. __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  1232. {
  1233.   /* Prevent unused argument(s) compilation warning */
  1234.   UNUSED(hpcd);
  1235.   UNUSED(epnum);
  1236.  
  1237.   /* NOTE : This function should not be modified, when the callback is needed,
  1238.             the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file
  1239.    */
  1240. }
  1241.  
  1242. /**
  1243.   * @brief  Incomplete ISO IN callback.
  1244.   * @param  hpcd PCD handle
  1245.   * @param  epnum endpoint number
  1246.   * @retval None
  1247.   */
  1248. __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  1249. {
  1250.   /* Prevent unused argument(s) compilation warning */
  1251.   UNUSED(hpcd);
  1252.   UNUSED(epnum);
  1253.  
  1254.   /* NOTE : This function should not be modified, when the callback is needed,
  1255.             the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file
  1256.    */
  1257. }
  1258.  
  1259. /**
  1260.   * @brief  Connection event callback.
  1261.   * @param  hpcd PCD handle
  1262.   * @retval None
  1263.   */
  1264. __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
  1265. {
  1266.   /* Prevent unused argument(s) compilation warning */
  1267.   UNUSED(hpcd);
  1268.  
  1269.   /* NOTE : This function should not be modified, when the callback is needed,
  1270.             the HAL_PCD_ConnectCallback could be implemented in the user file
  1271.    */
  1272. }
  1273.  
  1274. /**
  1275.   * @brief  Disconnection event callback.
  1276.   * @param  hpcd PCD handle
  1277.   * @retval None
  1278.   */
  1279. __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
  1280. {
  1281.   /* Prevent unused argument(s) compilation warning */
  1282.   UNUSED(hpcd);
  1283.  
  1284.   /* NOTE : This function should not be modified, when the callback is needed,
  1285.             the HAL_PCD_DisconnectCallback could be implemented in the user file
  1286.    */
  1287. }
  1288.  
  1289. /**
  1290.   * @}
  1291.   */
  1292.  
  1293. /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
  1294.  *  @brief   management functions
  1295.  *
  1296. @verbatim
  1297.  ===============================================================================
  1298.                       ##### Peripheral Control functions #####
  1299.  ===============================================================================
  1300.     [..]
  1301.     This subsection provides a set of functions allowing to control the PCD data
  1302.     transfers.
  1303.  
  1304. @endverbatim
  1305.   * @{
  1306.   */
  1307.  
  1308. /**
  1309.   * @brief  Connect the USB device
  1310.   * @param  hpcd PCD handle
  1311.   * @retval HAL status
  1312.   */
  1313. HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd)
  1314. {
  1315.   __HAL_LOCK(hpcd);
  1316.   (void)USB_DevConnect(hpcd->Instance);
  1317.   __HAL_UNLOCK(hpcd);
  1318.   return HAL_OK;
  1319. }
  1320.  
  1321. /**
  1322.   * @brief  Disconnect the USB device.
  1323.   * @param  hpcd PCD handle
  1324.   * @retval HAL status
  1325.   */
  1326. HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd)
  1327. {
  1328.   __HAL_LOCK(hpcd);
  1329.   (void)USB_DevDisconnect(hpcd->Instance);
  1330.   __HAL_UNLOCK(hpcd);
  1331.   return HAL_OK;
  1332. }
  1333.  
  1334. /**
  1335.   * @brief  Set the USB Device address.
  1336.   * @param  hpcd PCD handle
  1337.   * @param  address new device address
  1338.   * @retval HAL status
  1339.   */
  1340. HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)
  1341. {
  1342.   __HAL_LOCK(hpcd);
  1343.   hpcd->USB_Address = address;
  1344.   (void)USB_SetDevAddress(hpcd->Instance, address);
  1345.   __HAL_UNLOCK(hpcd);
  1346.   return HAL_OK;
  1347. }
  1348. /**
  1349.   * @brief  Open and configure an endpoint.
  1350.   * @param  hpcd PCD handle
  1351.   * @param  ep_addr endpoint address
  1352.   * @param  ep_mps endpoint max packet size
  1353.   * @param  ep_type endpoint type
  1354.   * @retval HAL status
  1355.   */
  1356. HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type)
  1357. {
  1358.   HAL_StatusTypeDef  ret = HAL_OK;
  1359.   PCD_EPTypeDef *ep;
  1360.  
  1361.   if ((ep_addr & 0x80U) == 0x80U)
  1362.   {
  1363.     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1364.     ep->is_in = 1U;
  1365.   }
  1366.   else
  1367.   {
  1368.     ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1369.     ep->is_in = 0U;
  1370.   }
  1371.  
  1372.   ep->num = ep_addr & EP_ADDR_MSK;
  1373.   ep->maxpacket = ep_mps;
  1374.   ep->type = ep_type;
  1375.  
  1376.   if (ep->is_in != 0U)
  1377.   {
  1378.     /* Assign a Tx FIFO */
  1379.     ep->tx_fifo_num = ep->num;
  1380.   }
  1381.   /* Set initial data PID. */
  1382.   if (ep_type == EP_TYPE_BULK)
  1383.   {
  1384.     ep->data_pid_start = 0U;
  1385.   }
  1386.  
  1387.   __HAL_LOCK(hpcd);
  1388.   (void)USB_ActivateEndpoint(hpcd->Instance, ep);
  1389.   __HAL_UNLOCK(hpcd);
  1390.  
  1391.   return ret;
  1392. }
  1393.  
  1394. /**
  1395.   * @brief  Deactivate an endpoint.
  1396.   * @param  hpcd PCD handle
  1397.   * @param  ep_addr endpoint address
  1398.   * @retval HAL status
  1399.   */
  1400. HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1401. {
  1402.   PCD_EPTypeDef *ep;
  1403.  
  1404.   if ((ep_addr & 0x80U) == 0x80U)
  1405.   {
  1406.     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1407.     ep->is_in = 1U;
  1408.   }
  1409.   else
  1410.   {
  1411.     ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1412.     ep->is_in = 0U;
  1413.   }
  1414.   ep->num   = ep_addr & EP_ADDR_MSK;
  1415.  
  1416.   __HAL_LOCK(hpcd);
  1417.   (void)USB_DeactivateEndpoint(hpcd->Instance, ep);
  1418.   __HAL_UNLOCK(hpcd);
  1419.   return HAL_OK;
  1420. }
  1421.  
  1422.  
  1423. /**
  1424.   * @brief  Receive an amount of data.
  1425.   * @param  hpcd PCD handle
  1426.   * @param  ep_addr endpoint address
  1427.   * @param  pBuf pointer to the reception buffer
  1428.   * @param  len amount of data to be received
  1429.   * @retval HAL status
  1430.   */
  1431. HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
  1432. {
  1433.   PCD_EPTypeDef *ep;
  1434.  
  1435.   ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1436.  
  1437.   /*setup and start the Xfer */
  1438.   ep->xfer_buff = pBuf;
  1439.   ep->xfer_len = len;
  1440.   ep->xfer_count = 0U;
  1441.   ep->is_in = 0U;
  1442.   ep->num = ep_addr & EP_ADDR_MSK;
  1443.  
  1444.   if ((ep_addr & EP_ADDR_MSK) == 0U)
  1445.   {
  1446.     (void)USB_EP0StartXfer(hpcd->Instance, ep);
  1447.   }
  1448.   else
  1449.   {
  1450.     (void)USB_EPStartXfer(hpcd->Instance, ep);
  1451.   }
  1452.  
  1453.   return HAL_OK;
  1454. }
  1455.  
  1456. /**
  1457.   * @brief  Get Received Data Size
  1458.   * @param  hpcd PCD handle
  1459.   * @param  ep_addr endpoint address
  1460.   * @retval Data Size
  1461.   */
  1462. uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1463. {
  1464.   return hpcd->OUT_ep[ep_addr & EP_ADDR_MSK].xfer_count;
  1465. }
  1466. /**
  1467.   * @brief  Send an amount of data
  1468.   * @param  hpcd PCD handle
  1469.   * @param  ep_addr endpoint address
  1470.   * @param  pBuf pointer to the transmission buffer
  1471.   * @param  len amount of data to be sent
  1472.   * @retval HAL status
  1473.   */
  1474. HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
  1475. {
  1476.   PCD_EPTypeDef *ep;
  1477.  
  1478.   ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1479.  
  1480.   /*setup and start the Xfer */
  1481.   ep->xfer_buff = pBuf;
  1482.   ep->xfer_len = len;
  1483.   ep->xfer_count = 0U;
  1484.   ep->is_in = 1U;
  1485.   ep->num = ep_addr & EP_ADDR_MSK;
  1486.  
  1487.   if ((ep_addr & EP_ADDR_MSK) == 0U)
  1488.   {
  1489.     (void)USB_EP0StartXfer(hpcd->Instance, ep);
  1490.   }
  1491.   else
  1492.   {
  1493.     (void)USB_EPStartXfer(hpcd->Instance, ep);
  1494.   }
  1495.  
  1496.   return HAL_OK;
  1497. }
  1498.  
  1499. /**
  1500.   * @brief  Set a STALL condition over an endpoint
  1501.   * @param  hpcd PCD handle
  1502.   * @param  ep_addr endpoint address
  1503.   * @retval HAL status
  1504.   */
  1505. HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1506. {
  1507.   PCD_EPTypeDef *ep;
  1508.  
  1509.   if (((uint32_t)ep_addr & EP_ADDR_MSK) > hpcd->Init.dev_endpoints)
  1510.   {
  1511.     return HAL_ERROR;
  1512.   }
  1513.  
  1514.   if ((0x80U & ep_addr) == 0x80U)
  1515.   {
  1516.     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1517.     ep->is_in = 1U;
  1518.   }
  1519.   else
  1520.   {
  1521.     ep = &hpcd->OUT_ep[ep_addr];
  1522.     ep->is_in = 0U;
  1523.   }
  1524.  
  1525.   ep->is_stall = 1U;
  1526.   ep->num = ep_addr & EP_ADDR_MSK;
  1527.  
  1528.   __HAL_LOCK(hpcd);
  1529.  
  1530.   (void)USB_EPSetStall(hpcd->Instance, ep);
  1531.   if ((ep_addr & EP_ADDR_MSK) == 0U)
  1532.   {
  1533.     (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
  1534.   }
  1535.   __HAL_UNLOCK(hpcd);
  1536.  
  1537.   return HAL_OK;
  1538. }
  1539.  
  1540. /**
  1541.   * @brief  Clear a STALL condition over in an endpoint
  1542.   * @param  hpcd PCD handle
  1543.   * @param  ep_addr endpoint address
  1544.   * @retval HAL status
  1545.   */
  1546. HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1547. {
  1548.   PCD_EPTypeDef *ep;
  1549.  
  1550.   if (((uint32_t)ep_addr & 0x0FU) > hpcd->Init.dev_endpoints)
  1551.   {
  1552.     return HAL_ERROR;
  1553.   }
  1554.  
  1555.   if ((0x80U & ep_addr) == 0x80U)
  1556.   {
  1557.     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1558.     ep->is_in = 1U;
  1559.   }
  1560.   else
  1561.   {
  1562.     ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1563.     ep->is_in = 0U;
  1564.   }
  1565.  
  1566.   ep->is_stall = 0U;
  1567.   ep->num = ep_addr & EP_ADDR_MSK;
  1568.  
  1569.   __HAL_LOCK(hpcd);
  1570.   (void)USB_EPClearStall(hpcd->Instance, ep);
  1571.   __HAL_UNLOCK(hpcd);
  1572.  
  1573.   return HAL_OK;
  1574. }
  1575.  
  1576. /**
  1577.   * @brief  Flush an endpoint
  1578.   * @param  hpcd PCD handle
  1579.   * @param  ep_addr endpoint address
  1580.   * @retval HAL status
  1581.   */
  1582. HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1583. {
  1584.   /* Prevent unused argument(s) compilation warning */
  1585.   UNUSED(hpcd);
  1586.   UNUSED(ep_addr);
  1587.  
  1588.   return HAL_OK;
  1589. }
  1590.  
  1591. /**
  1592.   * @brief  Activate remote wakeup signalling
  1593.   * @param  hpcd PCD handle
  1594.   * @retval HAL status
  1595.   */
  1596. HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
  1597. {
  1598.   return (USB_ActivateRemoteWakeup(hpcd->Instance));
  1599. }
  1600.  
  1601. /**
  1602.   * @brief  De-activate remote wakeup signalling.
  1603.   * @param  hpcd PCD handle
  1604.   * @retval HAL status
  1605.   */
  1606. HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
  1607. {
  1608.   return (USB_DeActivateRemoteWakeup(hpcd->Instance));
  1609. }
  1610.  
  1611. /**
  1612.   * @}
  1613.   */
  1614.  
  1615. /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions
  1616.  *  @brief   Peripheral State functions
  1617.  *
  1618. @verbatim
  1619.  ===============================================================================
  1620.                       ##### Peripheral State functions #####
  1621.  ===============================================================================
  1622.     [..]
  1623.     This subsection permits to get in run-time the status of the peripheral
  1624.     and the data flow.
  1625.  
  1626. @endverbatim
  1627.   * @{
  1628.   */
  1629.  
  1630. /**
  1631.   * @brief  Return the PCD handle state.
  1632.   * @param  hpcd PCD handle
  1633.   * @retval HAL state
  1634.   */
  1635. PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd)
  1636. {
  1637.   return hpcd->State;
  1638. }
  1639.  
  1640. /**
  1641.   * @}
  1642.   */
  1643.  
  1644. /**
  1645.   * @}
  1646.   */
  1647.  
  1648. /* Private functions ---------------------------------------------------------*/
  1649. /** @addtogroup PCD_Private_Functions
  1650.   * @{
  1651.   */
  1652.  
  1653.  
  1654. /**
  1655.   * @brief  This function handles PCD Endpoint interrupt request.
  1656.   * @param  hpcd PCD handle
  1657.   * @retval HAL status
  1658.   */
  1659. static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
  1660. {
  1661.   PCD_EPTypeDef *ep;
  1662.   uint16_t count;
  1663.   uint16_t wIstr;
  1664.   uint16_t wEPVal;
  1665.   uint8_t epindex;
  1666.  
  1667.   /* stay in loop while pending interrupts */
  1668.   while ((hpcd->Instance->ISTR & USB_ISTR_CTR) != 0U)
  1669.   {
  1670.     wIstr = hpcd->Instance->ISTR;
  1671.     /* extract highest priority endpoint number */
  1672.     epindex = (uint8_t)(wIstr & USB_ISTR_EP_ID);
  1673.  
  1674.     if (epindex == 0U)
  1675.     {
  1676.       /* Decode and service control endpoint interrupt */
  1677.  
  1678.       /* DIR bit = origin of the interrupt */
  1679.       if ((wIstr & USB_ISTR_DIR) == 0U)
  1680.       {
  1681.         /* DIR = 0 */
  1682.  
  1683.         /* DIR = 0      => IN  int */
  1684.         /* DIR = 0 implies that (EP_CTR_TX = 1) always  */
  1685.         PCD_CLEAR_TX_EP_CTR(hpcd->Instance, PCD_ENDP0);
  1686.         ep = &hpcd->IN_ep[0];
  1687.  
  1688.         ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
  1689.         ep->xfer_buff += ep->xfer_count;
  1690.  
  1691.         /* TX COMPLETE */
  1692. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1693.         hpcd->DataInStageCallback(hpcd, 0U);
  1694. #else
  1695.         HAL_PCD_DataInStageCallback(hpcd, 0U);
  1696. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1697.  
  1698.         if ((hpcd->USB_Address > 0U) && (ep->xfer_len == 0U))
  1699.         {
  1700.           hpcd->Instance->DADDR = ((uint16_t)hpcd->USB_Address | USB_DADDR_EF);
  1701.           hpcd->USB_Address = 0U;
  1702.         }
  1703.       }
  1704.       else
  1705.       {
  1706.         /* DIR = 1 */
  1707.  
  1708.         /* DIR = 1 & CTR_RX       => SETUP or OUT int */
  1709.         /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */
  1710.         ep = &hpcd->OUT_ep[0];
  1711.         wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0);
  1712.  
  1713.         if ((wEPVal & USB_EP_SETUP) != 0U)
  1714.         {
  1715.           /* Get SETUP Packet*/
  1716.           ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
  1717.  
  1718.           USB_ReadPMA(hpcd->Instance, (uint8_t *)hpcd->Setup,
  1719.                       ep->pmaadress, (uint16_t)ep->xfer_count);
  1720.  
  1721.           /* SETUP bit kept frozen while CTR_RX = 1*/
  1722.           PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
  1723.  
  1724.           /* Process SETUP Packet*/
  1725. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1726.           hpcd->SetupStageCallback(hpcd);
  1727. #else
  1728.           HAL_PCD_SetupStageCallback(hpcd);
  1729. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1730.         }
  1731.  
  1732.         else if ((wEPVal & USB_EP_CTR_RX) != 0U)
  1733.         {
  1734.           PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
  1735.  
  1736.           /* Get Control Data OUT Packet*/
  1737.           ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
  1738.  
  1739.           if ((ep->xfer_count != 0U) && (ep->xfer_buff != 0U))
  1740.           {
  1741.             USB_ReadPMA(hpcd->Instance, ep->xfer_buff,
  1742.                         ep->pmaadress, (uint16_t)ep->xfer_count);
  1743.  
  1744.             ep->xfer_buff += ep->xfer_count;
  1745.  
  1746.             /* Process Control Data OUT Packet*/
  1747. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1748.             hpcd->DataOutStageCallback(hpcd, 0U);
  1749. #else
  1750.             HAL_PCD_DataOutStageCallback(hpcd, 0U);
  1751. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1752.           }
  1753.  
  1754.           PCD_SET_EP_RX_CNT(hpcd->Instance, PCD_ENDP0, ep->maxpacket);
  1755.           PCD_SET_EP_RX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_RX_VALID);
  1756.         }
  1757.       }
  1758.     }
  1759.     else
  1760.     {
  1761.       /* Decode and service non control endpoints interrupt  */
  1762.  
  1763.       /* process related endpoint register */
  1764.       wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, epindex);
  1765.       if ((wEPVal & USB_EP_CTR_RX) != 0U)
  1766.       {
  1767.         /* clear int flag */
  1768.         PCD_CLEAR_RX_EP_CTR(hpcd->Instance, epindex);
  1769.         ep = &hpcd->OUT_ep[epindex];
  1770.  
  1771.         /* OUT double Buffering*/
  1772.         if (ep->doublebuffer == 0U)
  1773.         {
  1774.           count = (uint16_t)PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
  1775.           if (count != 0U)
  1776.           {
  1777.             USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, count);
  1778.           }
  1779.         }
  1780.         else
  1781.         {
  1782.           if ((PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_RX) != 0U)
  1783.           {
  1784.             /*read from endpoint BUF0Addr buffer*/
  1785.             count = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
  1786.             if (count != 0U)
  1787.             {
  1788.               USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count);
  1789.             }
  1790.           }
  1791.           else
  1792.           {
  1793.             /*read from endpoint BUF1Addr buffer*/
  1794.             count = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
  1795.             if (count != 0U)
  1796.             {
  1797.               USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count);
  1798.             }
  1799.           }
  1800.           /* free EP OUT Buffer */
  1801.           PCD_FreeUserBuffer(hpcd->Instance, ep->num, 0U);
  1802.         }
  1803.         /*multi-packet on the NON control OUT endpoint*/
  1804.         ep->xfer_count += count;
  1805.         ep->xfer_buff += count;
  1806.  
  1807.         if ((ep->xfer_len == 0U) || (count < ep->maxpacket))
  1808.         {
  1809.           /* RX COMPLETE */
  1810. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1811.           hpcd->DataOutStageCallback(hpcd, ep->num);
  1812. #else
  1813.           HAL_PCD_DataOutStageCallback(hpcd, ep->num);
  1814. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1815.         }
  1816.         else
  1817.         {
  1818.           (void)HAL_PCD_EP_Receive(hpcd, ep->num, ep->xfer_buff, ep->xfer_len);
  1819.         }
  1820.  
  1821.       } /* if((wEPVal & EP_CTR_RX) */
  1822.  
  1823.       if ((wEPVal & USB_EP_CTR_TX) != 0U)
  1824.       {
  1825.         ep = &hpcd->IN_ep[epindex];
  1826.  
  1827.         /* clear int flag */
  1828.         PCD_CLEAR_TX_EP_CTR(hpcd->Instance, epindex);
  1829.  
  1830.         /*multi-packet on the NON control IN endpoint*/
  1831.         ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
  1832.         ep->xfer_buff += ep->xfer_count;
  1833.  
  1834.         /* Zero Length Packet? */
  1835.         if (ep->xfer_len == 0U)
  1836.         {
  1837.           /* TX COMPLETE */
  1838. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1839.           hpcd->DataInStageCallback(hpcd, ep->num);
  1840. #else
  1841.           HAL_PCD_DataInStageCallback(hpcd, ep->num);
  1842. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1843.         }
  1844.         else
  1845.         {
  1846.           (void)HAL_PCD_EP_Transmit(hpcd, ep->num, ep->xfer_buff, ep->xfer_len);
  1847.         }
  1848.       }
  1849.     }
  1850.   }
  1851.   return HAL_OK;
  1852. }
  1853.  
  1854.  
  1855. /**
  1856.   * @}
  1857.   */
  1858. #endif /* defined (USB) */
  1859. #endif /* HAL_PCD_MODULE_ENABLED */
  1860.  
  1861. /**
  1862.   * @}
  1863.   */
  1864.  
  1865. /**
  1866.   * @}
  1867.   */
  1868.  
  1869. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
  1870.