Explorar o código

add support for EFM32GG

merge GG12 GG12 to simply OPT_MCU_EFM32GG
hathach %!s(int64=4) %!d(string=hai) anos
pai
achega
9cd5a87c64

+ 1 - 1
hw/bsp/board_mcu.h

@@ -125,7 +125,7 @@
 #elif CFG_TUSB_MCU == OPT_MCU_RP2040
   #include "pico.h"
   
-#elif CFG_TUSB_MCU == OPT_MCU_EFM32GG || CFG_TUSB_MCU == OPT_MCU_EFM32GG11 || CFG_TUSB_MCU == OPT_MCU_EFM32GG12
+#elif CFG_TUSB_MCU == OPT_MCU_EFM32GG
   #include "em_device.h"
 
 #elif CFG_TUSB_MCU == OPT_MCU_RX63X || CFG_TUSB_MCU == OPT_MCU_RX65X

+ 2 - 2
hw/bsp/sltb009a/board.mk

@@ -8,7 +8,7 @@ CFLAGS += \
   -D__STARTUP_CLEAR_BSS \
   -D__START=main \
   -DEFM32GG12B810F1024GM64 \
-  -DCFG_TUSB_MCU=OPT_MCU_EFM32GG12 
+  -DCFG_TUSB_MCU=OPT_MCU_EFM32GG
 
 # mcu driver cause following warnings
 #CFLAGS += -Wno-error=unused-parameter
@@ -24,7 +24,7 @@ LD_FILE = $(SILABS_CMSIS)/Source/GCC/$(SILABS_FAMILY).ld
 
 SRC_C += \
   $(SILABS_CMSIS)/Source/system_$(SILABS_FAMILY).c \
-  src/portable/silabs/efm32/dcd_efm32.c
+	src/portable/synopsys/dwc2/dcd_dwc2.c
 
 SRC_S += \
   $(SILABS_CMSIS)/Source/GCC/startup_$(SILABS_FAMILY).S

+ 7 - 0
hw/bsp/stm32f4/family.c

@@ -36,6 +36,11 @@ void OTG_FS_IRQHandler(void)
   tud_int_handler(0);
 }
 
+void OTG_HS_IRQHandler(void)
+{
+  tud_int_handler(1);
+}
+
 //--------------------------------------------------------------------+
 // MACRO TYPEDEF CONSTANT ENUM
 //--------------------------------------------------------------------+
@@ -134,6 +139,8 @@ void board_init(void)
   // Enable USB OTG clock
   __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
 
+//  __HAL_RCC_USB_OTG_HS_CLK_ENABLE();
+
   board_vbus_sense_init();
 }
 

+ 1 - 0
hw/bsp/stm32h7/boards/stm32h743eval/board.mk

@@ -2,6 +2,7 @@ CFLAGS += -DSTM32H743xx -DHSE_VALUE=25000000
 
 # Default is Highspeed port
 PORT ?= 1
+SPEED ?= high
 
 SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32h743xx.s
 LD_FILE = $(BOARD_PATH)/stm32h743xx_flash.ld

+ 9 - 3
hw/bsp/stm32h7/family.mk

@@ -19,16 +19,22 @@ CFLAGS += \
 	-DBOARD_DEVICE_RHPORT_NUM=$(PORT)
 
 ifeq ($(PORT), 1)
-  CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED
-  $(info "PORT1 High Speed")
+  ifeq ($(SPEED), high)
+    CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED
+    $(info "Using OTG_HS in HighSpeed mode")
+  else
+    CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_FULL_SPEED
+    $(info "Using OTG_HS in FullSpeed mode")
+  endif
 else
-  $(info "PORT0 Full Speed")
+  $(info "Using OTG_FS")
 endif
 
 # suppress warning caused by vendor mcu driver
 CFLAGS += -Wno-error=maybe-uninitialized -Wno-error=cast-align
 
 # All source paths should be relative to the top level.
