Subversion Repositories DashDisplay

Rev

Rev 61 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /**
  2.   ******************************************************************************
  3.   * @file    stm32l1xx_hal_pcd.c
  4.   * @author  MCD Application Team
  5.   * @brief   PCD HAL module driver.
  6.   *          This file provides firmware functions to manage the following
  7.   *          functionalities of the USB Peripheral Controller:
  8.   *           + Initialization and de-initialization functions
  9.   *           + IO operation functions
  10.   *           + Peripheral Control functions
  11.   *           + Peripheral State functions
  12.   *
  13.   ******************************************************************************
  14.   * @attention
  15.   *
  16.   * Copyright (c) 2016 STMicroelectronics.
  17.   * All rights reserved.
  18.   *
  19.   * This software is licensed under terms that can be found in the LICENSE file
  20.   * in the root directory of this software component.
  21.   * If no LICENSE file comes with this software, it is provided AS-IS.
  22.   *
  23.   ******************************************************************************
  24.   @verbatim
  25.   ==============================================================================
  26.                     ##### How to use this driver #####
  27.   ==============================================================================
  28.     [..]
  29.       The PCD HAL driver can be used as follows:
  30.  
  31.      (#) Declare a PCD_HandleTypeDef handle structure, for example:
  32.          PCD_HandleTypeDef  hpcd;
  33.  
  34.      (#) Fill parameters of Init structure in HCD handle
  35.  
  36.      (#) Call HAL_PCD_Init() API to initialize the PCD peripheral (Core, Device core, ...)
  37.  
  38.      (#) Initialize the PCD low level resources through the HAL_PCD_MspInit() API:
  39.          (##) Enable the PCD/USB Low Level interface clock using
  40.               (+++) __HAL_RCC_USB_CLK_ENABLE(); For USB Device FS peripheral
  41.  
  42.          (##) Initialize the related GPIO clocks
  43.          (##) Configure PCD pin-out
  44.          (##) Configure PCD NVIC interrupt
  45.  
  46.      (#)Associate the Upper USB device stack to the HAL PCD Driver:
  47.          (##) hpcd.pData = pdev;
  48.  
  49.      (#)Enable PCD transmission and reception:
  50.          (##) HAL_PCD_Start();
  51.  
  52.   @endverbatim
  53.   ******************************************************************************
  54.   */
  55.  
  56. /* Includes ------------------------------------------------------------------*/
  57. #include "stm32l1xx_hal.h"
  58.  
  59. /** @addtogroup STM32L1xx_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. #if (USE_USB_DOUBLE_BUFFER == 1U)
  92. static HAL_StatusTypeDef HAL_PCD_EP_DB_Transmit(PCD_HandleTypeDef *hpcd, PCD_EPTypeDef *ep, uint16_t wEPVal);
  93. static uint16_t HAL_PCD_EP_DB_Receive(PCD_HandleTypeDef *hpcd, PCD_EPTypeDef *ep, uint16_t wEPVal);
  94. #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
  95.  
  96. /**
  97.   * @}
  98.   */
  99.  
  100. /* Exported functions --------------------------------------------------------*/
  101. /** @defgroup PCD_Exported_Functions PCD Exported Functions
  102.   * @{
  103.   */
  104.  
  105. /** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
  106.   *  @brief    Initialization and Configuration functions
  107.   *
  108. @verbatim
  109.  ===============================================================================
  110.             ##### Initialization and de-initialization functions #####
  111.  ===============================================================================
  112.     [..]  This section provides functions allowing to:
  113.  
  114. @endverbatim
  115.   * @{
  116.   */
  117.  
  118. /**
  119.   * @brief  Initializes the PCD according to the specified
  120.   *         parameters in the PCD_InitTypeDef and initialize the associated handle.
  121.   * @param  hpcd PCD handle
  122.   * @retval HAL status
  123.   */
  124. HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd)
  125. {
  126.   uint8_t i;
  127.  
  128.   /* Check the PCD handle allocation */
  129.   if (hpcd == NULL)
  130.   {
  131.     return HAL_ERROR;
  132.   }
  133.  
  134.   /* Check the parameters */
  135.   assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance));
  136.  
  137.   if (hpcd->State == HAL_PCD_STATE_RESET)
  138.   {
  139.     /* Allocate lock resource and initialize it */
  140.     hpcd->Lock = HAL_UNLOCKED;
  141.  
  142. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  143.     hpcd->SOFCallback = HAL_PCD_SOFCallback;
  144.     hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
  145.     hpcd->ResetCallback = HAL_PCD_ResetCallback;
  146.     hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
  147.     hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
  148.     hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
  149.     hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
  150.     hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback;
  151.     hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback;
  152.     hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback;
  153.     hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback;
  154.  
  155.     if (hpcd->MspInitCallback == NULL)
  156.     {
  157.       hpcd->MspInitCallback = HAL_PCD_MspInit;
  158.     }
  159.  
  160.     /* Init the low level hardware */
  161.     hpcd->MspInitCallback(hpcd);
  162. #else
  163.     /* Init the low level hardware : GPIO, CLOCK, NVIC... */
  164.     HAL_PCD_MspInit(hpcd);
  165. #endif /* (USE_HAL_PCD_REGISTER_CALLBACKS) */
  166.   }
  167.  
  168.   hpcd->State = HAL_PCD_STATE_BUSY;
  169.  
  170.   /* Disable the Interrupts */
  171.   __HAL_PCD_DISABLE(hpcd);
  172.  
  173.   /* Init endpoints structures */
  174.   for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
  175.   {
  176.     /* Init ep structure */
  177.     hpcd->IN_ep[i].is_in = 1U;
  178.     hpcd->IN_ep[i].num = i;
  179.     /* Control until ep is activated */
  180.     hpcd->IN_ep[i].type = EP_TYPE_CTRL;
  181.     hpcd->IN_ep[i].maxpacket = 0U;
  182.     hpcd->IN_ep[i].xfer_buff = 0U;
  183.     hpcd->IN_ep[i].xfer_len = 0U;
  184.   }
  185.  
  186.   for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
  187.   {
  188.     hpcd->OUT_ep[i].is_in = 0U;
  189.     hpcd->OUT_ep[i].num = i;
  190.     /* Control until ep is activated */
  191.     hpcd->OUT_ep[i].type = EP_TYPE_CTRL;
  192.     hpcd->OUT_ep[i].maxpacket = 0U;
  193.     hpcd->OUT_ep[i].xfer_buff = 0U;
  194.     hpcd->OUT_ep[i].xfer_len = 0U;
  195.   }
  196.  
  197.   /* Init Device */
  198.   (void)USB_DevInit(hpcd->Instance, hpcd->Init);
  199.  
  200.   hpcd->USB_Address = 0U;
  201.   hpcd->State = HAL_PCD_STATE_READY;
  202.   return HAL_OK;
  203. }
  204.  
  205. /**
  206.   * @brief  DeInitializes the PCD peripheral.
  207.   * @param  hpcd PCD handle
  208.   * @retval HAL status
  209.   */
  210. HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
  211. {
  212.   /* Check the PCD handle allocation */
  213.   if (hpcd == NULL)
  214.   {
  215.     return HAL_ERROR;
  216.   }
  217.  
  218.   hpcd->State = HAL_PCD_STATE_BUSY;
  219.  
  220.   /* Stop Device */
  221.   if (USB_StopDevice(hpcd->Instance) != HAL_OK)
  222.   {
  223.     return HAL_ERROR;
  224.   }
  225.  
  226. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  227.   if (hpcd->MspDeInitCallback == NULL)
  228.   {
  229.     hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; /* Legacy weak MspDeInit  */
  230.   }
  231.  
  232.   /* DeInit the low level hardware */
  233.   hpcd->MspDeInitCallback(hpcd);
  234. #else
  235.   /* DeInit the low level hardware: CLOCK, NVIC.*/
  236.   HAL_PCD_MspDeInit(hpcd);
  237. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  238.  
  239.   hpcd->State = HAL_PCD_STATE_RESET;
  240.  
  241.   return HAL_OK;
  242. }
  243.  
  244. /**
  245.   * @brief  Initializes the PCD MSP.
  246.   * @param  hpcd PCD handle
  247.   * @retval None
  248.   */
  249. __weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
  250. {
  251.   /* Prevent unused argument(s) compilation warning */
  252.   UNUSED(hpcd);
  253.  
  254.   /* NOTE : This function should not be modified, when the callback is needed,
  255.             the HAL_PCD_MspInit could be implemented in the user file
  256.    */
  257. }
  258.  
  259. /**
  260.   * @brief  DeInitializes PCD MSP.
  261.   * @param  hpcd PCD handle
  262.   * @retval None
  263.   */
  264. __weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
  265. {
  266.   /* Prevent unused argument(s) compilation warning */
  267.   UNUSED(hpcd);
  268.  
  269.   /* NOTE : This function should not be modified, when the callback is needed,
  270.             the HAL_PCD_MspDeInit could be implemented in the user file
  271.    */
  272. }
  273.  
  274. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  275. /**
  276.   * @brief  Register a User USB PCD Callback
  277.   *         To be used instead of the weak predefined callback
  278.   * @param  hpcd USB PCD handle
  279.   * @param  CallbackID ID of the callback to be registered
  280.   *         This parameter can be one of the following values:
  281.   *          @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
  282.   *          @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
  283.   *          @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
  284.   *          @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
  285.   *          @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
  286.   *          @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
  287.   *          @arg @ref HAL_PCD_DISCONNECT_CB_ID USB PCD Disconnect callback ID
  288.   *          @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
  289.   *          @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
  290.   * @param  pCallback pointer to the Callback function
  291.   * @retval HAL status
  292.   */
  293. HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd,
  294.                                            HAL_PCD_CallbackIDTypeDef CallbackID,
  295.                                            pPCD_CallbackTypeDef pCallback)
  296. {
  297.   HAL_StatusTypeDef status = HAL_OK;
  298.  
  299.   if (pCallback == NULL)
  300.   {
  301.     /* Update the error code */
  302.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  303.     return HAL_ERROR;
  304.   }
  305.   /* Process locked */
  306.   __HAL_LOCK(hpcd);
  307.  
  308.   if (hpcd->State == HAL_PCD_STATE_READY)
  309.   {
  310.     switch (CallbackID)
  311.     {
  312.       case HAL_PCD_SOF_CB_ID :
  313.         hpcd->SOFCallback = pCallback;
  314.         break;
  315.  
  316.       case HAL_PCD_SETUPSTAGE_CB_ID :
  317.         hpcd->SetupStageCallback = pCallback;
  318.         break;
  319.  
  320.       case HAL_PCD_RESET_CB_ID :
  321.         hpcd->ResetCallback = pCallback;
  322.         break;
  323.  
  324.       case HAL_PCD_SUSPEND_CB_ID :
  325.         hpcd->SuspendCallback = pCallback;
  326.         break;
  327.  
  328.       case HAL_PCD_RESUME_CB_ID :
  329.         hpcd->ResumeCallback = pCallback;
  330.         break;
  331.  
  332.       case HAL_PCD_CONNECT_CB_ID :
  333.         hpcd->ConnectCallback = pCallback;
  334.         break;
  335.  
  336.       case HAL_PCD_DISCONNECT_CB_ID :
  337.         hpcd->DisconnectCallback = pCallback;
  338.         break;
  339.  
  340.       case HAL_PCD_MSPINIT_CB_ID :
  341.         hpcd->MspInitCallback = pCallback;
  342.         break;
  343.  
  344.       case HAL_PCD_MSPDEINIT_CB_ID :
  345.         hpcd->MspDeInitCallback = pCallback;
  346.         break;
  347.  
  348.       default :
  349.         /* Update the error code */
  350.         hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  351.         /* Return error status */
  352.         status =  HAL_ERROR;
  353.         break;
  354.     }
  355.   }
  356.   else if (hpcd->State == HAL_PCD_STATE_RESET)
  357.   {
  358.     switch (CallbackID)
  359.     {
  360.       case HAL_PCD_MSPINIT_CB_ID :
  361.         hpcd->MspInitCallback = pCallback;
  362.         break;
  363.  
  364.       case HAL_PCD_MSPDEINIT_CB_ID :
  365.         hpcd->MspDeInitCallback = pCallback;
  366.         break;
  367.  
  368.       default :
  369.         /* Update the error code */
  370.         hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  371.         /* Return error status */
  372.         status =  HAL_ERROR;
  373.         break;
  374.     }
  375.   }
  376.   else
  377.   {
  378.     /* Update the error code */
  379.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  380.     /* Return error status */
  381.     status =  HAL_ERROR;
  382.   }
  383.  
  384.   /* Release Lock */
  385.   __HAL_UNLOCK(hpcd);
  386.   return status;
  387. }
  388.  
  389. /**
  390.   * @brief  Unregister an USB PCD Callback
  391.   *         USB PCD callback is redirected to the weak predefined callback
  392.   * @param  hpcd USB PCD handle
  393.   * @param  CallbackID ID of the callback to be unregistered
  394.   *         This parameter can be one of the following values:
  395.   *          @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
  396.   *          @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
  397.   *          @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
  398.   *          @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
  399.   *          @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
  400.   *          @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
  401.   *          @arg @ref HAL_PCD_DISCONNECT_CB_ID USB PCD Disconnect callback ID
  402.   *          @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
  403.   *          @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
  404.   * @retval HAL status
  405.   */
  406. HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID)
  407. {
  408.   HAL_StatusTypeDef status = HAL_OK;
  409.  
  410.   /* Process locked */
  411.   __HAL_LOCK(hpcd);
  412.  
  413.   /* Setup Legacy weak Callbacks  */
  414.   if (hpcd->State == HAL_PCD_STATE_READY)
  415.   {
  416.     switch (CallbackID)
  417.     {
  418.       case HAL_PCD_SOF_CB_ID :
  419.         hpcd->SOFCallback = HAL_PCD_SOFCallback;
  420.         break;
  421.  
  422.       case HAL_PCD_SETUPSTAGE_CB_ID :
  423.         hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
  424.         break;
  425.  
  426.       case HAL_PCD_RESET_CB_ID :
  427.         hpcd->ResetCallback = HAL_PCD_ResetCallback;
  428.         break;
  429.  
  430.       case HAL_PCD_SUSPEND_CB_ID :
  431.         hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
  432.         break;
  433.  
  434.       case HAL_PCD_RESUME_CB_ID :
  435.         hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
  436.         break;
  437.  
  438.       case HAL_PCD_CONNECT_CB_ID :
  439.         hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
  440.         break;
  441.  
  442.       case HAL_PCD_DISCONNECT_CB_ID :
  443.         hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
  444.         break;
  445.  
  446.       case HAL_PCD_MSPINIT_CB_ID :
  447.         hpcd->MspInitCallback = HAL_PCD_MspInit;
  448.         break;
  449.  
  450.       case HAL_PCD_MSPDEINIT_CB_ID :
  451.         hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
  452.         break;
  453.  
  454.       default :
  455.         /* Update the error code */
  456.         hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  457.  
  458.         /* Return error status */
  459.         status =  HAL_ERROR;
  460.         break;
  461.     }
  462.   }
  463.   else if (hpcd->State == HAL_PCD_STATE_RESET)
  464.   {
  465.     switch (CallbackID)
  466.     {
  467.       case HAL_PCD_MSPINIT_CB_ID :
  468.         hpcd->MspInitCallback = HAL_PCD_MspInit;
  469.         break;
  470.  
  471.       case HAL_PCD_MSPDEINIT_CB_ID :
  472.         hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
  473.         break;
  474.  
  475.       default :
  476.         /* Update the error code */
  477.         hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  478.  
  479.         /* Return error status */
  480.         status =  HAL_ERROR;
  481.         break;
  482.     }
  483.   }
  484.   else
  485.   {
  486.     /* Update the error code */
  487.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  488.  
  489.     /* Return error status */
  490.     status =  HAL_ERROR;
  491.   }
  492.  
  493.   /* Release Lock */
  494.   __HAL_UNLOCK(hpcd);
  495.   return status;
  496. }
  497.  
  498. /**
  499.   * @brief  Register USB PCD Data OUT Stage Callback
  500.   *         To be used instead of the weak HAL_PCD_DataOutStageCallback() predefined callback
  501.   * @param  hpcd PCD handle
  502.   * @param  pCallback pointer to the USB PCD Data OUT Stage Callback function
  503.   * @retval HAL status
  504.   */
  505. HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd,
  506.                                                        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,
  580.                                                       pPCD_DataInStageCallbackTypeDef pCallback)
  581. {
  582.   HAL_StatusTypeDef status = HAL_OK;
  583.  
  584.   if (pCallback == NULL)
  585.   {
  586.     /* Update the error code */
  587.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  588.  
  589.     return HAL_ERROR;
  590.   }
  591.  
  592.   /* Process locked */
  593.   __HAL_LOCK(hpcd);
  594.  
  595.   if (hpcd->State == HAL_PCD_STATE_READY)
  596.   {
  597.     hpcd->DataInStageCallback = pCallback;
  598.   }
  599.   else
  600.   {
  601.     /* Update the error code */
  602.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  603.  
  604.     /* Return error status */
  605.     status =  HAL_ERROR;
  606.   }
  607.  
  608.   /* Release Lock */
  609.   __HAL_UNLOCK(hpcd);
  610.  
  611.   return status;
  612. }
  613.  
  614. /**
  615.   * @brief  Unregister the USB PCD Data IN Stage Callback
  616.   *         USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataInStageCallback() predefined callback
  617.   * @param  hpcd PCD handle
  618.   * @retval HAL status
  619.   */
  620. HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd)
  621. {
  622.   HAL_StatusTypeDef status = HAL_OK;
  623.  
  624.   /* Process locked */
  625.   __HAL_LOCK(hpcd);
  626.  
  627.   if (hpcd->State == HAL_PCD_STATE_READY)
  628.   {
  629.     hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback; /* Legacy weak DataInStageCallback  */
  630.   }
  631.   else
  632.   {
  633.     /* Update the error code */
  634.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  635.  
  636.     /* Return error status */
  637.     status =  HAL_ERROR;
  638.   }
  639.  
  640.   /* Release Lock */
  641.   __HAL_UNLOCK(hpcd);
  642.  
  643.   return status;
  644. }
  645.  
  646. /**
  647.   * @brief  Register USB PCD Iso OUT incomplete Callback
  648.   *         To be used instead of the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
  649.   * @param  hpcd PCD handle
  650.   * @param  pCallback pointer to the USB PCD Iso OUT incomplete Callback function
  651.   * @retval HAL status
  652.   */
  653. HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd,
  654.                                                        pPCD_IsoOutIncpltCallbackTypeDef pCallback)
  655. {
  656.   HAL_StatusTypeDef status = HAL_OK;
  657.  
  658.   if (pCallback == NULL)
  659.   {
  660.     /* Update the error code */
  661.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  662.  
  663.     return HAL_ERROR;
  664.   }
  665.  
  666.   /* Process locked */
  667.   __HAL_LOCK(hpcd);
  668.  
  669.   if (hpcd->State == HAL_PCD_STATE_READY)
  670.   {
  671.     hpcd->ISOOUTIncompleteCallback = pCallback;
  672.   }
  673.   else
  674.   {
  675.     /* Update the error code */
  676.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  677.  
  678.     /* Return error status */
  679.     status =  HAL_ERROR;
  680.   }
  681.  
  682.   /* Release Lock */
  683.   __HAL_UNLOCK(hpcd);
  684.  
  685.   return status;
  686. }
  687.  
  688. /**
  689.   * @brief  Unregister the USB PCD Iso OUT incomplete Callback
  690.   *         USB PCD Iso OUT incomplete Callback is redirected
  691.   *         to the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
  692.   * @param  hpcd PCD handle
  693.   * @retval HAL status
  694.   */
  695. HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd)
  696. {
  697.   HAL_StatusTypeDef status = HAL_OK;
  698.  
  699.   /* Process locked */
  700.   __HAL_LOCK(hpcd);
  701.  
  702.   if (hpcd->State == HAL_PCD_STATE_READY)
  703.   {
  704.     hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback; /* Legacy weak ISOOUTIncompleteCallback  */
  705.   }
  706.   else
  707.   {
  708.     /* Update the error code */
  709.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  710.  
  711.     /* Return error status */
  712.     status =  HAL_ERROR;
  713.   }
  714.  
  715.   /* Release Lock */
  716.   __HAL_UNLOCK(hpcd);
  717.  
  718.   return status;
  719. }
  720.  
  721. /**
  722.   * @brief  Register USB PCD Iso IN incomplete Callback
  723.   *         To be used instead of the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
  724.   * @param  hpcd PCD handle
  725.   * @param  pCallback pointer to the USB PCD Iso IN incomplete Callback function
  726.   * @retval HAL status
  727.   */
  728. HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd,
  729.                                                       pPCD_IsoInIncpltCallbackTypeDef pCallback)
  730. {
  731.   HAL_StatusTypeDef status = HAL_OK;
  732.  
  733.   if (pCallback == NULL)
  734.   {
  735.     /* Update the error code */
  736.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  737.  
  738.     return HAL_ERROR;
  739.   }
  740.  
  741.   /* Process locked */
  742.   __HAL_LOCK(hpcd);
  743.  
  744.   if (hpcd->State == HAL_PCD_STATE_READY)
  745.   {
  746.     hpcd->ISOINIncompleteCallback = pCallback;
  747.   }
  748.   else
  749.   {
  750.     /* Update the error code */
  751.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  752.  
  753.     /* Return error status */
  754.     status =  HAL_ERROR;
  755.   }
  756.  
  757.   /* Release Lock */
  758.   __HAL_UNLOCK(hpcd);
  759.  
  760.   return status;
  761. }
  762.  
  763. /**
  764.   * @brief  Unregister the USB PCD Iso IN incomplete Callback
  765.   *         USB PCD Iso IN incomplete Callback is redirected
  766.   *         to the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
  767.   * @param  hpcd PCD handle
  768.   * @retval HAL status
  769.   */
  770. HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd)
  771. {
  772.   HAL_StatusTypeDef status = HAL_OK;
  773.  
  774.   /* Process locked */
  775.   __HAL_LOCK(hpcd);
  776.  
  777.   if (hpcd->State == HAL_PCD_STATE_READY)
  778.   {
  779.     hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback; /* Legacy weak ISOINIncompleteCallback  */
  780.   }
  781.   else
  782.   {
  783.     /* Update the error code */
  784.     hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  785.  
  786.     /* Return error status */
  787.     status =  HAL_ERROR;
  788.   }
  789.  
  790.   /* Release Lock */
  791.   __HAL_UNLOCK(hpcd);
  792.  
  793.   return status;
  794. }
  795.  
  796. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  797.  
  798. /**
  799.   * @}
  800.   */
  801.  
  802. /** @defgroup PCD_Exported_Functions_Group2 Input and Output operation functions
  803.   *  @brief   Data transfers functions
  804.   *
  805. @verbatim
  806.  ===============================================================================
  807.                       ##### IO operation functions #####
  808.  ===============================================================================
  809.     [..]
  810.     This subsection provides a set of functions allowing to manage the PCD data
  811.     transfers.
  812.  
  813. @endverbatim
  814.   * @{
  815.   */
  816.  
  817. /**
  818.   * @brief  Start the USB device
  819.   * @param  hpcd PCD handle
  820.   * @retval HAL status
  821.   */
  822. HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)
  823. {
  824.   __HAL_LOCK(hpcd);
  825.   __HAL_PCD_ENABLE(hpcd);
  826.  
  827.   HAL_PCDEx_SetConnectionState(hpcd, 1U);
  828.  
  829.   (void)USB_DevConnect(hpcd->Instance);
  830.   __HAL_UNLOCK(hpcd);
  831.  
  832.   return HAL_OK;
  833. }
  834.  
  835. /**
  836.   * @brief  Stop the USB device.
  837.   * @param  hpcd PCD handle
  838.   * @retval HAL status
  839.   */
  840. HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
  841. {
  842.   __HAL_LOCK(hpcd);
  843.   __HAL_PCD_DISABLE(hpcd);
  844.  
  845.   HAL_PCDEx_SetConnectionState(hpcd, 0U);
  846.  
  847.   (void)USB_DevDisconnect(hpcd->Instance);
  848.   __HAL_UNLOCK(hpcd);
  849.  
  850.   return HAL_OK;
  851. }
  852.  
  853.  
  854. /**
  855.   * @brief  This function handles PCD interrupt request.
  856.   * @param  hpcd PCD handle
  857.   * @retval HAL status
  858.   */
  859. void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
  860. {
  861.   uint32_t wIstr = USB_ReadInterrupts(hpcd->Instance);
  862.  
  863.   if ((wIstr & USB_ISTR_CTR) == USB_ISTR_CTR)
  864.   {
  865.     /* servicing of the endpoint correct transfer interrupt */
  866.     /* clear of the CTR flag into the sub */
  867.     (void)PCD_EP_ISR_Handler(hpcd);
  868.  
  869.     return;
  870.   }
  871.  
  872.   if ((wIstr & USB_ISTR_RESET) == USB_ISTR_RESET)
  873.   {
  874.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET);
  875.  
  876. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  877.     hpcd->ResetCallback(hpcd);
  878. #else
  879.     HAL_PCD_ResetCallback(hpcd);
  880. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  881.  
  882.     (void)HAL_PCD_SetAddress(hpcd, 0U);
  883.  
  884.     return;
  885.   }
  886.  
  887.   if ((wIstr & USB_ISTR_PMAOVR) == USB_ISTR_PMAOVR)
  888.   {
  889.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_PMAOVR);
  890.  
  891.     return;
  892.   }
  893.  
  894.   if ((wIstr & USB_ISTR_ERR) == USB_ISTR_ERR)
  895.   {
  896.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ERR);
  897.  
  898.     return;
  899.   }
  900.  
  901.   if ((wIstr & USB_ISTR_WKUP) == USB_ISTR_WKUP)
  902.   {
  903.     hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_LPMODE);
  904.     hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_FSUSP);
  905.  
  906. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  907.     hpcd->ResumeCallback(hpcd);
  908. #else
  909.     HAL_PCD_ResumeCallback(hpcd);
  910. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  911.  
  912.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP);
  913.  
  914.     return;
  915.   }
  916.  
  917.   if ((wIstr & USB_ISTR_SUSP) == USB_ISTR_SUSP)
  918.   {
  919.     /* Force low-power mode in the macrocell */
  920.     hpcd->Instance->CNTR |= (uint16_t)USB_CNTR_FSUSP;
  921.  
  922.     /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
  923.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SUSP);
  924.  
  925.     hpcd->Instance->CNTR |= (uint16_t)USB_CNTR_LPMODE;
  926.  
  927. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  928.     hpcd->SuspendCallback(hpcd);
  929. #else
  930.     HAL_PCD_SuspendCallback(hpcd);
  931. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  932.  
  933.     return;
  934.   }
  935.  
  936.   if ((wIstr & USB_ISTR_SOF) == USB_ISTR_SOF)
  937.   {
  938.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SOF);
  939.  
  940. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  941.     hpcd->SOFCallback(hpcd);
  942. #else
  943.     HAL_PCD_SOFCallback(hpcd);
  944. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  945.  
  946.     return;
  947.   }
  948.  
  949.   if ((wIstr & USB_ISTR_ESOF) == USB_ISTR_ESOF)
  950.   {
  951.     /* clear ESOF flag in ISTR */
  952.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ESOF);
  953.  
  954.     return;
  955.   }
  956. }
  957.  
  958.  
  959. /**
  960.   * @brief  Handles PCD Wakeup interrupt request.
  961.   * @param  hpcd PCD handle
  962.   * @retval HAL status
  963.   */
  964. void HAL_PCD_WKUP_IRQHandler(PCD_HandleTypeDef *hpcd)
  965. {
  966.   /* Clear EXTI pending Bit */
  967.   __HAL_USB_WAKEUP_EXTI_CLEAR_FLAG();
  968. }
  969.  
  970.  
  971. /**
  972.   * @brief  Data OUT stage callback.
  973.   * @param  hpcd PCD handle
  974.   * @param  epnum endpoint number
  975.   * @retval None
  976.   */
  977. __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  978. {
  979.   /* Prevent unused argument(s) compilation warning */
  980.   UNUSED(hpcd);
  981.   UNUSED(epnum);
  982.  
  983.   /* NOTE : This function should not be modified, when the callback is needed,
  984.             the HAL_PCD_DataOutStageCallback could be implemented in the user file
  985.    */
  986. }
  987.  
  988. /**
  989.   * @brief  Data IN stage callback
  990.   * @param  hpcd PCD handle
  991.   * @param  epnum endpoint number
  992.   * @retval None
  993.   */
  994. __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  995. {
  996.   /* Prevent unused argument(s) compilation warning */
  997.   UNUSED(hpcd);
  998.   UNUSED(epnum);
  999.  
  1000.   /* NOTE : This function should not be modified, when the callback is needed,
  1001.             the HAL_PCD_DataInStageCallback could be implemented in the user file
  1002.    */
  1003. }
  1004. /**
  1005.   * @brief  Setup stage callback
  1006.   * @param  hpcd PCD handle
  1007.   * @retval None
  1008.   */
  1009. __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
  1010. {
  1011.   /* Prevent unused argument(s) compilation warning */
  1012.   UNUSED(hpcd);
  1013.  
  1014.   /* NOTE : This function should not be modified, when the callback is needed,
  1015.             the HAL_PCD_SetupStageCallback could be implemented in the user file
  1016.    */
  1017. }
  1018.  
  1019. /**
  1020.   * @brief  USB Start Of Frame callback.
  1021.   * @param  hpcd PCD handle
  1022.   * @retval None
  1023.   */
  1024. __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
  1025. {
  1026.   /* Prevent unused argument(s) compilation warning */
  1027.   UNUSED(hpcd);
  1028.  
  1029.   /* NOTE : This function should not be modified, when the callback is needed,
  1030.             the HAL_PCD_SOFCallback could be implemented in the user file
  1031.    */
  1032. }
  1033.  
  1034. /**
  1035.   * @brief  USB Reset callback.
  1036.   * @param  hpcd PCD handle
  1037.   * @retval None
  1038.   */
  1039. __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
  1040. {
  1041.   /* Prevent unused argument(s) compilation warning */
  1042.   UNUSED(hpcd);
  1043.  
  1044.   /* NOTE : This function should not be modified, when the callback is needed,
  1045.             the HAL_PCD_ResetCallback could be implemented in the user file
  1046.    */
  1047. }
  1048.  
  1049. /**
  1050.   * @brief  Suspend event callback.
  1051.   * @param  hpcd PCD handle
  1052.   * @retval None
  1053.   */
  1054. __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
  1055. {
  1056.   /* Prevent unused argument(s) compilation warning */
  1057.   UNUSED(hpcd);
  1058.  
  1059.   /* NOTE : This function should not be modified, when the callback is needed,
  1060.             the HAL_PCD_SuspendCallback could be implemented in the user file
  1061.    */
  1062. }
  1063.  
  1064. /**
  1065.   * @brief  Resume event callback.
  1066.   * @param  hpcd PCD handle
  1067.   * @retval None
  1068.   */
  1069. __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
  1070. {
  1071.   /* Prevent unused argument(s) compilation warning */
  1072.   UNUSED(hpcd);
  1073.  
  1074.   /* NOTE : This function should not be modified, when the callback is needed,
  1075.             the HAL_PCD_ResumeCallback could be implemented in the user file
  1076.    */
  1077. }
  1078.  
  1079. /**
  1080.   * @brief  Incomplete ISO OUT callback.
  1081.   * @param  hpcd PCD handle
  1082.   * @param  epnum endpoint number
  1083.   * @retval None
  1084.   */
  1085. __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  1086. {
  1087.   /* Prevent unused argument(s) compilation warning */
  1088.   UNUSED(hpcd);
  1089.   UNUSED(epnum);
  1090.  
  1091.   /* NOTE : This function should not be modified, when the callback is needed,
  1092.             the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file
  1093.    */
  1094. }
  1095.  
  1096. /**
  1097.   * @brief  Incomplete ISO IN callback.
  1098.   * @param  hpcd PCD handle
  1099.   * @param  epnum endpoint number
  1100.   * @retval None
  1101.   */
  1102. __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  1103. {
  1104.   /* Prevent unused argument(s) compilation warning */
  1105.   UNUSED(hpcd);
  1106.   UNUSED(epnum);
  1107.  
  1108.   /* NOTE : This function should not be modified, when the callback is needed,
  1109.             the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file
  1110.    */
  1111. }
  1112.  
  1113. /**
  1114.   * @brief  Connection event callback.
  1115.   * @param  hpcd PCD handle
  1116.   * @retval None
  1117.   */
  1118. __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
  1119. {
  1120.   /* Prevent unused argument(s) compilation warning */
  1121.   UNUSED(hpcd);
  1122.  
  1123.   /* NOTE : This function should not be modified, when the callback is needed,
  1124.             the HAL_PCD_ConnectCallback could be implemented in the user file
  1125.    */
  1126. }
  1127.  
  1128. /**
  1129.   * @brief  Disconnection event callback.
  1130.   * @param  hpcd PCD handle
  1131.   * @retval None
  1132.   */
  1133. __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
  1134. {
  1135.   /* Prevent unused argument(s) compilation warning */
  1136.   UNUSED(hpcd);
  1137.  
  1138.   /* NOTE : This function should not be modified, when the callback is needed,
  1139.             the HAL_PCD_DisconnectCallback could be implemented in the user file
  1140.    */
  1141. }
  1142.  
  1143. /**
  1144.   * @}
  1145.   */
  1146.  
  1147. /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
  1148.   *  @brief   management functions
  1149.   *
  1150. @verbatim
  1151.  ===============================================================================
  1152.                       ##### Peripheral Control functions #####
  1153.  ===============================================================================
  1154.     [..]
  1155.     This subsection provides a set of functions allowing to control the PCD data
  1156.     transfers.
  1157.  
  1158. @endverbatim
  1159.   * @{
  1160.   */
  1161.  
  1162. /**
  1163.   * @brief  Connect the USB device
  1164.   * @param  hpcd PCD handle
  1165.   * @retval HAL status
  1166.   */
  1167. HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd)
  1168. {
  1169.   __HAL_LOCK(hpcd);
  1170.  
  1171.   HAL_PCDEx_SetConnectionState(hpcd, 1U);
  1172.  
  1173.   (void)USB_DevConnect(hpcd->Instance);
  1174.   __HAL_UNLOCK(hpcd);
  1175.  
  1176.   return HAL_OK;
  1177. }
  1178.  
  1179. /**
  1180.   * @brief  Disconnect the USB device.
  1181.   * @param  hpcd PCD handle
  1182.   * @retval HAL status
  1183.   */
  1184. HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd)
  1185. {
  1186.   __HAL_LOCK(hpcd);
  1187.  
  1188.   HAL_PCDEx_SetConnectionState(hpcd, 0U);
  1189.  
  1190.   (void)USB_DevDisconnect(hpcd->Instance);
  1191.   __HAL_UNLOCK(hpcd);
  1192.  
  1193.   return HAL_OK;
  1194. }
  1195.  
  1196. /**
  1197.   * @brief  Set the USB Device address.
  1198.   * @param  hpcd PCD handle
  1199.   * @param  address new device address
  1200.   * @retval HAL status
  1201.   */
  1202. HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)
  1203. {
  1204.   __HAL_LOCK(hpcd);
  1205.   hpcd->USB_Address = address;
  1206.   (void)USB_SetDevAddress(hpcd->Instance, address);
  1207.   __HAL_UNLOCK(hpcd);
  1208.  
  1209.   return HAL_OK;
  1210. }
  1211. /**
  1212.   * @brief  Open and configure an endpoint.
  1213.   * @param  hpcd PCD handle
  1214.   * @param  ep_addr endpoint address
  1215.   * @param  ep_mps endpoint max packet size
  1216.   * @param  ep_type endpoint type
  1217.   * @retval HAL status
  1218.   */
  1219. HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr,
  1220.                                   uint16_t ep_mps, uint8_t ep_type)
  1221. {
  1222.   HAL_StatusTypeDef  ret = HAL_OK;
  1223.   PCD_EPTypeDef *ep;
  1224.  
  1225.   if ((ep_addr & 0x80U) == 0x80U)
  1226.   {
  1227.     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1228.     ep->is_in = 1U;
  1229.   }
  1230.   else
  1231.   {
  1232.     ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1233.     ep->is_in = 0U;
  1234.   }
  1235.  
  1236.   ep->num = ep_addr & EP_ADDR_MSK;
  1237.   ep->maxpacket = ep_mps;
  1238.   ep->type = ep_type;
  1239.  
  1240.   /* Set initial data PID. */
  1241.   if (ep_type == EP_TYPE_BULK)
  1242.   {
  1243.     ep->data_pid_start = 0U;
  1244.   }
  1245.  
  1246.   __HAL_LOCK(hpcd);
  1247.   (void)USB_ActivateEndpoint(hpcd->Instance, ep);
  1248.   __HAL_UNLOCK(hpcd);
  1249.  
  1250.   return ret;
  1251. }
  1252.  
  1253. /**
  1254.   * @brief  Deactivate an endpoint.
  1255.   * @param  hpcd PCD handle
  1256.   * @param  ep_addr endpoint address
  1257.   * @retval HAL status
  1258.   */
  1259. HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1260. {
  1261.   PCD_EPTypeDef *ep;
  1262.  
  1263.   if ((ep_addr & 0x80U) == 0x80U)
  1264.   {
  1265.     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1266.     ep->is_in = 1U;
  1267.   }
  1268.   else
  1269.   {
  1270.     ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1271.     ep->is_in = 0U;
  1272.   }
  1273.   ep->num = ep_addr & EP_ADDR_MSK;
  1274.  
  1275.   __HAL_LOCK(hpcd);
  1276.   (void)USB_DeactivateEndpoint(hpcd->Instance, ep);
  1277.   __HAL_UNLOCK(hpcd);
  1278.   return HAL_OK;
  1279. }
  1280.  
  1281.  
  1282. /**
  1283.   * @brief  Receive an amount of data.
  1284.   * @param  hpcd PCD handle
  1285.   * @param  ep_addr endpoint address
  1286.   * @param  pBuf pointer to the reception buffer
  1287.   * @param  len amount of data to be received
  1288.   * @retval HAL status
  1289.   */
  1290. HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
  1291. {
  1292.   PCD_EPTypeDef *ep;
  1293.  
  1294.   ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1295.  
  1296.   /*setup and start the Xfer */
  1297.   ep->xfer_buff = pBuf;
  1298.   ep->xfer_len = len;
  1299.   ep->xfer_count = 0U;
  1300.   ep->is_in = 0U;
  1301.   ep->num = ep_addr & EP_ADDR_MSK;
  1302.  
  1303.   (void)USB_EPStartXfer(hpcd->Instance, ep);
  1304.  
  1305.   return HAL_OK;
  1306. }
  1307.  
  1308. /**
  1309.   * @brief  Get Received Data Size
  1310.   * @param  hpcd PCD handle
  1311.   * @param  ep_addr endpoint address
  1312.   * @retval Data Size
  1313.   */
  1314. uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef const *hpcd, uint8_t ep_addr)
  1315. {
  1316.   return hpcd->OUT_ep[ep_addr & EP_ADDR_MSK].xfer_count;
  1317. }
  1318. /**
  1319.   * @brief  Send an amount of data
  1320.   * @param  hpcd PCD handle
  1321.   * @param  ep_addr endpoint address
  1322.   * @param  pBuf pointer to the transmission buffer
  1323.   * @param  len amount of data to be sent
  1324.   * @retval HAL status
  1325.   */
  1326. HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
  1327. {
  1328.   PCD_EPTypeDef *ep;
  1329.  
  1330.   ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1331.  
  1332.   /*setup and start the Xfer */
  1333.   ep->xfer_buff = pBuf;
  1334.   ep->xfer_len = len;
  1335.   ep->xfer_fill_db = 1U;
  1336.   ep->xfer_len_db = len;
  1337.   ep->xfer_count = 0U;
  1338.   ep->is_in = 1U;
  1339.   ep->num = ep_addr & EP_ADDR_MSK;
  1340.  
  1341.   (void)USB_EPStartXfer(hpcd->Instance, ep);
  1342.  
  1343.   return HAL_OK;
  1344. }
  1345.  
  1346. /**
  1347.   * @brief  Set a STALL condition over an endpoint
  1348.   * @param  hpcd PCD handle
  1349.   * @param  ep_addr endpoint address
  1350.   * @retval HAL status
  1351.   */
  1352. HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1353. {
  1354.   PCD_EPTypeDef *ep;
  1355.  
  1356.   if (((uint32_t)ep_addr & EP_ADDR_MSK) > hpcd->Init.dev_endpoints)
  1357.   {
  1358.     return HAL_ERROR;
  1359.   }
  1360.  
  1361.   if ((0x80U & ep_addr) == 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];
  1369.     ep->is_in = 0U;
  1370.   }
  1371.  
  1372.   ep->is_stall = 1U;
  1373.   ep->num = ep_addr & EP_ADDR_MSK;
  1374.  
  1375.   __HAL_LOCK(hpcd);
  1376.  
  1377.   (void)USB_EPSetStall(hpcd->Instance, ep);
  1378.  
  1379.   __HAL_UNLOCK(hpcd);
  1380.  
  1381.   return HAL_OK;
  1382. }
  1383.  
  1384. /**
  1385.   * @brief  Clear a STALL condition over in an endpoint
  1386.   * @param  hpcd PCD handle
  1387.   * @param  ep_addr endpoint address
  1388.   * @retval HAL status
  1389.   */
  1390. HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1391. {
  1392.   PCD_EPTypeDef *ep;
  1393.  
  1394.   if (((uint32_t)ep_addr & 0x0FU) > hpcd->Init.dev_endpoints)
  1395.   {
  1396.     return HAL_ERROR;
  1397.   }
  1398.  
  1399.   if ((0x80U & ep_addr) == 0x80U)
  1400.   {
  1401.     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1402.     ep->is_in = 1U;
  1403.   }
  1404.   else
  1405.   {
  1406.     ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1407.     ep->is_in = 0U;
  1408.   }
  1409.  
  1410.   ep->is_stall = 0U;
  1411.   ep->num = ep_addr & EP_ADDR_MSK;
  1412.  
  1413.   __HAL_LOCK(hpcd);
  1414.   (void)USB_EPClearStall(hpcd->Instance, ep);
  1415.   __HAL_UNLOCK(hpcd);
  1416.  
  1417.   return HAL_OK;
  1418. }
  1419.  
  1420. /**
  1421.    * @brief  Abort an USB EP transaction.
  1422.    * @param  hpcd PCD handle
  1423.    * @param  ep_addr endpoint address
  1424.    * @retval HAL status
  1425.    */
  1426. HAL_StatusTypeDef HAL_PCD_EP_Abort(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1427. {
  1428.   HAL_StatusTypeDef ret;
  1429.   PCD_EPTypeDef *ep;
  1430.  
  1431.   if ((0x80U & ep_addr) == 0x80U)
  1432.   {
  1433.     ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1434.   }
  1435.   else
  1436.   {
  1437.     ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1438.   }
  1439.  
  1440.   /* Stop Xfer */
  1441.   ret = USB_EPStopXfer(hpcd->Instance, ep);
  1442.  
  1443.   return ret;
  1444. }
  1445.  
  1446. /**
  1447.   * @brief  Flush an endpoint
  1448.   * @param  hpcd PCD handle
  1449.   * @param  ep_addr endpoint address
  1450.   * @retval HAL status
  1451.   */
  1452. HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1453. {
  1454.   __HAL_LOCK(hpcd);
  1455.  
  1456.   if ((ep_addr & 0x80U) == 0x80U)
  1457.   {
  1458.     (void)USB_FlushTxFifo(hpcd->Instance, (uint32_t)ep_addr & EP_ADDR_MSK);
  1459.   }
  1460.   else
  1461.   {
  1462.     (void)USB_FlushRxFifo(hpcd->Instance);
  1463.   }
  1464.  
  1465.   __HAL_UNLOCK(hpcd);
  1466.  
  1467.   return HAL_OK;
  1468. }
  1469.  
  1470. /**
  1471.   * @brief  Activate remote wakeup signalling
  1472.   * @param  hpcd PCD handle
  1473.   * @retval HAL status
  1474.   */
  1475. HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
  1476. {
  1477.   return (USB_ActivateRemoteWakeup(hpcd->Instance));
  1478. }
  1479.  
  1480. /**
  1481.   * @brief  De-activate remote wakeup signalling.
  1482.   * @param  hpcd PCD handle
  1483.   * @retval HAL status
  1484.   */
  1485. HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
  1486. {
  1487.   return (USB_DeActivateRemoteWakeup(hpcd->Instance));
  1488. }
  1489.  
  1490. /**
  1491.   * @}
  1492.   */
  1493.  
  1494. /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions
  1495.   *  @brief   Peripheral State functions
  1496.   *
  1497. @verbatim
  1498.  ===============================================================================
  1499.                       ##### Peripheral State functions #####
  1500.  ===============================================================================
  1501.     [..]
  1502.     This subsection permits to get in run-time the status of the peripheral
  1503.     and the data flow.
  1504.  
  1505. @endverbatim
  1506.   * @{
  1507.   */
  1508.  
  1509. /**
  1510.   * @brief  Return the PCD handle state.
  1511.   * @param  hpcd PCD handle
  1512.   * @retval HAL state
  1513.   */
  1514. PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef const *hpcd)
  1515. {
  1516.   return hpcd->State;
  1517. }
  1518.  
  1519. /**
  1520.   * @}
  1521.   */
  1522.  
  1523. /**
  1524.   * @}
  1525.   */
  1526.  
  1527. /* Private functions ---------------------------------------------------------*/
  1528. /** @addtogroup PCD_Private_Functions
  1529.   * @{
  1530.   */
  1531.  
  1532.  
  1533. /**
  1534.   * @brief  This function handles PCD Endpoint interrupt request.
  1535.   * @param  hpcd PCD handle
  1536.   * @retval HAL status
  1537.   */
  1538. static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
  1539. {
  1540.   PCD_EPTypeDef *ep;
  1541.   uint16_t count;
  1542.   uint16_t wIstr;
  1543.   uint16_t wEPVal;
  1544.   uint16_t TxPctSize;
  1545.   uint8_t epindex;
  1546.  
  1547. #if (USE_USB_DOUBLE_BUFFER != 1U)
  1548.   count = 0U;
  1549. #endif /* USE_USB_DOUBLE_BUFFER */
  1550.  
  1551.   /* stay in loop while pending interrupts */
  1552.   while ((hpcd->Instance->ISTR & USB_ISTR_CTR) != 0U)
  1553.   {
  1554.     wIstr = hpcd->Instance->ISTR;
  1555.  
  1556.     /* extract highest priority endpoint number */
  1557.     epindex = (uint8_t)(wIstr & USB_ISTR_EP_ID);
  1558.  
  1559.     if (epindex == 0U)
  1560.     {
  1561.       /* Decode and service control endpoint interrupt */
  1562.  
  1563.       /* DIR bit = origin of the interrupt */
  1564.       if ((wIstr & USB_ISTR_DIR) == 0U)
  1565.       {
  1566.         /* DIR = 0 */
  1567.  
  1568.         /* DIR = 0 => IN  int */
  1569.         /* DIR = 0 implies that (EP_CTR_TX = 1) always */
  1570.         PCD_CLEAR_TX_EP_CTR(hpcd->Instance, PCD_ENDP0);
  1571.         ep = &hpcd->IN_ep[0];
  1572.  
  1573.         ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
  1574.         ep->xfer_buff += ep->xfer_count;
  1575.  
  1576.         /* TX COMPLETE */
  1577. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1578.         hpcd->DataInStageCallback(hpcd, 0U);
  1579. #else
  1580.         HAL_PCD_DataInStageCallback(hpcd, 0U);
  1581. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1582.  
  1583.         if ((hpcd->USB_Address > 0U) && (ep->xfer_len == 0U))
  1584.         {
  1585.           hpcd->Instance->DADDR = ((uint16_t)hpcd->USB_Address | USB_DADDR_EF);
  1586.           hpcd->USB_Address = 0U;
  1587.         }
  1588.       }
  1589.       else
  1590.       {
  1591.         /* DIR = 1 */
  1592.  
  1593.         /* DIR = 1 & CTR_RX => SETUP or OUT int */
  1594.         /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */
  1595.         ep = &hpcd->OUT_ep[0];
  1596.         wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0);
  1597.  
  1598.         if ((wEPVal & USB_EP_SETUP) != 0U)
  1599.         {
  1600.           /* Get SETUP Packet */
  1601.           ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
  1602.  
  1603.           USB_ReadPMA(hpcd->Instance, (uint8_t *)hpcd->Setup,
  1604.                       ep->pmaadress, (uint16_t)ep->xfer_count);
  1605.  
  1606.           /* SETUP bit kept frozen while CTR_RX = 1 */
  1607.           PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
  1608.  
  1609.           /* Process SETUP Packet*/
  1610. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1611.           hpcd->SetupStageCallback(hpcd);
  1612. #else
  1613.           HAL_PCD_SetupStageCallback(hpcd);
  1614. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1615.         }
  1616.         else if ((wEPVal & USB_EP_CTR_RX) != 0U)
  1617.         {
  1618.           PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
  1619.  
  1620.           /* Get Control Data OUT Packet */
  1621.           ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
  1622.  
  1623.           if ((ep->xfer_count != 0U) && (ep->xfer_buff != 0U))
  1624.           {
  1625.             USB_ReadPMA(hpcd->Instance, ep->xfer_buff,
  1626.                         ep->pmaadress, (uint16_t)ep->xfer_count);
  1627.  
  1628.             ep->xfer_buff += ep->xfer_count;
  1629.  
  1630.             /* Process Control Data OUT Packet */
  1631. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1632.             hpcd->DataOutStageCallback(hpcd, 0U);
  1633. #else
  1634.             HAL_PCD_DataOutStageCallback(hpcd, 0U);
  1635. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1636.           }
  1637.  
  1638.           wEPVal = (uint16_t)PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0);
  1639.  
  1640.           if (((wEPVal & USB_EP_SETUP) == 0U) && ((wEPVal & USB_EP_RX_STRX) != USB_EP_RX_VALID))
  1641.           {
  1642.             PCD_SET_EP_RX_CNT(hpcd->Instance, PCD_ENDP0, ep->maxpacket);
  1643.             PCD_SET_EP_RX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_RX_VALID);
  1644.           }
  1645.         }
  1646.       }
  1647.     }
  1648.     else
  1649.     {
  1650.       /* Decode and service non control endpoints interrupt */
  1651.       /* process related endpoint register */
  1652.       wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, epindex);
  1653.  
  1654.       if ((wEPVal & USB_EP_CTR_RX) != 0U)
  1655.       {
  1656.         /* clear int flag */
  1657.         PCD_CLEAR_RX_EP_CTR(hpcd->Instance, epindex);
  1658.         ep = &hpcd->OUT_ep[epindex];
  1659.  
  1660.         /* OUT Single Buffering */
  1661.         if (ep->doublebuffer == 0U)
  1662.         {
  1663.           count = (uint16_t)PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
  1664.  
  1665.           if (count != 0U)
  1666.           {
  1667.             USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, count);
  1668.           }
  1669.         }
  1670. #if (USE_USB_DOUBLE_BUFFER == 1U)
  1671.         else
  1672.         {
  1673.           /* manage double buffer bulk out */
  1674.           if (ep->type == EP_TYPE_BULK)
  1675.           {
  1676.             count = HAL_PCD_EP_DB_Receive(hpcd, ep, wEPVal);
  1677.           }
  1678.           else /* manage double buffer iso out */
  1679.           {
  1680.             /* free EP OUT Buffer */
  1681.             PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 0U);
  1682.  
  1683.             if ((PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_RX) != 0U)
  1684.             {
  1685.               /* read from endpoint BUF0Addr buffer */
  1686.               count = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
  1687.  
  1688.               if (count != 0U)
  1689.               {
  1690.                 USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count);
  1691.               }
  1692.             }
  1693.             else
  1694.             {
  1695.               /* read from endpoint BUF1Addr buffer */
  1696.               count = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
  1697.  
  1698.               if (count != 0U)
  1699.               {
  1700.                 USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count);
  1701.               }
  1702.             }
  1703.           }
  1704.         }
  1705. #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
  1706.  
  1707.         /* multi-packet on the NON control OUT endpoint */
  1708.         ep->xfer_count += count;
  1709.         ep->xfer_buff += count;
  1710.  
  1711.         if ((ep->xfer_len == 0U) || (count < ep->maxpacket))
  1712.         {
  1713.           /* RX COMPLETE */
  1714. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1715.           hpcd->DataOutStageCallback(hpcd, ep->num);
  1716. #else
  1717.           HAL_PCD_DataOutStageCallback(hpcd, ep->num);
  1718. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1719.         }
  1720.         else
  1721.         {
  1722.           (void)USB_EPStartXfer(hpcd->Instance, ep);
  1723.         }
  1724.       }
  1725.  
  1726.       if ((wEPVal & USB_EP_CTR_TX) != 0U)
  1727.       {
  1728.         ep = &hpcd->IN_ep[epindex];
  1729.  
  1730.         /* clear int flag */
  1731.         PCD_CLEAR_TX_EP_CTR(hpcd->Instance, epindex);
  1732.  
  1733.         if (ep->type == EP_TYPE_ISOC)
  1734.         {
  1735.           ep->xfer_len = 0U;
  1736.  
  1737. #if (USE_USB_DOUBLE_BUFFER == 1U)
  1738.           if (ep->doublebuffer != 0U)
  1739.           {
  1740.             if ((wEPVal & USB_EP_DTOG_TX) != 0U)
  1741.             {
  1742.               PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, 0U);
  1743.             }
  1744.             else
  1745.             {
  1746.               PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, 0U);
  1747.             }
  1748.           }
  1749. #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
  1750.  
  1751.           /* TX COMPLETE */
  1752. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1753.           hpcd->DataInStageCallback(hpcd, ep->num);
  1754. #else
  1755.           HAL_PCD_DataInStageCallback(hpcd, ep->num);
  1756. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1757.         }
  1758.         else
  1759.         {
  1760.           /* Manage Single Buffer Transaction */
  1761.           if ((wEPVal & USB_EP_KIND) == 0U)
  1762.           {
  1763.             /* multi-packet on the NON control IN endpoint */
  1764.             TxPctSize = (uint16_t)PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
  1765.  
  1766.             if (ep->xfer_len > TxPctSize)
  1767.             {
  1768.               ep->xfer_len -= TxPctSize;
  1769.             }
  1770.             else
  1771.             {
  1772.               ep->xfer_len = 0U;
  1773.             }
  1774.  
  1775.             /* Zero Length Packet? */
  1776.             if (ep->xfer_len == 0U)
  1777.             {
  1778.               /* TX COMPLETE */
  1779. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1780.               hpcd->DataInStageCallback(hpcd, ep->num);
  1781. #else
  1782.               HAL_PCD_DataInStageCallback(hpcd, ep->num);
  1783. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1784.             }
  1785.             else
  1786.             {
  1787.               /* Transfer is not yet Done */
  1788.               ep->xfer_buff += TxPctSize;
  1789.               ep->xfer_count += TxPctSize;
  1790.               (void)USB_EPStartXfer(hpcd->Instance, ep);
  1791.             }
  1792.           }
  1793. #if (USE_USB_DOUBLE_BUFFER == 1U)
  1794.           /* Double Buffer bulk IN (bulk transfer Len > Ep_Mps) */
  1795.           else
  1796.           {
  1797.             (void)HAL_PCD_EP_DB_Transmit(hpcd, ep, wEPVal);
  1798.           }
  1799. #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
  1800.         }
  1801.       }
  1802.     }
  1803.   }
  1804.  
  1805.   return HAL_OK;
  1806. }
  1807.  
  1808.  
  1809. #if (USE_USB_DOUBLE_BUFFER == 1U)
  1810. /**
  1811.   * @brief  Manage double buffer bulk out transaction from ISR
  1812.   * @param  hpcd PCD handle
  1813.   * @param  ep current endpoint handle
  1814.   * @param  wEPVal Last snapshot of EPRx register value taken in ISR
  1815.   * @retval HAL status
  1816.   */
  1817. static uint16_t HAL_PCD_EP_DB_Receive(PCD_HandleTypeDef *hpcd,
  1818.                                       PCD_EPTypeDef *ep, uint16_t wEPVal)
  1819. {
  1820.   uint16_t count;
  1821.  
  1822.   /* Manage Buffer0 OUT */
  1823.   if ((wEPVal & USB_EP_DTOG_RX) != 0U)
  1824.   {
  1825.     /* Get count of received Data on buffer0 */
  1826.     count = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
  1827.  
  1828.     if (ep->xfer_len >= count)
  1829.     {
  1830.       ep->xfer_len -= count;
  1831.     }
  1832.     else
  1833.     {
  1834.       ep->xfer_len = 0U;
  1835.     }
  1836.  
  1837.     if (ep->xfer_len == 0U)
  1838.     {
  1839.       /* set NAK to OUT endpoint since double buffer is enabled */
  1840.       PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_NAK);
  1841.     }
  1842.  
  1843.     /* Check if Buffer1 is in blocked state which requires to toggle */
  1844.     if ((wEPVal & USB_EP_DTOG_TX) != 0U)
  1845.     {
  1846.       PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 0U);
  1847.     }
  1848.  
  1849.     if (count != 0U)
  1850.     {
  1851.       USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count);
  1852.     }
  1853.   }
  1854.   /* Manage Buffer 1 DTOG_RX=0 */
  1855.   else
  1856.   {
  1857.     /* Get count of received data */
  1858.     count = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
  1859.  
  1860.     if (ep->xfer_len >= count)
  1861.     {
  1862.       ep->xfer_len -= count;
  1863.     }
  1864.     else
  1865.     {
  1866.       ep->xfer_len = 0U;
  1867.     }
  1868.  
  1869.     if (ep->xfer_len == 0U)
  1870.     {
  1871.       /* set NAK on the current endpoint */
  1872.       PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_NAK);
  1873.     }
  1874.  
  1875.     /*Need to FreeUser Buffer*/
  1876.     if ((wEPVal & USB_EP_DTOG_TX) == 0U)
  1877.     {
  1878.       PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 0U);
  1879.     }
  1880.  
  1881.     if (count != 0U)
  1882.     {
  1883.       USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count);
  1884.     }
  1885.   }
  1886.  
  1887.   return count;
  1888. }
  1889.  
  1890.  
  1891. /**
  1892.   * @brief  Manage double buffer bulk IN transaction from ISR
  1893.   * @param  hpcd PCD handle
  1894.   * @param  ep current endpoint handle
  1895.   * @param  wEPVal Last snapshot of EPRx register value taken in ISR
  1896.   * @retval HAL status
  1897.   */
  1898. static HAL_StatusTypeDef HAL_PCD_EP_DB_Transmit(PCD_HandleTypeDef *hpcd,
  1899.                                                 PCD_EPTypeDef *ep, uint16_t wEPVal)
  1900. {
  1901.   uint32_t len;
  1902.   uint16_t TxPctSize;
  1903.  
  1904.   /* Data Buffer0 ACK received */
  1905.   if ((wEPVal & USB_EP_DTOG_TX) != 0U)
  1906.   {
  1907.     /* multi-packet on the NON control IN endpoint */
  1908.     TxPctSize = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
  1909.  
  1910.     if (ep->xfer_len > TxPctSize)
  1911.     {
  1912.       ep->xfer_len -= TxPctSize;
  1913.     }
  1914.     else
  1915.     {
  1916.       ep->xfer_len = 0U;
  1917.     }
  1918.  
  1919.     /* Transfer is completed */
  1920.     if (ep->xfer_len == 0U)
  1921.     {
  1922.       PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, 0U);
  1923.       PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, 0U);
  1924.  
  1925.       /* TX COMPLETE */
  1926. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1927.       hpcd->DataInStageCallback(hpcd, ep->num);
  1928. #else
  1929.       HAL_PCD_DataInStageCallback(hpcd, ep->num);
  1930. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1931.  
  1932.       if ((wEPVal & USB_EP_DTOG_RX) != 0U)
  1933.       {
  1934.         PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 1U);
  1935.       }
  1936.     }
  1937.     else /* Transfer is not yet Done */
  1938.     {
  1939.       /* need to Free USB Buff */
  1940.       if ((wEPVal & USB_EP_DTOG_RX) != 0U)
  1941.       {
  1942.         PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 1U);
  1943.       }
  1944.  
  1945.       /* Still there is data to Fill in the next Buffer */
  1946.       if (ep->xfer_fill_db == 1U)
  1947.       {
  1948.         ep->xfer_buff += TxPctSize;
  1949.         ep->xfer_count += TxPctSize;
  1950.  
  1951.         /* Calculate the len of the new buffer to fill */
  1952.         if (ep->xfer_len_db >= ep->maxpacket)
  1953.         {
  1954.           len = ep->maxpacket;
  1955.           ep->xfer_len_db -= len;
  1956.         }
  1957.         else if (ep->xfer_len_db == 0U)
  1958.         {
  1959.           len = TxPctSize;
  1960.           ep->xfer_fill_db = 0U;
  1961.         }
  1962.         else
  1963.         {
  1964.           ep->xfer_fill_db = 0U;
  1965.           len = ep->xfer_len_db;
  1966.           ep->xfer_len_db = 0U;
  1967.         }
  1968.  
  1969.         /* Write remaining Data to Buffer */
  1970.         /* Set the Double buffer counter for pma buffer1 */
  1971.         PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, len);
  1972.  
  1973.         /* Copy user buffer to USB PMA */
  1974.         USB_WritePMA(hpcd->Instance, ep->xfer_buff,  ep->pmaaddr0, (uint16_t)len);
  1975.       }
  1976.     }
  1977.   }
  1978.   else /* Data Buffer1 ACK received */
  1979.   {
  1980.     /* multi-packet on the NON control IN endpoint */
  1981.     TxPctSize = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
  1982.  
  1983.     if (ep->xfer_len >= TxPctSize)
  1984.     {
  1985.       ep->xfer_len -= TxPctSize;
  1986.     }
  1987.     else
  1988.     {
  1989.       ep->xfer_len = 0U;
  1990.     }
  1991.  
  1992.     /* Transfer is completed */
  1993.     if (ep->xfer_len == 0U)
  1994.     {
  1995.       PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, 0U);
  1996.       PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, 0U);
  1997.  
  1998.       /* TX COMPLETE */
  1999. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  2000.       hpcd->DataInStageCallback(hpcd, ep->num);
  2001. #else
  2002.       HAL_PCD_DataInStageCallback(hpcd, ep->num);
  2003. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  2004.  
  2005.       /* need to Free USB Buff */
  2006.       if ((wEPVal & USB_EP_DTOG_RX) == 0U)
  2007.       {
  2008.         PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 1U);
  2009.       }
  2010.     }
  2011.     else /* Transfer is not yet Done */
  2012.     {
  2013.       /* need to Free USB Buff */
  2014.       if ((wEPVal & USB_EP_DTOG_RX) == 0U)
  2015.       {
  2016.         PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 1U);
  2017.       }
  2018.  
  2019.       /* Still there is data to Fill in the next Buffer */
  2020.       if (ep->xfer_fill_db == 1U)
  2021.       {
  2022.         ep->xfer_buff += TxPctSize;
  2023.         ep->xfer_count += TxPctSize;
  2024.  
  2025.         /* Calculate the len of the new buffer to fill */
  2026.         if (ep->xfer_len_db >= ep->maxpacket)
  2027.         {
  2028.           len = ep->maxpacket;
  2029.           ep->xfer_len_db -= len;
  2030.         }
  2031.         else if (ep->xfer_len_db == 0U)
  2032.         {
  2033.           len = TxPctSize;
  2034.           ep->xfer_fill_db = 0U;
  2035.         }
  2036.         else
  2037.         {
  2038.           len = ep->xfer_len_db;
  2039.           ep->xfer_len_db = 0U;
  2040.           ep->xfer_fill_db = 0;
  2041.         }
  2042.  
  2043.         /* Set the Double buffer counter for pmabuffer1 */
  2044.         PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, len);
  2045.  
  2046.         /* Copy the user buffer to USB PMA */
  2047.         USB_WritePMA(hpcd->Instance, ep->xfer_buff,  ep->pmaaddr1, (uint16_t)len);
  2048.       }
  2049.     }
  2050.   }
  2051.  
  2052.   /*enable endpoint IN*/
  2053.   PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_VALID);
  2054.  
  2055.   return HAL_OK;
  2056. }
  2057. #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
  2058.  
  2059.  
  2060.  
  2061. /**
  2062.   * @}
  2063.   */
  2064. #endif /* defined (USB) */
  2065. #endif /* HAL_PCD_MODULE_ENABLED */
  2066.  
  2067. /**
  2068.   * @}
  2069.   */
  2070.  
  2071. /**
  2072.   * @}
  2073.   */
  2074.