Subversion Repositories DashDisplay

Rev

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