+
 SRC_C += \
 	src/portable/synopsys/dwc2/dcd_dwc2.c \
 	$(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \

+ 1 - 1
src/device/dcd_attr.h

@@ -169,7 +169,7 @@
   #define DCD_ATTR_ENDPOINT_MAX   16
 
 //------------- Silabs -------------//
-#elif TU_CHECK_MCU(OPT_MCU_EFM32GG, OPT_MCU_EFM32GG11, OPT_MCU_EFM32GG12)
+#elif TU_CHECK_MCU(OPT_MCU_EFM32GG)
   #define DCD_ATTR_ENDPOINT_MAX   7
 
 //------------- Renesas -------------//

+ 1 - 1
src/host/hcd_attr.h

@@ -82,7 +82,7 @@
 #elif TU_CHECK_MCU(OPT_MCU_RP2040)
 
 //------------- Silabs -------------//
-#elif TU_CHECK_MCU(OPT_MCU_EFM32GG, OPT_MCU_EFM32GG11, OPT_MCU_EFM32GG12)
+#elif TU_CHECK_MCU(OPT_MCU_EFM32GG)
 
 //------------- Renesas -------------//
 #elif TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N)

+ 54 - 36
src/portable/synopsys/dwc2/dcd_dwc2.c

@@ -31,7 +31,9 @@
 #include "device/dcd_attr.h"
 
 #if TUSB_OPT_DEVICE_ENABLED && \
-    ( defined(DCD_ATTR_DWC2_STM32) || TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3, OPT_MCU_GD32VF103, OPT_MCU_BCM2711) )
+    ( defined(DCD_ATTR_DWC2_STM32) || \
+      TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3, OPT_MCU_GD32VF103) || \
+      TU_CHECK_MCU(OPT_MCU_EFM32GG, OPT_MCU_BCM2711) )
 
 #include "device/dcd.h"
 #include "dwc2_type.h"
@@ -44,6 +46,8 @@
   #include "dwc2_gd32.h"
 #elif TU_CHECK_MCU(OPT_MCU_BCM2711)
   #include "dwc2_bcm.h"
+#elif TU_CHECK_MCU(OPT_MCU_EFM32GG)
+  #include "dwc2_efm32.h"
 #else
   #error "Unsupported MCUs"
 #endif
@@ -260,6 +264,9 @@ void print_dwc2_info(dwc2_regs_t * dwc2)
   dwc2_ghwcfg3_t const * hw_cfg3 = &dwc2->ghwcfg3_bm;
   dwc2_ghwcfg4_t const * hw_cfg4 = &dwc2->ghwcfg4_bm;
 
+  TU_LOG_HEX(DWC2_DEBUG, dwc2->gotgctl);
+  TU_LOG_HEX(DWC2_DEBUG, dwc2->gusbcfg);
+  TU_LOG_HEX(DWC2_DEBUG, dwc2->dcfg);
   TU_LOG_HEX(DWC2_DEBUG, dwc2->guid);
   TU_LOG_HEX(DWC2_DEBUG, dwc2->gsnpsid);
   TU_LOG_HEX(DWC2_DEBUG, dwc2->ghwcfg1);
@@ -349,23 +356,22 @@ static void phy_fs_init(dwc2_regs_t * dwc2)
   // Select FS PHY
   dwc2->gusbcfg |= GUSBCFG_PHYSEL;
 
+  // MCU specific PHY init before reset
+  dwc2_phy_init(dwc2, HS_PHY_TYPE_NONE);
+
   // Reset core after selecting PHY
   reset_core(dwc2);
 
-  // set turn around
   // USB turnaround time is critical for certification where long cables and 5-Hubs are used.
   // So if you need the AHB to run at less than 30 MHz, and if USB turnaround time is not critical,
-  // these bits can be programmed to a larger value.
-  //TU_LOG_INT(DWC2_DEBUG, (dwc2->gusbcfg & GUSBCFG_TRDT_Msk) >> GUSBCFG_TRDT_Pos );
-  dwc2_phyfs_set_turnaround(dwc2);
+  // these bits can be programmed to a larger value. Default is 5
+  dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_TRDT_Msk) | (5u << GUSBCFG_TRDT_Pos);
+
+  // MCU specific PHY update post reset
+  dwc2_phy_update(dwc2, HS_PHY_TYPE_NONE);
 
   // set max speed
   dwc2->dcfg = (dwc2->dcfg & ~DCFG_DSPD_Msk) | (DCFG_DSPD_FS << DCFG_DSPD_Pos);
