Create release.yml
[betaflight.git] / lib / main / STM32H7 / Drivers / STM32H7xx_HAL_Driver / Src / stm32h7xx_hal_hcd.c
blob45d8061f5b7d4a335e27c194e9ddefb58960a072
1 /**
2 ******************************************************************************
3 * @file stm32h7xx_hal_hcd.c
4 * @author MCD Application Team
5 * @brief HCD HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the USB Peripheral Controller:
8 * + Initialization and de-initialization functions
9 * + IO operation functions
10 * + Peripheral Control functions
11 * + Peripheral State functions
13 @verbatim
14 ==============================================================================
15 ##### How to use this driver #####
16 ==============================================================================
17 [..]
18 (#)Declare a HCD_HandleTypeDef handle structure, for example:
19 HCD_HandleTypeDef hhcd;
21 (#)Fill parameters of Init structure in HCD handle
23 (#)Call HAL_HCD_Init() API to initialize the HCD peripheral (Core, Host core, ...)
25 (#)Initialize the HCD low level resources through the HAL_HCD_MspInit() API:
26 (##) Enable the HCD/USB Low Level interface clock using the following macros
27 (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
28 (+++) __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); (For High Speed Mode)
29 (+++) __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE(); (For High Speed Mode)
31 (##) Initialize the related GPIO clocks
32 (##) Configure HCD pin-out
33 (##) Configure HCD NVIC interrupt
35 (#)Associate the Upper USB Host stack to the HAL HCD Driver:
36 (##) hhcd.pData = phost;
38 (#)Enable HCD transmission and reception:
39 (##) HAL_HCD_Start();
41 @endverbatim
42 ******************************************************************************
43 * @attention
45 * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
46 * All rights reserved.</center></h2>
48 * This software component is licensed by ST under BSD 3-Clause license,
49 * the "License"; You may not use this file except in compliance with the
50 * License. You may obtain a copy of the License at:
51 * opensource.org/licenses/BSD-3-Clause
53 ******************************************************************************
56 /* Includes ------------------------------------------------------------------*/
57 #include "stm32h7xx_hal.h"
59 /** @addtogroup STM32H7xx_HAL_Driver
60 * @{
63 #ifdef HAL_HCD_MODULE_ENABLED
65 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
67 /** @defgroup HCD HCD
68 * @brief HCD HAL module driver
69 * @{
72 /* Private typedef -----------------------------------------------------------*/
73 /* Private define ------------------------------------------------------------*/
74 /* Private macro -------------------------------------------------------------*/
75 /* Private variables ---------------------------------------------------------*/
76 /* Private function prototypes -----------------------------------------------*/
77 /** @defgroup HCD_Private_Functions HCD Private Functions
78 * @{
80 static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
81 static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
82 static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd);
83 static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd);
84 /**
85 * @}
88 /* Exported functions --------------------------------------------------------*/
89 /** @defgroup HCD_Exported_Functions HCD Exported Functions
90 * @{
93 /** @defgroup HCD_Exported_Functions_Group1 Initialization and de-initialization functions
94 * @brief Initialization and Configuration functions
96 @verbatim
97 ===============================================================================
98 ##### Initialization and de-initialization functions #####
99 ===============================================================================
100 [..] This section provides functions allowing to:
102 @endverbatim
103 * @{
107 * @brief Initialize the host driver.
108 * @param hhcd HCD handle
109 * @retval HAL status
111 HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd)
113 USB_OTG_GlobalTypeDef *USBx;
115 /* Check the HCD handle allocation */
116 if (hhcd == NULL)
118 return HAL_ERROR;
121 /* Check the parameters */
122 assert_param(IS_HCD_ALL_INSTANCE(hhcd->Instance));
124 USBx = hhcd->Instance;
126 if (hhcd->State == HAL_HCD_STATE_RESET)
128 /* Allocate lock resource and initialize it */
129 hhcd->Lock = HAL_UNLOCKED;
131 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
132 hhcd->SOFCallback = HAL_HCD_SOF_Callback;
133 hhcd->ConnectCallback = HAL_HCD_Connect_Callback;
134 hhcd->DisconnectCallback = HAL_HCD_Disconnect_Callback;
135 hhcd->PortEnabledCallback = HAL_HCD_PortEnabled_Callback;
136 hhcd->PortDisabledCallback = HAL_HCD_PortDisabled_Callback;
137 hhcd->HC_NotifyURBChangeCallback = HAL_HCD_HC_NotifyURBChange_Callback;
139 if (hhcd->MspInitCallback == NULL)
141 hhcd->MspInitCallback = HAL_HCD_MspInit;
144 /* Init the low level hardware */
145 hhcd->MspInitCallback(hhcd);
146 #else
147 /* Init the low level hardware : GPIO, CLOCK, NVIC... */
148 HAL_HCD_MspInit(hhcd);
149 #endif /* (USE_HAL_HCD_REGISTER_CALLBACKS) */
152 hhcd->State = HAL_HCD_STATE_BUSY;
154 /* Disable DMA mode for FS instance */
155 if ((USBx->CID & (0x1U << 8)) == 0U)
157 hhcd->Init.dma_enable = 0U;
160 /* Disable the Interrupts */
161 __HAL_HCD_DISABLE(hhcd);
163 /* Init the Core (common init.) */
164 (void)USB_CoreInit(hhcd->Instance, hhcd->Init);
166 /* Force Host Mode*/
167 (void)USB_SetCurrentMode(hhcd->Instance, USB_HOST_MODE);
169 /* Init Host */
170 (void)USB_HostInit(hhcd->Instance, hhcd->Init);
172 hhcd->State = HAL_HCD_STATE_READY;
174 return HAL_OK;
178 * @brief Initialize a host channel.
179 * @param hhcd HCD handle
180 * @param ch_num Channel number.
181 * This parameter can be a value from 1 to 15
182 * @param epnum Endpoint number.
183 * This parameter can be a value from 1 to 15
184 * @param dev_address Current device address
185 * This parameter can be a value from 0 to 255
186 * @param speed Current device speed.
187 * This parameter can be one of these values:
188 * HCD_SPEED_HIGH: High speed mode,
189 * HCD_SPEED_FULL: Full speed mode,
190 * HCD_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
201 HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd,
202 uint8_t ch_num,
203 uint8_t epnum,
204 uint8_t dev_address,
205 uint8_t speed,
206 uint8_t ep_type,
207 uint16_t mps)
209 HAL_StatusTypeDef status;
211 __HAL_LOCK(hhcd);
212 hhcd->hc[ch_num].do_ping = 0U;
213 hhcd->hc[ch_num].dev_addr = dev_address;
214 hhcd->hc[ch_num].max_packet = mps;
215 hhcd->hc[ch_num].ch_num = ch_num;
216 hhcd->hc[ch_num].ep_type = ep_type;
217 hhcd->hc[ch_num].ep_num = epnum & 0x7FU;
219 if ((epnum & 0x80U) == 0x80U)
221 hhcd->hc[ch_num].ep_is_in = 1U;
223 else
225 hhcd->hc[ch_num].ep_is_in = 0U;
228 hhcd->hc[ch_num].speed = speed;
230 status = USB_HC_Init(hhcd->Instance,
231 ch_num,
232 epnum,
233 dev_address,
234 speed,
235 ep_type,
236 mps);
237 __HAL_UNLOCK(hhcd);
239 return status;
243 * @brief Halt a host channel.
244 * @param hhcd HCD handle
245 * @param ch_num Channel number.
246 * This parameter can be a value from 1 to 15
247 * @retval HAL status
249 HAL_StatusTypeDef HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd, uint8_t ch_num)
251 HAL_StatusTypeDef status = HAL_OK;
253 __HAL_LOCK(hhcd);
254 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
255 __HAL_UNLOCK(hhcd);
257 return status;
261 * @brief DeInitialize the host driver.
262 * @param hhcd HCD handle
263 * @retval HAL status
265 HAL_StatusTypeDef HAL_HCD_DeInit(HCD_HandleTypeDef *hhcd)
267 /* Check the HCD handle allocation */
268 if (hhcd == NULL)
270 return HAL_ERROR;
273 hhcd->State = HAL_HCD_STATE_BUSY;
275 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
276 if (hhcd->MspDeInitCallback == NULL)
278 hhcd->MspDeInitCallback = HAL_HCD_MspDeInit; /* Legacy weak MspDeInit */
281 /* DeInit the low level hardware */
282 hhcd->MspDeInitCallback(hhcd);
283 #else
284 /* DeInit the low level hardware: CLOCK, NVIC.*/
285 HAL_HCD_MspDeInit(hhcd);
286 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
288 __HAL_HCD_DISABLE(hhcd);
290 hhcd->State = HAL_HCD_STATE_RESET;
292 return HAL_OK;
296 * @brief Initialize the HCD MSP.
297 * @param hhcd HCD handle
298 * @retval None
300 __weak void HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd)
302 /* Prevent unused argument(s) compilation warning */
303 UNUSED(hhcd);
305 /* NOTE : This function should not be modified, when the callback is needed,
306 the HAL_HCD_MspInit could be implemented in the user file
311 * @brief DeInitialize the HCD MSP.
312 * @param hhcd HCD handle
313 * @retval None
315 __weak void HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd)
317 /* Prevent unused argument(s) compilation warning */
318 UNUSED(hhcd);
320 /* NOTE : This function should not be modified, when the callback is needed,
321 the HAL_HCD_MspDeInit could be implemented in the user file
326 * @}
329 /** @defgroup HCD_Exported_Functions_Group2 Input and Output operation functions
330 * @brief HCD IO operation functions
332 @verbatim
333 ===============================================================================
334 ##### IO operation functions #####
335 ===============================================================================
336 [..] This subsection provides a set of functions allowing to manage the USB Host Data
337 Transfer
339 @endverbatim
340 * @{
344 * @brief Submit a new URB for processing.
345 * @param hhcd HCD handle
346 * @param ch_num Channel number.
347 * This parameter can be a value from 1 to 15
348 * @param direction Channel number.
349 * This parameter can be one of these values:
350 * 0 : Output / 1 : Input
351 * @param ep_type Endpoint Type.
352 * This parameter can be one of these values:
353 * EP_TYPE_CTRL: Control type/
354 * EP_TYPE_ISOC: Isochronous type/
355 * EP_TYPE_BULK: Bulk type/
356 * EP_TYPE_INTR: Interrupt type/
357 * @param token Endpoint Type.
358 * This parameter can be one of these values:
359 * 0: HC_PID_SETUP / 1: HC_PID_DATA1
360 * @param pbuff pointer to URB data
361 * @param length Length of URB data
362 * @param do_ping activate do ping protocol (for high speed only).
363 * This parameter can be one of these values:
364 * 0 : do ping inactive / 1 : do ping active
365 * @retval HAL status
367 HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd,
368 uint8_t ch_num,
369 uint8_t direction,
370 uint8_t ep_type,
371 uint8_t token,
372 uint8_t *pbuff,
373 uint16_t length,
374 uint8_t do_ping)
376 hhcd->hc[ch_num].ep_is_in = direction;
377 hhcd->hc[ch_num].ep_type = ep_type;
379 if (token == 0U)
381 hhcd->hc[ch_num].data_pid = HC_PID_SETUP;
382 hhcd->hc[ch_num].do_ping = do_ping;
384 else
386 hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
389 /* Manage Data Toggle */
390 switch (ep_type)
392 case EP_TYPE_CTRL:
393 if ((token == 1U) && (direction == 0U)) /*send data */
395 if (length == 0U)
397 /* For Status OUT stage, Length==0, Status Out PID = 1 */
398 hhcd->hc[ch_num].toggle_out = 1U;
401 /* Set the Data Toggle bit as per the Flag */
402 if (hhcd->hc[ch_num].toggle_out == 0U)
404 /* Put the PID 0 */
405 hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
407 else
409 /* Put the PID 1 */
410 hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
413 break;
415 case EP_TYPE_BULK:
416 if (direction == 0U)
418 /* Set the Data Toggle bit as per the Flag */
419 if (hhcd->hc[ch_num].toggle_out == 0U)
421 /* Put the PID 0 */
422 hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
424 else
426 /* Put the PID 1 */
427 hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
430 else
432 if (hhcd->hc[ch_num].toggle_in == 0U)
434 hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
436 else
438 hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
442 break;
443 case EP_TYPE_INTR:
444 if (direction == 0U)
446 /* Set the Data Toggle bit as per the Flag */
447 if (hhcd->hc[ch_num].toggle_out == 0U)
449 /* Put the PID 0 */
450 hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
452 else
454 /* Put the PID 1 */
455 hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
458 else
460 if (hhcd->hc[ch_num].toggle_in == 0U)
462 hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
464 else
466 hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
469 break;
471 case EP_TYPE_ISOC:
472 hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
473 break;
475 default:
476 break;
479 hhcd->hc[ch_num].xfer_buff = pbuff;
480 hhcd->hc[ch_num].xfer_len = length;
481 hhcd->hc[ch_num].urb_state = URB_IDLE;
482 hhcd->hc[ch_num].xfer_count = 0U;
483 hhcd->hc[ch_num].ch_num = ch_num;
484 hhcd->hc[ch_num].state = HC_IDLE;
486 return USB_HC_StartXfer(hhcd->Instance, &hhcd->hc[ch_num], (uint8_t)hhcd->Init.dma_enable);
490 * @brief Handle HCD interrupt request.
491 * @param hhcd HCD handle
492 * @retval None
494 void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd)
496 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
497 uint32_t USBx_BASE = (uint32_t)USBx;
498 uint32_t i, interrupt;
500 /* Ensure that we are in device mode */
501 if (USB_GetMode(hhcd->Instance) == USB_OTG_MODE_HOST)
503 /* Avoid spurious interrupt */
504 if (__HAL_HCD_IS_INVALID_INTERRUPT(hhcd))
506 return;
509 if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
511 /* Incorrect mode, acknowledge the interrupt */
512 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
515 if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR))
517 /* Incorrect mode, acknowledge the interrupt */
518 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR);
521 if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE))
523 /* Incorrect mode, acknowledge the interrupt */
524 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE);
527 if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_MMIS))
529 /* Incorrect mode, acknowledge the interrupt */
530 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_MMIS);
533 /* Handle Host Disconnect Interrupts */
534 if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT))
536 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT);
538 if ((USBx_HPRT0 & USB_OTG_HPRT_PCSTS) == 0U)
540 /* Handle Host Port Disconnect Interrupt */
541 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
542 hhcd->DisconnectCallback(hhcd);
543 #else
544 HAL_HCD_Disconnect_Callback(hhcd);
545 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
547 (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_48_MHZ);
551 /* Handle Host Port Interrupts */
552 if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HPRTINT))
554 HCD_Port_IRQHandler(hhcd);
557 /* Handle Host SOF Interrupt */
558 if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_SOF))
560 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
561 hhcd->SOFCallback(hhcd);
562 #else
563 HAL_HCD_SOF_Callback(hhcd);
564 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
566 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_SOF);
569 /* Handle Host channel Interrupt */
570 if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HCINT))
572 interrupt = USB_HC_ReadInterrupt(hhcd->Instance);
573 for (i = 0U; i < hhcd->Init.Host_channels; i++)
575 if ((interrupt & (1UL << (i & 0xFU))) != 0U)
577 if ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_EPDIR) == USB_OTG_HCCHAR_EPDIR)
579 HCD_HC_IN_IRQHandler(hhcd, (uint8_t)i);
581 else
583 HCD_HC_OUT_IRQHandler(hhcd, (uint8_t)i);
587 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_HCINT);
590 /* Handle Rx Queue Level Interrupts */
591 if ((__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_RXFLVL)) != 0U)
593 USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
595 HCD_RXQLVL_IRQHandler(hhcd);
597 USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
603 * @brief SOF callback.
604 * @param hhcd HCD handle
605 * @retval None
607 __weak void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd)
609 /* Prevent unused argument(s) compilation warning */
610 UNUSED(hhcd);
612 /* NOTE : This function should not be modified, when the callback is needed,
613 the HAL_HCD_SOF_Callback could be implemented in the user file
618 * @brief Connection Event callback.
619 * @param hhcd HCD handle
620 * @retval None
622 __weak void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
624 /* Prevent unused argument(s) compilation warning */
625 UNUSED(hhcd);
627 /* NOTE : This function should not be modified, when the callback is needed,
628 the HAL_HCD_Connect_Callback could be implemented in the user file
633 * @brief Disconnection Event callback.
634 * @param hhcd HCD handle
635 * @retval None
637 __weak void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
639 /* Prevent unused argument(s) compilation warning */
640 UNUSED(hhcd);
642 /* NOTE : This function should not be modified, when the callback is needed,
643 the HAL_HCD_Disconnect_Callback could be implemented in the user file
648 * @brief Port Enabled Event callback.
649 * @param hhcd HCD handle
650 * @retval None
652 __weak void HAL_HCD_PortEnabled_Callback(HCD_HandleTypeDef *hhcd)
654 /* Prevent unused argument(s) compilation warning */
655 UNUSED(hhcd);
657 /* NOTE : This function should not be modified, when the callback is needed,
658 the HAL_HCD_Disconnect_Callback could be implemented in the user file
663 * @brief Port Disabled Event callback.
664 * @param hhcd HCD handle
665 * @retval None
667 __weak void HAL_HCD_PortDisabled_Callback(HCD_HandleTypeDef *hhcd)
669 /* Prevent unused argument(s) compilation warning */
670 UNUSED(hhcd);
672 /* NOTE : This function should not be modified, when the callback is needed,
673 the HAL_HCD_Disconnect_Callback could be implemented in the user file
678 * @brief Notify URB state change callback.
679 * @param hhcd HCD handle
680 * @param chnum Channel number.
681 * This parameter can be a value from 1 to 15
682 * @param urb_state:
683 * This parameter can be one of these values:
684 * URB_IDLE/
685 * URB_DONE/
686 * URB_NOTREADY/
687 * URB_NYET/
688 * URB_ERROR/
689 * URB_STALL/
690 * @retval None
692 __weak void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state)
694 /* Prevent unused argument(s) compilation warning */
695 UNUSED(hhcd);
696 UNUSED(chnum);
697 UNUSED(urb_state);
699 /* NOTE : This function should not be modified, when the callback is needed,
700 the HAL_HCD_HC_NotifyURBChange_Callback could be implemented in the user file
704 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
706 * @brief Register a User USB HCD Callback
707 * To be used instead of the weak predefined callback
708 * @param hhcd USB HCD handle
709 * @param CallbackID ID of the callback to be registered
710 * This parameter can be one of the following values:
711 * @arg @ref HAL_HCD_SOF_CB_ID USB HCD SOF callback ID
712 * @arg @ref HAL_HCD_CONNECT_CB_ID USB HCD Connect callback ID
713 * @arg @ref HAL_HCD_DISCONNECT_CB_ID OTG HCD Disconnect callback ID
714 * @arg @ref HAL_HCD_PORT_ENABLED_CB_ID USB HCD Port Enable callback ID
715 * @arg @ref HAL_HCD_PORT_DISABLED_CB_ID USB HCD Port Disable callback ID
716 * @arg @ref HAL_HCD_MSPINIT_CB_ID MspDeInit callback ID
717 * @arg @ref HAL_HCD_MSPDEINIT_CB_ID MspDeInit callback ID
718 * @param pCallback pointer to the Callback function
719 * @retval HAL status
721 HAL_StatusTypeDef HAL_HCD_RegisterCallback(HCD_HandleTypeDef *hhcd, HAL_HCD_CallbackIDTypeDef CallbackID, pHCD_CallbackTypeDef pCallback)
723 HAL_StatusTypeDef status = HAL_OK;
725 if (pCallback == NULL)
727 /* Update the error code */
728 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
729 return HAL_ERROR;
731 /* Process locked */
732 __HAL_LOCK(hhcd);
734 if (hhcd->State == HAL_HCD_STATE_READY)
736 switch (CallbackID)
738 case HAL_HCD_SOF_CB_ID :
739 hhcd->SOFCallback = pCallback;
740 break;
742 case HAL_HCD_CONNECT_CB_ID :
743 hhcd->ConnectCallback = pCallback;
744 break;
746 case HAL_HCD_DISCONNECT_CB_ID :
747 hhcd->DisconnectCallback = pCallback;
748 break;
750 case HAL_HCD_PORT_ENABLED_CB_ID :
751 hhcd->PortEnabledCallback = pCallback;
752 break;
754 case HAL_HCD_PORT_DISABLED_CB_ID :
755 hhcd->PortDisabledCallback = pCallback;
756 break;
758 case HAL_HCD_MSPINIT_CB_ID :
759 hhcd->MspInitCallback = pCallback;
760 break;
762 case HAL_HCD_MSPDEINIT_CB_ID :
763 hhcd->MspDeInitCallback = pCallback;
764 break;
766 default :
767 /* Update the error code */
768 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
769 /* Return error status */
770 status = HAL_ERROR;
771 break;
774 else if (hhcd->State == HAL_HCD_STATE_RESET)
776 switch (CallbackID)
778 case HAL_HCD_MSPINIT_CB_ID :
779 hhcd->MspInitCallback = pCallback;
780 break;
782 case HAL_HCD_MSPDEINIT_CB_ID :
783 hhcd->MspDeInitCallback = pCallback;
784 break;
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;
794 else
796 /* Update the error code */
797 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
798 /* Return error status */
799 status = HAL_ERROR;
802 /* Release Lock */
803 __HAL_UNLOCK(hhcd);
804 return status;
808 * @brief Unregister an USB HCD Callback
809 * USB HCD callabck is redirected to the weak predefined callback
810 * @param hhcd USB HCD handle
811 * @param CallbackID ID of the callback to be unregistered
812 * This parameter can be one of the following values:
813 * @arg @ref HAL_HCD_SOF_CB_ID USB HCD SOF callback ID
814 * @arg @ref HAL_HCD_CONNECT_CB_ID USB HCD Connect callback ID
815 * @arg @ref HAL_HCD_DISCONNECT_CB_ID OTG HCD Disconnect callback ID
816 * @arg @ref HAL_HCD_PORT_ENABLED_CB_ID USB HCD Port Enabled callback ID
817 * @arg @ref HAL_HCD_PORT_DISABLED_CB_ID USB HCD Port Disabled callback ID
818 * @arg @ref HAL_HCD_MSPINIT_CB_ID MspDeInit callback ID
819 * @arg @ref HAL_HCD_MSPDEINIT_CB_ID MspDeInit callback ID
820 * @retval HAL status
822 HAL_StatusTypeDef HAL_HCD_UnRegisterCallback(HCD_HandleTypeDef *hhcd, HAL_HCD_CallbackIDTypeDef CallbackID)
824 HAL_StatusTypeDef status = HAL_OK;
826 /* Process locked */
827 __HAL_LOCK(hhcd);
829 /* Setup Legacy weak Callbacks */
830 if (hhcd->State == HAL_HCD_STATE_READY)
832 switch (CallbackID)
834 case HAL_HCD_SOF_CB_ID :
835 hhcd->SOFCallback = HAL_HCD_SOF_Callback;
836 break;
838 case HAL_HCD_CONNECT_CB_ID :
839 hhcd->ConnectCallback = HAL_HCD_Connect_Callback;
840 break;
842 case HAL_HCD_DISCONNECT_CB_ID :
843 hhcd->DisconnectCallback = HAL_HCD_Disconnect_Callback;
844 break;
846 case HAL_HCD_PORT_ENABLED_CB_ID :
847 hhcd->PortEnabledCallback = HAL_HCD_PortEnabled_Callback;
848 break;
850 case HAL_HCD_PORT_DISABLED_CB_ID :
851 hhcd->PortDisabledCallback = HAL_HCD_PortDisabled_Callback;
852 break;
854 case HAL_HCD_MSPINIT_CB_ID :
855 hhcd->MspInitCallback = HAL_HCD_MspInit;
856 break;
858 case HAL_HCD_MSPDEINIT_CB_ID :
859 hhcd->MspDeInitCallback = HAL_HCD_MspDeInit;
860 break;
862 default :
863 /* Update the error code */
864 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
866 /* Return error status */
867 status = HAL_ERROR;
868 break;
871 else if (hhcd->State == HAL_HCD_STATE_RESET)
873 switch (CallbackID)
875 case HAL_HCD_MSPINIT_CB_ID :
876 hhcd->MspInitCallback = HAL_HCD_MspInit;
877 break;
879 case HAL_HCD_MSPDEINIT_CB_ID :
880 hhcd->MspDeInitCallback = HAL_HCD_MspDeInit;
881 break;
883 default :
884 /* Update the error code */
885 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
887 /* Return error status */
888 status = HAL_ERROR;
889 break;
892 else
894 /* Update the error code */
895 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
897 /* Return error status */
898 status = HAL_ERROR;
901 /* Release Lock */
902 __HAL_UNLOCK(hhcd);
903 return status;
907 * @brief Register USB HCD Host Channel Notify URB Change Callback
908 * To be used instead of the weak HAL_HCD_HC_NotifyURBChange_Callback() predefined callback
909 * @param hhcd HCD handle
910 * @param pCallback pointer to the USB HCD Host Channel Notify URB Change Callback function
911 * @retval HAL status
913 HAL_StatusTypeDef HAL_HCD_RegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd, pHCD_HC_NotifyURBChangeCallbackTypeDef pCallback)
915 HAL_StatusTypeDef status = HAL_OK;
917 if (pCallback == NULL)
919 /* Update the error code */
920 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
922 return HAL_ERROR;
925 /* Process locked */
926 __HAL_LOCK(hhcd);
928 if (hhcd->State == HAL_HCD_STATE_READY)
930 hhcd->HC_NotifyURBChangeCallback = pCallback;
932 else
934 /* Update the error code */
935 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
937 /* Return error status */
938 status = HAL_ERROR;
941 /* Release Lock */
942 __HAL_UNLOCK(hhcd);
944 return status;
948 * @brief UnRegister the USB HCD Host Channel Notify URB Change Callback
949 * USB HCD Host Channel Notify URB Change Callback is redirected to the weak HAL_HCD_HC_NotifyURBChange_Callback() predefined callback
950 * @param hhcd HCD handle
951 * @retval HAL status
953 HAL_StatusTypeDef HAL_HCD_UnRegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd)
955 HAL_StatusTypeDef status = HAL_OK;
957 /* Process locked */
958 __HAL_LOCK(hhcd);
960 if (hhcd->State == HAL_HCD_STATE_READY)
962 hhcd->HC_NotifyURBChangeCallback = HAL_HCD_HC_NotifyURBChange_Callback; /* Legacy weak DataOutStageCallback */
964 else
966 /* Update the error code */
967 hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK;
969 /* Return error status */
970 status = HAL_ERROR;
973 /* Release Lock */
974 __HAL_UNLOCK(hhcd);
976 return status;
978 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
981 * @}
984 /** @defgroup HCD_Exported_Functions_Group3 Peripheral Control functions
985 * @brief Management functions
987 @verbatim
988 ===============================================================================
989 ##### Peripheral Control functions #####
990 ===============================================================================
991 [..]
992 This subsection provides a set of functions allowing to control the HCD data
993 transfers.
995 @endverbatim
996 * @{
1000 * @brief Start the host driver.
1001 * @param hhcd HCD handle
1002 * @retval HAL status
1004 HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd)
1006 __HAL_LOCK(hhcd);
1007 __HAL_HCD_ENABLE(hhcd);
1008 (void)USB_DriveVbus(hhcd->Instance, 1U);
1009 __HAL_UNLOCK(hhcd);
1011 return HAL_OK;
1015 * @brief Stop the host driver.
1016 * @param hhcd HCD handle
1017 * @retval HAL status
1020 HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd)
1022 __HAL_LOCK(hhcd);
1023 (void)USB_StopHost(hhcd->Instance);
1024 __HAL_UNLOCK(hhcd);
1026 return HAL_OK;
1030 * @brief Reset the host port.
1031 * @param hhcd HCD handle
1032 * @retval HAL status
1034 HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd)
1036 return (USB_ResetPort(hhcd->Instance));
1040 * @}
1043 /** @defgroup HCD_Exported_Functions_Group4 Peripheral State functions
1044 * @brief Peripheral State functions
1046 @verbatim
1047 ===============================================================================
1048 ##### Peripheral State functions #####
1049 ===============================================================================
1050 [..]
1051 This subsection permits to get in run-time the status of the peripheral
1052 and the data flow.
1054 @endverbatim
1055 * @{
1059 * @brief Return the HCD handle state.
1060 * @param hhcd HCD handle
1061 * @retval HAL state
1063 HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef *hhcd)
1065 return hhcd->State;
1069 * @brief Return URB state for a channel.
1070 * @param hhcd HCD handle
1071 * @param chnum Channel number.
1072 * This parameter can be a value from 1 to 15
1073 * @retval URB state.
1074 * This parameter can be one of these values:
1075 * URB_IDLE/
1076 * URB_DONE/
1077 * URB_NOTREADY/
1078 * URB_NYET/
1079 * URB_ERROR/
1080 * URB_STALL
1082 HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef *hhcd, uint8_t chnum)
1084 return hhcd->hc[chnum].urb_state;
1089 * @brief Return the last host transfer size.
1090 * @param hhcd HCD handle
1091 * @param chnum Channel number.
1092 * This parameter can be a value from 1 to 15
1093 * @retval last transfer size in byte
1095 uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef *hhcd, uint8_t chnum)
1097 return hhcd->hc[chnum].xfer_count;
1101 * @brief Return the Host Channel state.
1102 * @param hhcd HCD handle
1103 * @param chnum Channel number.
1104 * This parameter can be a value from 1 to 15
1105 * @retval Host channel state
1106 * This parameter can be one of these values:
1107 * HC_IDLE/
1108 * HC_XFRC/
1109 * HC_HALTED/
1110 * HC_NYET/
1111 * HC_NAK/
1112 * HC_STALL/
1113 * HC_XACTERR/
1114 * HC_BBLERR/
1115 * HC_DATATGLERR
1117 HCD_HCStateTypeDef HAL_HCD_HC_GetState(HCD_HandleTypeDef *hhcd, uint8_t chnum)
1119 return hhcd->hc[chnum].state;
1123 * @brief Return the current Host frame number.
1124 * @param hhcd HCD handle
1125 * @retval Current Host frame number
1127 uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd)
1129 return (USB_GetCurrentFrame(hhcd->Instance));
1133 * @brief Return the Host enumeration speed.
1134 * @param hhcd HCD handle
1135 * @retval Enumeration speed
1137 uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd)
1139 return (USB_GetHostSpeed(hhcd->Instance));
1143 * @}
1147 * @}
1150 /** @addtogroup HCD_Private_Functions
1151 * @{
1154 * @brief Handle Host Channel IN interrupt requests.
1155 * @param hhcd HCD handle
1156 * @param chnum Channel number.
1157 * This parameter can be a value from 1 to 15
1158 * @retval none
1160 static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
1162 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
1163 uint32_t USBx_BASE = (uint32_t)USBx;
1164 uint32_t ch_num = (uint32_t)chnum;
1166 uint32_t tmpreg;
1168 if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_AHBERR) == USB_OTG_HCINT_AHBERR)
1170 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_AHBERR);
1171 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1173 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_BBERR) == USB_OTG_HCINT_BBERR)
1175 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_BBERR);
1176 hhcd->hc[ch_num].state = HC_BBLERR;
1177 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1178 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1180 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_ACK) == USB_OTG_HCINT_ACK)
1182 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_ACK);
1184 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_STALL) == USB_OTG_HCINT_STALL)
1186 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1187 hhcd->hc[ch_num].state = HC_STALL;
1188 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
1189 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_STALL);
1190 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1192 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_DTERR) == USB_OTG_HCINT_DTERR)
1194 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1195 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1196 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
1197 hhcd->hc[ch_num].state = HC_DATATGLERR;
1198 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_DTERR);
1200 else
1202 /* ... */
1205 if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_FRMOR) == USB_OTG_HCINT_FRMOR)
1207 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1208 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1209 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_FRMOR);
1211 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_XFRC) == USB_OTG_HCINT_XFRC)
1213 if (hhcd->Init.dma_enable != 0U)
1215 hhcd->hc[ch_num].xfer_count = hhcd->hc[ch_num].xfer_len - \
1216 (USBx_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_XFRSIZ);
1219 hhcd->hc[ch_num].state = HC_XFRC;
1220 hhcd->hc[ch_num].ErrCnt = 0U;
1221 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_XFRC);
1223 if ((hhcd->hc[ch_num].ep_type == EP_TYPE_CTRL) ||
1224 (hhcd->hc[ch_num].ep_type == EP_TYPE_BULK))
1226 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1227 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1228 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
1230 else if (hhcd->hc[ch_num].ep_type == EP_TYPE_INTR)
1232 USBx_HC(ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
1233 hhcd->hc[ch_num].urb_state = URB_DONE;
1235 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1236 hhcd->HC_NotifyURBChangeCallback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
1237 #else
1238 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
1239 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1241 else if (hhcd->hc[ch_num].ep_type == EP_TYPE_ISOC)
1243 hhcd->hc[ch_num].urb_state = URB_DONE;
1244 hhcd->hc[ch_num].toggle_in ^= 1U;
1246 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1247 hhcd->HC_NotifyURBChangeCallback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
1248 #else
1249 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
1250 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1252 else
1254 /* ... */
1256 hhcd->hc[ch_num].toggle_in ^= 1U;
1259 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_CHH) == USB_OTG_HCINT_CHH)
1261 __HAL_HCD_MASK_HALT_HC_INT(ch_num);
1263 if (hhcd->hc[ch_num].state == HC_XFRC)
1265 hhcd->hc[ch_num].urb_state = URB_DONE;
1267 else if (hhcd->hc[ch_num].state == HC_STALL)
1269 hhcd->hc[ch_num].urb_state = URB_STALL;
1271 else if ((hhcd->hc[ch_num].state == HC_XACTERR) ||
1272 (hhcd->hc[ch_num].state == HC_DATATGLERR))
1274 hhcd->hc[ch_num].ErrCnt++;
1275 if (hhcd->hc[ch_num].ErrCnt > 3U)
1277 hhcd->hc[ch_num].ErrCnt = 0U;
1278 hhcd->hc[ch_num].urb_state = URB_ERROR;
1280 else
1282 hhcd->hc[ch_num].urb_state = URB_NOTREADY;
1285 /* re-activate the channel */
1286 tmpreg = USBx_HC(ch_num)->HCCHAR;
1287 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1288 tmpreg |= USB_OTG_HCCHAR_CHENA;
1289 USBx_HC(ch_num)->HCCHAR = tmpreg;
1291 else if (hhcd->hc[ch_num].state == HC_NAK)
1293 hhcd->hc[ch_num].urb_state = URB_NOTREADY;
1294 /* re-activate the channel */
1295 tmpreg = USBx_HC(ch_num)->HCCHAR;
1296 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1297 tmpreg |= USB_OTG_HCCHAR_CHENA;
1298 USBx_HC(ch_num)->HCCHAR = tmpreg;
1300 else if (hhcd->hc[ch_num].state == HC_BBLERR)
1302 hhcd->hc[ch_num].ErrCnt++;
1303 hhcd->hc[ch_num].urb_state = URB_ERROR;
1305 else
1307 /* ... */
1309 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_CHH);
1310 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
1312 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_TXERR) == USB_OTG_HCINT_TXERR)
1314 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1315 hhcd->hc[ch_num].ErrCnt++;
1316 hhcd->hc[ch_num].state = HC_XACTERR;
1317 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1318 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_TXERR);
1320 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_NAK) == USB_OTG_HCINT_NAK)
1322 if (hhcd->hc[ch_num].ep_type == EP_TYPE_INTR)
1324 hhcd->hc[ch_num].ErrCnt = 0U;
1325 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1326 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1328 else if ((hhcd->hc[ch_num].ep_type == EP_TYPE_CTRL) ||
1329 (hhcd->hc[ch_num].ep_type == EP_TYPE_BULK))
1331 hhcd->hc[ch_num].ErrCnt = 0U;
1333 if (hhcd->Init.dma_enable == 0U)
1335 hhcd->hc[ch_num].state = HC_NAK;
1336 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1337 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1340 else
1342 /* ... */
1344 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
1346 else
1348 /* ... */
1353 * @brief Handle Host Channel OUT interrupt requests.
1354 * @param hhcd HCD handle
1355 * @param chnum Channel number.
1356 * This parameter can be a value from 1 to 15
1357 * @retval none
1359 static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
1361 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
1362 uint32_t USBx_BASE = (uint32_t)USBx;
1363 uint32_t ch_num = (uint32_t)chnum;
1364 uint32_t tmpreg;
1366 if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_AHBERR) == USB_OTG_HCINT_AHBERR)
1368 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_AHBERR);
1369 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1371 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_ACK) == USB_OTG_HCINT_ACK)
1373 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_ACK);
1375 if (hhcd->hc[ch_num].do_ping == 1U)
1377 hhcd->hc[ch_num].do_ping = 0U;
1378 hhcd->hc[ch_num].urb_state = URB_NOTREADY;
1379 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1380 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1383 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_NYET) == USB_OTG_HCINT_NYET)
1385 hhcd->hc[ch_num].state = HC_NYET;
1386 hhcd->hc[ch_num].do_ping = 1U;
1387 hhcd->hc[ch_num].ErrCnt = 0U;
1388 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1389 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1390 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NYET);
1392 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_FRMOR) == USB_OTG_HCINT_FRMOR)
1394 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1395 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1396 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_FRMOR);
1398 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_XFRC) == USB_OTG_HCINT_XFRC)
1400 hhcd->hc[ch_num].ErrCnt = 0U;
1401 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1402 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1403 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_XFRC);
1404 hhcd->hc[ch_num].state = HC_XFRC;
1406 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_STALL) == USB_OTG_HCINT_STALL)
1408 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_STALL);
1409 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1410 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1411 hhcd->hc[ch_num].state = HC_STALL;
1413 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_NAK) == USB_OTG_HCINT_NAK)
1415 hhcd->hc[ch_num].ErrCnt = 0U;
1416 hhcd->hc[ch_num].state = HC_NAK;
1418 if (hhcd->hc[ch_num].do_ping == 0U)
1420 if (hhcd->hc[ch_num].speed == HCD_SPEED_HIGH)
1422 hhcd->hc[ch_num].do_ping = 1U;
1426 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1427 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1428 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
1430 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_TXERR) == USB_OTG_HCINT_TXERR)
1432 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1433 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1434 hhcd->hc[ch_num].state = HC_XACTERR;
1435 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_TXERR);
1437 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_DTERR) == USB_OTG_HCINT_DTERR)
1439 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num);
1440 (void)USB_HC_Halt(hhcd->Instance, (uint8_t)ch_num);
1441 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
1442 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_DTERR);
1443 hhcd->hc[ch_num].state = HC_DATATGLERR;
1445 else if ((USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_CHH) == USB_OTG_HCINT_CHH)
1447 __HAL_HCD_MASK_HALT_HC_INT(ch_num);
1449 if (hhcd->hc[ch_num].state == HC_XFRC)
1451 hhcd->hc[ch_num].urb_state = URB_DONE;
1452 if ((hhcd->hc[ch_num].ep_type == EP_TYPE_BULK) ||
1453 (hhcd->hc[ch_num].ep_type == EP_TYPE_INTR))
1455 hhcd->hc[ch_num].toggle_out ^= 1U;
1458 else if (hhcd->hc[ch_num].state == HC_NAK)
1460 hhcd->hc[ch_num].urb_state = URB_NOTREADY;
1462 else if (hhcd->hc[ch_num].state == HC_NYET)
1464 hhcd->hc[ch_num].urb_state = URB_NOTREADY;
1466 else if (hhcd->hc[ch_num].state == HC_STALL)
1468 hhcd->hc[ch_num].urb_state = URB_STALL;
1470 else if ((hhcd->hc[ch_num].state == HC_XACTERR) ||
1471 (hhcd->hc[ch_num].state == HC_DATATGLERR))
1473 hhcd->hc[ch_num].ErrCnt++;
1474 if (hhcd->hc[ch_num].ErrCnt > 3U)
1476 hhcd->hc[ch_num].ErrCnt = 0U;
1477 hhcd->hc[ch_num].urb_state = URB_ERROR;
1479 else
1481 hhcd->hc[ch_num].urb_state = URB_NOTREADY;
1484 /* re-activate the channel */
1485 tmpreg = USBx_HC(ch_num)->HCCHAR;
1486 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1487 tmpreg |= USB_OTG_HCCHAR_CHENA;
1488 USBx_HC(ch_num)->HCCHAR = tmpreg;
1490 else
1492 /* ... */
1495 __HAL_HCD_CLEAR_HC_INT(ch_num, USB_OTG_HCINT_CHH);
1496 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)ch_num, hhcd->hc[ch_num].urb_state);
1498 else
1500 /* ... */
1505 * @brief Handle Rx Queue Level interrupt requests.
1506 * @param hhcd HCD handle
1507 * @retval none
1509 static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd)
1511 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
1512 uint32_t USBx_BASE = (uint32_t)USBx;
1513 uint32_t pktsts;
1514 uint32_t pktcnt;
1515 uint32_t temp;
1516 uint32_t tmpreg;
1517 uint32_t ch_num;
1519 temp = hhcd->Instance->GRXSTSP;
1520 ch_num = temp & USB_OTG_GRXSTSP_EPNUM;
1521 pktsts = (temp & USB_OTG_GRXSTSP_PKTSTS) >> 17;
1522 pktcnt = (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
1524 switch (pktsts)
1526 case GRXSTS_PKTSTS_IN:
1527 /* Read the data into the host buffer. */
1528 if ((pktcnt > 0U) && (hhcd->hc[ch_num].xfer_buff != (void *)0))
1530 (void)USB_ReadPacket(hhcd->Instance, hhcd->hc[ch_num].xfer_buff, (uint16_t)pktcnt);
1532 /*manage multiple Xfer */
1533 hhcd->hc[ch_num].xfer_buff += pktcnt;
1534 hhcd->hc[ch_num].xfer_count += pktcnt;
1536 if ((USBx_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) > 0U)
1538 /* re-activate the channel when more packets are expected */
1539 tmpreg = USBx_HC(ch_num)->HCCHAR;
1540 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1541 tmpreg |= USB_OTG_HCCHAR_CHENA;
1542 USBx_HC(ch_num)->HCCHAR = tmpreg;
1543 hhcd->hc[ch_num].toggle_in ^= 1U;
1546 break;
1548 case GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
1549 break;
1551 case GRXSTS_PKTSTS_IN_XFER_COMP:
1552 case GRXSTS_PKTSTS_CH_HALTED:
1553 default:
1554 break;
1559 * @brief Handle Host Port interrupt requests.
1560 * @param hhcd HCD handle
1561 * @retval None
1563 static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd)
1565 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
1566 uint32_t USBx_BASE = (uint32_t)USBx;
1567 __IO uint32_t hprt0, hprt0_dup;
1569 /* Handle Host Port Interrupts */
1570 hprt0 = USBx_HPRT0;
1571 hprt0_dup = USBx_HPRT0;
1573 hprt0_dup &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET | \
1574 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
1576 /* Check whether Port Connect detected */
1577 if ((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET)
1579 if ((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS)
1581 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1582 hhcd->ConnectCallback(hhcd);
1583 #else
1584 HAL_HCD_Connect_Callback(hhcd);
1585 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1587 hprt0_dup |= USB_OTG_HPRT_PCDET;
1590 /* Check whether Port Enable Changed */
1591 if ((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG)
1593 hprt0_dup |= USB_OTG_HPRT_PENCHNG;
1595 if ((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA)
1597 if (hhcd->Init.phy_itface == USB_OTG_EMBEDDED_PHY)
1599 if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17))
1601 (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_6_MHZ);
1603 else
1605 (void)USB_InitFSLSPClkSel(hhcd->Instance, HCFG_48_MHZ);
1608 else
1610 if (hhcd->Init.speed == HCD_SPEED_FULL)
1612 USBx_HOST->HFIR = 60000U;
1615 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1616 hhcd->PortEnabledCallback(hhcd);
1617 #else
1618 HAL_HCD_PortEnabled_Callback(hhcd);
1619 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1622 else
1624 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1625 hhcd->PortDisabledCallback(hhcd);
1626 #else
1627 HAL_HCD_PortDisabled_Callback(hhcd);
1628 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1632 /* Check for an overcurrent */
1633 if ((hprt0 & USB_OTG_HPRT_POCCHNG) == USB_OTG_HPRT_POCCHNG)
1635 hprt0_dup |= USB_OTG_HPRT_POCCHNG;
1638 /* Clear Port Interrupts */
1639 USBx_HPRT0 = hprt0_dup;
1643 * @}
1647 * @}
1650 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
1651 #endif /* HAL_HCD_MODULE_ENABLED */
1654 * @}
1658 * @}
1661 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/