stm32f4: power: update rcc_clock_scale enum

- Change .power_save to .voltage_scale, a pwr_vos_scale enum
- Enable pwr clock before setting VOS scale
- Fix flash wait states
- Make flash_set_ws more robust
This commit is contained in:
Jordi Pakey-Rodriguez 2018-07-07 00:20:58 -07:00 committed by Karl Palsson
parent e076c3cadd
commit cc8c8a2f83
6 changed files with 52 additions and 36 deletions

View File

@ -50,7 +50,8 @@
/* --- FLASH_ACR values ---------------------------------------------------- */ /* --- 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_0WS 0x00
#define FLASH_ACR_LATENCY_1WS 0x01 #define FLASH_ACR_LATENCY_1WS 0x01
#define FLASH_ACR_LATENCY_2WS 0x02 #define FLASH_ACR_LATENCY_2WS 0x02

View File

@ -43,10 +43,11 @@ LGPL License Terms @ref lgpl_license
/* --- PWR_CR values ------------------------------------------------------- */ /* --- PWR_CR values ------------------------------------------------------- */
/* Bits [31:15]: Reserved */ /* Bits [31:16]: Reserved */
/* VOS: Regulator voltage scaling output selection */ /* 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 */ /* Bits [13:10]: Reserved */
@ -73,8 +74,9 @@ LGPL License Terms @ref lgpl_license
/* --- Function prototypes ------------------------------------------------- */ /* --- Function prototypes ------------------------------------------------- */
enum pwr_vos_scale { enum pwr_vos_scale {
PWR_SCALE1, PWR_SCALE1 = 0x3,
PWR_SCALE2, PWR_SCALE2 = 0x2,
PWR_SCALE3 = 0x1,
}; };
BEGIN_DECLS BEGIN_DECLS

View File

@ -45,6 +45,8 @@
#ifndef LIBOPENCM3_RCC_H #ifndef LIBOPENCM3_RCC_H
#define LIBOPENCM3_RCC_H #define LIBOPENCM3_RCC_H
#include <libopencm3/stm32/pwr.h>
/** @defgroup rcc_registers RCC Registers /** @defgroup rcc_registers RCC Registers
* @ingroup rcc_defines * @ingroup rcc_defines
* @brief Reset / Clock Control Registers * @brief Reset / Clock Control Registers
@ -781,7 +783,7 @@ struct rcc_clock_scale {
uint8_t hpre; uint8_t hpre;
uint8_t ppre1; uint8_t ppre1;
uint8_t ppre2; uint8_t ppre2;
uint8_t power_save; enum pwr_vos_scale voltage_scale;
uint32_t ahb_frequency; uint32_t ahb_frequency;
uint32_t apb1_frequency; uint32_t apb1_frequency;
uint32_t apb2_frequency; uint32_t apb2_frequency;

View File

@ -39,10 +39,8 @@ speed, or <b>after</b> any decrease in clock speed.
void flash_set_ws(uint32_t ws) void flash_set_ws(uint32_t ws)
{ {
uint32_t reg32; uint32_t reg32;
reg32 = FLASH_ACR & ~(FLASH_ACR_LATENCY_MASK);
reg32 = FLASH_ACR; reg32 |= ws & FLASH_ACR_LATENCY_MASK;
reg32 &= ~(FLASH_ACR_LATENCY_MASK);
reg32 |= ws;
FLASH_ACR = reg32; FLASH_ACR = reg32;
} }
@ -117,4 +115,3 @@ void flash_wait_for_last_operation(void)
while ((FLASH_SR & FLASH_SR_BSY) == FLASH_SR_BSY); while ((FLASH_SR & FLASH_SR_BSY) == FLASH_SR_BSY);
} }
/**@}*/ /**@}*/

View File

@ -38,9 +38,8 @@
void pwr_set_vos_scale(enum pwr_vos_scale scale) void pwr_set_vos_scale(enum pwr_vos_scale scale)
{ {
if (scale == PWR_SCALE1) { uint32_t reg32;
PWR_CR |= PWR_CR_VOS; reg32 = PWR_CR & ~(PWR_CR_VOS_MASK << PWR_CR_VOS_SHIFT);
} else if (scale == PWR_SCALE2) { reg32 |= (scale & PWR_CR_VOS_MASK) << PWR_CR_VOS_SHIFT;
PWR_CR &= PWR_CR_VOS; PWR_CR = reg32;
}
} }

View File

