Updated and Validated
[betaflight.git] / lib / main / STM32F7 / Drivers / STM32F7xx_HAL_Driver / Src / stm32f7xx_ll_usb.c
blobb5be3b59d84c3e39db6582ec565c06478628d807
1 /**
2 ******************************************************************************
3 * @file stm32f7xx_ll_usb.c
4 * @author MCD Application Team
5 * @brief USB Low Layer HAL module driver.
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
14 @verbatim
15 ==============================================================================
16 ##### How to use this driver #####
17 ==============================================================================
18 [..]
19 (#) Fill parameters of Init structure in USB_OTG_CfgTypeDef structure.
21 (#) Call USB_CoreInit() API to initialize the USB Core peripheral.
23 (#) The upper HAL HCD/PCD driver will call the right routines for its internal processes.
25 @endverbatim
26 ******************************************************************************
27 * @attention
29 * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
30 * All rights reserved.</center></h2>
32 * This software component is licensed by ST under BSD 3-Clause license,
33 * the "License"; You may not use this file except in compliance with the
34 * License. You may obtain a copy of the License at:
35 * opensource.org/licenses/BSD-3-Clause
37 ******************************************************************************
40 /* Includes ------------------------------------------------------------------*/
41 #include "stm32f7xx_hal.h"
43 /** @addtogroup STM32F7xx_LL_USB_DRIVER
44 * @{
47 #if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED)
48 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
49 /* Private typedef -----------------------------------------------------------*/
50 /* Private define ------------------------------------------------------------*/
51 /* Private macro -------------------------------------------------------------*/
52 /* Private variables ---------------------------------------------------------*/
53 /* Private function prototypes -----------------------------------------------*/
54 /* Private functions ---------------------------------------------------------*/
55 #if defined (USB_OTG_FS) || defined (USB_OTG_HS)
56 static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx);
58 #ifdef USB_HS_PHYC
59 static HAL_StatusTypeDef USB_HS_PHYCInit(USB_OTG_GlobalTypeDef *USBx);
60 #endif
62 /* Exported functions --------------------------------------------------------*/
63 /** @defgroup USB_LL_Exported_Functions USB Low Layer Exported Functions
64 * @{
67 /** @defgroup USB_LL_Exported_Functions_Group1 Initialization/de-initialization functions
68 * @brief Initialization and Configuration functions
70 @verbatim
71 ===============================================================================
72 ##### Initialization/de-initialization functions #####
73 ===============================================================================
75 @endverbatim
76 * @{
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
86 HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
88 HAL_StatusTypeDef ret;
90 if (cfg.phy_itface == USB_OTG_ULPI_PHY)
92 USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
94 /* Init The ULPI Interface */
95 USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL);
97 /* Select vbus source */
98 USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
99 if (cfg.use_external_vbus == 1U)
101 USBx->GUSBCFG |= USB_OTG_GUSBCFG_ULPIEVBUSD;
103 /* Reset after a PHY select */
104 ret = USB_CoreReset(USBx);
106 #ifdef USB_HS_PHYC
107 else if (cfg.phy_itface == USB_OTG_HS_EMBEDDED_PHY)
109 USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
111 /* Init The UTMI Interface */
112 USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL);
114 /* Select vbus source */
115 USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
117 /* Select UTMI Interace */
118 USBx->GUSBCFG &= ~ USB_OTG_GUSBCFG_ULPI_UTMI_SEL;
119 USBx->GCCFG |= USB_OTG_GCCFG_PHYHSEN;
121 /* Enables control of a High Speed USB PHY */
122 if (USB_HS_PHYCInit(USBx) != HAL_OK)
124 return HAL_ERROR;
127 if (cfg.use_external_vbus == 1U)
129 USBx->GUSBCFG |= USB_OTG_GUSBCFG_ULPIEVBUSD;
131 /* Reset after a PHY select */
132 ret = USB_CoreReset(USBx);
134 #endif
135 else /* FS interface (embedded Phy) */
137 /* Select FS Embedded PHY */
138 USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
140 /* Reset after a PHY select and set Host mode */
141 ret = USB_CoreReset(USBx);
143 /* Activate the USB Transceiver */
144 USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
147 if (cfg.dma_enable == 1U)
149 USBx->GAHBCFG |= USB_OTG_GAHBCFG_HBSTLEN_2;
150 USBx->GAHBCFG |= USB_OTG_GAHBCFG_DMAEN;
153 return ret;
158 * @brief Set the USB turnaround time
159 * @param USBx USB Instance
160 * @param hclk: AHB clock frequency
161 * @retval USB turnaround time In PHY Clocks number
163 HAL_StatusTypeDef USB_SetTurnaroundTime(USB_OTG_GlobalTypeDef *USBx,
164 uint32_t hclk, uint8_t speed)
166 uint32_t UsbTrd;
168 /* The USBTRD is configured according to the tables below, depending on AHB frequency
169 used by application. In the low AHB frequency range it is used to stretch enough the USB response
170 time to IN tokens, the USB turnaround time, so to compensate for the longer AHB read access
171 latency to the Data FIFO */
172 if (speed == USB_OTG_SPEED_FULL)
174 if ((hclk >= 14200000U) && (hclk < 15000000U))
176 /* hclk Clock Range between 14.2-15 MHz */
177 UsbTrd = 0xFU;
179 else if ((hclk >= 15000000U) && (hclk < 16000000U))
181 /* hclk Clock Range between 15-16 MHz */
182 UsbTrd = 0xEU;
184 else if ((hclk >= 16000000U) && (hclk < 17200000U))
186 /* hclk Clock Range between 16-17.2 MHz */
187 UsbTrd = 0xDU;
189 else if ((hclk >= 17200000U) && (hclk < 18500000U))
191 /* hclk Clock Range between 17.2-18.5 MHz */
192 UsbTrd = 0xCU;
194 else if ((hclk >= 18500000U) && (hclk < 20000000U))
196 /* hclk Clock Range between 18.5-20 MHz */
197 UsbTrd = 0xBU;
199 else if ((hclk >= 20000000U) && (hclk < 21800000U))
201 /* hclk Clock Range between 20-21.8 MHz */
202 UsbTrd = 0xAU;
204 else if ((hclk >= 21800000U) && (hclk < 24000000U))
206 /* hclk Clock Range between 21.8-24 MHz */
207 UsbTrd = 0x9U;
209 else if ((hclk >= 24000000U) && (hclk < 27700000U))
211 /* hclk Clock Range between 24-27.7 MHz */
212 UsbTrd = 0x8U;
214 else if ((hclk >= 27700000U) && (hclk < 32000000U))
216 /* hclk Clock Range between 27.7-32 MHz */
217 UsbTrd = 0x7U;
219 else /* if(hclk >= 32000000) */
221 /* hclk Clock Range between 32-200 MHz */
222 UsbTrd = 0x6U;
225 else if (speed == USB_OTG_SPEED_HIGH)
227 UsbTrd = USBD_HS_TRDT_VALUE;
229 else
231 UsbTrd = USBD_DEFAULT_TRDT_VALUE;
234 USBx->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
235 USBx->GUSBCFG |= (uint32_t)((UsbTrd << 10) & USB_OTG_GUSBCFG_TRDT);
237 return HAL_OK;
241 * @brief USB_EnableGlobalInt
242 * Enables the controller's Global Int in the AHB Config reg
243 * @param USBx Selected device
244 * @retval HAL status
246 HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
248 USBx->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
249 return HAL_OK;
253 * @brief USB_DisableGlobalInt
254 * Disable the controller's Global Int in the AHB Config reg
255 * @param USBx Selected device
256 * @retval HAL status
258 HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
260 USBx->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
261 return HAL_OK;
265 * @brief USB_SetCurrentMode : Set functional mode
266 * @param USBx Selected device
267 * @param mode current core mode
268 * This parameter can be one of these values:
269 * @arg USB_DEVICE_MODE: Peripheral mode
270 * @arg USB_HOST_MODE: Host mode
271 * @arg USB_DRD_MODE: Dual Role Device mode
272 * @retval HAL status
274 HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx, USB_OTG_ModeTypeDef mode)
276 USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
278 if (mode == USB_HOST_MODE)
280 USBx->GUSBCFG |= USB_OTG_GUSBCFG_FHMOD;
282 else if (mode == USB_DEVICE_MODE)
284 USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
286 else
288 return HAL_ERROR;
290 HAL_Delay(50U);
292 return HAL_OK;
296 * @brief USB_DevInit : Initializes the USB_OTG controller registers
297 * for device mode
298 * @param USBx Selected device
299 * @param cfg pointer to a USB_OTG_CfgTypeDef structure that contains
300 * the configuration information for the specified USBx peripheral.
301 * @retval HAL status
303 HAL_StatusTypeDef USB_DevInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
305 HAL_StatusTypeDef ret = HAL_OK;
306 uint32_t USBx_BASE = (uint32_t)USBx;
307 uint32_t i;
309 for (i = 0U; i < 15U; i++)
311 USBx->DIEPTXF[i] = 0U;
314 /* VBUS Sensing setup */
315 if (cfg.vbus_sensing_enable == 0U)
317 /* Deactivate VBUS Sensing B */
318 USBx->GCCFG &= ~USB_OTG_GCCFG_VBDEN;
320 /* B-peripheral session valid override enable */
321 USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN;
322 USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;
324 else
326 /* Enable HW VBUS sensing */
327 USBx->GCCFG |= USB_OTG_GCCFG_VBDEN;
330 /* Restart the Phy Clock */
331 USBx_PCGCCTL = 0U;
333 /* Device mode configuration */
334 USBx_DEVICE->DCFG |= DCFG_FRAME_INTERVAL_80;
336 if (cfg.phy_itface == USB_OTG_ULPI_PHY)
338 if (cfg.speed == USB_OTG_SPEED_HIGH)
340 /* Set High speed phy */
341 (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_HIGH);
343 else
345 /* set High speed phy in Full speed mode */
346 (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_HIGH_IN_FULL);
349 else if (cfg.phy_itface == USB_OTG_HS_EMBEDDED_PHY)
351 if (cfg.speed == USB_OTG_SPEED_HIGH)
353 /* Set High speed phy */
354 (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_HIGH);
356 else
358 /* set High speed phy in Full speed mode */
359 (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_HIGH_IN_FULL);
362 else
364 /* Set Full speed phy */
365 (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_FULL);
368 /* Flush the FIFOs */
369 if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
371 ret = HAL_ERROR;
374 if (USB_FlushRxFifo(USBx) != HAL_OK)
376 ret = HAL_ERROR;
379 /* Clear all pending Device Interrupts */
380 USBx_DEVICE->DIEPMSK = 0U;
381 USBx_DEVICE->DOEPMSK = 0U;
382 USBx_DEVICE->DAINTMSK = 0U;
384 for (i = 0U; i < cfg.dev_endpoints; i++)
386 if ((USBx_INEP(i)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
388 if (i == 0U)
390 USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_SNAK;
392 else
394 USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK;
397 else
399 USBx_INEP(i)->DIEPCTL = 0U;
402 USBx_INEP(i)->DIEPTSIZ = 0U;
403 USBx_INEP(i)->DIEPINT = 0xFB7FU;
406 for (i = 0U; i < cfg.dev_endpoints; i++)
408 if ((USBx_OUTEP(i)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
410 if (i == 0U)
412 USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_SNAK;
414 else
416 USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK;
419 else
421 USBx_OUTEP(i)->DOEPCTL = 0U;
424 USBx_OUTEP(i)->DOEPTSIZ = 0U;
425 USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
428 USBx_DEVICE->DIEPMSK &= ~(USB_OTG_DIEPMSK_TXFURM);
430 if (cfg.dma_enable == 1U)
432 /*Set threshold parameters */
433 USBx_DEVICE->DTHRCTL = USB_OTG_DTHRCTL_TXTHRLEN_6 |
434 USB_OTG_DTHRCTL_RXTHRLEN_6;
436 USBx_DEVICE->DTHRCTL |= USB_OTG_DTHRCTL_RXTHREN |
437 USB_OTG_DTHRCTL_ISOTHREN |
438 USB_OTG_DTHRCTL_NONISOTHREN;
441 /* Disable all interrupts. */
442 USBx->GINTMSK = 0U;
444 /* Clear any pending interrupts */
445 USBx->GINTSTS = 0xBFFFFFFFU;
447 /* Enable the common interrupts */
448 if (cfg.dma_enable == 0U)
450 USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
453 /* Enable interrupts matching to the Device mode ONLY */
454 USBx->GINTMSK |= USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |
455 USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |
456 USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IISOIXFRM |
457 USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM;
459 if (cfg.Sof_enable != 0U)
461 USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM;
464 if (cfg.vbus_sensing_enable == 1U)
466 USBx->GINTMSK |= (USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_OTGINT);
469 return ret;
473 * @brief USB_OTG_FlushTxFifo : Flush a Tx FIFO
474 * @param USBx Selected device
475 * @param num FIFO number
476 * This parameter can be a value from 1 to 15
477 15 means Flush all Tx FIFOs
478 * @retval HAL status
480 HAL_StatusTypeDef USB_FlushTxFifo(USB_OTG_GlobalTypeDef *USBx, uint32_t num)
482 uint32_t count = 0U;
484 USBx->GRSTCTL = (USB_OTG_GRSTCTL_TXFFLSH | (num << 6));
488 if (++count > 200000U)
490 return HAL_TIMEOUT;
493 while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
495 return HAL_OK;
499 * @brief USB_FlushRxFifo : Flush Rx FIFO
500 * @param USBx Selected device
501 * @retval HAL status
503 HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx)
505 uint32_t count = 0;
507 USBx->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
511 if (++count > 200000U)
513 return HAL_TIMEOUT;
516 while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
518 return HAL_OK;
522 * @brief USB_SetDevSpeed Initializes the DevSpd field of DCFG register
523 * depending the PHY type and the enumeration speed of the device.
524 * @param USBx Selected device
525 * @param speed device speed
526 * This parameter can be one of these values:
527 * @arg USB_OTG_SPEED_HIGH: High speed mode
528 * @arg USB_OTG_SPEED_HIGH_IN_FULL: High speed core in Full Speed mode
529 * @arg USB_OTG_SPEED_FULL: Full speed mode
530 * @retval Hal status
532 HAL_StatusTypeDef USB_SetDevSpeed(USB_OTG_GlobalTypeDef *USBx, uint8_t speed)
534 uint32_t USBx_BASE = (uint32_t)USBx;
536 USBx_DEVICE->DCFG |= speed;
537 return HAL_OK;
541 * @brief USB_GetDevSpeed Return the Dev Speed
542 * @param USBx Selected device
543 * @retval speed device speed
544 * This parameter can be one of these values:
545 * @arg USB_OTG_SPEED_HIGH: High speed mode
546 * @arg USB_OTG_SPEED_FULL: Full speed mode
548 uint8_t USB_GetDevSpeed(USB_OTG_GlobalTypeDef *USBx)
550 uint32_t USBx_BASE = (uint32_t)USBx;
551 uint8_t speed;
552 uint32_t DevEnumSpeed = USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD;
554 if (DevEnumSpeed == DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ)
556 speed = USB_OTG_SPEED_HIGH;
558 else if ((DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ) ||
559 (DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_48MHZ))
561 speed = USB_OTG_SPEED_FULL;
563 else
565 speed = 0U;
568 return speed;
572 * @brief Activate and configure an endpoint
573 * @param USBx Selected device
574 * @param ep pointer to endpoint structure
575 * @retval HAL status
577 HAL_StatusTypeDef USB_ActivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
579 uint32_t USBx_BASE = (uint32_t)USBx;
580 uint32_t epnum = (uint32_t)ep->num;
582 if (ep->is_in == 1U)
584 USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK));
586 if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_USBAEP) == 0U)
588 USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) |
589 ((uint32_t)ep->type << 18) | (epnum << 22) |
590 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
591 USB_OTG_DIEPCTL_USBAEP;
594 else
596 USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16);
598 if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
600 USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) |
601 ((uint32_t)ep->type << 18) |
602 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
603 USB_OTG_DOEPCTL_USBAEP;
606 return HAL_OK;
610 * @brief Activate and configure a dedicated endpoint
611 * @param USBx Selected device
612 * @param ep pointer to endpoint structure
613 * @retval HAL status
615 HAL_StatusTypeDef USB_ActivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
617 uint32_t USBx_BASE = (uint32_t)USBx;
618 uint32_t epnum = (uint32_t)ep->num;
620 /* Read DEPCTLn register */
621 if (ep->is_in == 1U)
623 if (((USBx_INEP(epnum)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0U)
625 USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) |
626 ((uint32_t)ep->type << 18) | (epnum << 22) |
627 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
628 USB_OTG_DIEPCTL_USBAEP;
631 USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK));
633 else
635 if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
637 USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) |
638 ((uint32_t)ep->type << 18) | (epnum << 22) |
639 USB_OTG_DOEPCTL_USBAEP;
642 USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16);
645 return HAL_OK;
649 * @brief De-activate and de-initialize an endpoint
650 * @param USBx Selected device
651 * @param ep pointer to endpoint structure
652 * @retval HAL status
654 HAL_StatusTypeDef USB_DeactivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
656 uint32_t USBx_BASE = (uint32_t)USBx;
657 uint32_t epnum = (uint32_t)ep->num;
659 /* Read DEPCTLn register */
660 if (ep->is_in == 1U)
662 USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
663 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
664 USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_USBAEP |
665 USB_OTG_DIEPCTL_MPSIZ |
666 USB_OTG_DIEPCTL_TXFNUM |
667 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
668 USB_OTG_DIEPCTL_EPTYP);
670 else
672 USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
673 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
674 USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_USBAEP |
675 USB_OTG_DOEPCTL_MPSIZ |
676 USB_OTG_DOEPCTL_SD0PID_SEVNFRM |
677 USB_OTG_DOEPCTL_EPTYP);
680 return HAL_OK;
684 * @brief De-activate and de-initialize a dedicated endpoint
685 * @param USBx Selected device
686 * @param ep pointer to endpoint structure
687 * @retval HAL status
689 HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
691 uint32_t USBx_BASE = (uint32_t)USBx;
692 uint32_t epnum = (uint32_t)ep->num;
694 /* Read DEPCTLn register */
695 if (ep->is_in == 1U)
697 USBx_INEP(epnum)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP;
698 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
700 else
702 USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP;
703 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
706 return HAL_OK;
710 * @brief USB_EPStartXfer : setup and starts a transfer over an EP
711 * @param USBx Selected device
712 * @param ep pointer to endpoint structure
713 * @param dma USB dma enabled or disabled
714 * This parameter can be one of these values:
715 * 0 : DMA feature not used
716 * 1 : DMA feature used
717 * @retval HAL status
719 HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep, uint8_t dma)
721 uint32_t USBx_BASE = (uint32_t)USBx;
722 uint32_t epnum = (uint32_t)ep->num;
723 uint16_t pktcnt;
725 /* IN endpoint */
726 if (ep->is_in == 1U)
728 /* Zero Length Packet? */
729 if (ep->xfer_len == 0U)
731 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
732 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
733 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
735 else
737 /* Program the transfer size and packet count
738 * as follows: xfersize = N * maxpacket +
739 * short_packet pktcnt = N + (short_packet
740 * exist ? 1 : 0)
742 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
743 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
744 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket) << 19));
745 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
747 if (ep->type == EP_TYPE_ISOC)
749 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT);
750 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1U << 29));
754 if (dma == 1U)
756 if ((uint32_t)ep->dma_addr != 0U)
758 USBx_INEP(epnum)->DIEPDMA = (uint32_t)(ep->dma_addr);
761 else
763 if (ep->type != EP_TYPE_ISOC)
765 /* Enable the Tx FIFO Empty Interrupt for this EP */
766 if (ep->xfer_len > 0U)
768 USBx_DEVICE->DIEPEMPMSK |= 1UL << (ep->num & EP_ADDR_MSK);
773 if (ep->type == EP_TYPE_ISOC)
775 if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
777 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
779 else
781 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
785 /* EP enable, IN data in FIFO */
786 USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
788 if (ep->type == EP_TYPE_ISOC)
790 (void)USB_WritePacket(USBx, ep->xfer_buff, ep->num, (uint16_t)ep->xfer_len, dma);
793 else /* OUT endpoint */
795 /* Program the transfer size and packet count as follows:
796 * pktcnt = N
797 * xfersize = N * maxpacket
799 USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
800 USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
802 if (ep->xfer_len == 0U)
804 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket);
805 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
807 else
809 pktcnt = (uint16_t)((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket);
810 USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_PKTCNT & ((uint32_t)pktcnt << 19);
811 USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket * pktcnt);
814 if (dma == 1U)
816 if ((uint32_t)ep->xfer_buff != 0U)
818 USBx_OUTEP(epnum)->DOEPDMA = (uint32_t)(ep->xfer_buff);
822 if (ep->type == EP_TYPE_ISOC)
824 if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
826 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM;
828 else
830 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
833 /* EP enable */
834 USBx_OUTEP(epnum)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
837 return HAL_OK;
841 * @brief USB_EP0StartXfer : setup and starts a transfer over the EP 0
842 * @param USBx Selected device
843 * @param ep pointer to endpoint structure
844 * @param dma USB dma enabled or disabled
845 * This parameter can be one of these values:
846 * 0 : DMA feature not used
847 * 1 : DMA feature used
848 * @retval HAL status
850 HAL_StatusTypeDef USB_EP0StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep, uint8_t dma)
852 uint32_t USBx_BASE = (uint32_t)USBx;
853 uint32_t epnum = (uint32_t)ep->num;
855 /* IN endpoint */
856 if (ep->is_in == 1U)
858 /* Zero Length Packet? */
859 if (ep->xfer_len == 0U)
861 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
862 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
863 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
865 else
867 /* Program the transfer size and packet count
868 * as follows: xfersize = N * maxpacket +
869 * short_packet pktcnt = N + (short_packet
870 * exist ? 1 : 0)
872 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
873 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
875 if (ep->xfer_len > ep->maxpacket)
877 ep->xfer_len = ep->maxpacket;
879 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
880 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
883 if (dma == 1U)
885 if ((uint32_t)ep->dma_addr != 0U)
887 USBx_INEP(epnum)->DIEPDMA = (uint32_t)(ep->dma_addr);
890 else
892 /* Enable the Tx FIFO Empty Interrupt for this EP */
893 if (ep->xfer_len > 0U)
895 USBx_DEVICE->DIEPEMPMSK |= 1UL << (ep->num & EP_ADDR_MSK);
899 /* EP enable, IN data in FIFO */
900 USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
902 else /* OUT endpoint */
904 /* Program the transfer size and packet count as follows:
905 * pktcnt = N
906 * xfersize = N * maxpacket
908 USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
909 USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
911 if (ep->xfer_len > 0U)
913 ep->xfer_len = ep->maxpacket;
916 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
917 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket));
919 if (dma == 1U)
921 if ((uint32_t)ep->xfer_buff != 0U)
923 USBx_OUTEP(epnum)->DOEPDMA = (uint32_t)(ep->xfer_buff);
927 /* EP enable */
928 USBx_OUTEP(epnum)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
931 return HAL_OK;
935 * @brief USB_WritePacket : Writes a packet into the Tx FIFO associated
936 * with the EP/channel
937 * @param USBx Selected device
938 * @param src pointer to source buffer
939 * @param ch_ep_num endpoint or host channel number
940 * @param len Number of bytes to write
941 * @param dma USB dma enabled or disabled
942 * This parameter can be one of these values:
943 * 0 : DMA feature not used
944 * 1 : DMA feature used
945 * @retval HAL status
947 HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len, uint8_t dma)
949 uint32_t USBx_BASE = (uint32_t)USBx;
950 uint32_t *pSrc = (uint32_t *)src;
951 uint32_t count32b, i;
953 if (dma == 0U)
955 count32b = ((uint32_t)len + 3U) / 4U;
956 for (i = 0U; i < count32b; i++)
958 USBx_DFIFO((uint32_t)ch_ep_num) = *((uint32_t *)pSrc);
959 pSrc++;
963 return HAL_OK;
967 * @brief USB_ReadPacket : read a packet from the Tx FIFO associated
968 * with the EP/channel
969 * @param USBx Selected device
970 * @param dest source pointer
971 * @param len Number of bytes to read
972 * @param dma USB dma enabled or disabled
973 * This parameter can be one of these values:
974 * 0 : DMA feature not used
975 * 1 : DMA feature used
976 * @retval pointer to destination buffer
978 void *USB_ReadPacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len)
980 uint32_t USBx_BASE = (uint32_t)USBx;
981 uint32_t *pDest = (uint32_t *)dest;
982 uint32_t i;
983 uint32_t count32b = ((uint32_t)len + 3U) / 4U;
985 for (i = 0U; i < count32b; i++)
987 *(uint32_t *)pDest = USBx_DFIFO(0U);
988 pDest++;
991 return ((void *)pDest);
995 * @brief USB_EPSetStall : set a stall condition over an EP
996 * @param USBx Selected device
997 * @param ep pointer to endpoint structure
998 * @retval HAL status
1000 HAL_StatusTypeDef USB_EPSetStall(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
1002 uint32_t USBx_BASE = (uint32_t)USBx;
1003 uint32_t epnum = (uint32_t)ep->num;
1005 if (ep->is_in == 1U)
1007 if (((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == 0U) && (epnum != 0U))
1009 USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_EPDIS);
1011 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
1013 else
1015 if (((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == 0U) && (epnum != 0U))
1017 USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_EPDIS);
1019 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;
1022 return HAL_OK;
1026 * @brief USB_EPClearStall : Clear a stall condition over an EP
1027 * @param USBx Selected device
1028 * @param ep pointer to endpoint structure
1029 * @retval HAL status
1031 HAL_StatusTypeDef USB_EPClearStall(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
1033 uint32_t USBx_BASE = (uint32_t)USBx;
1034 uint32_t epnum = (uint32_t)ep->num;
1036 if (ep->is_in == 1U)
1038 USBx_INEP(epnum)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
1039 if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK))
1041 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */
1044 else
1046 USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
1047 if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK))
1049 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */
1052 return HAL_OK;
1056 * @brief USB_StopDevice : Stop the usb device mode
1057 * @param USBx Selected device
1058 * @retval HAL status
1060 HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx)
1062 HAL_StatusTypeDef ret;
1063 uint32_t USBx_BASE = (uint32_t)USBx;
1064 uint32_t i;
1066 /* Clear Pending interrupt */
1067 for (i = 0U; i < 15U; i++)
1069 USBx_INEP(i)->DIEPINT = 0xFB7FU;
1070 USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
1073 /* Clear interrupt masks */
1074 USBx_DEVICE->DIEPMSK = 0U;
1075 USBx_DEVICE->DOEPMSK = 0U;
1076 USBx_DEVICE->DAINTMSK = 0U;
1078 /* Flush the FIFO */
1079 ret = USB_FlushRxFifo(USBx);
1080 if (ret != HAL_OK)
1082 return ret;
1085 ret = USB_FlushTxFifo(USBx, 0x10U);
1086 if (ret != HAL_OK)
1088 return ret;
1091 return ret;
1095 * @brief USB_SetDevAddress : Stop the usb device mode
1096 * @param USBx Selected device
1097 * @param address new device address to be assigned
1098 * This parameter can be a value from 0 to 255
1099 * @retval HAL status
1101 HAL_StatusTypeDef USB_SetDevAddress(USB_OTG_GlobalTypeDef *USBx, uint8_t address)
1103 uint32_t USBx_BASE = (uint32_t)USBx;
1105 USBx_DEVICE->DCFG &= ~(USB_OTG_DCFG_DAD);
1106 USBx_DEVICE->DCFG |= ((uint32_t)address << 4) & USB_OTG_DCFG_DAD;
1108 return HAL_OK;
1112 * @brief USB_DevConnect : Connect the USB device by enabling the pull-up/pull-down
1113 * @param USBx Selected device
1114 * @retval HAL status
1116 HAL_StatusTypeDef USB_DevConnect(USB_OTG_GlobalTypeDef *USBx)
1118 uint32_t USBx_BASE = (uint32_t)USBx;
1120 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS;
1121 HAL_Delay(3U);
1123 return HAL_OK;
1127 * @brief USB_DevDisconnect : Disconnect the USB device by disabling the pull-up/pull-down
1128 * @param USBx Selected device
1129 * @retval HAL status
1131 HAL_StatusTypeDef USB_DevDisconnect(USB_OTG_GlobalTypeDef *USBx)
1133 uint32_t USBx_BASE = (uint32_t)USBx;
1135 USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
1136 HAL_Delay(3U);
1138 return HAL_OK;
1142 * @brief USB_ReadInterrupts: return the global USB interrupt status
1143 * @param USBx Selected device
1144 * @retval HAL status
1146 uint32_t USB_ReadInterrupts(USB_OTG_GlobalTypeDef *USBx)
1148 uint32_t tmpreg;
1150 tmpreg = USBx->GINTSTS;
1151 tmpreg &= USBx->GINTMSK;
1153 return tmpreg;
1157 * @brief USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status
1158 * @param USBx Selected device
1159 * @retval HAL status
1161 uint32_t USB_ReadDevAllOutEpInterrupt(USB_OTG_GlobalTypeDef *USBx)
1163 uint32_t USBx_BASE = (uint32_t)USBx;
1164 uint32_t tmpreg;
1166 tmpreg = USBx_DEVICE->DAINT;
1167 tmpreg &= USBx_DEVICE->DAINTMSK;
1169 return ((tmpreg & 0xffff0000U) >> 16);
1173 * @brief USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status
1174 * @param USBx Selected device
1175 * @retval HAL status
1177 uint32_t USB_ReadDevAllInEpInterrupt(USB_OTG_GlobalTypeDef *USBx)
1179 uint32_t USBx_BASE = (uint32_t)USBx;
1180 uint32_t tmpreg;
1182 tmpreg = USBx_DEVICE->DAINT;
1183 tmpreg &= USBx_DEVICE->DAINTMSK;
1185 return ((tmpreg & 0xFFFFU));
1189 * @brief Returns Device OUT EP Interrupt register
1190 * @param USBx Selected device
1191 * @param epnum endpoint number
1192 * This parameter can be a value from 0 to 15
1193 * @retval Device OUT EP Interrupt register
1195 uint32_t USB_ReadDevOutEPInterrupt(USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
1197 uint32_t USBx_BASE = (uint32_t)USBx;
1198 uint32_t tmpreg;
1200 tmpreg = USBx_OUTEP((uint32_t)epnum)->DOEPINT;
1201 tmpreg &= USBx_DEVICE->DOEPMSK;
1203 return tmpreg;
1207 * @brief Returns Device IN EP Interrupt register
1208 * @param USBx Selected device
1209 * @param epnum endpoint number
1210 * This parameter can be a value from 0 to 15
1211 * @retval Device IN EP Interrupt register
1213 uint32_t USB_ReadDevInEPInterrupt(USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
1215 uint32_t USBx_BASE = (uint32_t)USBx;
1216 uint32_t tmpreg, msk, emp;
1218 msk = USBx_DEVICE->DIEPMSK;
1219 emp = USBx_DEVICE->DIEPEMPMSK;
1220 msk |= ((emp >> (epnum & EP_ADDR_MSK)) & 0x1U) << 7;
1221 tmpreg = USBx_INEP((uint32_t)epnum)->DIEPINT & msk;
1223 return tmpreg;
1227 * @brief USB_ClearInterrupts: clear a USB interrupt
1228 * @param USBx Selected device
1229 * @param interrupt interrupt flag
1230 * @retval None
1232 void USB_ClearInterrupts(USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt)
1234 USBx->GINTSTS |= interrupt;
1238 * @brief Returns USB core mode
1239 * @param USBx Selected device
1240 * @retval return core mode : Host or Device
1241 * This parameter can be one of these values:
1242 * 0 : Host
1243 * 1 : Device
1245 uint32_t USB_GetMode(USB_OTG_GlobalTypeDef *USBx)
1247 return ((USBx->GINTSTS) & 0x1U);
1251 * @brief Activate EP0 for Setup transactions
1252 * @param USBx Selected device
1253 * @retval HAL status
1255 HAL_StatusTypeDef USB_ActivateSetup(USB_OTG_GlobalTypeDef *USBx)
1257 uint32_t USBx_BASE = (uint32_t)USBx;
1259 /* Set the MPS of the IN EP based on the enumeration speed */
1260 USBx_INEP(0U)->DIEPCTL &= ~USB_OTG_DIEPCTL_MPSIZ;
1262 if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_LS_PHY_6MHZ)
1264 USBx_INEP(0U)->DIEPCTL |= 3U;
1266 USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK;
1268 return HAL_OK;
1272 * @brief Prepare the EP0 to start the first control setup
1273 * @param USBx Selected device
1274 * @param dma USB dma enabled or disabled
1275 * This parameter can be one of these values:
1276 * 0 : DMA feature not used
1277 * 1 : DMA feature used
1278 * @param psetup pointer to setup packet
1279 * @retval HAL status
1281 HAL_StatusTypeDef USB_EP0_OutStart(USB_OTG_GlobalTypeDef *USBx, uint8_t dma, uint8_t *psetup)
1283 uint32_t USBx_BASE = (uint32_t)USBx;
1284 uint32_t gSNPSiD = *(__IO uint32_t *)(&USBx->CID + 0x1U);
1286 if (gSNPSiD > USB_OTG_CORE_ID_300A)
1288 if ((USBx_OUTEP(0U)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
1290 return HAL_OK;
1294 USBx_OUTEP(0U)->DOEPTSIZ = 0U;
1295 USBx_OUTEP(0U)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
1296 USBx_OUTEP(0U)->DOEPTSIZ |= (3U * 8U);
1297 USBx_OUTEP(0U)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_STUPCNT;
1299 if (dma == 1U)
1301 USBx_OUTEP(0U)->DOEPDMA = (uint32_t)psetup;
1302 /* EP enable */
1303 USBx_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_USBAEP;
1306 return HAL_OK;
1310 * @brief Reset the USB Core (needed after USB clock settings change)
1311 * @param USBx Selected device
1312 * @retval HAL status
1314 static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx)
1316 uint32_t count = 0U;
1318 /* Wait for AHB master IDLE state. */
1321 if (++count > 200000U)
1323 return HAL_TIMEOUT;
1326 while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
1328 /* Core Soft Reset */
1329 count = 0U;
1330 USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
1334 if (++count > 200000U)
1336 return HAL_TIMEOUT;
1339 while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
1341 return HAL_OK;
1344 #ifdef USB_HS_PHYC
1346 * @brief Enables control of a High Speed USB PHYÂ’s
1347 * Init the low level hardware : GPIO, CLOCK, NVIC...
1348 * @param USBx Selected device
1349 * @retval HAL status
1351 static HAL_StatusTypeDef USB_HS_PHYCInit(USB_OTG_GlobalTypeDef *USBx)
1353 UNUSED(USBx);
1354 uint32_t count = 0U;
1356 /* Enable LDO */
1357 USB_HS_PHYC->USB_HS_PHYC_LDO |= USB_HS_PHYC_LDO_ENABLE;
1359 /* wait for LDO Ready */
1360 while ((USB_HS_PHYC->USB_HS_PHYC_LDO & USB_HS_PHYC_LDO_STATUS) == 0U)
1362 if (++count > 200000U)
1364 return HAL_TIMEOUT;
1368 /* Controls PHY frequency operation selection */
1369 if (HSE_VALUE == 12000000U) /* HSE = 12MHz */
1371 USB_HS_PHYC->USB_HS_PHYC_PLL = (0x0U << 1);
1373 else if (HSE_VALUE == 12500000U) /* HSE = 12.5MHz */
1375 USB_HS_PHYC->USB_HS_PHYC_PLL = (0x2U << 1);
1377 else if (HSE_VALUE == 16000000U) /* HSE = 16MHz */
1379 USB_HS_PHYC->USB_HS_PHYC_PLL = (0x3U << 1);
1381 else if (HSE_VALUE == 24000000U) /* HSE = 24MHz */
1383 USB_HS_PHYC->USB_HS_PHYC_PLL = (0x4U << 1);
1385 else if (HSE_VALUE == 25000000U) /* HSE = 25MHz */
1387 USB_HS_PHYC->USB_HS_PHYC_PLL = (0x5U << 1);
1389 else if (HSE_VALUE == 32000000U) /* HSE = 32MHz */
1391 USB_HS_PHYC->USB_HS_PHYC_PLL = (0x7U << 1);
1393 else
1395 /* ... */
1398 /* Control the tuning interface of the High Speed PHY */
1399 USB_HS_PHYC->USB_HS_PHYC_TUNE |= USB_HS_PHYC_TUNE_VALUE;
1401 /* Enable PLL internal PHY */
1402 USB_HS_PHYC->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL_PLLEN;
1404 /* 2ms Delay required to get internal phy clock stable */
1405 HAL_Delay(2U);
1407 return HAL_OK;
1410 #endif /* USB_HS_PHYC */
1412 * @brief USB_HostInit : Initializes the USB OTG controller registers
1413 * for Host mode
1414 * @param USBx Selected device
1415 * @param cfg pointer to a USB_OTG_CfgTypeDef structure that contains
1416 * the configuration information for the specified USBx peripheral.
1417 * @retval HAL status
1419 HAL_StatusTypeDef USB_HostInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
1421 uint32_t USBx_BASE = (uint32_t)USBx;
1422 uint32_t i;
1424 /* Restart the Phy Clock */
1425 USBx_PCGCCTL = 0U;
1427 /* Disable VBUS sensing */
1428 USBx->GCCFG &= ~(USB_OTG_GCCFG_VBDEN);
1430 if ((USBx->CID & (0x1U << 8)) != 0U)
1432 if (cfg.speed == USB_OTG_SPEED_FULL)
1434 /* Force Device Enumeration to FS/LS mode only */
1435 USBx_HOST->HCFG |= USB_OTG_HCFG_FSLSS;
1437 else
1439 /* Set default Max speed support */
1440 USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
1443 else
1445 /* Set default Max speed support */
1446 USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
1449 /* Make sure the FIFOs are flushed. */
1450 (void)USB_FlushTxFifo(USBx, 0x10U); /* all Tx FIFOs */
1451 (void)USB_FlushRxFifo(USBx);
1453 /* Clear all pending HC Interrupts */
1454 for (i = 0U; i < cfg.Host_channels; i++)
1456 USBx_HC(i)->HCINT = 0xFFFFFFFFU;
1457 USBx_HC(i)->HCINTMSK = 0U;
1460 /* Enable VBUS driving */
1461 (void)USB_DriveVbus(USBx, 1U);
1463 HAL_Delay(200U);
1465 /* Disable all interrupts. */
1466 USBx->GINTMSK = 0U;
1468 /* Clear any pending interrupts */
1469 USBx->GINTSTS = 0xFFFFFFFFU;
1471 if ((USBx->CID & (0x1U << 8)) != 0U)
1473 /* set Rx FIFO size */
1474 USBx->GRXFSIZ = 0x200U;
1475 USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t)(((0x100U << 16) & USB_OTG_NPTXFD) | 0x200U);
1476 USBx->HPTXFSIZ = (uint32_t)(((0xE0U << 16) & USB_OTG_HPTXFSIZ_PTXFD) | 0x300U);
1478 else
1480 /* set Rx FIFO size */
1481 USBx->GRXFSIZ = 0x80U;
1482 USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t)(((0x60U << 16) & USB_OTG_NPTXFD) | 0x80U);
1483 USBx->HPTXFSIZ = (uint32_t)(((0x40U << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0xE0U);
1486 /* Enable the common interrupts */
1487 if (cfg.dma_enable == 0U)
1489 USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
1492 /* Enable interrupts matching to the Host mode ONLY */
1493 USBx->GINTMSK |= (USB_OTG_GINTMSK_PRTIM | USB_OTG_GINTMSK_HCIM | \
1494 USB_OTG_GINTMSK_SOFM | USB_OTG_GINTSTS_DISCINT | \
1495 USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM);
1497 return HAL_OK;
1501 * @brief USB_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the
1502 * HCFG register on the PHY type and set the right frame interval
1503 * @param USBx Selected device
1504 * @param freq clock frequency
1505 * This parameter can be one of these values:
1506 * HCFG_48_MHZ : Full Speed 48 MHz Clock
1507 * HCFG_6_MHZ : Low Speed 6 MHz Clock
1508 * @retval HAL status
1510 HAL_StatusTypeDef USB_InitFSLSPClkSel(USB_OTG_GlobalTypeDef *USBx, uint8_t freq)
1512 uint32_t USBx_BASE = (uint32_t)USBx;
1514 USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSPCS);
1515 USBx_HOST->HCFG |= (uint32_t)freq & USB_OTG_HCFG_FSLSPCS;
1517 if (freq == HCFG_48_MHZ)
1519 USBx_HOST->HFIR = 48000U;
1521 else if (freq == HCFG_6_MHZ)
1523 USBx_HOST->HFIR = 6000U;
1525 else
1527 /* ... */
1530 return HAL_OK;
1534 * @brief USB_OTG_ResetPort : Reset Host Port
1535 * @param USBx Selected device
1536 * @retval HAL status
1537 * @note (1)The application must wait at least 10 ms
1538 * before clearing the reset bit.
1540 HAL_StatusTypeDef USB_ResetPort(USB_OTG_GlobalTypeDef *USBx)
1542 uint32_t USBx_BASE = (uint32_t)USBx;
1544 __IO uint32_t hprt0 = 0U;
1546 hprt0 = USBx_HPRT0;
1548 hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
1549 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
1551 USBx_HPRT0 = (USB_OTG_HPRT_PRST | hprt0);
1552 HAL_Delay(100U); /* See Note #1 */
1553 USBx_HPRT0 = ((~USB_OTG_HPRT_PRST) & hprt0);
1554 HAL_Delay(10U);
1556 return HAL_OK;
1560 * @brief USB_DriveVbus : activate or de-activate vbus
1561 * @param state VBUS state
1562 * This parameter can be one of these values:
1563 * 0 : VBUS Active
1564 * 1 : VBUS Inactive
1565 * @retval HAL status
1567 HAL_StatusTypeDef USB_DriveVbus(USB_OTG_GlobalTypeDef *USBx, uint8_t state)
1569 uint32_t USBx_BASE = (uint32_t)USBx;
1570 __IO uint32_t hprt0 = 0U;
1572 hprt0 = USBx_HPRT0;
1574 hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
1575 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
1577 if (((hprt0 & USB_OTG_HPRT_PPWR) == 0U) && (state == 1U))
1579 USBx_HPRT0 = (USB_OTG_HPRT_PPWR | hprt0);
1581 if (((hprt0 & USB_OTG_HPRT_PPWR) == USB_OTG_HPRT_PPWR) && (state == 0U))
1583 USBx_HPRT0 = ((~USB_OTG_HPRT_PPWR) & hprt0);
1585 return HAL_OK;
1589 * @brief Return Host Core speed
1590 * @param USBx Selected device
1591 * @retval speed : Host speed
1592 * This parameter can be one of these values:
1593 * @arg USB_OTG_SPEED_HIGH: High speed mode
1594 * @arg USB_OTG_SPEED_FULL: Full speed mode
1595 * @arg USB_OTG_SPEED_LOW: Low speed mode
1597 uint32_t USB_GetHostSpeed(USB_OTG_GlobalTypeDef *USBx)
1599 uint32_t USBx_BASE = (uint32_t)USBx;
1600 __IO uint32_t hprt0 = 0U;
1602 hprt0 = USBx_HPRT0;
1603 return ((hprt0 & USB_OTG_HPRT_PSPD) >> 17);
1607 * @brief Return Host Current Frame number
1608 * @param USBx Selected device
1609 * @retval current frame number
1611 uint32_t USB_GetCurrentFrame(USB_OTG_GlobalTypeDef *USBx)
1613 uint32_t USBx_BASE = (uint32_t)USBx;
1615 return (USBx_HOST->HFNUM & USB_OTG_HFNUM_FRNUM);
1619 * @brief Initialize a host channel
1620 * @param USBx Selected device
1621 * @param ch_num Channel number
1622 * This parameter can be a value from 1 to 15
1623 * @param epnum Endpoint number
1624 * This parameter can be a value from 1 to 15
1625 * @param dev_address Current device address
1626 * This parameter can be a value from 0 to 255
1627 * @param speed Current device speed
1628 * This parameter can be one of these values:
1629 * @arg USB_OTG_SPEED_HIGH: High speed mode
1630 * @arg USB_OTG_SPEED_FULL: Full speed mode
1631 * @arg USB_OTG_SPEED_LOW: Low speed mode
1632 * @param ep_type Endpoint Type
1633 * This parameter can be one of these values:
1634 * @arg EP_TYPE_CTRL: Control type
1635 * @arg EP_TYPE_ISOC: Isochronous type
1636 * @arg EP_TYPE_BULK: Bulk type
1637 * @arg EP_TYPE_INTR: Interrupt type
1638 * @param mps Max Packet Size
1639 * This parameter can be a value from 0 to32K
1640 * @retval HAL state
1642 HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx,
1643 uint8_t ch_num,
1644 uint8_t epnum,
1645 uint8_t dev_address,
1646 uint8_t speed,
1647 uint8_t ep_type,
1648 uint16_t mps)
1650 HAL_StatusTypeDef ret = HAL_OK;
1651 uint32_t USBx_BASE = (uint32_t)USBx;
1652 uint32_t HCcharEpDir, HCcharLowSpeed;
1654 /* Clear old interrupt conditions for this host channel. */
1655 USBx_HC((uint32_t)ch_num)->HCINT = 0xFFFFFFFFU;
1657 /* Enable channel interrupts required for this transfer. */
1658 switch (ep_type)
1660 case EP_TYPE_CTRL:
1661 case EP_TYPE_BULK:
1662 USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |
1663 USB_OTG_HCINTMSK_STALLM |
1664 USB_OTG_HCINTMSK_TXERRM |
1665 USB_OTG_HCINTMSK_DTERRM |
1666 USB_OTG_HCINTMSK_AHBERR |
1667 USB_OTG_HCINTMSK_NAKM;
1669 if ((epnum & 0x80U) == 0x80U)
1671 USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
1673 else
1675 if ((USBx->CID & (0x1U << 8)) != 0U)
1677 USBx_HC((uint32_t)ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_NYET | USB_OTG_HCINTMSK_ACKM);
1680 break;
1682 case EP_TYPE_INTR:
1683 USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |
1684 USB_OTG_HCINTMSK_STALLM |
1685 USB_OTG_HCINTMSK_TXERRM |
1686 USB_OTG_HCINTMSK_DTERRM |
1687 USB_OTG_HCINTMSK_NAKM |
1688 USB_OTG_HCINTMSK_AHBERR |
1689 USB_OTG_HCINTMSK_FRMORM;
1691 if ((epnum & 0x80U) == 0x80U)
1693 USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
1696 break;
1698 case EP_TYPE_ISOC:
1699 USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |
1700 USB_OTG_HCINTMSK_ACKM |
1701 USB_OTG_HCINTMSK_AHBERR |
1702 USB_OTG_HCINTMSK_FRMORM;
1704 if ((epnum & 0x80U) == 0x80U)
1706 USBx_HC((uint32_t)ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_BBERRM);
1708 break;
1710 default:
1711 ret = HAL_ERROR;
1712 break;
1715 /* Enable the top level host channel interrupt. */
1716 USBx_HOST->HAINTMSK |= 1UL << (ch_num & 0xFU);
1718 /* Make sure host channel interrupts are enabled. */
1719 USBx->GINTMSK |= USB_OTG_GINTMSK_HCIM;
1721 /* Program the HCCHAR register */
1722 if ((epnum & 0x80U) == 0x80U)
1724 HCcharEpDir = (0x1U << 15) & USB_OTG_HCCHAR_EPDIR;
1726 else
1728 HCcharEpDir = 0U;
1731 if (speed == HPRT0_PRTSPD_LOW_SPEED)
1733 HCcharLowSpeed = (0x1U << 17) & USB_OTG_HCCHAR_LSDEV;
1735 else
1737 HCcharLowSpeed = 0U;
1740 USBx_HC((uint32_t)ch_num)->HCCHAR = (((uint32_t)dev_address << 22) & USB_OTG_HCCHAR_DAD) |
1741 ((((uint32_t)epnum & 0x7FU) << 11) & USB_OTG_HCCHAR_EPNUM) |
1742 (((uint32_t)ep_type << 18) & USB_OTG_HCCHAR_EPTYP) |
1743 ((uint32_t)mps & USB_OTG_HCCHAR_MPSIZ) | HCcharEpDir | HCcharLowSpeed;
1745 if (ep_type == EP_TYPE_INTR)
1747 USBx_HC((uint32_t)ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM ;
1750 return ret;
1754 * @brief Start a transfer over a host channel
1755 * @param USBx Selected device
1756 * @param hc pointer to host channel structure
1757 * @param dma USB dma enabled or disabled
1758 * This parameter can be one of these values:
1759 * 0 : DMA feature not used
1760 * 1 : DMA feature used
1761 * @retval HAL state
1763 HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc, uint8_t dma)
1765 uint32_t USBx_BASE = (uint32_t)USBx;
1766 uint32_t ch_num = (uint32_t)hc->ch_num;
1767 static __IO uint32_t tmpreg = 0U;
1768 uint8_t is_oddframe;
1769 uint16_t len_words;
1770 uint16_t num_packets;
1771 uint16_t max_hc_pkt_count = 256U;
1773 if (((USBx->CID & (0x1U << 8)) != 0U) && (hc->speed == USB_OTG_SPEED_HIGH))
1775 if ((dma == 0U) && (hc->do_ping == 1U))
1777 (void)USB_DoPing(USBx, hc->ch_num);
1778 return HAL_OK;
1780 else if (dma == 1U)
1782 USBx_HC(ch_num)->HCINTMSK &= ~(USB_OTG_HCINTMSK_NYET | USB_OTG_HCINTMSK_ACKM);
1783 hc->do_ping = 0U;
1785 else
1787 /* ... */
1791 /* Compute the expected number of packets associated to the transfer */
1792 if (hc->xfer_len > 0U)
1794 num_packets = (uint16_t)((hc->xfer_len + hc->max_packet - 1U) / hc->max_packet);
1796 if (num_packets > max_hc_pkt_count)
1798 num_packets = max_hc_pkt_count;
1799 hc->xfer_len = (uint32_t)num_packets * hc->max_packet;
1802 else
1804 num_packets = 1U;
1806 if (hc->ep_is_in != 0U)
1808 hc->xfer_len = (uint32_t)num_packets * hc->max_packet;
1811 /* Initialize the HCTSIZn register */
1812 USBx_HC(ch_num)->HCTSIZ = (hc->xfer_len & USB_OTG_HCTSIZ_XFRSIZ) |
1813 (((uint32_t)num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
1814 (((uint32_t)hc->data_pid << 29) & USB_OTG_HCTSIZ_DPID);
1816 if (dma != 0U)
1818 /* xfer_buff MUST be 32-bits aligned */
1819 USBx_HC(ch_num)->HCDMA = (uint32_t)hc->xfer_buff;
1822 is_oddframe = (((uint32_t)USBx_HOST->HFNUM & 0x01U) != 0U) ? 0U : 1U;
1823 USBx_HC(ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM;
1824 USBx_HC(ch_num)->HCCHAR |= (uint32_t)is_oddframe << 29;
1826 /* Set host channel enable */
1827 tmpreg = USBx_HC(ch_num)->HCCHAR;
1828 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1830 /* make sure to set the correct ep direction */
1831 if (hc->ep_is_in != 0U)
1833 tmpreg |= USB_OTG_HCCHAR_EPDIR;
1835 else
1837 tmpreg &= ~USB_OTG_HCCHAR_EPDIR;
1839 tmpreg |= USB_OTG_HCCHAR_CHENA;
1840 USBx_HC(ch_num)->HCCHAR = tmpreg;
1842 if (dma == 0U) /* Slave mode */
1844 if ((hc->ep_is_in == 0U) && (hc->xfer_len > 0U))
1846 switch (hc->ep_type)
1848 /* Non periodic transfer */
1849 case EP_TYPE_CTRL:
1850 case EP_TYPE_BULK:
1852 len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
1854 /* check if there is enough space in FIFO space */
1855 if (len_words > (USBx->HNPTXSTS & 0xFFFFU))
1857 /* need to process data in nptxfempty interrupt */
1858 USBx->GINTMSK |= USB_OTG_GINTMSK_NPTXFEM;
1860 break;
1862 /* Periodic transfer */
1863 case EP_TYPE_INTR:
1864 case EP_TYPE_ISOC:
1865 len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
1866 /* check if there is enough space in FIFO space */
1867 if (len_words > (USBx_HOST->HPTXSTS & 0xFFFFU)) /* split the transfer */
1869 /* need to process data in ptxfempty interrupt */
1870 USBx->GINTMSK |= USB_OTG_GINTMSK_PTXFEM;
1872 break;
1874 default:
1875 break;
1878 /* Write packet into the Tx FIFO. */
1879 (void)USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, (uint16_t)hc->xfer_len, 0);
1883 return HAL_OK;
1887 * @brief Read all host channel interrupts status
1888 * @param USBx Selected device
1889 * @retval HAL state
1891 uint32_t USB_HC_ReadInterrupt(USB_OTG_GlobalTypeDef *USBx)
1893 uint32_t USBx_BASE = (uint32_t)USBx;
1895 return ((USBx_HOST->HAINT) & 0xFFFFU);
1899 * @brief Halt a host channel
1900 * @param USBx Selected device
1901 * @param hc_num Host Channel number
1902 * This parameter can be a value from 1 to 15
1903 * @retval HAL state
1905 HAL_StatusTypeDef USB_HC_Halt(USB_OTG_GlobalTypeDef *USBx, uint8_t hc_num)
1907 uint32_t USBx_BASE = (uint32_t)USBx;
1908 uint32_t hcnum = (uint32_t)hc_num;
1909 uint32_t count = 0U;
1910 uint32_t HcEpType = (USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_EPTYP) >> 18;
1912 /* Check for space in the request queue to issue the halt. */
1913 if ((HcEpType == HCCHAR_CTRL) || (HcEpType == HCCHAR_BULK))
1915 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
1917 if ((USBx->HNPTXSTS & (0xFFU << 16)) == 0U)
1919 USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
1920 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1921 USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR;
1924 if (++count > 1000U)
1926 break;
1929 while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
1931 else
1933 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1936 else
1938 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
1940 if ((USBx_HOST->HPTXSTS & (0xFFU << 16)) == 0U)
1942 USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
1943 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1944 USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR;
1947 if (++count > 1000U)
1949 break;
1952 while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
1954 else
1956 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1960 return HAL_OK;
1964 * @brief Initiate Do Ping protocol
1965 * @param USBx Selected device
1966 * @param hc_num Host Channel number
1967 * This parameter can be a value from 1 to 15
1968 * @retval HAL state
1970 HAL_StatusTypeDef USB_DoPing(USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num)
1972 uint32_t USBx_BASE = (uint32_t)USBx;
1973 uint32_t chnum = (uint32_t)ch_num;
1974 uint32_t num_packets = 1U;
1975 uint32_t tmpreg;
1977 USBx_HC(chnum)->HCTSIZ = ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
1978 USB_OTG_HCTSIZ_DOPING;
1980 /* Set host channel enable */
1981 tmpreg = USBx_HC(chnum)->HCCHAR;
1982 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1983 tmpreg |= USB_OTG_HCCHAR_CHENA;
1984 USBx_HC(chnum)->HCCHAR = tmpreg;
1986 return HAL_OK;
1990 * @brief Stop Host Core
1991 * @param USBx Selected device
1992 * @retval HAL state
1994 HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx)
1996 uint32_t USBx_BASE = (uint32_t)USBx;
1997 uint32_t count = 0U;
1998 uint32_t value;
1999 uint32_t i;
2002 (void)USB_DisableGlobalInt(USBx);
2004 /* Flush FIFO */
2005 (void)USB_FlushTxFifo(USBx, 0x10U);
2006 (void)USB_FlushRxFifo(USBx);
2008 /* Flush out any leftover queued requests. */
2009 for (i = 0U; i <= 15U; i++)
2011 value = USBx_HC(i)->HCCHAR;
2012 value |= USB_OTG_HCCHAR_CHDIS;
2013 value &= ~USB_OTG_HCCHAR_CHENA;
2014 value &= ~USB_OTG_HCCHAR_EPDIR;
2015 USBx_HC(i)->HCCHAR = value;
2018 /* Halt all channels to put them into a known state. */
2019 for (i = 0U; i <= 15U; i++)
2021 value = USBx_HC(i)->HCCHAR;
2022 value |= USB_OTG_HCCHAR_CHDIS;
2023 value |= USB_OTG_HCCHAR_CHENA;
2024 value &= ~USB_OTG_HCCHAR_EPDIR;
2025 USBx_HC(i)->HCCHAR = value;
2029 if (++count > 1000U)
2031 break;
2034 while ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
2037 /* Clear any pending Host interrupts */
2038 USBx_HOST->HAINT = 0xFFFFFFFFU;
2039 USBx->GINTSTS = 0xFFFFFFFFU;
2040 (void)USB_EnableGlobalInt(USBx);
2042 return HAL_OK;
2046 * @brief USB_ActivateRemoteWakeup active remote wakeup signalling
2047 * @param USBx Selected device
2048 * @retval HAL status
2050 HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx)
2052 uint32_t USBx_BASE = (uint32_t)USBx;
2054 if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
2056 /* active Remote wakeup signalling */
2057 USBx_DEVICE->DCTL |= USB_OTG_DCTL_RWUSIG;
2060 return HAL_OK;
2064 * @brief USB_DeActivateRemoteWakeup de-active remote wakeup signalling
2065 * @param USBx Selected device
2066 * @retval HAL status
2068 HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx)
2070 uint32_t USBx_BASE = (uint32_t)USBx;
2072 /* active Remote wakeup signalling */
2073 USBx_DEVICE->DCTL &= ~(USB_OTG_DCTL_RWUSIG);
2075 return HAL_OK;
2077 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2081 * @}
2085 * @}
2087 #endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2088 #endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */
2091 * @}
2094 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/