mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-17 04:52:59 +01:00
Merge pull request #18714 from gschorcht/drivers/usbdev_synopsys_dwc2_hs_utmi
drivers/usbdev_synopsys_dwc2: add support for internal UTMI HS PHY
This commit is contained in:
commit
0fca912e91
85
boards/common/stm32/include/cfg_usb_otg_hs_phy_utmi.h
Normal file
85
boards/common/stm32/include/cfg_usb_otg_hs_phy_utmi.h
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Koen Zandberg
|
||||
* 2022 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup boards_common_stm32
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Common configuration for STM32 OTG HS peripheral with internal UTMI HS PHY
|
||||
*
|
||||
* All STM32 boards which use the internal UTMI HS PHY for the USB OTG HS
|
||||
* peripheral use the same configuration. Therefore a common configuration file
|
||||
* can be used for these boards.
|
||||
*
|
||||
* @author Koen Zandberg <koen@bergzand.net>
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
*/
|
||||
|
||||
#ifndef CFG_USB_OTG_HS_PHY_UTMI_H
|
||||
#define CFG_USB_OTG_HS_PHY_UTMI_H
|
||||
|
||||
#include "periph_cpu.h"
|
||||
#include "usbdev_synopsys_dwc2.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enable the high speed USB OTG peripheral
|
||||
*/
|
||||
#define DWC2_USB_OTG_HS_ENABLED
|
||||
|
||||
#ifndef USBPHYC_TUNE_VALUE
|
||||
/**
|
||||
* @brief Default value of USBPHYC tuning control register
|
||||
*
|
||||
* The value of the USBPHYC tuning control register (USBPHYC_TUNE) is used by
|
||||
* the USB HS PHY controller for the tuning interface of the internal
|
||||
* USB HS PHY, please refer the Reference Manual for STM32F72xxx and STM32F73xxx
|
||||
* for details.
|
||||
*
|
||||
* The value as defined in the [STM32CubeF7 HAL Driver MCU Component for F7]
|
||||
* (https://bit.ly/3es9eFA) is used as default value.
|
||||
* If necessary, it can be overridden by the board configuration in
|
||||
* `periph_conf.h` by defining the value before this file is included.
|
||||
*/
|
||||
#define USBPHYC_TUNE_VALUE 0x00000f13U
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Common USB OTG HS configuration
|
||||
*/
|
||||
static const dwc2_usb_otg_fshs_config_t dwc2_usb_otg_fshs_config[] = {
|
||||
{
|
||||
.periph = USB_OTG_HS_PERIPH_BASE,
|
||||
.type = DWC2_USB_OTG_HS,
|
||||
.phy = DWC2_USB_OTG_PHY_UTMI,
|
||||
.rcc_mask = RCC_AHB1ENR_OTGHSEN,
|
||||
.irqn = OTG_HS_IRQn,
|
||||
.ahb = AHB1,
|
||||
.dm = GPIO_PIN(PORT_B, 14),
|
||||
.dp = GPIO_PIN(PORT_B, 15),
|
||||
.af = GPIO_AF10,
|
||||
.phy_tune = USBPHYC_TUNE_VALUE,
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Number of available USB OTG peripherals
|
||||
*/
|
||||
#define USBDEV_NUMOF ARRAY_SIZE(dwc2_usb_otg_fshs_config)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CFG_USB_OTG_HS_PHY_UTMI_H */
|
||||
/** @} */
|
@ -22,6 +22,7 @@ config BOARD_STM32F723E_DISCO
|
||||
select HAS_PERIPH_UART
|
||||
select HAS_PERIPH_UART_HW_FC
|
||||
select HAS_PERIPH_USBDEV
|
||||
select HAS_PERIPH_USBDEV_HS_UTMI
|
||||
|
||||
# Put other features for this board (in alphabetical order)
|
||||
select HAS_TINYUSB_DEVICE
|
||||
|
@ -11,6 +11,7 @@ FEATURES_PROVIDED += periph_timer
|
||||
FEATURES_PROVIDED += periph_uart
|
||||
FEATURES_PROVIDED += periph_uart_hw_fc
|
||||
FEATURES_PROVIDED += periph_usbdev
|
||||
FEATURES_PROVIDED += periph_usbdev_hs_utmi
|
||||
|
||||
# Put other features for this board (in alphabetical order)
|
||||
FEATURES_PROVIDED += tinyusb_device
|
||||
|
@ -28,4 +28,10 @@ Use the `term` target to open a terminal:
|
||||
|
||||
make BOARD=stm32f723e-disco -C examples/hello-world term
|
||||
|
||||
### USB OTG Peripheral Device Driver
|
||||
|
||||
By default, the USB OTG FS port is used. To use the USB OTG HS port with the
|
||||
internal UTMI+ HS PHY, enable the module `periph_usbdev_hs_utmi`:
|
||||
|
||||
make BOARD=stm32f723e-disco USEMODULE=periph_usbdev_hs_utmi -C examples/usbus_minimal
|
||||
*/
|
||||
|
@ -35,7 +35,11 @@
|
||||
#include "periph_cpu.h"
|
||||
#include "clk_conf.h"
|
||||
#include "cfg_rtt_default.h"
|
||||
#if defined(MODULE_PERIPH_USBDEV_HS_UTMI)
|
||||
#include "cfg_usb_otg_hs_phy_utmi.h"
|
||||
#else
|
||||
#include "cfg_usb_otg_fs.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -145,6 +145,10 @@ ifneq (,$(filter periph_usbdev_hs_ulpi,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += periph_usbdev_hs_ulpi
|
||||
endif
|
||||
|
||||
ifneq (,$(filter periph_usbdev_hs_utmi,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += periph_usbdev_hs_utmi
|
||||
endif
|
||||
|
||||
ifneq (,$(filter pn532_i2c,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += periph_i2c
|
||||
USEMODULE += pn532
|
||||
|
@ -67,7 +67,7 @@ typedef enum {
|
||||
} dwc2_usb_otg_fshs_phy_t;
|
||||
|
||||
/**
|
||||
* @brief stm32 USB OTG configuration
|
||||
* @brief USB OTG configuration
|
||||
*/
|
||||
typedef struct {
|
||||
uintptr_t periph; /**< USB peripheral base address */
|
||||
@ -95,6 +95,11 @@ typedef struct {
|
||||
gpio_t dm; /**< Data- gpio */
|
||||
gpio_t dp; /**< Data+ gpio */
|
||||
gpio_af_t af; /**< Alternative function */
|
||||
#if defined(MODULE_PERIPH_USBDEV_HS_UTMI) || DOXYGEN
|
||||
uint32_t phy_tune; /**< USB HS PHY controller tuning register
|
||||
* value (STM32-specific), see USBPHYC_TUNE
|
||||
* register in STM32 Reference Manual */
|
||||
#endif /* defined(MODULE_PERIPH_USBDEV_HS_UTMI) */
|
||||
#endif /* defined(MCU_STM32) || DOXYGEN */
|
||||
} dwc2_usb_otg_fshs_config_t;
|
||||
|
||||
|
@ -156,39 +156,7 @@ config MODULE_PERIPH_INIT_TEMPERATURE
|
||||
depends on MODULE_PERIPH_TEMPERATURE
|
||||
|
||||
rsource "Kconfig.uart"
|
||||
|
||||
config MODULE_PERIPH_USBDEV
|
||||
bool "USBDEV peripheral driver"
|
||||
depends on HAS_PERIPH_USBDEV
|
||||
select MODULE_PERIPH_COMMON
|
||||
select MODULE_PERIPH_USBDEV_CLK
|
||||
|
||||
config MODULE_PERIPH_INIT_USBDEV
|
||||
bool "Auto initialize USBDEV peripheral"
|
||||
default y if MODULE_PERIPH_INIT
|
||||
depends on MODULE_PERIPH_USBDEV
|
||||
|
||||
config MODULE_PERIPH_USBDEV_HS_ULPI
|
||||
bool "Use USB HS pripheral with UPLI HS PHY"
|
||||
depends on HAS_PERIPH_USBDEV_HS_ULPI
|
||||
depends on MODULE_PERIPH_USBDEV
|
||||
|
||||
config MODULE_PERIPH_INIT_USBDEV_HS_ULPI
|
||||
bool
|
||||
default y if MODULE_PERIPH_INIT && MODULE_PERIPH_USBDEV_HS_ULPI
|
||||
depends on HAS_PERIPH_USBDEV_HS_ULPI
|
||||
depends on MODULE_PERIPH_USBDEV
|
||||
|
||||
config MODULE_PERIPH_USBDEV_CLK
|
||||
bool
|
||||
depends on HAS_PERIPH_USBDEV
|
||||
help
|
||||
Enable the USB device specific clock settings, if there are any
|
||||
|
||||
config MODULE_PERIPH_INIT_USBDEV_CLK
|
||||
bool
|
||||
default y if MODULE_PERIPH_INIT && MODULE_PERIPH_USBDEV_CLK
|
||||
depends on HAS_PERIPH_USBDEV
|
||||
rsource "Kconfig.usbdev"
|
||||
|
||||
endif # TEST_KCONFIG
|
||||
|
||||
|
54
drivers/periph_common/Kconfig.usbdev
Normal file
54
drivers/periph_common/Kconfig.usbdev
Normal file
@ -0,0 +1,54 @@
|
||||
# Copyright (c) 2020 HAW Hamburg
|
||||
# 2022 Gunar Schorcht
|
||||
#
|
||||
# This file is subject to the terms and conditions of the GNU Lesser
|
||||
# General Public License v2.1. See the file LICENSE in the top level
|
||||
# directory for more details.
|
||||
#
|
||||
|
||||
menuconfig MODULE_PERIPH_USBDEV
|
||||
bool "USBDEV peripheral driver"
|
||||
depends on HAS_PERIPH_USBDEV
|
||||
select MODULE_PERIPH_COMMON
|
||||
select MODULE_PERIPH_USBDEV_CLK
|
||||
|
||||
if MODULE_PERIPH_USBDEV
|
||||
|
||||
# TODO: the 'init' modules are actually just artifacts from the way
|
||||
# periph_init_% modules are handled in Makefile. We need to define them to keep
|
||||
# the list the same for now. We should be able to remove them later on.
|
||||
|
||||
config MODULE_PERIPH_INIT_USBDEV
|
||||
bool "Auto initialize USBDEV peripheral"
|
||||
default y if MODULE_PERIPH_INIT
|
||||
|
||||
config MODULE_PERIPH_USBDEV_HS_ULPI
|
||||
bool "Use USB HS peripheral with ULPI HS PHY"
|
||||
depends on HAS_PERIPH_USBDEV_HS_ULPI
|
||||
|
||||
config MODULE_PERIPH_INIT_USBDEV_HS_ULPI
|
||||
bool
|
||||
depends on MODULE_PERIPH_USBDEV_HS_ULPI
|
||||
default y if MODULE_PERIPH_INIT
|
||||
|
||||
config MODULE_PERIPH_USBDEV_HS_UTMI
|
||||
bool "Use USB HS peripheral with internal UTMI+ HS PHY"
|
||||
depends on HAS_PERIPH_USBDEV_HS_UTMI
|
||||
|
||||
config MODULE_PERIPH_INIT_USBDEV_HS_UTMI
|
||||
bool
|
||||
depends on MODULE_PERIPH_USBDEV_HS_UTMI
|
||||
default y if MODULE_PERIPH_INIT
|
||||
|
||||
endif
|
||||
|
||||
config MODULE_PERIPH_USBDEV_CLK
|
||||
bool
|
||||
depends on HAS_PERIPH_USBDEV
|
||||
help
|
||||
Enable the USB device specific clock settings, if there are any
|
||||
|
||||
config MODULE_PERIPH_INIT_USBDEV_CLK
|
||||
bool
|
||||
depends on MODULE_PERIPH_USBDEV_CLK
|
||||
default y if MODULE_PERIPH_INIT
|
@ -633,14 +633,17 @@ static void _reset_periph(dwc2_usb_otg_fshs_t *usbdev)
|
||||
#ifdef MCU_STM32
|
||||
static void _enable_gpio(const dwc2_usb_otg_fshs_config_t *conf)
|
||||
{
|
||||
(void)conf;
|
||||
#ifndef MODULE_PERIPH_USBDEV_HS_ULPI
|
||||
/* Enables clock on the GPIO bus */
|
||||
gpio_init(conf->dp, GPIO_IN);
|
||||
gpio_init(conf->dm, GPIO_IN);
|
||||
/* Configure AF for the pins */
|
||||
gpio_init_af(conf->dp, conf->af);
|
||||
gpio_init_af(conf->dm, conf->af);
|
||||
#endif /* MODULE_PERIPH_USBDEV_HS_ULPI */
|
||||
}
|
||||
#endif
|
||||
#endif /* MCU_STM32 */
|
||||
|
||||
static void _set_mode_device(dwc2_usb_otg_fshs_t *usbdev)
|
||||
{
|
||||
@ -693,11 +696,12 @@ static void _usbdev_init(usbdev_t *dev)
|
||||
if (conf->type == DWC2_USB_OTG_HS) {
|
||||
if (conf->phy == DWC2_USB_OTG_PHY_BUILTIN) {
|
||||
/* Disable the ULPI clock in low power mode, this is essential for the
|
||||
* peripheral when using the built-in phy or UTMI phy */
|
||||
* peripheral when using the built-in PHY */
|
||||
periph_lpclk_dis(conf->ahb, RCC_AHB1LPENR_OTGHSULPILPEN);
|
||||
/* select on-chip builtin PHY */
|
||||
_global_regs(usbdev->config)->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
|
||||
}
|
||||
|
||||
#ifdef MODULE_PERIPH_USBDEV_HS_ULPI
|
||||
else if (conf->phy == DWC2_USB_OTG_PHY_ULPI) {
|
||||
/* initialize ULPI interface */
|
||||
@ -729,16 +733,18 @@ static void _usbdev_init(usbdev_t *dev)
|
||||
/* enable ULPI clock */
|
||||
periph_clk_en(conf->ahb, RCC_AHB1ENR_OTGHSULPIEN);
|
||||
|
||||
#if !defined(MCU_STM32)
|
||||
/* TODO following settings are required for DWC2 HS but are not
|
||||
* defined for STM32 MCUs where these settings correspond to the
|
||||
* reset value of the GUSBCFG register */
|
||||
#ifdef USB_OTG_GUSBCFG_ULPI_UTMI_SEL
|
||||
/* select ULPI PHY */
|
||||
_global_regs(usbdev->config)->GUSBCFG |= USB_OTG_GUSBCFG_ULPI_UTMI_SEL
|
||||
/* use the 8-bit interface and single data rate */
|
||||
_global_regs(usbdev->config)->GUSBCFG &= ~(USB_OTG_GUSBCFG_PHYIF16 |
|
||||
USB_OTG_GUSBCFG_DDRSEL);
|
||||
#endif /* !defined(MCU_STM32) */
|
||||
_global_regs(usbdev->config)->GUSBCFG |= USB_OTG_GUSBCFG_ULPI_UTMI_SEL;
|
||||
#endif
|
||||
#ifdef USB_OTG_GUSBCFG_PHYIF
|
||||
/* use the 8-bit interface */
|
||||
_global_regs(usbdev->config)->GUSBCFG &= ~USB_OTG_GUSBCFG_PHYIF;
|
||||
#endif /* USB_OTG_GUSBCFG_PHYIF */
|
||||
#ifdef USB_OTG_GUSBCFG_DDRSEL
|
||||
/* use single data rate */
|
||||
_global_regs(usbdev->config)->GUSBCFG &= ~USB_OTG_GUSBCFG_DDRSEL;
|
||||
#endif /* USB_OTG_GUSBCFG_DDRSEL */
|
||||
|
||||
/* disable the on-chip FS transceiver */
|
||||
_global_regs(usbdev->config)->GUSBCFG &= ~USB_OTG_GUSBCFG_PHYSEL;
|
||||
@ -749,12 +755,76 @@ static void _usbdev_init(usbdev_t *dev)
|
||||
/* disable ULPI FS/LS serial interface */
|
||||
_global_regs(usbdev->config)->GUSBCFG &= ~USB_OTG_GUSBCFG_ULPIFSLS;
|
||||
}
|
||||
|
||||
#elif defined(MODULE_PERIPH_USBDEV_HS_UTMI)
|
||||
else if (conf->phy == DWC2_USB_OTG_PHY_UTMI) {
|
||||
/* enable ULPI clock */
|
||||
periph_clk_en(conf->ahb, RCC_AHB1ENR_OTGHSULPIEN);
|
||||
/* enable UTMI HS PHY Controller clock */
|
||||
periph_clk_en(APB2, RCC_APB2ENR_OTGPHYCEN);
|
||||
|
||||
#ifdef USB_OTG_GUSBCFG_ULPI_UTMI_SEL
|
||||
/* select UTMI+ PHY */
|
||||
_global_regs(usbdev->config)->GUSBCFG &= ~USB_OTG_GUSBCFG_ULPI_UTMI_SEL;
|
||||
#endif /* USB_OTG_GUSBCFG_ULPI_UTMI_SEL */
|
||||
#ifdef USB_OTG_GUSBCFG_PHYIF
|
||||
/* use the 8-bit interface and single data rate */
|
||||
_global_regs(usbdev->config)->GUSBCFG &= ~USB_OTG_GUSBCFG_PHYIF;
|
||||
#endif /* USB_OTG_GUSBCFG_PHYIF */
|
||||
|
||||
/* disable the on-chip FS transceiver */
|
||||
_global_regs(usbdev->config)->GUSBCFG &= ~USB_OTG_GUSBCFG_PHYSEL;
|
||||
|
||||
/* configure the USB HS PHY Controller (USB_HS_PHYC),
|
||||
* USB_HS_PHYC and GCCFG are STM32 specific */
|
||||
#ifdef USB_HS_PHYC
|
||||
/* enable USB HS PHY Controller */
|
||||
_global_regs(usbdev->config)->GCCFG |= USB_OTG_GCCFG_PHYHSEN;
|
||||
|
||||
/* determine the PLL input clock of the USB HS PHY from HSE clock */
|
||||
switch (CLOCK_HSE) {
|
||||
case 12000000:
|
||||
USB_HS_PHYC->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL1_PLLSEL_12MHZ;
|
||||
break;
|
||||
case 12500000:
|
||||
USB_HS_PHYC->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL1_PLLSEL_12_5MHZ;
|
||||
break;
|
||||
case 16000000:
|
||||
USB_HS_PHYC->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL1_PLLSEL_16MHZ;
|
||||
break;
|
||||
case 24000000:
|
||||
USB_HS_PHYC->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL1_PLLSEL_24MHZ;
|
||||
break;
|
||||
case 25000000:
|
||||
USB_HS_PHYC->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL1_PLLSEL_25MHZ;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/* configure the tuning interface of the USB HS PHY */
|
||||
USB_HS_PHYC->USB_HS_PHYC_TUNE |= conf->phy_tune;
|
||||
|
||||
/* check whether the LDO regulator is used by on the chip */
|
||||
if (USB_HS_PHYC->USB_HS_PHYC_LDO & USB_HS_PHYC_LDO_USED) {
|
||||
/* enable the LDO */
|
||||
USB_HS_PHYC->USB_HS_PHYC_LDO |= USB_HS_PHYC_LDO_ENABLE;
|
||||
/* wait until the LDO is ready */
|
||||
while (!(USB_HS_PHYC->USB_HS_PHYC_LDO & USB_HS_PHYC_LDO_STATUS)) {}
|
||||
}
|
||||
|
||||
/* enable the PLL of the USB HS PHY */
|
||||
USB_HS_PHYC->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL_PLLEN;
|
||||
#endif /* USB_HS_PHYC */
|
||||
}
|
||||
|
||||
#else /* MODULE_PERIPH_USBDEV_HS_ULPI */
|
||||
else {
|
||||
/* only on-chip PHY support enabled */
|
||||
assert(conf->phy == DWC2_USB_OTG_PHY_BUILTIN);
|
||||
}
|
||||
#endif /* MODULE_PERIPH_USBDEV_HS_ULPI */
|
||||
|
||||
}
|
||||
#endif /* DWC2_USB_OTG_HS_ENABLED */
|
||||
|
||||
@ -782,14 +852,17 @@ static void _usbdev_init(usbdev_t *dev)
|
||||
USB_OTG_GOTGCTL_BVALOEN |
|
||||
USB_OTG_GOTGCTL_BVALOVAL;
|
||||
#endif /* defined(STM32_USB_OTG_CID_1x) */
|
||||
|
||||
if (conf->phy == DWC2_USB_OTG_PHY_BUILTIN) {
|
||||
/* set `Power Down Disable` to activate the on-chip FS transceiver */
|
||||
_global_regs(usbdev->config)->GCCFG |= USB_OTG_GCCFG_PWRDWN;
|
||||
}
|
||||
else if (IS_USED(MODULE_PERIPH_USBDEV_HS_ULPI) && (conf->phy == DWC2_USB_OTG_PHY_ULPI)) {
|
||||
/* clear `Power Down Disable` to deactivate the on-chip FS transceiver */
|
||||
_global_regs(usbdev->config)->GCCFG &= USB_OTG_GCCFG_PWRDWN;
|
||||
_global_regs(usbdev->config)->GCCFG &= ~USB_OTG_GCCFG_PWRDWN;
|
||||
}
|
||||
else if (IS_USED(MODULE_PERIPH_USBDEV_HS_UTMI) && (conf->phy == DWC2_USB_OTG_PHY_UTMI)) {
|
||||
/* clear `Power Down Disable` to deactivate the on-chip FS transceiver */
|
||||
_global_regs(usbdev->config)->GCCFG &= ~USB_OTG_GCCFG_PWRDWN;
|
||||
}
|
||||
|
||||
#elif defined(MCU_ESP32)
|
||||
|
@ -424,6 +424,11 @@ config HAS_PERIPH_USBDEV
|
||||
help
|
||||
Indicates that an USBDEV peripheral is present.
|
||||
|
||||
config HAS_PERIPH_USBDEV_HS_UTMI
|
||||
bool
|
||||
help
|
||||
Indicates that an USBDEV HS peripheral with internal UTMI+ HS PHY is present.
|
||||
|
||||
config HAS_PERIPH_USBDEV_HS_ULPI
|
||||
bool
|
||||
help
|
||||
|
Loading…
Reference in New Issue
Block a user