diff --git a/boards/seeedstudio-gd32/Kconfig b/boards/seeedstudio-gd32/Kconfig index c4272860fe..2443bc512e 100644 --- a/boards/seeedstudio-gd32/Kconfig +++ b/boards/seeedstudio-gd32/Kconfig @@ -13,3 +13,19 @@ config BOARD_SEEEDSTUDIO_GD32 default y select CPU_MODEL_GD32VF103VBT6 select HAS_PERIPH_UART + select BOARD_HAS_HXTAL + select BOARD_HAS_LXTAL + +config BOARD_HAS_HXTAL + bool + help + Indicates that the board is providing an HXTAL oscillator + +config BOARD_HAS_LXTAL + bool + help + Indicates that the board is providing an LXTAL oscillator + +config CLOCK_HXTAL + int + default 80000000 diff --git a/boards/seeedstudio-gd32/include/periph_conf.h b/boards/seeedstudio-gd32/include/periph_conf.h index 72342297e2..53af5b3f0c 100644 --- a/boards/seeedstudio-gd32/include/periph_conf.h +++ b/boards/seeedstudio-gd32/include/periph_conf.h @@ -28,11 +28,14 @@ extern "C" { /* This board provides an high frequency oscillator */ #ifndef CONFIG_BOARD_HAS_HXTAL -#define CONFIG_BOARD_HAS_HXTAL 1 +#define CONFIG_BOARD_HAS_HXTAL 1 #endif -#define CLOCK_HXTAL MHZ(8) /**< HXTAL frequency */ -#define CLOCK_CORECLOCK MHZ(104) /**< CPU clock frequency in Hz */ +#ifndef CONFIG_CLOCK_HXTAL +#define CONFIG_CLOCK_HXTAL MHZ(8) /**< HXTAL frequency */ +#endif + +#define CLOCK_CORECLOCK MHZ(108) /**< CPU clock frequency in Hz */ /** * @name Timer configuration diff --git a/cpu/gd32v/clock.c b/cpu/gd32v/clock.c index d9146d0353..6624ddf377 100644 --- a/cpu/gd32v/clock.c +++ b/cpu/gd32v/clock.c @@ -34,8 +34,12 @@ #define CLOCK_APB2_DIV_CONF (CLOCK_APB2_DIV << RCU_CFG0_APB2PSC_Pos) #define PREDV0_CONF 1 /* Divide by 2 */ +#ifdef CONFIG_BOARD_HAS_HXTAL #define PLL_MULT_FACTOR (CLOCK_CORECLOCK / \ - (CLOCK_HXTAL / (PREDV0_CONF + 1)) - 1) + (CONFIG_CLOCK_HXTAL / (PREDV0_CONF + 1)) - 1) +#else +#define PLL_MULT_FACTOR (CLOCK_CORECLOCK / (MHZ(8) / 2 ) - 1) +#endif #define RCU_CFG0_SCS_IRC8 (0 << RCU_CFG0_SCS_Pos) #define RCU_CFG0_SCS_HXTAL (1 << RCU_CFG0_SCS_Pos) @@ -119,20 +123,25 @@ void gd32vf103_clock_init(void) (RCU_CFG0_SCS_IRC8 << RCU_CFG0_SCSS_Pos)) {} /* disable all active clocks except IRC8 -> resets the clk configuration */ - RCU->CTL = (RCU_CTL_IRC8MEN_Msk); + RCU->CTL &= (RCU_CTL_IRC8MCALIB_Msk | RCU_CTL_IRC8MADJ_Msk); + RCU->CTL |= RCU_CTL_IRC8MEN_Msk; if (IS_ACTIVE(CONFIG_BOARD_HAS_HXTAL)) { + /* if the board has an HXTAL, HXTAL is used as PLL input and PREDEV0 is set */ cpu_reg_enable_bits(&RCU->CTL, RCU_CTL_HXTALEN_Msk); while (!(RCU->CTL & RCU_CTL_HXTALSTB_Msk)) {} + + RCU->CFG1 = PREDV0_CONF; + RCU->CFG0 |= RCU_CFG0_PLLSEL_Msk; } - - RCU->CFG1 = (PREDV0_CONF); - - RCU->CFG0 |= (CLOCK_HXTAL << RCU_CFG0_PLLSEL_Pos) | - ((PLL_MULT_FACTOR & 0xf) << RCU_CFG0_PLLMF_3_0_Pos) | + else { + /* if the board doesn't have HXTAL, IRCM8/2 is used as PLL input */ + RCU->CFG0 &= ~RCU_CFG0_PLLSEL_Msk; + } + RCU->CFG0 |= ((PLL_MULT_FACTOR & 0xf) << RCU_CFG0_PLLMF_3_0_Pos) | ((PLL_MULT_FACTOR & 0x10) << (RCU_CFG0_PLLMF_4_Pos - 4)); - RCU->CTL |= (RCU_CTL_PLLEN_Msk); + RCU->CTL |= RCU_CTL_PLLEN_Msk; /* Wait for PLL to stabilize */ while ((RCU->CTL & RCU_CTL_PLLSTB_Msk) != RCU_CTL_PLLSTB_Msk) {} @@ -144,6 +153,11 @@ void gd32vf103_clock_init(void) while ((RCU->CFG0 & RCU_CFG0_SCSS_Msk) != (RCU_CFG0_SCS_PLL << RCU_CFG0_SCSS_Pos)) {} - gd32v_disable_irc8(); + + if (IS_ACTIVE(CONFIG_BOARD_HAS_HXTAL)) { + /* disable IRCM8 clock if HXTAL is used */ + gd32v_disable_irc8(); + } + irq_restore(is); }