stm32/rcc: use more PLL etc enums from PAC.

This commit is contained in:
Dario Nieuwenhuis
2023-10-11 00:12:33 +02:00
parent eff73d6dfa
commit 0cfa8d1bb5
20 changed files with 368 additions and 932 deletions

View File

@ -1,6 +1,6 @@
use crate::pac::flash::vals::Latency;
pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Ppre as APBPrescaler};
use crate::pac::rcc::vals::{Hsidiv, Ppre, Sw};
use crate::pac::rcc::vals::Sw;
pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Hsidiv as HSIPrescaler, Ppre as APBPrescaler};
use crate::pac::{FLASH, RCC};
use crate::rcc::{set_freqs, Clocks};
use crate::time::Hertz;
@ -19,33 +19,6 @@ pub enum ClockSrc {
LSI,
}
#[derive(Clone, Copy)]
pub enum HSIPrescaler {
NotDivided,
Div2,
Div4,
Div8,
Div16,
Div32,
Div64,
Div128,
}
impl Into<Hsidiv> for HSIPrescaler {
fn into(self) -> Hsidiv {
match self {
HSIPrescaler::NotDivided => Hsidiv::DIV1,
HSIPrescaler::Div2 => Hsidiv::DIV2,
HSIPrescaler::Div4 => Hsidiv::DIV4,
HSIPrescaler::Div8 => Hsidiv::DIV8,
HSIPrescaler::Div16 => Hsidiv::DIV16,
HSIPrescaler::Div32 => Hsidiv::DIV32,
HSIPrescaler::Div64 => Hsidiv::DIV64,
HSIPrescaler::Div128 => Hsidiv::DIV128,
}
}
}
/// Clocks configutation
pub struct Config {
pub mux: ClockSrc,
@ -57,7 +30,7 @@ impl Default for Config {
#[inline]
fn default() -> Config {
Config {
mux: ClockSrc::HSI(HSIPrescaler::NotDivided),
mux: ClockSrc::HSI(HSIPrescaler::DIV1),
ahb_pre: AHBPrescaler::DIV1,
apb_pre: APBPrescaler::DIV1,
}
@ -68,33 +41,32 @@ pub(crate) unsafe fn init(config: Config) {
let (sys_clk, sw) = match config.mux {
ClockSrc::HSI(div) => {
// Enable HSI
let div: Hsidiv = div.into();
RCC.cr().write(|w| {
w.set_hsidiv(div);
w.set_hsion(true)
});
while !RCC.cr().read().hsirdy() {}
(HSI_FREQ.0 >> div.to_bits(), Sw::HSI)
(HSI_FREQ / div, Sw::HSI)
}
ClockSrc::HSE(freq) => {
// Enable HSE
RCC.cr().write(|w| w.set_hseon(true));
while !RCC.cr().read().hserdy() {}
(freq.0, Sw::HSE)
(freq, Sw::HSE)
}
ClockSrc::LSI => {
// Enable LSI
RCC.csr2().write(|w| w.set_lsion(true));
while !RCC.csr2().read().lsirdy() {}
(LSI_FREQ.0, Sw::LSI)
(LSI_FREQ, Sw::LSI)
}
};
// Determine the flash latency implied by the target clock speed
// RM0454 § 3.3.4:
let target_flash_latency = if sys_clk <= 24_000_000 {
let target_flash_latency = if sys_clk <= Hertz(24_000_000) {
Latency::WS0
} else {
Latency::WS1
@ -129,7 +101,7 @@ pub(crate) unsafe fn init(config: Config) {
}
// Configure SYSCLK source, HCLK divisor, and PCLK divisor all at once
let (sw, hpre, ppre) = (sw.into(), config.ahb_pre.into(), config.apb_pre.into());
let (sw, hpre, ppre) = (sw.into(), config.ahb_pre, config.apb_pre);
RCC.cfgr().modify(|w| {
w.set_sw(sw);
w.set_hpre(hpre);
@ -150,34 +122,20 @@ pub(crate) unsafe fn init(config: Config) {
FLASH.acr().modify(|w| w.set_latency(target_flash_latency));
}
let ahb_div = match config.ahb_pre {
AHBPrescaler::DIV1 => 1,
AHBPrescaler::DIV2 => 2,
AHBPrescaler::DIV4 => 4,
AHBPrescaler::DIV8 => 8,
AHBPrescaler::DIV16 => 16,
AHBPrescaler::DIV64 => 64,
AHBPrescaler::DIV128 => 128,
AHBPrescaler::DIV256 => 256,
AHBPrescaler::DIV512 => 512,
_ => unreachable!(),
};
let ahb_freq = sys_clk / ahb_div;
let ahb_freq = sys_clk / config.ahb_pre;
let (apb_freq, apb_tim_freq) = match config.apb_pre {
APBPrescaler::DIV1 => (ahb_freq, ahb_freq),
pre => {
let pre: Ppre = pre.into();
let pre: u8 = 1 << (pre.to_bits() - 3);
let freq = ahb_freq / pre as u32;
(freq, freq * 2)
let freq = ahb_freq / pre;
(freq, freq * 2u32)
}
};
set_freqs(Clocks {
sys: Hertz(sys_clk),
ahb1: Hertz(ahb_freq),
apb1: Hertz(apb_freq),
apb1_tim: Hertz(apb_tim_freq),
sys: sys_clk,
ahb1: ahb_freq,
apb1: apb_freq,
apb1_tim: apb_tim_freq,
});
}