-
-  #if defined(DCD_ATTR_DWC2_STM32)
-  // activate FS PHY on stm32
-  dwc2->stm32_gccfg |= STM32_GCCFG_PWRDWN;
-  #endif
 }
 
 static void phy_hs_init(dwc2_regs_t * dwc2)
@@ -399,19 +405,13 @@ static void phy_hs_init(dwc2_regs_t * dwc2)
 
     // Set 16-bit interface if supported
     if (dwc2->ghwcfg4_bm.utmi_phy_data_width) gusbcfg |= GUSBCFG_PHYIF16;
-
-    #if defined(DCD_ATTR_DWC2_STM32) && defined(USB_HS_PHYC)
-    dwc2_stm32_utmi_phy_init(dwc2);
-    #endif
   }
 
   // Apply config
   dwc2->gusbcfg = gusbcfg;
 
-  #if defined(DCD_ATTR_DWC2_STM32)
-  // Disable STM32 FS PHY
-  dwc2->stm32_gccfg &= ~STM32_GCCFG_PWRDWN;
-  #endif
+  // mcu specific phy init
+  dwc2_phy_init(dwc2, dwc2->ghwcfg2_bm.hs_phy_type);
 
   // Reset core after selecting PHY
   reset_core(dwc2);
@@ -421,7 +421,10 @@ static void phy_hs_init(dwc2_regs_t * dwc2)
   // - 5 if using 16-bit PHY interface
   gusbcfg &= ~GUSBCFG_TRDT_Msk;
   gusbcfg |= (dwc2->ghwcfg4_bm.utmi_phy_data_width ? 5u : 9u) << GUSBCFG_TRDT_Pos;
-  dwc2->gusbcfg = gusbcfg; // Apply config
+  dwc2->gusbcfg = gusbcfg;
+
+  // MCU specific PHY update post reset
+  dwc2_phy_update(dwc2, dwc2->ghwcfg2_bm.hs_phy_type);
 
   // Set max speed
   dwc2->dcfg = (dwc2->dcfg & ~DCFG_DSPD_Msk) | (DCFG_DSPD_HS << DCFG_DSPD_Pos);
@@ -429,16 +432,16 @@ static void phy_hs_init(dwc2_regs_t * dwc2)
 
 static bool check_dwc2(dwc2_regs_t * dwc2)
 {
+#if CFG_TUSB_DEBUG >= DWC2_DEBUG
+  print_dwc2_info(dwc2);
+#endif
+
   // For some reasons: GD32VF103 snpsid and all hwcfg register are always zero (skip it)
 #if !TU_CHECK_MCU(OPT_MCU_GD32VF103)
   uint32_t const gsnpsid = dwc2->gsnpsid & GSNPSID_ID_MASK;
   TU_ASSERT(gsnpsid == DWC2_OTG_ID || gsnpsid == DWC2_FS_IOT_ID || gsnpsid == DWC2_HS_IOT_ID);
 #endif
 
-#if CFG_TUSB_DEBUG >= DWC2_DEBUG
-  print_dwc2_info(dwc2);
-#endif
-
   return true;
 }
 
@@ -451,8 +454,10 @@ void dcd_init (uint8_t rhport)
   // Check Synopsys ID register, failed if controller clock/power is not enabled
   TU_VERIFY(check_dwc2(dwc2), );
 
-  // Force device mode
-  dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_FHMOD) | GUSBCFG_FDMOD;
+  dcd_disconnect(rhport);
+
+  // max number of endpoints & total_fifo_size are:
+  // hw_cfg2->num_dev_ep, hw_cfg2->total_fifo_size
 
   if( phy_hs_supported(dwc2) )
   {
@@ -464,7 +469,11 @@ void dcd_init (uint8_t rhport)
     phy_fs_init(dwc2);
   }
 
