2 ******************************************************************************
3 * @file stm32f4xx_ll_usb.c
4 * @author MCD Application Team
7 * @brief USB Low Layer HAL module driver.
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
17 ==============================================================================
18 ##### How to use this driver #####
19 ==============================================================================
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.
28 ******************************************************************************
31 * <h2><center>© 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 ******************************************************************************
58 /* Includes ------------------------------------------------------------------*/
59 #include "stm32f4xx_hal.h"
61 /** @addtogroup STM32F4xx_LL_USB_DRIVER
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
85 /** @defgroup LL_USB_Group1 Initialization/de-initialization functions
86 * @brief Initialization and Configuration functions
89 ===============================================================================
90 ##### Initialization/de-initialization functions #####
91 ===============================================================================
92 [..] This section provides functions allowing to:
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.
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 */
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 */
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
;
146 * @brief USB_EnableGlobalInt
147 * Enables the controller's Global Int in the AHB Config reg
148 * @param USBx : Selected device
151 HAL_StatusTypeDef
USB_EnableGlobalInt(USB_OTG_GlobalTypeDef
*USBx
)
153 USBx
->GAHBCFG
|= USB_OTG_GAHBCFG_GINT
;
159 * @brief USB_DisableGlobalInt
160 * Disable the controller's Global Int in the AHB Config reg
161 * @param USBx : Selected device
164 HAL_StatusTypeDef
USB_DisableGlobalInt(USB_OTG_GlobalTypeDef
*USBx
)
166 USBx
->GAHBCFG
&= ~USB_OTG_GAHBCFG_GINT
;
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
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
;
198 * @brief USB_DevInit : Initializes the USB_OTG controller registers
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.
205 HAL_StatusTypeDef
USB_DevInit (USB_OTG_GlobalTypeDef
*USBx
, USB_OTG_CfgTypeDef cfg
)
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
;
224 if (cfg
.vbus_sensing_enable
== 0U)
226 USBx
->GCCFG
|= USB_OTG_GCCFG_NOVBUSSENS
;
231 USBx
->GCCFG
|= USB_OTG_GCCFG_VBUSBSEN
;
233 #endif /* STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Rx || STM32F412Vx || STM32F412Cx || STM32F413xx || STM32F423xx */
235 /* Restart the Phy Clock */
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
);
250 /* set High speed phy in Full speed mode */
251 USB_SetDevSpeed (USBx
, USB_OTG_SPEED_HIGH_IN_FULL
);
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
);
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
);
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. */
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
);
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
);
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
351 HAL_StatusTypeDef
USB_FlushTxFifo (USB_OTG_GlobalTypeDef
*USBx
, uint32_t num
)
355 USBx
->GRSTCTL
= ( USB_OTG_GRSTCTL_TXFFLSH
|(uint32_t)( num
<< 6));
359 if (++count
> 200000)
364 while ((USBx
->GRSTCTL
& USB_OTG_GRSTCTL_TXFFLSH
) == USB_OTG_GRSTCTL_TXFFLSH
);
371 * @brief USB_FlushRxFifo : Flush Rx FIFO
372 * @param USBx : Selected device
375 HAL_StatusTypeDef
USB_FlushRxFifo(USB_OTG_GlobalTypeDef
*USBx
)
379 USBx
->GRSTCTL
= USB_OTG_GRSTCTL_RXFFLSH
;
383 if (++count
> 200000)
388 while ((USBx
->GRSTCTL
& USB_OTG_GRSTCTL_RXFFLSH
) == USB_OTG_GRSTCTL_RXFFLSH
);
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
405 HAL_StatusTypeDef
USB_SetDevSpeed(USB_OTG_GlobalTypeDef
*USBx
, uint8_t speed
)
407 USBx_DEVICE
->DCFG
|= speed
;
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
)
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
;
442 * @brief Activate and configure an endpoint
443 * @param USBx : Selected device
444 * @param ep: pointer to endpoint structure
447 HAL_StatusTypeDef
USB_ActivateEndpoint(USB_OTG_GlobalTypeDef
*USBx
, USB_OTG_EPTypeDef
*ep
)
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
));
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
));
472 * @brief Activate and configure a dedicated endpoint
473 * @param USBx : Selected device
474 * @param ep: pointer to endpoint structure
477 HAL_StatusTypeDef
USB_ActivateDedicatedEndpoint(USB_OTG_GlobalTypeDef
*USBx
, USB_OTG_EPTypeDef
*ep
)
479 static __IO
uint32_t debug
= 0U;
481 /* Read DEPCTLn register */
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
)));
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);
515 * @brief De-activate and de-initialize an endpoint
516 * @param USBx : Selected device
517 * @param ep: pointer to endpoint structure
520 HAL_StatusTypeDef
USB_DeactivateEndpoint(USB_OTG_GlobalTypeDef
*USBx
, USB_OTG_EPTypeDef
*ep
)
524 /* Disable the IN endpoint */
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)
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)
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));
586 * @brief De-activate and de-initialize a dedicated endpoint
587 * @param USBx : Selected device
588 * @param ep: pointer to endpoint structure
591 HAL_StatusTypeDef
USB_DeactivateDedicatedEndpoint(USB_OTG_GlobalTypeDef
*USBx
, USB_OTG_EPTypeDef
*ep
)
595 /* Disable the IN endpoint */
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)
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)
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));
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
667 HAL_StatusTypeDef
USB_EPStartXfer(USB_OTG_GlobalTypeDef
*USBx
, USB_OTG_EPTypeDef
*ep
, uint8_t dma
)
669 uint16_t pktcnt
= 0U;
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
);
683 /* Program the transfer size and packet count
684 * as follows: xfersize = N * maxpacket +
685 * short_packet pktcnt = N + (short_packet
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));
702 USBx_INEP(ep
->num
)->DIEPDMA
= (uint32_t)(ep
->dma_addr
);
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
;
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:
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));
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
));
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
;
770 USBx_OUTEP(ep
->num
)->DOEPCTL
|= USB_OTG_DOEPCTL_SD0PID_SEVNFRM
;
774 USBx_OUTEP(ep
->num
)->DOEPCTL
|= (USB_OTG_DOEPCTL_CNAK
| USB_OTG_DOEPCTL_EPENA
);
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
789 HAL_StatusTypeDef
USB_EP0StartXfer(USB_OTG_GlobalTypeDef
*USBx
, USB_OTG_EPTypeDef
*ep
, uint8_t dma
)
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
);
803 /* Program the transfer size and packet count
804 * as follows: xfersize = N * maxpacket +
805 * short_packet pktcnt = N + (short_packet
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
);
825 USBx_INEP(ep
->num
)->DIEPDMA
= (uint32_t)(ep
->dma_addr
);
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:
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
));
857 USBx_OUTEP(ep
->num
)->DOEPDMA
= (uint32_t)(ep
->xfer_buff
);
861 USBx_OUTEP(ep
->num
)->DOEPCTL
|= (USB_OTG_DOEPCTL_CNAK
| USB_OTG_DOEPCTL_EPENA
);
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
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;
885 count32b
= (len
+ 3U) / 4U;
886 for (i
= 0U; i
< count32b
; i
++, src
+= 4U)
888 USBx_DFIFO(ch_ep_num
) = *((__packed
uint32_t *)src
);
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
)
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
926 HAL_StatusTypeDef
USB_EPSetStall(USB_OTG_GlobalTypeDef
*USBx
, USB_OTG_EPTypeDef
*ep
)
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
;
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
;
949 * @brief USB_EPClearStall : Clear a stall condition over an EP
950 * @param USBx : Selected device
951 * @param ep: pointer to endpoint structure
954 HAL_StatusTypeDef
USB_EPClearStall(USB_OTG_GlobalTypeDef
*USBx
, USB_OTG_EPTypeDef
*ep
)
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 */
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 */
976 * @brief USB_StopDevice : Stop the usb device mode
977 * @param USBx : Selected device
980 HAL_StatusTypeDef
USB_StopDevice(USB_OTG_GlobalTypeDef
*USBx
)
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;
998 USB_FlushRxFifo(USBx
);
999 USB_FlushTxFifo(USBx
, 0x10U
);
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
;
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
;
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
;
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
)
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
)
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
)
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
)
1095 v
= USBx_OUTEP(epnum
)->DOEPINT
;
1096 v
&= USBx_DEVICE
->DOEPMSK
;
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
;
1119 * @brief USB_ClearInterrupts: clear a USB interrupt
1120 * @param USBx : Selected device
1121 * @param interrupt : interrupt flag
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:
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
;
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
;
1182 USBx_OUTEP(0U)->DOEPDMA
= (uint32_t)psetup
;
1184 USBx_OUTEP(0U)->DOEPCTL
= 0x80008000U
;
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)
1208 while ((USBx
->GRSTCTL
& USB_OTG_GRSTCTL_AHBIDL
) == 0U);
1210 /* Core Soft Reset */
1212 USBx
->GRSTCTL
|= USB_OTG_GRSTCTL_CSRST
;
1216 if (++count
> 200000U)
1221 while ((USBx
->GRSTCTL
& USB_OTG_GRSTCTL_CSRST
) == USB_OTG_GRSTCTL_CSRST
);
1228 * @brief USB_HostInit : Initializes the USB OTG controller registers
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
)
1239 /* Restart the Phy Clock */
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
;
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
;
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);
1279 /* Disable all interrupts. */
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
);
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
);
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;
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
;
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
);
1363 * @brief USB_DriveVbus : activate or de-activate vbus
1364 * @param state : VBUS state
1365 * This parameter can be one of these values:
1368 * @retval HAL status
1370 HAL_StatusTypeDef
USB_DriveVbus (USB_OTG_GlobalTypeDef
*USBx
, uint8_t state
)
1372 __IO
uint32_t 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
);
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
;
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
1440 HAL_StatusTypeDef
USB_HC_Init(USB_OTG_GlobalTypeDef
*USBx
,
1443 uint8_t dev_address
,
1449 /* Clear old interrupt conditions for this host channel. */
1450 USBx_HC(ch_num
)->HCINT
= 0xFFFFFFFFU
;
1452 /* Enable channel interrupts required for this transfer. */
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
;
1467 USBx_HC(ch_num
)->HCINTMSK
|= USB_OTG_HCINTMSK_BBERRM
;
1471 if(USBx
!= USB_OTG_FS
)
1473 USBx_HC(ch_num
)->HCINTMSK
|= (USB_OTG_HCINTMSK_NYET
| USB_OTG_HCINTMSK_ACKM
);
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
;
1490 USBx_HC(ch_num
)->HCINTMSK
|= USB_OTG_HCINTMSK_BBERRM
;
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
;
1503 USBx_HC(ch_num
)->HCINTMSK
|= (USB_OTG_HCINTMSK_TXERRM
| USB_OTG_HCINTMSK_BBERRM
);
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
;
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
1540 #if defined (__CC_ARM) /*!< ARM Compiler */
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
);
1562 USBx_HC(hc
->ch_num
)->HCINTMSK
&= ~(USB_OTG_HCINTMSK_NYET
| USB_OTG_HCINTMSK_ACKM
);
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
;
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
);
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))
1614 /* Non periodic transfer */
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
;
1627 /* Periodic transfer */
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
;
1643 /* Write packet into the Tx FIFO. */
1644 USB_WritePacket(USBx
, hc
->xfer_buff
, hc
->ch_num
, hc
->xfer_len
, 0);
1652 * @brief Read all host channel interrupts status
1653 * @param USBx : Selected device
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
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)
1689 while ((USBx_HC(hc_num
)->HCCHAR
& USB_OTG_HCCHAR_CHENA
) == USB_OTG_HCCHAR_CHENA
);
1693 USBx_HC(hc_num
)->HCCHAR
|= USB_OTG_HCCHAR_CHENA
;
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)
1711 while ((USBx_HC(hc_num
)->HCCHAR
& USB_OTG_HCCHAR_CHENA
) == USB_OTG_HCCHAR_CHENA
);
1715 USBx_HC(hc_num
)->HCCHAR
|= USB_OTG_HCCHAR_CHENA
;
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
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
;
1747 * @brief Stop Host Core
1748 * @param USBx : Selected device
1751 HAL_StatusTypeDef
USB_StopHost(USB_OTG_GlobalTypeDef
*USBx
)
1754 uint32_t count
= 0U;
1757 USB_DisableGlobalInt(USBx
);
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)
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
);
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) */
1812 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/