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