-  TU_LOG_HEX(DWC2_DEBUG, dwc2->gusbcfg);
+  // Restart PHY clock
+  dwc2->pcgctl &= ~(PCGCTL_STOPPCLK | PCGCTL_GATEHCLK | PCGCTL_PWRCLMP | PCGCTL_RSTPDWNMODULE);
+
+  // Force device mode
+  dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_FHMOD) | GUSBCFG_FDMOD;
 
 	/* Set HS/FS Timeout Calibration to 7 (max available value).
 	 * The number of PHY clocks that the application programs in
@@ -476,27 +485,34 @@ void dcd_init (uint8_t rhport)
 	 */
   dwc2->gusbcfg |= (7ul << GUSBCFG_TOCAL_Pos);
 
-  // Restart PHY clock
-  dwc2->pcgctl &= ~(PCGCTL_STOPPCLK | PCGCTL_GATEHCLK | PCGCTL_PWRCLMP | PCGCTL_RSTPDWNMODULE);
+  // If USB host misbehaves during status portion of control xfer
+  // (non zero-length packet), send STALL back and discard.
+  dwc2->dcfg |= DCFG_NZLSOHSK;
+
+  // Clear A,B, VBus valid override
+  dwc2->gotgctl &= ~(GOTGCTL_BVALOEN | GOTGCTL_AVALOEN | GOTGCTL_VBVALOEN);
 
   // Clear all interrupts
   dwc2->gintsts |= dwc2->gintsts;
+  dwc2->gotgint |= dwc2->gotgint;
 
   // Required as part of core initialization.
   // TODO: How should mode mismatch be handled? It will cause
   // the core to stop working/require reset.
-  dwc2->gintmsk |= GINTMSK_OTGINT | GINTMSK_MMISM;
-
-  // If USB host misbehaves during status portion of control xfer
-  // (non zero-length packet), send STALL back and discard.
-  dwc2->dcfg |= DCFG_NZLSOHSK;
-
-  dwc2->gintmsk |= GINTMSK_USBRST | GINTMSK_ENUMDNEM | GINTMSK_USBSUSPM |
-                   GINTMSK_WUIM   | GINTMSK_RXFLVLM;
+  dwc2->gintmsk = GINTMSK_OTGINT   | GINTMSK_MMISM  | GINTMSK_RXFLVLM  |
+                  GINTMSK_USBSUSPM | GINTMSK_USBRST | GINTMSK_ENUMDNEM | GINTMSK_WUIM;
 
   // Enable global interrupt
   dwc2->gahbcfg |= GAHBCFG_GINT;
 
+  // make sure we are in device mode
+//  TU_ASSERT(!(dwc2->gintsts & GINTSTS_CMOD), );
+
+//  TU_LOG_HEX(DWC2_DEBUG, dwc2->gotgctl);
+//  TU_LOG_HEX(DWC2_DEBUG, dwc2->gusbcfg);
+//  TU_LOG_HEX(DWC2_DEBUG, dwc2->dcfg);
+//  TU_LOG_HEX(DWC2_DEBUG, dwc2->gahbcfg);
+
   dcd_connect(rhport);
 }
 
@@ -1096,6 +1112,8 @@ void dcd_int_handler(uint8_t rhport)
 
   uint32_t const int_status = dwc2->gintsts & dwc2->gintmsk;
 
+//  TU_LOG_HEX(DWC2_DEBUG, int_status);
+
   if(int_status & GINTSTS_USBRST)
   {
     // USBRST is start of reset.

+ 14 - 3
src/portable/synopsys/dwc2/dwc2_bcm.h

@@ -51,17 +51,28 @@ static inline void dwc2_dcd_int_disable (uint8_t rhport)
   BP_DisableIRQ(USB_IRQn);
 }
 
-TU_ATTR_ALWAYS_INLINE
 static inline void dwc2_remote_wakeup_delay(void)
 {
   // try to delay for 1 ms
   // TODO implement later
 }
 
