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
14 ==============================================================================
15 ##### How to use this driver #####
16 ==============================================================================
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:
42 ******************************************************************************
45 * <h2><center>© 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
63 #ifdef HAL_HCD_MODULE_ENABLED
65 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
68 * @brief HCD HAL module driver
72 /* Private typedef -----------------------------------------------------------*/
73 /* Private define ------------------------------------------------------------*/
74 /* Private macro -------------------------------------------------------------*/
75 /* Private variables ---------------------------------------------------------*/
76 /* Private function prototypes -----------------------------------------------*/
77 /** @defgroup HCD_Private_Functions HCD Private Functions
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
);
88 /* Exported functions --------------------------------------------------------*/
89 /** @defgroup HCD_Exported_Functions HCD Exported Functions
93 /** @defgroup HCD_Exported_Functions_Group1 Initialization and de-initialization functions
94 * @brief Initialization and Configuration functions
97 ===============================================================================
98 ##### Initialization and de-initialization functions #####
99 ===============================================================================
100 [..] This section provides functions allowing to:
107 * @brief Initialize the host driver.
108 * @param hhcd HCD handle
111 HAL_StatusTypeDef
HAL_HCD_Init(HCD_HandleTypeDef
*hhcd
)
113 USB_OTG_GlobalTypeDef
*USBx
;
115 /* Check the HCD handle allocation */
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
);
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
);
167 (void)USB_SetCurrentMode(hhcd
->Instance
, USB_HOST_MODE
);
170 (void)USB_HostInit(hhcd
->Instance
, hhcd
->Init
);
172 hhcd
->State
= HAL_HCD_STATE_READY
;
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
201 HAL_StatusTypeDef
HAL_HCD_HC_Init(HCD_HandleTypeDef
*hhcd
,
209 HAL_StatusTypeDef status
;
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;
225 hhcd
->hc
[ch_num
].ep_is_in
= 0U;
228 hhcd
->hc
[ch_num
].speed
= speed
;
230 status
= USB_HC_Init(hhcd
->Instance
,
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
249 HAL_StatusTypeDef
HAL_HCD_HC_Halt(HCD_HandleTypeDef
*hhcd
, uint8_t ch_num
)
251 HAL_StatusTypeDef status
= HAL_OK
;
254 (void)USB_HC_Halt(hhcd
->Instance
, (uint8_t)ch_num
);
261 * @brief DeInitialize the host driver.
262 * @param hhcd HCD handle
265 HAL_StatusTypeDef
HAL_HCD_DeInit(HCD_HandleTypeDef
*hhcd
)
267 /* Check the HCD handle allocation */
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
);
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
;
296 * @brief Initialize the HCD MSP.
297 * @param hhcd HCD handle
300 __weak
void HAL_HCD_MspInit(HCD_HandleTypeDef
*hhcd
)
302 /* Prevent unused argument(s) compilation warning */
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
315 __weak
void HAL_HCD_MspDeInit(HCD_HandleTypeDef
*hhcd
)
317 /* Prevent unused argument(s) compilation warning */
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
329 /** @defgroup HCD_Exported_Functions_Group2 Input and Output operation functions
330 * @brief HCD IO operation functions
333 ===============================================================================
334 ##### IO operation functions #####
335 ===============================================================================
336 [..] This subsection provides a set of functions allowing to manage the USB Host Data
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
367 HAL_StatusTypeDef
HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef
*hhcd
,
376 hhcd
->hc
[ch_num
].ep_is_in
= direction
;
377 hhcd
->hc
[ch_num
].ep_type
= ep_type
;
381 hhcd
->hc
[ch_num
].data_pid
= HC_PID_SETUP
;
382 hhcd
->hc
[ch_num
].do_ping
= do_ping
;
386 hhcd
->hc
[ch_num
].data_pid
= HC_PID_DATA1
;
389 /* Manage Data Toggle */
393 if ((token
== 1U) && (direction
== 0U)) /*send data */
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)
405 hhcd
->hc
[ch_num
].data_pid
= HC_PID_DATA0
;
410 hhcd
->hc
[ch_num
].data_pid
= HC_PID_DATA1
;
418 /* Set the Data Toggle bit as per the Flag */
419 if (hhcd
->hc
[ch_num
].toggle_out
== 0U)
422 hhcd
->hc
[ch_num
].data_pid
= HC_PID_DATA0
;
427 hhcd
->hc
[ch_num
].data_pid
= HC_PID_DATA1
;
432 if (hhcd
->hc
[ch_num
].toggle_in
== 0U)
434 hhcd
->hc
[ch_num
].data_pid
= HC_PID_DATA0
;
438 hhcd
->hc
[ch_num
].data_pid
= HC_PID_DATA1
;
446 /* Set the Data Toggle bit as per the Flag */
447 if (hhcd
->hc
[ch_num
].toggle_out
== 0U)
450 hhcd
->hc
[ch_num
].data_pid
= HC_PID_DATA0
;
455 hhcd
->hc
[ch_num
].data_pid
= HC_PID_DATA1
;
460 if (hhcd
->hc
[ch_num
].toggle_in
== 0U)
462 hhcd
->hc
[ch_num
].data_pid
= HC_PID_DATA0
;
466 hhcd
->hc
[ch_num
].data_pid
= HC_PID_DATA1
;
472 hhcd
->hc
[ch_num
].data_pid
= HC_PID_DATA0
;
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
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
))
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
);
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
);
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
);
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
607 __weak
void HAL_HCD_SOF_Callback(HCD_HandleTypeDef
*hhcd
)
609 /* Prevent unused argument(s) compilation warning */
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
622 __weak
void HAL_HCD_Connect_Callback(HCD_HandleTypeDef
*hhcd
)
624 /* Prevent unused argument(s) compilation warning */
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
637 __weak
void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef
*hhcd
)
639 /* Prevent unused argument(s) compilation warning */
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
652 __weak
void HAL_HCD_PortEnabled_Callback(HCD_HandleTypeDef
*hhcd
)
654 /* Prevent unused argument(s) compilation warning */
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
667 __weak
void HAL_HCD_PortDisabled_Callback(HCD_HandleTypeDef
*hhcd
)
669 /* Prevent unused argument(s) compilation warning */
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
683 * This parameter can be one of these values:
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 */
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
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
;
734 if (hhcd
->State
== HAL_HCD_STATE_READY
)
738 case HAL_HCD_SOF_CB_ID
:
739 hhcd
->SOFCallback
= pCallback
;
742 case HAL_HCD_CONNECT_CB_ID
:
743 hhcd
->ConnectCallback
= pCallback
;
746 case HAL_HCD_DISCONNECT_CB_ID
:
747 hhcd
->DisconnectCallback
= pCallback
;
750 case HAL_HCD_PORT_ENABLED_CB_ID
:
751 hhcd
->PortEnabledCallback
= pCallback
;
754 case HAL_HCD_PORT_DISABLED_CB_ID
:
755 hhcd
->PortDisabledCallback
= pCallback
;
758 case HAL_HCD_MSPINIT_CB_ID
:
759 hhcd
->MspInitCallback
= pCallback
;
762 case HAL_HCD_MSPDEINIT_CB_ID
:
763 hhcd
->MspDeInitCallback
= pCallback
;
767 /* Update the error code */
768 hhcd
->ErrorCode
|= HAL_HCD_ERROR_INVALID_CALLBACK
;
769 /* Return error status */
774 else if (hhcd
->State
== HAL_HCD_STATE_RESET
)
778 case HAL_HCD_MSPINIT_CB_ID
:
779 hhcd
->MspInitCallback
= pCallback
;
782 case HAL_HCD_MSPDEINIT_CB_ID
:
783 hhcd
->MspDeInitCallback
= pCallback
;
787 /* Update the error code */
788 hhcd
->ErrorCode
|= HAL_HCD_ERROR_INVALID_CALLBACK
;
789 /* Return error status */
796 /* Update the error code */
797 hhcd
->ErrorCode
|= HAL_HCD_ERROR_INVALID_CALLBACK
;
798 /* Return error 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
822 HAL_StatusTypeDef
HAL_HCD_UnRegisterCallback(HCD_HandleTypeDef
*hhcd
, HAL_HCD_CallbackIDTypeDef CallbackID
)
824 HAL_StatusTypeDef status
= HAL_OK
;
829 /* Setup Legacy weak Callbacks */
830 if (hhcd
->State
== HAL_HCD_STATE_READY
)
834 case HAL_HCD_SOF_CB_ID
:
835 hhcd
->SOFCallback
= HAL_HCD_SOF_Callback
;
838 case HAL_HCD_CONNECT_CB_ID
:
839 hhcd
->ConnectCallback
= HAL_HCD_Connect_Callback
;
842 case HAL_HCD_DISCONNECT_CB_ID
:
843 hhcd
->DisconnectCallback
= HAL_HCD_Disconnect_Callback
;
846 case HAL_HCD_PORT_ENABLED_CB_ID
:
847 hhcd
->PortEnabledCallback
= HAL_HCD_PortEnabled_Callback
;
850 case HAL_HCD_PORT_DISABLED_CB_ID
:
851 hhcd
->PortDisabledCallback
= HAL_HCD_PortDisabled_Callback
;
854 case HAL_HCD_MSPINIT_CB_ID
:
855 hhcd
->MspInitCallback
= HAL_HCD_MspInit
;
858 case HAL_HCD_MSPDEINIT_CB_ID
:
859 hhcd
->MspDeInitCallback
= HAL_HCD_MspDeInit
;
863 /* Update the error code */
864 hhcd
->ErrorCode
|= HAL_HCD_ERROR_INVALID_CALLBACK
;
866 /* Return error status */
871 else if (hhcd
->State
== HAL_HCD_STATE_RESET
)
875 case HAL_HCD_MSPINIT_CB_ID
:
876 hhcd
->MspInitCallback
= HAL_HCD_MspInit
;
879 case HAL_HCD_MSPDEINIT_CB_ID
:
880 hhcd
->MspDeInitCallback
= HAL_HCD_MspDeInit
;
884 /* Update the error code */
885 hhcd
->ErrorCode
|= HAL_HCD_ERROR_INVALID_CALLBACK
;
887 /* Return error status */
894 /* Update the error code */
895 hhcd
->ErrorCode
|= HAL_HCD_ERROR_INVALID_CALLBACK
;
897 /* Return error 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
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
;
928 if (hhcd
->State
== HAL_HCD_STATE_READY
)
930 hhcd
->HC_NotifyURBChangeCallback
= pCallback
;
934 /* Update the error code */
935 hhcd
->ErrorCode
|= HAL_HCD_ERROR_INVALID_CALLBACK
;
937 /* Return error 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
953 HAL_StatusTypeDef
HAL_HCD_UnRegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef
*hhcd
)
955 HAL_StatusTypeDef status
= HAL_OK
;
960 if (hhcd
->State
== HAL_HCD_STATE_READY
)
962 hhcd
->HC_NotifyURBChangeCallback
= HAL_HCD_HC_NotifyURBChange_Callback
; /* Legacy weak DataOutStageCallback */
966 /* Update the error code */
967 hhcd
->ErrorCode
|= HAL_HCD_ERROR_INVALID_CALLBACK
;
969 /* Return error status */
978 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
984 /** @defgroup HCD_Exported_Functions_Group3 Peripheral Control functions
985 * @brief Management functions
988 ===============================================================================
989 ##### Peripheral Control functions #####
990 ===============================================================================
992 This subsection provides a set of functions allowing to control the HCD data
1000 * @brief Start the host driver.
1001 * @param hhcd HCD handle
1002 * @retval HAL status
1004 HAL_StatusTypeDef
HAL_HCD_Start(HCD_HandleTypeDef
*hhcd
)
1007 __HAL_HCD_ENABLE(hhcd
);
1008 (void)USB_DriveVbus(hhcd
->Instance
, 1U);
1015 * @brief Stop the host driver.
1016 * @param hhcd HCD handle
1017 * @retval HAL status
1020 HAL_StatusTypeDef
HAL_HCD_Stop(HCD_HandleTypeDef
*hhcd
)
1023 (void)USB_StopHost(hhcd
->Instance
);
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
));
1043 /** @defgroup HCD_Exported_Functions_Group4 Peripheral State functions
1044 * @brief Peripheral State functions
1047 ===============================================================================
1048 ##### Peripheral State functions #####
1049 ===============================================================================
1051 This subsection permits to get in run-time the status of the peripheral
1059 * @brief Return the HCD handle state.
1060 * @param hhcd HCD handle
1063 HCD_StateTypeDef
HAL_HCD_GetState(HCD_HandleTypeDef
*hhcd
)
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:
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:
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
));
1150 /** @addtogroup HCD_Private_Functions
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
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
;
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
);
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
);
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
);
1249 HAL_HCD_HC_NotifyURBChange_Callback(hhcd
, (uint8_t)ch_num
, hhcd
->hc
[ch_num
].urb_state
);
1250 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
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
;
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
;
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
);
1344 __HAL_HCD_CLEAR_HC_INT(ch_num
, USB_OTG_HCINT_NAK
);
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
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
;
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
;
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
;
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
);
1505 * @brief Handle Rx Queue Level interrupt requests.
1506 * @param hhcd HCD handle
1509 static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef
*hhcd
)
1511 USB_OTG_GlobalTypeDef
*USBx
= hhcd
->Instance
;
1512 uint32_t USBx_BASE
= (uint32_t)USBx
;
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;
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;
1548 case GRXSTS_PKTSTS_DATA_TOGGLE_ERR
:
1551 case GRXSTS_PKTSTS_IN_XFER_COMP
:
1552 case GRXSTS_PKTSTS_CH_HALTED
:
1559 * @brief Handle Host Port interrupt requests.
1560 * @param hhcd HCD handle
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 */
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
);
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
);
1605 (void)USB_InitFSLSPClkSel(hhcd
->Instance
, HCFG_48_MHZ
);
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
);
1618 HAL_HCD_PortEnabled_Callback(hhcd
);
1619 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1624 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1625 hhcd
->PortDisabledCallback(hhcd
);
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
;
1650 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
1651 #endif /* HAL_HCD_MODULE_ENABLED */
1661 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/