diff --git a/include/libopencm3/stm32/common/flash_common_f234.h b/include/libopencm3/stm32/common/flash_common_f234.h index 19247c4e..d4bfb054 100644 --- a/include/libopencm3/stm32/common/flash_common_f234.h +++ b/include/libopencm3/stm32/common/flash_common_f234.h @@ -50,7 +50,8 @@ /* --- FLASH_ACR values ---------------------------------------------------- */ -#define FLASH_ACR_LATENCY_MASK 0x07 +#define FLASH_ACR_LATENCY_MASK 0x0f +#define FLASH_ACR_LATENCY(w) ((w) & FLASH_ACR_LATENCY_MASK) #define FLASH_ACR_LATENCY_0WS 0x00 #define FLASH_ACR_LATENCY_1WS 0x01 #define FLASH_ACR_LATENCY_2WS 0x02 diff --git a/include/libopencm3/stm32/f4/pwr.h b/include/libopencm3/stm32/f4/pwr.h index ab608333..63f1015f 100644 --- a/include/libopencm3/stm32/f4/pwr.h +++ b/include/libopencm3/stm32/f4/pwr.h @@ -43,10 +43,11 @@ LGPL License Terms @ref lgpl_license /* --- PWR_CR values ------------------------------------------------------- */ -/* Bits [31:15]: Reserved */ +/* Bits [31:16]: Reserved */ /* VOS: Regulator voltage scaling output selection */ -#define PWR_CR_VOS (1 << 14) +#define PWR_CR_VOS_SHIFT 14 +#define PWR_CR_VOS_MASK 0x3 /* Bits [13:10]: Reserved */ @@ -73,8 +74,9 @@ LGPL License Terms @ref lgpl_license /* --- Function prototypes ------------------------------------------------- */ enum pwr_vos_scale { - PWR_SCALE1, - PWR_SCALE2, + PWR_SCALE1 = 0x3, + PWR_SCALE2 = 0x2, + PWR_SCALE3 = 0x1, }; BEGIN_DECLS diff --git a/include/libopencm3/stm32/f4/rcc.h b/include/libopencm3/stm32/f4/rcc.h index bd058742..0e9a2c8c 100644 --- a/include/libopencm3/stm32/f4/rcc.h +++ b/include/libopencm3/stm32/f4/rcc.h @@ -45,6 +45,8 @@ #ifndef LIBOPENCM3_RCC_H #define LIBOPENCM3_RCC_H +#include + /** @defgroup rcc_registers RCC Registers * @ingroup rcc_defines * @brief Reset / Clock Control Registers @@ -781,7 +783,7 @@ struct rcc_clock_scale { uint8_t hpre; uint8_t ppre1; uint8_t ppre2; - uint8_t power_save; + enum pwr_vos_scale voltage_scale; uint32_t ahb_frequency; uint32_t apb1_frequency; uint32_t apb2_frequency; diff --git a/lib/stm32/common/flash_common_f234.c b/lib/stm32/common/flash_common_f234.c index 1977fbbe..869fbeb5 100644 --- a/lib/stm32/common/flash_common_f234.c +++ b/lib/stm32/common/flash_common_f234.c @@ -39,10 +39,8 @@ speed, or after any decrease in clock speed. void flash_set_ws(uint32_t ws) { uint32_t reg32; - - reg32 = FLASH_ACR; - reg32 &= ~(FLASH_ACR_LATENCY_MASK); - reg32 |= ws; + reg32 = FLASH_ACR & ~(FLASH_ACR_LATENCY_MASK); + reg32 |= ws & FLASH_ACR_LATENCY_MASK; FLASH_ACR = reg32; } @@ -117,4 +115,3 @@ void flash_wait_for_last_operation(void) while ((FLASH_SR & FLASH_SR_BSY) == FLASH_SR_BSY); } /**@}*/ - diff --git a/lib/stm32/f4/pwr.c b/lib/stm32/f4/pwr.c index 499152b1..58d9bd19 100644 --- a/lib/stm32/f4/pwr.c +++ b/lib/stm32/f4/pwr.c @@ -38,9 +38,8 @@ void pwr_set_vos_scale(enum pwr_vos_scale scale) { - if (scale == PWR_SCALE1) { - PWR_CR |= PWR_CR_VOS; - } else if (scale == PWR_SCALE2) { - PWR_CR &= PWR_CR_VOS; - } + uint32_t reg32; + reg32 = PWR_CR & ~(PWR_CR_VOS_MASK << PWR_CR_VOS_SHIFT); + reg32 |= (scale & PWR_CR_VOS_MASK) << PWR_CR_VOS_SHIFT; + PWR_CR = reg32; } diff --git a/lib/stm32/f4/rcc.c b/lib/stm32/f4/rcc.c index be15a80c..5dd775d5 100644 --- a/lib/stm32/f4/rcc.c +++ b/lib/stm32/f4/rcc.c @@ -59,9 +59,9 @@ const struct rcc_clock_scale rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_END] = { .hpre = RCC_CFGR_HPRE_DIV_NONE, .ppre1 = RCC_CFGR_PPRE_DIV_4, .ppre2 = RCC_CFGR_PPRE_DIV_2, - .power_save = 1, + .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | - FLASH_ACR_LATENCY_3WS, + FLASH_ACR_LATENCY_1WS, .ahb_frequency = 48000000, .apb1_frequency = 12000000, .apb2_frequency = 24000000, @@ -75,6 +75,7 @@ const struct rcc_clock_scale rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_END] = { .hpre = RCC_CFGR_HPRE_DIV_NONE, .ppre1 = RCC_CFGR_PPRE_DIV_2, .ppre2 = RCC_CFGR_PPRE_DIV_NONE, + .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_2WS, .ahb_frequency = 84000000, @@ -90,7 +91,7 @@ const struct rcc_clock_scale rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_END] = { .hpre = RCC_CFGR_HPRE_DIV_NONE, .ppre1 = RCC_CFGR_PPRE_DIV_4, .ppre2 = RCC_CFGR_PPRE_DIV_2, - .power_save = 1, + .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_3WS, .ahb_frequency = 120000000, @@ -106,6 +107,7 @@ const struct rcc_clock_scale rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_END] = { .hpre = RCC_CFGR_HPRE_DIV_NONE, .ppre1 = RCC_CFGR_PPRE_DIV_4, .ppre2 = RCC_CFGR_PPRE_DIV_2, + .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_5WS, .ahb_frequency = 168000000, @@ -124,9 +126,9 @@ const struct rcc_clock_scale rcc_hse_12mhz_3v3[RCC_CLOCK_3V3_END] = { .hpre = RCC_CFGR_HPRE_DIV_NONE, .ppre1 = RCC_CFGR_PPRE_DIV_4, .ppre2 = RCC_CFGR_PPRE_DIV_2, - .power_save = 1, + .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | - FLASH_ACR_LATENCY_3WS, + FLASH_ACR_LATENCY_1WS, .ahb_frequency = 48000000, .apb1_frequency = 12000000, .apb2_frequency = 24000000, @@ -140,6 +142,7 @@ const struct rcc_clock_scale rcc_hse_12mhz_3v3[RCC_CLOCK_3V3_END] = { .hpre = RCC_CFGR_HPRE_DIV_NONE, .ppre1 = RCC_CFGR_PPRE_DIV_2, .ppre2 = RCC_CFGR_PPRE_DIV_NONE, + .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_2WS, .ahb_frequency = 84000000, @@ -155,7 +158,7 @@ const struct rcc_clock_scale rcc_hse_12mhz_3v3[RCC_CLOCK_3V3_END] = { .hpre = RCC_CFGR_HPRE_DIV_NONE, .ppre1 = RCC_CFGR_PPRE_DIV_4, .ppre2 = RCC_CFGR_PPRE_DIV_2, - .power_save = 1, + .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_3WS, .ahb_frequency = 120000000, @@ -171,6 +174,7 @@ const struct rcc_clock_scale rcc_hse_12mhz_3v3[RCC_CLOCK_3V3_END] = { .hpre = RCC_CFGR_HPRE_DIV_NONE, .ppre1 = RCC_CFGR_PPRE_DIV_4, .ppre2 = RCC_CFGR_PPRE_DIV_2, + .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_5WS, .ahb_frequency = 168000000, @@ -189,9 +193,9 @@ const struct rcc_clock_scale rcc_hse_16mhz_3v3[RCC_CLOCK_3V3_END] = { .hpre = RCC_CFGR_HPRE_DIV_NONE, .ppre1 = RCC_CFGR_PPRE_DIV_4, .ppre2 = RCC_CFGR_PPRE_DIV_2, - .power_save = 1, + .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | - FLASH_ACR_LATENCY_3WS, + FLASH_ACR_LATENCY_1WS, .ahb_frequency = 48000000, .apb1_frequency = 12000000, .apb2_frequency = 24000000, @@ -205,6 +209,7 @@ const struct rcc_clock_scale rcc_hse_16mhz_3v3[RCC_CLOCK_3V3_END] = { .hpre = RCC_CFGR_HPRE_DIV_NONE, .ppre1 = RCC_CFGR_PPRE_DIV_2, .ppre2 = RCC_CFGR_PPRE_DIV_NONE, + .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_2WS, .ahb_frequency = 84000000, @@ -220,7 +225,7 @@ const struct rcc_clock_scale rcc_hse_16mhz_3v3[RCC_CLOCK_3V3_END] = { .hpre = RCC_CFGR_HPRE_DIV_NONE, .ppre1 = RCC_CFGR_PPRE_DIV_4, .ppre2 = RCC_CFGR_PPRE_DIV_2, - .power_save = 1, + .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_3WS, .ahb_frequency = 120000000, @@ -236,6 +241,7 @@ const struct rcc_clock_scale rcc_hse_16mhz_3v3[RCC_CLOCK_3V3_END] = { .hpre = RCC_CFGR_HPRE_DIV_NONE, .ppre1 = RCC_CFGR_PPRE_DIV_4, .ppre2 = RCC_CFGR_PPRE_DIV_2, + .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_5WS, .ahb_frequency = 168000000, @@ -254,9 +260,9 @@ const struct rcc_clock_scale rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_END] = { .hpre = RCC_CFGR_HPRE_DIV_NONE, .ppre1 = RCC_CFGR_PPRE_DIV_4, .ppre2 = RCC_CFGR_PPRE_DIV_2, - .power_save = 1, + .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | - FLASH_ACR_LATENCY_3WS, + FLASH_ACR_LATENCY_1WS, .ahb_frequency = 48000000, .apb1_frequency = 12000000, .apb2_frequency = 24000000, @@ -270,6 +276,7 @@ const struct rcc_clock_scale rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_END] = { .hpre = RCC_CFGR_HPRE_DIV_NONE, .ppre1 = RCC_CFGR_PPRE_DIV_2, .ppre2 = RCC_CFGR_PPRE_DIV_NONE, + .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_2WS, .ahb_frequency = 84000000, @@ -285,7 +292,7 @@ const struct rcc_clock_scale rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_END] = { .hpre = RCC_CFGR_HPRE_DIV_NONE, .ppre1 = RCC_CFGR_PPRE_DIV_4, .ppre2 = RCC_CFGR_PPRE_DIV_2, - .power_save = 1, + .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_3WS, .ahb_frequency = 120000000, @@ -301,6 +308,7 @@ const struct rcc_clock_scale rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_END] = { .hpre = RCC_CFGR_HPRE_DIV_NONE, .ppre1 = RCC_CFGR_PPRE_DIV_4, .ppre2 = RCC_CFGR_PPRE_DIV_2, + .voltage_scale = PWR_SCALE1, .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_LATENCY_5WS, .ahb_frequency = 168000000, @@ -678,23 +686,20 @@ uint32_t rcc_system_clock_source(void) void rcc_clock_setup_hse_3v3(const struct rcc_clock_scale *clock) { - /* Enable internal high-speed oscillator. */ + /* Enable internal high-speed oscillator (HSI). */ rcc_osc_on(RCC_HSI); rcc_wait_for_osc_ready(RCC_HSI); /* Select HSI as SYSCLK source. */ rcc_set_sysclk_source(RCC_CFGR_SW_HSI); - /* Enable external high-speed oscillator 8MHz. */ + /* Enable external high-speed oscillator (HSE). */ rcc_osc_on(RCC_HSE); rcc_wait_for_osc_ready(RCC_HSE); - /* Enable/disable high performance mode */ - if (!clock->power_save) { - pwr_set_vos_scale(PWR_SCALE1); - } else { - pwr_set_vos_scale(PWR_SCALE2); - } + /* Set the VOS scale mode */ + rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_PWR); + pwr_set_vos_scale(clock->voltage_scale); /* * Set prescalers for AHB, ADC, ABP1, ABP2. @@ -712,6 +717,16 @@ void rcc_clock_setup_hse_3v3(const struct rcc_clock_scale *clock) rcc_wait_for_osc_ready(RCC_PLL); /* Configure flash settings. */ + if (clock->flash_config & FLASH_ACR_DCEN) { + flash_dcache_enable(); + } else { + flash_dcache_disable(); + } + if (clock->flash_config & FLASH_ACR_ICEN) { + flash_icache_enable(); + } else { + flash_icache_disable(); + } flash_set_ws(clock->flash_config); /* Select PLL as SYSCLK source. */