From dd0593a3c87ca794b23ea549447357a481d2ad72 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Sun, 8 Jan 2023 10:38:36 +0100 Subject: [PATCH 1/4] cpu/gd32v: fix clock setting Setting the `RCU_CTL` register just to the IRC8M bit also removes the IRC8M calibration and trim adjust value in this register. Therefore IRC8M calibration and trim adjust value have to be preserved and the IRC8M has to be set. --- boards/seeedstudio-gd32/include/periph_conf.h | 2 +- cpu/gd32v/clock.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/boards/seeedstudio-gd32/include/periph_conf.h b/boards/seeedstudio-gd32/include/periph_conf.h index 72342297e2..7e81b68ebb 100644 --- a/boards/seeedstudio-gd32/include/periph_conf.h +++ b/boards/seeedstudio-gd32/include/periph_conf.h @@ -32,7 +32,7 @@ extern "C" { #endif #define CLOCK_HXTAL MHZ(8) /**< HXTAL frequency */ -#define CLOCK_CORECLOCK MHZ(104) /**< CPU clock frequency in Hz */ +#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..ca0d5d0a7e 100644 --- a/cpu/gd32v/clock.c +++ b/cpu/gd32v/clock.c @@ -119,7 +119,8 @@ 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)) { cpu_reg_enable_bits(&RCU->CTL, RCU_CTL_HXTALEN_Msk); From e4010f7445790b3e3954a831bf472b29bdf02b4b Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Sun, 8 Jan 2023 09:41:15 +0100 Subject: [PATCH 2/4] cpu/gd32v: fix clock setting `CLOCK_HXTAL` is a value and not a flag, so that shifting to the left changes anything in the register but does not set the PLLSEL bit. `RCU_CFG0_PLLSEL_Msk` has to be used instead to set the PLLSEL bit. --- cpu/gd32v/clock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu/gd32v/clock.c b/cpu/gd32v/clock.c index ca0d5d0a7e..e269cc3b20 100644 --- a/cpu/gd32v/clock.c +++ b/cpu/gd32v/clock.c @@ -129,7 +129,7 @@ void gd32vf103_clock_init(void) RCU->CFG1 = (PREDV0_CONF); - RCU->CFG0 |= (CLOCK_HXTAL << RCU_CFG0_PLLSEL_Pos) | + RCU->CFG0 |= RCU_CFG0_PLLSEL_Msk | ((PLL_MULT_FACTOR & 0xf) << RCU_CFG0_PLLMF_3_0_Pos) | ((PLL_MULT_FACTOR & 0x10) << (RCU_CFG0_PLLMF_4_Pos - 4)); From f4d6b2d6421d125f32a73f18a7039a0d4a59862d Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Sun, 8 Jan 2023 09:54:13 +0100 Subject: [PATCH 3/4] cpu/gd32v: fix clock setting `CONFIG_BOARD_HAS_HXTAL` is used to indicate that the board has an HXTAL connected. If the HXTAL is present, it is used as PLL clock source. But if the HXTAL is not present, the half IRC8M clock should be used as PLL clock source and must not be disabled at the end of clock settings. Using IRC8M clock as PLL clock source also requires another PLL multiplication factor. --- cpu/gd32v/clock.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/cpu/gd32v/clock.c b/cpu/gd32v/clock.c index e269cc3b20..4dcec95935 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) +#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) @@ -123,17 +127,21 @@ void gd32vf103_clock_init(void) 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 |= RCU_CFG0_PLLSEL_Msk | - ((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) {} @@ -145,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); } From 72d11d84b82bbd7fc2cf74d941d3557bcee0b85a Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Mon, 9 Jan 2023 21:51:28 +0100 Subject: [PATCH 4/4] boards/seeedstudio-gd32: extend Kconfig by clock configuration The configuration whether a HXTAL is present and what its clock frequency is will be added to Kconfig. Since it is the only GD32V board at the moment, the configuration is added to the Kconfig of the board, but should be moved to a common Kconfig later when more GD32V boards are added. --- boards/seeedstudio-gd32/Kconfig | 16 ++++++++++++++++ boards/seeedstudio-gd32/include/periph_conf.h | 9 ++++++--- cpu/gd32v/clock.c | 2 +- 3 files changed, 23 insertions(+), 4 deletions(-) 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 7e81b68ebb..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(108) /**< 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 4dcec95935..6624ddf377 100644 --- a/cpu/gd32v/clock.c +++ b/cpu/gd32v/clock.c @@ -36,7 +36,7 @@ #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