From 861f80e853babd66102bbaad7658b0b4b06393e9 Mon Sep 17 00:00:00 2001 From: Matias Nitsche Date: Sun, 28 Jun 2020 01:09:11 -0300 Subject: [PATCH] stm32l4 RCC: configure flash wait states early, otherwise execution is corrupted when clock is increased before that --- arch/arm/src/stm32l4/stm32l4x6xx_rcc.c | 40 +++++++++++++++++--------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/arch/arm/src/stm32l4/stm32l4x6xx_rcc.c b/arch/arm/src/stm32l4/stm32l4x6xx_rcc.c index 546b720819..6a42d22085 100644 --- a/arch/arm/src/stm32l4/stm32l4x6xx_rcc.c +++ b/arch/arm/src/stm32l4/stm32l4x6xx_rcc.c @@ -682,6 +682,32 @@ static void stm32l4_stdclockconfig(void) uint32_t regval; volatile int32_t timeout; + /* Enable FLASH prefetch, instruction cache, data cache, + * and 4 wait states. We do this early since the default is zero + * wait states and if we are about to increase clock frequency + * bad things will happen. + * + * TODO: could reduce flash wait states according to vcore range + * and freq + */ + +#ifdef CONFIG_STM32L4_FLASH_PREFETCH + regval = (FLASH_ACR_LATENCY_4 | FLASH_ACR_ICEN | FLASH_ACR_DCEN | + FLASH_ACR_PRFTEN); +#else + regval = (FLASH_ACR_LATENCY_4 | FLASH_ACR_ICEN | FLASH_ACR_DCEN); +#endif + putreg32(regval, STM32L4_FLASH_ACR); + + /* Wait until the requested number of wait states is set */ + + while ((getreg32(STM32L4_FLASH_ACR) & FLASH_ACR_LATENCY_MASK) != + FLASH_ACR_LATENCY_4) + { + } + + /* Proceed to clock configuration */ + #if defined(STM32L4_BOARD_USEHSI) || defined(STM32L4_I2C_USE_HSI16) /* Enable Internal High-Speed Clock (HSI) */ @@ -959,20 +985,6 @@ static void stm32l4_stdclockconfig(void) } #endif - /* Enable FLASH prefetch, instruction cache, data cache, - * and 4 wait states. - * TODO: could reduce flash wait states according to vcore range - * and freq - */ - -#ifdef CONFIG_STM32L4_FLASH_PREFETCH - regval = (FLASH_ACR_LATENCY_4 | FLASH_ACR_ICEN | FLASH_ACR_DCEN | - FLASH_ACR_PRFTEN); -#else - regval = (FLASH_ACR_LATENCY_4 | FLASH_ACR_ICEN | FLASH_ACR_DCEN); -#endif - putreg32(regval, STM32L4_FLASH_ACR); - /* Select the system clock source */ regval = getreg32(STM32L4_RCC_CFGR);