comparison Common/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hcd.c @ 128:c78bcbd5deda FlipDisplay

Added current STM32 standandard libraries in version independend folder structure
author Ideenmodellierer
date Sun, 17 Feb 2019 21:12:22 +0100
parents
children
comparison
equal deleted inserted replaced
127:1369f8660eaa 128:c78bcbd5deda
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>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
46 *
47 * Redistribution and use in source and binary forms, with or without modification,
48 * are permitted provided that the following conditions are met:
49 * 1. Redistributions of source code must retain the above copyright notice,
50 * this list of conditions and the following disclaimer.
51 * 2. Redistributions in binary form must reproduce the above copyright notice,
52 * this list of conditions and the following disclaimer in the documentation
53 * and/or other materials provided with the distribution.
54 * 3. Neither the name of STMicroelectronics nor the names of its contributors
55 * may be used to endorse or promote products derived from this software
56 * without specific prior written permission.
57 *
58 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
59 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
61 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
64 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
65 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
66 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
67 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
68 *
69 ******************************************************************************
70 */
71
72 /* Includes ------------------------------------------------------------------*/
73 #include "stm32f4xx_hal.h"
74
75 /** @addtogroup STM32F4xx_HAL_Driver
76 * @{
77 */
78
79 /** @defgroup HCD HCD
80 * @brief HCD HAL module driver
81 * @{
82 */
83
84 #ifdef HAL_HCD_MODULE_ENABLED
85 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || \
86 defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || \
87 defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) || \
88 defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || \
89 defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
90 /* Private typedef -----------------------------------------------------------*/
91 /* Private define ------------------------------------------------------------*/
92 /* Private macro -------------------------------------------------------------*/
93 /* Private variables ---------------------------------------------------------*/
94 /* Private function prototypes -----------------------------------------------*/
95 /** @defgroup HCD_Private_Functions HCD Private Functions
96 * @{
97 */
98 static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
99 static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum);
100 static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd);
101 static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd);
102 /**
103 * @}
104 */
105
106 /* Exported functions --------------------------------------------------------*/
107 /** @defgroup HCD_Exported_Functions HCD Exported Functions
108 * @{
109 */
110
111 /** @defgroup HCD_Exported_Functions_Group1 Initialization and de-initialization functions
112 * @brief Initialization and Configuration functions
113 *
114 @verbatim
115 ===============================================================================
116 ##### Initialization and de-initialization functions #####
117 ===============================================================================
118 [..] This section provides functions allowing to:
119
120 @endverbatim
121 * @{
122 */
123
124 /**
125 * @brief Initialize the host driver.
126 * @param hhcd HCD handle
127 * @retval HAL status
128 */
129 HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd)
130 {
131 /* Check the HCD handle allocation */
132 if(hhcd == NULL)
133 {
134 return HAL_ERROR;
135 }
136
137 /* Check the parameters */
138 assert_param(IS_HCD_ALL_INSTANCE(hhcd->Instance));
139
140 hhcd->State = HAL_HCD_STATE_BUSY;
141
142 /* Init the low level hardware : GPIO, CLOCK, NVIC... */
143 HAL_HCD_MspInit(hhcd);
144
145 /* Disable the Interrupts */
146 __HAL_HCD_DISABLE(hhcd);
147
148 /* Init the Core (common init.) */
149 USB_CoreInit(hhcd->Instance, hhcd->Init);
150
151 /* Force Host Mode*/
152 USB_SetCurrentMode(hhcd->Instance , USB_OTG_HOST_MODE);
153
154 /* Init Host */
155 USB_HostInit(hhcd->Instance, hhcd->Init);
156
157 hhcd->State= HAL_HCD_STATE_READY;
158
159 return HAL_OK;
160 }
161
162 /**
163 * @brief Initialize a host channel.
164 * @param hhcd HCD handle
165 * @param ch_num Channel number.
166 * This parameter can be a value from 1 to 15
167 * @param epnum Endpoint number.
168 * This parameter can be a value from 1 to 15
169 * @param dev_address Current device address
170 * This parameter can be a value from 0 to 255
171 * @param speed Current device speed.
172 * This parameter can be one of these values:
173 * HCD_SPEED_HIGH: High speed mode,
174 * HCD_SPEED_FULL: Full speed mode,
175 * HCD_SPEED_LOW: Low speed mode
176 * @param ep_type Endpoint Type.
177 * This parameter can be one of these values:
178 * EP_TYPE_CTRL: Control type,
179 * EP_TYPE_ISOC: Isochronous type,
180 * EP_TYPE_BULK: Bulk type,
181 * EP_TYPE_INTR: Interrupt type
182 * @param mps Max Packet Size.
183 * This parameter can be a value from 0 to32K
184 * @retval HAL status
185 */
186 HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd,
187 uint8_t ch_num,
188 uint8_t epnum,
189 uint8_t dev_address,
190 uint8_t speed,
191 uint8_t ep_type,
192 uint16_t mps)
193 {
194 HAL_StatusTypeDef status = HAL_OK;
195
196 __HAL_LOCK(hhcd);
197
198 hhcd->hc[ch_num].dev_addr = dev_address;
199 hhcd->hc[ch_num].max_packet = mps;
200 hhcd->hc[ch_num].ch_num = ch_num;
201 hhcd->hc[ch_num].ep_type = ep_type;
202 hhcd->hc[ch_num].ep_num = epnum & 0x7F;
203 hhcd->hc[ch_num].ep_is_in = ((epnum & 0x80) == 0x80);
204 hhcd->hc[ch_num].speed = speed;
205
206 status = USB_HC_Init(hhcd->Instance,
207 ch_num,
208 epnum,
209 dev_address,
210 speed,
211 ep_type,
212 mps);
213 __HAL_UNLOCK(hhcd);
214
215 return status;
216 }
217
218 /**
219 * @brief Halt a host channel.
220 * @param hhcd HCD handle
221 * @param ch_num Channel number.
222 * This parameter can be a value from 1 to 15
223 * @retval HAL status
224 */
225 HAL_StatusTypeDef HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd, uint8_t ch_num)
226 {
227 HAL_StatusTypeDef status = HAL_OK;
228
229 __HAL_LOCK(hhcd);
230 USB_HC_Halt(hhcd->Instance, ch_num);
231 __HAL_UNLOCK(hhcd);
232
233 return status;
234 }
235
236 /**
237 * @brief DeInitialize the host driver.
238 * @param hhcd HCD handle
239 * @retval HAL status
240 */
241 HAL_StatusTypeDef HAL_HCD_DeInit(HCD_HandleTypeDef *hhcd)
242 {
243 /* Check the HCD handle allocation */
244 if(hhcd == NULL)
245 {
246 return HAL_ERROR;
247 }
248
249 hhcd->State = HAL_HCD_STATE_BUSY;
250
251 /* DeInit the low level hardware */
252 HAL_HCD_MspDeInit(hhcd);
253
254 __HAL_HCD_DISABLE(hhcd);
255
256 hhcd->State = HAL_HCD_STATE_RESET;
257
258 return HAL_OK;
259 }
260
261 /**
262 * @brief Initialize the HCD MSP.
263 * @param hhcd HCD handle
264 * @retval None
265 */
266 __weak void HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd)
267 {
268 /* Prevent unused argument(s) compilation warning */
269 UNUSED(hhcd);
270 /* NOTE : This function Should not be modified, when the callback is needed,
271 the HAL_PCD_MspInit could be implemented in the user file
272 */
273 }
274
275 /**
276 * @brief DeInitialize the HCD MSP.
277 * @param hhcd HCD handle
278 * @retval None
279 */
280 __weak void HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd)
281 {
282 /* Prevent unused argument(s) compilation warning */
283 UNUSED(hhcd);
284 /* NOTE : This function Should not be modified, when the callback is needed,
285 the HAL_PCD_MspDeInit could be implemented in the user file
286 */
287 }
288
289 /**
290 * @}
291 */
292
293 /** @defgroup HCD_Exported_Functions_Group2 Input and Output operation functions
294 * @brief HCD IO operation functions
295 *
296 @verbatim
297 ===============================================================================
298 ##### IO operation functions #####
299 ===============================================================================
300 [..] This subsection provides a set of functions allowing to manage the USB Host Data
301 Transfer
302
303 @endverbatim
304 * @{
305 */
306
307 /**
308 * @brief Submit a new URB for processing.
309 * @param hhcd HCD handle
310 * @param ch_num Channel number.
311 * This parameter can be a value from 1 to 15
312 * @param direction Channel number.
313 * This parameter can be one of these values:
314 * 0 : Output / 1 : Input
315 * @param ep_type Endpoint Type.
316 * This parameter can be one of these values:
317 * EP_TYPE_CTRL: Control type/
318 * EP_TYPE_ISOC: Isochronous type/
319 * EP_TYPE_BULK: Bulk type/
320 * EP_TYPE_INTR: Interrupt type/
321 * @param token Endpoint Type.
322 * This parameter can be one of these values:
323 * 0: HC_PID_SETUP / 1: HC_PID_DATA1
324 * @param pbuff pointer to URB data
325 * @param length Length of URB data
326 * @param do_ping activate do ping protocol (for high speed only).
327 * This parameter can be one of these values:
328 * 0 : do ping inactive / 1 : do ping active
329 * @retval HAL status
330 */
331 HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd,
332 uint8_t ch_num,
333 uint8_t direction,
334 uint8_t ep_type,
335 uint8_t token,
336 uint8_t* pbuff,
337 uint16_t length,
338 uint8_t do_ping)
339 {
340 hhcd->hc[ch_num].ep_is_in = direction;
341 hhcd->hc[ch_num].ep_type = ep_type;
342
343 if(token == 0)
344 {
345 hhcd->hc[ch_num].data_pid = HC_PID_SETUP;
346 }
347 else
348 {
349 hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
350 }
351
352 /* Manage Data Toggle */
353 switch(ep_type)
354 {
355 case EP_TYPE_CTRL:
356 if((token == 1) && (direction == 0)) /*send data */
357 {
358 if (length == 0)
359 { /* For Status OUT stage, Length==0, Status Out PID = 1 */
360 hhcd->hc[ch_num].toggle_out = 1;
361 }
362
363 /* Set the Data Toggle bit as per the Flag */
364 if (hhcd->hc[ch_num].toggle_out == 0)
365 { /* Put the PID 0 */
366 hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
367 }
368 else
369 { /* Put the PID 1 */
370 hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
371 }
372 if(hhcd->hc[ch_num].urb_state != URB_NOTREADY)
373 {
374 hhcd->hc[ch_num].do_ping = do_ping;
375 }
376 }
377 break;
378
379 case EP_TYPE_BULK:
380 if(direction == 0)
381 {
382 /* Set the Data Toggle bit as per the Flag */
383 if ( hhcd->hc[ch_num].toggle_out == 0)
384 { /* Put the PID 0 */
385 hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
386 }
387 else
388 { /* Put the PID 1 */
389 hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
390 }
391 if(hhcd->hc[ch_num].urb_state != URB_NOTREADY)
392 {
393 hhcd->hc[ch_num].do_ping = do_ping;
394 }
395 }
396 else
397 {
398 if( hhcd->hc[ch_num].toggle_in == 0)
399 {
400 hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
401 }
402 else
403 {
404 hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
405 }
406 }
407
408 break;
409 case EP_TYPE_INTR:
410 if(direction == 0)
411 {
412 /* Set the Data Toggle bit as per the Flag */
413 if ( hhcd->hc[ch_num].toggle_out == 0)
414 { /* Put the PID 0 */
415 hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
416 }
417 else
418 { /* Put the PID 1 */
419 hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
420 }
421 }
422 else
423 {
424 if( hhcd->hc[ch_num].toggle_in == 0)
425 {
426 hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
427 }
428 else
429 {
430 hhcd->hc[ch_num].data_pid = HC_PID_DATA1;
431 }
432 }
433 break;
434
435 case EP_TYPE_ISOC:
436 hhcd->hc[ch_num].data_pid = HC_PID_DATA0;
437 break;
438 }
439
440 hhcd->hc[ch_num].xfer_buff = pbuff;
441 hhcd->hc[ch_num].xfer_len = length;
442 hhcd->hc[ch_num].urb_state = URB_IDLE;
443 hhcd->hc[ch_num].xfer_count = 0;
444 hhcd->hc[ch_num].ch_num = ch_num;
445 hhcd->hc[ch_num].state = HC_IDLE;
446
447 return USB_HC_StartXfer(hhcd->Instance, &(hhcd->hc[ch_num]), hhcd->Init.dma_enable);
448 }
449
450 /**
451 * @brief Handle HCD interrupt request.
452 * @param hhcd HCD handle
453 * @retval None
454 */
455 void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd)
456 {
457 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
458 uint32_t i = 0U , interrupt = 0U;
459
460 /* Ensure that we are in device mode */
461 if (USB_GetMode(hhcd->Instance) == USB_OTG_MODE_HOST)
462 {
463 /* Avoid spurious interrupt */
464 if(__HAL_HCD_IS_INVALID_INTERRUPT(hhcd))
465 {
466 return;
467 }
468
469 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
470 {
471 /* Incorrect mode, acknowledge the interrupt */
472 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
473 }
474
475 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR))
476 {
477 /* Incorrect mode, acknowledge the interrupt */
478 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR);
479 }
480
481 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE))
482 {
483 /* Incorrect mode, acknowledge the interrupt */
484 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE);
485 }
486
487 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_MMIS))
488 {
489 /* Incorrect mode, acknowledge the interrupt */
490 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_MMIS);
491 }
492
493 /* Handle Host Disconnect Interrupts */
494 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT))
495 {
496
497 /* Cleanup HPRT */
498 USBx_HPRT0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
499 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
500
501 /* Handle Host Port Interrupts */
502 HAL_HCD_Disconnect_Callback(hhcd);
503 USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_48_MHZ );
504 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT);
505 }
506
507 /* Handle Host Port Interrupts */
508 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HPRTINT))
509 {
510 HCD_Port_IRQHandler (hhcd);
511 }
512
513 /* Handle Host SOF Interrupts */
514 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_SOF))
515 {
516 HAL_HCD_SOF_Callback(hhcd);
517 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_SOF);
518 }
519
520 /* Handle Host channel Interrupts */
521 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HCINT))
522 {
523 interrupt = USB_HC_ReadInterrupt(hhcd->Instance);
524 for (i = 0U; i < hhcd->Init.Host_channels; i++)
525 {
526 if (interrupt & (1U << i))
527 {
528 if ((USBx_HC(i)->HCCHAR) & USB_OTG_HCCHAR_EPDIR)
529 {
530 HCD_HC_IN_IRQHandler(hhcd, i);
531 }
532 else
533 {
534 HCD_HC_OUT_IRQHandler (hhcd, i);
535 }
536 }
537 }
538 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_HCINT);
539 }
540
541 /* Handle Rx Queue Level Interrupts */
542 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_RXFLVL))
543 {
544 USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
545
546 HCD_RXQLVL_IRQHandler (hhcd);
547
548 USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
549 }
550 }
551 }
552
553 /**
554 * @brief SOF callback.
555 * @param hhcd HCD handle
556 * @retval None
557 */
558 __weak void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd)
559 {
560 /* Prevent unused argument(s) compilation warning */
561 UNUSED(hhcd);
562 /* NOTE : This function Should not be modified, when the callback is needed,
563 the HAL_HCD_SOF_Callback could be implemented in the user file
564 */
565 }
566
567 /**
568 * @brief Connection Event callback.
569 * @param hhcd HCD handle
570 * @retval None
571 */
572 __weak void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
573 {
574 /* Prevent unused argument(s) compilation warning */
575 UNUSED(hhcd);
576 /* NOTE : This function Should not be modified, when the callback is needed,
577 the HAL_HCD_Connect_Callback could be implemented in the user file
578 */
579 }
580
581 /**
582 * @brief Disconnection Event callback.
583 * @param hhcd HCD handle
584 * @retval None
585 */
586 __weak void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
587 {
588 /* Prevent unused argument(s) compilation warning */
589 UNUSED(hhcd);
590 /* NOTE : This function Should not be modified, when the callback is needed,
591 the HAL_HCD_Disconnect_Callback could be implemented in the user file
592 */
593 }
594
595 /**
596 * @brief Notify URB state change callback.
597 * @param hhcd HCD handle
598 * @param chnum Channel number.
599 * This parameter can be a value from 1 to 15
600 * @param urb_state:
601 * This parameter can be one of these values:
602 * URB_IDLE/
603 * URB_DONE/
604 * URB_NOTREADY/
605 * URB_NYET/
606 * URB_ERROR/
607 * URB_STALL/
608 * @retval None
609 */
610 __weak void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state)
611 {
612 /* Prevent unused argument(s) compilation warning */
613 UNUSED(hhcd);
614 UNUSED(chnum);
615 UNUSED(urb_state);
616 /* NOTE : This function Should not be modified, when the callback is needed,
617 the HAL_HCD_HC_NotifyURBChange_Callback could be implemented in the user file
618 */
619 }
620
621 /**
622 * @}
623 */
624
625 /** @defgroup HCD_Exported_Functions_Group3 Peripheral Control functions
626 * @brief Management functions
627 *
628 @verbatim
629 ===============================================================================
630 ##### Peripheral Control functions #####
631 ===============================================================================
632 [..]
633 This subsection provides a set of functions allowing to control the HCD data
634 transfers.
635
636 @endverbatim
637 * @{
638 */
639
640 /**
641 * @brief Start the host driver.
642 * @param hhcd HCD handle
643 * @retval HAL status
644 */
645 HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd)
646 {
647 __HAL_LOCK(hhcd);
648 __HAL_HCD_ENABLE(hhcd);
649 USB_DriveVbus(hhcd->Instance, 1U);
650 __HAL_UNLOCK(hhcd);
651 return HAL_OK;
652 }
653
654 /**
655 * @brief Stop the host driver.
656 * @param hhcd HCD handle
657 * @retval HAL status
658 */
659
660 HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd)
661 {
662 __HAL_LOCK(hhcd);
663 USB_StopHost(hhcd->Instance);
664 __HAL_UNLOCK(hhcd);
665 return HAL_OK;
666 }
667
668 /**
669 * @brief Reset the host port.
670 * @param hhcd HCD handle
671 * @retval HAL status
672 */
673 HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd)
674 {
675 return (USB_ResetPort(hhcd->Instance));
676 }
677
678 /**
679 * @}
680 */
681
682 /** @defgroup HCD_Exported_Functions_Group4 Peripheral State functions
683 * @brief Peripheral State functions
684 *
685 @verbatim
686 ===============================================================================
687 ##### Peripheral State functions #####
688 ===============================================================================
689 [..]
690 This subsection permits to get in run-time the status of the peripheral
691 and the data flow.
692
693 @endverbatim
694 * @{
695 */
696
697 /**
698 * @brief Return the HCD handle state.
699 * @param hhcd HCD handle
700 * @retval HAL state
701 */
702 HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef *hhcd)
703 {
704 return hhcd->State;
705 }
706
707 /**
708 * @brief Return URB state for a channel.
709 * @param hhcd HCD handle
710 * @param chnum Channel number.
711 * This parameter can be a value from 1 to 15
712 * @retval URB state.
713 * This parameter can be one of these values:
714 * URB_IDLE/
715 * URB_DONE/
716 * URB_NOTREADY/
717 * URB_NYET/
718 * URB_ERROR/
719 * URB_STALL
720 */
721 HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef *hhcd, uint8_t chnum)
722 {
723 return hhcd->hc[chnum].urb_state;
724 }
725
726
727 /**
728 * @brief Return the last host transfer size.
729 * @param hhcd HCD handle
730 * @param chnum Channel number.
731 * This parameter can be a value from 1 to 15
732 * @retval last transfer size in byte
733 */
734 uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef *hhcd, uint8_t chnum)
735 {
736 return hhcd->hc[chnum].xfer_count;
737 }
738
739 /**
740 * @brief Return the Host Channel state.
741 * @param hhcd HCD handle
742 * @param chnum Channel number.
743 * This parameter can be a value from 1 to 15
744 * @retval Host channel state
745 * This parameter can be one of these values:
746 * HC_IDLE/
747 * HC_XFRC/
748 * HC_HALTED/
749 * HC_NYET/
750 * HC_NAK/
751 * HC_STALL/
752 * HC_XACTERR/
753 * HC_BBLERR/
754 * HC_DATATGLERR
755 */
756 HCD_HCStateTypeDef HAL_HCD_HC_GetState(HCD_HandleTypeDef *hhcd, uint8_t chnum)
757 {
758 return hhcd->hc[chnum].state;
759 }
760
761 /**
762 * @brief Return the current Host frame number.
763 * @param hhcd HCD handle
764 * @retval Current Host frame number
765 */
766 uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd)
767 {
768 return (USB_GetCurrentFrame(hhcd->Instance));
769 }
770
771 /**
772 * @brief Return the Host enumeration speed.
773 * @param hhcd HCD handle
774 * @retval Enumeration speed
775 */
776 uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd)
777 {
778 return (USB_GetHostSpeed(hhcd->Instance));
779 }
780
781 /**
782 * @}
783 */
784
785 /**
786 * @}
787 */
788
789 /** @addtogroup HCD_Private_Functions
790 * @{
791 */
792 /**
793 * @brief Handle Host Channel IN interrupt requests.
794 * @param hhcd HCD handle
795 * @param chnum Channel number.
796 * This parameter can be a value from 1 to 15
797 * @retval None
798 */
799 static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
800 {
801 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
802 uint32_t tmpreg = 0U;
803
804 if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_AHBERR)
805 {
806 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR);
807 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
808 }
809 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_ACK)
810 {
811 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
812 }
813
814 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_STALL)
815 {
816 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
817 hhcd->hc[chnum].state = HC_STALL;
818 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
819 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL);
820 USB_HC_Halt(hhcd->Instance, chnum);
821 }
822 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_DTERR)
823 {
824 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
825 USB_HC_Halt(hhcd->Instance, chnum);
826 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
827 hhcd->hc[chnum].state = HC_DATATGLERR;
828 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR);
829 }
830
831 if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_FRMOR)
832 {
833 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
834 USB_HC_Halt(hhcd->Instance, chnum);
835 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR);
836 }
837
838 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_XFRC)
839 {
840
841 if (hhcd->Init.dma_enable)
842 {
843 hhcd->hc[chnum].xfer_count = hhcd->hc[chnum].xfer_len - \
844 (USBx_HC(chnum)->HCTSIZ & USB_OTG_HCTSIZ_XFRSIZ);
845 }
846
847 hhcd->hc[chnum].state = HC_XFRC;
848 hhcd->hc[chnum].ErrCnt = 0U;
849 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC);
850
851
852 if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL)||
853 (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
854 {
855 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
856 USB_HC_Halt(hhcd->Instance, chnum);
857 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
858
859 }
860 else if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
861 {
862 USBx_HC(chnum)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
863 hhcd->hc[chnum].urb_state = URB_DONE;
864 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
865 }
866 hhcd->hc[chnum].toggle_in ^= 1U;
867
868 }
869 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_CHH)
870 {
871 __HAL_HCD_MASK_HALT_HC_INT(chnum);
872
873 if(hhcd->hc[chnum].state == HC_XFRC)
874 {
875 hhcd->hc[chnum].urb_state = URB_DONE;
876 }
877
878 else if (hhcd->hc[chnum].state == HC_STALL)
879 {
880 hhcd->hc[chnum].urb_state = URB_STALL;
881 }
882
883 else if((hhcd->hc[chnum].state == HC_XACTERR) ||
884 (hhcd->hc[chnum].state == HC_DATATGLERR))
885 {
886 if(hhcd->hc[chnum].ErrCnt++ > 3U)
887 {
888 hhcd->hc[chnum].ErrCnt = 0U;
889 hhcd->hc[chnum].urb_state = URB_ERROR;
890 }
891 else
892 {
893 hhcd->hc[chnum].urb_state = URB_NOTREADY;
894 }
895
896 /* re-activate the channel */
897 tmpreg = USBx_HC(chnum)->HCCHAR;
898 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
899 tmpreg |= USB_OTG_HCCHAR_CHENA;
900 USBx_HC(chnum)->HCCHAR = tmpreg;
901 }
902 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
903 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
904 }
905
906 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_TXERR)
907 {
908 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
909 hhcd->hc[chnum].ErrCnt++;
910 hhcd->hc[chnum].state = HC_XACTERR;
911 USB_HC_Halt(hhcd->Instance, chnum);
912 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR);
913 }
914 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NAK)
915 {
916 if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
917 {
918 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
919 USB_HC_Halt(hhcd->Instance, chnum);
920 }
921
922 /* Clear the NAK flag before re-enabling the channel for new IN request */
923 hhcd->hc[chnum].state = HC_NAK;
924 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
925
926 if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL)||
927 (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
928 {
929 /* re-activate the channel */
930 tmpreg = USBx_HC(chnum)->HCCHAR;
931 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
932 tmpreg |= USB_OTG_HCCHAR_CHENA;
933 USBx_HC(chnum)->HCCHAR = tmpreg;
934 }
935 }
936 }
937
938 /**
939 * @brief Handle Host Channel OUT interrupt requests.
940 * @param hhcd HCD handle
941 * @param chnum Channel number.
942 * This parameter can be a value from 1 to 15
943 * @retval None
944 */
945 static void HCD_HC_OUT_IRQHandler (HCD_HandleTypeDef *hhcd, uint8_t chnum)
946 {
947 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
948
949 if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_AHBERR)
950 {
951 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR);
952 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
953 }
954 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_ACK)
955 {
956 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
957
958 if( hhcd->hc[chnum].do_ping == 1U)
959 {
960 hhcd->hc[chnum].state = HC_NYET;
961 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
962 USB_HC_Halt(hhcd->Instance, chnum);
963 hhcd->hc[chnum].urb_state = URB_NOTREADY;
964 }
965 }
966
967 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NYET)
968 {
969 hhcd->hc[chnum].state = HC_NYET;
970 hhcd->hc[chnum].ErrCnt= 0U;
971 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
972 USB_HC_Halt(hhcd->Instance, chnum);
973 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NYET);
974
975 }
976
977 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_FRMOR)
978 {
979 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
980 USB_HC_Halt(hhcd->Instance, chnum);
981 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR);
982 }
983
984 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_XFRC)
985 {
986 hhcd->hc[chnum].ErrCnt = 0U;
987 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
988 USB_HC_Halt(hhcd->Instance, chnum);
989 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC);
990 hhcd->hc[chnum].state = HC_XFRC;
991
992 }
993
994 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_STALL)
995 {
996 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL);
997 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
998 USB_HC_Halt(hhcd->Instance, chnum);
999 hhcd->hc[chnum].state = HC_STALL;
1000 }
1001
1002 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NAK)
1003 {
1004 hhcd->hc[chnum].ErrCnt = 0U;
1005 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
1006 USB_HC_Halt(hhcd->Instance, chnum);
1007 hhcd->hc[chnum].state = HC_NAK;
1008 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
1009 }
1010
1011 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_TXERR)
1012 {
1013 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
1014 USB_HC_Halt(hhcd->Instance, chnum);
1015 hhcd->hc[chnum].state = HC_XACTERR;
1016 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR);
1017 }
1018
1019 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_DTERR)
1020 {
1021 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
1022 USB_HC_Halt(hhcd->Instance, chnum);
1023 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
1024 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR);
1025 hhcd->hc[chnum].state = HC_DATATGLERR;
1026 }
1027
1028
1029 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_CHH)
1030 {
1031 __HAL_HCD_MASK_HALT_HC_INT(chnum);
1032
1033 if(hhcd->hc[chnum].state == HC_XFRC)
1034 {
1035 hhcd->hc[chnum].urb_state = URB_DONE;
1036 if (hhcd->hc[chnum].ep_type == EP_TYPE_BULK)
1037 {
1038 hhcd->hc[chnum].toggle_out ^= 1U;
1039 }
1040 }
1041 else if (hhcd->hc[chnum].state == HC_NAK)
1042 {
1043 hhcd->hc[chnum].urb_state = URB_NOTREADY;
1044 }
1045
1046 else if (hhcd->hc[chnum].state == HC_NYET)
1047 {
1048 hhcd->hc[chnum].urb_state = URB_NOTREADY;
1049 hhcd->hc[chnum].do_ping = 0U;
1050 }
1051
1052 else if (hhcd->hc[chnum].state == HC_STALL)
1053 {
1054 hhcd->hc[chnum].urb_state = URB_STALL;
1055 }
1056
1057 else if((hhcd->hc[chnum].state == HC_XACTERR) ||
1058 (hhcd->hc[chnum].state == HC_DATATGLERR))
1059 {
1060 if(hhcd->hc[chnum].ErrCnt++ > 3U)
1061 {
1062 hhcd->hc[chnum].ErrCnt = 0U;
1063 hhcd->hc[chnum].urb_state = URB_ERROR;
1064 }
1065 else
1066 {
1067 hhcd->hc[chnum].urb_state = URB_NOTREADY;
1068 }
1069 }
1070
1071 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
1072 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
1073 }
1074 }
1075
1076 /**
1077 * @brief Handle Rx Queue Level interrupt requests.
1078 * @param hhcd HCD handle
1079 * @retval None
1080 */
1081 static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd)
1082 {
1083 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
1084 uint8_t channelnum = 0;
1085 uint32_t pktsts;
1086 uint32_t pktcnt;
1087 uint32_t temp = 0U;
1088 uint32_t tmpreg = 0U;
1089
1090 temp = hhcd->Instance->GRXSTSP;
1091 channelnum = temp & USB_OTG_GRXSTSP_EPNUM;
1092 pktsts = (temp & USB_OTG_GRXSTSP_PKTSTS) >> 17U;
1093 pktcnt = (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
1094
1095 switch (pktsts)
1096 {
1097 case GRXSTS_PKTSTS_IN:
1098 /* Read the data into the host buffer. */
1099 if ((pktcnt > 0U) && (hhcd->hc[channelnum].xfer_buff != (void *)0))
1100 {
1101
1102 USB_ReadPacket(hhcd->Instance, hhcd->hc[channelnum].xfer_buff, pktcnt);
1103
1104 /*manage multiple Xfer */
1105 hhcd->hc[channelnum].xfer_buff += pktcnt;
1106 hhcd->hc[channelnum].xfer_count += pktcnt;
1107
1108 if((USBx_HC(channelnum)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) > 0)
1109 {
1110 /* re-activate the channel when more packets are expected */
1111 tmpreg = USBx_HC(channelnum)->HCCHAR;
1112 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1113 tmpreg |= USB_OTG_HCCHAR_CHENA;
1114 USBx_HC(channelnum)->HCCHAR = tmpreg;
1115 hhcd->hc[channelnum].toggle_in ^= 1;
1116 }
1117 }
1118 break;
1119
1120 case GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
1121 break;
1122 case GRXSTS_PKTSTS_IN_XFER_COMP:
1123 case GRXSTS_PKTSTS_CH_HALTED:
1124 default:
1125 break;
1126 }
1127 }
1128
1129 /**
1130 * @brief Handle Host Port interrupt requests.
1131 * @param hhcd HCD handle
1132 * @retval None
1133 */
1134 static void HCD_Port_IRQHandler (HCD_HandleTypeDef *hhcd)
1135 {
1136 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
1137 __IO uint32_t hprt0, hprt0_dup;
1138
1139 /* Handle Host Port Interrupts */
1140 hprt0 = USBx_HPRT0;
1141 hprt0_dup = USBx_HPRT0;
1142
1143 hprt0_dup &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
1144 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
1145
1146 /* Check whether Port Connect Detected */
1147 if((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET)
1148 {
1149 if((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS)
1150 {
1151 USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT);
1152 HAL_HCD_Connect_Callback(hhcd);
1153 }
1154 hprt0_dup |= USB_OTG_HPRT_PCDET;
1155
1156 }
1157
1158 /* Check whether Port Enable Changed */
1159 if((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG)
1160 {
1161 hprt0_dup |= USB_OTG_HPRT_PENCHNG;
1162
1163 if((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA)
1164 {
1165 if(hhcd->Init.phy_itface == USB_OTG_EMBEDDED_PHY)
1166 {
1167 if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17U))
1168 {
1169 USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_6_MHZ );
1170 }
1171 else
1172 {
1173 USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_48_MHZ );
1174 }
1175 }
1176 else
1177 {
1178 if(hhcd->Init.speed == HCD_SPEED_FULL)
1179 {
1180 USBx_HOST->HFIR = 60000U;
1181 }
1182 }
1183
1184 HAL_HCD_Connect_Callback(hhcd);
1185 }
1186 else
1187 {
1188 /* Clean up HPRT */
1189 USBx_HPRT0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
1190 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
1191
1192 USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT);
1193 }
1194 }
1195
1196 /* Check for an over current */
1197 if((hprt0 & USB_OTG_HPRT_POCCHNG) == USB_OTG_HPRT_POCCHNG)
1198 {
1199 hprt0_dup |= USB_OTG_HPRT_POCCHNG;
1200 }
1201
1202 /* Clear Port Interrupts */
1203 USBx_HPRT0 = hprt0_dup;
1204 }
1205
1206 /**
1207 * @}
1208 */
1209 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx ||
1210 STM32F401xC || STM32F401xE || STM32F411xE || STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Rx ||
1211 STM32F412Vx || STM32F412Cx || defined(STM32F413xx) || defined(STM32F423xx) */
1212 #endif /* HAL_HCD_MODULE_ENABLED */
1213 /**
1214 * @}
1215 */
1216
1217 /**
1218 * @}
1219 */
1220
1221 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/