1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

drivers/usbdev_synopsys_dwc2: add internal UTMI HS PHY support

This commit is contained in:
Gunar Schorcht 2022-10-09 17:03:20 +02:00
parent 85054e3d1a
commit 41b0a3efae
5 changed files with 95 additions and 4 deletions

View File

@ -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

View File

@ -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;

View File

@ -31,6 +31,15 @@ config MODULE_PERIPH_INIT_USBDEV_HS_ULPI
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

View File

@ -697,11 +697,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 */
@ -755,12 +756,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 */
@ -788,14 +853,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)

View File

@ -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