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