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