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