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