1 /**
2 ******************************************************************************
3 * @file stm32f7xx_ll_usb.c
4 * @author MCD Application Team
5 * @brief USB Low Layer HAL module driver.
6 *
7 * This file provides firmware functions to manage the following
8 * functionalities of the USB Peripheral Controller:
9 * + Initialization/de-initialization functions
10 * + I/O operation functions
11 * + Peripheral Control functions
12 * + Peripheral State functions
13 *
14 ******************************************************************************
15 * @attention
16 *
17 * Copyright (c) 2017 STMicroelectronics.
18 * All rights reserved.
19 *
20 * This software is licensed under terms that can be found in the LICENSE file
21 * in the root directory of this software component.
22 * If no LICENSE file comes with this software, it is provided AS-IS.
23 *
24 ******************************************************************************
25 @verbatim
26 ==============================================================================
27 ##### How to use this driver #####
28 ==============================================================================
29 [..]
30 (#) Fill parameters of Init structure in USB_CfgTypeDef structure.
31
32 (#) Call USB_CoreInit() API to initialize the USB Core peripheral.
33
34 (#) The upper HAL HCD/PCD driver will call the right routines for its internal processes.
35
36 @endverbatim
37
38 ******************************************************************************
39 */
40
41 /* Includes ------------------------------------------------------------------*/
42 #include "stm32f7xx_hal.h"
43
44 /** @addtogroup STM32F7xx_LL_USB_DRIVER
45 * @{
46 */
47
48 #if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED)
49 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
50 /* Private typedef -----------------------------------------------------------*/
51 /* Private define ------------------------------------------------------------*/
52 /* Private macro -------------------------------------------------------------*/
53 /* Private variables ---------------------------------------------------------*/
54 /* Private function prototypes -----------------------------------------------*/
55 /* Private functions ---------------------------------------------------------*/
56 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
57 static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx);
58 #ifdef USBPHYC
59 static HAL_StatusTypeDef USB_HS_PHYCInit(USB_OTG_GlobalTypeDef *USBx);
60 #endif /* USBPHYC */
61
62 /* Exported functions --------------------------------------------------------*/
63 /** @defgroup USB_LL_Exported_Functions USB Low Layer Exported Functions
64 * @{
65 */
66
67 /** @defgroup USB_LL_Exported_Functions_Group1 Initialization/de-initialization functions
68 * @brief Initialization and Configuration functions
69 *
70 @verbatim
71 ===============================================================================
72 ##### Initialization/de-initialization functions #####
73 ===============================================================================
74
75 @endverbatim
76 * @{
77 */
78
79 /**
80 * @brief Initializes the USB Core
81 * @param USBx USB Instance
82 * @param cfg pointer to a USB_OTG_CfgTypeDef structure that contains
83 * the configuration information for the specified USBx peripheral.
84 * @retval HAL status
85 */
USB_CoreInit(USB_OTG_GlobalTypeDef * USBx,USB_OTG_CfgTypeDef cfg)86 HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
87 {
88 HAL_StatusTypeDef ret;
89
90 if (cfg.phy_itface == USB_OTG_ULPI_PHY)
91 {
92 USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
93
94 /* Init The ULPI Interface */
95 USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL);
96
97 #if defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F730xx) \
98 || defined(STM32F732xx) || defined(STM32F733xx)
99 /* Select ULPI Interface */
100 USBx->GUSBCFG |= USB_OTG_GUSBCFG_ULPI_UTMI_SEL;
101 #endif /* defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F730xx) ||
102 defined(STM32F732xx) || defined(STM32F733xx) */
103
104 /* Select vbus source */
105 USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
106 if (cfg.use_external_vbus == 1U)
107 {
108 USBx->GUSBCFG |= USB_OTG_GUSBCFG_ULPIEVBUSD;
109 }
110
111 /* Reset after a PHY select */
112 ret = USB_CoreReset(USBx);
113 }
114 #if defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F730xx) \
115 || defined(STM32F732xx) || defined(STM32F733xx)
116 else if (cfg.phy_itface == USB_OTG_HS_EMBEDDED_PHY)
117 {
118 USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
119
120 /* Init The UTMI Interface */
121 USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL);
122
123 /* Select vbus source */
124 USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
125
126 /* Select UTMI Interface */
127 USBx->GUSBCFG &= ~USB_OTG_GUSBCFG_ULPI_UTMI_SEL;
128 #ifdef USBPHYC
129 /* Enable USB HS PHY */
130 USBx->GCCFG |= USB_OTG_GCCFG_PHYHSEN;
131
132 /* Enables control of a High Speed USB PHY */
133 if (USB_HS_PHYCInit(USBx) != HAL_OK)
134 {
135 return HAL_ERROR;
136 }
137 #endif /* USBPHYC */
138
139 if (cfg.use_external_vbus == 1U)
140 {
141 USBx->GUSBCFG |= USB_OTG_GUSBCFG_ULPIEVBUSD;
142 }
143
144 /* Reset after a PHY select */
145 ret = USB_CoreReset(USBx);
146 }
147 #endif /* defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F730xx) ||
148 defined(STM32F732xx) || defined(STM32F733xx) */
149 else /* FS interface (embedded Phy) */
150 {
151 /* Select FS Embedded PHY */
152 USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
153
154 /* Reset after a PHY select */
155 ret = USB_CoreReset(USBx);
156
157 /* Activate the USB Transceiver */
158 USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
159 }
160
161 if (cfg.dma_enable == 1U)
162 {
163 USBx->GAHBCFG |= USB_OTG_GAHBCFG_HBSTLEN_2;
164 USBx->GAHBCFG |= USB_OTG_GAHBCFG_DMAEN;
165 }
166
167 return ret;
168 }
169
170
171 /**
172 * @brief Set the USB turnaround time
173 * @param USBx USB Instance
174 * @param hclk: AHB clock frequency
175 * @retval USB turnaround time In PHY Clocks number
176 */
USB_SetTurnaroundTime(USB_OTG_GlobalTypeDef * USBx,uint32_t hclk,uint8_t speed)177 HAL_StatusTypeDef USB_SetTurnaroundTime(USB_OTG_GlobalTypeDef *USBx,
178 uint32_t hclk, uint8_t speed)
179 {
180 uint32_t UsbTrd;
181
182 /* The USBTRD is configured according to the tables below, depending on AHB frequency
183 used by application. In the low AHB frequency range it is used to stretch enough the USB response
184 time to IN tokens, the USB turnaround time, so to compensate for the longer AHB read access
185 latency to the Data FIFO */
186 if (speed == USBD_FS_SPEED)
187 {
188 if ((hclk >= 14200000U) && (hclk < 15000000U))
189 {
190 /* hclk Clock Range between 14.2-15 MHz */
191 UsbTrd = 0xFU;
192 }
193 else if ((hclk >= 15000000U) && (hclk < 16000000U))
194 {
195 /* hclk Clock Range between 15-16 MHz */
196 UsbTrd = 0xEU;
197 }
198 else if ((hclk >= 16000000U) && (hclk < 17200000U))
199 {
200 /* hclk Clock Range between 16-17.2 MHz */
201 UsbTrd = 0xDU;
202 }
203 else if ((hclk >= 17200000U) && (hclk < 18500000U))
204 {
205 /* hclk Clock Range between 17.2-18.5 MHz */
206 UsbTrd = 0xCU;
207 }
208 else if ((hclk >= 18500000U) && (hclk < 20000000U))
209 {
210 /* hclk Clock Range between 18.5-20 MHz */
211 UsbTrd = 0xBU;
212 }
213 else if ((hclk >= 20000000U) && (hclk < 21800000U))
214 {
215 /* hclk Clock Range between 20-21.8 MHz */
216 UsbTrd = 0xAU;
217 }
218 else if ((hclk >= 21800000U) && (hclk < 24000000U))
219 {
220 /* hclk Clock Range between 21.8-24 MHz */
221 UsbTrd = 0x9U;
222 }
223 else if ((hclk >= 24000000U) && (hclk < 27700000U))
224 {
225 /* hclk Clock Range between 24-27.7 MHz */
226 UsbTrd = 0x8U;
227 }
228 else if ((hclk >= 27700000U) && (hclk < 32000000U))
229 {
230 /* hclk Clock Range between 27.7-32 MHz */
231 UsbTrd = 0x7U;
232 }
233 else /* if(hclk >= 32000000) */
234 {
235 /* hclk Clock Range between 32-200 MHz */
236 UsbTrd = 0x6U;
237 }
238 }
239 else if (speed == USBD_HS_SPEED)
240 {
241 UsbTrd = USBD_HS_TRDT_VALUE;
242 }
243 else
244 {
245 UsbTrd = USBD_DEFAULT_TRDT_VALUE;
246 }
247
248 USBx->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
249 USBx->GUSBCFG |= (uint32_t)((UsbTrd << 10) & USB_OTG_GUSBCFG_TRDT);
250
251 return HAL_OK;
252 }
253
254 /**
255 * @brief USB_EnableGlobalInt
256 * Enables the controller's Global Int in the AHB Config reg
257 * @param USBx Selected device
258 * @retval HAL status
259 */
USB_EnableGlobalInt(USB_OTG_GlobalTypeDef * USBx)260 HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
261 {
262 USBx->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
263 return HAL_OK;
264 }
265
266 /**
267 * @brief USB_DisableGlobalInt
268 * Disable the controller's Global Int in the AHB Config reg
269 * @param USBx Selected device
270 * @retval HAL status
271 */
USB_DisableGlobalInt(USB_OTG_GlobalTypeDef * USBx)272 HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
273 {
274 USBx->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
275 return HAL_OK;
276 }
277
278 /**
279 * @brief USB_SetCurrentMode Set functional mode
280 * @param USBx Selected device
281 * @param mode current core mode
282 * This parameter can be one of these values:
283 * @arg USB_DEVICE_MODE Peripheral mode
284 * @arg USB_HOST_MODE Host mode
285 * @retval HAL status
286 */
USB_SetCurrentMode(USB_OTG_GlobalTypeDef * USBx,USB_OTG_ModeTypeDef mode)287 HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx, USB_OTG_ModeTypeDef mode)
288 {
289 uint32_t ms = 0U;
290
291 USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
292
293 if (mode == USB_HOST_MODE)
294 {
295 USBx->GUSBCFG |= USB_OTG_GUSBCFG_FHMOD;
296
297 do
298 {
299 HAL_Delay(10U);
300 ms += 10U;
301 } while ((USB_GetMode(USBx) != (uint32_t)USB_HOST_MODE) && (ms < HAL_USB_CURRENT_MODE_MAX_DELAY_MS));
302 }
303 else if (mode == USB_DEVICE_MODE)
304 {
305 USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
306
307 do
308 {
309 HAL_Delay(10U);
310 ms += 10U;
311 } while ((USB_GetMode(USBx) != (uint32_t)USB_DEVICE_MODE) && (ms < HAL_USB_CURRENT_MODE_MAX_DELAY_MS));
312 }
313 else
314 {
315 return HAL_ERROR;
316 }
317
318 if (ms == HAL_USB_CURRENT_MODE_MAX_DELAY_MS)
319 {
320 return HAL_ERROR;
321 }
322
323 return HAL_OK;
324 }
325
326 /**
327 * @brief USB_DevInit Initializes the USB_OTG controller registers
328 * for device mode
329 * @param USBx Selected device
330 * @param cfg pointer to a USB_OTG_CfgTypeDef structure that contains
331 * the configuration information for the specified USBx peripheral.
332 * @retval HAL status
333 */
USB_DevInit(USB_OTG_GlobalTypeDef * USBx,USB_OTG_CfgTypeDef cfg)334 HAL_StatusTypeDef USB_DevInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
335 {
336 HAL_StatusTypeDef ret = HAL_OK;
337 uint32_t USBx_BASE = (uint32_t)USBx;
338 uint32_t i;
339
340 for (i = 0U; i < 15U; i++)
341 {
342 USBx->DIEPTXF[i] = 0U;
343 }
344
345 /* VBUS Sensing setup */
346 if (cfg.vbus_sensing_enable == 0U)
347 {
348 USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
349
350 /* Deactivate VBUS Sensing B */
351 USBx->GCCFG &= ~USB_OTG_GCCFG_VBDEN;
352
353 /* B-peripheral session valid override enable */
354 USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN;
355 USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;
356 }
357 else
358 {
359 /* Enable HW VBUS sensing */
360 USBx->GCCFG |= USB_OTG_GCCFG_VBDEN;
361 }
362
363 /* Restart the Phy Clock */
364 USBx_PCGCCTL = 0U;
365
366 if (cfg.phy_itface == USB_OTG_ULPI_PHY)
367 {
368 if (cfg.speed == USBD_HS_SPEED)
369 {
370 /* Set Core speed to High speed mode */
371 (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_HIGH);
372 }
373 else
374 {
375 /* Set Core speed to Full speed mode */
376 (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_HIGH_IN_FULL);
377 }
378 }
379 #if defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F730xx) \
380 || defined(STM32F732xx) || defined(STM32F733xx)
381 else if (cfg.phy_itface == USB_OTG_HS_EMBEDDED_PHY)
382 {
383 if (cfg.speed == USBD_HS_SPEED)
384 {
385 /* Set Core speed to High speed mode */
386 (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_HIGH);
387 }
388 else
389 {
390 /* Set Core speed to Full speed mode */
391 (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_HIGH_IN_FULL);
392 }
393 }
394 #endif /* defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F730xx) ||
395 defined(STM32F732xx) || defined(STM32F733xx) */
396 else
397 {
398 /* Set Core speed to Full speed mode */
399 (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_FULL);
400 }
401
402 /* Flush the FIFOs */
403 if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
404 {
405 ret = HAL_ERROR;
406 }
407
408 if (USB_FlushRxFifo(USBx) != HAL_OK)
409 {
410 ret = HAL_ERROR;
411 }
412
413 /* Clear all pending Device Interrupts */
414 USBx_DEVICE->DIEPMSK = 0U;
415 USBx_DEVICE->DOEPMSK = 0U;
416 USBx_DEVICE->DAINTMSK = 0U;
417
418 for (i = 0U; i < cfg.dev_endpoints; i++)
419 {
420 if ((USBx_INEP(i)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
421 {
422 if (i == 0U)
423 {
424 USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_SNAK;
425 }
426 else
427 {
428 USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK;
429 }
430 }
431 else
432 {
433 USBx_INEP(i)->DIEPCTL = 0U;
434 }
435
436 USBx_INEP(i)->DIEPTSIZ = 0U;
437 USBx_INEP(i)->DIEPINT = 0xFB7FU;
438 }
439
440 for (i = 0U; i < cfg.dev_endpoints; i++)
441 {
442 if ((USBx_OUTEP(i)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
443 {
444 if (i == 0U)
445 {
446 USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_SNAK;
447 }
448 else
449 {
450 USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK;
451 }
452 }
453 else
454 {
455 USBx_OUTEP(i)->DOEPCTL = 0U;
456 }
457
458 USBx_OUTEP(i)->DOEPTSIZ = 0U;
459 USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
460 }
461
462 USBx_DEVICE->DIEPMSK &= ~(USB_OTG_DIEPMSK_TXFURM);
463
464 /* Disable all interrupts. */
465 USBx->GINTMSK = 0U;
466
467 /* Clear any pending interrupts */
468 USBx->GINTSTS = 0xBFFFFFFFU;
469
470 /* Enable the common interrupts */
471 if (cfg.dma_enable == 0U)
472 {
473 USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
474 }
475
476 /* Enable interrupts matching to the Device mode ONLY */
477 USBx->GINTMSK |= USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |
478 USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |
479 USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IISOIXFRM |
480 USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM;
481
482 if (cfg.Sof_enable != 0U)
483 {
484 USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM;
485 }
486
487 if (cfg.vbus_sensing_enable == 1U)
488 {
489 USBx->GINTMSK |= (USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_OTGINT);
490 }
491
492 return ret;
493 }
494
495 /**
496 * @brief USB_FlushTxFifo Flush a Tx FIFO
497 * @param USBx Selected device
498 * @param num FIFO number
499 * This parameter can be a value from 1 to 15
500 15 means Flush all Tx FIFOs
501 * @retval HAL status
502 */
USB_FlushTxFifo(USB_OTG_GlobalTypeDef * USBx,uint32_t num)503 HAL_StatusTypeDef USB_FlushTxFifo(USB_OTG_GlobalTypeDef *USBx, uint32_t num)
504 {
505 __IO uint32_t count = 0U;
506
507 /* Wait for AHB master IDLE state. */
508 do
509 {
510 count++;
511
512 if (count > HAL_USB_TIMEOUT)
513 {
514 return HAL_TIMEOUT;
515 }
516 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
517
518 /* Flush TX Fifo */
519 count = 0U;
520 USBx->GRSTCTL = (USB_OTG_GRSTCTL_TXFFLSH | (num << 6));
521
522 do
523 {
524 count++;
525
526 if (count > HAL_USB_TIMEOUT)
527 {
528 return HAL_TIMEOUT;
529 }
530 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
531
532 return HAL_OK;
533 }
534
535 /**
536 * @brief USB_FlushRxFifo Flush Rx FIFO
537 * @param USBx Selected device
538 * @retval HAL status
539 */
USB_FlushRxFifo(USB_OTG_GlobalTypeDef * USBx)540 HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx)
541 {
542 __IO uint32_t count = 0U;
543
544 /* Wait for AHB master IDLE state. */
545 do
546 {
547 count++;
548
549 if (count > HAL_USB_TIMEOUT)
550 {
551 return HAL_TIMEOUT;
552 }
553 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
554
555 /* Flush RX Fifo */
556 count = 0U;
557 USBx->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
558
559 do
560 {
561 count++;
562
563 if (count > HAL_USB_TIMEOUT)
564 {
565 return HAL_TIMEOUT;
566 }
567 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
568
569 return HAL_OK;
570 }
571
572 /**
573 * @brief USB_SetDevSpeed Initializes the DevSpd field of DCFG register
574 * depending the PHY type and the enumeration speed of the device.
575 * @param USBx Selected device
576 * @param speed device speed
577 * This parameter can be one of these values:
578 * @arg USB_OTG_SPEED_HIGH: High speed mode
579 * @arg USB_OTG_SPEED_HIGH_IN_FULL: High speed core in Full Speed mode
580 * @arg USB_OTG_SPEED_FULL: Full speed mode
581 * @retval Hal status
582 */
USB_SetDevSpeed(const USB_OTG_GlobalTypeDef * USBx,uint8_t speed)583 HAL_StatusTypeDef USB_SetDevSpeed(const USB_OTG_GlobalTypeDef *USBx, uint8_t speed)
584 {
585 uint32_t USBx_BASE = (uint32_t)USBx;
586
587 USBx_DEVICE->DCFG |= speed;
588 return HAL_OK;
589 }
590
591 /**
592 * @brief USB_GetDevSpeed Return the Dev Speed
593 * @param USBx Selected device
594 * @retval speed device speed
595 * This parameter can be one of these values:
596 * @arg USBD_HS_SPEED: High speed mode
597 * @arg USBD_FS_SPEED: Full speed mode
598 */
USB_GetDevSpeed(const USB_OTG_GlobalTypeDef * USBx)599 uint8_t USB_GetDevSpeed(const USB_OTG_GlobalTypeDef *USBx)
600 {
601 uint32_t USBx_BASE = (uint32_t)USBx;
602 uint8_t speed;
603 uint32_t DevEnumSpeed = USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD;
604
605 if (DevEnumSpeed == DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ)
606 {
607 speed = USBD_HS_SPEED;
608 }
609 else if ((DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ) ||
610 (DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_48MHZ))
611 {
612 speed = USBD_FS_SPEED;
613 }
614 else
615 {
616 speed = 0xFU;
617 }
618
619 return speed;
620 }
621
622 /**
623 * @brief Activate and configure an endpoint
624 * @param USBx Selected device
625 * @param ep pointer to endpoint structure
626 * @retval HAL status
627 */
USB_ActivateEndpoint(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)628 HAL_StatusTypeDef USB_ActivateEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
629 {
630 uint32_t USBx_BASE = (uint32_t)USBx;
631 uint32_t epnum = (uint32_t)ep->num;
632
633 if (ep->is_in == 1U)
634 {
635 USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK));
636
637 if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_USBAEP) == 0U)
638 {
639 USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) |
640 ((uint32_t)ep->type << 18) | (epnum << 22) |
641 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
642 USB_OTG_DIEPCTL_USBAEP;
643 }
644 }
645 else
646 {
647 USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16);
648
649 if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
650 {
651 USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) |
652 ((uint32_t)ep->type << 18) |
653 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
654 USB_OTG_DOEPCTL_USBAEP;
655 }
656 }
657 return HAL_OK;
658 }
659
660 /**
661 * @brief Activate and configure a dedicated endpoint
662 * @param USBx Selected device
663 * @param ep pointer to endpoint structure
664 * @retval HAL status
665 */
USB_ActivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)666 HAL_StatusTypeDef USB_ActivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
667 {
668 uint32_t USBx_BASE = (uint32_t)USBx;
669 uint32_t epnum = (uint32_t)ep->num;
670
671 /* Read DEPCTLn register */
672 if (ep->is_in == 1U)
673 {
674 if (((USBx_INEP(epnum)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0U)
675 {
676 USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) |
677 ((uint32_t)ep->type << 18) | (epnum << 22) |
678 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
679 USB_OTG_DIEPCTL_USBAEP;
680 }
681
682 USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK));
683 }
684 else
685 {
686 if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
687 {
688 USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) |
689 ((uint32_t)ep->type << 18) | (epnum << 22) |
690 USB_OTG_DOEPCTL_USBAEP;
691 }
692
693 USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16);
694 }
695
696 return HAL_OK;
697 }
698
699 /**
700 * @brief De-activate and de-initialize an endpoint
701 * @param USBx Selected device
702 * @param ep pointer to endpoint structure
703 * @retval HAL status
704 */
USB_DeactivateEndpoint(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)705 HAL_StatusTypeDef USB_DeactivateEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
706 {
707 uint32_t USBx_BASE = (uint32_t)USBx;
708 uint32_t epnum = (uint32_t)ep->num;
709
710 /* Read DEPCTLn register */
711 if (ep->is_in == 1U)
712 {
713 if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
714 {
715 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
716 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS;
717 }
718
719 USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
720 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
721 USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_USBAEP |
722 USB_OTG_DIEPCTL_MPSIZ |
723 USB_OTG_DIEPCTL_TXFNUM |
724 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
725 USB_OTG_DIEPCTL_EPTYP);
726 }
727 else
728 {
729 if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
730 {
731 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
732 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS;
733 }
734
735 USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
736 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
737 USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_USBAEP |
738 USB_OTG_DOEPCTL_MPSIZ |
739 USB_OTG_DOEPCTL_SD0PID_SEVNFRM |
740 USB_OTG_DOEPCTL_EPTYP);
741 }
742
743 return HAL_OK;
744 }
745
746 /**
747 * @brief De-activate and de-initialize a dedicated endpoint
748 * @param USBx Selected device
749 * @param ep pointer to endpoint structure
750 * @retval HAL status
751 */
USB_DeactivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)752 HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
753 {
754 uint32_t USBx_BASE = (uint32_t)USBx;
755 uint32_t epnum = (uint32_t)ep->num;
756
757 /* Read DEPCTLn register */
758 if (ep->is_in == 1U)
759 {
760 if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
761 {
762 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
763 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS;
764 }
765
766 USBx_INEP(epnum)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP;
767 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
768 }
769 else
770 {
771 if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
772 {
773 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
774 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS;
775 }
776
777 USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP;
778 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
779 }
780
781 return HAL_OK;
782 }
783
784 /**
785 * @brief USB_EPStartXfer : setup and starts a transfer over an EP
786 * @param USBx Selected device
787 * @param ep pointer to endpoint structure
788 * @param dma USB dma enabled or disabled
789 * This parameter can be one of these values:
790 * 0 : DMA feature not used
791 * 1 : DMA feature used
792 * @retval HAL status
793 */
USB_EPStartXfer(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep,uint8_t dma)794 HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep, uint8_t dma)
795 {
796 uint32_t USBx_BASE = (uint32_t)USBx;
797 uint32_t epnum = (uint32_t)ep->num;
798 uint16_t pktcnt;
799
800 /* IN endpoint */
801 if (ep->is_in == 1U)
802 {
803 /* Zero Length Packet? */
804 if (ep->xfer_len == 0U)
805 {
806 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
807 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
808 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
809 }
810 else
811 {
812 /* Program the transfer size and packet count
813 * as follows: xfersize = N * maxpacket +
814 * short_packet pktcnt = N + (short_packet
815 * exist ? 1 : 0)
816 */
817 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
818 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
819
820 if (epnum == 0U)
821 {
822 if (ep->xfer_len > ep->maxpacket)
823 {
824 ep->xfer_len = ep->maxpacket;
825 }
826
827 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
828 }
829 else
830 {
831 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT &
832 (((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket) << 19));
833 }
834
835 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
836
837 if (ep->type == EP_TYPE_ISOC)
838 {
839 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT);
840 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1U << 29));
841 }
842 }
843
844 if (dma == 1U)
845 {
846 if ((uint32_t)ep->dma_addr != 0U)
847 {
848 USBx_INEP(epnum)->DIEPDMA = (uint32_t)(ep->dma_addr);
849 }
850
851 if (ep->type == EP_TYPE_ISOC)
852 {
853 if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
854 {
855 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
856 }
857 else
858 {
859 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
860 }
861 }
862
863 /* EP enable, IN data in FIFO */
864 USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
865 }
866 else
867 {
868 /* EP enable, IN data in FIFO */
869 USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
870
871 if (ep->type != EP_TYPE_ISOC)
872 {
873 /* Enable the Tx FIFO Empty Interrupt for this EP */
874 if (ep->xfer_len > 0U)
875 {
876 USBx_DEVICE->DIEPEMPMSK |= 1UL << (ep->num & EP_ADDR_MSK);
877 }
878 }
879 else
880 {
881 if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
882 {
883 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
884 }
885 else
886 {
887 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
888 }
889
890 (void)USB_WritePacket(USBx, ep->xfer_buff, ep->num, (uint16_t)ep->xfer_len, dma);
891 }
892 }
893 }
894 else /* OUT endpoint */
895 {
896 /* Program the transfer size and packet count as follows:
897 * pktcnt = N
898 * xfersize = N * maxpacket
899 */
900 USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
901 USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
902
903 if (epnum == 0U)
904 {
905 if (ep->xfer_len > 0U)
906 {
907 ep->xfer_len = ep->maxpacket;
908 }
909
910 /* Store transfer size, for EP0 this is equal to endpoint max packet size */
911 ep->xfer_size = ep->maxpacket;
912
913 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->xfer_size);
914 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
915 }
916 else
917 {
918 if (ep->xfer_len == 0U)
919 {
920 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket);
921 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
922 }
923 else
924 {
925 pktcnt = (uint16_t)((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket);
926 ep->xfer_size = ep->maxpacket * pktcnt;
927
928 USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_PKTCNT & ((uint32_t)pktcnt << 19);
929 USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_XFRSIZ & ep->xfer_size;
930 }
931 }
932
933 if (dma == 1U)
934 {
935 if ((uint32_t)ep->xfer_buff != 0U)
936 {
937 USBx_OUTEP(epnum)->DOEPDMA = (uint32_t)(ep->xfer_buff);
938 }
939 }
940
941 if (ep->type == EP_TYPE_ISOC)
942 {
943 if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
944 {
945 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM;
946 }
947 else
948 {
949 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
950 }
951 }
952 /* EP enable */
953 USBx_OUTEP(epnum)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
954 }
955
956 return HAL_OK;
957 }
958
959
960 /**
961 * @brief USB_EPStoptXfer Stop transfer on an EP
962 * @param USBx usb device instance
963 * @param ep pointer to endpoint structure
964 * @retval HAL status
965 */
USB_EPStopXfer(const USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep)966 HAL_StatusTypeDef USB_EPStopXfer(const USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
967 {
968 __IO uint32_t count = 0U;
969 HAL_StatusTypeDef ret = HAL_OK;
970 uint32_t USBx_BASE = (uint32_t)USBx;
971
972 /* IN endpoint */
973 if (ep->is_in == 1U)
974 {
975 /* EP enable, IN data in FIFO */
976 if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
977 {
978 USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_SNAK);
979 USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_EPDIS);
980
981 do
982 {
983 count++;
984
985 if (count > 10000U)
986 {
987 ret = HAL_ERROR;
988 break;
989 }
990 } while (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA);
991 }
992 }
993 else /* OUT endpoint */
994 {
995 if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
996 {
997 USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_SNAK);
998 USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_EPDIS);
999
1000 do
1001 {
1002 count++;
1003
1004 if (count > 10000U)
1005 {
1006 ret = HAL_ERROR;
1007 break;
1008 }
1009 } while (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA);
1010 }
1011 }
1012
1013 return ret;
1014 }
1015
1016
1017 /**
1018 * @brief USB_WritePacket : Writes a packet into the Tx FIFO associated
1019 * with the EP/channel
1020 * @param USBx Selected device
1021 * @param src pointer to source buffer
1022 * @param ch_ep_num endpoint or host channel number
1023 * @param len Number of bytes to write
1024 * @param dma USB dma enabled or disabled
1025 * This parameter can be one of these values:
1026 * 0 : DMA feature not used
1027 * 1 : DMA feature used
1028 * @retval HAL status
1029 */
USB_WritePacket(const USB_OTG_GlobalTypeDef * USBx,uint8_t * src,uint8_t ch_ep_num,uint16_t len,uint8_t dma)1030 HAL_StatusTypeDef USB_WritePacket(const USB_OTG_GlobalTypeDef *USBx, uint8_t *src,
1031 uint8_t ch_ep_num, uint16_t len, uint8_t dma)
1032 {
1033 uint32_t USBx_BASE = (uint32_t)USBx;
1034 uint8_t *pSrc = src;
1035 uint32_t count32b;
1036 uint32_t i;
1037
1038 if (dma == 0U)
1039 {
1040 count32b = ((uint32_t)len + 3U) / 4U;
1041 for (i = 0U; i < count32b; i++)
1042 {
1043 USBx_DFIFO((uint32_t)ch_ep_num) = __UNALIGNED_UINT32_READ(pSrc);
1044 pSrc++;
1045 pSrc++;
1046 pSrc++;
1047 pSrc++;
1048 }
1049 }
1050
1051 return HAL_OK;
1052 }
1053
1054 /**
1055 * @brief USB_ReadPacket : read a packet from the RX FIFO
1056 * @param USBx Selected device
1057 * @param dest source pointer
1058 * @param len Number of bytes to read
1059 * @retval pointer to destination buffer
1060 */
USB_ReadPacket(const USB_OTG_GlobalTypeDef * USBx,uint8_t * dest,uint16_t len)1061 void *USB_ReadPacket(const USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len)
1062 {
1063 uint32_t USBx_BASE = (uint32_t)USBx;
1064 uint8_t *pDest = dest;
1065 uint32_t pData;
1066 uint32_t i;
1067 uint32_t count32b = (uint32_t)len >> 2U;
1068 uint16_t remaining_bytes = len % 4U;
1069
1070 for (i = 0U; i < count32b; i++)
1071 {
1072 __UNALIGNED_UINT32_WRITE(pDest, USBx_DFIFO(0U));
1073 pDest++;
1074 pDest++;
1075 pDest++;
1076 pDest++;
1077 }
1078
1079 /* When Number of data is not word aligned, read the remaining byte */
1080 if (remaining_bytes != 0U)
1081 {
1082 i = 0U;
1083 __UNALIGNED_UINT32_WRITE(&pData, USBx_DFIFO(0U));
1084
1085 do
1086 {
1087 *(uint8_t *)pDest = (uint8_t)(pData >> (8U * (uint8_t)(i)));
1088 i++;
1089 pDest++;
1090 remaining_bytes--;
1091 } while (remaining_bytes != 0U);
1092 }
1093
1094 return ((void *)pDest);
1095 }
1096
1097 /**
1098 * @brief USB_EPSetStall : set a stall condition over an EP
1099 * @param USBx Selected device
1100 * @param ep pointer to endpoint structure
1101 * @retval HAL status
1102 */
USB_EPSetStall(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)1103 HAL_StatusTypeDef USB_EPSetStall(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
1104 {
1105 uint32_t USBx_BASE = (uint32_t)USBx;
1106 uint32_t epnum = (uint32_t)ep->num;
1107
1108 if (ep->is_in == 1U)
1109 {
1110 if (((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == 0U) && (epnum != 0U))
1111 {
1112 USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_EPDIS);
1113 }
1114 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
1115 }
1116 else
1117 {
1118 if (((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == 0U) && (epnum != 0U))
1119 {
1120 USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_EPDIS);
1121 }
1122 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;
1123 }
1124
1125 return HAL_OK;
1126 }
1127
1128 /**
1129 * @brief USB_EPClearStall : Clear a stall condition over an EP
1130 * @param USBx Selected device
1131 * @param ep pointer to endpoint structure
1132 * @retval HAL status
1133 */
USB_EPClearStall(const USB_OTG_GlobalTypeDef * USBx,const USB_OTG_EPTypeDef * ep)1134 HAL_StatusTypeDef USB_EPClearStall(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
1135 {
1136 uint32_t USBx_BASE = (uint32_t)USBx;
1137 uint32_t epnum = (uint32_t)ep->num;
1138
1139 if (ep->is_in == 1U)
1140 {
1141 USBx_INEP(epnum)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
1142 if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK))
1143 {
1144 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */
1145 }
1146 }
1147 else
1148 {
1149 USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
1150 if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK))
1151 {
1152 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */
1153 }
1154 }
1155 return HAL_OK;
1156 }
1157
1158 /**
1159 * @brief USB_StopDevice : Stop the usb device mode
1160 * @param USBx Selected device
1161 * @retval HAL status
1162 */
USB_StopDevice(USB_OTG_GlobalTypeDef * USBx)1163 HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx)
1164 {
1165 HAL_StatusTypeDef ret;
1166 uint32_t USBx_BASE = (uint32_t)USBx;
1167 uint32_t i;
1168
1169 /* Clear Pending interrupt */
1170 for (i = 0U; i < 15U; i++)
1171 {
1172 USBx_INEP(i)->DIEPINT = 0xFB7FU;
1173 USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
1174 }
1175
1176 /* Clear interrupt masks */
1177 USBx_DEVICE->DIEPMSK = 0U;
1178 USBx_DEVICE->DOEPMSK = 0U;
1179 USBx_DEVICE->DAINTMSK = 0U;
1180
1181 /* Flush the FIFO */
1182 ret = USB_FlushRxFifo(USBx);
1183 if (ret != HAL_OK)
1184 {
1185 return ret;
1186 }
1187
1188 ret = USB_FlushTxFifo(USBx, 0x10U);
1189 if (ret != HAL_OK)
1190 {
1191 return ret;
1192 }
1193
1194 return ret;
1195 }
1196
1197 /**
1198 * @brief USB_SetDevAddress : Stop the usb device mode
1199 * @param USBx Selected device
1200 * @param address new device address to be assigned
1201 * This parameter can be a value from 0 to 255
1202 * @retval HAL status
1203 */
USB_SetDevAddress(const USB_OTG_GlobalTypeDef * USBx,uint8_t address)1204 HAL_StatusTypeDef USB_SetDevAddress(const USB_OTG_GlobalTypeDef *USBx, uint8_t address)
1205 {
1206 uint32_t USBx_BASE = (uint32_t)USBx;
1207
1208 USBx_DEVICE->DCFG &= ~(USB_OTG_DCFG_DAD);
1209 USBx_DEVICE->DCFG |= ((uint32_t)address << 4) & USB_OTG_DCFG_DAD;
1210
1211 return HAL_OK;
1212 }
1213
1214 /**
1215 * @brief USB_DevConnect : Connect the USB device by enabling Rpu
1216 * @param USBx Selected device
1217 * @retval HAL status
1218 */
USB_DevConnect(const USB_OTG_GlobalTypeDef * USBx)1219 HAL_StatusTypeDef USB_DevConnect(const USB_OTG_GlobalTypeDef *USBx)
1220 {
1221 uint32_t USBx_BASE = (uint32_t)USBx;
1222
1223 /* In case phy is stopped, ensure to ungate and restore the phy CLK */
1224 USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK);
1225
1226 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS;
1227
1228 return HAL_OK;
1229 }
1230
1231 /**
1232 * @brief USB_DevDisconnect : Disconnect the USB device by disabling Rpu
1233 * @param USBx Selected device
1234 * @retval HAL status
1235 */
USB_DevDisconnect(const USB_OTG_GlobalTypeDef * USBx)1236 HAL_StatusTypeDef USB_DevDisconnect(const USB_OTG_GlobalTypeDef *USBx)
1237 {
1238 uint32_t USBx_BASE = (uint32_t)USBx;
1239
1240 /* In case phy is stopped, ensure to ungate and restore the phy CLK */
1241 USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK);
1242
1243 USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
1244
1245 return HAL_OK;
1246 }
1247
1248 /**
1249 * @brief USB_ReadInterrupts: return the global USB interrupt status
1250 * @param USBx Selected device
1251 * @retval USB Global Interrupt status
1252 */
USB_ReadInterrupts(USB_OTG_GlobalTypeDef const * USBx)1253 uint32_t USB_ReadInterrupts(USB_OTG_GlobalTypeDef const *USBx)
1254 {
1255 uint32_t tmpreg;
1256
1257 tmpreg = USBx->GINTSTS;
1258 tmpreg &= USBx->GINTMSK;
1259
1260 return tmpreg;
1261 }
1262
1263 /**
1264 * @brief USB_ReadChInterrupts: return USB channel interrupt status
1265 * @param USBx Selected device
1266 * @param chnum Channel number
1267 * @retval USB Channel Interrupt status
1268 */
USB_ReadChInterrupts(const USB_OTG_GlobalTypeDef * USBx,uint8_t chnum)1269 uint32_t USB_ReadChInterrupts(const USB_OTG_GlobalTypeDef *USBx, uint8_t chnum)
1270 {
1271 uint32_t USBx_BASE = (uint32_t)USBx;
1272 uint32_t tmpreg;
1273
1274 tmpreg = USBx_HC(chnum)->HCINT;
1275 tmpreg &= USBx_HC(chnum)->HCINTMSK;
1276
1277 return tmpreg;
1278 }
1279
1280 /**
1281 * @brief USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status
1282 * @param USBx Selected device
1283 * @retval USB Device OUT EP interrupt status
1284 */
USB_ReadDevAllOutEpInterrupt(const USB_OTG_GlobalTypeDef * USBx)1285 uint32_t USB_ReadDevAllOutEpInterrupt(const USB_OTG_GlobalTypeDef *USBx)
1286 {
1287 uint32_t USBx_BASE = (uint32_t)USBx;
1288 uint32_t tmpreg;
1289
1290 tmpreg = USBx_DEVICE->DAINT;
1291 tmpreg &= USBx_DEVICE->DAINTMSK;
1292
1293 return ((tmpreg & 0xffff0000U) >> 16);
1294 }
1295
1296 /**
1297 * @brief USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status
1298 * @param USBx Selected device
1299 * @retval USB Device IN EP interrupt status
1300 */
USB_ReadDevAllInEpInterrupt(const USB_OTG_GlobalTypeDef * USBx)1301 uint32_t USB_ReadDevAllInEpInterrupt(const USB_OTG_GlobalTypeDef *USBx)
1302 {
1303 uint32_t USBx_BASE = (uint32_t)USBx;
1304 uint32_t tmpreg;
1305
1306 tmpreg = USBx_DEVICE->DAINT;
1307 tmpreg &= USBx_DEVICE->DAINTMSK;
1308
1309 return ((tmpreg & 0xFFFFU));
1310 }
1311
1312 /**
1313 * @brief Returns Device OUT EP Interrupt register
1314 * @param USBx Selected device
1315 * @param epnum endpoint number
1316 * This parameter can be a value from 0 to 15
1317 * @retval Device OUT EP Interrupt register
1318 */
USB_ReadDevOutEPInterrupt(const USB_OTG_GlobalTypeDef * USBx,uint8_t epnum)1319 uint32_t USB_ReadDevOutEPInterrupt(const USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
1320 {
1321 uint32_t USBx_BASE = (uint32_t)USBx;
1322 uint32_t tmpreg;
1323
1324 tmpreg = USBx_OUTEP((uint32_t)epnum)->DOEPINT;
1325 tmpreg &= USBx_DEVICE->DOEPMSK;
1326
1327 return tmpreg;
1328 }
1329
1330 /**
1331 * @brief Returns Device IN EP Interrupt register
1332 * @param USBx Selected device
1333 * @param epnum endpoint number
1334 * This parameter can be a value from 0 to 15
1335 * @retval Device IN EP Interrupt register
1336 */
USB_ReadDevInEPInterrupt(const USB_OTG_GlobalTypeDef * USBx,uint8_t epnum)1337 uint32_t USB_ReadDevInEPInterrupt(const USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
1338 {
1339 uint32_t USBx_BASE = (uint32_t)USBx;
1340 uint32_t tmpreg;
1341 uint32_t msk;
1342 uint32_t emp;
1343
1344 msk = USBx_DEVICE->DIEPMSK;
1345 emp = USBx_DEVICE->DIEPEMPMSK;
1346 msk |= ((emp >> (epnum & EP_ADDR_MSK)) & 0x1U) << 7;
1347 tmpreg = USBx_INEP((uint32_t)epnum)->DIEPINT & msk;
1348
1349 return tmpreg;
1350 }
1351
1352 /**
1353 * @brief USB_ClearInterrupts: clear a USB interrupt
1354 * @param USBx Selected device
1355 * @param interrupt flag
1356 * @retval None
1357 */
USB_ClearInterrupts(USB_OTG_GlobalTypeDef * USBx,uint32_t interrupt)1358 void USB_ClearInterrupts(USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt)
1359 {
1360 USBx->GINTSTS &= interrupt;
1361 }
1362
1363 /**
1364 * @brief Returns USB core mode
1365 * @param USBx Selected device
1366 * @retval return core mode : Host or Device
1367 * This parameter can be one of these values:
1368 * 0 : Host
1369 * 1 : Device
1370 */
USB_GetMode(const USB_OTG_GlobalTypeDef * USBx)1371 uint32_t USB_GetMode(const USB_OTG_GlobalTypeDef *USBx)
1372 {
1373 return ((USBx->GINTSTS) & 0x1U);
1374 }
1375
1376 /**
1377 * @brief Activate EP0 for Setup transactions
1378 * @param USBx Selected device
1379 * @retval HAL status
1380 */
USB_ActivateSetup(const USB_OTG_GlobalTypeDef * USBx)1381 HAL_StatusTypeDef USB_ActivateSetup(const USB_OTG_GlobalTypeDef *USBx)
1382 {
1383 uint32_t USBx_BASE = (uint32_t)USBx;
1384
1385 /* Set the MPS of the IN EP0 to 64 bytes */
1386 USBx_INEP(0U)->DIEPCTL &= ~USB_OTG_DIEPCTL_MPSIZ;
1387
1388 USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK;
1389
1390 return HAL_OK;
1391 }
1392
1393 /**
1394 * @brief Prepare the EP0 to start the first control setup
1395 * @param USBx Selected device
1396 * @param dma USB dma enabled or disabled
1397 * This parameter can be one of these values:
1398 * 0 : DMA feature not used
1399 * 1 : DMA feature used
1400 * @param psetup pointer to setup packet
1401 * @retval HAL status
1402 */
USB_EP0_OutStart(const USB_OTG_GlobalTypeDef * USBx,uint8_t dma,const uint8_t * psetup)1403 HAL_StatusTypeDef USB_EP0_OutStart(const USB_OTG_GlobalTypeDef *USBx, uint8_t dma, const uint8_t *psetup)
1404 {
1405 uint32_t USBx_BASE = (uint32_t)USBx;
1406 uint32_t gSNPSiD = *(__IO const uint32_t *)(&USBx->CID + 0x1U);
1407
1408 if (gSNPSiD > USB_OTG_CORE_ID_300A)
1409 {
1410 if ((USBx_OUTEP(0U)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
1411 {
1412 return HAL_OK;
1413 }
1414 }
1415
1416 USBx_OUTEP(0U)->DOEPTSIZ = 0U;
1417 USBx_OUTEP(0U)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
1418 USBx_OUTEP(0U)->DOEPTSIZ |= (3U * 8U);
1419 USBx_OUTEP(0U)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_STUPCNT;
1420
1421 if (dma == 1U)
1422 {
1423 USBx_OUTEP(0U)->DOEPDMA = (uint32_t)psetup;
1424 /* EP enable */
1425 USBx_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_USBAEP;
1426 }
1427
1428 return HAL_OK;
1429 }
1430
1431 /**
1432 * @brief Reset the USB Core (needed after USB clock settings change)
1433 * @param USBx Selected device
1434 * @retval HAL status
1435 */
USB_CoreReset(USB_OTG_GlobalTypeDef * USBx)1436 static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx)
1437 {
1438 __IO uint32_t count = 0U;
1439
1440 /* Wait for AHB master IDLE state. */
1441 do
1442 {
1443 count++;
1444
1445 if (count > HAL_USB_TIMEOUT)
1446 {
1447 return HAL_TIMEOUT;
1448 }
1449 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
1450
1451 /* Core Soft Reset */
1452 count = 0U;
1453 USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
1454
1455 do
1456 {
1457 count++;
1458
1459 if (count > HAL_USB_TIMEOUT)
1460 {
1461 return HAL_TIMEOUT;
1462 }
1463 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
1464
1465 return HAL_OK;
1466 }
1467
1468 #ifdef USBPHYC
1469 /**
1470 * @brief Enables control of a High Speed USB PHY
1471 * Init the low level hardware : GPIO, CLOCK, NVIC...
1472 * @param USBx Selected device
1473 * @retval HAL status
1474 */
USB_HS_PHYCInit(USB_OTG_GlobalTypeDef * USBx)1475 static HAL_StatusTypeDef USB_HS_PHYCInit(USB_OTG_GlobalTypeDef *USBx)
1476 {
1477 UNUSED(USBx);
1478 __IO uint32_t count = 0U;
1479
1480 /* Enable LDO */
1481 USB_HS_PHYC->USB_HS_PHYC_LDO |= USB_HS_PHYC_LDO_ENABLE;
1482
1483 /* wait for LDO Ready */
1484 while ((USB_HS_PHYC->USB_HS_PHYC_LDO & USB_HS_PHYC_LDO_STATUS) == 0U)
1485 {
1486 count++;
1487
1488 if (count > HAL_USB_TIMEOUT)
1489 {
1490 return HAL_TIMEOUT;
1491 }
1492 }
1493
1494 /* Controls PHY frequency operation selection */
1495 if (HSE_VALUE == PHYC_12_MHZ) /* HSE = 12MHz */
1496 {
1497 USB_HS_PHYC->USB_HS_PHYC_PLL = (0x0U << 1);
1498 }
1499 else if (HSE_VALUE == PHYC_12_5_MHZ) /* HSE = 12.5MHz */
1500 {
1501 USB_HS_PHYC->USB_HS_PHYC_PLL = (0x2U << 1);
1502 }
1503 else if (HSE_VALUE == PHYC_16_MHZ) /* HSE = 16MHz */
1504 {
1505 USB_HS_PHYC->USB_HS_PHYC_PLL = (0x3U << 1);
1506 }
1507 else if (HSE_VALUE == PHYC_24_MHZ) /* HSE = 24MHz */
1508 {
1509 USB_HS_PHYC->USB_HS_PHYC_PLL = (0x4U << 1);
1510 }
1511 else if (HSE_VALUE == PHYC_25_MHZ) /* HSE = 25MHz */
1512 {
1513 USB_HS_PHYC->USB_HS_PHYC_PLL = (0x5U << 1);
1514 }
1515 else if (HSE_VALUE == PHYC_32_MHZ) /* HSE = 32MHz */
1516 {
1517 USB_HS_PHYC->USB_HS_PHYC_PLL = (0x7U << 1);
1518 }
1519 else
1520 {
1521 /* ... */
1522 }
1523
1524 /* Control the tuning interface of the High Speed PHY */
1525 USB_HS_PHYC->USB_HS_PHYC_TUNE |= USB_HS_PHYC_TUNE_VALUE;
1526
1527 /* Enable PLL internal PHY */
1528 USB_HS_PHYC->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL_PLLEN;
1529
1530
1531 /* 2ms Delay required to get internal phy clock stable */
1532 HAL_Delay(2U);
1533
1534 return HAL_OK;
1535 }
1536
1537 #endif /* USBPHYC */
1538 /**
1539 * @brief USB_HostInit : Initializes the USB OTG controller registers
1540 * for Host mode
1541 * @param USBx Selected device
1542 * @param cfg pointer to a USB_OTG_CfgTypeDef structure that contains
1543 * the configuration information for the specified USBx peripheral.
1544 * @retval HAL status
1545 */
USB_HostInit(USB_OTG_GlobalTypeDef * USBx,USB_OTG_CfgTypeDef cfg)1546 HAL_StatusTypeDef USB_HostInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
1547 {
1548 HAL_StatusTypeDef ret = HAL_OK;
1549 uint32_t USBx_BASE = (uint32_t)USBx;
1550 uint32_t i;
1551
1552 /* Restart the Phy Clock */
1553 USBx_PCGCCTL = 0U;
1554
1555 /* Disable VBUS sensing */
1556 USBx->GCCFG &= ~(USB_OTG_GCCFG_VBDEN);
1557
1558 if ((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) == 0U)
1559 {
1560 if (cfg.speed == USBH_FSLS_SPEED)
1561 {
1562 /* Force Device Enumeration to FS/LS mode only */
1563 USBx_HOST->HCFG |= USB_OTG_HCFG_FSLSS;
1564 }
1565 else
1566 {
1567 /* Set default Max speed support */
1568 USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
1569 }
1570 }
1571 else
1572 {
1573 /* Set default Max speed support */
1574 USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
1575 }
1576
1577 /* Make sure the FIFOs are flushed. */
1578 if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
1579 {
1580 ret = HAL_ERROR;
1581 }
1582
1583 if (USB_FlushRxFifo(USBx) != HAL_OK)
1584 {
1585 ret = HAL_ERROR;
1586 }
1587
1588 /* Clear all pending HC Interrupts */
1589 for (i = 0U; i < cfg.Host_channels; i++)
1590 {
1591 USBx_HC(i)->HCINT = CLEAR_INTERRUPT_MASK;
1592 USBx_HC(i)->HCINTMSK = 0U;
1593 }
1594
1595 /* Disable all interrupts. */
1596 USBx->GINTMSK = 0U;
1597
1598 /* Clear any pending interrupts */
1599 USBx->GINTSTS = CLEAR_INTERRUPT_MASK;
1600 #if defined (USB_OTG_HS)
1601 if (USBx == USB_OTG_HS)
1602 {
1603 /* set Rx FIFO size */
1604 USBx->GRXFSIZ = 0x200U;
1605 USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t)(((0x100U << 16) & USB_OTG_NPTXFD) | 0x200U);
1606 USBx->HPTXFSIZ = (uint32_t)(((0xE0U << 16) & USB_OTG_HPTXFSIZ_PTXFD) | 0x300U);
1607 }
1608 else
1609 #endif /* defined (USB_OTG_HS) */
1610 {
1611 /* set Rx FIFO size */
1612 USBx->GRXFSIZ = 0x80U;
1613 USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t)(((0x60U << 16) & USB_OTG_NPTXFD) | 0x80U);
1614 USBx->HPTXFSIZ = (uint32_t)(((0x40U << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0xE0U);
1615 }
1616
1617 /* Enable the common interrupts */
1618 if (cfg.dma_enable == 0U)
1619 {
1620 USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
1621 }
1622
1623 /* Enable interrupts matching to the Host mode ONLY */
1624 USBx->GINTMSK |= (USB_OTG_GINTMSK_PRTIM | USB_OTG_GINTMSK_HCIM | \
1625 USB_OTG_GINTMSK_SOFM | USB_OTG_GINTSTS_DISCINT | \
1626 USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM);
1627
1628 return ret;
1629 }
1630
1631 /**
1632 * @brief USB_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the
1633 * HCFG register on the PHY type and set the right frame interval
1634 * @param USBx Selected device
1635 * @param freq clock frequency
1636 * This parameter can be one of these values:
1637 * HCFG_48_MHZ : Full Speed 48 MHz Clock
1638 * HCFG_6_MHZ : Low Speed 6 MHz Clock
1639 * @retval HAL status
1640 */
USB_InitFSLSPClkSel(const USB_OTG_GlobalTypeDef * USBx,uint8_t freq)1641 HAL_StatusTypeDef USB_InitFSLSPClkSel(const USB_OTG_GlobalTypeDef *USBx, uint8_t freq)
1642 {
1643 uint32_t USBx_BASE = (uint32_t)USBx;
1644
1645 USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSPCS);
1646 USBx_HOST->HCFG |= (uint32_t)freq & USB_OTG_HCFG_FSLSPCS;
1647
1648 if (freq == HCFG_48_MHZ)
1649 {
1650 USBx_HOST->HFIR = HFIR_48_MHZ;
1651 }
1652 else if (freq == HCFG_6_MHZ)
1653 {
1654 USBx_HOST->HFIR = HFIR_6_MHZ;
1655 }
1656 else
1657 {
1658 return HAL_ERROR;
1659 }
1660
1661 return HAL_OK;
1662 }
1663
1664 /**
1665 * @brief USB_OTG_ResetPort : Reset Host Port
1666 * @param USBx Selected device
1667 * @retval HAL status
1668 * @note (1)The application must wait at least 10 ms
1669 * before clearing the reset bit.
1670 */
USB_ResetPort(const USB_OTG_GlobalTypeDef * USBx)1671 HAL_StatusTypeDef USB_ResetPort(const USB_OTG_GlobalTypeDef *USBx)
1672 {
1673 uint32_t USBx_BASE = (uint32_t)USBx;
1674
1675 __IO uint32_t hprt0 = 0U;
1676
1677 hprt0 = USBx_HPRT0;
1678
1679 hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
1680 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
1681
1682 USBx_HPRT0 = (USB_OTG_HPRT_PRST | hprt0);
1683 HAL_Delay(100U); /* See Note #1 */
1684 USBx_HPRT0 = ((~USB_OTG_HPRT_PRST) & hprt0);
1685 HAL_Delay(10U);
1686
1687 return HAL_OK;
1688 }
1689
1690 /**
1691 * @brief USB_DriveVbus : activate or de-activate vbus
1692 * @param state VBUS state
1693 * This parameter can be one of these values:
1694 * 0 : Deactivate VBUS
1695 * 1 : Activate VBUS
1696 * @retval HAL status
1697 */
USB_DriveVbus(const USB_OTG_GlobalTypeDef * USBx,uint8_t state)1698 HAL_StatusTypeDef USB_DriveVbus(const USB_OTG_GlobalTypeDef *USBx, uint8_t state)
1699 {
1700 uint32_t USBx_BASE = (uint32_t)USBx;
1701 __IO uint32_t hprt0 = 0U;
1702
1703 hprt0 = USBx_HPRT0;
1704
1705 hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
1706 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
1707
1708 if (((hprt0 & USB_OTG_HPRT_PPWR) == 0U) && (state == 1U))
1709 {
1710 USBx_HPRT0 = (USB_OTG_HPRT_PPWR | hprt0);
1711 }
1712 if (((hprt0 & USB_OTG_HPRT_PPWR) == USB_OTG_HPRT_PPWR) && (state == 0U))
1713 {
1714 USBx_HPRT0 = ((~USB_OTG_HPRT_PPWR) & hprt0);
1715 }
1716 return HAL_OK;
1717 }
1718
1719 /**
1720 * @brief Return Host Core speed
1721 * @param USBx Selected device
1722 * @retval speed : Host speed
1723 * This parameter can be one of these values:
1724 * @arg HCD_SPEED_HIGH: High speed mode
1725 * @arg HCD_SPEED_FULL: Full speed mode
1726 * @arg HCD_SPEED_LOW: Low speed mode
1727 */
USB_GetHostSpeed(USB_OTG_GlobalTypeDef const * USBx)1728 uint32_t USB_GetHostSpeed(USB_OTG_GlobalTypeDef const *USBx)
1729 {
1730 uint32_t USBx_BASE = (uint32_t)USBx;
1731 __IO uint32_t hprt0 = 0U;
1732
1733 hprt0 = USBx_HPRT0;
1734 return ((hprt0 & USB_OTG_HPRT_PSPD) >> 17);
1735 }
1736
1737 /**
1738 * @brief Return Host Current Frame number
1739 * @param USBx Selected device
1740 * @retval current frame number
1741 */
USB_GetCurrentFrame(USB_OTG_GlobalTypeDef const * USBx)1742 uint32_t USB_GetCurrentFrame(USB_OTG_GlobalTypeDef const *USBx)
1743 {
1744 uint32_t USBx_BASE = (uint32_t)USBx;
1745
1746 return (USBx_HOST->HFNUM & USB_OTG_HFNUM_FRNUM);
1747 }
1748
1749 /**
1750 * @brief Initialize a host channel
1751 * @param USBx Selected device
1752 * @param ch_num Channel number
1753 * This parameter can be a value from 1 to 15
1754 * @param epnum Endpoint number
1755 * This parameter can be a value from 1 to 15
1756 * @param dev_address Current device address
1757 * This parameter can be a value from 0 to 255
1758 * @param speed Current device speed
1759 * This parameter can be one of these values:
1760 * @arg USB_OTG_SPEED_HIGH: High speed mode
1761 * @arg USB_OTG_SPEED_FULL: Full speed mode
1762 * @arg USB_OTG_SPEED_LOW: Low speed mode
1763 * @param ep_type Endpoint Type
1764 * This parameter can be one of these values:
1765 * @arg EP_TYPE_CTRL: Control type
1766 * @arg EP_TYPE_ISOC: Isochronous type
1767 * @arg EP_TYPE_BULK: Bulk type
1768 * @arg EP_TYPE_INTR: Interrupt type
1769 * @param mps Max Packet Size
1770 * This parameter can be a value from 0 to 32K
1771 * @retval HAL state
1772 */
USB_HC_Init(USB_OTG_GlobalTypeDef * USBx,uint8_t ch_num,uint8_t epnum,uint8_t dev_address,uint8_t speed,uint8_t ep_type,uint16_t mps)1773 HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num,
1774 uint8_t epnum, uint8_t dev_address, uint8_t speed,
1775 uint8_t ep_type, uint16_t mps)
1776 {
1777 HAL_StatusTypeDef ret = HAL_OK;
1778 uint32_t USBx_BASE = (uint32_t)USBx;
1779 uint32_t HCcharEpDir;
1780 uint32_t HCcharLowSpeed;
1781 uint32_t HostCoreSpeed;
1782
1783 /* Clear old interrupt conditions for this host channel. */
1784 USBx_HC((uint32_t)ch_num)->HCINT = CLEAR_INTERRUPT_MASK;
1785
1786 /* Enable channel interrupts required for this transfer. */
1787 switch (ep_type)
1788 {
1789 case EP_TYPE_CTRL:
1790 case EP_TYPE_BULK:
1791 USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |
1792 USB_OTG_HCINTMSK_STALLM |
1793 USB_OTG_HCINTMSK_TXERRM |
1794 USB_OTG_HCINTMSK_DTERRM |
1795 USB_OTG_HCINTMSK_AHBERR |
1796 USB_OTG_HCINTMSK_NAKM;
1797
1798 if ((epnum & 0x80U) == 0x80U)
1799 {
1800 USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
1801 }
1802 else
1803 {
1804 #if defined (USB_OTG_HS)
1805 if (USBx == USB_OTG_HS)
1806 {
1807 USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_NYET |
1808 USB_OTG_HCINTMSK_ACKM;
1809 }
1810 #endif /* defined (USB_OTG_HS) */
1811 }
1812 break;
1813
1814 case EP_TYPE_INTR:
1815 USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |
1816 USB_OTG_HCINTMSK_STALLM |
1817 USB_OTG_HCINTMSK_TXERRM |
1818 USB_OTG_HCINTMSK_DTERRM |
1819 USB_OTG_HCINTMSK_NAKM |
1820 USB_OTG_HCINTMSK_AHBERR |
1821 USB_OTG_HCINTMSK_FRMORM;
1822
1823 if ((epnum & 0x80U) == 0x80U)
1824 {
1825 USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
1826 }
1827
1828 break;
1829
1830 case EP_TYPE_ISOC:
1831 USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |
1832 USB_OTG_HCINTMSK_ACKM |
1833 USB_OTG_HCINTMSK_AHBERR |
1834 USB_OTG_HCINTMSK_FRMORM;
1835
1836 if ((epnum & 0x80U) == 0x80U)
1837 {
1838 USBx_HC((uint32_t)ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_BBERRM);
1839 }
1840 break;
1841
1842 default:
1843 ret = HAL_ERROR;
1844 break;
1845 }
1846
1847 /* Clear Hub Start Split transaction */
1848 USBx_HC((uint32_t)ch_num)->HCSPLT = 0U;
1849
1850 /* Enable host channel Halt interrupt */
1851 USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_CHHM;
1852
1853 /* Enable the top level host channel interrupt. */
1854 USBx_HOST->HAINTMSK |= 1UL << (ch_num & 0xFU);
1855
1856 /* Make sure host channel interrupts are enabled. */
1857 USBx->GINTMSK |= USB_OTG_GINTMSK_HCIM;
1858
1859 /* Program the HCCHAR register */
1860 if ((epnum & 0x80U) == 0x80U)
1861 {
1862 HCcharEpDir = (0x1U << 15) & USB_OTG_HCCHAR_EPDIR;
1863 }
1864 else
1865 {
1866 HCcharEpDir = 0U;
1867 }
1868
1869 HostCoreSpeed = USB_GetHostSpeed(USBx);
1870
1871 /* LS device plugged to HUB */
1872 if ((speed == HPRT0_PRTSPD_LOW_SPEED) && (HostCoreSpeed != HPRT0_PRTSPD_LOW_SPEED))
1873 {
1874 HCcharLowSpeed = (0x1U << 17) & USB_OTG_HCCHAR_LSDEV;
1875 }
1876 else
1877 {
1878 HCcharLowSpeed = 0U;
1879 }
1880
1881 USBx_HC((uint32_t)ch_num)->HCCHAR = (((uint32_t)dev_address << 22) & USB_OTG_HCCHAR_DAD) |
1882 ((((uint32_t)epnum & 0x7FU) << 11) & USB_OTG_HCCHAR_EPNUM) |
1883 (((uint32_t)ep_type << 18) & USB_OTG_HCCHAR_EPTYP) |
1884 ((uint32_t)mps & USB_OTG_HCCHAR_MPSIZ) |
1885 USB_OTG_HCCHAR_MC_0 | HCcharEpDir | HCcharLowSpeed;
1886
1887 if ((ep_type == EP_TYPE_INTR) || (ep_type == EP_TYPE_ISOC))
1888 {
1889 USBx_HC((uint32_t)ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
1890 }
1891
1892 return ret;
1893 }
1894
1895 /**
1896 * @brief Start a transfer over a host channel
1897 * @param USBx Selected device
1898 * @param hc pointer to host channel structure
1899 * @param dma USB dma enabled or disabled
1900 * This parameter can be one of these values:
1901 * 0 : DMA feature not used
1902 * 1 : DMA feature used
1903 * @retval HAL state
1904 */
USB_HC_StartXfer(USB_OTG_GlobalTypeDef * USBx,USB_OTG_HCTypeDef * hc,uint8_t dma)1905 HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc, uint8_t dma)
1906 {
1907 uint32_t USBx_BASE = (uint32_t)USBx;
1908 uint32_t ch_num = (uint32_t)hc->ch_num;
1909 __IO uint32_t tmpreg;
1910 uint8_t is_oddframe;
1911 uint16_t len_words;
1912 uint16_t num_packets;
1913 uint16_t max_hc_pkt_count = HC_MAX_PKT_CNT;
1914
1915 #if defined (USB_OTG_HS)
1916 if (USBx == USB_OTG_HS)
1917 {
1918 /* in DMA mode host Core automatically issues ping in case of NYET/NAK */
1919 if (dma == 1U)
1920 {
1921 if (((hc->ep_type == EP_TYPE_CTRL) || (hc->ep_type == EP_TYPE_BULK)) && (hc->do_ssplit == 0U))
1922 {
1923
1924 USBx_HC((uint32_t)ch_num)->HCINTMSK &= ~(USB_OTG_HCINTMSK_NYET |
1925 USB_OTG_HCINTMSK_ACKM |
1926 USB_OTG_HCINTMSK_NAKM);
1927 }
1928 }
1929 else
1930 {
1931 if ((hc->speed == USBH_HS_SPEED) && (hc->do_ping == 1U))
1932 {
1933 (void)USB_DoPing(USBx, hc->ch_num);
1934 return HAL_OK;
1935 }
1936 }
1937 }
1938 #endif /* defined (USB_OTG_HS) */
1939
1940 if (hc->do_ssplit == 1U)
1941 {
1942 /* Set number of packet to 1 for Split transaction */
1943 num_packets = 1U;
1944
1945 if (hc->ep_is_in != 0U)
1946 {
1947 hc->XferSize = (uint32_t)num_packets * hc->max_packet;
1948 }
1949 else
1950 {
1951 if (hc->ep_type == EP_TYPE_ISOC)
1952 {
1953 if (hc->xfer_len > ISO_SPLT_MPS)
1954 {
1955 /* Isochrone Max Packet Size for Split mode */
1956 hc->XferSize = hc->max_packet;
1957 hc->xfer_len = hc->XferSize;
1958
1959 if ((hc->iso_splt_xactPos == HCSPLT_BEGIN) || (hc->iso_splt_xactPos == HCSPLT_MIDDLE))
1960 {
1961 hc->iso_splt_xactPos = HCSPLT_MIDDLE;
1962 }
1963 else
1964 {
1965 hc->iso_splt_xactPos = HCSPLT_BEGIN;
1966 }
1967 }
1968 else
1969 {
1970 hc->XferSize = hc->xfer_len;
1971
1972 if ((hc->iso_splt_xactPos != HCSPLT_BEGIN) && (hc->iso_splt_xactPos != HCSPLT_MIDDLE))
1973 {
1974 hc->iso_splt_xactPos = HCSPLT_FULL;
1975 }
1976 else
1977 {
1978 hc->iso_splt_xactPos = HCSPLT_END;
1979 }
1980 }
1981 }
1982 else
1983 {
1984 if ((dma == 1U) && (hc->xfer_len > hc->max_packet))
1985 {
1986 hc->XferSize = (uint32_t)num_packets * hc->max_packet;
1987 }
1988 else
1989 {
1990 hc->XferSize = hc->xfer_len;
1991 }
1992 }
1993 }
1994 }
1995 else
1996 {
1997 /* Compute the expected number of packets associated to the transfer */
1998 if (hc->xfer_len > 0U)
1999 {
2000 num_packets = (uint16_t)((hc->xfer_len + hc->max_packet - 1U) / hc->max_packet);
2001
2002 if (num_packets > max_hc_pkt_count)
2003 {
2004 num_packets = max_hc_pkt_count;
2005 hc->XferSize = (uint32_t)num_packets * hc->max_packet;
2006 }
2007 }
2008 else
2009 {
2010 num_packets = 1U;
2011 }
2012
2013 /*
2014 * For IN channel HCTSIZ.XferSize is expected to be an integer multiple of
2015 * max_packet size.
2016 */
2017 if (hc->ep_is_in != 0U)
2018 {
2019 hc->XferSize = (uint32_t)num_packets * hc->max_packet;
2020 }
2021 else
2022 {
2023 hc->XferSize = hc->xfer_len;
2024 }
2025 }
2026
2027 /* Initialize the HCTSIZn register */
2028 USBx_HC(ch_num)->HCTSIZ = (hc->XferSize & USB_OTG_HCTSIZ_XFRSIZ) |
2029 (((uint32_t)num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
2030 (((uint32_t)hc->data_pid << 29) & USB_OTG_HCTSIZ_DPID);
2031
2032 if (dma != 0U)
2033 {
2034 /* xfer_buff MUST be 32-bits aligned */
2035 USBx_HC(ch_num)->HCDMA = (uint32_t)hc->xfer_buff;
2036 }
2037
2038 is_oddframe = (((uint32_t)USBx_HOST->HFNUM & 0x01U) != 0U) ? 0U : 1U;
2039 USBx_HC(ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM;
2040 USBx_HC(ch_num)->HCCHAR |= (uint32_t)is_oddframe << 29;
2041
2042 if (hc->do_ssplit == 1U)
2043 {
2044 /* Set Hub start Split transaction */
2045 USBx_HC((uint32_t)ch_num)->HCSPLT = ((uint32_t)hc->hub_addr << USB_OTG_HCSPLT_HUBADDR_Pos) |
2046 (uint32_t)hc->hub_port_nbr | USB_OTG_HCSPLT_SPLITEN;
2047
2048 /* unmask ack & nyet for IN/OUT transactions */
2049 USBx_HC((uint32_t)ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_ACKM |
2050 USB_OTG_HCINTMSK_NYET);
2051
2052 if ((hc->do_csplit == 1U) && (hc->ep_is_in == 0U))
2053 {
2054 USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_COMPLSPLT;
2055 USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_NYET;
2056 }
2057
2058 if (((hc->ep_type == EP_TYPE_ISOC) || (hc->ep_type == EP_TYPE_INTR)) &&
2059 (hc->do_csplit == 1U) && (hc->ep_is_in == 1U))
2060 {
2061 USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_COMPLSPLT;
2062 }
2063
2064 /* Position management for iso out transaction on split mode */
2065 if ((hc->ep_type == EP_TYPE_ISOC) && (hc->ep_is_in == 0U))
2066 {
2067 /* Set data payload position */
2068 switch (hc->iso_splt_xactPos)
2069 {
2070 case HCSPLT_BEGIN:
2071 /* First data payload for OUT Transaction */
2072 USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_XACTPOS_1;
2073 break;
2074
2075 case HCSPLT_MIDDLE:
2076 /* Middle data payload for OUT Transaction */
2077 USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_XACTPOS_Pos;
2078 break;
2079
2080 case HCSPLT_END:
2081 /* End data payload for OUT Transaction */
2082 USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_XACTPOS_0;
2083 break;
2084
2085 case HCSPLT_FULL:
2086 /* Entire data payload for OUT Transaction */
2087 USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_XACTPOS;
2088 break;
2089
2090 default:
2091 break;
2092 }
2093 }
2094 }
2095 else
2096 {
2097 /* Clear Hub Start Split transaction */
2098 USBx_HC((uint32_t)ch_num)->HCSPLT = 0U;
2099 }
2100
2101 /* Set host channel enable */
2102 tmpreg = USBx_HC(ch_num)->HCCHAR;
2103 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
2104
2105 /* make sure to set the correct ep direction */
2106 if (hc->ep_is_in != 0U)
2107 {
2108 tmpreg |= USB_OTG_HCCHAR_EPDIR;
2109 }
2110 else
2111 {
2112 tmpreg &= ~USB_OTG_HCCHAR_EPDIR;
2113 }
2114 tmpreg |= USB_OTG_HCCHAR_CHENA;
2115 USBx_HC(ch_num)->HCCHAR = tmpreg;
2116
2117 if (dma != 0U) /* dma mode */
2118 {
2119 return HAL_OK;
2120 }
2121
2122 if ((hc->ep_is_in == 0U) && (hc->xfer_len > 0U) && (hc->do_csplit == 0U))
2123 {
2124 switch (hc->ep_type)
2125 {
2126 /* Non periodic transfer */
2127 case EP_TYPE_CTRL:
2128 case EP_TYPE_BULK:
2129
2130 len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
2131
2132 /* check if there is enough space in FIFO space */
2133 if (len_words > (USBx->HNPTXSTS & 0xFFFFU))
2134 {
2135 /* need to process data in nptxfempty interrupt */
2136 USBx->GINTMSK |= USB_OTG_GINTMSK_NPTXFEM;
2137 }
2138 break;
2139
2140 /* Periodic transfer */
2141 case EP_TYPE_INTR:
2142 case EP_TYPE_ISOC:
2143 len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
2144 /* check if there is enough space in FIFO space */
2145 if (len_words > (USBx_HOST->HPTXSTS & 0xFFFFU)) /* split the transfer */
2146 {
2147 /* need to process data in ptxfempty interrupt */
2148 USBx->GINTMSK |= USB_OTG_GINTMSK_PTXFEM;
2149 }
2150 break;
2151
2152 default:
2153 break;
2154 }
2155
2156 /* Write packet into the Tx FIFO. */
2157 (void)USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, (uint16_t)hc->xfer_len, 0);
2158 }
2159
2160 return HAL_OK;
2161 }
2162
2163 /**
2164 * @brief Read all host channel interrupts status
2165 * @param USBx Selected device
2166 * @retval HAL state
2167 */
USB_HC_ReadInterrupt(const USB_OTG_GlobalTypeDef * USBx)2168 uint32_t USB_HC_ReadInterrupt(const USB_OTG_GlobalTypeDef *USBx)
2169 {
2170 uint32_t USBx_BASE = (uint32_t)USBx;
2171
2172 return ((USBx_HOST->HAINT) & 0xFFFFU);
2173 }
2174
2175 /**
2176 * @brief Halt a host channel
2177 * @param USBx Selected device
2178 * @param hc_num Host Channel number
2179 * This parameter can be a value from 1 to 15
2180 * @retval HAL state
2181 */
USB_HC_Halt(const USB_OTG_GlobalTypeDef * USBx,uint8_t hc_num)2182 HAL_StatusTypeDef USB_HC_Halt(const USB_OTG_GlobalTypeDef *USBx, uint8_t hc_num)
2183 {
2184 uint32_t USBx_BASE = (uint32_t)USBx;
2185 uint32_t hcnum = (uint32_t)hc_num;
2186 __IO uint32_t count = 0U;
2187 uint32_t HcEpType = (USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_EPTYP) >> 18;
2188 uint32_t ChannelEna = (USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) >> 31;
2189 uint32_t SplitEna = (USBx_HC(hcnum)->HCSPLT & USB_OTG_HCSPLT_SPLITEN) >> 31;
2190
2191 /* In buffer DMA, Channel disable must not be programmed for non-split periodic channels.
2192 At the end of the next uframe/frame (in the worst case), the core generates a channel halted
2193 and disables the channel automatically. */
2194
2195 if ((((USBx->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == USB_OTG_GAHBCFG_DMAEN) && (SplitEna == 0U)) &&
2196 ((ChannelEna == 0U) || (((HcEpType == HCCHAR_ISOC) || (HcEpType == HCCHAR_INTR)))))
2197 {
2198 return HAL_OK;
2199 }
2200
2201 /* Check for space in the request queue to issue the halt. */
2202 if ((HcEpType == HCCHAR_CTRL) || (HcEpType == HCCHAR_BULK))
2203 {
2204 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
2205
2206 if ((USBx->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == 0U)
2207 {
2208 if ((USBx->HNPTXSTS & (0xFFU << 16)) == 0U)
2209 {
2210 USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
2211 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
2212 do
2213 {
2214 count++;
2215
2216 if (count > 1000U)
2217 {
2218 break;
2219 }
2220 } while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
2221 }
2222 else
2223 {
2224 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
2225 }
2226 }
2227 else
2228 {
2229 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
2230 }
2231 }
2232 else
2233 {
2234 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
2235
2236 if ((USBx_HOST->HPTXSTS & (0xFFU << 16)) == 0U)
2237 {
2238 USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
2239 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
2240 do
2241 {
2242 count++;
2243
2244 if (count > 1000U)
2245 {
2246 break;
2247 }
2248 } while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
2249 }
2250 else
2251 {
2252 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
2253 }
2254 }
2255
2256 return HAL_OK;
2257 }
2258
2259 /**
2260 * @brief Initiate Do Ping protocol
2261 * @param USBx Selected device
2262 * @param hc_num Host Channel number
2263 * This parameter can be a value from 1 to 15
2264 * @retval HAL state
2265 */
USB_DoPing(const USB_OTG_GlobalTypeDef * USBx,uint8_t ch_num)2266 HAL_StatusTypeDef USB_DoPing(const USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num)
2267 {
2268 uint32_t USBx_BASE = (uint32_t)USBx;
2269 uint32_t chnum = (uint32_t)ch_num;
2270 uint32_t num_packets = 1U;
2271 uint32_t tmpreg;
2272
2273 USBx_HC(chnum)->HCTSIZ = ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
2274 USB_OTG_HCTSIZ_DOPING;
2275
2276 /* Set host channel enable */
2277 tmpreg = USBx_HC(chnum)->HCCHAR;
2278 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
2279 tmpreg |= USB_OTG_HCCHAR_CHENA;
2280 USBx_HC(chnum)->HCCHAR = tmpreg;
2281
2282 return HAL_OK;
2283 }
2284
2285 /**
2286 * @brief Stop Host Core
2287 * @param USBx Selected device
2288 * @retval HAL state
2289 */
USB_StopHost(USB_OTG_GlobalTypeDef * USBx)2290 HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx)
2291 {
2292 HAL_StatusTypeDef ret = HAL_OK;
2293 uint32_t USBx_BASE = (uint32_t)USBx;
2294 __IO uint32_t count = 0U;
2295 uint32_t value;
2296 uint32_t i;
2297
2298 (void)USB_DisableGlobalInt(USBx);
2299
2300 /* Flush USB FIFO */
2301 if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
2302 {
2303 ret = HAL_ERROR;
2304 }
2305
2306 if (USB_FlushRxFifo(USBx) != HAL_OK)
2307 {
2308 ret = HAL_ERROR;
2309 }
2310
2311 /* Flush out any leftover queued requests. */
2312 for (i = 0U; i <= 15U; i++)
2313 {
2314 value = USBx_HC(i)->HCCHAR;
2315 value |= USB_OTG_HCCHAR_CHDIS;
2316 value &= ~USB_OTG_HCCHAR_CHENA;
2317 value &= ~USB_OTG_HCCHAR_EPDIR;
2318 USBx_HC(i)->HCCHAR = value;
2319 }
2320
2321 /* Halt all channels to put them into a known state. */
2322 for (i = 0U; i <= 15U; i++)
2323 {
2324 value = USBx_HC(i)->HCCHAR;
2325 value |= USB_OTG_HCCHAR_CHDIS;
2326 value |= USB_OTG_HCCHAR_CHENA;
2327 value &= ~USB_OTG_HCCHAR_EPDIR;
2328 USBx_HC(i)->HCCHAR = value;
2329
2330 do
2331 {
2332 count++;
2333
2334 if (count > 1000U)
2335 {
2336 break;
2337 }
2338 } while ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
2339 }
2340
2341 /* Clear any pending Host interrupts */
2342 USBx_HOST->HAINT = CLEAR_INTERRUPT_MASK;
2343 USBx->GINTSTS = CLEAR_INTERRUPT_MASK;
2344
2345 (void)USB_EnableGlobalInt(USBx);
2346
2347 return ret;
2348 }
2349
2350 /**
2351 * @brief USB_ActivateRemoteWakeup active remote wakeup signalling
2352 * @param USBx Selected device
2353 * @retval HAL status
2354 */
USB_ActivateRemoteWakeup(const USB_OTG_GlobalTypeDef * USBx)2355 HAL_StatusTypeDef USB_ActivateRemoteWakeup(const USB_OTG_GlobalTypeDef *USBx)
2356 {
2357 uint32_t USBx_BASE = (uint32_t)USBx;
2358
2359 if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
2360 {
2361 /* active Remote wakeup signalling */
2362 USBx_DEVICE->DCTL |= USB_OTG_DCTL_RWUSIG;
2363 }
2364
2365 return HAL_OK;
2366 }
2367
2368 /**
2369 * @brief USB_DeActivateRemoteWakeup de-active remote wakeup signalling
2370 * @param USBx Selected device
2371 * @retval HAL status
2372 */
USB_DeActivateRemoteWakeup(const USB_OTG_GlobalTypeDef * USBx)2373 HAL_StatusTypeDef USB_DeActivateRemoteWakeup(const USB_OTG_GlobalTypeDef *USBx)
2374 {
2375 uint32_t USBx_BASE = (uint32_t)USBx;
2376
2377 /* active Remote wakeup signalling */
2378 USBx_DEVICE->DCTL &= ~(USB_OTG_DCTL_RWUSIG);
2379
2380 return HAL_OK;
2381 }
2382 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2383
2384 /**
2385 * @}
2386 */
2387
2388 /**
2389 * @}
2390 */
2391 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2392 #endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */
2393
2394 /**
2395 * @}
2396 */
2397