mirror of
https://github.com/hathach/tinyusb.git
synced 2025-03-14 04:18:56 +00:00
add support for EFM32GG
merge GG12 GG12 to simply OPT_MCU_EFM32GG
This commit is contained in:
parent
660e8b8c88
commit
9cd5a87c64
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 \
|
||||
|
@ -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 -------------//
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
// Clear all interrupts
|
||||
dwc2->gintsts |= dwc2->gintsts;
|
||||
|
||||
// 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;
|
||||
// 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 | 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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -112,78 +112,91 @@ 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 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;
|
||||
|
||||
// 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 )
|
||||
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, );
|
||||
// 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
|
||||
}
|
||||
}
|
||||
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
|
||||
// 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;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user