stm32/rcc: f4/f7 cleanup and make a bit more consistent.

This commit is contained in:
Dario Nieuwenhuis 2022-01-04 21:17:17 +01:00
parent b06e705a73
commit c3fd9a0f44
6 changed files with 38 additions and 38 deletions

View file

@ -7,6 +7,7 @@
#[cfg_attr(pwr_g4, path = "g4.rs")]
#[cfg_attr(pwr_l1, path = "l1.rs")]
#[cfg_attr(pwr_u5, path = "u5.rs")]
#[cfg_attr(pwr_wb55, path = "wb55.rs")]
mod _version;
pub use _version::*;

View file

View file

@ -7,17 +7,18 @@ use embassy::util::Unborrow;
const HSI: u32 = 16_000_000;
/// Clocks configutation
/// Clocks configuration
#[non_exhaustive]
#[derive(Default)]
pub struct Config {
pub hse: Option<Hertz>,
pub bypass_hse: bool,
pub pll48: bool,
pub sys_ck: Option<Hertz>,
pub hclk: Option<Hertz>,
pub sys_ck: Option<Hertz>,
pub pclk1: Option<Hertz>,
pub pclk2: Option<Hertz>,
pub pll48: bool,
}
/// RCC peripheral
@ -38,6 +39,8 @@ impl<'d> Rcc<'d> {
use super::sealed::RccPeripheral;
use crate::pac::rcc::vals::{Hpre, Hsebyp, Ppre, Sw};
peripherals::PWR::enable();
let pllsrcclk = self.config.hse.map(|hse| hse.0).unwrap_or(HSI);
let sysclk = self.config.sys_ck.map(|sys| sys.0).unwrap_or(pllsrcclk);
let sysclk_on_pll = sysclk != pllsrcclk;
@ -50,12 +53,9 @@ impl<'d> Rcc<'d> {
);
if self.config.pll48 {
assert!(
// USB specification allows +-0.25%
plls.pll48clk
.map(|freq| (48_000_000 - freq as i32).abs() <= 120_000)
.unwrap_or(false)
);
let freq = unwrap!(plls.pll48clk);
assert!((max::PLL_48_CLK as i32 - freq as i32).abs() <= max::PLL_48_TOLERANCE as i32);
}
let sysclk = if sysclk_on_pll {
@ -64,6 +64,7 @@ impl<'d> Rcc<'d> {
sysclk
};
// AHB prescaler
let hclk = self.config.hclk.map(|h| h.0).unwrap_or(sysclk);
let (hpre_bits, hpre_div) = match (sysclk + hclk - 1) / hclk {
0 => unreachable!(),
@ -86,6 +87,7 @@ impl<'d> Rcc<'d> {
.pclk1
.map(|p| p.0)
.unwrap_or_else(|| core::cmp::min(max::PCLK1_MAX, hclk));
let (ppre1_bits, ppre1) = match (hclk + pclk1 - 1) / pclk1 {
0 => unreachable!(),
1 => (0b000, 1),
@ -136,14 +138,12 @@ impl<'d> Rcc<'d> {
unsafe {
RCC.cr().modify(|w| w.set_pllon(true));
if hclk > 168_000_000 {
peripherals::PWR::enable();
if hclk > max::HCLK_OVERDRIVE_FREQUENCY {
PWR.cr1().modify(|w| w.set_oden(true));
while !PWR.csr1().read().odrdy() {}
PWR.cr().modify(|w| w.set_oden(true));
while !PWR.csr().read().odrdy() {}
PWR.cr().modify(|w| w.set_odswen(true));
while !PWR.csr().read().odswrdy() {}
PWR.cr1().modify(|w| w.set_odswen(true));
while !PWR.csr1().read().odswrdy() {}
}
while !RCC.cr().read().pllrdy() {}
@ -310,23 +310,24 @@ struct PllResults {
mod max {
#[cfg(stm32f401)]
pub(crate) const SYSCLK_MAX: u32 = 84_000_000;
#[cfg(any(stm32f405, stm32f407, stm32f415, stm32f417,))]
pub(crate) const SYSCLK_MAX: u32 = 168_000_000;
#[cfg(any(stm32f410, stm32f411, stm32f412, stm32f413, stm32f423,))]
pub(crate) const SYSCLK_MAX: u32 = 100_000_000;
#[cfg(any(
stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479,
))]
pub(crate) const SYSCLK_MAX: u32 = 180_000_000;
pub(crate) const HCLK_OVERDRIVE_FREQUENCY: u32 = 168_000_000;
pub(crate) const PCLK1_MAX: u32 = PCLK2_MAX / 2;
#[cfg(any(stm32f401, stm32f410, stm32f411, stm32f412, stm32f413, stm32f423,))]
pub(crate) const PCLK2_MAX: u32 = SYSCLK_MAX;
#[cfg(not(any(stm32f401, stm32f410, stm32f411, stm32f412, stm32f413, stm32f423,)))]
pub(crate) const PCLK2_MAX: u32 = SYSCLK_MAX / 2;
pub(crate) const PCLK1_MAX: u32 = PCLK2_MAX / 2;
pub(crate) const PLL_48_CLK: u32 = 48_000_000;
pub(crate) const PLL_48_TOLERANCE: u32 = 120_000;
}

View file

@ -7,6 +7,7 @@ use embassy::util::Unborrow;
const HSI: u32 = 16_000_000;
/// Clocks configuration
#[non_exhaustive]
#[derive(Default)]
pub struct Config {
@ -46,27 +47,25 @@ impl<'d> Rcc<'d> {
use crate::pac::pwr::vals::Vos;
use crate::pac::rcc::vals::{Hpre, Hsebyp, Ppre, Sw};
let base_clock = self.config.hse.map(|hse| hse.0).unwrap_or(HSI);
let sysclk = self.config.sys_ck.map(|sys| sys.0).unwrap_or(base_clock);
let sysclk_on_pll = sysclk != base_clock;
peripherals::PWR::enable();
let pllsrcclk = self.config.hse.map(|hse| hse.0).unwrap_or(HSI);
let sysclk = self.config.sys_ck.map(|sys| sys.0).unwrap_or(pllsrcclk);
let sysclk_on_pll = sysclk != pllsrcclk;
assert!((max::SYSCLK_MIN..=max::SYSCLK_MAX).contains(&sysclk));
let plls = self.setup_pll(
base_clock,
pllsrcclk,
self.config.hse.is_some(),
if sysclk_on_pll { Some(sysclk) } else { None },
self.config.pll48,
);
if self.config.pll48 {
assert!(
// USB specification allows +-0.25%
plls.pll48clk
.map(|freq| (max::PLL_48_CLK as i32 - freq as i32).abs()
<= max::PLL_48_TOLERANCE as i32)
.unwrap_or(false)
);
let freq = unwrap!(plls.pll48clk);
assert!((max::PLL_48_CLK as i32 - freq as i32).abs() <= max::PLL_48_TOLERANCE as i32);
}
let sysclk = if sysclk_on_pll {
@ -173,11 +172,7 @@ impl<'d> Rcc<'d> {
RCC.cr().modify(|w| w.set_pllon(true));
while !RCC.cr().read().pllrdy() {}
if hclk > max::HCLK_OVERDRIVE_FREQUENCY {
peripherals::PWR::enable();
PWR.cr1().modify(|w| w.set_oden(true));
while !PWR.csr1().read().odrdy() {}
@ -222,6 +217,8 @@ impl<'d> Rcc<'d> {
ahb1: Hertz(hclk),
ahb2: Hertz(hclk),
ahb3: Hertz(hclk),
pll48: plls.pll48clk.map(Hertz),
}
}
@ -362,6 +359,7 @@ mod max {
pub(crate) const PCLK2_MIN: u32 = SYSCLK_MIN;
pub(crate) const PCLK2_MAX: u32 = SYSCLK_MAX / 2;
// USB specification allows +-0.25%
pub(crate) const PLL_48_CLK: u32 = 48_000_000;
pub(crate) const PLL_48_TOLERANCE: u32 = 120_000;
}

View file

@ -61,7 +61,7 @@ pub struct Clocks {
#[cfg(any(rcc_h7))]
pub apb4: Hertz,
#[cfg(rcc_f4)]
#[cfg(any(rcc_f4, rcc_f7))]
pub pll48: Option<Hertz>,
#[cfg(rcc_f1)]

@ -1 +1 @@
Subproject commit 27f9d6dc2c5afaa5003ce9afc06def9b16d30adb
Subproject commit 8530a19ffdcdcbc608a97b40895827d09e670eb7