Update MixerProfile.md
[inav.git] / lib / main / STM32F4 / Drivers / STM32F4xx_HAL_Driver / Src / stm32f4xx_ll_usb.c
blob14fedd0d01014d180b611590e0bf6dfa419a76dd
1 /**
2 ******************************************************************************
3 * @file stm32f4xx_ll_usb.c
4 * @author MCD Application Team
5 * @version V1.7.1
6 * @date 14-April-2017
7 * @brief USB Low Layer HAL module driver.
8 *
9 * This file provides firmware functions to manage the following
10 * functionalities of the USB Peripheral Controller:
11 * + Initialization/de-initialization functions
12 * + I/O operation functions
13 * + Peripheral Control functions
14 * + Peripheral State functions
16 @verbatim
17 ==============================================================================
18 ##### How to use this driver #####
19 ==============================================================================
20 [..]
21 (#) Fill parameters of Init structure in USB_OTG_CfgTypeDef structure.
23 (#) Call USB_CoreInit() API to initialize the USB Core peripheral.
25 (#) The upper HAL HCD/PCD driver will call the right routines for its internal processes.
27 @endverbatim
28 ******************************************************************************
29 * @attention
31 * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
33 * Redistribution and use in source and binary forms, with or without modification,
34 * are permitted provided that the following conditions are met:
35 * 1. Redistributions of source code must retain the above copyright notice,
36 * this list of conditions and the following disclaimer.
37 * 2. Redistributions in binary form must reproduce the above copyright notice,
38 * this list of conditions and the following disclaimer in the documentation
39 * and/or other materials provided with the distribution.
40 * 3. Neither the name of STMicroelectronics nor the names of its contributors
41 * may be used to endorse or promote products derived from this software
42 * without specific prior written permission.
44 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
45 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
47 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
48 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
50 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
51 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
52 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
55 ******************************************************************************
56 */
58 /* Includes ------------------------------------------------------------------*/
59 #include "stm32f4xx_hal.h"
61 /** @addtogroup STM32F4xx_LL_USB_DRIVER
62 * @{
65 #if defined(HAL_PCD_MODULE_ENABLED) || defined(HAL_HCD_MODULE_ENABLED)
66 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || \
67 defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || \
68 defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) || \
69 defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || \
70 defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
71 /* Private typedef -----------------------------------------------------------*/
72 /* Private define ------------------------------------------------------------*/
73 /* Private macro -------------------------------------------------------------*/
74 /* Private variables ---------------------------------------------------------*/
75 /* Private function prototypes -----------------------------------------------*/
76 /* Private functions ---------------------------------------------------------*/
77 static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx);
79 /* Exported functions --------------------------------------------------------*/
81 /** @defgroup LL_USB_Exported_Functions USB Low Layer Exported Functions
82 * @{
85 /** @defgroup LL_USB_Group1 Initialization/de-initialization functions
86 * @brief Initialization and Configuration functions
88 @verbatim
89 ===============================================================================
90 ##### Initialization/de-initialization functions #####
91 ===============================================================================
92 [..] This section provides functions allowing to:
94 @endverbatim
95 * @{
98 /**
99 * @brief Initializes the USB Core
100 * @param USBx: USB Instance
101 * @param cfg : pointer to a USB_OTG_CfgTypeDef structure that contains
102 * the configuration information for the specified USBx peripheral.
103 * @retval HAL status
105 HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
107 if (cfg.phy_itface == USB_OTG_ULPI_PHY)
110 USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
112 /* Init The ULPI Interface */
113 USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL);
115 /* Select vbus source */
116 USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
117 if(cfg.use_external_vbus == 1U)
119 USBx->GUSBCFG |= USB_OTG_GUSBCFG_ULPIEVBUSD;
121 /* Reset after a PHY select */
122 USB_CoreReset(USBx);
124 else /* FS interface (embedded Phy) */
126 /* Select FS Embedded PHY */
127 USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
129 /* Reset after a PHY select and set Host mode */
130 USB_CoreReset(USBx);
132 /* Deactivate the power down*/
133 USBx->GCCFG = USB_OTG_GCCFG_PWRDWN;
136 if(cfg.dma_enable == ENABLE)
138 USBx->GAHBCFG |= USB_OTG_GAHBCFG_HBSTLEN_2;
139 USBx->GAHBCFG |= USB_OTG_GAHBCFG_DMAEN;
142 return HAL_OK;
146 * @brief USB_EnableGlobalInt
147 * Enables the controller's Global Int in the AHB Config reg
148 * @param USBx : Selected device
149 * @retval HAL status
151 HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
153 USBx->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
154 return HAL_OK;
159 * @brief USB_DisableGlobalInt
160 * Disable the controller's Global Int in the AHB Config reg
161 * @param USBx : Selected device
162 * @retval HAL status
164 HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
166 USBx->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
167 return HAL_OK;
171 * @brief USB_SetCurrentMode : Set functional mode
172 * @param USBx : Selected device
173 * @param mode : current core mode
174 * This parameter can be one of these values:
175 * @arg USB_OTG_DEVICE_MODE: Peripheral mode
176 * @arg USB_OTG_HOST_MODE: Host mode
177 * @arg USB_OTG_DRD_MODE: Dual Role Device mode
178 * @retval HAL status
180 HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx , USB_OTG_ModeTypeDef mode)
182 USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
184 if ( mode == USB_OTG_HOST_MODE)
186 USBx->GUSBCFG |= USB_OTG_GUSBCFG_FHMOD;
188 else if ( mode == USB_OTG_DEVICE_MODE)
190 USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
192 HAL_Delay(50U);
194 return HAL_OK;
198 * @brief USB_DevInit : Initializes the USB_OTG controller registers
199 * for device mode
200 * @param USBx : Selected device
201 * @param cfg : pointer to a USB_OTG_CfgTypeDef structure that contains
202 * the configuration information for the specified USBx peripheral.
203 * @retval HAL status
205 HAL_StatusTypeDef USB_DevInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
207 uint32_t i = 0U;
209 /*Activate VBUS Sensing B */
210 #if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || \
211 defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
212 USBx->GCCFG |= USB_OTG_GCCFG_VBDEN;
214 if (cfg.vbus_sensing_enable == 0U)
216 /* Deactivate VBUS Sensing B */
217 USBx->GCCFG &= ~USB_OTG_GCCFG_VBDEN;
219 /* B-peripheral session valid override enable*/
220 USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN;
221 USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;
223 #else
224 if (cfg.vbus_sensing_enable == 0U)
226 USBx->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS;
228 else
230 /* Enable VBUS */
231 USBx->GCCFG |= USB_OTG_GCCFG_VBUSBSEN;
233 #endif /* STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Rx || STM32F412Vx || STM32F412Cx || STM32F413xx || STM32F423xx */
235 /* Restart the Phy Clock */
236 USBx_PCGCCTL = 0U;
238 /* Device mode configuration */
239 USBx_DEVICE->DCFG |= DCFG_FRAME_INTERVAL_80;
241 if(cfg.phy_itface == USB_OTG_ULPI_PHY)
243 if(cfg.speed == USB_OTG_SPEED_HIGH)
245 /* Set High speed phy */
246 USB_SetDevSpeed (USBx , USB_OTG_SPEED_HIGH);
248 else
250 /* set High speed phy in Full speed mode */
251 USB_SetDevSpeed (USBx , USB_OTG_SPEED_HIGH_IN_FULL);
254 else
256 /* Set Full speed phy */
257 USB_SetDevSpeed (USBx , USB_OTG_SPEED_FULL);
260 /* Flush the FIFOs */
261 USB_FlushTxFifo(USBx , 0x10U); /* all Tx FIFOs */
262 USB_FlushRxFifo(USBx);
264 /* Clear all pending Device Interrupts */
265 USBx_DEVICE->DIEPMSK = 0U;
266 USBx_DEVICE->DOEPMSK = 0U;
267 USBx_DEVICE->DAINT = 0xFFFFFFFFU;
268 USBx_DEVICE->DAINTMSK = 0U;
270 for (i = 0U; i < cfg.dev_endpoints; i++)
272 if ((USBx_INEP(i)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
274 USBx_INEP(i)->DIEPCTL = (USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK);
276 else
278 USBx_INEP(i)->DIEPCTL = 0U;
281 USBx_INEP(i)->DIEPTSIZ = 0U;
282 USBx_INEP(i)->DIEPINT = 0xFFU;
285 for (i = 0U; i < cfg.dev_endpoints; i++)
287 if ((USBx_OUTEP(i)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
289 USBx_OUTEP(i)->DOEPCTL = (USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK);
291 else
293 USBx_OUTEP(i)->DOEPCTL = 0U;
296 USBx_OUTEP(i)->DOEPTSIZ = 0U;
297 USBx_OUTEP(i)->DOEPINT = 0xFFU;
300 USBx_DEVICE->DIEPMSK &= ~(USB_OTG_DIEPMSK_TXFURM);
302 if (cfg.dma_enable == 1U)
304 /*Set threshold parameters */
305 USBx_DEVICE->DTHRCTL = (USB_OTG_DTHRCTL_TXTHRLEN_6 | USB_OTG_DTHRCTL_RXTHRLEN_6);
306 USBx_DEVICE->DTHRCTL |= (USB_OTG_DTHRCTL_RXTHREN | USB_OTG_DTHRCTL_ISOTHREN | USB_OTG_DTHRCTL_NONISOTHREN);
308 i= USBx_DEVICE->DTHRCTL;
311 /* Disable all interrupts. */
312 USBx->GINTMSK = 0U;
314 /* Clear any pending interrupts */
315 USBx->GINTSTS = 0xBFFFFFFFU;
317 /* Enable the common interrupts */
318 if (cfg.dma_enable == DISABLE)
320 USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
323 /* Enable interrupts matching to the Device mode ONLY */
324 USBx->GINTMSK |= (USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |\
325 USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |\
326 USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IISOIXFRM|\
327 USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM);
329 if(cfg.Sof_enable)
331 USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM;
334 if (cfg.vbus_sensing_enable == ENABLE)
336 USBx->GINTMSK |= (USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_OTGINT);
339 return HAL_OK;
344 * @brief USB_OTG_FlushTxFifo : Flush a Tx FIFO
345 * @param USBx : Selected device
346 * @param num : FIFO number
347 * This parameter can be a value from 1 to 15
348 15 means Flush all Tx FIFOs
349 * @retval HAL status
351 HAL_StatusTypeDef USB_FlushTxFifo (USB_OTG_GlobalTypeDef *USBx, uint32_t num )
353 uint32_t count = 0;
355 USBx->GRSTCTL = ( USB_OTG_GRSTCTL_TXFFLSH |(uint32_t)( num << 6));
359 if (++count > 200000)
361 return HAL_TIMEOUT;
364 while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
366 return HAL_OK;
371 * @brief USB_FlushRxFifo : Flush Rx FIFO
372 * @param USBx : Selected device
373 * @retval HAL status
375 HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx)
377 uint32_t count = 0;
379 USBx->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
383 if (++count > 200000)
385 return HAL_TIMEOUT;
388 while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
390 return HAL_OK;
394 * @brief USB_SetDevSpeed :Initializes the DevSpd field of DCFG register
395 * depending the PHY type and the enumeration speed of the device.
396 * @param USBx : Selected device
397 * @param speed : device speed
398 * This parameter can be one of these values:
399 * @arg USB_OTG_SPEED_HIGH: High speed mode
400 * @arg USB_OTG_SPEED_HIGH_IN_FULL: High speed core in Full Speed mode
401 * @arg USB_OTG_SPEED_FULL: Full speed mode
402 * @arg USB_OTG_SPEED_LOW: Low speed mode
403 * @retval Hal status
405 HAL_StatusTypeDef USB_SetDevSpeed(USB_OTG_GlobalTypeDef *USBx , uint8_t speed)
407 USBx_DEVICE->DCFG |= speed;
408 return HAL_OK;
412 * @brief USB_GetDevSpeed :Return the Dev Speed
413 * @param USBx : Selected device
414 * @retval speed : device speed
415 * This parameter can be one of these values:
416 * @arg USB_OTG_SPEED_HIGH: High speed mode
417 * @arg USB_OTG_SPEED_FULL: Full speed mode
418 * @arg USB_OTG_SPEED_LOW: Low speed mode
420 uint8_t USB_GetDevSpeed(USB_OTG_GlobalTypeDef *USBx)
422 uint8_t speed = 0U;
424 if((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ)
426 speed = USB_OTG_SPEED_HIGH;
428 else if (((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ)||
429 ((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_FS_PHY_48MHZ))
431 speed = USB_OTG_SPEED_FULL;
433 else if((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_LS_PHY_6MHZ)
435 speed = USB_OTG_SPEED_LOW;
438 return speed;
442 * @brief Activate and configure an endpoint
443 * @param USBx : Selected device
444 * @param ep: pointer to endpoint structure
445 * @retval HAL status
447 HAL_StatusTypeDef USB_ActivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
449 if (ep->is_in == 1U)
451 USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & ((1U << (ep->num)));
453 if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0U)
455 USBx_INEP(ep->num)->DIEPCTL |= ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18U) |\
456 ((ep->num) << 22U) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP));
459 else
461 USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & ((1U << (ep->num)) << 16U);
463 if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
465 USBx_OUTEP(ep->num)->DOEPCTL |= ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18U) |\
466 (USB_OTG_DIEPCTL_SD0PID_SEVNFRM)| (USB_OTG_DOEPCTL_USBAEP));
469 return HAL_OK;
472 * @brief Activate and configure a dedicated endpoint
473 * @param USBx : Selected device
474 * @param ep: pointer to endpoint structure
475 * @retval HAL status
477 HAL_StatusTypeDef USB_ActivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
479 static __IO uint32_t debug = 0U;
481 /* Read DEPCTLn register */
482 if (ep->is_in == 1U)
484 if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0U)
486 USBx_INEP(ep->num)->DIEPCTL |= ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18U) |\
487 ((ep->num) << 22U) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP));
491 debug |= ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18U) |\
492 ((ep->num) << 22U) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP));
494 USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_IEPM & ((1U << (ep->num)));
496 else
498 if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
500 USBx_OUTEP(ep->num)->DOEPCTL |= ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18U) |\
501 ((ep->num) << 22U) | (USB_OTG_DOEPCTL_USBAEP));
503 debug = (uint32_t)(((uint32_t )USBx) + USB_OTG_OUT_ENDPOINT_BASE + (0U)*USB_OTG_EP_REG_SIZE);
504 debug = (uint32_t )&USBx_OUTEP(ep->num)->DOEPCTL;
505 debug |= ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18U) |\
506 ((ep->num) << 22U) | (USB_OTG_DOEPCTL_USBAEP));
509 USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_OEPM & ((1U << (ep->num)) << 16U);
512 return HAL_OK;
515 * @brief De-activate and de-initialize an endpoint
516 * @param USBx : Selected device
517 * @param ep: pointer to endpoint structure
518 * @retval HAL status
520 HAL_StatusTypeDef USB_DeactivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
522 uint32_t count = 0U;
524 /* Disable the IN endpoint */
525 if (ep->is_in == 1U)
527 USBx_INEP(ep->num)->DIEPCTL &= ~USB_OTG_DIEPCTL_USBAEP;
529 /* sets the NAK bit for the IN endpoint */
530 USBx_INEP(ep->num)->DIEPCTL = USB_OTG_DIEPCTL_SNAK;
532 /* Disable IN endpoint */
533 USBx_INEP(ep->num)->DIEPCTL = USB_OTG_DIEPCTL_EPDIS;
537 if (++count > 200000U)
539 return HAL_TIMEOUT;
543 /*Wait for EPDISD endpoint disabled interrupt*/
544 while ((USBx_INEP(ep->num)->DIEPINT & USB_OTG_DIEPCTL_EPDIS) == USB_OTG_DIEPCTL_EPDIS);
547 /* Flush any data remaining in the TxFIFO */
548 USB_FlushTxFifo(USBx , 0x10U);
550 /* Disable endpoint interrupts */
551 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & ((1U << (ep->num))));
554 else /* Disable the OUT endpoint */
557 USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP;
559 /* sets the NAK bit for the OUT endpoint */
560 USBx_OUTEP(ep->num)->DOEPCTL = USB_OTG_DOEPCTL_SNAK;
562 /* Disable OUT endpoint */
563 USBx_OUTEP(ep->num)->DOEPCTL = USB_OTG_DOEPCTL_EPDIS;
567 if (++count > 200000U)
569 return HAL_TIMEOUT;
573 /*Wait for EPDISD endpoint disabled interrupt*/
574 while ((USBx_OUTEP(ep->num)->DOEPINT & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS);
576 /* Set the "Clear the Global OUT NAK bit" to disable global OUT NAK mode */
577 USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGONAK;
579 /* Disable endpoint interrupts */
580 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((1U << (ep->num)) << 16U));
582 return HAL_OK;
586 * @brief De-activate and de-initialize a dedicated endpoint
587 * @param USBx : Selected device
588 * @param ep: pointer to endpoint structure
589 * @retval HAL status
591 HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
593 uint32_t count = 0U;
595 /* Disable the IN endpoint */
596 if (ep->is_in == 1U)
598 USBx_INEP(ep->num)->DIEPCTL &= ~USB_OTG_DIEPCTL_USBAEP;
600 /* sets the NAK bit for the IN endpoint */
601 USBx_INEP(ep->num)->DIEPCTL = USB_OTG_DIEPCTL_SNAK;
603 /* Disable IN endpoint */
604 USBx_INEP(ep->num)->DIEPCTL = USB_OTG_DIEPCTL_EPDIS;
608 if (++count > 200000U)
610 return HAL_TIMEOUT;
614 /*Wait for EPDISD endpoint disabled interrupt*/
615 while ((USBx_INEP(ep->num)->DIEPINT & USB_OTG_DIEPCTL_EPDIS) == USB_OTG_DIEPCTL_EPDIS);
618 /* Flush any data remaining in the TxFIFO */
619 USB_FlushTxFifo(USBx , 0x10U);
621 /* Disable endpoint interrupts */
622 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & ((1U << (ep->num))));
625 else /* Disable the OUT endpoint */
628 USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP;
630 /* sets the NAK bit for the OUT endpoint */
631 USBx_OUTEP(ep->num)->DOEPCTL = USB_OTG_DOEPCTL_SNAK;
633 /* Disable OUT endpoint */
634 USBx_OUTEP(ep->num)->DOEPCTL = USB_OTG_DOEPCTL_EPDIS;
638 if (++count > 200000U)
640 return HAL_TIMEOUT;
644 /*Wait for EPDISD endpoint disabled interrupt*/
645 while ((USBx_OUTEP(ep->num)->DOEPINT & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS);
647 /* Set the "Clear the Global OUT NAK bit" to disable global OUT NAK mode */
648 USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGONAK;
650 /* Disable endpoint interrupts */
651 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((1U << (ep->num)) << 16U));
653 return HAL_OK;
658 * @brief USB_EPStartXfer : setup and starts a transfer over an EP
659 * @param USBx : Selected device
660 * @param ep: pointer to endpoint structure
661 * @param dma: USB dma enabled or disabled
662 * This parameter can be one of these values:
663 * 0 : DMA feature not used
664 * 1 : DMA feature used
665 * @retval HAL status
667 HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep, uint8_t dma)
669 uint16_t pktcnt = 0U;
671 /* IN endpoint */
672 if (ep->is_in == 1U)
674 /* Zero Length Packet? */
675 if (ep->xfer_len == 0U)
677 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
678 USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19U)) ;
679 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
681 else
683 /* Program the transfer size and packet count
684 * as follows: xfersize = N * maxpacket +
685 * short_packet pktcnt = N + (short_packet
686 * exist ? 1 : 0)
688 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
689 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
690 USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (((ep->xfer_len + ep->maxpacket -1U)/ ep->maxpacket) << 19U)) ;
691 USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
693 if (ep->type == EP_TYPE_ISOC)
695 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT);
696 USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1U << 29U));
700 if (dma == 1U)
702 USBx_INEP(ep->num)->DIEPDMA = (uint32_t)(ep->dma_addr);
704 else
706 if (ep->type != EP_TYPE_ISOC)
708 /* Enable the Tx FIFO Empty Interrupt for this EP */
709 if (ep->xfer_len > 0U)
711 USBx_DEVICE->DIEPEMPMSK |= 1U << ep->num;
716 if (ep->type == EP_TYPE_ISOC)
718 if ((USBx_DEVICE->DSTS & ( 1U << 8U )) == 0U)
720 USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
722 else
724 USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
728 /* EP enable, IN data in FIFO */
729 USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
731 if (ep->type == EP_TYPE_ISOC)
733 USB_WritePacket(USBx, ep->xfer_buff, ep->num, ep->xfer_len, dma);
736 else /* OUT endpoint */
738 /* Program the transfer size and packet count as follows:
739 * pktcnt = N
740 * xfersize = N * maxpacket
742 USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
743 USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
745 if (ep->xfer_len == 0U)
747 USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket);
748 USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19U));
750 else
752 pktcnt = (ep->xfer_len + ep->maxpacket -1U)/ ep->maxpacket;
753 USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (pktcnt << 19U));
754 USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket * pktcnt));
757 if (dma == 1U)
759 USBx_OUTEP(ep->num)->DOEPDMA = (uint32_t)ep->xfer_buff;
762 if (ep->type == EP_TYPE_ISOC)
764 if ((USBx_DEVICE->DSTS & ( 1U << 8U )) == 0U)
766 USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM;
768 else
770 USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
773 /* EP enable */
774 USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
776 return HAL_OK;
780 * @brief USB_EP0StartXfer : setup and starts a transfer over the EP 0
781 * @param USBx : Selected device
782 * @param ep: pointer to endpoint structure
783 * @param dma: USB dma enabled or disabled
784 * This parameter can be one of these values:
785 * 0 : DMA feature not used
786 * 1 : DMA feature used
787 * @retval HAL status
789 HAL_StatusTypeDef USB_EP0StartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep, uint8_t dma)
791 /* IN endpoint */
792 if (ep->is_in == 1U)
794 /* Zero Length Packet? */
795 if (ep->xfer_len == 0U)
797 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
798 USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19U)) ;
799 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
801 else
803 /* Program the transfer size and packet count
804 * as follows: xfersize = N * maxpacket +
805 * short_packet pktcnt = N + (short_packet
806 * exist ? 1 : 0)
808 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
809 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
811 if(ep->xfer_len > ep->maxpacket)
813 ep->xfer_len = ep->maxpacket;
815 USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19U)) ;
816 USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
820 /* EP enable, IN data in FIFO */
821 USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
823 if (dma == 1)
825 USBx_INEP(ep->num)->DIEPDMA = (uint32_t)(ep->dma_addr);
827 else
829 /* Enable the Tx FIFO Empty Interrupt for this EP */
830 if (ep->xfer_len > 0U)
832 USBx_DEVICE->DIEPEMPMSK |= 1U << (ep->num);
837 else /* OUT endpoint */
839 /* Program the transfer size and packet count as follows:
840 * pktcnt = N
841 * xfersize = N * maxpacket
843 USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
844 USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
846 if (ep->xfer_len > 0U)
848 ep->xfer_len = ep->maxpacket;
851 USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19U));
852 USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket));
855 if (dma == 1U)
857 USBx_OUTEP(ep->num)->DOEPDMA = (uint32_t)(ep->xfer_buff);
860 /* EP enable */
861 USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
863 return HAL_OK;
867 * @brief USB_WritePacket : Writes a packet into the Tx FIFO associated
868 * with the EP/channel
869 * @param USBx : Selected device
870 * @param src : pointer to source buffer
871 * @param ch_ep_num : endpoint or host channel number
872 * @param len : Number of bytes to write
873 * @param dma: USB dma enabled or disabled
874 * This parameter can be one of these values:
875 * 0 : DMA feature not used
876 * 1 : DMA feature used
877 * @retval HAL status
879 HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len, uint8_t dma)
881 uint32_t count32b = 0U , i = 0U;
883 if (dma == 0U)
885 count32b = (len + 3U) / 4U;
886 for (i = 0U; i < count32b; i++, src += 4U)
888 USBx_DFIFO(ch_ep_num) = *((__packed uint32_t *)src);
891 return HAL_OK;
895 * @brief USB_ReadPacket : read a packet from the Tx FIFO associated
896 * with the EP/channel
897 * @param USBx : Selected device
898 * @param src : source pointer
899 * @param ch_ep_num : endpoint or host channel number
900 * @param len : Number of bytes to read
901 * @param dma: USB dma enabled or disabled
902 * This parameter can be one of these values:
903 * 0 : DMA feature not used
904 * 1 : DMA feature used
905 * @retval pointer to destination buffer
907 void *USB_ReadPacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len)
909 uint32_t i=0U;
910 uint32_t count32b = (len + 3U) / 4U;
912 for ( i = 0U; i < count32b; i++, dest += 4U )
914 *(__packed uint32_t *)dest = USBx_DFIFO(0U);
917 return ((void *)dest);
921 * @brief USB_EPSetStall : set a stall condition over an EP
922 * @param USBx : Selected device
923 * @param ep: pointer to endpoint structure
924 * @retval HAL status
926 HAL_StatusTypeDef USB_EPSetStall(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep)
928 if (ep->is_in == 1U)
930 if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == 0U)
932 USBx_INEP(ep->num)->DIEPCTL &= ~(USB_OTG_DIEPCTL_EPDIS);
934 USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
936 else
938 if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == 0U)
940 USBx_OUTEP(ep->num)->DOEPCTL &= ~(USB_OTG_DOEPCTL_EPDIS);
942 USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;
944 return HAL_OK;
949 * @brief USB_EPClearStall : Clear a stall condition over an EP
950 * @param USBx : Selected device
951 * @param ep: pointer to endpoint structure
952 * @retval HAL status
954 HAL_StatusTypeDef USB_EPClearStall(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
956 if (ep->is_in == 1U)
958 USBx_INEP(ep->num)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
959 if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK)
961 USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */
964 else
966 USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
967 if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK)
969 USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */
972 return HAL_OK;
976 * @brief USB_StopDevice : Stop the usb device mode
977 * @param USBx : Selected device
978 * @retval HAL status
980 HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx)
982 uint32_t i;
984 /* Clear Pending interrupt */
985 for (i = 0U; i < 15U ; i++)
987 USBx_INEP(i)->DIEPINT = 0xFFU;
988 USBx_OUTEP(i)->DOEPINT = 0xFFU;
990 USBx_DEVICE->DAINT = 0xFFFFFFFFU;
992 /* Clear interrupt masks */
993 USBx_DEVICE->DIEPMSK = 0U;
994 USBx_DEVICE->DOEPMSK = 0U;
995 USBx_DEVICE->DAINTMSK = 0U;
997 /* Flush the FIFO */
998 USB_FlushRxFifo(USBx);
999 USB_FlushTxFifo(USBx , 0x10U);
1001 return HAL_OK;
1005 * @brief USB_SetDevAddress : Stop the usb device mode
1006 * @param USBx : Selected device
1007 * @param address : new device address to be assigned
1008 * This parameter can be a value from 0 to 255
1009 * @retval HAL status
1011 HAL_StatusTypeDef USB_SetDevAddress (USB_OTG_GlobalTypeDef *USBx, uint8_t address)
1013 USBx_DEVICE->DCFG &= ~ (USB_OTG_DCFG_DAD);
1014 USBx_DEVICE->DCFG |= (address << 4U) & USB_OTG_DCFG_DAD ;
1016 return HAL_OK;
1020 * @brief USB_DevConnect : Connect the USB device by enabling the pull-up/pull-down
1021 * @param USBx : Selected device
1022 * @retval HAL status
1024 HAL_StatusTypeDef USB_DevConnect (USB_OTG_GlobalTypeDef *USBx)
1026 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS ;
1027 HAL_Delay(3U);
1029 return HAL_OK;
1033 * @brief USB_DevDisconnect : Disconnect the USB device by disabling the pull-up/pull-down
1034 * @param USBx : Selected device
1035 * @retval HAL status
1037 HAL_StatusTypeDef USB_DevDisconnect (USB_OTG_GlobalTypeDef *USBx)
1039 USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS ;
1040 HAL_Delay(3U);
1042 return HAL_OK;
1046 * @brief USB_ReadInterrupts: return the global USB interrupt status
1047 * @param USBx : Selected device
1048 * @retval HAL status
1050 uint32_t USB_ReadInterrupts (USB_OTG_GlobalTypeDef *USBx)
1052 uint32_t v = 0U;
1054 v = USBx->GINTSTS;
1055 v &= USBx->GINTMSK;
1056 return v;
1060 * @brief USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status
1061 * @param USBx : Selected device
1062 * @retval HAL status
1064 uint32_t USB_ReadDevAllOutEpInterrupt (USB_OTG_GlobalTypeDef *USBx)
1066 uint32_t v;
1067 v = USBx_DEVICE->DAINT;
1068 v &= USBx_DEVICE->DAINTMSK;
1069 return ((v & 0xffff0000U) >> 16U);
1073 * @brief USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status
1074 * @param USBx : Selected device
1075 * @retval HAL status
1077 uint32_t USB_ReadDevAllInEpInterrupt (USB_OTG_GlobalTypeDef *USBx)
1079 uint32_t v;
1080 v = USBx_DEVICE->DAINT;
1081 v &= USBx_DEVICE->DAINTMSK;
1082 return ((v & 0xFFFFU));
1086 * @brief Returns Device OUT EP Interrupt register
1087 * @param USBx : Selected device
1088 * @param epnum : endpoint number
1089 * This parameter can be a value from 0 to 15
1090 * @retval Device OUT EP Interrupt register
1092 uint32_t USB_ReadDevOutEPInterrupt (USB_OTG_GlobalTypeDef *USBx , uint8_t epnum)
1094 uint32_t v;
1095 v = USBx_OUTEP(epnum)->DOEPINT;
1096 v &= USBx_DEVICE->DOEPMSK;
1097 return v;
1101 * @brief Returns Device IN EP Interrupt register
1102 * @param USBx : Selected device
1103 * @param epnum : endpoint number
1104 * This parameter can be a value from 0 to 15
1105 * @retval Device IN EP Interrupt register
1107 uint32_t USB_ReadDevInEPInterrupt (USB_OTG_GlobalTypeDef *USBx , uint8_t epnum)
1109 uint32_t v, msk, emp;
1111 msk = USBx_DEVICE->DIEPMSK;
1112 emp = USBx_DEVICE->DIEPEMPMSK;
1113 msk |= ((emp >> epnum) & 0x1U) << 7U;
1114 v = USBx_INEP(epnum)->DIEPINT & msk;
1115 return v;
1119 * @brief USB_ClearInterrupts: clear a USB interrupt
1120 * @param USBx : Selected device
1121 * @param interrupt : interrupt flag
1122 * @retval None
1124 void USB_ClearInterrupts (USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt)
1126 USBx->GINTSTS |= interrupt;
1130 * @brief Returns USB core mode
1131 * @param USBx : Selected device
1132 * @retval return core mode : Host or Device
1133 * This parameter can be one of these values:
1134 * 0 : Host
1135 * 1 : Device
1137 uint32_t USB_GetMode(USB_OTG_GlobalTypeDef *USBx)
1139 return ((USBx->GINTSTS ) & 0x1U);
1144 * @brief Activate EP0 for Setup transactions
1145 * @param USBx : Selected device
1146 * @retval HAL status
1148 HAL_StatusTypeDef USB_ActivateSetup (USB_OTG_GlobalTypeDef *USBx)
1150 /* Set the MPS of the IN EP based on the enumeration speed */
1151 USBx_INEP(0U)->DIEPCTL &= ~USB_OTG_DIEPCTL_MPSIZ;
1153 if((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_LS_PHY_6MHZ)
1155 USBx_INEP(0U)->DIEPCTL |= 3U;
1157 USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK;
1159 return HAL_OK;
1164 * @brief Prepare the EP0 to start the first control setup
1165 * @param USBx : Selected device
1166 * @param dma: USB dma enabled or disabled
1167 * This parameter can be one of these values:
1168 * 0 : DMA feature not used
1169 * 1 : DMA feature used
1170 * @param psetup : pointer to setup packet
1171 * @retval HAL status
1173 HAL_StatusTypeDef USB_EP0_OutStart(USB_OTG_GlobalTypeDef *USBx, uint8_t dma, uint8_t *psetup)
1175 USBx_OUTEP(0U)->DOEPTSIZ = 0U;
1176 USBx_OUTEP(0U)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19U)) ;
1177 USBx_OUTEP(0U)->DOEPTSIZ |= (3U * 8U);
1178 USBx_OUTEP(0U)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_STUPCNT;
1180 if (dma == 1U)
1182 USBx_OUTEP(0U)->DOEPDMA = (uint32_t)psetup;
1183 /* EP enable */
1184 USBx_OUTEP(0U)->DOEPCTL = 0x80008000U;
1187 return HAL_OK;
1192 * @brief Reset the USB Core (needed after USB clock settings change)
1193 * @param USBx : Selected device
1194 * @retval HAL status
1196 static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx)
1198 uint32_t count = 0U;
1200 /* Wait for AHB master IDLE state. */
1203 if (++count > 200000U)
1205 return HAL_TIMEOUT;
1208 while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
1210 /* Core Soft Reset */
1211 count = 0U;
1212 USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
1216 if (++count > 200000U)
1218 return HAL_TIMEOUT;
1221 while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
1223 return HAL_OK;
1228 * @brief USB_HostInit : Initializes the USB OTG controller registers
1229 * for Host mode
1230 * @param USBx : Selected device
1231 * @param cfg : pointer to a USB_OTG_CfgTypeDef structure that contains
1232 * the configuration information for the specified USBx peripheral.
1233 * @retval HAL status
1235 HAL_StatusTypeDef USB_HostInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
1237 uint32_t i;
1239 /* Restart the Phy Clock */
1240 USBx_PCGCCTL = 0U;
1242 /* Activate VBUS Sensing B */
1243 #if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || \
1244 defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
1245 USBx->GCCFG |= USB_OTG_GCCFG_VBDEN;
1246 #else
1247 USBx->GCCFG &=~ (USB_OTG_GCCFG_VBUSASEN);
1248 USBx->GCCFG &=~ (USB_OTG_GCCFG_VBUSBSEN);
1249 USBx->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS;
1250 #endif /* STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Rx || STM32F412Vx || STM32F412Cx || STM32F413xx || STM32F423xx */
1252 /* Disable the FS/LS support mode only */
1253 if((cfg.speed == USB_OTG_SPEED_FULL)&&
1254 (USBx != USB_OTG_FS))
1256 USBx_HOST->HCFG |= USB_OTG_HCFG_FSLSS;
1258 else
1260 USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
1263 /* Make sure the FIFOs are flushed. */
1264 USB_FlushTxFifo(USBx, 0x10U); /* all Tx FIFOs */
1265 USB_FlushRxFifo(USBx);
1267 /* Clear all pending HC Interrupts */
1268 for (i = 0U; i < cfg.Host_channels; i++)
1270 USBx_HC(i)->HCINT = 0xFFFFFFFFU;
1271 USBx_HC(i)->HCINTMSK = 0U;
1274 /* Enable VBUS driving */
1275 USB_DriveVbus(USBx, 1U);
1277 HAL_Delay(200U);
1279 /* Disable all interrupts. */
1280 USBx->GINTMSK = 0U;
1282 /* Clear any pending interrupts */
1283 USBx->GINTSTS = 0xFFFFFFFFU;
1285 if(USBx == USB_OTG_FS)
1287 /* set Rx FIFO size */
1288 USBx->GRXFSIZ = 0x80U;
1289 USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t )(((0x60U << 16U)& USB_OTG_NPTXFD) | 0x80U);
1290 USBx->HPTXFSIZ = (uint32_t )(((0x40U << 16U)& USB_OTG_HPTXFSIZ_PTXFD) | 0xE0U);
1292 else
1294 /* set Rx FIFO size */
1295 USBx->GRXFSIZ = 0x200U;
1296 USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t )(((0x100U << 16U)& USB_OTG_NPTXFD) | 0x200U);
1297 USBx->HPTXFSIZ = (uint32_t )(((0xE0U << 16U)& USB_OTG_HPTXFSIZ_PTXFD) | 0x300U);
1300 /* Enable the common interrupts */
1301 if (cfg.dma_enable == DISABLE)
1303 USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
1306 /* Enable interrupts matching to the Host mode ONLY */
1307 USBx->GINTMSK |= (USB_OTG_GINTMSK_PRTIM | USB_OTG_GINTMSK_HCIM |\
1308 USB_OTG_GINTMSK_SOFM |USB_OTG_GINTSTS_DISCINT|\
1309 USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM);
1311 return HAL_OK;
1315 * @brief USB_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the
1316 * HCFG register on the PHY type and set the right frame interval
1317 * @param USBx : Selected device
1318 * @param freq : clock frequency
1319 * This parameter can be one of these values:
1320 * HCFG_48_MHZ : Full Speed 48 MHz Clock
1321 * HCFG_6_MHZ : Low Speed 6 MHz Clock
1322 * @retval HAL status
1324 HAL_StatusTypeDef USB_InitFSLSPClkSel(USB_OTG_GlobalTypeDef *USBx , uint8_t freq)
1326 USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSPCS);
1327 USBx_HOST->HCFG |= (freq & USB_OTG_HCFG_FSLSPCS);
1329 if (freq == HCFG_48_MHZ)
1331 USBx_HOST->HFIR = 48000U;
1333 else if (freq == HCFG_6_MHZ)
1335 USBx_HOST->HFIR = 6000U;
1337 return HAL_OK;
1341 * @brief USB_OTG_ResetPort : Reset Host Port
1342 * @param USBx : Selected device
1343 * @retval HAL status
1344 * @note (1)The application must wait at least 10 ms
1345 * before clearing the reset bit.
1347 HAL_StatusTypeDef USB_ResetPort(USB_OTG_GlobalTypeDef *USBx)
1349 __IO uint32_t hprt0;
1351 hprt0 = USBx_HPRT0;
1353 hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
1354 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
1356 USBx_HPRT0 = (USB_OTG_HPRT_PRST | hprt0);
1357 HAL_Delay (10U); /* See Note #1 */
1358 USBx_HPRT0 = ((~USB_OTG_HPRT_PRST) & hprt0);
1359 return HAL_OK;
1363 * @brief USB_DriveVbus : activate or de-activate vbus
1364 * @param state : VBUS state
1365 * This parameter can be one of these values:
1366 * 0 : VBUS Active
1367 * 1 : VBUS Inactive
1368 * @retval HAL status
1370 HAL_StatusTypeDef USB_DriveVbus (USB_OTG_GlobalTypeDef *USBx, uint8_t state)
1372 __IO uint32_t hprt0;
1374 hprt0 = USBx_HPRT0;
1375 hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
1376 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
1378 if (((hprt0 & USB_OTG_HPRT_PPWR) == 0U) && (state == 1U))
1380 USBx_HPRT0 = (USB_OTG_HPRT_PPWR | hprt0);
1382 if (((hprt0 & USB_OTG_HPRT_PPWR) == USB_OTG_HPRT_PPWR) && (state == 0U))
1384 USBx_HPRT0 = ((~USB_OTG_HPRT_PPWR) & hprt0);
1386 return HAL_OK;
1390 * @brief Return Host Core speed
1391 * @param USBx : Selected device
1392 * @retval speed : Host speed
1393 * This parameter can be one of these values:
1394 * @arg USB_OTG_SPEED_HIGH: High speed mode
1395 * @arg USB_OTG_SPEED_FULL: Full speed mode
1396 * @arg USB_OTG_SPEED_LOW: Low speed mode
1398 uint32_t USB_GetHostSpeed (USB_OTG_GlobalTypeDef *USBx)
1400 __IO uint32_t hprt0;
1402 hprt0 = USBx_HPRT0;
1403 return ((hprt0 & USB_OTG_HPRT_PSPD) >> 17U);
1407 * @brief Return Host Current Frame number
1408 * @param USBx : Selected device
1409 * @retval current frame number
1411 uint32_t USB_GetCurrentFrame (USB_OTG_GlobalTypeDef *USBx)
1413 return (USBx_HOST->HFNUM & USB_OTG_HFNUM_FRNUM);
1417 * @brief Initialize a host channel
1418 * @param USBx : Selected device
1419 * @param ch_num : Channel number
1420 * This parameter can be a value from 1 to 15
1421 * @param epnum : Endpoint number
1422 * This parameter can be a value from 1 to 15
1423 * @param dev_address : Current device address
1424 * This parameter can be a value from 0 to 255
1425 * @param speed : Current device speed
1426 * This parameter can be one of these values:
1427 * @arg USB_OTG_SPEED_HIGH: High speed mode
1428 * @arg USB_OTG_SPEED_FULL: Full speed mode
1429 * @arg USB_OTG_SPEED_LOW: Low speed mode
1430 * @param ep_type : Endpoint Type
1431 * This parameter can be one of these values:
1432 * @arg EP_TYPE_CTRL: Control type
1433 * @arg EP_TYPE_ISOC: Isochronous type
1434 * @arg EP_TYPE_BULK: Bulk type
1435 * @arg EP_TYPE_INTR: Interrupt type
1436 * @param mps : Max Packet Size
1437 * This parameter can be a value from 0 to32K
1438 * @retval HAL state
1440 HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx,
1441 uint8_t ch_num,
1442 uint8_t epnum,
1443 uint8_t dev_address,
1444 uint8_t speed,
1445 uint8_t ep_type,
1446 uint16_t mps)
1449 /* Clear old interrupt conditions for this host channel. */
1450 USBx_HC(ch_num)->HCINT = 0xFFFFFFFFU;
1452 /* Enable channel interrupts required for this transfer. */
1453 switch (ep_type)
1455 case EP_TYPE_CTRL:
1456 case EP_TYPE_BULK:
1458 USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |\
1459 USB_OTG_HCINTMSK_STALLM |\
1460 USB_OTG_HCINTMSK_TXERRM |\
1461 USB_OTG_HCINTMSK_DTERRM |\
1462 USB_OTG_HCINTMSK_AHBERR |\
1463 USB_OTG_HCINTMSK_NAKM ;
1465 if (epnum & 0x80U)
1467 USBx_HC(ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
1469 else
1471 if(USBx != USB_OTG_FS)
1473 USBx_HC(ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_NYET | USB_OTG_HCINTMSK_ACKM);
1476 break;
1478 case EP_TYPE_INTR:
1480 USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |\
1481 USB_OTG_HCINTMSK_STALLM |\
1482 USB_OTG_HCINTMSK_TXERRM |\
1483 USB_OTG_HCINTMSK_DTERRM |\
1484 USB_OTG_HCINTMSK_NAKM |\
1485 USB_OTG_HCINTMSK_AHBERR |\
1486 USB_OTG_HCINTMSK_FRMORM ;
1488 if (epnum & 0x80U)
1490 USBx_HC(ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
1493 break;
1494 case EP_TYPE_ISOC:
1496 USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |\
1497 USB_OTG_HCINTMSK_ACKM |\
1498 USB_OTG_HCINTMSK_AHBERR |\
1499 USB_OTG_HCINTMSK_FRMORM ;
1501 if (epnum & 0x80U)
1503 USBx_HC(ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_BBERRM);
1505 break;
1508 /* Enable the top level host channel interrupt. */
1509 USBx_HOST->HAINTMSK |= (1 << ch_num);
1511 /* Make sure host channel interrupts are enabled. */
1512 USBx->GINTMSK |= USB_OTG_GINTMSK_HCIM;
1514 /* Program the HCCHAR register */
1515 USBx_HC(ch_num)->HCCHAR = (((dev_address << 22U) & USB_OTG_HCCHAR_DAD) |\
1516 (((epnum & 0x7FU)<< 11U) & USB_OTG_HCCHAR_EPNUM)|\
1517 ((((epnum & 0x80U) == 0x80U)<< 15U) & USB_OTG_HCCHAR_EPDIR)|\
1518 (((speed == USB_OTG_SPEED_LOW)<< 17U) & USB_OTG_HCCHAR_LSDEV)|\
1519 ((ep_type << 18U) & USB_OTG_HCCHAR_EPTYP)|\
1520 (mps & USB_OTG_HCCHAR_MPSIZ));
1522 if (ep_type == EP_TYPE_INTR)
1524 USBx_HC(ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM ;
1527 return HAL_OK;
1531 * @brief Start a transfer over a host channel
1532 * @param USBx : Selected device
1533 * @param hc : pointer to host channel structure
1534 * @param dma: USB dma enabled or disabled
1535 * This parameter can be one of these values:
1536 * 0 : DMA feature not used
1537 * 1 : DMA feature used
1538 * @retval HAL state
1540 #if defined (__CC_ARM) /*!< ARM Compiler */
1541 #pragma O0
1542 #elif defined (__GNUC__) /*!< GNU Compiler */
1543 #pragma GCC optimize ("O0")
1544 #endif /* __CC_ARM */
1545 HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc, uint8_t dma)
1547 uint8_t is_oddframe = 0;
1548 uint16_t len_words = 0;
1549 uint16_t num_packets = 0;
1550 uint16_t max_hc_pkt_count = 256;
1551 uint32_t tmpreg = 0U;
1553 if((USBx != USB_OTG_FS) && (hc->speed == USB_OTG_SPEED_HIGH))
1555 if((dma == 0) && (hc->do_ping == 1U))
1557 USB_DoPing(USBx, hc->ch_num);
1558 return HAL_OK;
1560 else if(dma == 1)
1562 USBx_HC(hc->ch_num)->HCINTMSK &= ~(USB_OTG_HCINTMSK_NYET | USB_OTG_HCINTMSK_ACKM);
1563 hc->do_ping = 0U;
1567 /* Compute the expected number of packets associated to the transfer */
1568 if (hc->xfer_len > 0U)
1570 num_packets = (hc->xfer_len + hc->max_packet - 1U) / hc->max_packet;
1572 if (num_packets > max_hc_pkt_count)
1574 num_packets = max_hc_pkt_count;
1575 hc->xfer_len = num_packets * hc->max_packet;
1578 else
1580 num_packets = 1;
1582 if (hc->ep_is_in)
1584 hc->xfer_len = num_packets * hc->max_packet;
1587 /* Initialize the HCTSIZn register */
1588 USBx_HC(hc->ch_num)->HCTSIZ = (((hc->xfer_len) & USB_OTG_HCTSIZ_XFRSIZ)) |\
1589 ((num_packets << 19U) & USB_OTG_HCTSIZ_PKTCNT) |\
1590 (((hc->data_pid) << 29U) & USB_OTG_HCTSIZ_DPID);
1592 if (dma)
1594 /* xfer_buff MUST be 32-bits aligned */
1595 USBx_HC(hc->ch_num)->HCDMA = (uint32_t)hc->xfer_buff;
1598 is_oddframe = (USBx_HOST->HFNUM & 0x01) ? 0 : 1;
1599 USBx_HC(hc->ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM;
1600 USBx_HC(hc->ch_num)->HCCHAR |= (is_oddframe << 29);
1602 /* Set host channel enable */
1603 tmpreg = USBx_HC(hc->ch_num)->HCCHAR;
1604 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1605 tmpreg |= USB_OTG_HCCHAR_CHENA;
1606 USBx_HC(hc->ch_num)->HCCHAR = tmpreg;
1608 if (dma == 0) /* Slave mode */
1610 if((hc->ep_is_in == 0U) && (hc->xfer_len > 0U))
1612 switch(hc->ep_type)
1614 /* Non periodic transfer */
1615 case EP_TYPE_CTRL:
1616 case EP_TYPE_BULK:
1618 len_words = (hc->xfer_len + 3) / 4;
1620 /* check if there is enough space in FIFO space */
1621 if(len_words > (USBx->HNPTXSTS & 0xFFFF))
1623 /* need to process data in nptxfempty interrupt */
1624 USBx->GINTMSK |= USB_OTG_GINTMSK_NPTXFEM;
1626 break;
1627 /* Periodic transfer */
1628 case EP_TYPE_INTR:
1629 case EP_TYPE_ISOC:
1630 len_words = (hc->xfer_len + 3) / 4;
1631 /* check if there is enough space in FIFO space */
1632 if(len_words > (USBx_HOST->HPTXSTS & 0xFFFF)) /* split the transfer */
1634 /* need to process data in ptxfempty interrupt */
1635 USBx->GINTMSK |= USB_OTG_GINTMSK_PTXFEM;
1637 break;
1639 default:
1640 break;
1643 /* Write packet into the Tx FIFO. */
1644 USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, hc->xfer_len, 0);
1648 return HAL_OK;
1652 * @brief Read all host channel interrupts status
1653 * @param USBx : Selected device
1654 * @retval HAL state
1656 uint32_t USB_HC_ReadInterrupt (USB_OTG_GlobalTypeDef *USBx)
1658 return ((USBx_HOST->HAINT) & 0xFFFFU);
1662 * @brief Halt a host channel
1663 * @param USBx : Selected device
1664 * @param hc_num : Host Channel number
1665 * This parameter can be a value from 1 to 15
1666 * @retval HAL state
1668 HAL_StatusTypeDef USB_HC_Halt(USB_OTG_GlobalTypeDef *USBx , uint8_t hc_num)
1670 uint32_t count = 0U;
1672 /* Check for space in the request queue to issue the halt. */
1673 if (((((USBx_HC(hc_num)->HCCHAR) & USB_OTG_HCCHAR_EPTYP) >> 18) == HCCHAR_CTRL) || (((((USBx_HC(hc_num)->HCCHAR) &
1674 USB_OTG_HCCHAR_EPTYP) >> 18) == HCCHAR_BULK)))
1676 USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
1678 if ((USBx->HNPTXSTS & 0xFF0000U) == 0U)
1680 USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
1681 USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1684 if (++count > 1000U)
1686 break;
1689 while ((USBx_HC(hc_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
1691 else
1693 USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1696 else
1698 USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
1700 if ((USBx_HOST->HPTXSTS & 0xFFFFU) == 0U)
1702 USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
1703 USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1706 if (++count > 1000U)
1708 break;
1711 while ((USBx_HC(hc_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
1713 else
1715 USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1719 return HAL_OK;
1723 * @brief Initiate Do Ping protocol
1724 * @param USBx : Selected device
1725 * @param hc_num : Host Channel number
1726 * This parameter can be a value from 1 to 15
1727 * @retval HAL state
1729 HAL_StatusTypeDef USB_DoPing(USB_OTG_GlobalTypeDef *USBx , uint8_t ch_num)
1731 uint8_t num_packets = 1U;
1732 uint32_t tmpreg = 0U;
1734 USBx_HC(ch_num)->HCTSIZ = ((num_packets << 19U) & USB_OTG_HCTSIZ_PKTCNT) |\
1735 USB_OTG_HCTSIZ_DOPING;
1737 /* Set host channel enable */
1738 tmpreg = USBx_HC(ch_num)->HCCHAR;
1739 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1740 tmpreg |= USB_OTG_HCCHAR_CHENA;
1741 USBx_HC(ch_num)->HCCHAR = tmpreg;
1743 return HAL_OK;
1747 * @brief Stop Host Core
1748 * @param USBx : Selected device
1749 * @retval HAL state
1751 HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx)
1753 uint8_t i;
1754 uint32_t count = 0U;
1755 uint32_t value;
1757 USB_DisableGlobalInt(USBx);
1759 /* Flush FIFO */
1760 USB_FlushTxFifo(USBx, 0x10U);
1761 USB_FlushRxFifo(USBx);
1763 /* Flush out any leftover queued requests. */
1764 for (i = 0; i <= 15; i++)
1767 value = USBx_HC(i)->HCCHAR ;
1768 value |= USB_OTG_HCCHAR_CHDIS;
1769 value &= ~USB_OTG_HCCHAR_CHENA;
1770 value &= ~USB_OTG_HCCHAR_EPDIR;
1771 USBx_HC(i)->HCCHAR = value;
1774 /* Halt all channels to put them into a known state. */
1775 for (i = 0; i <= 15; i++)
1777 value = USBx_HC(i)->HCCHAR ;
1779 value |= USB_OTG_HCCHAR_CHDIS;
1780 value |= USB_OTG_HCCHAR_CHENA;
1781 value &= ~USB_OTG_HCCHAR_EPDIR;
1783 USBx_HC(i)->HCCHAR = value;
1786 if (++count > 1000U)
1788 break;
1791 while ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
1794 /* Clear any pending Host interrupts */
1795 USBx_HOST->HAINT = 0xFFFFFFFFU;
1796 USBx->GINTSTS = 0xFFFFFFFFU;
1797 USB_EnableGlobalInt(USBx);
1798 return HAL_OK;
1801 * @}
1803 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx ||
1804 STM32F401xC || STM32F401xE || STM32F411xE || STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Rx ||
1805 STM32F412Vx || STM32F412Cx || STM32F413xx || STM32F423xx */
1806 #endif /* defined(HAL_PCD_MODULE_ENABLED) || defined(HAL_HCD_MODULE_ENABLED) */
1809 * @}
1812 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/