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