add 16MHz resonator for stm32f4

This commit is contained in:
Gautier Hattenberger 2013-04-09 10:38:21 +02:00 committed by Felix Ruess
parent 8545d9d565
commit a4b582f91d
2 changed files with 369 additions and 266 deletions

View File

@ -457,6 +457,7 @@ extern u32 rcc_ppre2_frequency;
/* --- Function prototypes ------------------------------------------------- */ /* --- Function prototypes ------------------------------------------------- */
typedef enum { typedef enum {
CLOCK_3V3_48MHZ,
CLOCK_3V3_120MHZ, CLOCK_3V3_120MHZ,
CLOCK_3V3_168MHZ, CLOCK_3V3_168MHZ,
CLOCK_3V3_END CLOCK_3V3_END
@ -477,6 +478,8 @@ typedef struct {
} clock_scale_t; } clock_scale_t;
extern const clock_scale_t hse_8mhz_3v3[CLOCK_3V3_END]; extern const clock_scale_t hse_8mhz_3v3[CLOCK_3V3_END];
extern const clock_scale_t hse_12mhz_3v3[CLOCK_3V3_END];
extern const clock_scale_t hse_16mhz_3v3[CLOCK_3V3_END];
typedef enum { typedef enum {
PLL, HSE, HSI, LSE, LSI PLL, HSE, HSI, LSE, LSI

View File

@ -30,404 +30,504 @@ u32 rcc_ppre2_frequency = 16000000;
const clock_scale_t hse_8mhz_3v3[CLOCK_3V3_END] = const clock_scale_t hse_8mhz_3v3[CLOCK_3V3_END] =
{ {
{ /* 120MHz */ { /* 48MHz */
.pllm = 8, .pllm = 8,
.plln = 240, .plln = 96,
.pllp = 2, .pllp = 2,
.pllq = 5, .pllq = 2,
.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, .power_save = 1,
.flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE | FLASH_ACR_LATENCY_3WS, .flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE | FLASH_ACR_LATENCY_3WS,
.apb1_frequency = 30000000, .apb1_frequency = 12000000,
.apb2_frequency = 60000000, .apb2_frequency = 24000000,
}, },
{ /* 168MHz */ { /* 120MHz */
.pllm = 8, .pllm = 8,
.plln = 336, .plln = 240,
.pllp = 2, .pllp = 2,
.pllq = 7, .pllq = 5,
.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,
.flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE | FLASH_ACR_LATENCY_5WS, .power_save = 1,
.apb1_frequency = 42000000, .flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE | FLASH_ACR_LATENCY_3WS,
.apb2_frequency = 84000000, .apb1_frequency = 30000000,
}, .apb2_frequency = 60000000,
},
{ /* 168MHz */
.pllm = 8,
.plln = 336,
.pllp = 2,
.pllq = 7,
.hpre = RCC_CFGR_HPRE_DIV_NONE,
.ppre1 = RCC_CFGR_PPRE_DIV_4,
.ppre2 = RCC_CFGR_PPRE_DIV_2,
.flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE | FLASH_ACR_LATENCY_5WS,
.apb1_frequency = 42000000,
.apb2_frequency = 84000000,
},
};
const clock_scale_t hse_12mhz_3v3[CLOCK_3V3_END] =
{
{ /* 48MHz */
.pllm = 12,
.plln = 96,
.pllp = 2,
.pllq = 2,
.hpre = RCC_CFGR_HPRE_DIV_NONE,
.ppre1 = RCC_CFGR_PPRE_DIV_4,
.ppre2 = RCC_CFGR_PPRE_DIV_2,
.power_save = 1,
.flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE | FLASH_ACR_LATENCY_3WS,
.apb1_frequency = 12000000,
.apb2_frequency = 24000000,
},
{ /* 120MHz */
.pllm = 12,
.plln = 240,
.pllp = 2,
.pllq = 5,
.hpre = RCC_CFGR_HPRE_DIV_NONE,
.ppre1 = RCC_CFGR_PPRE_DIV_4,
.ppre2 = RCC_CFGR_PPRE_DIV_2,
.power_save = 1,
.flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE | FLASH_ACR_LATENCY_3WS,
.apb1_frequency = 30000000,
.apb2_frequency = 60000000,
},
{ /* 168MHz */
.pllm = 12,
.plln = 336,
.pllp = 2,
.pllq = 7,
.hpre = RCC_CFGR_HPRE_DIV_NONE,
.ppre1 = RCC_CFGR_PPRE_DIV_4,
.ppre2 = RCC_CFGR_PPRE_DIV_2,
.flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE | FLASH_ACR_LATENCY_5WS,
.apb1_frequency = 42000000,
.apb2_frequency = 84000000,
},
};
const clock_scale_t hse_16mhz_3v3[CLOCK_3V3_END] =
{
{ /* 48MHz */
.pllm = 16,
.plln = 96,
.pllp = 2,
.pllq = 2,
.hpre = RCC_CFGR_HPRE_DIV_NONE,
.ppre1 = RCC_CFGR_PPRE_DIV_4,
.ppre2 = RCC_CFGR_PPRE_DIV_2,
.power_save = 1,
.flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE | FLASH_ACR_LATENCY_3WS,
.apb1_frequency = 12000000,
.apb2_frequency = 24000000,
},
{ /* 120MHz */
.pllm = 16,
.plln = 240,
.pllp = 2,
.pllq = 5,
.hpre = RCC_CFGR_HPRE_DIV_NONE,
.ppre1 = RCC_CFGR_PPRE_DIV_4,
.ppre2 = RCC_CFGR_PPRE_DIV_2,
.power_save = 1,
.flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE | FLASH_ACR_LATENCY_3WS,
.apb1_frequency = 30000000,
.apb2_frequency = 60000000,
},
{ /* 168MHz */
.pllm = 16,
.plln = 336,
.pllp = 2,
.pllq = 7,
.hpre = RCC_CFGR_HPRE_DIV_NONE,
.ppre1 = RCC_CFGR_PPRE_DIV_4,
.ppre2 = RCC_CFGR_PPRE_DIV_2,
.flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE | FLASH_ACR_LATENCY_5WS,
.apb1_frequency = 42000000,
.apb2_frequency = 84000000,
},
}; };
void rcc_osc_ready_int_clear(osc_t osc) void rcc_osc_ready_int_clear(osc_t osc)
{ {
switch (osc) { switch (osc) {
case PLL: case PLL:
RCC_CIR |= RCC_CIR_PLLRDYC; RCC_CIR |= RCC_CIR_PLLRDYC;
break; break;
case HSE: case HSE:
RCC_CIR |= RCC_CIR_HSERDYC; RCC_CIR |= RCC_CIR_HSERDYC;
break; break;
case HSI: case HSI:
RCC_CIR |= RCC_CIR_HSIRDYC; RCC_CIR |= RCC_CIR_HSIRDYC;
break; break;
case LSE: case LSE:
RCC_CIR |= RCC_CIR_LSERDYC; RCC_CIR |= RCC_CIR_LSERDYC;
break; break;
case LSI: case LSI:
RCC_CIR |= RCC_CIR_LSIRDYC; RCC_CIR |= RCC_CIR_LSIRDYC;
break; break;
} }
} }
void rcc_osc_ready_int_enable(osc_t osc) void rcc_osc_ready_int_enable(osc_t osc)
{ {
switch (osc) { switch (osc) {
case PLL: case PLL:
RCC_CIR |= RCC_CIR_PLLRDYIE; RCC_CIR |= RCC_CIR_PLLRDYIE;
break; break;
case HSE: case HSE:
RCC_CIR |= RCC_CIR_HSERDYIE; RCC_CIR |= RCC_CIR_HSERDYIE;
break; break;
case HSI: case HSI:
RCC_CIR |= RCC_CIR_HSIRDYIE; RCC_CIR |= RCC_CIR_HSIRDYIE;
break; break;
case LSE: case LSE:
RCC_CIR |= RCC_CIR_LSERDYIE; RCC_CIR |= RCC_CIR_LSERDYIE;
break; break;
case LSI: case LSI:
RCC_CIR |= RCC_CIR_LSIRDYIE; RCC_CIR |= RCC_CIR_LSIRDYIE;
break; break;
} }
} }
void rcc_osc_ready_int_disable(osc_t osc) void rcc_osc_ready_int_disable(osc_t osc)
{ {
switch (osc) { switch (osc) {
case PLL: case PLL:
RCC_CIR &= ~RCC_CIR_PLLRDYIE; RCC_CIR &= ~RCC_CIR_PLLRDYIE;
break; break;
case HSE: case HSE:
RCC_CIR &= ~RCC_CIR_HSERDYIE; RCC_CIR &= ~RCC_CIR_HSERDYIE;
break; break;
case HSI: case HSI:
RCC_CIR &= ~RCC_CIR_HSIRDYIE; RCC_CIR &= ~RCC_CIR_HSIRDYIE;
break; break;
case LSE: case LSE:
RCC_CIR &= ~RCC_CIR_LSERDYIE; RCC_CIR &= ~RCC_CIR_LSERDYIE;
break; break;
case LSI: case LSI:
RCC_CIR &= ~RCC_CIR_LSIRDYIE; RCC_CIR &= ~RCC_CIR_LSIRDYIE;
break; break;
} }
} }
int rcc_osc_ready_int_flag(osc_t osc) int rcc_osc_ready_int_flag(osc_t osc)
{ {
switch (osc) { switch (osc) {
case PLL: case PLL:
return ((RCC_CIR & RCC_CIR_PLLRDYF) != 0); return ((RCC_CIR & RCC_CIR_PLLRDYF) != 0);
break; break;
case HSE: case HSE:
return ((RCC_CIR & RCC_CIR_HSERDYF) != 0); return ((RCC_CIR & RCC_CIR_HSERDYF) != 0);
break; break;
case HSI: case HSI:
return ((RCC_CIR & RCC_CIR_HSIRDYF) != 0); return ((RCC_CIR & RCC_CIR_HSIRDYF) != 0);
break; break;
case LSE: case LSE:
return ((RCC_CIR & RCC_CIR_LSERDYF) != 0); return ((RCC_CIR & RCC_CIR_LSERDYF) != 0);
break; break;
case LSI: case LSI:
return ((RCC_CIR & RCC_CIR_LSIRDYF) != 0); return ((RCC_CIR & RCC_CIR_LSIRDYF) != 0);
break; break;
} }
cm3_assert_not_reached(); cm3_assert_not_reached();
} }
void rcc_css_int_clear(void) void rcc_css_int_clear(void)
{ {
RCC_CIR |= RCC_CIR_CSSC; RCC_CIR |= RCC_CIR_CSSC;
} }
int rcc_css_int_flag(void) int rcc_css_int_flag(void)
{ {
return ((RCC_CIR & RCC_CIR_CSSF) != 0); return ((RCC_CIR & RCC_CIR_CSSF) != 0);
} }
void rcc_wait_for_osc_ready(osc_t osc) void rcc_wait_for_osc_ready(osc_t osc)
{ {
switch (osc) { switch (osc) {
case PLL: case PLL:
while ((RCC_CR & RCC_CR_PLLRDY) == 0); while ((RCC_CR & RCC_CR_PLLRDY) == 0);
break; break;
case HSE: case HSE:
while ((RCC_CR & RCC_CR_HSERDY) == 0); while ((RCC_CR & RCC_CR_HSERDY) == 0);
break; break;
case HSI: case HSI:
while ((RCC_CR & RCC_CR_HSIRDY) == 0); while ((RCC_CR & RCC_CR_HSIRDY) == 0);
break; break;
case LSE: case LSE:
while ((RCC_BDCR & RCC_BDCR_LSERDY) == 0); while ((RCC_BDCR & RCC_BDCR_LSERDY) == 0);
break; break;
case LSI: case LSI:
while ((RCC_CSR & RCC_CSR_LSIRDY) == 0); while ((RCC_CSR & RCC_CSR_LSIRDY) == 0);
break; break;
} }
} }
void rcc_wait_for_sysclk_status(osc_t osc) void rcc_wait_for_sysclk_status(osc_t osc)
{ {
switch (osc) { switch (osc) {
case PLL: case PLL:
while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SWS_PLL); while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SWS_PLL);
break; break;
case HSE: case HSE:
while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SWS_HSE); while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SWS_HSE);
break; break;
case HSI: case HSI:
while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SWS_HSI); while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SWS_HSI);
break; break;
default: default:
/* Shouldn't be reached. */ /* Shouldn't be reached. */
break; break;
} }
} }
void rcc_osc_on(osc_t osc) void rcc_osc_on(osc_t osc)
{ {
switch (osc) { switch (osc) {
case PLL: case PLL:
RCC_CR |= RCC_CR_PLLON; RCC_CR |= RCC_CR_PLLON;
break; break;
case HSE: case HSE:
RCC_CR |= RCC_CR_HSEON; RCC_CR |= RCC_CR_HSEON;
break; break;
case HSI: case HSI:
RCC_CR |= RCC_CR_HSION; RCC_CR |= RCC_CR_HSION;
break; break;
case LSE: case LSE:
RCC_BDCR |= RCC_BDCR_LSEON; RCC_BDCR |= RCC_BDCR_LSEON;
break; break;
case LSI: case LSI:
RCC_CSR |= RCC_CSR_LSION; RCC_CSR |= RCC_CSR_LSION;
break; break;
} }
} }
void rcc_osc_off(osc_t osc) void rcc_osc_off(osc_t osc)
{ {
switch (osc) { switch (osc) {
case PLL: case PLL:
RCC_CR &= ~RCC_CR_PLLON; RCC_CR &= ~RCC_CR_PLLON;
break; break;
case HSE: case HSE:
RCC_CR &= ~RCC_CR_HSEON; RCC_CR &= ~RCC_CR_HSEON;
break; break;
case HSI: case HSI:
RCC_CR &= ~RCC_CR_HSION; RCC_CR &= ~RCC_CR_HSION;
break; break;
case LSE: case LSE:
RCC_BDCR &= ~RCC_BDCR_LSEON; RCC_BDCR &= ~RCC_BDCR_LSEON;
break; break;
case LSI: case LSI:
RCC_CSR &= ~RCC_CSR_LSION; RCC_CSR &= ~RCC_CSR_LSION;
break; break;
} }
} }
void rcc_css_enable(void) void rcc_css_enable(void)
{ {
RCC_CR |= RCC_CR_CSSON; RCC_CR |= RCC_CR_CSSON;
} }
void rcc_css_disable(void) void rcc_css_disable(void)
{ {
RCC_CR &= ~RCC_CR_CSSON; RCC_CR &= ~RCC_CR_CSSON;
} }
void rcc_osc_bypass_enable(osc_t osc) void rcc_osc_bypass_enable(osc_t osc)
{ {
switch (osc) { switch (osc) {
case HSE: case HSE:
RCC_CR |= RCC_CR_HSEBYP; RCC_CR |= RCC_CR_HSEBYP;
break; break;
case LSE: case LSE:
RCC_BDCR |= RCC_BDCR_LSEBYP; RCC_BDCR |= RCC_BDCR_LSEBYP;
break; break;
case PLL: case PLL:
case HSI: case HSI:
case LSI: case LSI:
/* Do nothing, only HSE/LSE allowed here. */ /* Do nothing, only HSE/LSE allowed here. */
break; break;
} }
} }
void rcc_osc_bypass_disable(osc_t osc) void rcc_osc_bypass_disable(osc_t osc)
{ {
switch (osc) { switch (osc) {
case HSE: case HSE:
RCC_CR &= ~RCC_CR_HSEBYP; RCC_CR &= ~RCC_CR_HSEBYP;
break; break;
case LSE: case LSE:
RCC_BDCR &= ~RCC_BDCR_LSEBYP; RCC_BDCR &= ~RCC_BDCR_LSEBYP;
break; break;
case PLL: case PLL:
case HSI: case HSI:
case LSI: case LSI:
/* Do nothing, only HSE/LSE allowed here. */ /* Do nothing, only HSE/LSE allowed here. */
break; break;
} }
} }
void rcc_peripheral_enable_clock(volatile u32 *reg, u32 en) void rcc_peripheral_enable_clock(volatile u32 *reg, u32 en)
{ {
*reg |= en; *reg |= en;
} }
void rcc_peripheral_disable_clock(volatile u32 *reg, u32 en) void rcc_peripheral_disable_clock(volatile u32 *reg, u32 en)
{ {
*reg &= ~en; *reg &= ~en;
} }
void rcc_peripheral_reset(volatile u32 *reg, u32 reset) void rcc_peripheral_reset(volatile u32 *reg, u32 reset)
{ {
*reg |= reset; *reg |= reset;
} }
void rcc_peripheral_clear_reset(volatile u32 *reg, u32 clear_reset) void rcc_peripheral_clear_reset(volatile u32 *reg, u32 clear_reset)
{ {
*reg &= ~clear_reset; *reg &= ~clear_reset;
} }
void rcc_set_sysclk_source(u32 clk) void rcc_set_sysclk_source(u32 clk)
{ {
u32 reg32; u32 reg32;
reg32 = RCC_CFGR; reg32 = RCC_CFGR;
reg32 &= ~((1 << 1) | (1 << 0)); reg32 &= ~((1 << 1) | (1 << 0));
RCC_CFGR = (reg32 | clk); RCC_CFGR = (reg32 | clk);
} }
void rcc_set_pll_source(u32 pllsrc) void rcc_set_pll_source(u32 pllsrc)
{ {
u32 reg32; u32 reg32;
reg32 = RCC_PLLCFGR; reg32 = RCC_PLLCFGR;
reg32 &= ~(1 << 22); reg32 &= ~(1 << 22);
RCC_PLLCFGR = (reg32 | (pllsrc << 22)); RCC_PLLCFGR = (reg32 | (pllsrc << 22));
} }
void rcc_set_ppre2(u32 ppre2) void rcc_set_ppre2(u32 ppre2)
{ {
u32 reg32; u32 reg32;
reg32 = RCC_CFGR; reg32 = RCC_CFGR;
reg32 &= ~((1 << 13) | (1 << 14) | (1 << 15)); reg32 &= ~((1 << 13) | (1 << 14) | (1 << 15));
RCC_CFGR = (reg32 | (ppre2 << 13)); RCC_CFGR = (reg32 | (ppre2 << 13));
} }
void rcc_set_ppre1(u32 ppre1) void rcc_set_ppre1(u32 ppre1)
{ {
u32 reg32; u32 reg32;
reg32 = RCC_CFGR; reg32 = RCC_CFGR;
reg32 &= ~((1 << 10) | (1 << 11) | (1 << 12)); reg32 &= ~((1 << 10) | (1 << 11) | (1 << 12));
RCC_CFGR = (reg32 | (ppre1 << 10)); RCC_CFGR = (reg32 | (ppre1 << 10));
} }
void rcc_set_hpre(u32 hpre) void rcc_set_hpre(u32 hpre)
{ {
u32 reg32; u32 reg32;
reg32 = RCC_CFGR; reg32 = RCC_CFGR;
reg32 &= ~((1 << 4) | (1 << 5) | (1 << 6) | (1 << 7)); reg32 &= ~((1 << 4) | (1 << 5) | (1 << 6) | (1 << 7));
RCC_CFGR = (reg32 | (hpre << 4)); RCC_CFGR = (reg32 | (hpre << 4));
} }
void rcc_set_rtcpre(u32 rtcpre) void rcc_set_rtcpre(u32 rtcpre)
{ {
u32 reg32; u32 reg32;
reg32 = RCC_CFGR; reg32 = RCC_CFGR;
reg32 &= ~((1 << 16) | (1 << 17) | (1 << 18) | (1 << 19) | (1 << 20)); reg32 &= ~((1 << 16) | (1 << 17) | (1 << 18) | (1 << 19) | (1 << 20));
RCC_CFGR = (reg32 | (rtcpre << 16)); RCC_CFGR = (reg32 | (rtcpre << 16));
} }
void rcc_set_main_pll_hsi(u32 pllm, u32 plln, u32 pllp, u32 pllq) void rcc_set_main_pll_hsi(u32 pllm, u32 plln, u32 pllp, u32 pllq)
{ {
RCC_PLLCFGR = (pllm << RCC_PLLCFGR_PLLM_SHIFT) | RCC_PLLCFGR = (pllm << RCC_PLLCFGR_PLLM_SHIFT) |
(plln << RCC_PLLCFGR_PLLN_SHIFT) | (plln << RCC_PLLCFGR_PLLN_SHIFT) |
(((pllp >> 1) - 1) << RCC_PLLCFGR_PLLP_SHIFT) | (((pllp >> 1) - 1) << RCC_PLLCFGR_PLLP_SHIFT) |
(pllq << RCC_PLLCFGR_PLLQ_SHIFT); (pllq << RCC_PLLCFGR_PLLQ_SHIFT);
} }
void rcc_set_main_pll_hse(u32 pllm, u32 plln, u32 pllp, u32 pllq) void rcc_set_main_pll_hse(u32 pllm, u32 plln, u32 pllp, u32 pllq)
{ {
RCC_PLLCFGR = (pllm << RCC_PLLCFGR_PLLM_SHIFT) | RCC_PLLCFGR = (pllm << RCC_PLLCFGR_PLLM_SHIFT) |
(plln << RCC_PLLCFGR_PLLN_SHIFT) | (plln << RCC_PLLCFGR_PLLN_SHIFT) |
(((pllp >> 1) - 1) << RCC_PLLCFGR_PLLP_SHIFT) | (((pllp >> 1) - 1) << RCC_PLLCFGR_PLLP_SHIFT) |
RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLSRC |
(pllq << RCC_PLLCFGR_PLLQ_SHIFT); (pllq << RCC_PLLCFGR_PLLQ_SHIFT);
} }
u32 rcc_system_clock_source(void) u32 rcc_system_clock_source(void)
{ {
/* Return the clock source which is used as system clock. */ /* Return the clock source which is used as system clock. */
return ((RCC_CFGR & 0x000c) >> 2); return ((RCC_CFGR & 0x000c) >> 2);
} }
void rcc_clock_setup_hse_3v3(const clock_scale_t *clock) void rcc_clock_setup_hse_3v3(const clock_scale_t *clock)
{ {
/* Enable internal high-speed oscillator. */ /* Enable internal high-speed oscillator. */
rcc_osc_on(HSI); rcc_osc_on(HSI);
rcc_wait_for_osc_ready(HSI); rcc_wait_for_osc_ready(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 8MHz. */
rcc_osc_on(HSE); rcc_osc_on(HSE);
rcc_wait_for_osc_ready(HSE); rcc_wait_for_osc_ready(HSE);
/* Enable/disable high performance mode */ /* Enable/disable high performance mode */
if (!clock->power_save) if (!clock->power_save)
pwr_set_vos_scale(SCALE1); pwr_set_vos_scale(SCALE1);
else else
pwr_set_vos_scale(SCALE2); pwr_set_vos_scale(SCALE2);
/* /*
* Set prescalers for AHB, ADC, ABP1, ABP2. * Set prescalers for AHB, ADC, ABP1, ABP2.
* Do this before touching the PLL (TODO: why?). * Do this before touching the PLL (TODO: why?).
*/ */
rcc_set_hpre(clock->hpre); rcc_set_hpre(clock->hpre);
rcc_set_ppre1(clock->ppre1); rcc_set_ppre1(clock->ppre1);
rcc_set_ppre2(clock->ppre2); rcc_set_ppre2(clock->ppre2);
rcc_set_main_pll_hse(clock->pllm, clock->plln, rcc_set_main_pll_hse(clock->pllm, clock->plln,
clock->pllp, clock->pllq); clock->pllp, clock->pllq);
/* Enable PLL oscillator and wait for it to stabilize. */ /* Enable PLL oscillator and wait for it to stabilize. */
rcc_osc_on(PLL); rcc_osc_on(PLL);
rcc_wait_for_osc_ready(PLL); rcc_wait_for_osc_ready(PLL);
/* Configure flash settings. */ /* Configure flash settings. */
flash_set_ws(clock->flash_config); flash_set_ws(clock->flash_config);
/* Select PLL as SYSCLK source. */ /* Select PLL as SYSCLK source. */
rcc_set_sysclk_source(RCC_CFGR_SW_PLL); rcc_set_sysclk_source(RCC_CFGR_SW_PLL);
/* Wait for PLL clock to be selected. */ /* Wait for PLL clock to be selected. */
rcc_wait_for_sysclk_status(PLL); rcc_wait_for_sysclk_status(PLL);
/* Set the peripheral clock frequencies used. */ /* Set the peripheral clock frequencies used. */
rcc_ppre1_frequency = clock->apb1_frequency; rcc_ppre1_frequency = clock->apb1_frequency;
rcc_ppre2_frequency = clock->apb2_frequency; rcc_ppre2_frequency = clock->apb2_frequency;
/* Disable internal high-speed oscillator. */
rcc_osc_off(HSI);
} }
void rcc_backupdomain_reset(void) void rcc_backupdomain_reset(void)
{ {
/* Set the backup domain software reset. */ /* Set the backup domain software reset. */
RCC_BDCR |= RCC_BDCR_BDRST; RCC_BDCR |= RCC_BDCR_BDRST;
/* Clear the backup domain software reset. */ /* Clear the backup domain software reset. */
RCC_BDCR &= ~RCC_BDCR_BDRST; RCC_BDCR &= ~RCC_BDCR_BDRST;
} }