|
|
@ -35,8 +35,15 @@ |
|
|
|
/**@{*/ |
|
|
|
|
|
|
|
#include <libopencm3/cm3/assert.h> |
|
|
|
#include <libopencm3/stm32/flash.h> |
|
|
|
#include <libopencm3/stm32/pwr.h> |
|
|
|
#include <libopencm3/stm32/rcc.h> |
|
|
|
|
|
|
|
/* Set the default clock frequencies after reset. */ |
|
|
|
uint32_t rcc_ahb_frequency = 2097000; |
|
|
|
uint32_t rcc_apb1_frequency = 2097000; |
|
|
|
uint32_t rcc_apb2_frequency = 2097000; |
|
|
|
|
|
|
|
void rcc_osc_on(enum rcc_osc osc) |
|
|
|
{ |
|
|
|
switch (osc) { |
|
|
@ -371,5 +378,46 @@ void rcc_set_hpre(uint32_t hpre) |
|
|
|
RCC_CFGR = reg | (hpre << RCC_CFGR_HPRE_SHIFT); |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* Set up sysclock with PLL from HSI16 |
|
|
|
* @param clock full struct with desired parameters |
|
|
|
*/ |
|
|
|
void rcc_clock_setup_pll(const struct rcc_clock_scale *clock) |
|
|
|
{ |
|
|
|
/* Turn on the appropriate source for the PLL */ |
|
|
|
if (clock->pll_source == RCC_CFGR_PLLSRC_HSE_CLK) { |
|
|
|
rcc_osc_on(RCC_HSE); |
|
|
|
rcc_wait_for_osc_ready(RCC_HSE); |
|
|
|
} else { |
|
|
|
rcc_osc_on(RCC_HSI16); |
|
|
|
rcc_wait_for_osc_ready(RCC_HSI16); |
|
|
|
} |
|
|
|
|
|
|
|
rcc_set_hpre(clock->hpre); |
|
|
|
rcc_set_ppre1(clock->ppre1); |
|
|
|
rcc_set_ppre2(clock->ppre2); |
|
|
|
|
|
|
|
rcc_periph_clock_enable(RCC_PWR); |
|
|
|
pwr_set_vos_scale(clock->voltage_scale); |
|
|
|
|
|
|
|
rcc_osc_off(RCC_PLL); |
|
|
|
while (rcc_is_osc_ready(RCC_PLL)); |
|
|
|
|
|
|
|
flash_prefetch_enable(); |
|
|
|
flash_set_ws(clock->flash_waitstates); |
|
|
|
|
|
|
|
/* Set up the PLL */ |
|
|
|
rcc_set_pll_multiplier(clock->pll_mul); |
|
|
|
rcc_set_pll_divider(clock->pll_div); |
|
|
|
|
|
|
|
rcc_osc_on(RCC_PLL); |
|
|
|
rcc_wait_for_osc_ready(RCC_PLL); |
|
|
|
rcc_set_sysclk_source(RCC_PLL); |
|
|
|
|
|
|
|
/* Set the peripheral clock frequencies used. */ |
|
|
|
rcc_ahb_frequency = clock->ahb_frequency; |
|
|
|
rcc_apb1_frequency = clock->apb1_frequency; |
|
|
|
rcc_apb2_frequency = clock->apb2_frequency; |
|
|
|
} |
|
|
|
|
|
|
|
/**@}*/ |
|
|
|