Merge pull request #2618 from barnabywalters/g4rcc

[embassy-stm32] G4 RCC refactor amendments and additions
This commit is contained in:
Dario Nieuwenhuis 2024-02-23 13:05:01 +00:00 committed by GitHub
commit f77d59500e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -176,7 +176,7 @@ pub(crate) unsafe fn init(config: Config) {
_ => unreachable!(), _ => unreachable!(),
}; };
// TODO: check PLL input, internal and output frequencies for validity assert!(max::PLL_IN.contains(&src_freq));
// Disable PLL before configuration // Disable PLL before configuration
RCC.cr().modify(|w| w.set_pllon(false)); RCC.cr().modify(|w| w.set_pllon(false));
@ -184,6 +184,8 @@ pub(crate) unsafe fn init(config: Config) {
let internal_freq = src_freq / pll_config.prediv * pll_config.mul; let internal_freq = src_freq / pll_config.prediv * pll_config.mul;
assert!(max::PLL_VCO.contains(&internal_freq));
RCC.pllcfgr().write(|w| { RCC.pllcfgr().write(|w| {
w.set_plln(pll_config.mul); w.set_plln(pll_config.mul);
w.set_pllm(pll_config.prediv); w.set_pllm(pll_config.prediv);
@ -195,7 +197,9 @@ pub(crate) unsafe fn init(config: Config) {
w.set_pllp(div_p); w.set_pllp(div_p);
w.set_pllpen(true); w.set_pllpen(true);
}); });
internal_freq / div_p let freq = internal_freq / div_p;
assert!(max::PCLK.contains(&freq));
freq
}); });
let pll_q_freq = pll_config.divq.map(|div_q| { let pll_q_freq = pll_config.divq.map(|div_q| {
@ -203,7 +207,9 @@ pub(crate) unsafe fn init(config: Config) {
w.set_pllq(div_q); w.set_pllq(div_q);
w.set_pllqen(true); w.set_pllqen(true);
}); });
internal_freq / div_q let freq = internal_freq / div_q;
assert!(max::PCLK.contains(&freq));
freq
}); });
let pll_r_freq = pll_config.divr.map(|div_r| { let pll_r_freq = pll_config.divr.map(|div_r| {
@ -211,7 +217,9 @@ pub(crate) unsafe fn init(config: Config) {
w.set_pllr(div_r); w.set_pllr(div_r);
w.set_pllren(true); w.set_pllren(true);
}); });
internal_freq / div_r let freq = internal_freq / div_r;
assert!(max::PCLK.contains(&freq));
freq
}); });
// Enable the PLL // Enable the PLL
@ -234,7 +242,7 @@ pub(crate) unsafe fn init(config: Config) {
let freq = pll_freq.as_ref().unwrap().pll_r.unwrap().0; let freq = pll_freq.as_ref().unwrap().pll_r.unwrap().0;
assert!(freq <= 170_000_000); assert!(max::SYSCLK.contains(&Hertz(freq)));
(Hertz(freq), Sw::PLL1_R) (Hertz(freq), Sw::PLL1_R)
} }
@ -244,6 +252,8 @@ pub(crate) unsafe fn init(config: Config) {
// Calculate the AHB frequency (HCLK), among other things so we can calculate the correct flash read latency. // Calculate the AHB frequency (HCLK), among other things so we can calculate the correct flash read latency.
let hclk = sys_clk / config.ahb_pre; let hclk = sys_clk / config.ahb_pre;
assert!(max::HCLK.contains(&hclk));
// Configure Core Boost mode ([RM0440] p234 inverted because setting r1mode to 0 enables boost mode!) // Configure Core Boost mode ([RM0440] p234 inverted because setting r1mode to 0 enables boost mode!)
if config.boost { if config.boost {
// RM0440 p235 // RM0440 p235
@ -346,32 +356,40 @@ pub(crate) unsafe fn init(config: Config) {
adc: adc12_ck, adc: adc12_ck,
adc34: adc345_ck, adc34: adc345_ck,
pll1_p: pll_freq.as_ref().and_then(|pll| pll.pll_p), pll1_p: pll_freq.as_ref().and_then(|pll| pll.pll_p),
pll1_q: pll_freq.as_ref().and_then(|pll| pll.pll_p), pll1_q: pll_freq.as_ref().and_then(|pll| pll.pll_q),
pll1_r: pll_freq.as_ref().and_then(|pll| pll.pll_r),
hse: hse, hse: hse,
rtc: rtc, rtc: rtc,
); );
} }
// TODO: if necessary, make more of these, gated behind cfg attrs /// Acceptable Frequency Ranges
/// Currently assuming voltage scaling range 1 boost mode.
/// Where not specified in the generic G4 reference manual (RM0440), values taken from the STM32G474 datasheet.
/// If acceptable ranges for other G4-family chips differ, make additional max modules gated behind cfg attrs.
mod max { mod max {
use core::ops::RangeInclusive; use core::ops::RangeInclusive;
use crate::time::Hertz; use crate::time::Hertz;
/// HSE 4-48MHz (RM0440 p280) /// HSE Frequency Range (RM0440 p280)
pub(crate) const HSE_OSC: RangeInclusive<Hertz> = Hertz(4_000_000)..=Hertz(48_000_000); pub(crate) const HSE_OSC: RangeInclusive<Hertz> = Hertz(4_000_000)..=Hertz(48_000_000);
/// External Clock ?-48MHz (RM0440 p280) /// External Clock Frequency Range (RM0440 p280)
pub(crate) const HSE_BYP: RangeInclusive<Hertz> = Hertz(0)..=Hertz(48_000_000); pub(crate) const HSE_BYP: RangeInclusive<Hertz> = Hertz(0)..=Hertz(48_000_000);
// SYSCLK ?-170MHz (RM0440 p282) /// SYSCLK Frequency Range (RM0440 p282)
//pub(crate) const SYSCLK: RangeInclusive<Hertz> = Hertz(0)..=Hertz(170_000_000); pub(crate) const SYSCLK: RangeInclusive<Hertz> = Hertz(0)..=Hertz(170_000_000);
// PLL Output frequency ?-170MHz (RM0440 p281) /// PLL Output Frequency Range (RM0440 p281, STM32G474 Datasheet p123, Table 46)
//pub(crate) const PCLK: RangeInclusive<Hertz> = Hertz(0)..=Hertz(170_000_000); pub(crate) const PCLK: RangeInclusive<Hertz> = Hertz(8)..=Hertz(170_000_000);
// Left over from f.rs, remove if not necessary /// HCLK (AHB) Clock Frequency Range (STM32G474 Datasheet)
//pub(crate) const HCLK: RangeInclusive<Hertz> = Hertz(12_500_000)..=Hertz(216_000_000); pub(crate) const HCLK: RangeInclusive<Hertz> = Hertz(0)..=Hertz(170_000_000);
//pub(crate) const PLL_IN: RangeInclusive<Hertz> = Hertz(1_000_000)..=Hertz(2_100_000);
//pub(crate) const PLL_VCO: RangeInclusive<Hertz> = Hertz(100_000_000)..=Hertz(432_000_000); /// PLL Source Frequency Range (STM32G474 Datasheet p123, Table 46)
pub(crate) const PLL_IN: RangeInclusive<Hertz> = Hertz(2_660_000)..=Hertz(16_000_000);
/// PLL VCO (internal) Frequency Range (STM32G474 Datasheet p123, Table 46)
pub(crate) const PLL_VCO: RangeInclusive<Hertz> = Hertz(96_000_000)..=Hertz(344_000_000);
} }