Subversion Repositories DashDisplay

Rev

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

  1. /**
  2.   ******************************************************************************
  3.   * @file    stm32f1xx_hal_pcd.c
  4.   * @author  MCD Application Team
  5.   * @version V1.0.1
  6.   * @date    31-July-2015
  7.   * @brief   PCD HAL module driver.
  8.   *          This file provides firmware functions to manage the following
  9.   *          functionalities of the USB Peripheral Controller:
  10.   *           + Initialization and de-initialization functions
  11.   *           + IO operation functions
  12.   *           + Peripheral Control functions
  13.   *           + Peripheral State functions
  14.   *
  15.   @verbatim
  16.   ==============================================================================
  17.                     ##### How to use this driver #####
  18.   ==============================================================================
  19.     [..]
  20.       The PCD HAL driver can be used as follows:
  21.  
  22.      (#) Declare a PCD_HandleTypeDef handle structure, for example:
  23.          PCD_HandleTypeDef  hpcd;
  24.  
  25.      (#) Fill parameters of Init structure in HCD handle
  26.  
  27.      (#) Call HAL_PCD_Init() API to initialize the HCD peripheral (Core, Device core, ...)
  28.  
  29.      (#) Initialize the PCD low level resources through the HAL_PCD_MspInit() API:
  30.          (##) Enable the PCD/USB Low Level interface clock using the following macro
  31.               (+++) __HAL_RCC_USB_CLK_ENABLE(); For USB Device FS peripheral available
  32.                     on STM32F102xx and STM32F103xx devices
  33.               (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); For USB OTG FS peripheral available
  34.                     on STM32F105xx and STM32F107xx devices
  35.  
  36.          (##) Initialize the related GPIO clocks
  37.          (##) Configure PCD pin-out
  38.          (##) Configure PCD NVIC interrupt
  39.  
  40.      (#)Associate the Upper USB device stack to the HAL PCD Driver:
  41.          (##) hpcd.pData = pdev;
  42.  
  43.      (#)Enable HCD transmission and reception:
  44.          (##) HAL_PCD_Start();
  45.  
  46.   @endverbatim
  47.   ******************************************************************************
  48.   * @attention
  49.   *
  50.   * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
  51.   *
  52.   * Redistribution and use in source and binary forms, with or without modification,
  53.   * are permitted provided that the following conditions are met:
  54.   *   1. Redistributions of source code must retain the above copyright notice,
  55.   *      this list of conditions and the following disclaimer.
  56.   *   2. Redistributions in binary form must reproduce the above copyright notice,
  57.   *      this list of conditions and the following disclaimer in the documentation
  58.   *      and/or other materials provided with the distribution.
  59.   *   3. Neither the name of STMicroelectronics nor the names of its contributors
  60.   *      may be used to endorse or promote products derived from this software
  61.   *      without specific prior written permission.
  62.   *
  63.   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  64.   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  65.   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  66.   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  67.   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  68.   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  69.   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  70.   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  71.   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  72.   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  73.   *
  74.   ******************************************************************************
  75.   */
  76.  
  77. /* Includes ------------------------------------------------------------------*/
  78. #include "stm32f1xx_hal.h"
  79.  
  80. /** @addtogroup STM32F1xx_HAL_Driver
  81.   * @{
  82.   */
  83.  
  84.  
  85.  
  86. #ifdef HAL_PCD_MODULE_ENABLED
  87.  
  88. #if defined(STM32F102x6) || defined(STM32F102xB) || \
  89.     defined(STM32F103x6) || defined(STM32F103xB) || \
  90.     defined(STM32F103xE) || defined(STM32F103xG) || \
  91.     defined(STM32F105xC) || defined(STM32F107xC)
  92.  
  93. /** @defgroup PCD PCD
  94.   * @brief PCD HAL module driver
  95.   * @{
  96.   */
  97.  
  98. /* Private types -------------------------------------------------------------*/
  99. /* Private variables ---------------------------------------------------------*/
  100. /* Private constants ---------------------------------------------------------*/
  101. /* Private macros ------------------------------------------------------------*/
  102. /** @defgroup PCD_Private_Macros PCD Private Macros
  103.   * @{
  104.   */
  105. #define PCD_MIN(a, b)  (((a) < (b)) ? (a) : (b))
  106. #define PCD_MAX(a, b)  (((a) > (b)) ? (a) : (b))
  107. /**
  108.   * @}
  109.   */
  110.  
  111. /* Private functions ---------------------------------------------------------*/
  112. /** @defgroup PCD_Private_Functions PCD Private Functions
  113.   * @{
  114.   */
  115. #if defined (USB_OTG_FS)
  116. static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum);
  117. #endif /* USB_OTG_FS */
  118.  
  119. #if defined (USB)
  120. static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd);
  121. #endif /* USB */
  122. /**
  123.   * @}
  124.   */
  125.  
  126. /* Exported functions --------------------------------------------------------*/
  127. /** @defgroup PCD_Exported_Functions PCD Exported Functions
  128.   * @{
  129.   */
  130.  
  131. /** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
  132.  *  @brief    Initialization and Configuration functions
  133.  *
  134. @verbatim
  135.  ===============================================================================
  136.             ##### Initialization and de-initialization functions #####
  137.  ===============================================================================
  138.     [..]  This section provides functions allowing to:
  139.  
  140. @endverbatim
  141.   * @{
  142.   */
  143.  
  144. /**
  145.   * @brief  Initializes the PCD according to the specified
  146.   *         parameters in the PCD_InitTypeDef and create the associated handle.
  147.   * @param  hpcd: PCD handle
  148.   * @retval HAL status
  149.   */
  150. HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd)
  151. {
  152.   uint32_t index = 0;
  153.  
  154.   /* Check the PCD handle allocation */
  155.   if(hpcd == NULL)
  156.   {
  157.     return HAL_ERROR;
  158.   }
  159.  
  160.   /* Check the parameters */
  161.   assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance));
  162.  
  163.   if(hpcd->State == HAL_PCD_STATE_RESET)
  164.   {  
  165.     /* Allocate lock resource and initialize it */
  166.     hpcd->Lock = HAL_UNLOCKED;
  167.  
  168.     /* Init the low level hardware : GPIO, CLOCK, NVIC... */
  169.     HAL_PCD_MspInit(hpcd);
  170.   }
  171.  
  172.   hpcd->State = HAL_PCD_STATE_BUSY;
  173.  
  174.   /* Disable the Interrupts */
  175.   __HAL_PCD_DISABLE(hpcd);
  176.  
  177.   /*Init the Core (common init.) */
  178.   USB_CoreInit(hpcd->Instance, hpcd->Init);
  179.  
  180.   /* Force Device Mode*/
  181.   USB_SetCurrentMode(hpcd->Instance , USB_DEVICE_MODE);
  182.  
  183.   /* Init endpoints structures */
  184.   for (index = 0; index < 15 ; index++)
  185.   {
  186.     /* Init ep structure */
  187.     hpcd->IN_ep[index].is_in = 1;
  188.     hpcd->IN_ep[index].num = index;
  189.     hpcd->IN_ep[index].tx_fifo_num = index;
  190.     /* Control until ep is actvated */
  191.     hpcd->IN_ep[index].type = EP_TYPE_CTRL;
  192.     hpcd->IN_ep[index].maxpacket =  0;
  193.     hpcd->IN_ep[index].xfer_buff = 0;
  194.     hpcd->IN_ep[index].xfer_len = 0;
  195.   }
  196.  
  197.   for (index = 0; index < 15 ; index++)
  198.   {
  199.     hpcd->OUT_ep[index].is_in = 0;
  200.     hpcd->OUT_ep[index].num = index;
  201.     hpcd->IN_ep[index].tx_fifo_num = index;
  202.     /* Control until ep is activated */
  203.     hpcd->OUT_ep[index].type = EP_TYPE_CTRL;
  204.     hpcd->OUT_ep[index].maxpacket = 0;
  205.     hpcd->OUT_ep[index].xfer_buff = 0;
  206.     hpcd->OUT_ep[index].xfer_len = 0;
  207.   }
  208.  
  209.   /* Init Device */
  210.   USB_DevInit(hpcd->Instance, hpcd->Init);
  211.  
  212.   hpcd->USB_Address = 0;
  213.   hpcd->State= HAL_PCD_STATE_READY;
  214.  
  215.   USB_DevDisconnect (hpcd->Instance);  
  216.   return HAL_OK;
  217. }
  218.  
  219. /**
  220.   * @brief  DeInitializes the PCD peripheral
  221.   * @param  hpcd: PCD handle
  222.   * @retval HAL status
  223.   */
  224. HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
  225. {
  226.   /* Check the PCD handle allocation */
  227.   if(hpcd == NULL)
  228.   {
  229.     return HAL_ERROR;
  230.   }
  231.  
  232.   hpcd->State = HAL_PCD_STATE_BUSY;
  233.  
  234.   /* Stop Device */
  235.   HAL_PCD_Stop(hpcd);
  236.  
  237.   /* DeInit the low level hardware */
  238.   HAL_PCD_MspDeInit(hpcd);
  239.  
  240.   hpcd->State = HAL_PCD_STATE_RESET;
  241.  
  242.   return HAL_OK;
  243. }
  244.  
  245. /**
  246.   * @brief  Initializes the PCD MSP.
  247.   * @param  hpcd: PCD handle
  248.   * @retval None
  249.   */
  250. __weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
  251. {
  252.   /* NOTE : This function should not be modified, when the callback is needed,
  253.             the HAL_PCD_MspInit could be implemented in the user file
  254.    */
  255. }
  256.  
  257. /**
  258.   * @brief  DeInitializes PCD MSP.
  259.   * @param  hpcd: PCD handle
  260.   * @retval None
  261.   */
  262. __weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
  263. {
  264.   /* NOTE : This function should not be modified, when the callback is needed,
  265.             the HAL_PCD_MspDeInit could be implemented in the user file
  266.    */
  267. }
  268.  
  269. /**
  270.   * @}
  271.   */
  272.  
  273. /** @defgroup PCD_Exported_Functions_Group2 IO operation functions
  274.  *  @brief   Data transfers functions
  275.  *
  276. @verbatim
  277.  ===============================================================================
  278.                       ##### IO operation functions #####
  279.  ===============================================================================
  280.     [..]
  281.     This subsection provides a set of functions allowing to manage the PCD data
  282.     transfers.
  283.  
  284. @endverbatim
  285.   * @{
  286.   */
  287.  
  288. /**
  289.   * @brief  Start The USB Device.
  290.   * @param  hpcd: PCD handle
  291.   * @retval HAL status
  292.   */
  293. HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)
  294. {
  295.   __HAL_LOCK(hpcd);
  296.   HAL_PCDEx_SetConnectionState (hpcd, 1);
  297.   USB_DevConnect (hpcd->Instance);
  298.   __HAL_PCD_ENABLE(hpcd);
  299.   __HAL_UNLOCK(hpcd);
  300.   return HAL_OK;
  301. }
  302.  
  303. /**
  304.   * @brief  Stop The USB Device.
  305.   * @param  hpcd: PCD handle
  306.   * @retval HAL status
  307.   */
  308. HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
  309. {  
  310.   __HAL_LOCK(hpcd);
  311.   __HAL_PCD_DISABLE(hpcd);
  312.   USB_StopDevice(hpcd->Instance);
  313.   USB_DevDisconnect (hpcd->Instance);
  314.   __HAL_UNLOCK(hpcd);
  315.   return HAL_OK;
  316. }
  317.  
  318. #if defined (USB_OTG_FS)
  319. /**
  320.   * @brief  This function handles PCD interrupt request.
  321.   * @param  hpcd: PCD handle
  322.   * @retval HAL status
  323.   */
  324. void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
  325. {
  326.   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
  327.   uint32_t index = 0, ep_intr = 0, epint = 0, epnum = 0;
  328.   uint32_t fifoemptymsk = 0, temp = 0;
  329.   USB_OTG_EPTypeDef *ep = NULL;
  330.  
  331.   /* ensure that we are in device mode */
  332.   if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE)
  333.   {
  334.     /* avoid spurious interrupt */
  335.     if(__HAL_PCD_IS_INVALID_INTERRUPT(hpcd))
  336.     {
  337.       return;
  338.     }
  339.    
  340.     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS))
  341.     {
  342.      /* incorrect mode, acknowledge the interrupt */
  343.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS);
  344.     }
  345.    
  346.     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT))
  347.     {
  348.       epnum = 0;
  349.      
  350.       /* Read in the device interrupt bits */
  351.       ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance);
  352.      
  353.       while ( ep_intr )
  354.       {
  355.         if (ep_intr & 0x1)
  356.         {
  357.           epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, epnum);
  358.          
  359.           if(( epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC)
  360.           {
  361.             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC);
  362.            
  363.             HAL_PCD_DataOutStageCallback(hpcd, epnum);
  364.           }
  365.          
  366.           if(( epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP)
  367.           {
  368.             /* Inform the upper layer that a setup packet is available */
  369.             HAL_PCD_SetupStageCallback(hpcd);
  370.             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP);
  371.           }
  372.          
  373.           if(( epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS)
  374.           {
  375.             CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS);
  376.           }
  377.         }
  378.         epnum++;
  379.         ep_intr >>= 1;
  380.       }
  381.     }
  382.    
  383.     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT))
  384.     {
  385.       /* Read in the device interrupt bits */
  386.       ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance);
  387.      
  388.       epnum = 0;
  389.      
  390.       while ( ep_intr )
  391.       {
  392.         if (ep_intr & 0x1) /* In ITR */
  393.         {
  394.           epint = USB_ReadDevInEPInterrupt(hpcd->Instance, epnum);
  395.          
  396.           if(( epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC)
  397.           {
  398.             fifoemptymsk = 0x1 << epnum;
  399.             USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
  400.            
  401.             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC);
  402.            
  403.             HAL_PCD_DataInStageCallback(hpcd, epnum);
  404.           }
  405.           if(( epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC)
  406.           {
  407.             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC);
  408.           }
  409.           if(( epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE)
  410.           {
  411.             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE);
  412.           }
  413.           if(( epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE)
  414.           {
  415.             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE);
  416.           }
  417.           if(( epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD)
  418.           {
  419.             CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD);
  420.           }
  421.           if(( epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE)
  422.           {
  423.             PCD_WriteEmptyTxFifo(hpcd , epnum);
  424.           }
  425.         }
  426.         epnum++;
  427.         ep_intr >>= 1;
  428.       }
  429.     }
  430.    
  431.     /* Handle Resume Interrupt */
  432.     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT))
  433.     {
  434.      /* Clear the Remote Wake-up signalling */
  435.       USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
  436.      
  437.      HAL_PCD_ResumeCallback(hpcd);
  438.      
  439.      __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT);
  440.     }
  441.    
  442.     /* Handle Suspend Interrupt */
  443.     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP))
  444.     {
  445.       if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
  446.       {
  447.        
  448.         HAL_PCD_SuspendCallback(hpcd);
  449.       }
  450.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP);
  451.     }
  452.    
  453.     /* Handle Reset Interrupt */
  454.     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST))
  455.     {
  456.       USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
  457.       USB_FlushTxFifo(hpcd->Instance ,  0 );
  458.      
  459.       for (index = 0; index < hpcd->Init.dev_endpoints ; index++)
  460.       {
  461.         USBx_INEP(index)->DIEPINT = 0xFF;
  462.         USBx_OUTEP(index)->DOEPINT = 0xFF;
  463.       }
  464.       USBx_DEVICE->DAINT = 0xFFFFFFFF;
  465.       USBx_DEVICE->DAINTMSK |= 0x10001;
  466.      
  467.       USBx_DEVICE->DOEPMSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM);
  468.       USBx_DEVICE->DIEPMSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM);
  469.      
  470.       /* Set Default Address to 0 */
  471.       USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD;
  472.      
  473.       /* setup EP0 to receive SETUP packets */
  474.       USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
  475.      
  476.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST);
  477.     }
  478.    
  479.     /* Handle Enumeration done Interrupt */
  480.     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE))
  481.     {
  482.       USB_ActivateSetup(hpcd->Instance);
  483.       hpcd->Instance->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
  484.      
  485.       hpcd->Init.speed            = USB_OTG_SPEED_FULL;
  486.       hpcd->Init.ep0_mps          = USB_OTG_FS_MAX_PACKET_SIZE ;
  487.       hpcd->Instance->GUSBCFG |= (uint32_t)((USBD_FS_TRDT_VALUE << 10) & USB_OTG_GUSBCFG_TRDT);
  488.      
  489.       HAL_PCD_ResetCallback(hpcd);
  490.      
  491.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE);
  492.     }
  493.    
  494.     /* Handle RxQLevel Interrupt */
  495.     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL))
  496.     {
  497.       USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
  498.       temp = USBx->GRXSTSP;
  499.       ep = &hpcd->OUT_ep[temp & USB_OTG_GRXSTSP_EPNUM];
  500.      
  501.       if(((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) ==  STS_DATA_UPDT)
  502.       {
  503.         if((temp & USB_OTG_GRXSTSP_BCNT) != 0)
  504.         {
  505.           USB_ReadPacket(USBx, ep->xfer_buff, (temp & USB_OTG_GRXSTSP_BCNT) >> 4);
  506.           ep->xfer_buff += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
  507.           ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
  508.         }
  509.       }
  510.       else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) ==  STS_SETUP_UPDT)
  511.       {
  512.         USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8);
  513.         ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
  514.       }
  515.       USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
  516.     }
  517.    
  518.     /* Handle SOF Interrupt */
  519.     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF))
  520.     {
  521.       HAL_PCD_SOFCallback(hpcd);
  522.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF);
  523.     }
  524.    
  525.     /* Handle Incomplete ISO IN Interrupt */
  526.     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR))
  527.     {
  528.       HAL_PCD_ISOINIncompleteCallback(hpcd, epnum);
  529.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR);
  530.     }
  531.    
  532.     /* Handle Incomplete ISO OUT Interrupt */
  533.     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
  534.     {
  535.       HAL_PCD_ISOOUTIncompleteCallback(hpcd, epnum);
  536.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
  537.     }
  538.    
  539.     /* Handle Connection event Interrupt */
  540.     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT))
  541.     {
  542.       HAL_PCD_ConnectCallback(hpcd);
  543.       __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT);
  544.     }
  545.    
  546.     /* Handle Disconnection event Interrupt */
  547.     if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT))
  548.     {
  549.       temp = hpcd->Instance->GOTGINT;
  550.      
  551.       if((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET)
  552.       {
  553.         HAL_PCD_DisconnectCallback(hpcd);
  554.       }
  555.       hpcd->Instance->GOTGINT |= temp;
  556.     }
  557.   }
  558. }
  559. #endif /* USB_OTG_FS */
  560.  
  561. #if defined (USB)
  562. /**
  563.   * @brief  This function handles PCD interrupt request.
  564.   * @param  hpcd: PCD handle
  565.   * @retval HAL status
  566.   */
  567. void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
  568. {
  569.   uint32_t wInterrupt_Mask = 0;
  570.  
  571.   if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_CTR))
  572.   {
  573.     /* servicing of the endpoint correct transfer interrupt */
  574.     /* clear of the CTR flag into the sub */
  575.     PCD_EP_ISR_Handler(hpcd);
  576.   }
  577.  
  578.   if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_RESET))
  579.   {
  580.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET);
  581.     HAL_PCD_ResetCallback(hpcd);
  582.     HAL_PCD_SetAddress(hpcd, 0);
  583.   }
  584.  
  585.   if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_PMAOVR))
  586.   {
  587.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_PMAOVR);    
  588.   }
  589.   if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_ERR))
  590.   {
  591.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ERR);
  592.   }
  593.  
  594.   if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_WKUP))
  595.   {  
  596.     hpcd->Instance->CNTR &= ~(USB_CNTR_LP_MODE);
  597.    
  598.     /*set wInterrupt_Mask global variable*/
  599.     wInterrupt_Mask = USB_CNTR_CTRM  | USB_CNTR_WKUPM | USB_CNTR_SUSPM | USB_CNTR_ERRM \
  600.       | USB_CNTR_ESOFM | USB_CNTR_RESETM;
  601.    
  602.     /*Set interrupt mask*/
  603.     hpcd->Instance->CNTR = wInterrupt_Mask;
  604.    
  605.     HAL_PCD_ResumeCallback(hpcd);
  606.    
  607.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP);    
  608.   }
  609.  
  610.   if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_SUSP))
  611.   {
  612.     /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
  613.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SUSP);  
  614.    
  615.     /* Force low-power mode in the macrocell */
  616.     hpcd->Instance->CNTR |= USB_CNTR_FSUSP;
  617.     hpcd->Instance->CNTR |= USB_CNTR_LP_MODE;
  618.     if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_WKUP) == 0)
  619.     {
  620.       HAL_PCD_SuspendCallback(hpcd);
  621.     }
  622.   }
  623.  
  624.   if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_SOF))
  625.   {
  626.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SOF);
  627.     HAL_PCD_SOFCallback(hpcd);
  628.   }
  629.  
  630.   if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_ESOF))
  631.   {
  632.     /* clear ESOF flag in ISTR */
  633.     __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ESOF);
  634.   }
  635. }
  636. #endif /* USB */
  637.  
  638. /**
  639.   * @brief  Data out stage callbacks
  640.   * @param  hpcd: PCD handle
  641.   * @param  epnum: endpoint number
  642.   * @retval None
  643.   */
  644.  __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  645. {
  646.   /* NOTE : This function should not be modified, when the callback is needed,
  647.             the HAL_PCD_DataOutStageCallback could be implemented in the user file
  648.    */
  649. }
  650.  
  651. /**
  652.   * @brief  Data IN stage callbacks
  653.   * @param  hpcd: PCD handle
  654.   * @param  epnum: endpoint number
  655.   * @retval None
  656.   */
  657.  __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  658. {
  659.   /* NOTE : This function should not be modified, when the callback is needed,
  660.             the HAL_PCD_DataInStageCallback could be implemented in the user file
  661.    */
  662. }
  663. /**
  664.   * @brief  Setup stage callback
  665.   * @param  hpcd: PCD handle
  666.   * @retval None
  667.   */
  668.  __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
  669. {
  670.   /* NOTE : This function should not be modified, when the callback is needed,
  671.             the HAL_PCD_SetupStageCallback could be implemented in the user file
  672.    */
  673. }
  674.  
  675. /**
  676.   * @brief  USB Start Of Frame callbacks
  677.   * @param  hpcd: PCD handle
  678.   * @retval None
  679.   */
  680.  __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
  681. {
  682.   /* NOTE : This function should not be modified, when the callback is needed,
  683.             the HAL_PCD_SOFCallback could be implemented in the user file
  684.    */
  685. }
  686.  
  687. /**
  688.   * @brief  USB Reset callbacks
  689.   * @param  hpcd: PCD handle
  690.   * @retval None
  691.   */
  692.  __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
  693. {
  694.   /* NOTE : This function should not be modified, when the callback is needed,
  695.             the HAL_PCD_ResetCallback could be implemented in the user file
  696.    */
  697. }
  698.  
  699. /**
  700.   * @brief  Suspend event callbacks
  701.   * @param  hpcd: PCD handle
  702.   * @retval None
  703.   */
  704.  __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
  705. {
  706.   /* NOTE : This function should not be modified, when the callback is needed,
  707.             the HAL_PCD_SuspendCallback could be implemented in the user file
  708.    */
  709. }
  710.  
  711. /**
  712.   * @brief  Resume event callbacks
  713.   * @param  hpcd: PCD handle
  714.   * @retval None
  715.   */
  716.  __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
  717. {
  718.   /* NOTE : This function should not be modified, when the callback is needed,
  719.             the HAL_PCD_ResumeCallback could be implemented in the user file
  720.    */
  721. }
  722.  
  723. /**
  724.   * @brief  Incomplete ISO OUT callbacks
  725.   * @param  hpcd: PCD handle
  726.   * @param  epnum: endpoint number
  727.   * @retval None
  728.   */
  729.  __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  730. {
  731.   /* NOTE : This function should not be modified, when the callback is needed,
  732.             the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file
  733.    */
  734. }
  735.  
  736. /**
  737.   * @brief  Incomplete ISO IN  callbacks
  738.   * @param  hpcd: PCD handle
  739.   * @param  epnum: endpoint number
  740.   * @retval None
  741.   */
  742.  __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  743. {
  744.   /* NOTE : This function should not be modified, when the callback is needed,
  745.             the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file
  746.    */
  747. }
  748.  
  749. /**
  750.   * @brief  Connection event callbacks
  751.   * @param  hpcd: PCD handle
  752.   * @retval None
  753.   */
  754.  __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
  755. {
  756.   /* NOTE : This function should not be modified, when the callback is needed,
  757.             the HAL_PCD_ConnectCallback could be implemented in the user file
  758.    */
  759. }
  760.  
  761. /**
  762.   * @brief  Disconnection event callbacks
  763.   * @param  hpcd: PCD handle
  764.   * @retval None
  765.   */
  766.  __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
  767. {
  768.   /* NOTE : This function should not be modified, when the callback is needed,
  769.             the HAL_PCD_DisconnectCallback could be implemented in the user file
  770.    */
  771. }
  772.  
  773. /**
  774.   * @}
  775.   */
  776.  
  777. /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
  778.  *  @brief   management functions
  779.  *
  780. @verbatim
  781.  ===============================================================================
  782.                       ##### Peripheral Control functions #####
  783.  ===============================================================================  
  784.     [..]
  785.     This subsection provides a set of functions allowing to control the PCD data
  786.     transfers.
  787.  
  788. @endverbatim
  789.   * @{
  790.   */
  791.  
  792. /**
  793.   * @brief  Connect the USB device
  794.   * @param  hpcd: PCD handle
  795.   * @retval HAL status
  796.   */
  797. HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd)
  798. {
  799.   __HAL_LOCK(hpcd);
  800.   HAL_PCDEx_SetConnectionState (hpcd, 1);
  801.   USB_DevConnect(hpcd->Instance);
  802.   __HAL_UNLOCK(hpcd);
  803.   return HAL_OK;
  804. }
  805.  
  806. /**
  807.   * @brief  Disconnect the USB device
  808.   * @param  hpcd: PCD handle
  809.   * @retval HAL status
  810.   */
  811. HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd)
  812. {
  813.   __HAL_LOCK(hpcd);
  814.   HAL_PCDEx_SetConnectionState (hpcd, 0);
  815.   USB_DevDisconnect(hpcd->Instance);
  816.   __HAL_UNLOCK(hpcd);
  817.   return HAL_OK;
  818. }
  819.  
  820. /**
  821.   * @brief  Set the USB Device address
  822.   * @param  hpcd: PCD handle
  823.   * @param  address: new device address
  824.   * @retval HAL status
  825.   */
  826. HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)
  827. {
  828.   __HAL_LOCK(hpcd);
  829.   hpcd->USB_Address = address;
  830.   USB_SetDevAddress(hpcd->Instance, address);
  831.   __HAL_UNLOCK(hpcd);
  832.   return HAL_OK;
  833. }
  834. /**
  835.   * @brief  Open and configure an endpoint
  836.   * @param  hpcd: PCD handle
  837.   * @param  ep_addr: endpoint address
  838.   * @param  ep_mps: endpoint max packet size
  839.   * @param  ep_type: endpoint type  
  840.   * @retval HAL status
  841.   */
  842. HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type)
  843. {
  844.   HAL_StatusTypeDef  ret = HAL_OK;
  845.   PCD_EPTypeDef *ep = NULL;
  846.  
  847.   if ((ep_addr & 0x80) == 0x80)
  848.   {
  849.     ep = &hpcd->IN_ep[ep_addr & 0x7F];
  850.   }
  851.   else
  852.   {
  853.     ep = &hpcd->OUT_ep[ep_addr & 0x7F];
  854.   }
  855.   ep->num   = ep_addr & 0x7F;
  856.  
  857.   ep->is_in = (0x80 & ep_addr) != 0;
  858.   ep->maxpacket = ep_mps;
  859.   ep->type = ep_type;
  860.    
  861.   __HAL_LOCK(hpcd);
  862.   USB_ActivateEndpoint(hpcd->Instance , ep);
  863.   __HAL_UNLOCK(hpcd);
  864.   return ret;
  865. }
  866.  
  867. /**
  868.   * @brief  Deactivate an endpoint
  869.   * @param  hpcd: PCD handle
  870.   * @param  ep_addr: endpoint address
  871.   * @retval HAL status
  872.   */
  873. HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  874. {  
  875.   PCD_EPTypeDef *ep = NULL;
  876.  
  877.   if ((ep_addr & 0x80) == 0x80)
  878.   {
  879.     ep = &hpcd->IN_ep[ep_addr & 0x7F];
  880.   }
  881.   else
  882.   {
  883.     ep = &hpcd->OUT_ep[ep_addr & 0x7F];
  884.   }
  885.   ep->num   = ep_addr & 0x7F;
  886.  
  887.   ep->is_in = (0x80 & ep_addr) != 0;
  888.  
  889.   __HAL_LOCK(hpcd);
  890.   USB_DeactivateEndpoint(hpcd->Instance , ep);
  891.   __HAL_UNLOCK(hpcd);
  892.   return HAL_OK;
  893. }
  894.  
  895.  
  896. /**
  897.   * @brief  Receive an amount of data
  898.   * @param  hpcd: PCD handle
  899.   * @param  ep_addr: endpoint address
  900.   * @param  pBuf: pointer to the reception buffer
  901.   * @param  len: amount of data to be received
  902.   * @retval HAL status
  903.   */
  904. HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
  905. {
  906.   PCD_EPTypeDef *ep = NULL;
  907.  
  908.   ep = &hpcd->OUT_ep[ep_addr & 0x7F];
  909.  
  910.   /*setup and start the Xfer */
  911.   ep->xfer_buff = pBuf;  
  912.   ep->xfer_len = len;
  913.   ep->xfer_count = 0;
  914.   ep->is_in = 0;
  915.   ep->num = ep_addr & 0x7F;
  916.  
  917.   __HAL_LOCK(hpcd);
  918.  
  919.   if ((ep_addr & 0x7F) == 0 )
  920.   {
  921.     USB_EP0StartXfer(hpcd->Instance , ep);
  922.   }
  923.   else
  924.   {
  925.     USB_EPStartXfer(hpcd->Instance , ep);
  926.   }
  927.   __HAL_UNLOCK(hpcd);
  928.  
  929.   return HAL_OK;
  930. }
  931.  
  932. /**
  933.   * @brief  Get Received Data Size
  934.   * @param  hpcd: PCD handle
  935.   * @param  ep_addr: endpoint address
  936.   * @retval Data Size
  937.   */
  938. uint16_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  939. {
  940.   return hpcd->OUT_ep[ep_addr & 0x7F].xfer_count;
  941. }
  942. /**
  943.   * @brief  Send an amount of data
  944.   * @param  hpcd: PCD handle
  945.   * @param  ep_addr: endpoint address
  946.   * @param  pBuf: pointer to the transmission buffer
  947.   * @param  len: amount of data to be sent
  948.   * @retval HAL status
  949.   */
  950. HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
  951. {
  952.   PCD_EPTypeDef *ep = NULL;
  953.  
  954.   ep = &hpcd->IN_ep[ep_addr & 0x7F];
  955.  
  956.   /*setup and start the Xfer */
  957.   ep->xfer_buff = pBuf;  
  958.   ep->xfer_len = len;
  959.   ep->xfer_count = 0;
  960.   ep->is_in = 1;
  961.   ep->num = ep_addr & 0x7F;
  962.  
  963.   __HAL_LOCK(hpcd);
  964.  
  965.   if ((ep_addr & 0x7F) == 0 )
  966.   {
  967.     USB_EP0StartXfer(hpcd->Instance , ep);
  968.   }
  969.   else
  970.   {
  971.     USB_EPStartXfer(hpcd->Instance , ep);
  972.   }
  973.  
  974.   __HAL_UNLOCK(hpcd);
  975.  
  976.   return HAL_OK;
  977. }
  978.  
  979. /**
  980.   * @brief  Set a STALL condition over an endpoint
  981.   * @param  hpcd: PCD handle
  982.   * @param  ep_addr: endpoint address
  983.   * @retval HAL status
  984.   */
  985. HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  986. {
  987.   PCD_EPTypeDef *ep = NULL;
  988.  
  989.   if ((0x80 & ep_addr) == 0x80)
  990.   {
  991.     ep = &hpcd->IN_ep[ep_addr & 0x7F];
  992.   }
  993.   else
  994.   {
  995.     ep = &hpcd->OUT_ep[ep_addr];
  996.   }
  997.  
  998.   ep->is_stall = 1;
  999.   ep->num   = ep_addr & 0x7F;
  1000.   ep->is_in = ((ep_addr & 0x80) == 0x80);
  1001.  
  1002.   __HAL_LOCK(hpcd);
  1003.   USB_EPSetStall(hpcd->Instance , ep);
  1004.   if((ep_addr & 0x7F) == 0)
  1005.   {
  1006.     USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
  1007.   }
  1008.   __HAL_UNLOCK(hpcd);
  1009.  
  1010.   return HAL_OK;
  1011. }
  1012.  
  1013. /**
  1014.   * @brief  Clear a STALL condition over in an endpoint
  1015.   * @param  hpcd: PCD handle
  1016.   * @param  ep_addr: endpoint address
  1017.   * @retval HAL status
  1018.   */
  1019. HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1020. {
  1021.   PCD_EPTypeDef *ep = NULL;
  1022.  
  1023.   if ((0x80 & ep_addr) == 0x80)
  1024.   {
  1025.     ep = &hpcd->IN_ep[ep_addr & 0x7F];
  1026.   }
  1027.   else
  1028.   {
  1029.     ep = &hpcd->OUT_ep[ep_addr];
  1030.   }
  1031.  
  1032.   ep->is_stall = 0;
  1033.   ep->num   = ep_addr & 0x7F;
  1034.   ep->is_in = ((ep_addr & 0x80) == 0x80);
  1035.  
  1036.   __HAL_LOCK(hpcd);
  1037.   USB_EPClearStall(hpcd->Instance , ep);
  1038.   __HAL_UNLOCK(hpcd);
  1039.  
  1040.   return HAL_OK;
  1041. }
  1042.  
  1043. /**
  1044.   * @brief  Flush an endpoint
  1045.   * @param  hpcd: PCD handle
  1046.   * @param  ep_addr: endpoint address
  1047.   * @retval HAL status
  1048.   */
  1049. HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1050. {
  1051.   __HAL_LOCK(hpcd);
  1052.  
  1053.   if ((ep_addr & 0x80) == 0x80)
  1054.   {
  1055.     USB_FlushTxFifo(hpcd->Instance, ep_addr & 0x7F);
  1056.   }
  1057.   else
  1058.   {
  1059.     USB_FlushRxFifo(hpcd->Instance);
  1060.   }
  1061.  
  1062.   __HAL_UNLOCK(hpcd);
  1063.  
  1064.   return HAL_OK;
  1065. }
  1066.  
  1067. /**
  1068.   * @brief  HAL_PCD_ActivateRemoteWakeup : active remote wakeup signalling
  1069.   * @param  hpcd: PCD handle
  1070.   * @retval HAL status
  1071.   */
  1072. HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
  1073. {
  1074.   return(USB_ActivateRemoteWakeup(hpcd->Instance));
  1075. }
  1076.  
  1077. /**
  1078.   * @brief  HAL_PCD_DeActivateRemoteWakeup : de-active remote wakeup signalling
  1079.   * @param  hpcd: PCD handle
  1080.   * @retval HAL status
  1081.   */
  1082. HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
  1083. {
  1084.   return(USB_DeActivateRemoteWakeup(hpcd->Instance));
  1085. }
  1086. /**
  1087.   * @}
  1088.   */
  1089.  
  1090. /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions
  1091.  *  @brief   Peripheral State functions
  1092.  *
  1093. @verbatim
  1094.  ===============================================================================
  1095.                       ##### Peripheral State functions #####
  1096.  ===============================================================================
  1097.     [..]
  1098.     This subsection permits to get in run-time the status of the peripheral
  1099.     and the data flow.
  1100.  
  1101. @endverbatim
  1102.   * @{
  1103.   */
  1104.  
  1105. /**
  1106.   * @brief  Return the PCD state
  1107.   * @param  hpcd: PCD handle
  1108.   * @retval HAL state
  1109.   */
  1110. PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd)
  1111. {
  1112.   return hpcd->State;
  1113. }
  1114.  
  1115. /**
  1116.   * @}
  1117.   */
  1118.  
  1119. /**
  1120.   * @}
  1121.   */
  1122.  
  1123. /** @addtogroup PCD_Private_Functions
  1124.   * @{
  1125.   */
  1126. #if defined (USB_OTG_FS)
  1127. /**
  1128.   * @brief  DCD_WriteEmptyTxFifo
  1129.   *         check FIFO for the next packet to be loaded
  1130.   * @param  hpcd: PCD handle
  1131.   * @param  epnum : endpoint number
  1132.   *          This parameter can be a value from 0 to 15  
  1133.   * @retval HAL status
  1134.   */
  1135. static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum)
  1136. {
  1137.   USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;  
  1138.   USB_OTG_EPTypeDef *ep = NULL;
  1139.   int32_t len = 0;
  1140.   uint32_t len32b = 0;
  1141.   uint32_t fifoemptymsk = 0;
  1142.  
  1143.   ep = &hpcd->IN_ep[epnum];
  1144.   len = ep->xfer_len - ep->xfer_count;
  1145.  
  1146.   if (len > ep->maxpacket)
  1147.   {
  1148.     len = ep->maxpacket;
  1149.   }
  1150.  
  1151.   len32b = (len + 3) / 4;
  1152.  
  1153.   while ((USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) > len32b &&
  1154.          ep->xfer_count < ep->xfer_len &&
  1155.          ep->xfer_len != 0)
  1156.   {
  1157.     /* Write the FIFO */
  1158.     len = ep->xfer_len - ep->xfer_count;
  1159.    
  1160.     if (len > ep->maxpacket)
  1161.     {
  1162.       len = ep->maxpacket;
  1163.     }
  1164.     len32b = (len + 3) / 4;
  1165.    
  1166.     USB_WritePacket(USBx, ep->xfer_buff, epnum, len);
  1167.    
  1168.     ep->xfer_buff  += len;
  1169.     ep->xfer_count += len;
  1170.   }
  1171.  
  1172.   if(len <= 0)
  1173.   {
  1174.     fifoemptymsk = 0x1 << epnum;
  1175.     USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
  1176.    
  1177.   }
  1178.  
  1179.   return HAL_OK;
  1180. }
  1181. #endif /* USB_OTG_FS */
  1182.  
  1183. #if defined (USB)
  1184. /**
  1185.   * @brief  This function handles PCD Endpoint interrupt request.
  1186.   * @param  hpcd: PCD handle
  1187.   * @retval HAL status
  1188.   */
  1189. static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
  1190. {
  1191.   PCD_EPTypeDef *ep = NULL;
  1192.   uint16_t count = 0;
  1193.   uint8_t epindex = 0;
  1194.   __IO uint16_t wIstr = 0;  
  1195.   __IO uint16_t wEPVal = 0;
  1196.  
  1197.   /* stay in loop while pending interrupts */
  1198.   while (((wIstr = hpcd->Instance->ISTR) & USB_ISTR_CTR) != 0)
  1199.   {
  1200.     /* extract highest priority endpoint number */
  1201.     epindex = (uint8_t)(wIstr & USB_ISTR_EP_ID);
  1202.    
  1203.     if (epindex == 0)
  1204.     {
  1205.       /* Decode and service control endpoint interrupt */
  1206.      
  1207.       /* DIR bit = origin of the interrupt */  
  1208.       if ((wIstr & USB_ISTR_DIR) == 0)
  1209.       {
  1210.         /* DIR = 0 */
  1211.        
  1212.         /* DIR = 0      => IN  int */
  1213.         /* DIR = 0 implies that (EP_CTR_TX = 1) always  */
  1214.         PCD_CLEAR_TX_EP_CTR(hpcd->Instance, PCD_ENDP0);
  1215.         ep = &hpcd->IN_ep[0];
  1216.        
  1217.         ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
  1218.         ep->xfer_buff += ep->xfer_count;
  1219.  
  1220.         /* TX COMPLETE */
  1221.         HAL_PCD_DataInStageCallback(hpcd, 0);
  1222.        
  1223.        
  1224.         if((hpcd->USB_Address > 0)&& ( ep->xfer_len == 0))
  1225.         {
  1226.           hpcd->Instance->DADDR = (hpcd->USB_Address | USB_DADDR_EF);
  1227.           hpcd->USB_Address = 0;
  1228.         }
  1229.        
  1230.       }
  1231.       else
  1232.       {
  1233.         /* DIR = 1 */
  1234.        
  1235.         /* DIR = 1 & CTR_RX       => SETUP or OUT int */
  1236.         /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */
  1237.         ep = &hpcd->OUT_ep[0];
  1238.         wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0);
  1239.        
  1240.         if ((wEPVal & USB_EP_SETUP) != 0)
  1241.         {
  1242.           /* Get SETUP Packet*/
  1243.           ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
  1244.           USB_ReadPMA(hpcd->Instance, (uint8_t*)hpcd->Setup ,ep->pmaadress , ep->xfer_count);      
  1245.           /* SETUP bit kept frozen while CTR_RX = 1*/
  1246.           PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
  1247.          
  1248.           /* Process SETUP Packet*/
  1249.           HAL_PCD_SetupStageCallback(hpcd);
  1250.         }
  1251.        
  1252.         else if ((wEPVal & USB_EP_CTR_RX) != 0)
  1253.         {
  1254.           PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
  1255.           /* Get Control Data OUT Packet*/
  1256.           ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
  1257.          
  1258.           if (ep->xfer_count != 0)
  1259.           {
  1260.             USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, ep->xfer_count);
  1261.             ep->xfer_buff+=ep->xfer_count;
  1262.           }
  1263.          
  1264.           /* Process Control Data OUT Packet*/
  1265.            HAL_PCD_DataOutStageCallback(hpcd, 0);
  1266.          
  1267.           PCD_SET_EP_RX_CNT(hpcd->Instance, PCD_ENDP0, ep->maxpacket);
  1268.           PCD_SET_EP_RX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_RX_VALID);
  1269.         }
  1270.       }
  1271.     }
  1272.     else
  1273.     {
  1274.       /* Decode and service non control endpoints interrupt  */
  1275.          
  1276.       /* process related endpoint register */
  1277.       wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, epindex);
  1278.       if ((wEPVal & USB_EP_CTR_RX) != 0)
  1279.       {  
  1280.         /* clear int flag */
  1281.         PCD_CLEAR_RX_EP_CTR(hpcd->Instance, epindex);
  1282.         ep = &hpcd->OUT_ep[epindex];
  1283.        
  1284.         /* OUT double Buffering*/
  1285.         if (ep->doublebuffer == 0)
  1286.         {
  1287.           count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
  1288.           if (count != 0)
  1289.           {
  1290.             USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, count);
  1291.           }
  1292.         }
  1293.         else
  1294.         {
  1295.           if (PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_RX)
  1296.           {
  1297.             /*read from endpoint BUF0Addr buffer*/
  1298.             count = PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
  1299.             if (count != 0)
  1300.             {
  1301.               USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count);
  1302.             }
  1303.           }
  1304.           else
  1305.           {
  1306.             /*read from endpoint BUF1Addr buffer*/
  1307.             count = PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
  1308.             if (count != 0)
  1309.             {
  1310.               USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count);
  1311.             }
  1312.           }
  1313.           PCD_FreeUserBuffer(hpcd->Instance, ep->num, PCD_EP_DBUF_OUT);  
  1314.         }
  1315.         /*multi-packet on the NON control OUT endpoint*/
  1316.         ep->xfer_count+=count;
  1317.         ep->xfer_buff+=count;
  1318.        
  1319.         if ((ep->xfer_len == 0) || (count < ep->maxpacket))
  1320.         {
  1321.           /* RX COMPLETE */
  1322.           HAL_PCD_DataOutStageCallback(hpcd, ep->num);
  1323.         }
  1324.         else
  1325.         {
  1326.           HAL_PCD_EP_Receive(hpcd, ep->num, ep->xfer_buff, ep->xfer_len);
  1327.         }
  1328.        
  1329.       } /* if((wEPVal & EP_CTR_RX) */
  1330.      
  1331.       if ((wEPVal & USB_EP_CTR_TX) != 0)
  1332.       {
  1333.         ep = &hpcd->IN_ep[epindex];
  1334.        
  1335.         /* clear int flag */
  1336.         PCD_CLEAR_TX_EP_CTR(hpcd->Instance, epindex);
  1337.        
  1338.         /* IN double Buffering*/
  1339.         if (ep->doublebuffer == 0)
  1340.         {
  1341.           ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
  1342.           if (ep->xfer_count != 0)
  1343.           {
  1344.             USB_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, ep->xfer_count);
  1345.           }
  1346.         }
  1347.         else
  1348.         {
  1349.           if (PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_TX)
  1350.           {
  1351.             /*read from endpoint BUF0Addr buffer*/
  1352.             ep->xfer_count = PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
  1353.             if (ep->xfer_count != 0)
  1354.             {
  1355.               USB_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, ep->xfer_count);
  1356.             }
  1357.           }
  1358.           else
  1359.           {
  1360.             /*read from endpoint BUF1Addr buffer*/
  1361.             ep->xfer_count = PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
  1362.             if (ep->xfer_count != 0)
  1363.             {
  1364.               USB_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, ep->xfer_count);
  1365.             }
  1366.           }
  1367.           PCD_FreeUserBuffer(hpcd->Instance, ep->num, PCD_EP_DBUF_IN);  
  1368.         }
  1369.         /*multi-packet on the NON control IN endpoint*/
  1370.         ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
  1371.         ep->xfer_buff+=ep->xfer_count;
  1372.        
  1373.         /* Zero Length Packet? */
  1374.         if (ep->xfer_len == 0)
  1375.         {
  1376.           /* TX COMPLETE */
  1377.           HAL_PCD_DataInStageCallback(hpcd, ep->num);
  1378.         }
  1379.         else
  1380.         {
  1381.           HAL_PCD_EP_Transmit(hpcd, ep->num, ep->xfer_buff, ep->xfer_len);
  1382.         }
  1383.       }
  1384.     }
  1385.   }
  1386.   return HAL_OK;
  1387. }
  1388. #endif /* USB */
  1389.  
  1390. /**
  1391.   * @}
  1392.   */
  1393.  
  1394. /**
  1395.   * @}
  1396.   */
  1397.  
  1398. #endif /* STM32F102x6 || STM32F102xB || */
  1399.        /* STM32F103x6 || STM32F103xB || */
  1400.        /* STM32F103xE || STM32F103xG || */
  1401.        /* STM32F105xC || STM32F107xC    */
  1402.  
  1403. #endif /* HAL_PCD_MODULE_ENABLED */
  1404.  
  1405.  
  1406. /**
  1407.   * @}
  1408.   */
  1409.  
  1410. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
  1411.