@ -59,9 +59,9 @@ const struct rcc_clock_scale rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_END] = {
.hpre = RCC_CFGR_HPRE_DIV_NONE, .hpre = RCC_CFGR_HPRE_DIV_NONE,
.ppre1 = RCC_CFGR_PPRE_DIV_4, .ppre1 = RCC_CFGR_PPRE_DIV_4,
.ppre2 = RCC_CFGR_PPRE_DIV_2, .ppre2 = RCC_CFGR_PPRE_DIV_2,
.power_save = 1, .voltage_scale = PWR_SCALE1,
.flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
FLASH_ACR_LATENCY_3WS, FLASH_ACR_LATENCY_1WS,
.ahb_frequency = 48000000, .ahb_frequency = 48000000,
.apb1_frequency = 12000000, .apb1_frequency = 12000000,
.apb2_frequency = 24000000, .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, .hpre = RCC_CFGR_HPRE_DIV_NONE,
.ppre1 = RCC_CFGR_PPRE_DIV_2, .ppre1 = RCC_CFGR_PPRE_DIV_2,
.ppre2 = RCC_CFGR_PPRE_DIV_NONE, .ppre2 = RCC_CFGR_PPRE_DIV_NONE,
.voltage_scale = PWR_SCALE1,
.flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
FLASH_ACR_LATENCY_2WS, FLASH_ACR_LATENCY_2WS,
.ahb_frequency = 84000000, .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, .hpre = RCC_CFGR_HPRE_DIV_NONE,
.ppre1 = RCC_CFGR_PPRE_DIV_4, .ppre1 = RCC_CFGR_PPRE_DIV_4,
.ppre2 = RCC_CFGR_PPRE_DIV_2, .ppre2 = RCC_CFGR_PPRE_DIV_2,
.power_save = 1, .voltage_scale = PWR_SCALE1,
.flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
FLASH_ACR_LATENCY_3WS, FLASH_ACR_LATENCY_3WS,
.ahb_frequency = 120000000, .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, .hpre = RCC_CFGR_HPRE_DIV_NONE,
.ppre1 = RCC_CFGR_PPRE_DIV_4, .ppre1 = RCC_CFGR_PPRE_DIV_4,
.ppre2 = RCC_CFGR_PPRE_DIV_2, .ppre2 = RCC_CFGR_PPRE_DIV_2,
.voltage_scale = PWR_SCALE1,
.flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
FLASH_ACR_LATENCY_5WS, FLASH_ACR_LATENCY_5WS,
.ahb_frequency = 168000000, .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, .hpre = RCC_CFGR_HPRE_DIV_NONE,
.ppre1 = RCC_CFGR_PPRE_DIV_4, .ppre1 = RCC_CFGR_PPRE_DIV_4,
.ppre2 = RCC_CFGR_PPRE_DIV_2, .ppre2 = RCC_CFGR_PPRE_DIV_2,
.power_save = 1, .voltage_scale = PWR_SCALE1,
.flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
FLASH_ACR_LATENCY_3WS, FLASH_ACR_LATENCY_1WS,
.ahb_frequency = 48000000, .ahb_frequency = 48000000,
.apb1_frequency = 12000000, .apb1_frequency = 12000000,
.apb2_frequency = 24000000, .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, .hpre = RCC_CFGR_HPRE_DIV_NONE,
.ppre1 = RCC_CFGR_PPRE_DIV_2, .ppre1 = RCC_CFGR_PPRE_DIV_2,
.ppre2 = RCC_CFGR_PPRE_DIV_NONE, .ppre2 = RCC_CFGR_PPRE_DIV_NONE,
.voltage_scale = PWR_SCALE1,
.flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
FLASH_ACR_LATENCY_2WS, FLASH_ACR_LATENCY_2WS,
.ahb_frequency = 84000000, .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, .hpre = RCC_CFGR_HPRE_DIV_NONE,
.ppre1 = RCC_CFGR_PPRE_DIV_4, .ppre1 = RCC_CFGR_PPRE_DIV_4,
.ppre2 = RCC_CFGR_PPRE_DIV_2, .ppre2 = RCC_CFGR_PPRE_DIV_2,
.power_save = 1, .voltage_scale = PWR_SCALE1,
.flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
FLASH_ACR_LATENCY_3WS, FLASH_ACR_LATENCY_3WS,
.ahb_frequency = 120000000, .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, .hpre = RCC_CFGR_HPRE_DIV_NONE,
.ppre1 = RCC_CFGR_PPRE_DIV_4, .ppre1 = RCC_CFGR_PPRE_DIV_4,
.ppre2 = RCC_CFGR_PPRE_DIV_2, .ppre2 = RCC_CFGR_PPRE_DIV_2,
.voltage_scale = PWR_SCALE1,
.flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
FLASH_ACR_LATENCY_5WS, FLASH_ACR_LATENCY_5WS,
.ahb_frequency = 168000000, .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, .hpre = RCC_CFGR_HPRE_DIV_NONE,
.ppre1 = RCC_CFGR_PPRE_DIV_4, .ppre1 = RCC_CFGR_PPRE_DIV_4,
.ppre2 = RCC_CFGR_PPRE_DIV_2, .ppre2 = RCC_CFGR_PPRE_DIV_2,
.power_save = 1, .voltage_scale = PWR_SCALE1,
.flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
FLASH_ACR_LATENCY_3WS, FLASH_ACR_LATENCY_1WS,
.ahb_frequency = 48000000, .ahb_frequency = 48000000,
.apb1_frequency = 12000000, .apb1_frequency = 12000000,
.apb2_frequency = 24000000, .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, .hpre = RCC_CFGR_HPRE_DIV_NONE,
.ppre1 = RCC_CFGR_PPRE_DIV_2, .ppre1 = RCC_CFGR_PPRE_DIV_2,
.ppre2 = RCC_CFGR_PPRE_DIV_NONE, .ppre2 = RCC_CFGR_PPRE_DIV_NONE,
.voltage_scale = PWR_SCALE1,
.flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
FLASH_ACR_LATENCY_2WS, FLASH_ACR_LATENCY_2WS,
.ahb_frequency = 84000000, .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, .hpre = RCC_CFGR_HPRE_DIV_NONE,
.ppre1 = RCC_CFGR_PPRE_DIV_4, .ppre1 = RCC_CFGR_PPRE_DIV_4,
.ppre2 = RCC_CFGR_PPRE_DIV_2, .ppre2 = RCC_CFGR_PPRE_DIV_2,
.power_save = 1, .voltage_scale = PWR_SCALE1,
.flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
FLASH_ACR_LATENCY_3WS, FLASH_ACR_LATENCY_3WS,
.ahb_frequency = 120000000, .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, .hpre = RCC_CFGR_HPRE_DIV_NONE,
.ppre1 = RCC_CFGR_PPRE_DIV_4, .ppre1 = RCC_CFGR_PPRE_DIV_4,
.ppre2 = RCC_CFGR_PPRE_DIV_2, .ppre2 = RCC_CFGR_PPRE_DIV_2,
.voltage_scale = PWR_SCALE1,
.flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
FLASH_ACR_LATENCY_5WS, FLASH_ACR_LATENCY_5WS,
.ahb_frequency = 168000000, .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, .hpre = RCC_CFGR_HPRE_DIV_NONE,
.ppre1 = RCC_CFGR_PPRE_DIV_4, .ppre1 = RCC_CFGR_PPRE_DIV_4,
.ppre2 = RCC_CFGR_PPRE_DIV_2, .ppre2 = RCC_CFGR_PPRE_DIV_2,
.power_save = 1, .voltage_scale = PWR_SCALE1,
.flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
FLASH_ACR_LATENCY_3WS, FLASH_ACR_LATENCY_1WS,
.ahb_frequency = 48000000, .ahb_frequency = 48000000,
.apb1_frequency = 12000000, .apb1_frequency = 12000000,
.apb2_frequency = 24000000, .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, .hpre = RCC_CFGR_HPRE_DIV_NONE,
.ppre1 = RCC_CFGR_PPRE_DIV_2, .ppre1 = RCC_CFGR_PPRE_DIV_2,
.ppre2 = RCC_CFGR_PPRE_DIV_NONE, .ppre2 = RCC_CFGR_PPRE_DIV_NONE,
.voltage_scale = PWR_SCALE1,
.flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
FLASH_ACR_LATENCY_2WS, FLASH_ACR_LATENCY_2WS,
.ahb_frequency = 84000000, .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, .hpre = RCC_CFGR_HPRE_DIV_NONE,
.ppre1 = RCC_CFGR_PPRE_DIV_4, .ppre1 = RCC_CFGR_PPRE_DIV_4,
.ppre2 = RCC_CFGR_PPRE_DIV_2, .ppre2 = RCC_CFGR_PPRE_DIV_2,
.power_save = 1, .voltage_scale = PWR_SCALE1,
.flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
FLASH_ACR_LATENCY_3WS, FLASH_ACR_LATENCY_3WS,
.ahb_frequency = 120000000, .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, .hpre = RCC_CFGR_HPRE_DIV_NONE,
.ppre1 = RCC_CFGR_PPRE_DIV_4, .ppre1 = RCC_CFGR_PPRE_DIV_4,
.ppre2 = RCC_CFGR_PPRE_DIV_2, .ppre2 = RCC_CFGR_PPRE_DIV_2,
.voltage_scale = PWR_SCALE1,
.flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN | .flash_config = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
FLASH_ACR_LATENCY_5WS, FLASH_ACR_LATENCY_5WS,
.ahb_frequency = 168000000, .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) 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_osc_on(RCC_HSI);
rcc_wait_for_osc_ready(RCC_HSI); rcc_wait_for_osc_ready(RCC_HSI);
/* Select HSI as SYSCLK source. */ /* Select HSI as SYSCLK source. */
rcc_set_sysclk_source(RCC_CFGR_SW_HSI); 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_osc_on(RCC_HSE);
rcc_wait_for_osc_ready(RCC_HSE); rcc_wait_for_osc_ready(RCC_HSE);
/* Enable/disable high performance mode */ /* Set the VOS scale mode */
if (!clock->power_save) { rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_PWR);
pwr_set_vos_scale(PWR_SCALE1); pwr_set_vos_scale(clock->voltage_scale);
} else {
pwr_set_vos_scale(PWR_SCALE2);
}
/* /*
* Set prescalers for AHB, ADC, ABP1, ABP2. * 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); rcc_wait_for_osc_ready(RCC_PLL);
/* Configure flash settings. */ /* 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); flash_set_ws(clock->flash_config);
/* Select PLL as SYSCLK source. */ /* Select PLL as SYSCLK source. */