summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorhathach <[email protected]>2021-10-30 20:42:55 +0700
committerhathach <[email protected]>2021-10-30 20:42:55 +0700
commit9cd5a87c64425b8a7427531735f06f255117aeeb (patch)
treebb2a05f9c40cf30f6321e23a78f87abbba00c193 /src
parent660e8b8c887091e17323c361f25e804a5d06d6df (diff)
add support for EFM32GG
merge GG12 GG12 to simply OPT_MCU_EFM32GG
Diffstat (limited to 'src')
-rw-r--r--src/device/dcd_attr.h2
-rw-r--r--src/host/hcd_attr.h2
-rw-r--r--src/portable/synopsys/dwc2/dcd_dwc2.c90
-rw-r--r--src/portable/synopsys/dwc2/dwc2_bcm.h17
-rw-r--r--src/portable/synopsys/dwc2/dwc2_esp32.h18
-rw-r--r--src/portable/synopsys/dwc2/dwc2_gd32.h18
-rw-r--r--src/portable/synopsys/dwc2/dwc2_stm32.h131
-rw-r--r--src/portable/synopsys/dwc2/dwc2_type.h2
-rw-r--r--src/tusb_option.h2
9 files changed, 173 insertions, 109 deletions
diff --git a/src/device/dcd_attr.h b/src/device/dcd_attr.h
index 90f3a526a..70854f9c6 100644
--- a/src/device/dcd_attr.h
+++ b/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 -------------//
diff --git a/src/host/hcd_attr.h b/src/host/hcd_attr.h
index a9bc242d7..06011c63c 100644
--- a/src/host/hcd_attr.h
+++ b/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)
diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c
index aad7e45cc..16780cba8 100644
--- a/src/portable/synopsys/dwc2/dcd_dwc2.c
+++ b/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.
diff --git a/src/portable/synopsys/dwc2/dwc2_bcm.h b/src/portable/synopsys/dwc2/dwc2_bcm.h
index c064946cf..38d10930c 100644
--- a/src/portable/synopsys/dwc2/dwc2_bcm.h
+++ b/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
diff --git a/src/portable/synopsys/dwc2/dwc2_esp32.h b/src/portable/synopsys/dwc2/dwc2_esp32.h
index af5d5f093..78da277d5 100644
--- a/src/portable/synopsys/dwc2/dwc2_esp32.h
+++ b/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
diff --git a/src/portable/synopsys/dwc2/dwc2_gd32.h b/src/portable/synopsys/dwc2/dwc2_gd32.h
index 15e73ad1e..f8fa01ee0 100644
--- a/src/portable/synopsys/dwc2/dwc2_gd32.h
+++ b/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
}
diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h
index 4d0ed3f0a..469045ac4 100644
--- a/src/portable/synopsys/dwc2/dwc2_stm32.h
+++ b/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 ( 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;
- 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;
+ // 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;
- dwc2->gusbcfg = (dwc2->gusbcfg & GUSBCFG_TRDT_Msk) | (turnaround << GUSBCFG_TRDT_Pos);
-}
+ // Enable LDO
+ USB_HS_PHYC->USB_HS_PHYC_LDO |= USB_HS_PHYC_LDO_ENABLE;
-#if defined(USB_HS_PHYC)
-static inline void dwc2_stm32_utmi_phy_init(dwc2_regs_t * dwc2)
-{
- USB_HS_PHYC_GlobalTypeDef *usb_hs_phyc = (USB_HS_PHYC_GlobalTypeDef*) USB_HS_PHYC_CONTROLLER_BASE;
+ // Wait until LDO ready
+ while ( 0 == (USB_HS_PHYC->USB_HS_PHYC_LDO & USB_HS_PHYC_LDO_STATUS) ) {}
- // Enable UTMI HS PHY
- dwc2->stm32_gccfg |= STM32_GCCFG_PHYHSEN;
+ uint32_t phyc_pll = 0;
- // Enable LDO
- usb_hs_phyc->USB_HS_PHYC_LDO |= USB_HS_PHYC_LDO_ENABLE;
+ // 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;
- // Wait until LDO ready
- while ( 0 == (usb_hs_phyc->USB_HS_PHYC_LDO & USB_HS_PHYC_LDO_STATUS) ) {}
+ // 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;
- 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, );
+ // Enable PLL internal PHY
+ USB_HS_PHYC->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL_PLLEN;
+#endif
+ }
}
- 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;
+// 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)
+{
+ // used to set turnaround time for fullspeed, nothing to do in highspeed mode
+ if ( hs_phy_type == HS_PHY_TYPE_NONE )
+ {
+ // Turnaround timeout depends on the AHB clock dictated by STM32 Reference Manual
+ uint32_t turnaround;
- // Enable PLL internal PHY
- usb_hs_phyc->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL_PLLEN;
+ 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;
- // 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
+ dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_TRDT_Msk) | (turnaround << GUSBCFG_TRDT_Pos);
+ }
}
-#endif
-
#ifdef __cplusplus
}
#endif
diff --git a/src/portable/synopsys/dwc2/dwc2_type.h b/src/portable/synopsys/dwc2/dwc2_type.h
index 7b3db4dd9..583a7274a 100644
--- a/src/portable/synopsys/dwc2/dwc2_type.h
+++ b/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 */
diff --git a/src/tusb_option.h b/src/tusb_option.h
index de0279dda..4da07e241 100644
--- a/src/tusb_option.h
+++ b/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