2 ******************************************************************************
3 * @file stm32f7xx_hal_hcd.c
4 * @author MCD Application Team
5 * @brief HCD HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the USB Peripheral Controller:
8 * + Initialization and de-initialization functions
9 * + IO operation functions
10 * + Peripheral Control functions
11 * + Peripheral State functions
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</center></h2>
49 * <h2><center>© Copyright (c) YYYY STMicroelectronics.
50 * All rights reserved.</center></h2>
52 * This software component is licensed by ST under BSD 3-Clause license,
53 * the "License"; You may not use this file except in compliance with the
54 * License. You may obtain a copy of the License at:
55 * opensource.org/licenses/BSD-3-Clause
57 ******************************************************************************
60 /* Includes ------------------------------------------------------------------*/
61 #include "stm32f7xx_hal.h"
63 /** @addtogroup STM32F7xx_HAL_Driver
67 #ifdef HAL_HCD_MODULE_ENABLED
69 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
72 * @brief HCD HAL module driver
76 /* Private typedef -----------------------------------------------------------*/
77 /* Private define ------------------------------------------------------------*/
78 /* Private macro -------------------------------------------------------------*/
79 /* Private variables ---------------------------------------------------------*/
80 /* Private function prototypes -----------------------------------------------*/
81 /** @defgroup HCD_Private_Functions HCD Private Functions
84 static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef
*hhcd
, uint8_t chnum
);
85 static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef
*hhcd
, uint8_t chnum
);
86 static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef
*hhcd
);
87 static void HCD_Port_IRQHandler(HCD_HandleTypeDef
*hhcd
);
92 /* Exported functions --------------------------------------------------------*/
93 /** @defgroup HCD_Exported_Functions HCD Exported Functions
97 /** @defgroup HCD_Exported_Functions_Group1 Initialization and de-initialization functions
98 * @brief Initialization and Configuration functions
101 ===============================================================================
102 ##### Initialization and de-initialization functions #####
103 ===============================================================================
104 [..] This section provides functions allowing to:
111 * @brief Initialize the host driver.
112 * @param hhcd HCD handle
115 HAL_StatusTypeDef
HAL_HCD_Init(HCD_HandleTypeDef
*hhcd
)
117 /* Check the HCD handle allocation */
123 /* Check the parameters */
124 assert_param(IS_HCD_ALL_INSTANCE(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 the Interrupts */
155 __HAL_HCD_DISABLE(hhcd
);
157 /* Init the Core (common init.) */
158 (void)USB_CoreInit(hhcd
->Instance
, hhcd
->Init
);
161 (void)USB_SetCurrentMode(hhcd
->Instance
, USB_HOST_MODE
);
164 (void)USB_HostInit(hhcd
->Instance
, hhcd
->Init
);
166 hhcd
->State
= HAL_HCD_STATE_READY
;
172 * @brief Initialize a host channel.
173 * @param hhcd HCD handle
174 * @param ch_num Channel number.
175 * This parameter can be a value from 1 to 15
176 * @param epnum Endpoint number.
177 * This parameter can be a value from 1 to 15
178 * @param dev_address Current device address
179 * This parameter can be a value from 0 to 255
180 * @param speed Current device speed.
181 * This parameter can be one of these values:
182 * HCD_SPEED_HIGH: High speed mode,
183 * HCD_SPEED_FULL: Full speed mode,
184 * HCD_SPEED_LOW: Low speed mode
185 * @param ep_type Endpoint Type.
186 * This parameter can be one of these values:
187 * EP_TYPE_CTRL: Control type,
188 * EP_TYPE_ISOC: Isochronous type,
189 * EP_TYPE_BULK: Bulk type,
190 * EP_TYPE_INTR: Interrupt type
191 * @param mps Max Packet Size.
192 * This parameter can be a value from 0 to32K
195 HAL_StatusTypeDef
HAL_HCD_HC_Init(HCD_HandleTypeDef
*hhcd
,
203 HAL_StatusTypeDef status
;
206 hhcd
->hc
[ch_num
].do_ping
= 0U;
207 hhcd
->hc
[ch_num
].dev_addr
= dev_address
;
208 hhcd
->hc
[ch_num
].max_packet
= mps
;
209 hhcd
->hc
[ch_num
].ch_num
= ch_num
;
210 hhcd
->hc
[ch_num
].ep_type
= ep_type
;
211 hhcd
->hc
[ch_num
].ep_num
= epnum
& 0x7FU
;
213 if ((epnum
& 0x80U
) == 0x80U
)
215 hhcd
->hc
[ch_num
].ep_is_in
= 1U;
219 hhcd
->hc
[ch_num
].ep_is_in
= 0U;
222 hhcd
->hc
[ch_num
].speed
= speed
;
224 status
= USB_HC_Init(hhcd
->Instance
,
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
243 HAL_StatusTypeDef
HAL_HCD_HC_Halt(HCD_HandleTypeDef
*hhcd
, uint8_t ch_num
)
245 HAL_StatusTypeDef status
= HAL_OK
;
248 (void)USB_HC_Halt(hhcd
->Instance
, (uint8_t)ch_num
);
255 * @brief DeInitialize the host driver.
256 * @param hhcd HCD handle
259 HAL_StatusTypeDef
HAL_HCD_DeInit(HCD_HandleTypeDef
*hhcd
)
261 /* Check the HCD handle allocation */
267 hhcd
->State
= HAL_HCD_STATE_BUSY
;
269 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
270 if (hhcd
->MspDeInitCallback
== NULL
)
272 hhcd
->MspDeInitCallback
= HAL_HCD_MspDeInit
; /* Legacy weak MspDeInit */
275 /* DeInit the low level hardware */
276 hhcd
->MspDeInitCallback(hhcd
);
278 /* DeInit the low level hardware: CLOCK, NVIC.*/
279 HAL_HCD_MspDeInit(hhcd
);
280 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
282 __HAL_HCD_DISABLE(hhcd
);
284 hhcd
->State
= HAL_HCD_STATE_RESET
;
290 * @brief Initialize the HCD MSP.
291 * @param hhcd HCD handle
294 __weak
void HAL_HCD_MspInit(HCD_HandleTypeDef
*hhcd
)
296 /* Prevent unused argument(s) compilation warning */
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
305 * @brief DeInitialize the HCD MSP.
306 * @param hhcd HCD handle
309 __weak
void HAL_HCD_MspDeInit(HCD_HandleTypeDef
*hhcd
)
311 /* Prevent unused argument(s) compilation warning */
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
323 /** @defgroup HCD_Exported_Functions_Group2 Input and Output operation functions
324 * @brief HCD IO operation functions
327 ===============================================================================
328 ##### IO operation functions #####
329 ===============================================================================
330 [..] This subsection provides a set of functions allowing to manage the USB Host Data
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
361 HAL_StatusTypeDef
HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef
*hhcd
,
372 hhcd
->hc
[ch_num
].ep_is_in
= direction
;
373 hhcd
->hc
[ch_num
].ep_type
= ep_type
;
377 hhcd
->hc
[ch_num
].data_pid
= HC_PID_SETUP
;
381 hhcd
->hc
[ch_num
].data_pid
= HC_PID_DATA1
;
384 /* Manage Data Toggle */
388 if ((token
== 1U) && (direction
== 0U)) /*send data */
392 /* For Status OUT stage, Length==0, Status Out PID = 1 */
393 hhcd
->hc
[ch_num
].toggle_out
= 1U;
396 /* Set the Data Toggle bit as per the Flag */
397 if (hhcd
->hc
[ch_num
].toggle_out
== 0U)
400 hhcd
->hc
[ch_num
].data_pid
= HC_PID_DATA0
;
405 hhcd
->hc
[ch_num
].data_pid
= HC_PID_DATA1
;
413 /* Set the Data Toggle bit as per the Flag */
414 if (hhcd
->hc
[ch_num
].toggle_out
== 0U)
417 hhcd
->hc
[ch_num
].data_pid
= HC_PID_DATA0
;
422 hhcd
->hc
[ch_num
].data_pid
= HC_PID_DATA1
;
427 if (hhcd
->hc
[ch_num
].toggle_in
== 0U)
429 hhcd
->hc
[ch_num
].data_pid
= HC_PID_DATA0
;
433 hhcd
->hc
[ch_num
].data_pid
= HC_PID_DATA1
;
441 /* Set the Data Toggle bit as per the Flag */
442 if (hhcd
->hc
[ch_num
].toggle_out
== 0U)
445 hhcd
->hc
[ch_num
].data_pid
= HC_PID_DATA0
;
450 hhcd
->hc
[ch_num
].data_pid
= HC_PID_DATA1
;
455 if (hhcd
->hc
[ch_num
].toggle_in
== 0U)
457 hhcd
->hc
[ch_num
].data_pid
= HC_PID_DATA0
;
461 hhcd
->hc
[ch_num
].data_pid
= HC_PID_DATA1
;
467 hhcd
->hc
[ch_num
].data_pid
= HC_PID_DATA0
;
474 hhcd
->hc
[ch_num
].xfer_buff
= pbuff
;
475 hhcd
->hc
[ch_num
].xfer_len
= length
;
476 hhcd
->hc
[ch_num
].urb_state
= URB_IDLE
;
477 hhcd
->hc
[ch_num
].xfer_count
= 0U;
478 hhcd
->hc
[ch_num
].ch_num
= ch_num
;
479 hhcd
->hc
[ch_num
].state
= HC_IDLE
;
481 return USB_HC_StartXfer(hhcd
->Instance
, &hhcd
->hc
[ch_num
], (uint8_t)hhcd
->Init
.dma_enable
);
485 * @brief Handle HCD interrupt request.
486 * @param hhcd HCD handle
489 void HAL_HCD_IRQHandler(HCD_HandleTypeDef
*hhcd
)
491 USB_OTG_GlobalTypeDef
*USBx
= hhcd
->Instance
;
492 uint32_t USBx_BASE
= (uint32_t)USBx
;
493 uint32_t i
, interrupt
;
495 /* Ensure that we are in device mode */
496 if (USB_GetMode(hhcd
->Instance
) == USB_OTG_MODE_HOST
)
498 /* Avoid spurious interrupt */
499 if (__HAL_HCD_IS_INVALID_INTERRUPT(hhcd
))
504 if (__HAL_HCD_GET_FLAG(hhcd
, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT
))
506 /* Incorrect mode, acknowledge the interrupt */
507 __HAL_HCD_CLEAR_FLAG(hhcd
, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT
);
510 if (__HAL_HCD_GET_FLAG(hhcd
, USB_OTG_GINTSTS_IISOIXFR
))
512 /* Incorrect mode, acknowledge the interrupt */
513 __HAL_HCD_CLEAR_FLAG(hhcd
, USB_OTG_GINTSTS_IISOIXFR
);
516 if (__HAL_HCD_GET_FLAG(hhcd
, USB_OTG_GINTSTS_PTXFE
))
518 /* Incorrect mode, acknowledge the interrupt */
519 __HAL_HCD_CLEAR_FLAG(hhcd
, USB_OTG_GINTSTS_PTXFE
);
522 if (__HAL_HCD_GET_FLAG(hhcd
, USB_OTG_GINTSTS_MMIS
))
524 /* Incorrect mode, acknowledge the interrupt */
525 __HAL_HCD_CLEAR_FLAG(hhcd
, USB_OTG_GINTSTS_MMIS
);
528 /* Handle Host Disconnect Interrupts */
529 if (__HAL_HCD_GET_FLAG(hhcd
, USB_OTG_GINTSTS_DISCINT
))
533 USBx_HPRT0
&= ~(USB_OTG_HPRT_PENA
| USB_OTG_HPRT_PCDET
| \
534 USB_OTG_HPRT_PENCHNG
| USB_OTG_HPRT_POCCHNG
);
536 /* Handle Host Port Disconnect Interrupt */
537 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
538 hhcd
->DisconnectCallback(hhcd
);
540 HAL_HCD_Disconnect_Callback(hhcd
);
541 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
543 (void)USB_InitFSLSPClkSel(hhcd
->Instance
, HCFG_48_MHZ
);
544 __HAL_HCD_CLEAR_FLAG(hhcd
, USB_OTG_GINTSTS_DISCINT
);
547 /* Handle Host Port Interrupts */
548 if (__HAL_HCD_GET_FLAG(hhcd
, USB_OTG_GINTSTS_HPRTINT
))
550 HCD_Port_IRQHandler(hhcd
);
553 /* Handle Host SOF Interrupt */
554 if (__HAL_HCD_GET_FLAG(hhcd
, USB_OTG_GINTSTS_SOF
))
556 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
557 hhcd
->SOFCallback(hhcd
);
559 HAL_HCD_SOF_Callback(hhcd
);
560 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
562 __HAL_HCD_CLEAR_FLAG(hhcd
, USB_OTG_GINTSTS_SOF
);
565 /* Handle Host channel Interrupt */
566 if (__HAL_HCD_GET_FLAG(hhcd
, USB_OTG_GINTSTS_HCINT
))
568 interrupt
= USB_HC_ReadInterrupt(hhcd
->Instance
);
569 for (i
= 0U; i
< hhcd
->Init
.Host_channels
; i
++)
571 if ((interrupt
& (1UL << (i
& 0xFU
))) != 0U)
573 if ((USBx_HC(i
)->HCCHAR
& USB_OTG_HCCHAR_EPDIR
) == USB_OTG_HCCHAR_EPDIR
)
575 HCD_HC_IN_IRQHandler(hhcd
, (uint8_t)i
);
579 HCD_HC_OUT_IRQHandler(hhcd
, (uint8_t)i
);
583 __HAL_HCD_CLEAR_FLAG(hhcd
, USB_OTG_GINTSTS_HCINT
);
586 /* Handle Rx Queue Level Interrupts */
587 if ((__HAL_HCD_GET_FLAG(hhcd
, USB_OTG_GINTSTS_RXFLVL
)) != 0U)
589 USB_MASK_INTERRUPT(hhcd
->Instance
, USB_OTG_GINTSTS_RXFLVL
);
591 HCD_RXQLVL_IRQHandler(hhcd
);
593 USB_UNMASK_INTERRUPT(hhcd
->Instance
, USB_OTG_GINTSTS_RXFLVL
);
599 * @brief SOF callback.
600 * @param hhcd HCD handle
603 __weak
void HAL_HCD_SOF_Callback(HCD_HandleTypeDef
*hhcd
)
605 /* Prevent unused argument(s) compilation warning */
608 /* NOTE : This function should not be modified, when the callback is needed,
609 the HAL_HCD_SOF_Callback could be implemented in the user file
614 * @brief Connection Event callback.
615 * @param hhcd HCD handle
618 __weak
void HAL_HCD_Connect_Callback(HCD_HandleTypeDef
*hhcd
)
620 /* Prevent unused argument(s) compilation warning */
623 /* NOTE : This function should not be modified, when the callback is needed,
624 the HAL_HCD_Connect_Callback could be implemented in the user file
629 * @brief Disconnection Event callback.
630 * @param hhcd HCD handle
633 __weak
void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef
*hhcd
)
635 /* Prevent unused argument(s) compilation warning */
638 /* NOTE : This function should not be modified, when the callback is needed,
639 the HAL_HCD_Disconnect_Callback could be implemented in the user file
644 * @brief Port Enabled Event callback.
645 * @param hhcd HCD handle
648 __weak
void HAL_HCD_PortEnabled_Callback(HCD_HandleTypeDef
*hhcd
)
650 /* Prevent unused argument(s) compilation warning */
653 /* NOTE : This function should not be modified, when the callback is needed,
654 the HAL_HCD_Disconnect_Callback could be implemented in the user file
659 * @brief Port Disabled Event callback.
660 * @param hhcd HCD handle
663 __weak
void HAL_HCD_PortDisabled_Callback(HCD_HandleTypeDef
*hhcd
)
665 /* Prevent unused argument(s) compilation warning */
668 /* NOTE : This function should not be modified, when the callback is needed,
669 the HAL_HCD_Disconnect_Callback could be implemented in the user file
674 * @brief Notify URB state change callback.
675 * @param hhcd HCD handle
676 * @param chnum Channel number.
677 * This parameter can be a value from 1 to 15
679 * This parameter can be one of these values:
688 __weak
void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef
*hhcd
, uint8_t chnum
, HCD_URBStateTypeDef urb_state
)
690 /* Prevent unused argument(s) compilation warning */
695 /* NOTE : This function should not be modified, when the callback is needed,
696 the HAL_HCD_HC_NotifyURBChange_Callback could be implemented in the user file
700 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
702 * @brief Register a User USB HCD Callback
703 * To be used instead of the weak predefined callback
704 * @param hhcd USB HCD handle
705 * @param CallbackID ID of the callback to be registered
706 * This parameter can be one of the following values:
707 * @arg @ref HAL_HCD_SOF_CB_ID USB HCD SOF callback ID
708 * @arg @ref HAL_HCD_CONNECT_CB_ID USB HCD Connect callback ID
709 * @arg @ref HAL_HCD_DISCONNECT_CB_ID OTG HCD Disconnect callback ID
710 * @arg @ref HAL_HCD_PORT_ENABLED_CB_ID USB HCD Port Enable callback ID
711 * @arg @ref HAL_HCD_PORT_DISABLED_CB_ID USB HCD Port Disable callback ID
712 * @arg @ref HAL_HCD_MSPINIT_CB_ID MspDeInit callback ID
713 * @arg @ref HAL_HCD_MSPDEINIT_CB_ID MspDeInit callback ID
714 * @param pCallback pointer to the Callback function
717 HAL_StatusTypeDef
HAL_HCD_RegisterCallback(HCD_HandleTypeDef
*hhcd
, HAL_HCD_CallbackIDTypeDef CallbackID
, pHCD_CallbackTypeDef pCallback
)
719 HAL_StatusTypeDef status
= HAL_OK
;
721 if (pCallback
== NULL
)
723 /* Update the error code */
724 hhcd
->ErrorCode
|= HAL_HCD_ERROR_INVALID_CALLBACK
;
730 if (hhcd
->State
== HAL_HCD_STATE_READY
)
734 case HAL_HCD_SOF_CB_ID
:
735 hhcd
->SOFCallback
= pCallback
;
738 case HAL_HCD_CONNECT_CB_ID
:
739 hhcd
->ConnectCallback
= pCallback
;
742 case HAL_HCD_DISCONNECT_CB_ID
:
743 hhcd
->DisconnectCallback
= pCallback
;
746 case HAL_HCD_PORT_ENABLED_CB_ID
:
747 hhcd
->PortEnabledCallback
= pCallback
;
750 case HAL_HCD_PORT_DISABLED_CB_ID
:
751 hhcd
->PortDisabledCallback
= pCallback
;
754 case HAL_HCD_MSPINIT_CB_ID
:
755 hhcd
->MspInitCallback
= pCallback
;
758 case HAL_HCD_MSPDEINIT_CB_ID
:
759 hhcd
->MspDeInitCallback
= pCallback
;
763 /* Update the error code */
764 hhcd
->ErrorCode
|= HAL_HCD_ERROR_INVALID_CALLBACK
;
765 /* Return error status */
770 else if (hhcd
->State
== HAL_HCD_STATE_RESET
)
774 case HAL_HCD_MSPINIT_CB_ID
:
775 hhcd
->MspInitCallback
= pCallback
;
778 case HAL_HCD_MSPDEINIT_CB_ID
:
779 hhcd
->MspDeInitCallback
= pCallback
;
783 /* Update the error code */
784 hhcd
->ErrorCode
|= HAL_HCD_ERROR_INVALID_CALLBACK
;
785 /* Return error status */
792 /* Update the error code */
793 hhcd
->ErrorCode
|= HAL_HCD_ERROR_INVALID_CALLBACK
;
794 /* Return error status */
804 * @brief Unregister an USB HCD Callback
805 * USB HCD callabck is redirected to the weak predefined callback
806 * @param hhcd USB HCD handle
807 * @param CallbackID ID of the callback to be unregistered
808 * This parameter can be one of the following values:
809 * @arg @ref HAL_HCD_SOF_CB_ID USB HCD SOF callback ID
810 * @arg @ref HAL_HCD_CONNECT_CB_ID USB HCD Connect callback ID
811 * @arg @ref HAL_HCD_DISCONNECT_CB_ID OTG HCD Disconnect callback ID
812 * @arg @ref HAL_HCD_PORT_ENABLED_CB_ID USB HCD Port Enabled callback ID
813 * @arg @ref HAL_HCD_PORT_DISABLED_CB_ID USB HCD Port Disabled callback ID
814 * @arg @ref HAL_HCD_MSPINIT_CB_ID MspDeInit callback ID
815 * @arg @ref HAL_HCD_MSPDEINIT_CB_ID MspDeInit callback ID
818 HAL_StatusTypeDef
HAL_HCD_UnRegisterCallback(HCD_HandleTypeDef
*hhcd
, HAL_HCD_CallbackIDTypeDef CallbackID
)
820 HAL_StatusTypeDef status
= HAL_OK
;
825 /* Setup Legacy weak Callbacks */
826 if (hhcd
->State
== HAL_HCD_STATE_READY
)
830 case HAL_HCD_SOF_CB_ID
:
831 hhcd
->SOFCallback
= HAL_HCD_SOF_Callback
;
834 case HAL_HCD_CONNECT_CB_ID
:
835 hhcd
->ConnectCallback
= HAL_HCD_Connect_Callback
;
838 case HAL_HCD_DISCONNECT_CB_ID
:
839 hhcd
->DisconnectCallback
= HAL_HCD_Disconnect_Callback
;
842 case HAL_HCD_PORT_ENABLED_CB_ID
:
843 hhcd
->PortEnabledCallback
= HAL_HCD_PortEnabled_Callback
;
846 case HAL_HCD_PORT_DISABLED_CB_ID
:
847 hhcd
->PortDisabledCallback
= HAL_HCD_PortDisabled_Callback
;
850 case HAL_HCD_MSPINIT_CB_ID
:
851 hhcd
->MspInitCallback
= HAL_HCD_MspInit
;
854 case HAL_HCD_MSPDEINIT_CB_ID
:
855 hhcd
->MspDeInitCallback
= HAL_HCD_MspDeInit
;
859 /* Update the error code */
860 hhcd
->ErrorCode
|= HAL_HCD_ERROR_INVALID_CALLBACK
;
862 /* Return error status */
867 else if (hhcd
->State
== HAL_HCD_STATE_RESET
)
871 case HAL_HCD_MSPINIT_CB_ID
:
872 hhcd
->MspInitCallback
= HAL_HCD_MspInit
;
875 case HAL_HCD_MSPDEINIT_CB_ID
:
876 hhcd
->MspDeInitCallback
= HAL_HCD_MspDeInit
;
880 /* Update the error code */
881 hhcd
->ErrorCode
|= HAL_HCD_ERROR_INVALID_CALLBACK
;
883 /* Return error status */
890 /* Update the error code */
891 hhcd
->ErrorCode
|= HAL_HCD_ERROR_INVALID_CALLBACK
;
893 /* Return error status */
903 * @brief Register USB HCD Host Channel Notify URB Change Callback
904 * To be used instead of the weak HAL_HCD_HC_NotifyURBChange_Callback() predefined callback
905 * @param hhcd HCD handle
906 * @param pCallback pointer to the USB HCD Host Channel Notify URB Change Callback function
909 HAL_StatusTypeDef
HAL_HCD_RegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef
*hhcd
, pHCD_HC_NotifyURBChangeCallbackTypeDef pCallback
)
911 HAL_StatusTypeDef status
= HAL_OK
;
913 if (pCallback
== NULL
)
915 /* Update the error code */
916 hhcd
->ErrorCode
|= HAL_HCD_ERROR_INVALID_CALLBACK
;
924 if (hhcd
->State
== HAL_HCD_STATE_READY
)
926 hhcd
->HC_NotifyURBChangeCallback
= pCallback
;
930 /* Update the error code */
931 hhcd
->ErrorCode
|= HAL_HCD_ERROR_INVALID_CALLBACK
;
933 /* Return error status */
944 * @brief UnRegister the USB HCD Host Channel Notify URB Change Callback
945 * USB HCD Host Channel Notify URB Change Callback is redirected to the weak HAL_HCD_HC_NotifyURBChange_Callback() predefined callback
946 * @param hhcd HCD handle
949 HAL_StatusTypeDef
HAL_HCD_UnRegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef
*hhcd
)
951 HAL_StatusTypeDef status
= HAL_OK
;
956 if (hhcd
->State
== HAL_HCD_STATE_READY
)
958 hhcd
->HC_NotifyURBChangeCallback
= HAL_HCD_HC_NotifyURBChange_Callback
; /* Legacy weak DataOutStageCallback */
962 /* Update the error code */
963 hhcd
->ErrorCode
|= HAL_HCD_ERROR_INVALID_CALLBACK
;
965 /* Return error status */
974 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
980 /** @defgroup HCD_Exported_Functions_Group3 Peripheral Control functions
981 * @brief Management functions
984 ===============================================================================
985 ##### Peripheral Control functions #####
986 ===============================================================================
988 This subsection provides a set of functions allowing to control the HCD data
996 * @brief Start the host driver.
997 * @param hhcd HCD handle
1000 HAL_StatusTypeDef
HAL_HCD_Start(HCD_HandleTypeDef
*hhcd
)
1003 __HAL_HCD_ENABLE(hhcd
);
1004 (void)USB_DriveVbus(hhcd
->Instance
, 1U);
1010 * @brief Stop the host driver.
1011 * @param hhcd HCD handle
1012 * @retval HAL status
1015 HAL_StatusTypeDef
HAL_HCD_Stop(HCD_HandleTypeDef
*hhcd
)
1018 (void)USB_StopHost(hhcd
->Instance
);
1024 * @brief Reset the host port.
1025 * @param hhcd HCD handle
1026 * @retval HAL status
1028 HAL_StatusTypeDef
HAL_HCD_ResetPort(HCD_HandleTypeDef
*hhcd
)
1030 return (USB_ResetPort(hhcd
->Instance
));
1037 /** @defgroup HCD_Exported_Functions_Group4 Peripheral State functions
1038 * @brief Peripheral State functions
1041 ===============================================================================
1042 ##### Peripheral State functions #####
1043 ===============================================================================
1045 This subsection permits to get in run-time the status of the peripheral
1053 * @brief Return the HCD handle state.
1054 * @param hhcd HCD handle
1057 HCD_StateTypeDef
HAL_HCD_GetState(HCD_HandleTypeDef
*hhcd
)
1063 * @brief Return URB state for a channel.
1064 * @param hhcd HCD handle
1065 * @param chnum Channel number.
1066 * This parameter can be a value from 1 to 15
1067 * @retval URB state.
1068 * This parameter can be one of these values:
1076 HCD_URBStateTypeDef
HAL_HCD_HC_GetURBState(HCD_HandleTypeDef
*hhcd
, uint8_t chnum
)
1078 return hhcd
->hc
[chnum
].urb_state
;
1083 * @brief Return the last host transfer size.
1084 * @param hhcd HCD handle
1085 * @param chnum Channel number.
1086 * This parameter can be a value from 1 to 15
1087 * @retval last transfer size in byte
1089 uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef
*hhcd
, uint8_t chnum
)
1091 return hhcd
->hc
[chnum
].xfer_count
;
1095 * @brief Return the Host Channel state.
1096 * @param hhcd HCD handle
1097 * @param chnum Channel number.
1098 * This parameter can be a value from 1 to 15
1099 * @retval Host channel state
1100 * This parameter can be one of these values:
1111 HCD_HCStateTypeDef
HAL_HCD_HC_GetState(HCD_HandleTypeDef
*hhcd
, uint8_t chnum
)
1113 return hhcd
->hc
[chnum
].state
;
1117 * @brief Return the current Host frame number.
1118 * @param hhcd HCD handle
1119 * @retval Current Host frame number
1121 uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef
*hhcd
)
1123 return (USB_GetCurrentFrame(hhcd
->Instance
));
1127 * @brief Return the Host enumeration speed.
1128 * @param hhcd HCD handle
1129 * @retval Enumeration speed
1131 uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef
*hhcd
)
1133 return (USB_GetHostSpeed(hhcd
->Instance
));
1144 /** @addtogroup HCD_Private_Functions
1148 * @brief Handle Host Channel IN interrupt requests.
1149 * @param hhcd HCD handle
1150 * @param chnum Channel number.
1151 * This parameter can be a value from 1 to 15
1154 static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef
*hhcd
, uint8_t chnum
)
1156 USB_OTG_GlobalTypeDef
*USBx
= hhcd
->Instance
;
1157 uint32_t USBx_BASE
= (uint32_t)USBx
;
1158 uint32_t ch_num
= (uint32_t)chnum
;
1162 if ((USBx_HC(ch_num
)->HCINT
& USB_OTG_HCINT_AHBERR
) == USB_OTG_HCINT_AHBERR
)
1164 __HAL_HCD_CLEAR_HC_INT(ch_num
, USB_OTG_HCINT_AHBERR
);
1165 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num
);
1167 else if ((USBx_HC(ch_num
)->HCINT
& USB_OTG_HCINT_ACK
) == USB_OTG_HCINT_ACK
)
1169 __HAL_HCD_CLEAR_HC_INT(ch_num
, USB_OTG_HCINT_ACK
);
1171 else if ((USBx_HC(ch_num
)->HCINT
& USB_OTG_HCINT_STALL
) == USB_OTG_HCINT_STALL
)
1173 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num
);
1174 hhcd
->hc
[ch_num
].state
= HC_STALL
;
1175 __HAL_HCD_CLEAR_HC_INT(ch_num
, USB_OTG_HCINT_NAK
);
1176 __HAL_HCD_CLEAR_HC_INT(ch_num
, USB_OTG_HCINT_STALL
);
1177 (void)USB_HC_Halt(hhcd
->Instance
, (uint8_t)ch_num
);
1179 else if ((USBx_HC(ch_num
)->HCINT
& USB_OTG_HCINT_DTERR
) == USB_OTG_HCINT_DTERR
)
1181 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num
);
1182 (void)USB_HC_Halt(hhcd
->Instance
, (uint8_t)ch_num
);
1183 __HAL_HCD_CLEAR_HC_INT(ch_num
, USB_OTG_HCINT_NAK
);
1184 hhcd
->hc
[ch_num
].state
= HC_DATATGLERR
;
1185 __HAL_HCD_CLEAR_HC_INT(ch_num
, USB_OTG_HCINT_DTERR
);
1192 if ((USBx_HC(ch_num
)->HCINT
& USB_OTG_HCINT_FRMOR
) == USB_OTG_HCINT_FRMOR
)
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_FRMOR
);
1198 else if ((USBx_HC(ch_num
)->HCINT
& USB_OTG_HCINT_XFRC
) == USB_OTG_HCINT_XFRC
)
1200 if (hhcd
->Init
.dma_enable
!= 0U)
1202 hhcd
->hc
[ch_num
].xfer_count
= hhcd
->hc
[ch_num
].xfer_len
- \
1203 (USBx_HC(ch_num
)->HCTSIZ
& USB_OTG_HCTSIZ_XFRSIZ
);
1206 hhcd
->hc
[ch_num
].state
= HC_XFRC
;
1207 hhcd
->hc
[ch_num
].ErrCnt
= 0U;
1208 __HAL_HCD_CLEAR_HC_INT(ch_num
, USB_OTG_HCINT_XFRC
);
1210 if ((hhcd
->hc
[ch_num
].ep_type
== EP_TYPE_CTRL
) ||
1211 (hhcd
->hc
[ch_num
].ep_type
== EP_TYPE_BULK
))
1213 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num
);
1214 (void)USB_HC_Halt(hhcd
->Instance
, (uint8_t)ch_num
);
1215 __HAL_HCD_CLEAR_HC_INT(ch_num
, USB_OTG_HCINT_NAK
);
1217 else if (hhcd
->hc
[ch_num
].ep_type
== EP_TYPE_INTR
)
1219 USBx_HC(ch_num
)->HCCHAR
|= USB_OTG_HCCHAR_ODDFRM
;
1220 hhcd
->hc
[ch_num
].urb_state
= URB_DONE
;
1222 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1223 hhcd
->HC_NotifyURBChangeCallback(hhcd
, (uint8_t)ch_num
, hhcd
->hc
[ch_num
].urb_state
);
1225 HAL_HCD_HC_NotifyURBChange_Callback(hhcd
, (uint8_t)ch_num
, hhcd
->hc
[ch_num
].urb_state
);
1226 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1232 hhcd
->hc
[ch_num
].toggle_in
^= 1U;
1235 else if ((USBx_HC(ch_num
)->HCINT
& USB_OTG_HCINT_CHH
) == USB_OTG_HCINT_CHH
)
1237 __HAL_HCD_MASK_HALT_HC_INT(ch_num
);
1239 if (hhcd
->hc
[ch_num
].state
== HC_XFRC
)
1241 hhcd
->hc
[ch_num
].urb_state
= URB_DONE
;
1243 else if (hhcd
->hc
[ch_num
].state
== HC_STALL
)
1245 hhcd
->hc
[ch_num
].urb_state
= URB_STALL
;
1247 else if ((hhcd
->hc
[ch_num
].state
== HC_XACTERR
) ||
1248 (hhcd
->hc
[ch_num
].state
== HC_DATATGLERR
))
1250 hhcd
->hc
[ch_num
].ErrCnt
++;
1251 if (hhcd
->hc
[ch_num
].ErrCnt
> 3U)
1253 hhcd
->hc
[ch_num
].ErrCnt
= 0U;
1254 hhcd
->hc
[ch_num
].urb_state
= URB_ERROR
;
1258 hhcd
->hc
[ch_num
].urb_state
= URB_NOTREADY
;
1261 /* re-activate the channel */
1262 tmpreg
= USBx_HC(ch_num
)->HCCHAR
;
1263 tmpreg
&= ~USB_OTG_HCCHAR_CHDIS
;
1264 tmpreg
|= USB_OTG_HCCHAR_CHENA
;
1265 USBx_HC(ch_num
)->HCCHAR
= tmpreg
;
1267 else if (hhcd
->hc
[ch_num
].state
== HC_NAK
)
1269 hhcd
->hc
[ch_num
].urb_state
= URB_NOTREADY
;
1270 /* re-activate the channel */
1271 tmpreg
= USBx_HC(ch_num
)->HCCHAR
;
1272 tmpreg
&= ~USB_OTG_HCCHAR_CHDIS
;
1273 tmpreg
|= USB_OTG_HCCHAR_CHENA
;
1274 USBx_HC(ch_num
)->HCCHAR
= tmpreg
;
1280 __HAL_HCD_CLEAR_HC_INT(ch_num
, USB_OTG_HCINT_CHH
);
1281 HAL_HCD_HC_NotifyURBChange_Callback(hhcd
, (uint8_t)ch_num
, hhcd
->hc
[ch_num
].urb_state
);
1283 else if ((USBx_HC(ch_num
)->HCINT
& USB_OTG_HCINT_TXERR
) == USB_OTG_HCINT_TXERR
)
1285 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num
);
1286 hhcd
->hc
[ch_num
].ErrCnt
++;
1287 hhcd
->hc
[ch_num
].state
= HC_XACTERR
;
1288 (void)USB_HC_Halt(hhcd
->Instance
, (uint8_t)ch_num
);
1289 __HAL_HCD_CLEAR_HC_INT(ch_num
, USB_OTG_HCINT_TXERR
);
1291 else if ((USBx_HC(ch_num
)->HCINT
& USB_OTG_HCINT_NAK
) == USB_OTG_HCINT_NAK
)
1293 if (hhcd
->hc
[ch_num
].ep_type
== EP_TYPE_INTR
)
1295 hhcd
->hc
[ch_num
].ErrCnt
= 0U;
1296 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num
);
1297 (void)USB_HC_Halt(hhcd
->Instance
, (uint8_t)ch_num
);
1299 else if ((hhcd
->hc
[ch_num
].ep_type
== EP_TYPE_CTRL
) ||
1300 (hhcd
->hc
[ch_num
].ep_type
== EP_TYPE_BULK
))
1302 hhcd
->hc
[ch_num
].ErrCnt
= 0U;
1303 if (hhcd
->Init
.dma_enable
== 0U)
1305 hhcd
->hc
[ch_num
].state
= HC_NAK
;
1306 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num
);
1307 (void)USB_HC_Halt(hhcd
->Instance
, (uint8_t)ch_num
);
1314 __HAL_HCD_CLEAR_HC_INT(ch_num
, USB_OTG_HCINT_NAK
);
1323 * @brief Handle Host Channel OUT interrupt requests.
1324 * @param hhcd HCD handle
1325 * @param chnum Channel number.
1326 * This parameter can be a value from 1 to 15
1329 static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef
*hhcd
, uint8_t chnum
)
1331 USB_OTG_GlobalTypeDef
*USBx
= hhcd
->Instance
;
1332 uint32_t USBx_BASE
= (uint32_t)USBx
;
1333 uint32_t ch_num
= (uint32_t)chnum
;
1336 if ((USBx_HC(ch_num
)->HCINT
& USB_OTG_HCINT_AHBERR
) == USB_OTG_HCINT_AHBERR
)
1338 __HAL_HCD_CLEAR_HC_INT(ch_num
, USB_OTG_HCINT_AHBERR
);
1339 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num
);
1341 else if ((USBx_HC(ch_num
)->HCINT
& USB_OTG_HCINT_ACK
) == USB_OTG_HCINT_ACK
)
1343 __HAL_HCD_CLEAR_HC_INT(ch_num
, USB_OTG_HCINT_ACK
);
1345 if (hhcd
->hc
[ch_num
].do_ping
== 1U)
1347 hhcd
->hc
[ch_num
].do_ping
= 0U;
1348 hhcd
->hc
[ch_num
].urb_state
= URB_NOTREADY
;
1349 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num
);
1350 (void)USB_HC_Halt(hhcd
->Instance
, (uint8_t)ch_num
);
1353 else if ((USBx_HC(ch_num
)->HCINT
& USB_OTG_HCINT_NYET
) == USB_OTG_HCINT_NYET
)
1355 hhcd
->hc
[ch_num
].state
= HC_NYET
;
1356 hhcd
->hc
[ch_num
].do_ping
= 1U;
1357 hhcd
->hc
[ch_num
].ErrCnt
= 0U;
1358 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num
);
1359 (void)USB_HC_Halt(hhcd
->Instance
, (uint8_t)ch_num
);
1360 __HAL_HCD_CLEAR_HC_INT(ch_num
, USB_OTG_HCINT_NYET
);
1362 else if ((USBx_HC(ch_num
)->HCINT
& USB_OTG_HCINT_FRMOR
) == USB_OTG_HCINT_FRMOR
)
1364 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num
);
1365 (void)USB_HC_Halt(hhcd
->Instance
, (uint8_t)ch_num
);
1366 __HAL_HCD_CLEAR_HC_INT(ch_num
, USB_OTG_HCINT_FRMOR
);
1368 else if ((USBx_HC(ch_num
)->HCINT
& USB_OTG_HCINT_XFRC
) == USB_OTG_HCINT_XFRC
)
1370 hhcd
->hc
[ch_num
].ErrCnt
= 0U;
1371 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num
);
1372 (void)USB_HC_Halt(hhcd
->Instance
, (uint8_t)ch_num
);
1373 __HAL_HCD_CLEAR_HC_INT(ch_num
, USB_OTG_HCINT_XFRC
);
1374 hhcd
->hc
[ch_num
].state
= HC_XFRC
;
1376 else if ((USBx_HC(ch_num
)->HCINT
& USB_OTG_HCINT_STALL
) == USB_OTG_HCINT_STALL
)
1378 __HAL_HCD_CLEAR_HC_INT(ch_num
, USB_OTG_HCINT_STALL
);
1379 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num
);
1380 (void)USB_HC_Halt(hhcd
->Instance
, (uint8_t)ch_num
);
1381 hhcd
->hc
[ch_num
].state
= HC_STALL
;
1383 else if ((USBx_HC(ch_num
)->HCINT
& USB_OTG_HCINT_NAK
) == USB_OTG_HCINT_NAK
)
1385 hhcd
->hc
[ch_num
].ErrCnt
= 0U;
1386 hhcd
->hc
[ch_num
].state
= HC_NAK
;
1388 if (hhcd
->hc
[ch_num
].do_ping
== 0U)
1390 if (hhcd
->hc
[ch_num
].speed
== HCD_SPEED_HIGH
)
1392 hhcd
->hc
[ch_num
].do_ping
= 1U;
1396 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num
);
1397 (void)USB_HC_Halt(hhcd
->Instance
, (uint8_t)ch_num
);
1398 __HAL_HCD_CLEAR_HC_INT(ch_num
, USB_OTG_HCINT_NAK
);
1400 else if ((USBx_HC(ch_num
)->HCINT
& USB_OTG_HCINT_TXERR
) == USB_OTG_HCINT_TXERR
)
1402 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num
);
1403 (void)USB_HC_Halt(hhcd
->Instance
, (uint8_t)ch_num
);
1404 hhcd
->hc
[ch_num
].state
= HC_XACTERR
;
1405 __HAL_HCD_CLEAR_HC_INT(ch_num
, USB_OTG_HCINT_TXERR
);
1407 else if ((USBx_HC(ch_num
)->HCINT
& USB_OTG_HCINT_DTERR
) == USB_OTG_HCINT_DTERR
)
1409 __HAL_HCD_UNMASK_HALT_HC_INT(ch_num
);
1410 (void)USB_HC_Halt(hhcd
->Instance
, (uint8_t)ch_num
);
1411 __HAL_HCD_CLEAR_HC_INT(ch_num
, USB_OTG_HCINT_NAK
);
1412 __HAL_HCD_CLEAR_HC_INT(ch_num
, USB_OTG_HCINT_DTERR
);
1413 hhcd
->hc
[ch_num
].state
= HC_DATATGLERR
;
1415 else if ((USBx_HC(ch_num
)->HCINT
& USB_OTG_HCINT_CHH
) == USB_OTG_HCINT_CHH
)
1417 __HAL_HCD_MASK_HALT_HC_INT(ch_num
);
1419 if (hhcd
->hc
[ch_num
].state
== HC_XFRC
)
1421 hhcd
->hc
[ch_num
].urb_state
= URB_DONE
;
1422 if ((hhcd
->hc
[ch_num
].ep_type
== EP_TYPE_BULK
) ||
1423 (hhcd
->hc
[ch_num
].ep_type
== EP_TYPE_INTR
))
1425 hhcd
->hc
[ch_num
].toggle_out
^= 1U;
1428 else if (hhcd
->hc
[ch_num
].state
== HC_NAK
)
1430 hhcd
->hc
[ch_num
].urb_state
= URB_NOTREADY
;
1432 else if (hhcd
->hc
[ch_num
].state
== HC_NYET
)
1434 hhcd
->hc
[ch_num
].urb_state
= URB_NOTREADY
;
1436 else if (hhcd
->hc
[ch_num
].state
== HC_STALL
)
1438 hhcd
->hc
[ch_num
].urb_state
= URB_STALL
;
1440 else if ((hhcd
->hc
[ch_num
].state
== HC_XACTERR
) ||
1441 (hhcd
->hc
[ch_num
].state
== HC_DATATGLERR
))
1443 hhcd
->hc
[ch_num
].ErrCnt
++;
1444 if (hhcd
->hc
[ch_num
].ErrCnt
> 3U)
1446 hhcd
->hc
[ch_num
].ErrCnt
= 0U;
1447 hhcd
->hc
[ch_num
].urb_state
= URB_ERROR
;
1451 hhcd
->hc
[ch_num
].urb_state
= URB_NOTREADY
;
1454 /* re-activate the channel */
1455 tmpreg
= USBx_HC(ch_num
)->HCCHAR
;
1456 tmpreg
&= ~USB_OTG_HCCHAR_CHDIS
;
1457 tmpreg
|= USB_OTG_HCCHAR_CHENA
;
1458 USBx_HC(ch_num
)->HCCHAR
= tmpreg
;
1465 __HAL_HCD_CLEAR_HC_INT(ch_num
, USB_OTG_HCINT_CHH
);
1466 HAL_HCD_HC_NotifyURBChange_Callback(hhcd
, (uint8_t)ch_num
, hhcd
->hc
[ch_num
].urb_state
);
1475 * @brief Handle Rx Queue Level interrupt requests.
1476 * @param hhcd HCD handle
1479 static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef
*hhcd
)
1481 USB_OTG_GlobalTypeDef
*USBx
= hhcd
->Instance
;
1482 uint32_t USBx_BASE
= (uint32_t)USBx
;
1489 temp
= hhcd
->Instance
->GRXSTSP
;
1490 ch_num
= temp
& USB_OTG_GRXSTSP_EPNUM
;
1491 pktsts
= (temp
& USB_OTG_GRXSTSP_PKTSTS
) >> 17;
1492 pktcnt
= (temp
& USB_OTG_GRXSTSP_BCNT
) >> 4;
1496 case GRXSTS_PKTSTS_IN
:
1497 /* Read the data into the host buffer. */
1498 if ((pktcnt
> 0U) && (hhcd
->hc
[ch_num
].xfer_buff
!= (void *)0))
1500 (void)USB_ReadPacket(hhcd
->Instance
, hhcd
->hc
[ch_num
].xfer_buff
, (uint16_t)pktcnt
);
1502 /*manage multiple Xfer */
1503 hhcd
->hc
[ch_num
].xfer_buff
+= pktcnt
;
1504 hhcd
->hc
[ch_num
].xfer_count
+= pktcnt
;
1506 if ((USBx_HC(ch_num
)->HCTSIZ
& USB_OTG_HCTSIZ_PKTCNT
) > 0U)
1508 /* re-activate the channel when more packets are expected */
1509 tmpreg
= USBx_HC(ch_num
)->HCCHAR
;
1510 tmpreg
&= ~USB_OTG_HCCHAR_CHDIS
;
1511 tmpreg
|= USB_OTG_HCCHAR_CHENA
;
1512 USBx_HC(ch_num
)->HCCHAR
= tmpreg
;
1513 hhcd
->hc
[ch_num
].toggle_in
^= 1U;
1518 case GRXSTS_PKTSTS_DATA_TOGGLE_ERR
:
1521 case GRXSTS_PKTSTS_IN_XFER_COMP
:
1522 case GRXSTS_PKTSTS_CH_HALTED
:
1529 * @brief Handle Host Port interrupt requests.
1530 * @param hhcd HCD handle
1533 static void HCD_Port_IRQHandler(HCD_HandleTypeDef
*hhcd
)
1535 USB_OTG_GlobalTypeDef
*USBx
= hhcd
->Instance
;
1536 uint32_t USBx_BASE
= (uint32_t)USBx
;
1537 __IO
uint32_t hprt0
, hprt0_dup
;
1539 /* Handle Host Port Interrupts */
1541 hprt0_dup
= USBx_HPRT0
;
1543 hprt0_dup
&= ~(USB_OTG_HPRT_PENA
| USB_OTG_HPRT_PCDET
| \
1544 USB_OTG_HPRT_PENCHNG
| USB_OTG_HPRT_POCCHNG
);
1546 /* Check whether Port Connect detected */
1547 if ((hprt0
& USB_OTG_HPRT_PCDET
) == USB_OTG_HPRT_PCDET
)
1549 if ((hprt0
& USB_OTG_HPRT_PCSTS
) == USB_OTG_HPRT_PCSTS
)
1551 USB_MASK_INTERRUPT(hhcd
->Instance
, USB_OTG_GINTSTS_DISCINT
);
1553 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1554 hhcd
->ConnectCallback(hhcd
);
1556 HAL_HCD_Connect_Callback(hhcd
);
1557 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1559 hprt0_dup
|= USB_OTG_HPRT_PCDET
;
1562 /* Check whether Port Enable Changed */
1563 if ((hprt0
& USB_OTG_HPRT_PENCHNG
) == USB_OTG_HPRT_PENCHNG
)
1565 hprt0_dup
|= USB_OTG_HPRT_PENCHNG
;
1567 if ((hprt0
& USB_OTG_HPRT_PENA
) == USB_OTG_HPRT_PENA
)
1569 if (hhcd
->Init
.phy_itface
== USB_OTG_EMBEDDED_PHY
)
1571 if ((hprt0
& USB_OTG_HPRT_PSPD
) == (HPRT0_PRTSPD_LOW_SPEED
<< 17))
1573 (void)USB_InitFSLSPClkSel(hhcd
->Instance
, HCFG_6_MHZ
);
1577 (void)USB_InitFSLSPClkSel(hhcd
->Instance
, HCFG_48_MHZ
);
1582 if (hhcd
->Init
.speed
== HCD_SPEED_FULL
)
1584 USBx_HOST
->HFIR
= 60000U;
1587 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1588 hhcd
->PortEnabledCallback(hhcd
);
1589 hhcd
->ConnectCallback(hhcd
);
1591 HAL_HCD_PortEnabled_Callback(hhcd
);
1592 HAL_HCD_Connect_Callback(hhcd
);
1593 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1598 #if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
1599 hhcd
->PortDisabledCallback(hhcd
);
1601 HAL_HCD_PortDisabled_Callback(hhcd
);
1602 #endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
1605 USBx_HPRT0
&= ~(USB_OTG_HPRT_PENA
| USB_OTG_HPRT_PCDET
| \
1606 USB_OTG_HPRT_PENCHNG
| USB_OTG_HPRT_POCCHNG
);
1608 USB_UNMASK_INTERRUPT(hhcd
->Instance
, USB_OTG_GINTSTS_DISCINT
);
1612 /* Check for an overcurrent */
1613 if ((hprt0
& USB_OTG_HPRT_POCCHNG
) == USB_OTG_HPRT_POCCHNG
)
1615 hprt0_dup
|= USB_OTG_HPRT_POCCHNG
;
1618 /* Clear Port Interrupts */
1619 USBx_HPRT0
= hprt0_dup
;
1630 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
1631 #endif /* HAL_HCD_MODULE_ENABLED */
1641 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/