Skip to content

Commit

Permalink
Merge #19109
Browse files Browse the repository at this point in the history
19109: cpu/gd32v: fix and extend Kconfig clock settings r=benpicco a=gschorcht

### Contribution description

This PR fixes the following issus of the clock configuration which led to highly deviating peripheral clocks so that the UART interface was not usable in my case:

1. 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.
2. `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.
3. `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.

Issues 1 and 2 led to the problem that IRC8M was used without calibration instead of HXTAL. With the fixes, the GD32V is working with as well as without HXTAL correctly.

Furthermore, the Kconfig configuration has been extended. It is now possible to configure the HXTAL frequency as well, since the GD32VF103 allows HXTAL clocks from 3 MHz to 25 MHz. This has currently been added directly to the board's Kconfig, as it is currently the only GD32VF103 board. It should be moved to a common Kconfig later when more GD32V boards are added.

### Testing procedure

`BOARD=seeedstudio-gd32 make -C tests/shell flash term` should still work.

### Issues/PRs references


Co-authored-by: Gunar Schorcht <[email protected]>
  • Loading branch information
bors[bot] and gschorcht authored Jan 9, 2023
2 parents 58d5847 + 72d11d8 commit bb708e2
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 12 deletions.
16 changes: 16 additions & 0 deletions boards/seeedstudio-gd32/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
9 changes: 6 additions & 3 deletions boards/seeedstudio-gd32/include/periph_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
32 changes: 23 additions & 9 deletions cpu/gd32v/clock.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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 |= (CLOCK_HXTAL << RCU_CFG0_PLLSEL_Pos) |
((PLL_MULT_FACTOR & 0xf) << RCU_CFG0_PLLMF_3_0_Pos) |
RCU->CFG1 = PREDV0_CONF;
RCU->CFG0 |= RCU_CFG0_PLLSEL_Msk;
}
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) {}
Expand All @@ -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);
}

0 comments on commit bb708e2

Please sign in to comment.