diff --git a/arch/arm/src/stm32h7/Kconfig b/arch/arm/src/stm32h7/Kconfig index 93d1def5db2..e4aaa2256e2 100644 --- a/arch/arm/src/stm32h7/Kconfig +++ b/arch/arm/src/stm32h7/Kconfig @@ -637,7 +637,7 @@ config STM32H7_OTGFS select USBHOST_HAVE_ASYNCH if USBHOST config STM32H7_OTGHS - bool "OTG HS" + bool "OTG FS/HS" default n depends on EXPERIMENTAL select USBHOST_HAVE_ASYNCH if USBHOST @@ -960,6 +960,10 @@ config STM32H7_SYSCFG_IOCOMPENSATION menu "OTG_HS Configuration" depends on STM32H7_OTGHS +config STM32H7_OTGHS_FS + bool "OTGHS in FS mode" + default n + choice prompt "ULPI Selection" default STM32H7_OTGHS_NO_ULPI diff --git a/arch/arm/src/stm32h7/hardware/stm32h7x3xx_pinmap.h b/arch/arm/src/stm32h7/hardware/stm32h7x3xx_pinmap.h index 99f4d4d814e..8338771baa8 100644 --- a/arch/arm/src/stm32h7/hardware/stm32h7x3xx_pinmap.h +++ b/arch/arm/src/stm32h7/hardware/stm32h7x3xx_pinmap.h @@ -737,20 +737,20 @@ #define GPIO_OTGHS_ID (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_OPENDRAIN|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN12) #define GPIO_OTGHS_SOF (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN4) -#define GPIO_OTG_HS_ULPI_CK (GPIO_ALT|GPIO_AF10|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN5) -#define GPIO_OTG_HS_ULPI_D0 (GPIO_ALT|GPIO_AF10|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3) -#define GPIO_OTG_HS_ULPI_D1 (GPIO_ALT|GPIO_AF10|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN0) -#define GPIO_OTG_HS_ULPI_D2 (GPIO_ALT|GPIO_AF10|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN1) -#define GPIO_OTG_HS_ULPI_D3 (GPIO_ALT|GPIO_AF10|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN10) -#define GPIO_OTG_HS_ULPI_D4 (GPIO_ALT|GPIO_AF10|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN11) -#define GPIO_OTG_HS_ULPI_D5 (GPIO_ALT|GPIO_AF10|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN12) -#define GPIO_OTG_HS_ULPI_D6 (GPIO_ALT|GPIO_AF10|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN13) -#define GPIO_OTG_HS_ULPI_D7 (GPIO_ALT|GPIO_AF10|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN5) -#define GPIO_OTG_HS_ULPI_DIR_1 (GPIO_ALT|GPIO_AF10|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN2) -#define GPIO_OTG_HS_ULPI_DIR_2 (GPIO_ALT|GPIO_AF10|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN11) -#define GPIO_OTG_HS_ULPI_NXT_1 (GPIO_ALT|GPIO_AF10|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN3) -#define GPIO_OTG_HS_ULPI_NXT_2 (GPIO_ALT|GPIO_AF10|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN4) -#define GPIO_OTG_HS_ULPI_STP (GPIO_ALT|GPIO_AF10|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN0) +#define GPIO_OTG_HS_ULPI_CK_1 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN5) +#define GPIO_OTG_HS_ULPI_D0_1 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3) +#define GPIO_OTG_HS_ULPI_D1_1 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN0) +#define GPIO_OTG_HS_ULPI_D2_1 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN1) +#define GPIO_OTG_HS_ULPI_D3_1 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN10) +#define GPIO_OTG_HS_ULPI_D4_1 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN11) +#define GPIO_OTG_HS_ULPI_D5_1 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN12) +#define GPIO_OTG_HS_ULPI_D6_1 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN13) +#define GPIO_OTG_HS_ULPI_D7_1 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN5) +#define GPIO_OTG_HS_ULPI_DIR_1 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN2) +#define GPIO_OTG_HS_ULPI_DIR_2 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTI|GPIO_PIN11) +#define GPIO_OTG_HS_ULPI_NXT_1 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN3) +#define GPIO_OTG_HS_ULPI_NXT_2 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN4) +#define GPIO_OTG_HS_ULPI_STP_1 (GPIO_ALT|GPIO_AF10|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN0) /* Event outputs */ diff --git a/arch/arm/src/stm32h7/stm32_otg.h b/arch/arm/src/stm32h7/stm32_otg.h index ebffd0ddb35..2a414566685 100644 --- a/arch/arm/src/stm32h7/stm32_otg.h +++ b/arch/arm/src/stm32h7/stm32_otg.h @@ -121,6 +121,19 @@ struct usbhost_connection_s *stm32_otgfshost_initialize(int controller); struct usbdev_s; void stm32_usbsuspend(struct usbdev_s *dev, bool resume); +#ifdef CONFIG_STM32H7_OTGHS_EXTERNAL_ULPI +/**************************************************************************** + * Name: stm32_usbulpireset + * + * Description: + * Reset external ULPI. + * + ****************************************************************************/ + +struct usbdev_s; +void stm32_usbulpireset(struct usbdev_s *dev); +#endif + #undef EXTERN #if defined(__cplusplus) } diff --git a/arch/arm/src/stm32h7/stm32_otgdev.c b/arch/arm/src/stm32h7/stm32_otgdev.c index 23f394f5af0..1172ce7d3ee 100644 --- a/arch/arm/src/stm32h7/stm32_otgdev.c +++ b/arch/arm/src/stm32h7/stm32_otgdev.c @@ -60,6 +60,16 @@ enabled. Enable STM32H7_HSI48 #endif +#if defined(CONFIG_STM32H7_OTGHS) && !defined(CONFIG_STM32H7_OTGHS_FS) && \ + defined(CONFIG_STM32H7_OTGHS_NO_ULPI) +# error OTG HS selected but no ULPI enabled +#endif + +#if defined(CONFIG_STM32H7_OTGHS_EXTERNAL_ULPI) && \ + !defined(CONFIG_STM32H7_SYSCFG_IOCOMPENSATION) +# error External ULPI needs IOCOMPENSATION enabled +#endif + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -2103,7 +2113,11 @@ static void stm32_usbreset(struct stm32_usbdev_s *priv) stm32_setaddress(priv, 0); priv->devstate = DEVSTATE_DEFAULT; +#ifdef CONFIG_STM32H7_OTGHS_EXTERNAL_ULPI + priv->usbdev.speed = USB_SPEED_HIGH; +#else priv->usbdev.speed = USB_SPEED_FULL; +#endif /* Re-configure EP0 */ @@ -3407,7 +3421,11 @@ static inline void stm32_enuminterrupt(struct stm32_usbdev_s *priv) regval = stm32_getreg(STM32_OTG_GUSBCFG); regval &= ~OTG_GUSBCFG_TRDT_MASK; +#ifdef CONFIG_STM32H7_OTGHS + regval |= OTG_GUSBCFG_TRDT(9); +#else regval |= OTG_GUSBCFG_TRDT(6); +#endif stm32_putreg(regval, STM32_OTG_GUSBCFG); } @@ -5244,14 +5262,23 @@ static void stm32_hwinitialize(struct stm32_usbdev_s *priv) stm32_putreg(OTG_GAHBCFG_TXFELVL, STM32_OTG_GAHBCFG); -#if defined(CONFIG_STM32H7_OTGFS) || defined (CONFIG_STM32H7_OTGHS_NO_ULPI) +#ifdef CONFIG_STM32H7_OTGHS_NO_ULPI /* Full speed serial transceiver select */ - regval = stm32_getreg(STM32_OTG_GUSBCFG); + regval = stm32_getreg(STM32_OTG_GUSBCFG); regval |= OTG_GUSBCFG_PHYSEL; stm32_putreg(regval, STM32_OTG_GUSBCFG); #endif +#if defined(CONFIG_STM32H7_OTGHS_FS) && \ + defined(CONFIG_STM32H7_OTGHS_EXTERNAL_ULPI) + /* ULPI Full speed mode */ + + regval = stm32_getreg(STM32_OTG_GUSBCFG); + regval |= OTG_GUSBCFG_ULPIFSL; + stm32_putreg(regval, STM32_OTG_GUSBCFG); +#endif + /* Common USB OTG core initialization */ /* Wait for AHB master IDLE state */ @@ -5268,7 +5295,9 @@ static void stm32_hwinitialize(struct stm32_usbdev_s *priv) /* Then perform the core soft reset. */ - stm32_putreg(OTG_GRSTCTL_CSRST, STM32_OTG_GRSTCTL); + regval = stm32_getreg(STM32_OTG_GRSTCTL); + regval |= OTG_GRSTCTL_CSRST; + stm32_putreg(regval, STM32_OTG_GRSTCTL); for (timeout = 0; timeout < STM32_READY_DELAY; timeout++) { regval = stm32_getreg(STM32_OTG_GRSTCTL); @@ -5282,21 +5311,37 @@ static void stm32_hwinitialize(struct stm32_usbdev_s *priv) up_udelay(3); + regval = stm32_getreg(STM32_OTG_GCCFG); + +#ifdef CONFIG_STM32H7_OTGHS_NO_ULPI /* Enable USB FS transceiver */ - regval = OTG_GCCFG_PWRDWN; + regval |= OTG_GCCFG_PWRDWN; +#endif #ifdef CONFIG_USBDEV_VBUSSENSING + /* Detection Enable when set */ + regval |= OTG_GCCFG_VBDEN; #endif stm32_putreg(regval, STM32_OTG_GCCFG); up_mdelay(20); +#ifdef CONFIG_STM32H7_OTGHS_EXTERNAL_ULPI + /* Enable delay to default timing, necessary for some ULPI PHYs such + * as such as USB334x + */ + + regval = stm32_getreg(STM32_OTG_DCFG); + regval |= OTG_DCFG_XCVRDLY; + stm32_putreg(regval, STM32_OTG_DCFG); +#endif + /* When VBUS sensing is not used we need to force the B session valid */ #ifndef CONFIG_USBDEV_VBUSSENSING - regval = stm32_getreg(STM32_OTG_GOTGCTL); + regval = stm32_getreg(STM32_OTG_GOTGCTL); regval |= (OTG_GOTGCTL_BVALOEN | OTG_GOTGCTL_BVALOVAL); stm32_putreg(regval, STM32_OTG_GOTGCTL); #endif @@ -5322,11 +5367,17 @@ static void stm32_hwinitialize(struct stm32_usbdev_s *priv) regval |= OTG_DCFG_PFIVL_80PCT; stm32_putreg(regval, STM32_OTG_DCFG); - /* Set full speed PHY */ + /* Set device high or full speed */ regval = stm32_getreg(STM32_OTG_DCFG); regval &= ~OTG_DCFG_DSPD_MASK; +#if defined(CONFIG_STM32H7_OTGHS_FS) + regval |= OTG_DCFG_DSPD_FSHS; +#elif defined(CONFIG_STM32H7_OTGHS) + regval |= OTG_DCFG_DSPD_HS; +#else regval |= OTG_DCFG_DSPD_FS; +#endif stm32_putreg(regval, STM32_OTG_DCFG); /* Set Rx FIFO size */ @@ -5574,8 +5625,8 @@ void arm_usbinitialize(void) * current detection. */ - /* Configure OTG alternate function pins - */ +#ifndef CONFIG_STM32H7_OTGHS_EXTERNAL_ULPI + /* Configure OTG alternate function pins */ stm32_configgpio(GPIO_OTG_DM); stm32_configgpio(GPIO_OTG_DP); @@ -5587,8 +5638,29 @@ void arm_usbinitialize(void) /* SOF output pin configuration is configurable. */ -#ifdef CONFIG_STM32H7_OTG_SOFOUTPUT +# ifdef CONFIG_STM32H7_OTG_SOFOUTPUT stm32_configgpio(GPIO_OTG_SOF); +# endif + +#else + /* Configure ULPI alternate function pins */ + + stm32_configgpio(GPIO_OTG_HS_ULPI_CK); + stm32_configgpio(GPIO_OTG_HS_ULPI_D0); + stm32_configgpio(GPIO_OTG_HS_ULPI_D1); + stm32_configgpio(GPIO_OTG_HS_ULPI_D2); + stm32_configgpio(GPIO_OTG_HS_ULPI_D3); + stm32_configgpio(GPIO_OTG_HS_ULPI_D4); + stm32_configgpio(GPIO_OTG_HS_ULPI_D5); + stm32_configgpio(GPIO_OTG_HS_ULPI_D6); + stm32_configgpio(GPIO_OTG_HS_ULPI_D7); + stm32_configgpio(GPIO_OTG_HS_ULPI_DIR); + stm32_configgpio(GPIO_OTG_HS_ULPI_NXT); + stm32_configgpio(GPIO_OTG_HS_ULPI_STP); + + /* Reset external ULPI */ + + stm32_usbulpireset((struct usbdev_s *) priv); #endif /* Uninitialize the hardware so that we know that we are starting from a @@ -5757,7 +5829,12 @@ int usbdev_register(struct usbdevclass_driver_s *driver) */ stm32_pullup(&priv->usbdev, true); + +#if defined(CONFIG_STM32H7_OTGHS_EXTERNAL_ULPI) + priv->usbdev.speed = USB_SPEED_HIGH; +#else priv->usbdev.speed = USB_SPEED_FULL; +#endif } return ret;