Subversion Repositories LedShow

Rev

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

  1. /**
  2.   ******************************************************************************
  3.   * @file    stm32f1xx_hal_hcd.c
  4.   * @author  MCD Application Team
  5.   * @brief   HCD 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.     (#)Declare a HCD_HandleTypeDef handle structure, for example:
  19.        HCD_HandleTypeDef  hhcd;
  20.        
  21.     (#)Fill parameters of Init structure in HCD handle
  22.  
  23.     (#)Call HAL_HCD_Init() API to initialize the HCD peripheral (Core, Host core, ...)
  24.  
  25.     (#)Initialize the HCD low level resources through the HAL_HCD_MspInit() API:
  26.         (##) Enable the HCD/USB Low Level interface clock using the following macro
  27.              (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE()
  28.  
  29.         (##) Initialize the related GPIO clocks
  30.         (##) Configure HCD pin-out
  31.         (##) Configure HCD NVIC interrupt
  32.  
  33.     (#)Associate the Upper USB Host stack to the HAL HCD Driver:
  34.         (##) hhcd.pData = phost;
  35.  
  36.     (#)Enable HCD transmission and reception:
  37.         (##) HAL_HCD_Start();
  38.  
  39.   @endverbatim
  40.   ******************************************************************************
  41.   * @attention
  42.   *
  43.   * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
  44.   *
  45.   * Redistribution and use in source and binary forms, with or without modification,
  46.   * are permitted provided that the following conditions are met:
  47.   *   1. Redistributions of source code must retain the above copyright notice,
  48.   *      this list of conditions and the following disclaimer.
  49.   *   2. Redistributions in binary form must reproduce the above copyright notice,
  50.   *      this list of conditions and the following disclaimer in the documentation
  51.   *      and/or other materials provided with the distribution.
  52.   *   3. Neither the name of STMicroelectronics nor the names of its contributors
  53.   *      may be used to endorse or promote products derived from this software
  54.   *      without specific prior written permission.
  55.   *
  56.   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  57.   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  58.   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  59.   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  60.   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  61.   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  62.   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  63.   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  64.   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  65.   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  66.   *
  67.   ******************************************************************************
  68.   */
  69.  
  70. /* Includes ------------------------------------------------------------------*/
  71. #include "stm32f1xx_hal.h"
  72. /** @addtogroup STM32F1xx_HAL_Driver
  73.   * @{
  74.   */
  75.  
  76.  
  77. #ifdef HAL_HCD_MODULE_ENABLED
  78.  
  79. #if defined(STM32F105xC) || defined(STM32F107xC)
  80.  
  81. /** @defgroup HCD HCD
  82.   * @brief HCD HAL module driver
  83.   * @{
  84.   */
  85.  
  86. /* Private types -------------------------------------------------------------*/
  87. /* Private variables ---------------------------------------------------------*/
  88. /* Private constants ---------------------------------------------------------*/
  89. /* Private macros ------------------------------------------------------------*/
  90. /* Private function ----------------------------------------------------------*/
  91. /** @defgroup HCD_Private_Functions HCD Private Functions
  92.   * @{
  93.   */
  94. static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
  95. static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
  96. static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd);
  97. static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd);
  98. /**
  99.   * @}
  100.   */
  101.  
  102. /* Exported functions --------------------------------------------------------*/
  103. /** @defgroup HCD_Exported_Functions HCD Exported Functions
  104.   * @{
  105.   */
  106.  
  107. /** @defgroup HCD_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  Initialize the host driver
  122.   * @param  hhcd: HCD handle
  123.   * @retval HAL status
  124.   */
  125. HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd)
  126. {
  127.   /* Check the HCD handle allocation */
  128.   if(hhcd == NULL)
  129.   {
  130.     return HAL_ERROR;
  131.   }
  132.  
  133.   /* Check the parameters */
  134.   assert_param(IS_HCD_ALL_INSTANCE(hhcd->Instance));
  135.  
  136.   if(hhcd->State == HAL_HCD_STATE_RESET)
  137.   {  
  138.     /* Allocate lock resource and initialize it */
  139.     hhcd->Lock = HAL_UNLOCKED;
  140.  
  141.     /* Init the low level hardware : GPIO, CLOCK, NVIC... */
  142.     HAL_HCD_MspInit(hhcd);
  143.   }
  144.  
  145.   hhcd->State = HAL_HCD_STATE_BUSY;
  146.  
  147.   /* Disable the Interrupts */
  148.   __HAL_HCD_DISABLE(hhcd);
  149.  
  150.   /* Init the Core (common init.) */
  151.   USB_CoreInit(hhcd->Instance, hhcd->Init);
  152.  
  153.   /* Force Host Mode*/
  154.   USB_SetCurrentMode(hhcd->Instance , USB_HOST_MODE);
  155.  
  156.   /* Init Host */
  157.   USB_HostInit(hhcd->Instance, hhcd->Init);
  158.  
  159.   hhcd->State= HAL_HCD_STATE_READY;
  160.  
  161.   return HAL_OK;
  162. }
  163.  
  164. /**
  165.   * @brief  Initialize a host channel
  166.   * @param  hhcd: HCD handle
  167.   * @param  ch_num: Channel number.
  168.   *         This parameter can be a value from 1 to 15
  169.   * @param  epnum: Endpoint number.
  170.   *          This parameter can be a value from 1 to 15
  171.   * @param  dev_address : Current device address
  172.   *          This parameter can be a value from 0 to 255
  173.   * @param  speed: Current device speed.
  174.   *          This parameter can be one of these values:
  175.   *            HCD_SPEED_FULL: Full speed mode,
  176.   *            HCD_SPEED_LOW: Low speed mode
  177.   * @param  ep_type: Endpoint Type.
  178.   *          This parameter can be one of these values:
  179.   *            EP_TYPE_CTRL: Control type,
  180.   *            EP_TYPE_ISOC: Isochronous type,
  181.   *            EP_TYPE_BULK: Bulk type,
  182.   *            EP_TYPE_INTR: Interrupt type
  183.   * @param  mps: Max Packet Size.
  184.   *          This parameter can be a value from 0 to32K
  185.   * @retval HAL status
  186.   */
  187. HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd,
  188.                                   uint8_t ch_num,
  189.                                   uint8_t epnum,
  190.                                   uint8_t dev_address,
  191.                                   uint8_t speed,
  192.                                   uint8_t ep_type,
  193.                                   uint16_t mps)
  194. {
  195.   HAL_StatusTypeDef status = HAL_OK;
  196.  
  197.   __HAL_LOCK(hhcd);
  198.  
  199.   hhcd->hc[ch_num].dev_addr = dev_address;
  200.   hhcd->hc[ch_num].max_packet = mps;
  201.   hhcd->hc[ch_num].ch_num = ch_num;
  202.   hhcd->hc[ch_num].ep_type = ep_type;
  203.   hhcd->hc[ch_num].ep_num = epnum & 0x7FU;
  204.   hhcd->hc[ch_num].ep_is_in = ((epnum & 0x80U) == 0x80U);
  205.   hhcd->hc[ch_num].speed = speed;
  206.  
  207.   status =  USB_HC_Init(hhcd->Instance,
  208.                         ch_num,
  209.                         epnum,
  210.                         dev_address,
  211.                         speed,
  212.                         ep_type,
  213.                         mps);
  214.   __HAL_UNLOCK(hhcd);
  215.  
  216.   return status;
  217. }
  218.  
  219. /**
  220.   * @brief  Halt a host channel
  221.   * @param  hhcd: HCD handle
  222.   * @param  ch_num: Channel number.
  223.   *         This parameter can be a value from 1 to 15
  224.   * @retval HAL status
  225.   */
  226. HAL_StatusTypeDef HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd,
  227.                                   uint8_t ch_num)
  228. {
  229.   __HAL_LOCK(hhcd);
  230.   USB_HC_Halt(hhcd->Instance, ch_num);
  231.   __HAL_UNLOCK(hhcd);
  232.  
  233.   return HAL_OK;
  234. }
  235.  
  236. /**
  237.   * @brief  DeInitialize the host driver
  238.   * @param  hhcd: HCD handle
  239.   * @retval HAL status
  240.   */
  241. HAL_StatusTypeDef HAL_HCD_DeInit(HCD_HandleTypeDef *hhcd)
  242. {
  243.   /* Check the HCD handle allocation */
  244.   if(hhcd == NULL)
  245.   {
  246.     return HAL_ERROR;
  247.   }
  248.  
  249.   hhcd->State = HAL_HCD_STATE_BUSY;
  250.  
  251.   /* DeInit the low level hardware */
  252.   HAL_HCD_MspDeInit(hhcd);
  253.  
  254.   __HAL_HCD_DISABLE(hhcd);
  255.  
  256.   hhcd->State = HAL_HCD_STATE_RESET;
  257.  
  258.   return HAL_OK;
  259. }
  260.  
  261. /**
  262.   * @brief  Initializes the HCD MSP.
  263.   * @param  hhcd: HCD handle
  264.   * @retval None
  265.   */
  266. __weak void  HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd)
  267. {
  268.   /* Prevent unused argument(s) compilation warning */
  269.   UNUSED(hhcd);
  270.   /* NOTE : This function Should not be modified, when the callback is needed,
  271.             the HAL_HCD_MspInit could be implemented in the user file
  272.    */
  273. }
  274.  
  275. /**
  276.   * @brief  DeInitializes HCD MSP.
  277.   * @param  hhcd: HCD handle
  278.   * @retval None
  279.   */
  280. __weak void  HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd)
  281. {
  282.   /* Prevent unused argument(s) compilation warning */
  283.   UNUSED(hhcd);
  284.   /* NOTE : This function Should not be modified, when the callback is needed,
  285.             the HAL_HCD_MspDeInit could be implemented in the user file
  286.    */
  287. }
  288.  
  289. /**
  290.   * @}
  291.   */
  292.  
  293. /** @defgroup HCD_Exported_Functions_Group2 IO operation functions
  294.   *  @brief   HCD IO operation functions
  295.   *
  296. @verbatim
  297.  ===============================================================================
  298.                       ##### IO operation functions #####
  299.  ===============================================================================
  300.     This subsection provides a set of functions allowing to manage the USB Host Data
  301.     Transfer
  302.        
  303. @endverbatim
  304.   * @{
  305.   */
  306.  
  307. /**                                
  308.   * @brief  Submit a new URB for processing
  309.   * @param  hhcd: HCD handle
  310.   * @param  ch_num: Channel number.
  311.   *         This parameter can be a value from 1 to 15
  312.   * @param  direction: Channel number.
  313.   *          This parameter can be one of these values:
  314.   *           0 : Output / 1 : Input
  315.   * @param  ep_type: Endpoint Type.
  316.   *          This parameter can be one of these values:
  317.   *            EP_TYPE_CTRL: Control type/
  318.   *            EP_TYPE_ISOC: Isochronous type/
  319.   *            EP_TYPE_BULK: Bulk type/
  320.   *            EP_TYPE_INTR: Interrupt type/
  321.   * @param  token: Endpoint Type.
  322.   *          This parameter can be one of these values:
  323.   *            0: HC_PID_SETUP / 1: HC_PID_DATA1
  324.   * @param  pbuff: pointer to URB data
  325.   * @param  length: Length of URB data
  326.   * @param  do_ping: activate do ping protocol (for high speed only).
  327.   *          This parameter can be one of these values:
  328.   *           0 : do ping inactive / 1 : do ping active
  329.   * @retval HAL status
  330.   */
  331. HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd,
  332.                                            uint8_t ch_num,
  333.                                            uint8_t direction,
  334.                                            uint8_t ep_type,  
  335.                                            uint8_t token,
  336.                                            uint8_t* pbuff,
  337.                                            uint16_t length,
  338.                                            uint8_t do_ping)
  339. {
  340.   hhcd->hc[ch_num].ep_is_in = direction;
  341.   hhcd->hc[ch_num].ep_type  = ep_type;
  342.  
  343.   if(token == 0U)
  344.   {
  345.     hhcd->hc[ch_num].data_pid = HC_PID_SETUP;
  346.   }
  347.   else
  348.   {
  349.     hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
  350.   }
  351.  
  352.   /* Manage Data Toggle */
  353.   switch(ep_type)
  354.   {
  355.   case EP_TYPE_CTRL:
  356.     if((token == 1U) && (direction == 0U)) /*send data */
  357.     {
  358.       if (length == 0U)
  359.       { /* For Status OUT stage, Length==0, Status Out PID = 1 */
  360.         hhcd->hc[ch_num].toggle_out = 1U;
  361.       }
  362.      
  363.       /* Set the Data Toggle bit as per the Flag */
  364.       if ( hhcd->hc[ch_num].toggle_out == 0U)
  365.       { /* Put the PID 0 */
  366.         hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  367.       }
  368.       else
  369.       { /* Put the PID 1 */
  370.         hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
  371.       }
  372.       if(hhcd->hc[ch_num].urb_state  != URB_NOTREADY)
  373.       {
  374.         hhcd->hc[ch_num].do_ping = do_ping;
  375.       }
  376.     }
  377.     break;
  378.  
  379.   case EP_TYPE_BULK:
  380.     if(direction == 0U)
  381.     {
  382.       /* Set the Data Toggle bit as per the Flag */
  383.       if ( hhcd->hc[ch_num].toggle_out == 0U)
  384.       { /* Put the PID 0 */
  385.         hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  386.       }
  387.       else
  388.       { /* Put the PID 1 */
  389.         hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
  390.       }
  391.       if(hhcd->hc[ch_num].urb_state  != URB_NOTREADY)
  392.       {
  393.         hhcd->hc[ch_num].do_ping = do_ping;
  394.       }
  395.     }
  396.     else
  397.     {
  398.       if( hhcd->hc[ch_num].toggle_in == 0U)
  399.       {
  400.         hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  401.       }
  402.       else
  403.       {
  404.         hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
  405.       }
  406.     }
  407.     break;
  408.  
  409.   case EP_TYPE_INTR:
  410.     if(direction == 0U)
  411.     {
  412.       /* Set the Data Toggle bit as per the Flag */
  413.       if ( hhcd->hc[ch_num].toggle_out == 0U)
  414.       { /* Put the PID 0 */
  415.         hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  416.       }
  417.       else
  418.       { /* Put the PID 1 */
  419.         hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
  420.       }
  421.     }
  422.     else
  423.     {
  424.       if( hhcd->hc[ch_num].toggle_in == 0U)
  425.       {
  426.         hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  427.       }
  428.       else
  429.       {
  430.         hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
  431.       }
  432.     }
  433.     break;
  434.  
  435.   case EP_TYPE_ISOC:
  436.     hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
  437.     break;
  438.   }
  439.  
  440.   hhcd->hc[ch_num].xfer_buff = pbuff;
  441.   hhcd->hc[ch_num].xfer_len  = length;
  442.   hhcd->hc[ch_num].urb_state = URB_IDLE;
  443.   hhcd->hc[ch_num].xfer_count = 0U;
  444.   hhcd->hc[ch_num].ch_num = ch_num;
  445.   hhcd->hc[ch_num].state = HC_IDLE;
  446.  
  447.   return USB_HC_StartXfer(hhcd->Instance, &(hhcd->hc[ch_num]));
  448. }
  449.  
  450. /**
  451.   * @brief  handle HCD interrupt request.
  452.   * @param  hhcd: HCD handle
  453.   * @retval None
  454.   */
  455. void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd)
  456. {
  457.   USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
  458.  
  459.   uint32_t index = 0U, interrupt = 0U;
  460.  
  461.   /* ensure that we are in device mode */
  462.   if (USB_GetMode(hhcd->Instance) == USB_OTG_MODE_HOST)
  463.   {
  464.     /* Avoid spurious interrupt */
  465.     if(__HAL_HCD_IS_INVALID_INTERRUPT(hhcd))
  466.     {
  467.       return;
  468.     }
  469.    
  470.     if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
  471.     {
  472.      /* Incorrect mode, acknowledge the interrupt */
  473.       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
  474.     }
  475.    
  476.     if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR))
  477.     {
  478.      /* Incorrect mode, acknowledge the interrupt */
  479.       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR);
  480.     }
  481.    
  482.     if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE))
  483.     {
  484.      /* Incorrect mode, acknowledge the interrupt */
  485.       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE);
  486.     }
  487.    
  488.     if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_MMIS))
  489.     {
  490.      /* Incorrect mode, acknowledge the interrupt */
  491.       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_MMIS);
  492.     }
  493.    
  494.     /* Handle Host Disconnect Interrupts */
  495.     if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT))
  496.     {
  497.    
  498.       /* Cleanup HPRT */
  499.       USBx_HPRT0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
  500.         USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
  501.      
  502.       /* Handle Host Port Interrupts */
  503.       HAL_HCD_Disconnect_Callback(hhcd);
  504.       USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_48_MHZ);
  505.       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT);
  506.     }
  507.    
  508.     /* Handle Host Port Interrupts */
  509.     if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HPRTINT))
  510.     {
  511.       HCD_Port_IRQHandler (hhcd);
  512.     }
  513.    
  514.     /* Handle Host SOF Interrupts */
  515.     if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_SOF))
  516.     {
  517.       HAL_HCD_SOF_Callback(hhcd);
  518.       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_SOF);
  519.     }
  520.    
  521.     /* Handle Host channel Interrupts */
  522.     if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HCINT))
  523.     {
  524.       interrupt = USB_HC_ReadInterrupt(hhcd->Instance);
  525.       for (index = 0U; index < hhcd->Init.Host_channels ; index++)
  526.       {
  527.         if (interrupt & (1 << index))
  528.         {
  529.           if ((USBx_HC(index)->HCCHAR) &  USB_OTG_HCCHAR_EPDIR)
  530.           {
  531.             HCD_HC_IN_IRQHandler (hhcd, index);
  532.           }
  533.           else
  534.           {
  535.             HCD_HC_OUT_IRQHandler (hhcd, index);
  536.           }
  537.         }
  538.       }
  539.       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_HCINT);
  540.     }
  541.    
  542.     /* Handle Rx Queue Level Interrupts */
  543.     if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_RXFLVL))
  544.     {
  545.       USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
  546.      
  547.       HCD_RXQLVL_IRQHandler (hhcd);
  548.      
  549.       USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
  550.     }
  551.   }
  552. }
  553.  
  554. /**
  555.   * @brief  SOF callback.
  556.   * @param  hhcd: HCD handle
  557.   * @retval None
  558.   */
  559. __weak void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd)
  560. {
  561.   /* Prevent unused argument(s) compilation warning */
  562.   UNUSED(hhcd);
  563.   /* NOTE : This function Should not be modified, when the callback is needed,
  564.             the HAL_HCD_SOF_Callback could be implemented in the user file
  565.    */
  566. }
  567.  
  568. /**
  569.   * @brief Connexion Event callback.
  570.   * @param  hhcd: HCD handle
  571.   * @retval None
  572.   */
  573. __weak void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
  574. {
  575.   /* Prevent unused argument(s) compilation warning */
  576.   UNUSED(hhcd);
  577.   /* NOTE : This function Should not be modified, when the callback is needed,
  578.             the HAL_HCD_Connect_Callback could be implemented in the user file
  579.    */
  580. }
  581.  
  582. /**
  583.   * @brief  Disonnection Event callback.
  584.   * @param  hhcd: HCD handle
  585.   * @retval None
  586.   */
  587. __weak void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
  588. {
  589.   /* Prevent unused argument(s) compilation warning */
  590.   UNUSED(hhcd);
  591.   /* NOTE : This function Should not be modified, when the callback is needed,
  592.             the HAL_HCD_Disconnect_Callback could be implemented in the user file
  593.    */
  594. }
  595.  
  596. /**
  597.   * @brief  Notify URB state change callback.
  598.   * @param  hhcd: HCD handle
  599.   * @param  chnum: Channel number.
  600.   *         This parameter can be a value from 1 to 15
  601.   * @param  urb_state:
  602.   *          This parameter can be one of these values:
  603.   *            URB_IDLE/
  604.   *            URB_DONE/
  605.   *            URB_NOTREADY/
  606.   *            URB_NYET/
  607.   *            URB_ERROR/  
  608.   *            URB_STALL/
  609.   * @retval None
  610.   */
  611. __weak void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state)
  612. {
  613.   /* Prevent unused argument(s) compilation warning */
  614.   UNUSED(hhcd);
  615.   UNUSED(chnum);
  616.   UNUSED(urb_state);
  617.   /* NOTE : This function Should not be modified, when the callback is needed,
  618.             the HAL_HCD_HC_NotifyURBChange_Callback could be implemented in the user file
  619.    */
  620. }
  621.  
  622. /**
  623.   * @}
  624.   */
  625.  
  626. /** @defgroup HCD_Exported_Functions_Group3 Peripheral Control functions
  627.  *  @brief   management functions
  628.  *
  629. @verbatim
  630.  ===============================================================================
  631.                       ##### Peripheral Control functions #####
  632.  ===============================================================================
  633.     [..]
  634.     This subsection provides a set of functions allowing to control the HCD data
  635.     transfers.
  636.  
  637. @endverbatim
  638.   * @{
  639.   */
  640.  
  641. /**
  642.   * @brief  Start the host driver
  643.   * @param  hhcd: HCD handle
  644.   * @retval HAL status
  645.   */
  646. HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd)
  647. {
  648.   __HAL_LOCK(hhcd);
  649.   __HAL_HCD_ENABLE(hhcd);
  650.   USB_DriveVbus(hhcd->Instance, 1U);
  651.   __HAL_UNLOCK(hhcd);
  652.   return HAL_OK;
  653. }
  654.  
  655. /**
  656.   * @brief  Stop the host driver
  657.   * @param  hhcd: HCD handle
  658.   * @retval HAL status
  659.   */
  660.  
  661. HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd)
  662. {
  663.   __HAL_LOCK(hhcd);
  664.   USB_StopHost(hhcd->Instance);
  665.   __HAL_UNLOCK(hhcd);
  666.   return HAL_OK;
  667. }
  668.  
  669. /**
  670.   * @brief  Reset the host port
  671.   * @param  hhcd: HCD handle
  672.   * @retval HAL status
  673.   */
  674. HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd)
  675. {
  676.   return (USB_ResetPort(hhcd->Instance));
  677. }
  678.  
  679. /**
  680.   * @}
  681.   */
  682.  
  683. /** @defgroup HCD_Exported_Functions_Group4 Peripheral State functions
  684.  *  @brief   Peripheral State functions
  685.  *
  686. @verbatim
  687.  ===============================================================================
  688.                       ##### Peripheral State functions #####
  689.  ===============================================================================
  690.     [..]
  691.     This subsection permits to get in run-time the status of the peripheral
  692.     and the data flow.
  693.  
  694. @endverbatim
  695.   * @{
  696.   */
  697.  
  698. /**
  699.   * @brief  Return the HCD handle state
  700.   * @param  hhcd: HCD handle
  701.   * @retval HAL state
  702.   */
  703. HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef *hhcd)
  704. {
  705.   return hhcd->State;
  706. }
  707.  
  708. /**
  709.   * @brief  Return  URB state for a channel
  710.   * @param  hhcd: HCD handle
  711.   * @param  chnum: Channel number.
  712.   *         This parameter can be a value from 1 to 15
  713.   * @retval URB state.
  714.   *          This parameter can be one of these values:
  715.   *            URB_IDLE/
  716.   *            URB_DONE/
  717.   *            URB_NOTREADY/
  718.   *            URB_NYET/
  719.   *            URB_ERROR/
  720.   *            URB_STALL/
  721.   */
  722. HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef *hhcd, uint8_t chnum)
  723. {
  724.   return hhcd->hc[chnum].urb_state;
  725. }
  726.  
  727.  
  728. /**
  729.   * @brief  Return the last host transfer size
  730.   * @param  hhcd: HCD handle
  731.   * @param  chnum: Channel number.
  732.   *         This parameter can be a value from 1 to 15
  733.   * @retval last transfer size in byte
  734.   */
  735. uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef *hhcd, uint8_t chnum)
  736. {
  737.   return hhcd->hc[chnum].xfer_count;
  738. }
  739.  
  740. /**
  741.   * @brief  Return the Host Channel state
  742.   * @param  hhcd: HCD handle
  743.   * @param  chnum: Channel number.
  744.   *         This parameter can be a value from 1 to 15
  745.   * @retval Host channel state
  746.   *          This parameter can be one of the these values:
  747.   *            HC_IDLE/
  748.   *            HC_XFRC/
  749.   *            HC_HALTED/
  750.   *            HC_NYET/
  751.   *            HC_NAK/
  752.   *            HC_STALL/
  753.   *            HC_XACTERR/
  754.   *            HC_BBLERR/
  755.   *            HC_DATATGLERR/
  756.   */
  757. HCD_HCStateTypeDef  HAL_HCD_HC_GetState(HCD_HandleTypeDef *hhcd, uint8_t chnum)
  758. {
  759.   return hhcd->hc[chnum].state;
  760. }
  761.  
  762. /**
  763.   * @brief  Return the current Host frame number
  764.   * @param  hhcd: HCD handle
  765.   * @retval Current Host frame number
  766.   */
  767. uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd)
  768. {
  769.   return (USB_GetCurrentFrame(hhcd->Instance));
  770. }
  771.  
  772. /**
  773.   * @brief  Return the Host enumeration speed
  774.   * @param  hhcd: HCD handle
  775.   * @retval Enumeration speed
  776.   */
  777. uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd)
  778. {
  779.   return (USB_GetHostSpeed(hhcd->Instance));
  780. }
  781.  
  782. /**
  783.   * @}
  784.   */
  785. /**
  786.   * @}
  787.   */
  788.  
  789. /** @addtogroup HCD_Private_Functions
  790.   * @{
  791.   */
  792. /**
  793.   * @brief  This function handles Host Channel IN interrupt requests.
  794.   * @param  hhcd: HCD handle
  795.   * @param  chnum: Channel number.
  796.   *         This parameter can be a value from 1 to 15
  797.   * @retval none
  798.   */
  799. static void HCD_HC_IN_IRQHandler (HCD_HandleTypeDef *hhcd, uint8_t chnum)
  800. {
  801.   USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
  802.   uint32_t tmpreg = 0U;
  803.  
  804.   if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_AHBERR)
  805.   {
  806.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR);
  807.     __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  808.   }  
  809.   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_ACK)
  810.   {
  811.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
  812.   }
  813.  
  814.   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_STALL)
  815.   {
  816.     __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  817.     hhcd->hc[chnum].state = HC_STALL;
  818.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
  819.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL);
  820.     USB_HC_Halt(hhcd->Instance, chnum);
  821.   }
  822.   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_DTERR)
  823.   {
  824.     __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  825.     USB_HC_Halt(hhcd->Instance, chnum);
  826.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
  827.     hhcd->hc[chnum].state = HC_DATATGLERR;
  828.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR);
  829.   }
  830.  
  831.   if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_FRMOR)
  832.   {
  833.     __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  834.     USB_HC_Halt(hhcd->Instance, chnum);
  835.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR);
  836.   }
  837.  
  838.   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_XFRC)
  839.   {
  840.     hhcd->hc[chnum].state = HC_XFRC;
  841.     hhcd->hc[chnum].ErrCnt = 0U;
  842.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC);
  843.    
  844.     if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL)||
  845.         (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
  846.     {
  847.       __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  848.       USB_HC_Halt(hhcd->Instance, chnum);
  849.       __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
  850.      
  851.     }
  852.     else if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
  853.     {
  854.       USBx_HC(chnum)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
  855.       hhcd->hc[chnum].urb_state = URB_DONE;
  856.       HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
  857.     }
  858.     hhcd->hc[chnum].toggle_in ^= 1U;
  859.    
  860.   }
  861.   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_CHH)
  862.   {
  863.     __HAL_HCD_MASK_HALT_HC_INT(chnum);
  864.    
  865.     if(hhcd->hc[chnum].state == HC_XFRC)
  866.     {
  867.       hhcd->hc[chnum].urb_state  = URB_DONE;
  868.     }
  869.     else if (hhcd->hc[chnum].state == HC_STALL)
  870.     {
  871.       hhcd->hc[chnum].urb_state  = URB_STALL;
  872.     }
  873.     else if((hhcd->hc[chnum].state == HC_XACTERR) ||
  874.             (hhcd->hc[chnum].state == HC_DATATGLERR))
  875.     {
  876.       if(hhcd->hc[chnum].ErrCnt++ > 3U)
  877.       {
  878.         hhcd->hc[chnum].ErrCnt = 0U;
  879.         hhcd->hc[chnum].urb_state = URB_ERROR;
  880.       }
  881.       else
  882.       {
  883.         hhcd->hc[chnum].urb_state = URB_NOTREADY;
  884.       }
  885.      
  886.       /* re-activate the channel  */
  887.       tmpreg = USBx_HC(chnum)->HCCHAR;
  888.       tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  889.       tmpreg |= USB_OTG_HCCHAR_CHENA;
  890.       USBx_HC(chnum)->HCCHAR = tmpreg;
  891.     }
  892.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
  893.     HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
  894.   }
  895.  
  896.   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_TXERR)
  897.   {
  898.     __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  899.      hhcd->hc[chnum].ErrCnt++;
  900.      hhcd->hc[chnum].state = HC_XACTERR;
  901.      USB_HC_Halt(hhcd->Instance, chnum);
  902.      __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR);
  903.   }
  904.   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_NAK)
  905.   {
  906.     if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
  907.     {
  908.       __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  909.       USB_HC_Halt(hhcd->Instance, chnum);
  910.     }
  911.     else if  ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL)||
  912.               (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
  913.     {
  914.       /* re-activate the channel  */
  915.       tmpreg = USBx_HC(chnum)->HCCHAR;
  916.       tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  917.       tmpreg |= USB_OTG_HCCHAR_CHENA;
  918.       USBx_HC(chnum)->HCCHAR = tmpreg;
  919.     }
  920.     hhcd->hc[chnum].state = HC_NAK;
  921.      __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
  922.   }
  923. }
  924.  
  925. /**
  926.   * @brief  This function handles Host Channel OUT interrupt requests.
  927.   * @param  hhcd: HCD handle
  928.   * @param  chnum: Channel number.
  929.   *         This parameter can be a value from 1 to 15
  930.   * @retval none
  931.   */
  932. static void HCD_HC_OUT_IRQHandler (HCD_HandleTypeDef *hhcd, uint8_t chnum)
  933. {
  934.   USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
  935.   uint32_t tmpreg = 0U;
  936.  
  937.   if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_AHBERR)
  938.   {
  939.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR);
  940.     __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  941.   }
  942.   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_ACK)
  943.   {
  944.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
  945.    
  946.     if( hhcd->hc[chnum].do_ping == 1U)
  947.     {
  948.       hhcd->hc[chnum].state = HC_NYET;
  949.       __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  950.       USB_HC_Halt(hhcd->Instance, chnum);
  951.       hhcd->hc[chnum].urb_state  = URB_NOTREADY;
  952.     }
  953.   }
  954.  
  955.   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_NYET)
  956.   {
  957.     hhcd->hc[chnum].state = HC_NYET;
  958.     hhcd->hc[chnum].ErrCnt= 0U;
  959.     __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  960.     USB_HC_Halt(hhcd->Instance, chnum);
  961.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NYET);
  962.  
  963.   }
  964.  
  965.   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_FRMOR)
  966.   {
  967.     __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  968.     USB_HC_Halt(hhcd->Instance, chnum);
  969.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR);
  970.   }
  971.  
  972.   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_XFRC)
  973.   {
  974.     hhcd->hc[chnum].ErrCnt = 0U;
  975.     __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  976.     USB_HC_Halt(hhcd->Instance, chnum);
  977.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC);
  978.     hhcd->hc[chnum].state = HC_XFRC;
  979.   }
  980.   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_STALL)
  981.   {
  982.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL);
  983.     __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  984.     USB_HC_Halt(hhcd->Instance, chnum);
  985.     hhcd->hc[chnum].state = HC_STALL;
  986.   }
  987.   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_NAK)
  988.   {
  989.     hhcd->hc[chnum].ErrCnt = 0U;
  990.     __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  991.     USB_HC_Halt(hhcd->Instance, chnum);
  992.     hhcd->hc[chnum].state = HC_NAK;
  993.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
  994.   }
  995.   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_TXERR)
  996.   {
  997.     __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  998.     USB_HC_Halt(hhcd->Instance, chnum);
  999.     hhcd->hc[chnum].state = HC_XACTERR;
  1000.      __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR);
  1001.   }
  1002.   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_DTERR)
  1003.   {
  1004.     __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
  1005.     USB_HC_Halt(hhcd->Instance, chnum);
  1006.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
  1007.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR);
  1008.     hhcd->hc[chnum].state = HC_DATATGLERR;
  1009.   }
  1010.   else if ((USBx_HC(chnum)->HCINT) &  USB_OTG_HCINT_CHH)
  1011.   {
  1012.     __HAL_HCD_MASK_HALT_HC_INT(chnum);
  1013.    
  1014.     if(hhcd->hc[chnum].state == HC_XFRC)
  1015.     {
  1016.       hhcd->hc[chnum].urb_state  = URB_DONE;
  1017.       if (hhcd->hc[chnum].ep_type == EP_TYPE_BULK)
  1018.       {
  1019.         hhcd->hc[chnum].toggle_out ^= 1U;
  1020.       }
  1021.     }
  1022.     else if (hhcd->hc[chnum].state == HC_NAK)
  1023.     {
  1024.       hhcd->hc[chnum].urb_state  = URB_NOTREADY;
  1025.     }
  1026.     else if (hhcd->hc[chnum].state == HC_NYET)
  1027.     {
  1028.       hhcd->hc[chnum].urb_state  = URB_NOTREADY;
  1029.       hhcd->hc[chnum].do_ping = 0U;
  1030.     }
  1031.     else if (hhcd->hc[chnum].state == HC_STALL)
  1032.     {
  1033.       hhcd->hc[chnum].urb_state  = URB_STALL;
  1034.     }
  1035.     else if((hhcd->hc[chnum].state == HC_XACTERR) ||
  1036.             (hhcd->hc[chnum].state == HC_DATATGLERR))
  1037.     {
  1038.       if(hhcd->hc[chnum].ErrCnt++ > 3U)
  1039.       {
  1040.         hhcd->hc[chnum].ErrCnt = 0U;
  1041.         hhcd->hc[chnum].urb_state = URB_ERROR;
  1042.       }
  1043.       else
  1044.       {
  1045.         hhcd->hc[chnum].urb_state = URB_NOTREADY;
  1046.       }
  1047.      
  1048.       /* re-activate the channel  */
  1049.       tmpreg = USBx_HC(chnum)->HCCHAR;
  1050.       tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  1051.       tmpreg |= USB_OTG_HCCHAR_CHENA;
  1052.       USBx_HC(chnum)->HCCHAR = tmpreg;
  1053.     }
  1054.    
  1055.     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
  1056.     HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
  1057.   }
  1058. }
  1059.  
  1060. /**
  1061.   * @brief  This function handles Rx Queue Level interrupt requests.
  1062.   * @param  hhcd: HCD handle
  1063.   * @retval none
  1064.   */
  1065. static void HCD_RXQLVL_IRQHandler  (HCD_HandleTypeDef *hhcd)
  1066. {
  1067.   USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
  1068.   uint8_t                       channelnum =0U;
  1069.   uint32_t                      pktsts;
  1070.   uint32_t                      pktcnt;
  1071.   uint32_t                      temp = 0U;
  1072.   uint32_t tmpreg = 0U;
  1073.  
  1074.   temp = hhcd->Instance->GRXSTSP;
  1075.   channelnum = temp &  USB_OTG_GRXSTSP_EPNUM;
  1076.   pktsts = (temp &  USB_OTG_GRXSTSP_PKTSTS) >> 17U;
  1077.   pktcnt = (temp &  USB_OTG_GRXSTSP_BCNT) >> 4U;
  1078.  
  1079.   switch (pktsts)
  1080.   {
  1081.   case GRXSTS_PKTSTS_IN:
  1082.     /* Read the data into the host buffer. */
  1083.     if ((pktcnt > 0U) && (hhcd->hc[channelnum].xfer_buff != (void  *)0U))
  1084.     {
  1085.       USB_ReadPacket(hhcd->Instance, hhcd->hc[channelnum].xfer_buff, pktcnt);
  1086.      
  1087.       /*manage multiple Xfer */
  1088.       hhcd->hc[channelnum].xfer_buff += pktcnt;
  1089.       hhcd->hc[channelnum].xfer_count  += pktcnt;
  1090.      
  1091.       if((USBx_HC(channelnum)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) > 0U)
  1092.       {
  1093.         /* re-activate the channel when more packets are expected */
  1094.         tmpreg = USBx_HC(channelnum)->HCCHAR;
  1095.         tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  1096.         tmpreg |= USB_OTG_HCCHAR_CHENA;
  1097.         USBx_HC(channelnum)->HCCHAR = tmpreg;
  1098.         hhcd->hc[channelnum].toggle_in ^= 1U;
  1099.       }
  1100.     }
  1101.     break;
  1102.  
  1103.   case GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
  1104.     break;
  1105.  
  1106.   case GRXSTS_PKTSTS_IN_XFER_COMP:
  1107.   case GRXSTS_PKTSTS_CH_HALTED:
  1108.   default:
  1109.     break;
  1110.   }
  1111. }
  1112.  
  1113. /**
  1114.   * @brief  This function handles Host Port interrupt requests.
  1115.   * @param  hhcd: HCD handle
  1116.   * @retval None
  1117.   */
  1118. static void HCD_Port_IRQHandler (HCD_HandleTypeDef *hhcd)
  1119. {
  1120.   USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;  
  1121.   __IO uint32_t hprt0 = 0, hprt0_dup = 0U;
  1122.  
  1123.   /* Handle Host Port Interrupts */
  1124.   hprt0 = USBx_HPRT0;
  1125.   hprt0_dup = USBx_HPRT0;
  1126.  
  1127.   hprt0_dup &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
  1128.                  USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
  1129.  
  1130.   /* Check whether Port Connect Detected */
  1131.   if((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET)
  1132.   {
  1133.     if((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS)
  1134.     {
  1135.       USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT);
  1136.       HAL_HCD_Connect_Callback(hhcd);
  1137.     }
  1138.     hprt0_dup  |= USB_OTG_HPRT_PCDET;
  1139.   }
  1140.  
  1141.   /* Check whether Port Enable Changed */
  1142.   if((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG)
  1143.   {
  1144.     hprt0_dup |= USB_OTG_HPRT_PENCHNG;
  1145.    
  1146.     if((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA)
  1147.     {
  1148.       if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17U))
  1149.       {
  1150.         USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_6_MHZ );
  1151.       }
  1152.       else
  1153.       {
  1154.         USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_48_MHZ );
  1155.       }
  1156.       HAL_HCD_Connect_Callback(hhcd);
  1157.     }
  1158.     else
  1159.     {
  1160.       /* Cleanup HPRT */
  1161.       USBx_HPRT0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
  1162.         USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
  1163.      
  1164.       USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT);
  1165.     }
  1166.   }
  1167.  
  1168.   /* Check For an over current */
  1169.   if((hprt0 & USB_OTG_HPRT_POCCHNG) == USB_OTG_HPRT_POCCHNG)
  1170.   {
  1171.     hprt0_dup |= USB_OTG_HPRT_POCCHNG;
  1172.   }
  1173.  
  1174.   /* Clear Port Interrupts */
  1175.   USBx_HPRT0 = hprt0_dup;
  1176. }
  1177.  
  1178. /**
  1179.   * @}
  1180.   */
  1181.  
  1182. /**
  1183.   * @}
  1184.   */
  1185.  
  1186. #endif /* STM32F105xC || STM32F107xC */
  1187.  
  1188. #endif /* HAL_HCD_MODULE_ENABLED */
  1189.  
  1190. /**
  1191.   * @}
  1192.   */
  1193.  
  1194. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
  1195.