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