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