1 /**
2   ******************************************************************************
3   * @file    stm32f2xx_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   ******************************************************************************
14   * @attention
15   *
16   * Copyright (c) 2016 STMicroelectronics.
17   * All rights reserved.
18   *
19   * This software is licensed under terms that can be found in the LICENSE file
20   * in the root directory of this software component.
21   * If no LICENSE file comes with this software, it is provided AS-IS.
22   *
23   ******************************************************************************
24   @verbatim
25   ==============================================================================
26                     ##### How to use this driver #####
27   ==============================================================================
28   [..]
29     (#)Declare a HCD_HandleTypeDef handle structure, for example:
30        HCD_HandleTypeDef  hhcd;
31 
32     (#)Fill parameters of Init structure in HCD handle
33 
34     (#)Call HAL_HCD_Init() API to initialize the HCD peripheral (Core, Host core, ...)
35 
36     (#)Initialize the HCD low level resources through the HAL_HCD_MspInit() API:
37         (##) Enable the HCD/USB Low Level interface clock using the following macros
38              (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
39              (+++) __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); (For High Speed Mode)
40              (+++) __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE(); (For High Speed Mode)
41 
42         (##) Initialize the related GPIO clocks
43         (##) Configure HCD pin-out
44         (##) Configure HCD NVIC interrupt
45 
46     (#)Associate the Upper USB Host stack to the HAL HCD Driver:
47         (##) hhcd.pData = phost;
48 
49     (#)Enable HCD transmission and reception:
50         (##) HAL_HCD_Start();
51 
52   @endverbatim
53   ******************************************************************************
54   */
55 
56 /* Includes ------------------------------------------------------------------*/
57 #include "stm32f2xx_hal.h"
58 
59 /** @addtogroup STM32F2xx_HAL_Driver
60   * @{
61   */
62 
63 #ifdef HAL_HCD_MODULE_ENABLED
64 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
65 
66 /** @defgroup HCD HCD
67   * @brief HCD HAL module driver
68   * @{
69   */
70 
71 /* Private typedef -----------------------------------------------------------*/
72 /* Private define ------------------------------------------------------------*/
73 /* Private macro -------------------------------------------------------------*/
74 /* Private variables ---------------------------------------------------------*/
75 /* Private function prototypes -----------------------------------------------*/
76 /** @defgroup HCD_Private_Functions HCD Private Functions
77   * @{
78   */
79 static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
80 static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
81 static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd);
82 static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd);
83 /**
84   * @}
85   */
86 
87 /* Exported functions --------------------------------------------------------*/
88 /** @defgroup HCD_Exported_Functions HCD Exported Functions
89   * @{
90   */
91 
92 /** @defgroup HCD_Exported_Functions_Group1 Initialization and de-initialization functions
93   *  @brief    Initialization and Configuration functions
94   *
95 @verbatim
96  ===============================================================================
97           ##### Initialization and de-initialization functions #####
98  ===============================================================================
99     [..]  This section provides functions allowing to:
100 
101 @endverbatim
102   * @{
103   */
104 
105 /**
106   * @brief  Initialize the host driver.
107   * @param  hhcd HCD handle
108   * @retval HAL status
109   */
HAL_HCD_Init(HCD_HandleTypeDef * hhcd)110 HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd)
111 {
112   USB_OTG_GlobalTypeDef *USBx;
113 
114   /* Check the HCD handle allocation */
115   if (hhcd == NULL)
116   {
117     return HAL_ERROR;
118   }
119 
120   /* Check the parameters */
121   assert_param(IS_HCD_ALL_INSTANCE(hhcd->Instance));
122 
123   USBx = hhcd->Instance;
124 
125   if (hhcd->State == HAL_HCD_STATE_RESET)
126   {
127     /* Allocate lock resource and initialize it */
128     hhcd->Lock = HAL_UNLOCKED;
129 
130 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
131     hhcd->SOFCallback = HAL_HCD_SOF_Callback;
132     hhcd->ConnectCallback = HAL_HCD_Connect_Callback;
133     hhcd->DisconnectCallback = HAL_HCD_Disconnect_Callback;
134     hhcd->PortEnabledCallback = HAL_HCD_PortEnabled_Callback;
135     hhcd->PortDisabledCallback = HAL_HCD_PortDisabled_Callback;
136     hhcd->HC_NotifyURBChangeCallback = HAL_HCD_HC_NotifyURBChange_Callback;
137 
138     if (hhcd->MspInitCallback == NULL)
139     {
140       hhcd->MspInitCallback = HAL_HCD_MspInit;
141     }
142 
143     /* Init the low level hardware */
144     hhcd->MspInitCallback(hhcd);
145 #else
146     /* Init the low level hardware : GPIO, CLOCK, NVIC... */
147     HAL_HCD_MspInit(hhcd);
148 #endif /* (USE_HAL_HCD_REGISTER_CALLBACKS) */
149   }
150 
151   hhcd->State = HAL_HCD_STATE_BUSY;
152 
153   /* Disable DMA mode for FS instance */
154   if ((USBx->CID & (0x1U << 8)) == 0U)
155   {
156     hhcd->Init.dma_enable = 0U;
157   }
158 
159   /* Disable the Interrupts */
160   __HAL_HCD_DISABLE(hhcd);
161 
162   /* Init the Core (common init.) */
163   (void)USB_CoreInit(hhcd->Instance, hhcd->Init);
164 
165   /* Force Host Mode*/
166   (void)USB_SetCurrentMode(hhcd->Instance, USB_HOST_MODE);
167 
168   /* Init Host */
169   (void)USB_HostInit(hhcd->Instance, hhcd->Init);
170 
171   hhcd->State = HAL_HCD_STATE_READY;
172 
173   return HAL_OK;
174 }
175 
176 /**
177   * @brief  Initialize a host channel.
178   * @param  hhcd HCD handle
179   * @param  ch_num Channel number.
180   *         This parameter can be a value from 1 to 15
181   * @param  epnum Endpoint number.
182   *          This parameter can be a value from 1 to 15
183   * @param  dev_address Current device address
184   *          This parameter can be a value from 0 to 255
185   * @param  speed Current device speed.
186   *          This parameter can be one of these values:
187   *            HCD_DEVICE_SPEED_HIGH: High speed mode,
188   *            HCD_DEVICE_SPEED_FULL: Full speed mode,
189   *            HCD_DEVICE_SPEED_LOW: Low speed mode
190   * @param  ep_type Endpoint Type.
191   *          This parameter can be one of these values:
192   *            EP_TYPE_CTRL: Control type,
193   *            EP_TYPE_ISOC: Isochronous type,
194   *            EP_TYPE_BULK: Bulk type,
195   *            EP_TYPE_INTR: Interrupt type
196   * @param  mps Max Packet Size.
197   *          This parameter can be a value from 0 to32K
198   * @retval HAL status
199   */
HAL_HCD_HC_Init(HCD_HandleTypeDef * hhcd,uint8_t ch_num,uint8_t epnum,uint8_t dev_address,uint8_t speed,uint8_t ep_type,uint16_t mps)200 HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd, uint8_t ch_num, uint8_t epnum,
201                                   uint8_t dev_address, uint8_t speed, uint8_t ep_type, uint16_t mps)
202 {
203   HAL_StatusTypeDef status;
204   uint32_t HostCoreSpeed;
205   uint32_t HCcharMps = mps;
206 
207   __HAL_LOCK(hhcd);
208   hhcd->hc[ch_num].do_ping = 0U;
209   hhcd->hc[ch_num].dev_addr = dev_address;
210   hhcd->hc[ch_num].ch_num = ch_num;
211   hhcd->hc[ch_num].ep_type = ep_type;
212   hhcd->hc[ch_num].ep_num = epnum & 0x7FU;
213 
214   (void)HAL_HCD_HC_ClearHubInfo(hhcd, ch_num);
215 
216   if ((epnum & 0x80U) == 0x80U)
217   {
218     hhcd->hc[ch_num].ep_is_in = 1U;
219   }
220   else
221   {
222     hhcd->hc[ch_num].ep_is_in = 0U;
223   }
224 
225   HostCoreSpeed = USB_GetHostSpeed(hhcd->Instance);
226 
227   if (ep_type == EP_TYPE_ISOC)
228   {
229     /* FS device plugged to HS HUB */
230     if ((speed == HCD_DEVICE_SPEED_FULL) && (HostCoreSpeed == HPRT0_PRTSPD_HIGH_SPEED))
231     {
232       if (HCcharMps > ISO_SPLT_MPS)
233       {
234         /* ISO Max Packet Size for Split mode */
235         HCcharMps = ISO_SPLT_MPS;
236       }
237     }
238   }
239 
240   hhcd->hc[ch_num].speed = speed;
241   hhcd->hc[ch_num].max_packet = (uint16_t)HCcharMps;
242 
243   status =  USB_HC_Init(hhcd->Instance, ch_num, epnum,
244                         dev_address, speed, ep_type, (uint16_t)HCcharMps);
245 
246   __HAL_UNLOCK(hhcd);
247 
248   return status;
249 }
250 
251 /**
252   * @brief  Halt a host channel.
253   * @param  hhcd HCD handle
254   * @param  ch_num Channel number.
255   *         This parameter can be a value from 1 to 15
256   * @retval HAL status
257   */
HAL_HCD_HC_Halt(HCD_HandleTypeDef * hhcd,uint8_t ch_num)258 HAL_StatusTypeDef HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd, uint8_t ch_num)
259 {
260   HAL_StatusTypeDef status = HAL_OK;
261 
262   __HAL_LOCK(hhcd);
263   (void)USB_HC_Halt(hhcd->Instance, ch_num);
264   __HAL_UNLOCK(hhcd);
265 
266   return status;
267 }
268 
269 /**
270   * @brief  DeInitialize the host driver.
271   * @param  hhcd HCD handle
272   * @retval HAL status
273   */
HAL_HCD_DeInit(HCD_HandleTypeDef * hhcd)274 HAL_StatusTypeDef HAL_HCD_DeInit(HCD_HandleTypeDef *hhcd)
275 {
276   /* Check the HCD handle allocation */
277   if (hhcd == NULL)
278   {
279     return HAL_ERROR;
280   }
281 
282   hhcd->State = HAL_HCD_STATE_BUSY;
283 
284 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
285   if (hhcd->MspDeInitCallback == NULL)
286   {
287     hhcd->MspDeInitCallback = HAL_HCD_MspDeInit; /* Legacy weak MspDeInit  */
288   }
289 
290   /* DeInit the low level hardware */
291   hhcd->MspDeInitCallback(hhcd);
292 #else
293   /* DeInit the low level hardware: CLOCK, NVIC.*/
294   HAL_HCD_MspDeInit(hhcd);
295 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
296 
297   __HAL_HCD_DISABLE(hhcd);
298 
299   hhcd->State = HAL_HCD_STATE_RESET;
300 
301   return HAL_OK;
302 }
303 
304 /**
305   * @brief  Initialize the HCD MSP.
306   * @param  hhcd HCD handle
307   * @retval None
308   */
HAL_HCD_MspInit(HCD_HandleTypeDef * hhcd)309 __weak void  HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd)
310 {
311   /* Prevent unused argument(s) compilation warning */
312   UNUSED(hhcd);
313 
314   /* NOTE : This function should not be modified, when the callback is needed,
315             the HAL_HCD_MspInit could be implemented in the user file
316    */
317 }
318 
319 /**
320   * @brief  DeInitialize the HCD MSP.
321   * @param  hhcd HCD handle
322   * @retval None
323   */
HAL_HCD_MspDeInit(HCD_HandleTypeDef * hhcd)324 __weak void  HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd)
325 {
326   /* Prevent unused argument(s) compilation warning */
327   UNUSED(hhcd);
328 
329   /* NOTE : This function should not be modified, when the callback is needed,
330             the HAL_HCD_MspDeInit could be implemented in the user file
331    */
332 }
333 
334 /**
335   * @}
336   */
337 
338 /** @defgroup HCD_Exported_Functions_Group2 Input and Output operation functions
339   *  @brief   HCD IO operation functions
340   *
341 @verbatim
342  ===============================================================================
343                       ##### IO operation functions #####
344  ===============================================================================
345  [..] This subsection provides a set of functions allowing to manage the USB Host Data
346     Transfer
347 
348 @endverbatim
349   * @{
350   */
351 
352 /**
353   * @brief  Submit a new URB for processing.
354   * @param  hhcd HCD handle
355   * @param  ch_num Channel number.
356   *         This parameter can be a value from 1 to 15
357   * @param  direction Channel number.
358   *          This parameter can be one of these values:
359   *           0 : Output / 1 : Input
360   * @param  ep_type Endpoint Type.
361   *          This parameter can be one of these values:
362   *            EP_TYPE_CTRL: Control type/
363   *            EP_TYPE_ISOC: Isochronous type/
364   *            EP_TYPE_BULK: Bulk type/
365   *            EP_TYPE_INTR: Interrupt type/
366   * @param  token Endpoint Type.
367   *          This parameter can be one of these values:
368   *            0: HC_PID_SETUP / 1: HC_PID_DATA1
369   * @param  pbuff pointer to URB data
370   * @param  length Length of URB data
371   * @param  do_ping activate do ping protocol (for high speed only).
372   *          This parameter can be one of these values:
373   *           0 : do ping inactive / 1 : do ping active
374   * @retval HAL status
375   */
HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef * hhcd,uint8_t ch_num,uint8_t direction,uint8_t ep_type,uint8_t token,uint8_t * pbuff,uint16_t length,uint8_t do_ping)376 HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd,
377                                            uint8_t ch_num,
378                                            uint8_t direction,
379                                            uint8_t ep_type,
380                                            uint8_t token,
381                                            uint8_t *pbuff,
382                                            uint16_t length,
383                                            uint8_t do_ping)
384 {
385   hhcd->hc[ch_num].ep_is_in = direction;
386   hhcd->hc[ch_num].ep_type  = ep_type;
387 
388   if (token == 0U)
389   {
390     hhcd->hc[ch_num].data_pid = HC_PID_SETUP;
391     hhcd->hc[ch_num].do_ping = do_ping;
392   }
393   else
394   {
395     hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
396   }
397 
398   /* Manage Data Toggle */
399   switch (ep_type)
400   {
401     case EP_TYPE_CTRL:
402       if (token == 1U) /* send data */
403       {
404         if (direction == 0U)
405         {
406           if (length == 0U)
407           {
408             /* For Status OUT stage, Length == 0U, Status Out PID = 1 */
409             hhcd->hc[ch_num].toggle_out = 1U;
410           }
411 
412           /* Set the Data Toggle bit as per the Flag */
413           if (hhcd->hc[ch_num].toggle_out == 0U)
414           {
415             /* Put the PID 0 */
416             hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
417           }
418           else
419           {
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].do_ssplit == 1U)
427           {
428             if (hhcd->hc[ch_num].toggle_in == 0U)
429             {
430               hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
431             }
432             else
433             {
434               hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
435             }
436           }
437         }
438       }
439       break;
440 
441     case EP_TYPE_BULK:
442       if (direction == 0U)
443       {
444         /* Set the Data Toggle bit as per the Flag */
445         if (hhcd->hc[ch_num].toggle_out == 0U)
446         {
447           /* Put the PID 0 */
448           hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
449         }
450         else
451         {
452           /* Put the PID 1 */
453           hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
454         }
455       }
456       else
457       {
458         if (hhcd->hc[ch_num].toggle_in == 0U)
459         {
460           hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
461         }
462         else
463         {
464           hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
465         }
466       }
467 
468       break;
469     case EP_TYPE_INTR:
470       if (direction == 0U)
471       {
472         /* Set the Data Toggle bit as per the Flag */
473         if (hhcd->hc[ch_num].toggle_out == 0U)
474         {
475           /* Put the PID 0 */
476           hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
477         }
478         else
479         {
480           /* Put the PID 1 */
481           hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
482         }
483       }
484       else
485       {
486         if (hhcd->hc[ch_num].toggle_in == 0U)
487         {
488           hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
489         }
490         else
491         {
492           hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
493         }
494       }
495       break;
496 
497     case EP_TYPE_ISOC:
498       hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
499       break;
500 
501     default:
502       break;
503   }
504 
505   hhcd->hc[ch_num].xfer_buff = pbuff;
506   hhcd->hc[ch_num].xfer_len  = length;
507   hhcd->hc[ch_num].urb_state = URB_IDLE;
508   hhcd->hc[ch_num].xfer_count = 0U;
509   hhcd->hc[ch_num].ch_num = ch_num;
510   hhcd->hc[ch_num].state = HC_IDLE;
511 
512   return USB_HC_StartXfer(hhcd->Instance, &hhcd->hc[ch_num], (uint8_t)hhcd->Init.dma_enable);
513 }
514 
515 /**
516   * @brief  Handle HCD interrupt request.
517   * @param  hhcd HCD handle
518   * @retval None
519   */
HAL_HCD_IRQHandler(HCD_HandleTypeDef * hhcd)520 void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd)
521 {
522   USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
523   uint32_t USBx_BASE = (uint32_t)USBx;
524   uint32_t i;
525   uint32_t interrupt;
526 
527   /* Ensure that we are in device mode */
528   if (USB_GetMode(hhcd->Instance) == USB_OTG_MODE_HOST)
529   {
530     /* Avoid spurious interrupt */
531     if (__HAL_HCD_IS_INVALID_INTERRUPT(hhcd))
532     {
533       return;
534     }
535 
536     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
537     {
538       /* Incorrect mode, acknowledge the interrupt */
539       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
540     }
541 
542     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR))
543     {
544       /* Incorrect mode, acknowledge the interrupt */
545       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR);
546     }
547 
548     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE))
549     {
550       /* Incorrect mode, acknowledge the interrupt */
551       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE);
552     }
553 
554     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_MMIS))
555     {
556       /* Incorrect mode, acknowledge the interrupt */
557       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_MMIS);
558     }
559 
560     /* Handle Host Disconnect Interrupts */
561     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT))
562     {
563       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT);
564 
565       if ((USBx_HPRT0 & USB_OTG_HPRT_PCSTS) == 0U)
566       {
567         /* Flush USB Fifo */
568         (void)USB_FlushTxFifo(USBx, 0x10U);
569         (void)USB_FlushRxFifo(USBx);
570 
571         if (hhcd->Init.phy_itface == USB_OTG_EMBEDDED_PHY)
572         {
573           /* Restore FS Clock */
574           (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_48_MHZ);
575         }
576 
577         /* Handle Host Port Disconnect Interrupt */
578 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
579         hhcd->DisconnectCallback(hhcd);
580 #else
581         HAL_HCD_Disconnect_Callback(hhcd);
582 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
583       }
584     }
585 
586     /* Handle Host Port Interrupts */
587     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HPRTINT))
588     {
589       HCD_Port_IRQHandler(hhcd);
590     }
591 
592     /* Handle Host SOF Interrupt */
593     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_SOF))
594     {
595 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
596       hhcd->SOFCallback(hhcd);
597 #else
598       HAL_HCD_SOF_Callback(hhcd);
599 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
600 
601       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_SOF);
602     }
603 
604     /* Handle Host channel Interrupt */
605     if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HCINT))
606     {
607       interrupt = USB_HC_ReadInterrupt(hhcd->Instance);
608       for (i = 0U; i < hhcd->Init.Host_channels; i++)
609       {
610         if ((interrupt & (1UL << (i & 0xFU))) != 0U)
611         {
612           if ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_EPDIR) == USB_OTG_HCCHAR_EPDIR)
613           {
614             HCD_HC_IN_IRQHandler(hhcd, (uint8_t)i);
615           }
616           else
617           {
618             HCD_HC_OUT_IRQHandler(hhcd, (uint8_t)i);
619           }
620         }
621       }
622       __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_HCINT);
623     }
624 
625     /* Handle Rx Queue Level Interrupts */
626     if ((__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_RXFLVL)) != 0U)
627     {
628       USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
629 
630       HCD_RXQLVL_IRQHandler(hhcd);
631 
632       USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
633     }
634   }
635 }
636 
637 
638 /**
639   * @brief  Handles HCD Wakeup interrupt request.
640   * @param  hhcd HCD handle
641   * @retval HAL status
642   */
HAL_HCD_WKUP_IRQHandler(HCD_HandleTypeDef * hhcd)643 void HAL_HCD_WKUP_IRQHandler(HCD_HandleTypeDef *hhcd)
644 {
645   UNUSED(hhcd);
646 }
647 
648 
649 /**
650   * @brief  SOF callback.
651   * @param  hhcd HCD handle
652   * @retval None
653   */
HAL_HCD_SOF_Callback(HCD_HandleTypeDef * hhcd)654 __weak void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd)
655 {
656   /* Prevent unused argument(s) compilation warning */
657   UNUSED(hhcd);
658 
659   /* NOTE : This function should not be modified, when the callback is needed,
660             the HAL_HCD_SOF_Callback could be implemented in the user file
661    */
662 }
663 
664 /**
665   * @brief Connection Event callback.
666   * @param  hhcd HCD handle
667   * @retval None
668   */
HAL_HCD_Connect_Callback(HCD_HandleTypeDef * hhcd)669 __weak void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
670 {
671   /* Prevent unused argument(s) compilation warning */
672   UNUSED(hhcd);
673 
674   /* NOTE : This function should not be modified, when the callback is needed,
675             the HAL_HCD_Connect_Callback could be implemented in the user file
676    */
677 }
678 
679 /**
680   * @brief  Disconnection Event callback.
681   * @param  hhcd HCD handle
682   * @retval None
683   */
HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef * hhcd)684 __weak void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
685 {
686   /* Prevent unused argument(s) compilation warning */
687   UNUSED(hhcd);
688 
689   /* NOTE : This function should not be modified, when the callback is needed,
690             the HAL_HCD_Disconnect_Callback could be implemented in the user file
691    */
692 }
693 
694 /**
695   * @brief  Port Enabled  Event callback.
696   * @param  hhcd HCD handle
697   * @retval None
698   */
HAL_HCD_PortEnabled_Callback(HCD_HandleTypeDef * hhcd)699 __weak void HAL_HCD_PortEnabled_Callback(HCD_HandleTypeDef *hhcd)
700 {
701   /* Prevent unused argument(s) compilation warning */
702   UNUSED(hhcd);
703 
704   /* NOTE : This function should not be modified, when the callback is needed,
705             the HAL_HCD_Disconnect_Callback could be implemented in the user file
706    */
707 }
708 
709 /**
710   * @brief  Port Disabled  Event callback.
711   * @param  hhcd HCD handle
712   * @retval None
713   */
HAL_HCD_PortDisabled_Callback(HCD_HandleTypeDef * hhcd)714 __weak void HAL_HCD_PortDisabled_Callback(HCD_HandleTypeDef *hhcd)
715 {
716   /* Prevent unused argument(s) compilation warning */
717   UNUSED(hhcd);
718 
719   /* NOTE : This function should not be modified, when the callback is needed,
720             the HAL_HCD_Disconnect_Callback could be implemented in the user file
721    */
722 }
723 
724 /**
725   * @brief  Notify URB state change callback.
726   * @param  hhcd HCD handle
727   * @param  chnum Channel number.
728   *         This parameter can be a value from 1 to 15
729   * @param  urb_state:
730   *          This parameter can be one of these values:
731   *            URB_IDLE/
732   *            URB_DONE/
733   *            URB_NOTREADY/
734   *            URB_NYET/
735   *            URB_ERROR/
736   *            URB_STALL/
737   * @retval None
738   */
HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef * hhcd,uint8_t chnum,HCD_URBStateTypeDef urb_state)739 __weak void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state)
740 {
741   /* Prevent unused argument(s) compilation warning */
742   UNUSED(hhcd);
743   UNUSED(chnum);
744   UNUSED(urb_state);
745 
746   /* NOTE : This function should not be modified, when the callback is needed,
747             the HAL_HCD_HC_NotifyURBChange_Callback could be implemented in the user file
748    */
749 }
750 
751 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
752 /**
753   * @brief  Register a User USB HCD Callback
754   *         To be used instead of the weak predefined callback
755   * @param  hhcd USB HCD handle
756   * @param  CallbackID ID of the callback to be registered
757   *         This parameter can be one of the following values:
758   *          @arg @ref HAL_HCD_SOF_CB_ID USB HCD SOF callback ID
759   *          @arg @ref HAL_HCD_CONNECT_CB_ID USB HCD Connect callback ID
760   *          @arg @ref HAL_HCD_DISCONNECT_CB_ID OTG HCD Disconnect callback ID
761   *          @arg @ref HAL_HCD_PORT_ENABLED_CB_ID USB HCD Port Enable callback ID
762   *          @arg @ref HAL_HCD_PORT_DISABLED_CB_ID USB HCD Port Disable callback ID
763   *          @arg @ref HAL_HCD_MSPINIT_CB_ID MspDeInit callback ID
764   *          @arg @ref HAL_HCD_MSPDEINIT_CB_ID MspDeInit callback ID
765   * @param  pCallback pointer to the Callback function
766   * @retval HAL status
767   */
HAL_HCD_RegisterCallback(HCD_HandleTypeDef * hhcd,HAL_HCD_CallbackIDTypeDef CallbackID,pHCD_CallbackTypeDef pCallback)768 HAL_StatusTypeDef HAL_HCD_RegisterCallback(HCD_HandleTypeDef *hhcd,
769                                            HAL_HCD_CallbackIDTypeDef CallbackID,
770                                            pHCD_CallbackTypeDef pCallback)
771 {
772   HAL_StatusTypeDef status = HAL_OK;
773 
774   if (pCallback == NULL)
775   {
776     /* Update the error code */
777     hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
778     return HAL_ERROR;
779   }
780   /* Process locked */
781   __HAL_LOCK(hhcd);
782 
783   if (hhcd->State == HAL_HCD_STATE_READY)
784   {
785     switch (CallbackID)
786     {
787       case HAL_HCD_SOF_CB_ID :
788         hhcd->SOFCallback = pCallback;
789         break;
790 
791       case HAL_HCD_CONNECT_CB_ID :
792         hhcd->ConnectCallback = pCallback;
793         break;
794 
795       case HAL_HCD_DISCONNECT_CB_ID :
796         hhcd->DisconnectCallback = pCallback;
797         break;
798 
799       case HAL_HCD_PORT_ENABLED_CB_ID :
800         hhcd->PortEnabledCallback = pCallback;
801         break;
802 
803       case HAL_HCD_PORT_DISABLED_CB_ID :
804         hhcd->PortDisabledCallback = pCallback;
805         break;
806 
807       case HAL_HCD_MSPINIT_CB_ID :
808         hhcd->MspInitCallback = pCallback;
809         break;
810 
811       case HAL_HCD_MSPDEINIT_CB_ID :
812         hhcd->MspDeInitCallback = pCallback;
813         break;
814 
815       default :
816         /* Update the error code */
817         hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
818         /* Return error status */
819         status =  HAL_ERROR;
820         break;
821     }
822   }
823   else if (hhcd->State == HAL_HCD_STATE_RESET)
824   {
825     switch (CallbackID)
826     {
827       case HAL_HCD_MSPINIT_CB_ID :
828         hhcd->MspInitCallback = pCallback;
829         break;
830 
831       case HAL_HCD_MSPDEINIT_CB_ID :
832         hhcd->MspDeInitCallback = pCallback;
833         break;
834 
835       default :
836         /* Update the error code */
837         hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
838         /* Return error status */
839         status =  HAL_ERROR;
840         break;
841     }
842   }
843   else
844   {
845     /* Update the error code */
846     hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
847     /* Return error status */
848     status =  HAL_ERROR;
849   }
850 
851   /* Release Lock */
852   __HAL_UNLOCK(hhcd);
853   return status;
854 }
855 
856 /**
857   * @brief  Unregister an USB HCD Callback
858   *         USB HCD callback is redirected to the weak predefined callback
859   * @param  hhcd USB HCD handle
860   * @param  CallbackID ID of the callback to be unregistered
861   *         This parameter can be one of the following values:
862   *          @arg @ref HAL_HCD_SOF_CB_ID USB HCD SOF callback ID
863   *          @arg @ref HAL_HCD_CONNECT_CB_ID USB HCD Connect callback ID
864   *          @arg @ref HAL_HCD_DISCONNECT_CB_ID OTG HCD Disconnect callback ID
865   *          @arg @ref HAL_HCD_PORT_ENABLED_CB_ID USB HCD Port Enabled callback ID
866   *          @arg @ref HAL_HCD_PORT_DISABLED_CB_ID USB HCD Port Disabled callback ID
867   *          @arg @ref HAL_HCD_MSPINIT_CB_ID MspDeInit callback ID
868   *          @arg @ref HAL_HCD_MSPDEINIT_CB_ID MspDeInit callback ID
869   * @retval HAL status
870   */
HAL_HCD_UnRegisterCallback(HCD_HandleTypeDef * hhcd,HAL_HCD_CallbackIDTypeDef CallbackID)871 HAL_StatusTypeDef HAL_HCD_UnRegisterCallback(HCD_HandleTypeDef *hhcd, HAL_HCD_CallbackIDTypeDef CallbackID)
872 {
873   HAL_StatusTypeDef status = HAL_OK;
874 
875   /* Process locked */
876   __HAL_LOCK(hhcd);
877 
878   /* Setup Legacy weak Callbacks  */
879   if (hhcd->State == HAL_HCD_STATE_READY)
880   {
881     switch (CallbackID)
882     {
883       case HAL_HCD_SOF_CB_ID :
884         hhcd->SOFCallback = HAL_HCD_SOF_Callback;
885         break;
886 
887       case HAL_HCD_CONNECT_CB_ID :
888         hhcd->ConnectCallback = HAL_HCD_Connect_Callback;
889         break;
890 
891       case HAL_HCD_DISCONNECT_CB_ID :
892         hhcd->DisconnectCallback = HAL_HCD_Disconnect_Callback;
893         break;
894 
895       case HAL_HCD_PORT_ENABLED_CB_ID :
896         hhcd->PortEnabledCallback = HAL_HCD_PortEnabled_Callback;
897         break;
898 
899       case HAL_HCD_PORT_DISABLED_CB_ID :
900         hhcd->PortDisabledCallback = HAL_HCD_PortDisabled_Callback;
901         break;
902 
903       case HAL_HCD_MSPINIT_CB_ID :
904         hhcd->MspInitCallback = HAL_HCD_MspInit;
905         break;
906 
907       case HAL_HCD_MSPDEINIT_CB_ID :
908         hhcd->MspDeInitCallback = HAL_HCD_MspDeInit;
909         break;
910 
911       default :
912         /* Update the error code */
913         hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
914 
915         /* Return error status */
916         status =  HAL_ERROR;
917         break;
918     }
919   }
920   else if (hhcd->State == HAL_HCD_STATE_RESET)
921   {
922     switch (CallbackID)
923     {
924       case HAL_HCD_MSPINIT_CB_ID :
925         hhcd->MspInitCallback = HAL_HCD_MspInit;
926         break;
927 
928       case HAL_HCD_MSPDEINIT_CB_ID :
929         hhcd->MspDeInitCallback = HAL_HCD_MspDeInit;
930         break;
931 
932       default :
933         /* Update the error code */
934         hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
935 
936         /* Return error status */
937         status =  HAL_ERROR;
938         break;
939     }
940   }
941   else
942   {
943     /* Update the error code */
944     hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
945 
946     /* Return error status */
947     status =  HAL_ERROR;
948   }
949 
950   /* Release Lock */
951   __HAL_UNLOCK(hhcd);
952   return status;
953 }
954 
955 /**
956   * @brief  Register USB HCD Host Channel Notify URB Change Callback
957   *         To be used instead of the weak HAL_HCD_HC_NotifyURBChange_Callback() predefined callback
958   * @param  hhcd HCD handle
959   * @param  pCallback pointer to the USB HCD Host Channel Notify URB Change Callback function
960   * @retval HAL status
961   */
HAL_HCD_RegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef * hhcd,pHCD_HC_NotifyURBChangeCallbackTypeDef pCallback)962 HAL_StatusTypeDef HAL_HCD_RegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd,
963                                                              pHCD_HC_NotifyURBChangeCallbackTypeDef pCallback)
964 {
965   HAL_StatusTypeDef status = HAL_OK;
966 
967   if (pCallback == NULL)
968   {
969     /* Update the error code */
970     hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
971 
972     return HAL_ERROR;
973   }
974 
975   /* Process locked */
976   __HAL_LOCK(hhcd);
977 
978   if (hhcd->State == HAL_HCD_STATE_READY)
979   {
980     hhcd->HC_NotifyURBChangeCallback = pCallback;
981   }
982   else
983   {
984     /* Update the error code */
985     hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
986 
987     /* Return error status */
988     status =  HAL_ERROR;
989   }
990 
991   /* Release Lock */
992   __HAL_UNLOCK(hhcd);
993 
994   return status;
995 }
996 
997 /**
998   * @brief  Unregister the USB HCD Host Channel Notify URB Change Callback
999   *         USB HCD Host Channel Notify URB Change Callback is redirected
1000   *         to the weak HAL_HCD_HC_NotifyURBChange_Callback() predefined callback
1001   * @param  hhcd HCD handle
1002   * @retval HAL status
1003   */
HAL_HCD_UnRegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef * hhcd)1004 HAL_StatusTypeDef HAL_HCD_UnRegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd)
1005 {
1006   HAL_StatusTypeDef status = HAL_OK;
1007 
1008   /* Process locked */
1009   __HAL_LOCK(hhcd);
1010 
1011   if (hhcd->State == HAL_HCD_STATE_READY)
1012   {
1013     hhcd->HC_NotifyURBChangeCallback = HAL_HCD_HC_NotifyURBChange_Callback; /* Legacy weak DataOutStageCallback  */
1014   }
1015   else
1016   {
1017     /* Update the error code */
1018     hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
1019 
1020     /* Return error status */
1021     status =  HAL_ERROR;
1022   }
1023 
1024   /* Release Lock */
1025   __HAL_UNLOCK(hhcd);
1026 
1027   return status;
1028 }
1029 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1030 
1031 /**
1032   * @}
1033   */
1034 
1035 /** @defgroup HCD_Exported_Functions_Group3 Peripheral Control functions
1036   *  @brief   Management functions
1037   *
1038 @verbatim
1039  ===============================================================================
1040                       ##### Peripheral Control functions #####
1041  ===============================================================================
1042     [..]
1043     This subsection provides a set of functions allowing to control the HCD data
1044     transfers.
1045 
1046 @endverbatim
1047   * @{
1048   */
1049 
1050 /**
1051   * @brief  Start the host driver.
1052   * @param  hhcd HCD handle
1053   * @retval HAL status
1054   */
HAL_HCD_Start(HCD_HandleTypeDef * hhcd)1055 HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd)
1056 {
1057   __HAL_LOCK(hhcd);
1058   /* Enable port power */
1059   (void)USB_DriveVbus(hhcd->Instance, 1U);
1060 
1061   /* Enable global interrupt */
1062   __HAL_HCD_ENABLE(hhcd);
1063   __HAL_UNLOCK(hhcd);
1064 
1065   return HAL_OK;
1066 }
1067 
1068 /**
1069   * @brief  Stop the host driver.
1070   * @param  hhcd HCD handle
1071   * @retval HAL status
1072   */
1073 
HAL_HCD_Stop(HCD_HandleTypeDef * hhcd)1074 HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd)
1075 {
1076   __HAL_LOCK(hhcd);
1077   (void)USB_StopHost(hhcd->Instance);
1078   __HAL_UNLOCK(hhcd);
1079 
1080   return HAL_OK;
1081 }
1082 
1083 /**
1084   * @brief  Reset the host port.
1085   * @param  hhcd HCD handle
1086   * @retval HAL status
1087   */
HAL_HCD_ResetPort(HCD_HandleTypeDef * hhcd)1088 HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd)
1089 {
1090   return (USB_ResetPort(hhcd->Instance));
1091 }
1092 
1093 /**
1094   * @}
1095   */
1096 
1097 /** @defgroup HCD_Exported_Functions_Group4 Peripheral State functions
1098   *  @brief   Peripheral State functions
1099   *
1100 @verbatim
1101  ===============================================================================
1102                       ##### Peripheral State functions #####
1103  ===============================================================================
1104     [..]
1105     This subsection permits to get in run-time the status of the peripheral
1106     and the data flow.
1107 
1108 @endverbatim
1109   * @{
1110   */
1111 
1112 /**
1113   * @brief  Return the HCD handle state.
1114   * @param  hhcd HCD handle
1115   * @retval HAL state
1116   */
HAL_HCD_GetState(HCD_HandleTypeDef const * hhcd)1117 HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef const *hhcd)
1118 {
1119   return hhcd->State;
1120 }
1121 
1122 /**
1123   * @brief  Return  URB state for a channel.
1124   * @param  hhcd HCD handle
1125   * @param  chnum Channel number.
1126   *         This parameter can be a value from 1 to 15
1127   * @retval URB state.
1128   *          This parameter can be one of these values:
1129   *            URB_IDLE/
1130   *            URB_DONE/
1131   *            URB_NOTREADY/
1132   *            URB_NYET/
1133   *            URB_ERROR/
1134   *            URB_STALL
1135   */
HAL_HCD_HC_GetURBState(HCD_HandleTypeDef const * hhcd,uint8_t chnum)1136 HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef const *hhcd, uint8_t chnum)
1137 {
1138   return hhcd->hc[chnum].urb_state;
1139 }
1140 
1141 
1142 /**
1143   * @brief  Return the last host transfer size.
1144   * @param  hhcd HCD handle
1145   * @param  chnum Channel number.
1146   *         This parameter can be a value from 1 to 15
1147   * @retval last transfer size in byte
1148   */
HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef const * hhcd,uint8_t chnum)1149 uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef const *hhcd, uint8_t chnum)
1150 {
1151   return hhcd->hc[chnum].xfer_count;
1152 }
1153 
1154 /**
1155   * @brief  Return the Host Channel state.
1156   * @param  hhcd HCD handle
1157   * @param  chnum Channel number.
1158   *         This parameter can be a value from 1 to 15
1159   * @retval Host channel state
1160   *          This parameter can be one of these values:
1161   *            HC_IDLE/
1162   *            HC_XFRC/
1163   *            HC_HALTED/
1164   *            HC_NYET/
1165   *            HC_NAK/
1166   *            HC_STALL/
1167   *            HC_XACTERR/
1168   *            HC_BBLERR/
1169   *            HC_DATATGLERR
1170   */
HAL_HCD_HC_GetState(HCD_HandleTypeDef const * hhcd,uint8_t chnum)1171 HCD_HCStateTypeDef  HAL_HCD_HC_GetState(HCD_HandleTypeDef const *hhcd, uint8_t chnum)
1172 {
1173   return hhcd->hc[chnum].state;
1174 }
1175 
1176 /**
1177   * @brief  Return the current Host frame number.
1178   * @param  hhcd HCD handle
1179   * @retval Current Host frame number
1180   */
HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef * hhcd)1181 uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd)
1182 {
1183   return (USB_GetCurrentFrame(hhcd->Instance));
1184 }
1185 
1186 /**
1187   * @brief  Return the Host enumeration speed.
1188   * @param  hhcd HCD handle
1189   * @retval Enumeration speed
1190   */
HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef * hhcd)1191 uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd)
1192 {
1193   return (USB_GetHostSpeed(hhcd->Instance));
1194 }
1195 
1196 /**
1197   * @brief  Set host channel Hub information.
1198   * @param  hhcd HCD handle
1199   * @param  ch_num Channel number.
1200   *         This parameter can be a value from 1 to 15
1201   * @param  addr Hub address
1202   * @param  PortNbr Hub port number
1203   * @retval HAL status
1204   */
HAL_HCD_HC_SetHubInfo(HCD_HandleTypeDef * hhcd,uint8_t ch_num,uint8_t addr,uint8_t PortNbr)1205 HAL_StatusTypeDef HAL_HCD_HC_SetHubInfo(HCD_HandleTypeDef *hhcd, uint8_t ch_num,
1206                                         uint8_t addr, uint8_t PortNbr)
1207 {
1208   uint32_t HostCoreSpeed = USB_GetHostSpeed(hhcd->Instance);
1209 
1210   /* LS/FS device plugged to HS HUB */
1211   if ((hhcd->hc[ch_num].speed != HCD_DEVICE_SPEED_HIGH) && (HostCoreSpeed == HPRT0_PRTSPD_HIGH_SPEED))
1212   {
1213     hhcd->hc[ch_num].do_ssplit = 1U;
1214 
1215     if ((hhcd->hc[ch_num].ep_type == EP_TYPE_CTRL) && (hhcd->hc[ch_num].ep_is_in != 0U))
1216     {
1217       hhcd->hc[ch_num].toggle_in = 1U;
1218     }
1219   }
1220 
1221   hhcd->hc[ch_num].hub_addr = addr;
1222   hhcd->hc[ch_num].hub_port_nbr = PortNbr;
1223 
1224   return HAL_OK;
1225 }
1226 
1227 
1228 /**
1229   * @brief  Clear host channel hub information.
1230   * @param  hhcd HCD handle
1231   * @param  ch_num Channel number.
1232   *         This parameter can be a value from 1 to 15
1233   * @retval HAL status
1234   */
HAL_HCD_HC_ClearHubInfo(HCD_HandleTypeDef * hhcd,uint8_t ch_num)1235 HAL_StatusTypeDef HAL_HCD_HC_ClearHubInfo(HCD_HandleTypeDef *hhcd, uint8_t ch_num)
1236 {
1237   hhcd->hc[ch_num].do_ssplit = 0U;
1238   hhcd->hc[ch_num].do_csplit = 0U;
1239   hhcd->hc[ch_num].hub_addr = 0U;
1240   hhcd->hc[ch_num].hub_port_nbr = 0U;
1241 
1242   return HAL_OK;
1243 }
1244 /**
1245   * @}
1246   */
1247 
1248 /**
1249   * @}
1250   */
1251 
1252 /** @addtogroup HCD_Private_Functions
1253   * @{
1254   */
1255 /**
1256   * @brief  Handle Host Channel IN interrupt requests.
1257   * @param  hhcd HCD handle
1258   * @param  chnum Channel number.
1259   *         This parameter can be a value from 1 to 15
1260   * @retval none
1261   */
HCD_HC_IN_IRQHandler(HCD_HandleTypeDef * hhcd,uint8_t chnum)1262 static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
1263 {
1264   USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
1265   uint32_t USBx_BASE = (uint32_t)USBx;
1266   uint32_t tmpreg;
1267 
1268   if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_AHBERR))
1269   {
1270     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR);
1271     hhcd->hc[chnum].state = HC_XACTERR;
1272     (void)USB_HC_Halt(hhcd->Instance, chnum);
1273   }
1274   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_BBERR))
1275   {
1276     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_BBERR);
1277     hhcd->hc[chnum].state = HC_BBLERR;
1278     (void)USB_HC_Halt(hhcd->Instance, chnum);
1279   }
1280   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_STALL))
1281   {
1282     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL);
1283     hhcd->hc[chnum].state = HC_STALL;
1284     (void)USB_HC_Halt(hhcd->Instance, chnum);
1285   }
1286   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_DTERR))
1287   {
1288     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR);
1289     hhcd->hc[chnum].state = HC_DATATGLERR;
1290     (void)USB_HC_Halt(hhcd->Instance, chnum);
1291   }
1292   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_TXERR))
1293   {
1294     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR);
1295     hhcd->hc[chnum].state = HC_XACTERR;
1296     (void)USB_HC_Halt(hhcd->Instance, chnum);
1297   }
1298   else
1299   {
1300     /* ... */
1301   }
1302 
1303   if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_FRMOR))
1304   {
1305     (void)USB_HC_Halt(hhcd->Instance, chnum);
1306     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR);
1307   }
1308   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_XFRC))
1309   {
1310     /* Clear any pending ACK IT */
1311     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
1312 
1313     if (hhcd->hc[chnum].do_csplit == 1U)
1314     {
1315       hhcd->hc[chnum].do_csplit = 0U;
1316       __HAL_HCD_CLEAR_HC_CSPLT(chnum);
1317     }
1318 
1319     if (hhcd->Init.dma_enable != 0U)
1320     {
1321       hhcd->hc[chnum].xfer_count = hhcd->hc[chnum].XferSize - (USBx_HC(chnum)->HCTSIZ & USB_OTG_HCTSIZ_XFRSIZ);
1322     }
1323 
1324     hhcd->hc[chnum].state = HC_XFRC;
1325     hhcd->hc[chnum].ErrCnt = 0U;
1326     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC);
1327 
1328     if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) ||
1329         (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
1330     {
1331       (void)USB_HC_Halt(hhcd->Instance, chnum);
1332       __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
1333     }
1334     else if ((hhcd->hc[chnum].ep_type == EP_TYPE_INTR) ||
1335              (hhcd->hc[chnum].ep_type == EP_TYPE_ISOC))
1336     {
1337       USBx_HC(chnum)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
1338       hhcd->hc[chnum].urb_state = URB_DONE;
1339 
1340 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1341       hhcd->HC_NotifyURBChangeCallback(hhcd, chnum, hhcd->hc[chnum].urb_state);
1342 #else
1343       HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
1344 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1345     }
1346     else
1347     {
1348       /* ... */
1349     }
1350 
1351     if (hhcd->Init.dma_enable == 1U)
1352     {
1353       if ((((hhcd->hc[chnum].xfer_count + hhcd->hc[chnum].max_packet - 1U) / hhcd->hc[chnum].max_packet) & 1U) != 0U)
1354       {
1355         hhcd->hc[chnum].toggle_in ^= 1U;
1356       }
1357     }
1358     else
1359     {
1360       hhcd->hc[chnum].toggle_in ^= 1U;
1361     }
1362   }
1363   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_ACK))
1364   {
1365     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
1366 
1367     if (hhcd->hc[chnum].do_ssplit == 1U)
1368     {
1369       hhcd->hc[chnum].do_csplit = 1U;
1370       hhcd->hc[chnum].state = HC_ACK;
1371 
1372       (void)USB_HC_Halt(hhcd->Instance, chnum);
1373     }
1374   }
1375   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_CHH))
1376   {
1377     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
1378 
1379     if (hhcd->hc[chnum].state == HC_XFRC)
1380     {
1381       hhcd->hc[chnum].state = HC_HALTED;
1382       hhcd->hc[chnum].urb_state = URB_DONE;
1383     }
1384     else if (hhcd->hc[chnum].state == HC_STALL)
1385     {
1386       hhcd->hc[chnum].state = HC_HALTED;
1387       hhcd->hc[chnum].urb_state = URB_STALL;
1388     }
1389     else if ((hhcd->hc[chnum].state == HC_XACTERR) ||
1390              (hhcd->hc[chnum].state == HC_DATATGLERR))
1391     {
1392       hhcd->hc[chnum].state = HC_HALTED;
1393       hhcd->hc[chnum].ErrCnt++;
1394       if (hhcd->hc[chnum].ErrCnt > 2U)
1395       {
1396         hhcd->hc[chnum].ErrCnt = 0U;
1397 
1398         if (hhcd->hc[chnum].do_ssplit == 1U)
1399         {
1400           hhcd->hc[chnum].do_csplit = 0U;
1401           hhcd->hc[chnum].ep_ss_schedule = 0U;
1402           __HAL_HCD_CLEAR_HC_CSPLT(chnum);
1403         }
1404 
1405         hhcd->hc[chnum].urb_state = URB_ERROR;
1406       }
1407       else
1408       {
1409         hhcd->hc[chnum].urb_state = URB_NOTREADY;
1410 
1411         if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) ||
1412             (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
1413         {
1414           /* re-activate the channel */
1415           tmpreg = USBx_HC(chnum)->HCCHAR;
1416           tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1417           tmpreg |= USB_OTG_HCCHAR_CHENA;
1418           USBx_HC(chnum)->HCCHAR = tmpreg;
1419         }
1420       }
1421     }
1422     else if (hhcd->hc[chnum].state == HC_NYET)
1423     {
1424       hhcd->hc[chnum].state = HC_HALTED;
1425 
1426       if (hhcd->hc[chnum].do_csplit == 1U)
1427       {
1428         if (hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
1429         {
1430           hhcd->hc[chnum].NyetErrCnt++;
1431           if (hhcd->hc[chnum].NyetErrCnt > 2U)
1432           {
1433             hhcd->hc[chnum].NyetErrCnt = 0U;
1434             hhcd->hc[chnum].do_csplit = 0U;
1435 
1436             if (hhcd->hc[chnum].ErrCnt < 3U)
1437             {
1438               hhcd->hc[chnum].ep_ss_schedule = 1U;
1439             }
1440             __HAL_HCD_CLEAR_HC_CSPLT(chnum);
1441             hhcd->hc[chnum].urb_state = URB_ERROR;
1442           }
1443           else
1444           {
1445             hhcd->hc[chnum].urb_state = URB_NOTREADY;
1446           }
1447         }
1448         else
1449         {
1450           hhcd->hc[chnum].urb_state = URB_NOTREADY;
1451         }
1452 
1453         if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) ||
1454             (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
1455         {
1456           /* re-activate the channel */
1457           tmpreg = USBx_HC(chnum)->HCCHAR;
1458           tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1459           tmpreg |= USB_OTG_HCCHAR_CHENA;
1460           USBx_HC(chnum)->HCCHAR = tmpreg;
1461         }
1462       }
1463     }
1464     else if (hhcd->hc[chnum].state == HC_ACK)
1465     {
1466       hhcd->hc[chnum].state = HC_HALTED;
1467 
1468       if (hhcd->hc[chnum].do_csplit == 1U)
1469       {
1470         hhcd->hc[chnum].urb_state = URB_NOTREADY;
1471 
1472         /* Set Complete split and re-activate the channel */
1473         USBx_HC(chnum)->HCSPLT |= USB_OTG_HCSPLT_COMPLSPLT;
1474         USBx_HC(chnum)->HCINTMSK |= USB_OTG_HCINTMSK_NYET;
1475         USBx_HC(chnum)->HCINTMSK &= ~USB_OTG_HCINT_ACK;
1476 
1477         if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) ||
1478             (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
1479         {
1480           /* re-activate the channel */
1481           tmpreg = USBx_HC(chnum)->HCCHAR;
1482           tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1483           tmpreg |= USB_OTG_HCCHAR_CHENA;
1484           USBx_HC(chnum)->HCCHAR = tmpreg;
1485         }
1486       }
1487     }
1488     else if (hhcd->hc[chnum].state == HC_NAK)
1489     {
1490       hhcd->hc[chnum].state = HC_HALTED;
1491       hhcd->hc[chnum].urb_state = URB_NOTREADY;
1492 
1493       if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) ||
1494           (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
1495       {
1496         /* re-activate the channel */
1497         tmpreg = USBx_HC(chnum)->HCCHAR;
1498         tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1499         tmpreg |= USB_OTG_HCCHAR_CHENA;
1500         USBx_HC(chnum)->HCCHAR = tmpreg;
1501       }
1502     }
1503     else if (hhcd->hc[chnum].state == HC_BBLERR)
1504     {
1505       hhcd->hc[chnum].state = HC_HALTED;
1506       hhcd->hc[chnum].ErrCnt++;
1507       hhcd->hc[chnum].urb_state = URB_ERROR;
1508     }
1509     else
1510     {
1511       if (hhcd->hc[chnum].state == HC_HALTED)
1512       {
1513         return;
1514       }
1515     }
1516 
1517 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1518     hhcd->HC_NotifyURBChangeCallback(hhcd, chnum, hhcd->hc[chnum].urb_state);
1519 #else
1520     HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
1521 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1522   }
1523   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_NYET))
1524   {
1525     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NYET);
1526     hhcd->hc[chnum].state = HC_NYET;
1527 
1528     if (hhcd->hc[chnum].do_ssplit == 0U)
1529     {
1530       hhcd->hc[chnum].ErrCnt = 0U;
1531     }
1532 
1533     (void)USB_HC_Halt(hhcd->Instance, chnum);
1534   }
1535   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_NAK))
1536   {
1537     if (hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
1538     {
1539       hhcd->hc[chnum].ErrCnt = 0U;
1540       hhcd->hc[chnum].state = HC_NAK;
1541       (void)USB_HC_Halt(hhcd->Instance, chnum);
1542     }
1543     else if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL) ||
1544              (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
1545     {
1546       hhcd->hc[chnum].ErrCnt = 0U;
1547 
1548       if ((hhcd->Init.dma_enable == 0U) || (hhcd->hc[chnum].do_csplit == 1U))
1549       {
1550         hhcd->hc[chnum].state = HC_NAK;
1551         (void)USB_HC_Halt(hhcd->Instance, chnum);
1552       }
1553     }
1554     else
1555     {
1556       /* ... */
1557     }
1558 
1559     if (hhcd->hc[chnum].do_csplit == 1U)
1560     {
1561       hhcd->hc[chnum].do_csplit = 0U;
1562       __HAL_HCD_CLEAR_HC_CSPLT(chnum);
1563       __HAL_HCD_UNMASK_ACK_HC_INT(chnum);
1564     }
1565 
1566     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
1567   }
1568   else
1569   {
1570     /* ... */
1571   }
1572 }
1573 
1574 /**
1575   * @brief  Handle Host Channel OUT interrupt requests.
1576   * @param  hhcd HCD handle
1577   * @param  chnum Channel number.
1578   *         This parameter can be a value from 1 to 15
1579   * @retval none
1580   */
HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef * hhcd,uint8_t chnum)1581 static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
1582 {
1583   USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
1584   uint32_t USBx_BASE = (uint32_t)USBx;
1585   uint32_t tmpreg;
1586   uint32_t num_packets;
1587 
1588   if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_AHBERR))
1589   {
1590     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR);
1591     hhcd->hc[chnum].state = HC_XACTERR;
1592     (void)USB_HC_Halt(hhcd->Instance, chnum);
1593   }
1594   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_ACK))
1595   {
1596     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
1597 
1598     if (hhcd->hc[chnum].do_ping == 1U)
1599     {
1600       hhcd->hc[chnum].do_ping = 0U;
1601       hhcd->hc[chnum].urb_state = URB_NOTREADY;
1602       hhcd->hc[chnum].state = HC_ACK;
1603       (void)USB_HC_Halt(hhcd->Instance, chnum);
1604     }
1605 
1606     if ((hhcd->hc[chnum].do_ssplit == 1U) && (hhcd->hc[chnum].do_csplit == 0U))
1607     {
1608       if (hhcd->hc[chnum].ep_type != EP_TYPE_ISOC)
1609       {
1610         hhcd->hc[chnum].do_csplit = 1U;
1611       }
1612 
1613       hhcd->hc[chnum].state = HC_ACK;
1614       (void)USB_HC_Halt(hhcd->Instance, chnum);
1615 
1616       /* reset error_count */
1617       hhcd->hc[chnum].ErrCnt = 0U;
1618     }
1619   }
1620   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_FRMOR))
1621   {
1622     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR);
1623     (void)USB_HC_Halt(hhcd->Instance, chnum);
1624   }
1625   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_XFRC))
1626   {
1627     hhcd->hc[chnum].ErrCnt = 0U;
1628 
1629     /* transaction completed with NYET state, update do ping state */
1630     if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_NYET))
1631     {
1632       hhcd->hc[chnum].do_ping = 1U;
1633       __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NYET);
1634     }
1635 
1636     if (hhcd->hc[chnum].do_csplit != 0U)
1637     {
1638       hhcd->hc[chnum].do_csplit = 0U;
1639       __HAL_HCD_CLEAR_HC_CSPLT(chnum);
1640     }
1641 
1642     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC);
1643     hhcd->hc[chnum].state = HC_XFRC;
1644     (void)USB_HC_Halt(hhcd->Instance, chnum);
1645   }
1646   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_NYET))
1647   {
1648     hhcd->hc[chnum].state = HC_NYET;
1649 
1650     if (hhcd->hc[chnum].do_ssplit == 0U)
1651     {
1652       hhcd->hc[chnum].do_ping = 1U;
1653     }
1654 
1655     hhcd->hc[chnum].ErrCnt = 0U;
1656     (void)USB_HC_Halt(hhcd->Instance, chnum);
1657     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NYET);
1658   }
1659   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_STALL))
1660   {
1661     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL);
1662     hhcd->hc[chnum].state = HC_STALL;
1663     (void)USB_HC_Halt(hhcd->Instance, chnum);
1664   }
1665   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_NAK))
1666   {
1667     hhcd->hc[chnum].ErrCnt = 0U;
1668     hhcd->hc[chnum].state = HC_NAK;
1669 
1670     if (hhcd->hc[chnum].do_ping == 0U)
1671     {
1672       if (hhcd->hc[chnum].speed == HCD_DEVICE_SPEED_HIGH)
1673       {
1674         hhcd->hc[chnum].do_ping = 1U;
1675       }
1676     }
1677 
1678     (void)USB_HC_Halt(hhcd->Instance, chnum);
1679     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
1680   }
1681   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_TXERR))
1682   {
1683     if (hhcd->Init.dma_enable == 0U)
1684     {
1685       hhcd->hc[chnum].state = HC_XACTERR;
1686       (void)USB_HC_Halt(hhcd->Instance, chnum);
1687     }
1688     else
1689     {
1690       hhcd->hc[chnum].ErrCnt++;
1691       if (hhcd->hc[chnum].ErrCnt > 2U)
1692       {
1693         hhcd->hc[chnum].ErrCnt = 0U;
1694         hhcd->hc[chnum].urb_state = URB_ERROR;
1695 
1696 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1697         hhcd->HC_NotifyURBChangeCallback(hhcd, chnum, hhcd->hc[chnum].urb_state);
1698 #else
1699         HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
1700 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1701       }
1702       else
1703       {
1704         hhcd->hc[chnum].urb_state = URB_NOTREADY;
1705       }
1706     }
1707     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR);
1708   }
1709   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_DTERR))
1710   {
1711     hhcd->hc[chnum].state = HC_DATATGLERR;
1712     (void)USB_HC_Halt(hhcd->Instance, chnum);
1713     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR);
1714   }
1715   else if (__HAL_HCD_GET_CH_FLAG(hhcd, chnum, USB_OTG_HCINT_CHH))
1716   {
1717     __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
1718 
1719     if (hhcd->hc[chnum].state == HC_XFRC)
1720     {
1721       hhcd->hc[chnum].state = HC_HALTED;
1722       hhcd->hc[chnum].urb_state = URB_DONE;
1723 
1724       if ((hhcd->hc[chnum].ep_type == EP_TYPE_BULK) ||
1725           (hhcd->hc[chnum].ep_type == EP_TYPE_INTR))
1726       {
1727         if (hhcd->Init.dma_enable == 0U)
1728         {
1729           hhcd->hc[chnum].toggle_out ^= 1U;
1730         }
1731 
1732         if ((hhcd->Init.dma_enable == 1U) && (hhcd->hc[chnum].xfer_len > 0U))
1733         {
1734           num_packets = (hhcd->hc[chnum].xfer_len + hhcd->hc[chnum].max_packet - 1U) / hhcd->hc[chnum].max_packet;
1735 
1736           if ((num_packets & 1U) != 0U)
1737           {
1738             hhcd->hc[chnum].toggle_out ^= 1U;
1739           }
1740         }
1741       }
1742     }
1743     else if (hhcd->hc[chnum].state == HC_ACK)
1744     {
1745       hhcd->hc[chnum].state = HC_HALTED;
1746 
1747       if (hhcd->hc[chnum].do_csplit == 1U)
1748       {
1749         hhcd->hc[chnum].urb_state = URB_NOTREADY;
1750       }
1751     }
1752     else if (hhcd->hc[chnum].state == HC_NAK)
1753     {
1754       hhcd->hc[chnum].state = HC_HALTED;
1755       hhcd->hc[chnum].urb_state = URB_NOTREADY;
1756 
1757       if (hhcd->hc[chnum].do_csplit == 1U)
1758       {
1759         hhcd->hc[chnum].do_csplit = 0U;
1760         __HAL_HCD_CLEAR_HC_CSPLT(chnum);
1761       }
1762     }
1763     else if (hhcd->hc[chnum].state == HC_NYET)
1764     {
1765       hhcd->hc[chnum].state = HC_HALTED;
1766       hhcd->hc[chnum].urb_state  = URB_NOTREADY;
1767     }
1768     else if (hhcd->hc[chnum].state == HC_STALL)
1769     {
1770       hhcd->hc[chnum].state = HC_HALTED;
1771       hhcd->hc[chnum].urb_state  = URB_STALL;
1772     }
1773     else if ((hhcd->hc[chnum].state == HC_XACTERR) ||
1774              (hhcd->hc[chnum].state == HC_DATATGLERR))
1775     {
1776       hhcd->hc[chnum].state = HC_HALTED;
1777       hhcd->hc[chnum].ErrCnt++;
1778       if (hhcd->hc[chnum].ErrCnt > 2U)
1779       {
1780         hhcd->hc[chnum].ErrCnt = 0U;
1781         hhcd->hc[chnum].urb_state = URB_ERROR;
1782       }
1783       else
1784       {
1785         hhcd->hc[chnum].urb_state = URB_NOTREADY;
1786 
1787         /* re-activate the channel  */
1788         tmpreg = USBx_HC(chnum)->HCCHAR;
1789         tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1790         tmpreg |= USB_OTG_HCCHAR_CHENA;
1791         USBx_HC(chnum)->HCCHAR = tmpreg;
1792       }
1793     }
1794     else
1795     {
1796       return;
1797     }
1798 
1799 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1800     hhcd->HC_NotifyURBChangeCallback(hhcd, chnum, hhcd->hc[chnum].urb_state);
1801 #else
1802     HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
1803 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1804   }
1805   else
1806   {
1807     return;
1808   }
1809 }
1810 
1811 /**
1812   * @brief  Handle Rx Queue Level interrupt requests.
1813   * @param  hhcd HCD handle
1814   * @retval none
1815   */
HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef * hhcd)1816 static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd)
1817 {
1818   USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
1819   uint32_t USBx_BASE = (uint32_t)USBx;
1820   uint32_t pktsts;
1821   uint32_t pktcnt;
1822   uint32_t GrxstspReg;
1823   uint32_t xferSizePktCnt;
1824   uint32_t tmpreg;
1825   uint32_t chnum;
1826 
1827   GrxstspReg = hhcd->Instance->GRXSTSP;
1828   chnum = GrxstspReg & USB_OTG_GRXSTSP_EPNUM;
1829   pktsts = (GrxstspReg & USB_OTG_GRXSTSP_PKTSTS) >> 17;
1830   pktcnt = (GrxstspReg & USB_OTG_GRXSTSP_BCNT) >> 4;
1831 
1832   switch (pktsts)
1833   {
1834     case GRXSTS_PKTSTS_IN:
1835       /* Read the data into the host buffer. */
1836       if ((pktcnt > 0U) && (hhcd->hc[chnum].xfer_buff != (void *)0))
1837       {
1838         if ((hhcd->hc[chnum].xfer_count + pktcnt) <= hhcd->hc[chnum].xfer_len)
1839         {
1840           (void)USB_ReadPacket(hhcd->Instance,
1841                                hhcd->hc[chnum].xfer_buff, (uint16_t)pktcnt);
1842 
1843           /* manage multiple Xfer */
1844           hhcd->hc[chnum].xfer_buff += pktcnt;
1845           hhcd->hc[chnum].xfer_count += pktcnt;
1846 
1847           /* get transfer size packet count */
1848           xferSizePktCnt = (USBx_HC(chnum)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) >> 19;
1849 
1850           if ((hhcd->hc[chnum].max_packet == pktcnt) && (xferSizePktCnt > 0U))
1851           {
1852             /* re-activate the channel when more packets are expected */
1853             tmpreg = USBx_HC(chnum)->HCCHAR;
1854             tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1855             tmpreg |= USB_OTG_HCCHAR_CHENA;
1856             USBx_HC(chnum)->HCCHAR = tmpreg;
1857             hhcd->hc[chnum].toggle_in ^= 1U;
1858           }
1859         }
1860         else
1861         {
1862           hhcd->hc[chnum].urb_state = URB_ERROR;
1863         }
1864       }
1865       break;
1866 
1867     case GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
1868       break;
1869 
1870     case GRXSTS_PKTSTS_IN_XFER_COMP:
1871     case GRXSTS_PKTSTS_CH_HALTED:
1872     default:
1873       break;
1874   }
1875 }
1876 
1877 /**
1878   * @brief  Handle Host Port interrupt requests.
1879   * @param  hhcd HCD handle
1880   * @retval None
1881   */
HCD_Port_IRQHandler(HCD_HandleTypeDef * hhcd)1882 static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd)
1883 {
1884   USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
1885   uint32_t USBx_BASE = (uint32_t)USBx;
1886   __IO uint32_t hprt0;
1887   __IO uint32_t hprt0_dup;
1888 
1889   /* Handle Host Port Interrupts */
1890   hprt0 = USBx_HPRT0;
1891   hprt0_dup = USBx_HPRT0;
1892 
1893   hprt0_dup &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET | \
1894                  USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
1895 
1896   /* Check whether Port Connect detected */
1897   if ((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET)
1898   {
1899     if ((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS)
1900     {
1901 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1902       hhcd->ConnectCallback(hhcd);
1903 #else
1904       HAL_HCD_Connect_Callback(hhcd);
1905 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1906     }
1907     hprt0_dup |= USB_OTG_HPRT_PCDET;
1908   }
1909 
1910   /* Check whether Port Enable Changed */
1911   if ((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG)
1912   {
1913     hprt0_dup |= USB_OTG_HPRT_PENCHNG;
1914 
1915     if ((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA)
1916     {
1917       if (hhcd->Init.phy_itface == USB_OTG_EMBEDDED_PHY)
1918       {
1919         if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17))
1920         {
1921           (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_6_MHZ);
1922         }
1923         else
1924         {
1925           (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_48_MHZ);
1926         }
1927       }
1928       else
1929       {
1930         if (hhcd->Init.speed == HCD_SPEED_FULL)
1931         {
1932           USBx_HOST->HFIR = HFIR_60_MHZ;
1933         }
1934       }
1935 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1936       hhcd->PortEnabledCallback(hhcd);
1937 #else
1938       HAL_HCD_PortEnabled_Callback(hhcd);
1939 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1940 
1941     }
1942     else
1943     {
1944 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1945       hhcd->PortDisabledCallback(hhcd);
1946 #else
1947       HAL_HCD_PortDisabled_Callback(hhcd);
1948 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1949     }
1950   }
1951 
1952   /* Check for an overcurrent */
1953   if ((hprt0 & USB_OTG_HPRT_POCCHNG) == USB_OTG_HPRT_POCCHNG)
1954   {
1955     hprt0_dup |= USB_OTG_HPRT_POCCHNG;
1956   }
1957 
1958   /* Clear Port Interrupts */
1959   USBx_HPRT0 = hprt0_dup;
1960 }
1961 
1962 /**
1963   * @}
1964   */
1965 
1966 /**
1967   * @}
1968   */
1969 
1970 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
1971 #endif /* HAL_HCD_MODULE_ENABLED */
1972 
1973 /**
1974   * @}
1975   */
1976 
1977 /**
1978   * @}
1979   */
1980