-static inline void dwc2_phyfs_set_turnaround(dwc2_regs_t * dwc2)
+// MCU specific PHY init, called BEFORE core reset
+static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type)
 {
   (void) dwc2;
-  // do nothing since bcm alwyas use HS PHY
+  (void) hs_phy_type;
+
+  // nothing to do
+}
+
+// MCU specific PHY update, it is called AFTER init() and core reset
+static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type)
+{
+  (void) dwc2;
+  (void) hs_phy_type;
+
+  // nothing to do
 }
 
 #ifdef __cplusplus

+ 16 - 2
src/portable/synopsys/dwc2/dwc2_esp32.h

@@ -50,12 +50,14 @@ static void dcd_int_handler_wrap(void* arg)
   dcd_int_handler(0);
 }
 
+TU_ATTR_ALWAYS_INLINE
 static inline void dwc2_dcd_int_enable (uint8_t rhport)
 {
   (void) rhport;
   esp_intr_alloc(ETS_USB_INTR_SOURCE, ESP_INTR_FLAG_LOWMED, dcd_int_handler_wrap, NULL, &usb_ih);
 }
 
+TU_ATTR_ALWAYS_INLINE
 static inline void dwc2_dcd_int_disable (uint8_t rhport)
 {
   (void) rhport;
@@ -67,10 +69,22 @@ static inline void dwc2_remote_wakeup_delay(void)
   vTaskDelay(pdMS_TO_TICKS(1));
 }
 
-static inline void dwc2_phyfs_set_turnaround(dwc2_regs_t * dwc2)
+// MCU specific PHY init, called BEFORE core reset
+static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type)
 {
   (void) dwc2;
-  // keep the reset value which is 5 on this port
+  (void) hs_phy_type;
+
+  // nothing to do
+}
+
+// MCU specific PHY update, it is called AFTER init() and core reset
+static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type)
+{
+  (void) dwc2;
+  (void) hs_phy_type;
+
+  // nothing to do
 }
 
 #ifdef __cplusplus

+ 14 - 4
src/portable/synopsys/dwc2/dwc2_gd32.h

@@ -68,7 +68,6 @@ static inline void dwc2_dcd_int_disable (uint8_t rhport)
   __eclic_disable_interrupt(RHPORT_IRQn);
 }
 
-TU_ATTR_ALWAYS_INLINE
 static inline void dwc2_remote_wakeup_delay(void)
 {
   // try to delay for 1 ms
@@ -76,12 +75,23 @@ static inline void dwc2_remote_wakeup_delay(void)
   while ( count-- ) __asm volatile ("nop");
 }
 
-static inline void dwc2_phyfs_set_turnaround(dwc2_regs_t * dwc2)
+// MCU specific PHY init, called BEFORE core reset
+static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type)
 {
-  // use recommeded value 6 by stm32 for mcu with AHB clock > 32Mhz
-  dwc2->gusbcfg = (dwc2->gusbcfg & GUSBCFG_TRDT_Msk) | (6u << GUSBCFG_TRDT_Pos);
+  (void) dwc2;
+  (void) hs_phy_type;
+
+  // nothing to do
 }
 
+// MCU specific PHY update, it is called AFTER init() and core reset
+static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type)
+{
+  (void) dwc2;
+  (void) hs_phy_type;
+
+  // nothing to do
+}
 
 #ifdef __cplusplus
 }

+ 78 - 65
src/portable/synopsys/dwc2/dwc2_stm32.h

@@ -112,79 +112,92 @@ static inline void dwc2_remote_wakeup_delay(void)
   while ( count-- ) __NOP();
 }
 
