From c6e0e7adcbe75080dbb98ff2656db9309b451f20 Mon Sep 17 00:00:00 2001 From: Francisco Molina Date: Mon, 15 Jul 2019 14:34:27 +0200 Subject: [PATCH] cpu/stm32_common: add common L4 and WB stmclk --- .../stmclk.c => stm32_common/stmclk_l4wb.c} | 36 +++- cpu/stm32l4/stmclk.c | 160 ------------------ 2 files changed, 33 insertions(+), 163 deletions(-) rename cpu/{stm32wb/stmclk.c => stm32_common/stmclk_l4wb.c} (86%) delete mode 100644 cpu/stm32l4/stmclk.c diff --git a/cpu/stm32wb/stmclk.c b/cpu/stm32_common/stmclk_l4wb.c similarity index 86% rename from cpu/stm32wb/stmclk.c rename to cpu/stm32_common/stmclk_l4wb.c index c28c121b1a..e543f6c71f 100644 --- a/cpu/stm32wb/stmclk.c +++ b/cpu/stm32_common/stmclk_l4wb.c @@ -9,7 +9,7 @@ */ /** - * @ingroup cpu_stm32wb + * @ingroup cpu_stm32_common * @{ * * @file @@ -27,6 +27,8 @@ #include "stmclk.h" #include "periph_conf.h" +#if defined(CPU_FAM_STM32L4) || defined(CPU_FAM_STM32WB) + /* make sure we have all needed information about the clock configuration */ #ifndef CLOCK_HSE #error "Please provide CLOCK_HSE in your board's perhip_conf.h" @@ -76,18 +78,40 @@ #endif #define PLL_N (CLOCK_PLL_N << RCC_PLLCFGR_PLLN_Pos) +#if defined(CPU_FAM_STM32WB) #if (CLOCK_PLL_R < 1 || CLOCK_PLL_R > 8) #error "PLL configuration: PLL R value is invalid" #else #define PLL_R ((CLOCK_PLL_R - 1)<< RCC_PLLCFGR_PLLR_Pos) #endif +#else +#if (CLOCK_PLL_R == 2) +#define PLL_R (0) +#elif (CLOCK_PLL_R == 4) +#define PLL_R (RCC_PLLCFGR_PLLR_0) +#elif (CLOCK_PLL_R == 6) +#define PLL_R (RCC_PLLCFGR_PLLR_1) +#elif (CLOCK_PLL_R == 8) +#define PLL_R (RCC_PLLCFGR_PLLR_0 | RCC_PLLCFGR_PLLR_1) +#else +#error "PLL configuration: PLL R value is invalid" +#endif +#endif /** @} */ /** * @name Deduct the needed flash wait states from the core clock frequency * @{ */ -#define FLASH_WAITSTATES ((CLOCK_CORECLOCK - 1) / 18000000U) +#if defined(CPU_FAM_STM32WB) +#if (CLOCK_AHB <= 64000000) +#define FLASH_WAITSTATES ((CLOCK_AHB - 1) / 18000000U) +#else +#define FLASH_WAITSTATES FLASH_ACR_LATENCY_3WS +#endif +#else +#define FLASH_WAITSTATES ((CLOCK_AHB - 1) / 16000000U) +#endif /** @} */ @@ -105,9 +129,10 @@ void stmclk_init_sysclk(void) * configure the AHB and APB clock dividers as configure by the board */ RCC->CFGR = (RCC_CFGR_SW_HSI | CLOCK_AHB_DIV | CLOCK_APB1_DIV | CLOCK_APB2_DIV); +#if defined(CPU_FAM_STM32WB) /* Use HSE/2 for radios systems */ RCC->EXTCFGR = (RCC_EXTCFGR_RFCSS | CLOCK_EXTAHB_DIV); - +#endif while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) {} /* we enable I+D cashes, pre-fetch, and we set the actual number of @@ -136,7 +161,11 @@ void stmclk_init_sysclk(void) #if ((CLOCK_HSE == 0) || CLOCK_MSI_ENABLE) /* reset clock to MSI with 48MHz, disables all other clocks */ +#if defined(CPU_FAM_STM32WB) RCC->CR |= (RCC_CR_MSIRANGE_11 | RCC_CR_MSION); +#else + RCC->CR |= (RCC_CR_MSIRANGE_11 | RCC_CR_MSION | RCC_CR_MSIRGSEL); +#endif while (!(RCC->CR & RCC_CR_MSIRDY)) {} /* select the MSI clock for the 48MHz clock tree (USB, RNG) */ RCC->CCIPR = (RCC_CCIPR_CLK48SEL_0 | RCC_CCIPR_CLK48SEL_1); @@ -161,3 +190,4 @@ void stmclk_init_sysclk(void) stmclk_disable_hsi(); irq_restore(is); } +#endif diff --git a/cpu/stm32l4/stmclk.c b/cpu/stm32l4/stmclk.c deleted file mode 100644 index 7af9bf24eb..0000000000 --- a/cpu/stm32l4/stmclk.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (C) 2017 Freie Universität Berlin - * 2017 OTA keys S.A. - * 2017 HAW-Hamburg - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License v2.1. See the file LICENSE in the top level - * directory for more details. - */ - -/** - * @ingroup cpu_stm32l4 - * @{ - * - * @file - * @brief Implementation of STM32 clock configuration - * - * @author Hauke Petersen - * @author Nick van IJzendoorn - * @author Vincent Dupont - * @author Michel Rottleuthner - * @} - */ - -#include "cpu.h" -#include "stmclk.h" -#include "periph_conf.h" - -/* make sure we have all needed information about the clock configuration */ -#ifndef CLOCK_HSE -#error "Please provide CLOCK_HSE in your board's perhip_conf.h" -#endif -#ifndef CLOCK_LSE -#error "Please provide CLOCK_LSE in your board's periph_conf.h" -#endif -#if !defined(CLOCK_PLL_M) || !defined(CLOCK_PLL_N) || !defined(CLOCK_PLL_R) -#error "Please provide the PLL configuration in your board's periph_conf.h" -#endif - -/** - * @name PLL configuration - * @{ - */ -/* figure out which input to use */ -#if (CLOCK_HSE) -#define PLL_IN CLOCK_HSE -#define PLL_SRC RCC_PLLCFGR_PLLSRC_HSE -#else -#define PLL_IN (48000000) /* MSI @ 48MHz */ -#define PLL_SRC RCC_PLLCFGR_PLLSRC_MSI -#endif - -/**check configuration and get the corresponding bitfields */ -#if (CLOCK_PLL_M < 1 || CLOCK_PLL_M > 8) -#error "PLL configuration: PLL M value is out of range" -#endif -#define PLL_M ((CLOCK_PLL_M - 1) << RCC_PLLCFGR_PLLM_Pos) - -#if (CLOCK_PLL_N < 8 || CLOCK_PLL_N > 86) -#error "PLL configuration: PLL N value is out of range" -#endif -#define PLL_N (CLOCK_PLL_N << RCC_PLLCFGR_PLLN_Pos) - -#if (CLOCK_PLL_R == 2) -#define PLL_R (0) -#elif (CLOCK_PLL_R == 4) -#define PLL_R (RCC_PLLCFGR_PLLR_0) -#elif (CLOCK_PLL_R == 6) -#define PLL_R (RCC_PLLCFGR_PLLR_1) -#elif (CLOCK_PLL_R == 8) -#define PLL_R (RCC_PLLCFGR_PLLR_0 | RCC_PLLCFGR_PLLR_1) -#else -#error "PLL configuration: PLL R value is invalid" -#endif -/** @} */ - -/** - * @name Deduct the needed flash wait states from the core clock frequency - * @{ - */ -#if (CLOCK_CORECLOCK <= 16000000) -#define FLASH_WAITSTATES FLASH_ACR_LATENCY_0WS -#elif (CLOCK_CORECLOCK <= 32000000) -#define FLASH_WAITSTATES FLASH_ACR_LATENCY_1WS -#elif (CLOCK_CORECLOCK <= 48000000) -#define FLASH_WAITSTATES FLASH_ACR_LATENCY_2WS -#elif (CLOCK_CORECLOCK <= 64000000) -#define FLASH_WAITSTATES FLASH_ACR_LATENCY_3WS -#else -#define FLASH_WAITSTATES FLASH_ACR_LATENCY_4WS -#endif -/** @} */ - -void stmclk_init_sysclk(void) -{ - /* disable any interrupts. Global interrupts could be enabled if this is - * called from some kind of bootloader... */ - unsigned is = irq_disable(); - RCC->CIER = 0; - - /* enable HSI clock for the duration of initialization */ - stmclk_enable_hsi(); - - /* use HSI as system clock while we do any further configuration and - * configure the AHB and APB clock dividers as configure by the board */ - RCC->CFGR = (RCC_CFGR_SW_HSI | CLOCK_AHB_DIV | - CLOCK_APB1_DIV | CLOCK_APB2_DIV); - while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) {} - - /* we enable I+D cashes, pre-fetch, and we set the actual number of - * needed flash wait states */ - FLASH->ACR = (FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_PRFTEN | - FLASH_WAITSTATES); - - /* disable all active clocks except HSI -> resets the clk configuration - * Note: on STM32L4x5 & STM32L4x6 this disables the following: - PLLSAI2, PLLSAI1, Main PLL (via PLLON), - Clock security system (via CSSON), MSI clock PLL (via MSIPLLEN), - HSE crystal oscillator bypass (via HSEBYP), HSE, - HSI16 automatic start from Stop (via HSIASFS), - HSI16 always enable for peripheral kernels (via HSIKERON). - - Additionally it configures the MSI clock range (MSIRANGE) to - ~100 kHz and the MSI clock to be based on MSISRANGE in RCC_CSR - (instead of MSIRANGE in the RCC_CR) */ - RCC->CR = (RCC_CR_HSION); - -#if (CLOCK_HSE) - /* if configured, we need to enable the HSE clock now */ - RCC->CR |= (RCC_CR_HSEON); - while (!(RCC->CR & RCC_CR_HSERDY)) {} -#endif - -#if ((CLOCK_HSE == 0) || CLOCK_MSI_ENABLE) - /* reset clock to MSI with 48MHz, disables all other clocks */ - RCC->CR |= (RCC_CR_MSIRANGE_11 | RCC_CR_MSION | RCC_CR_MSIRGSEL); - while (!(RCC->CR & RCC_CR_MSIRDY)) {} - /* select the MSI clock for the 48MHz clock tree (USB, RNG) */ - RCC->CCIPR = (RCC_CCIPR_CLK48SEL_0 | RCC_CCIPR_CLK48SEL_1); -#if (CLOCK_MSI_LSE_PLL && CLOCK_LSE) - /* configure the low speed clock domain */ - stmclk_enable_lfclk(); - /* now we can enable the MSI PLL mode to enhance accuracy of the MSI*/ - RCC->CR |= RCC_CR_MSIPLLEN; - while (!(RCC->CR & RCC_CR_MSIRDY)) {} -#endif /* (CLOCK_MSI_LSE_PLL && CLOCK_LSE) */ -#endif /* ((CLOCK_HSE == 0) || CLOCK_MSI_ENABLE) */ - - /* now we can safely configure and start the PLL */ - RCC->PLLCFGR = (PLL_SRC | PLL_M | PLL_N | PLL_R | RCC_PLLCFGR_PLLREN); - RCC->CR |= (RCC_CR_PLLON); - while (!(RCC->CR & RCC_CR_PLLRDY)) {} - - /* now that the PLL is running, we use it as system clock */ - RCC->CFGR |= (RCC_CFGR_SW_PLL); - while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL) {} - - stmclk_disable_hsi(); - irq_restore(is); -}