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