-// Set turn-around timeout according to link speed
-static inline void dwc2_phyfs_set_turnaround(dwc2_regs_t * dwc2)
+// MCU specific PHY init, called BEFORE core reset
+static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type)
 {
-  // Turnaround timeout depends on the AHB clock dictated by STM32 Reference Manual
-  uint32_t turnaround;
-
-  if ( SystemCoreClock >= 32000000U )
-    turnaround = 0x6u;
-  else if ( SystemCoreClock >= 27500000U )
-    turnaround = 0x7u;
-  else if ( SystemCoreClock >= 24000000U )
-    turnaround = 0x8u;
-  else if ( SystemCoreClock >= 21800000U )
-    turnaround = 0x9u;
-  else if ( SystemCoreClock >= 20000000U )
-    turnaround = 0xAu;
-  else if ( SystemCoreClock >= 18500000U )
-    turnaround = 0xBu;
-  else if ( SystemCoreClock >= 17200000U )
-    turnaround = 0xCu;
-  else if ( SystemCoreClock >= 16000000U )
-    turnaround = 0xDu;
-  else if ( SystemCoreClock >= 15000000U )
-    turnaround = 0xEu;
-  else
-    turnaround = 0xFu;
-
-  dwc2->gusbcfg = (dwc2->gusbcfg & GUSBCFG_TRDT_Msk) | (turnaround << GUSBCFG_TRDT_Pos);
+  if ( hs_phy_type == HS_PHY_TYPE_NONE )
+  {
+    // Enable on-chip FS PHY
+    dwc2->stm32_gccfg |= STM32_GCCFG_PWRDWN;
+  }else
+  {
+    // Disable FS PHY
+    dwc2->stm32_gccfg &= ~STM32_GCCFG_PWRDWN;
+
+    // Enable on-chip HS PHY
+    if (hs_phy_type == HS_PHY_TYPE_UTMI || hs_phy_type == HS_PHY_TYPE_UTMI_ULPI)
+    {
+#ifdef USB_HS_PHYC
+      // Enable UTMI HS PHY
+      dwc2->stm32_gccfg |= STM32_GCCFG_PHYHSEN;
+
+      // Enable LDO
+      USB_HS_PHYC->USB_HS_PHYC_LDO |= USB_HS_PHYC_LDO_ENABLE;
+
+      // Wait until LDO ready
+      while ( 0 == (USB_HS_PHYC->USB_HS_PHYC_LDO & USB_HS_PHYC_LDO_STATUS) ) {}
+
+      uint32_t phyc_pll = 0;
+
+      // TODO Try to get HSE_VALUE from registers instead of depending CFLAGS
+      switch ( HSE_VALUE )
+      {
+        case 12000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_12MHZ   ; break;
+        case 12500000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_12_5MHZ ; break;
+        case 16000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_16MHZ   ; break;
+        case 24000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_24MHZ   ; break;
+        case 25000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_25MHZ   ; break;
+        case 32000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_Msk     ; break; // Value not defined in header
+        default:
+          TU_ASSERT(false, );
+      }
+      USB_HS_PHYC->USB_HS_PHYC_PLL = phyc_pll;
+
+      // Control the tuning interface of the High Speed PHY
+      // Use magic value (USB_HS_PHYC_TUNE_VALUE) from ST driver for F7
+      USB_HS_PHYC->USB_HS_PHYC_TUNE |= 0x00000F13U;
+
+      // Enable PLL internal PHY
+      USB_HS_PHYC->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL_PLLEN;
+#endif
+    }
+  }
 }
 
