Subversion Repositories dashGPS

Rev

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

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