BREAKING: stm32f3:rcc: add more generic pll setup routines
Deprecate the old routine and make a new one that actually handles HSI and HSE properly, and includes the predivider and the usb divider settings as well.
This commit is contained in:
parent
622475f543
commit
2204f447bb
@ -51,6 +51,8 @@
|
|||||||
#ifndef LIBOPENCM3_RCC_H
|
#ifndef LIBOPENCM3_RCC_H
|
||||||
#define LIBOPENCM3_RCC_H
|
#define LIBOPENCM3_RCC_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
/* --- RCC registers ------------------------------------------------------- */
|
/* --- RCC registers ------------------------------------------------------- */
|
||||||
|
|
||||||
#define RCC_CR MMIO32(RCC_BASE + 0x00)
|
#define RCC_CR MMIO32(RCC_BASE + 0x00)
|
||||||
@ -419,9 +421,11 @@ enum rcc_clock {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct rcc_clock_scale {
|
struct rcc_clock_scale {
|
||||||
uint8_t pll;
|
|
||||||
uint8_t pllsrc;
|
uint8_t pllsrc;
|
||||||
uint32_t flash_config;
|
uint8_t pllmul;
|
||||||
|
uint8_t plldiv;
|
||||||
|
bool usbdiv1;
|
||||||
|
uint32_t flash_waitstates;
|
||||||
uint8_t hpre;
|
uint8_t hpre;
|
||||||
uint8_t ppre1;
|
uint8_t ppre1;
|
||||||
uint8_t ppre2;
|
uint8_t ppre2;
|
||||||
@ -607,6 +611,7 @@ void rcc_set_prediv(uint32_t prediv);
|
|||||||
void rcc_set_pll_multiplier(uint32_t pll);
|
void rcc_set_pll_multiplier(uint32_t pll);
|
||||||
uint32_t rcc_get_system_clock_source(void);
|
uint32_t rcc_get_system_clock_source(void);
|
||||||
void rcc_backupdomain_reset(void);
|
void rcc_backupdomain_reset(void);
|
||||||
|
void rcc_clock_setup_pll(const struct rcc_clock_scale *clock);
|
||||||
void rcc_clock_setup_hsi(const struct rcc_clock_scale *clock);
|
void rcc_clock_setup_hsi(const struct rcc_clock_scale *clock);
|
||||||
void rcc_set_i2c_clock_hsi(uint32_t i2c);
|
void rcc_set_i2c_clock_hsi(uint32_t i2c);
|
||||||
void rcc_set_i2c_clock_sysclk(uint32_t i2c);
|
void rcc_set_i2c_clock_sysclk(uint32_t i2c);
|
||||||
|
@ -46,34 +46,34 @@ uint32_t rcc_apb2_frequency = 8000000;
|
|||||||
|
|
||||||
const struct rcc_clock_scale rcc_hsi_8mhz[RCC_CLOCK_END] = {
|
const struct rcc_clock_scale rcc_hsi_8mhz[RCC_CLOCK_END] = {
|
||||||
{ /* 44MHz */
|
{ /* 44MHz */
|
||||||
.pll = RCC_CFGR_PLLMUL_MUL11,
|
.pllmul = RCC_CFGR_PLLMUL_MUL11,
|
||||||
.pllsrc = RCC_CFGR_PLLSRC_HSI_DIV2,
|
.pllsrc = RCC_CFGR_PLLSRC_HSI_DIV2,
|
||||||
.hpre = RCC_CFGR_HPRE_DIV_NONE,
|
.hpre = RCC_CFGR_HPRE_DIV_NONE,
|
||||||
.ppre1 = RCC_CFGR_PPRE1_DIV_2,
|
.ppre1 = RCC_CFGR_PPRE1_DIV_2,
|
||||||
.ppre2 = RCC_CFGR_PPRE2_DIV_NONE,
|
.ppre2 = RCC_CFGR_PPRE2_DIV_NONE,
|
||||||
.flash_config = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY_1WS,
|
.flash_waitstates = 1,
|
||||||
.ahb_frequency = 44000000,
|
.ahb_frequency = 44000000,
|
||||||
.apb1_frequency = 22000000,
|
.apb1_frequency = 22000000,
|
||||||
.apb2_frequency = 44000000,
|
.apb2_frequency = 44000000,
|
||||||
},
|
},
|
||||||
{ /* 48MHz */
|
{ /* 48MHz */
|
||||||
.pll = RCC_CFGR_PLLMUL_MUL12,
|
.pllmul = RCC_CFGR_PLLMUL_MUL12,
|
||||||
.pllsrc = RCC_CFGR_PLLSRC_HSI_DIV2,
|
.pllsrc = RCC_CFGR_PLLSRC_HSI_DIV2,
|
||||||
.hpre = RCC_CFGR_HPRE_DIV_NONE,
|
.hpre = RCC_CFGR_HPRE_DIV_NONE,
|
||||||
.ppre1 = RCC_CFGR_PPRE1_DIV_2,
|
.ppre1 = RCC_CFGR_PPRE1_DIV_2,
|
||||||
.ppre2 = RCC_CFGR_PPRE2_DIV_NONE,
|
.ppre2 = RCC_CFGR_PPRE2_DIV_NONE,
|
||||||
.flash_config = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY_1WS,
|
.flash_waitstates = 1,
|
||||||
.ahb_frequency = 48000000,
|
.ahb_frequency = 48000000,
|
||||||
.apb1_frequency = 24000000,
|
.apb1_frequency = 24000000,
|
||||||
.apb2_frequency = 48000000,
|
.apb2_frequency = 48000000,
|
||||||
},
|
},
|
||||||
{ /* 64MHz */
|
{ /* 64MHz */
|
||||||
.pll = RCC_CFGR_PLLMUL_MUL16,
|
.pllmul = RCC_CFGR_PLLMUL_MUL16,
|
||||||
.pllsrc = RCC_CFGR_PLLSRC_HSI_DIV2,
|
.pllsrc = RCC_CFGR_PLLSRC_HSI_DIV2,
|
||||||
.hpre = RCC_CFGR_HPRE_DIV_NONE,
|
.hpre = RCC_CFGR_HPRE_DIV_NONE,
|
||||||
.ppre1 = RCC_CFGR_PPRE1_DIV_2,
|
.ppre1 = RCC_CFGR_PPRE1_DIV_2,
|
||||||
.ppre2 = RCC_CFGR_PPRE2_DIV_NONE,
|
.ppre2 = RCC_CFGR_PPRE2_DIV_NONE,
|
||||||
.flash_config = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY_2WS,
|
.flash_waitstates = 2,
|
||||||
.ahb_frequency = 64000000,
|
.ahb_frequency = 64000000,
|
||||||
.apb1_frequency = 32000000,
|
.apb1_frequency = 32000000,
|
||||||
.apb2_frequency = 64000000,
|
.apb2_frequency = 64000000,
|
||||||
@ -349,8 +349,54 @@ uint32_t rcc_get_system_clock_source(void)
|
|||||||
return (RCC_CFGR & 0x000c) >> 2;
|
return (RCC_CFGR & 0x000c) >> 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup clocks to run from PLL.
|
||||||
|
* The arguments provide the pll source, multipliers, dividers, all that's
|
||||||
|
* needed to establish a system clock.
|
||||||
|
* @param clock clock information structure
|
||||||
|
*/
|
||||||
|
void rcc_clock_setup_pll(const struct rcc_clock_scale *clock)
|
||||||
|
{
|
||||||
|
if (clock->pllsrc == RCC_CFGR_PLLSRC_HSE_PREDIV) {
|
||||||
|
rcc_osc_on(RCC_HSE);
|
||||||
|
rcc_wait_for_osc_ready(RCC_HSE);
|
||||||
|
} else {
|
||||||
|
rcc_osc_on(RCC_HSI);
|
||||||
|
rcc_wait_for_osc_ready(RCC_HSI);
|
||||||
|
}
|
||||||
|
rcc_osc_off(RCC_PLL);
|
||||||
|
rcc_usb_prescale_1_5();
|
||||||
|
if (clock->usbdiv1) {
|
||||||
|
rcc_usb_prescale_1();
|
||||||
|
}
|
||||||
|
rcc_wait_for_osc_not_ready(RCC_PLL);
|
||||||
|
rcc_set_pll_source(clock->pllsrc);
|
||||||
|
rcc_set_pll_multiplier(clock->pllmul);
|
||||||
|
rcc_set_prediv(clock->plldiv);
|
||||||
|
/* Enable PLL oscillator and wait for it to stabilize. */
|
||||||
|
rcc_osc_on(RCC_PLL);
|
||||||
|
rcc_wait_for_osc_ready(RCC_PLL);
|
||||||
|
|
||||||
void rcc_clock_setup_hsi(const struct rcc_clock_scale *clock)
|
/* Configure flash settings. */
|
||||||
|
flash_prefetch_enable();
|
||||||
|
flash_set_ws(clock->flash_waitstates);
|
||||||
|
|
||||||
|
rcc_set_hpre(clock->hpre);
|
||||||
|
rcc_set_ppre2(clock->ppre2);
|
||||||
|
rcc_set_ppre1(clock->ppre1);
|
||||||
|
/* Select PLL as SYSCLK source. */
|
||||||
|
rcc_set_sysclk_source(RCC_CFGR_SW_PLL);
|
||||||
|
/* Wait for PLL clock to be selected. */
|
||||||
|
rcc_wait_for_sysclk_status(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void __attribute__((deprecated)) rcc_clock_setup_hsi(const struct rcc_clock_scale *clock)
|
||||||
{
|
{
|
||||||
/* Enable internal high-speed oscillator. */
|
/* Enable internal high-speed oscillator. */
|
||||||
rcc_osc_on(RCC_HSI);
|
rcc_osc_on(RCC_HSI);
|
||||||
@ -362,7 +408,7 @@ void rcc_clock_setup_hsi(const struct rcc_clock_scale *clock)
|
|||||||
rcc_osc_off(RCC_PLL);
|
rcc_osc_off(RCC_PLL);
|
||||||
rcc_wait_for_osc_not_ready(RCC_PLL);
|
rcc_wait_for_osc_not_ready(RCC_PLL);
|
||||||
rcc_set_pll_source(clock->pllsrc);
|
rcc_set_pll_source(clock->pllsrc);
|
||||||
rcc_set_pll_multiplier(clock->pll);
|
rcc_set_pll_multiplier(clock->pllmul);
|
||||||
/* Enable PLL oscillator and wait for it to stabilize. */
|
/* Enable PLL oscillator and wait for it to stabilize. */
|
||||||
rcc_osc_on(RCC_PLL);
|
rcc_osc_on(RCC_PLL);
|
||||||
rcc_wait_for_osc_ready(RCC_PLL);
|
rcc_wait_for_osc_ready(RCC_PLL);
|
||||||
@ -374,7 +420,7 @@ void rcc_clock_setup_hsi(const struct rcc_clock_scale *clock)
|
|||||||
rcc_set_ppre2(clock->ppre2);
|
rcc_set_ppre2(clock->ppre2);
|
||||||
rcc_set_ppre1(clock->ppre1);
|
rcc_set_ppre1(clock->ppre1);
|
||||||
/* Configure flash settings. */
|
/* Configure flash settings. */
|
||||||
flash_set_ws(clock->flash_config);
|
flash_set_ws(clock->flash_waitstates);
|
||||||
/* Select PLL as SYSCLK source. */
|
/* Select PLL as SYSCLK source. */
|
||||||
rcc_set_sysclk_source(RCC_CFGR_SW_PLL); /* XXX: se cayo */
|
rcc_set_sysclk_source(RCC_CFGR_SW_PLL); /* XXX: se cayo */
|
||||||
/* Wait for PLL clock to be selected. */
|
/* Wait for PLL clock to be selected. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user