-#if defined(USB_HS_PHYC)
-static inline void dwc2_stm32_utmi_phy_init(dwc2_regs_t * dwc2)
+// MCU specific PHY update, it is called AFTER init() and core reset
+static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type)
 {
-  USB_HS_PHYC_GlobalTypeDef *usb_hs_phyc = (USB_HS_PHYC_GlobalTypeDef*) USB_HS_PHYC_CONTROLLER_BASE;
-
-  // Enable UTMI HS PHY
-  dwc2->stm32_gccfg |= STM32_GCCFG_PHYHSEN;
-
-  // Enable LDO
-  usb_hs_phyc->USB_HS_PHYC_LDO |= USB_HS_PHYC_LDO_ENABLE;
-
-  // Wait until LDO ready
-  while ( 0 == (usb_hs_phyc->USB_HS_PHYC_LDO & USB_HS_PHYC_LDO_STATUS) ) {}
-
-  uint32_t phyc_pll = 0;
-
-  // TODO Try to get HSE_VALUE from registers instead of depending CFLAGS
-  switch ( HSE_VALUE )
+  // used to set turnaround time for fullspeed, nothing to do in highspeed mode
+  if ( hs_phy_type == HS_PHY_TYPE_NONE )
   {
-    case 12000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_12MHZ   ; break;
-    case 12500000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_12_5MHZ ; break;
-    case 16000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_16MHZ   ; break;
-    case 24000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_24MHZ   ; break;
-    case 25000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_25MHZ   ; break;
-    case 32000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_Msk     ; break; // Value not defined in header
-    default:
-      TU_ASSERT(false, );
+    // Turnaround timeout depends on the AHB clock dictated by STM32 Reference Manual
+    uint32_t turnaround;
+
+    if ( SystemCoreClock >= 32000000u )
+      turnaround = 0x6u;
+    else if ( SystemCoreClock >= 27500000u )
+      turnaround = 0x7u;
+    else if ( SystemCoreClock >= 24000000u )
+      turnaround = 0x8u;
+    else if ( SystemCoreClock >= 21800000u )
+      turnaround = 0x9u;
+    else if ( SystemCoreClock >= 20000000u )
+      turnaround = 0xAu;
+    else if ( SystemCoreClock >= 18500000u )
+      turnaround = 0xBu;
+    else if ( SystemCoreClock >= 17200000u )
+      turnaround = 0xCu;
+    else if ( SystemCoreClock >= 16000000u )
+      turnaround = 0xDu;
+    else if ( SystemCoreClock >= 15000000u )
+      turnaround = 0xEu;
+    else
+      turnaround = 0xFu;
+
+    dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_TRDT_Msk) | (turnaround << GUSBCFG_TRDT_Pos);
   }
-  usb_hs_phyc->USB_HS_PHYC_PLL = phyc_pll;
-
-  // Control the tuning interface of the High Speed PHY
-  // Use magic value (USB_HS_PHYC_TUNE_VALUE) from ST driver
-  usb_hs_phyc->USB_HS_PHYC_TUNE |= 0x00000F13U;
-
-  // Enable PLL internal PHY
-  usb_hs_phyc->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL_PLLEN;
-
-  // Original ST code has 2 ms delay for PLL stabilization.
-  // Primitive test shows that more than 10 USB un/replug cycle showed no error with enumeration
 }
 
-#endif
-
 #ifdef __cplusplus
 }
 #endif

+ 1 - 1
src/portable/synopsys/dwc2/dwc2_type.h

@@ -528,7 +528,7 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo   ) == 0x1000, "incorrect size");
 #define GUSBCFG_PHYSEL_Pos               (6U)
 #define GUSBCFG_PHYSEL_Msk               (0x1UL << GUSBCFG_PHYSEL_Pos)            // 0x00000040 */
 #define GUSBCFG_PHYSEL                   GUSBCFG_PHYSEL_Msk                       // USB 2.0 high-speed ULPI PHY or USB 1.1 full-speed serial transceiver select */
-#define GUSBCFG_DDRSEL                TU_BIT(7)                                // Single Data Rate (SDR) or Double Data Rate (DDR) or ULPI interface.
+#define GUSBCFG_DDRSEL                   TU_BIT(7)                                // Single Data Rate (SDR) or Double Data Rate (DDR) or ULPI interface.
 #define GUSBCFG_SRPCAP_Pos               (8U)
 #define GUSBCFG_SRPCAP_Msk               (0x1UL << GUSBCFG_SRPCAP_Pos)            // 0x00000100 */
 #define GUSBCFG_SRPCAP                   GUSBCFG_SRPCAP_Msk                       // SRP-capable */

+ 0 - 2
src/tusb_option.h

@@ -113,8 +113,6 @@
 
 // Silabs
 #define OPT_MCU_EFM32GG          1300 ///< Silabs EFM32GG
-#define OPT_MCU_EFM32GG11        1301 ///< Silabs EFM32GG11
-#define OPT_MCU_EFM32GG12        1302 ///< Silabs EFM32GG12
 
 // Renesas RX
 #define OPT_MCU_RX63X            1400 ///< Renesas RX63N/631