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