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