stm32: autogenerate clocks struct, enable mux for all chips.

This commit is contained in:
Dario Nieuwenhuis 2024-02-02 22:42:32 +01:00
parent a099084bff
commit 9866847375
25 changed files with 284 additions and 450 deletions

View file

@ -68,7 +68,7 @@ rand_core = "0.6.3"
sdio-host = "0.5.0" sdio-host = "0.5.0"
critical-section = "1.1" critical-section = "1.1"
#stm32-metapac = { version = "15" } #stm32-metapac = { version = "15" }
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-768b3e8e3199e03de0acd0d4590d06f51eebb7dd" } stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-3e3b53df78b4c90ae9c44a58b4f9f93c93a415b7" }
vcell = "0.1.3" vcell = "0.1.3"
bxcan = "0.7.0" bxcan = "0.7.0"
nb = "1.0.0" nb = "1.0.0"
@ -89,7 +89,7 @@ critical-section = { version = "1.1", features = ["std"] }
proc-macro2 = "1.0.36" proc-macro2 = "1.0.36"
quote = "1.0.15" quote = "1.0.15"
#stm32-metapac = { version = "15", default-features = false, features = ["metadata"]} #stm32-metapac = { version = "15", default-features = false, features = ["metadata"]}
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-768b3e8e3199e03de0acd0d4590d06f51eebb7dd", default-features = false, features = ["metadata"]} stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-3e3b53df78b4c90ae9c44a58b4f9f93c93a415b7", default-features = false, features = ["metadata"]}
[features] [features]

View file

@ -461,6 +461,8 @@ fn main() {
let force_refcount = HashSet::from(["usart"]); let force_refcount = HashSet::from(["usart"]);
let mut refcount_statics = BTreeSet::new(); let mut refcount_statics = BTreeSet::new();
let mut clock_names = BTreeSet::new();
for p in METADATA.peripherals { for p in METADATA.peripherals {
if !singletons.contains(&p.name.to_string()) { if !singletons.contains(&p.name.to_string()) {
continue; continue;
@ -492,7 +494,6 @@ fn main() {
let ptype = if let Some(reg) = &p.registers { reg.kind } else { "" }; let ptype = if let Some(reg) = &p.registers { reg.kind } else { "" };
let pname = format_ident!("{}", p.name); let pname = format_ident!("{}", p.name);
let clk = format_ident!("{}", rcc.clock);
let en_reg = format_ident!("{}", en.register); let en_reg = format_ident!("{}", en.register);
let set_en_field = format_ident!("set_{}", en.field); let set_en_field = format_ident!("set_{}", en.field);
@ -522,14 +523,7 @@ fn main() {
(TokenStream::new(), TokenStream::new()) (TokenStream::new(), TokenStream::new())
}; };
let mux_supported = HashSet::from(["c0", "h5", "h50", "h7", "h7ab", "h7rm0433", "g0", "g4", "l4"])
.contains(rcc_registers.version);
let mux_for = |mux: Option<&'static PeripheralRccRegister>| { let mux_for = |mux: Option<&'static PeripheralRccRegister>| {
// restrict mux implementation to supported versions
if !mux_supported {
return None;
}
let mux = mux?; let mux = mux?;
let fieldset = rcc_enum_map.get(mux.register)?; let fieldset = rcc_enum_map.get(mux.register)?;
let enumm = fieldset.get(mux.field)?; let enumm = fieldset.get(mux.field)?;
@ -550,15 +544,9 @@ fn main() {
.map(|v| { .map(|v| {
let variant_name = format_ident!("{}", v.name); let variant_name = format_ident!("{}", v.name);
let clock_name = format_ident!("{}", v.name.to_ascii_lowercase()); let clock_name = format_ident!("{}", v.name.to_ascii_lowercase());
clock_names.insert(v.name.to_ascii_lowercase());
if v.name.starts_with("HCLK") || v.name.starts_with("PCLK") || v.name == "SYS" { quote! {
quote! { #enum_name::#variant_name => unsafe { crate::rcc::get_freqs().#clock_name.unwrap() },
#enum_name::#variant_name => unsafe { crate::rcc::get_freqs().#clock_name },
}
} else {
quote! {
#enum_name::#variant_name => unsafe { crate::rcc::get_freqs().#clock_name.unwrap() },
}
} }
}) })
.collect(); .collect();
@ -569,19 +557,21 @@ fn main() {
#[allow(unreachable_patterns)] #[allow(unreachable_patterns)]
match crate::pac::RCC.#fieldset_name().read().#field_name() { match crate::pac::RCC.#fieldset_name().read().#field_name() {
#match_arms #match_arms
_ => unreachable!(), _ => unreachable!(),
} }
} }
} }
None => quote! { None => {
unsafe { crate::rcc::get_freqs().#clk } let clock_name = format_ident!("{}", rcc.clock);
}, clock_names.insert(rcc.clock.to_string());
quote! {
unsafe { crate::rcc::get_freqs().#clock_name.unwrap() }
}
}
}; };
/* /*
A refcount leak can result if the same field is shared by peripherals with different stop modes A refcount leak can result if the same field is shared by peripherals with different stop modes
This condition should be checked in stm32-data This condition should be checked in stm32-data
*/ */
let stop_refcount = match rcc.stop_mode { let stop_refcount = match rcc.stop_mode {
@ -628,6 +618,39 @@ fn main() {
} }
} }
// Generate RCC
clock_names.insert("sys".to_string());
clock_names.insert("rtc".to_string());
let clock_idents: Vec<_> = clock_names.iter().map(|n| format_ident!("{}", n)).collect();
g.extend(quote! {
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Clocks {
#(
pub #clock_idents: Option<crate::time::Hertz>,
)*
}
});
let clocks_macro = quote!(
macro_rules! set_clocks {
($($(#[$m:meta])* $k:ident: $v:expr,)*) => {
{
#[allow(unused)]
struct Temp {
$($(#[$m])* $k: Option<crate::time::Hertz>,)*
}
let all = Temp {
$($(#[$m])* $k: $v,)*
};
crate::rcc::set_freqs(crate::rcc::Clocks {
#( #clock_idents: all.#clock_idents, )*
});
}
};
}
);
let refcount_mod: TokenStream = refcount_statics let refcount_mod: TokenStream = refcount_statics
.iter() .iter()
.map(|refcount_static| { .map(|refcount_static| {
@ -1349,7 +1372,7 @@ fn main() {
} }
} }
let mut m = String::new(); let mut m = clocks_macro.to_string();
// DO NOT ADD more macros like these. // DO NOT ADD more macros like these.
// These turned to be a bad idea! // These turned to be a bad idea!

View file

@ -6,7 +6,6 @@ use embassy_hal_internal::into_ref;
use embedded_hal_02::blocking::delay::DelayUs; use embedded_hal_02::blocking::delay::DelayUs;
use crate::adc::{Adc, AdcPin, Instance, SampleTime}; use crate::adc::{Adc, AdcPin, Instance, SampleTime};
use crate::rcc::get_freqs;
use crate::time::Hertz; use crate::time::Hertz;
use crate::{interrupt, Peripheral}; use crate::{interrupt, Peripheral};
@ -80,7 +79,7 @@ impl<'d, T: Instance> Adc<'d, T> {
} }
fn freq() -> Hertz { fn freq() -> Hertz {
unsafe { get_freqs() }.adc.unwrap() T::frequency()
} }
pub fn sample_time_for_us(&self, us: u32) -> SampleTime { pub fn sample_time_for_us(&self, us: u32) -> SampleTime {

View file

@ -102,7 +102,7 @@ impl<'d, T: Instance> Adc<'d, T> {
} }
fn freq() -> Hertz { fn freq() -> Hertz {
<T as crate::adc::sealed::Instance>::frequency() <T as crate::rcc::sealed::RccPeripheral>::frequency()
} }
pub fn sample_time_for_us(&self, us: u32) -> SampleTime { pub fn sample_time_for_us(&self, us: u32) -> SampleTime {

View file

@ -61,8 +61,6 @@ pub(crate) mod sealed {
fn regs() -> crate::pac::adc::Adc; fn regs() -> crate::pac::adc::Adc;
#[cfg(not(any(adc_f1, adc_v1, adc_f3_v2, adc_f3_v1_1, adc_g0)))] #[cfg(not(any(adc_f1, adc_v1, adc_f3_v2, adc_f3_v1_1, adc_g0)))]
fn common_regs() -> crate::pac::adccommon::AdcCommon; fn common_regs() -> crate::pac::adccommon::AdcCommon;
#[cfg(adc_f3)]
fn frequency() -> crate::time::Hertz;
#[cfg(any(adc_f1, adc_f3, adc_v1, adc_f3_v1_1))] #[cfg(any(adc_f1, adc_f3, adc_v1, adc_f3_v1_1))]
fn state() -> &'static State; fn state() -> &'static State;
} }
@ -103,11 +101,6 @@ foreach_adc!(
return crate::pac::$common_inst return crate::pac::$common_inst
} }
#[cfg(adc_f3)]
fn frequency() -> crate::time::Hertz {
unsafe { crate::rcc::get_freqs() }.$clock.unwrap()
}
#[cfg(any(adc_f1, adc_f3, adc_v1, adc_f3_v1_1))] #[cfg(any(adc_f1, adc_f3, adc_v1, adc_f3_v1_1))]
fn state() -> &'static sealed::State { fn state() -> &'static sealed::State {
static STATE: sealed::State = sealed::State::new(); static STATE: sealed::State = sealed::State::new();

View file

@ -13,6 +13,7 @@ use embassy_net_driver::{Capabilities, HardwareAddress, LinkState};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
pub use self::_version::{InterruptHandler, *}; pub use self::_version::{InterruptHandler, *};
use crate::rcc::RccPeripheral;
#[allow(unused)] #[allow(unused)]
const MTU: usize = 1514; const MTU: usize = 1514;
@ -183,7 +184,7 @@ pub(crate) mod sealed {
} }
/// Ethernet instance. /// Ethernet instance.
pub trait Instance: sealed::Instance + Send + 'static {} pub trait Instance: sealed::Instance + RccPeripheral + Send + 'static {}
impl sealed::Instance for crate::peripherals::ETH { impl sealed::Instance for crate::peripherals::ETH {
fn regs() -> crate::pac::eth::Eth { fn regs() -> crate::pac::eth::Eth {

View file

@ -20,6 +20,7 @@ use crate::pac::AFIO;
#[cfg(any(eth_v1b, eth_v1c))] #[cfg(any(eth_v1b, eth_v1c))]
use crate::pac::SYSCFG; use crate::pac::SYSCFG;
use crate::pac::{ETH, RCC}; use crate::pac::{ETH, RCC};
use crate::rcc::sealed::RccPeripheral;
use crate::{interrupt, Peripheral}; use crate::{interrupt, Peripheral};
/// Interrupt handler. /// Interrupt handler.
@ -191,8 +192,7 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
// TODO MTU size setting not found for v1 ethernet, check if correct // TODO MTU size setting not found for v1 ethernet, check if correct
// NOTE(unsafe) We got the peripheral singleton, which means that `rcc::init` was called let hclk = <T as RccPeripheral>::frequency();
let hclk = unsafe { crate::rcc::get_freqs() }.hclk1;
let hclk_mhz = hclk.0 / 1_000_000; let hclk_mhz = hclk.0 / 1_000_000;
// Set the MDC clock frequency in the range 1MHz - 2.5MHz // Set the MDC clock frequency in the range 1MHz - 2.5MHz

View file

@ -11,6 +11,7 @@ use crate::gpio::sealed::{AFType, Pin as _};
use crate::gpio::{AnyPin, Speed}; use crate::gpio::{AnyPin, Speed};
use crate::interrupt::InterruptExt; use crate::interrupt::InterruptExt;
use crate::pac::ETH; use crate::pac::ETH;
use crate::rcc::sealed::RccPeripheral;
use crate::{interrupt, Peripheral}; use crate::{interrupt, Peripheral};
/// Interrupt handler. /// Interrupt handler.
@ -264,8 +265,7 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
w.set_rbsz(RX_BUFFER_SIZE as u16); w.set_rbsz(RX_BUFFER_SIZE as u16);
}); });
// NOTE(unsafe) We got the peripheral singleton, which means that `rcc::init` was called let hclk = <T as RccPeripheral>::frequency();
let hclk = unsafe { crate::rcc::get_freqs() }.hclk1;
let hclk_mhz = hclk.0 / 1_000_000; let hclk_mhz = hclk.0 / 1_000_000;
// Set the MDC clock frequency in the range 1MHz - 2.5MHz // Set the MDC clock frequency in the range 1MHz - 2.5MHz

View file

@ -10,8 +10,6 @@ pub use traits::Instance;
#[allow(unused_imports)] #[allow(unused_imports)]
use crate::gpio::sealed::{AFType, Pin}; use crate::gpio::sealed::{AFType, Pin};
use crate::gpio::AnyPin; use crate::gpio::AnyPin;
#[cfg(stm32f334)]
use crate::rcc::get_freqs;
use crate::time::Hertz; use crate::time::Hertz;
use crate::Peripheral; use crate::Peripheral;
@ -182,7 +180,7 @@ impl<'d, T: Instance> AdvancedPwm<'d, T> {
T::enable_and_reset(); T::enable_and_reset();
#[cfg(stm32f334)] #[cfg(stm32f334)]
if unsafe { get_freqs() }.hrtim.is_some() { if crate::pac::RCC.cfgr3().read().hrtim1sw() == crate::pac::rcc::vals::Timsw::PLL1_P {
// Enable and and stabilize the DLL // Enable and and stabilize the DLL
T::regs().dllcr().modify(|w| { T::regs().dllcr().modify(|w| {
w.set_cal(true); w.set_cal(true);

View file

@ -80,10 +80,12 @@ pub(crate) mod sealed {
fn set_master_frequency(frequency: Hertz) { fn set_master_frequency(frequency: Hertz) {
let f = frequency.0; let f = frequency.0;
#[cfg(not(stm32f334))]
// TODO: wire up HRTIM to the RCC mux infra.
//#[cfg(stm32f334)]
//let timer_f = unsafe { crate::rcc::get_freqs() }.hrtim.unwrap_or(Self::frequency()).0;
//#[cfg(not(stm32f334))]
let timer_f = Self::frequency().0; let timer_f = Self::frequency().0;
#[cfg(stm32f334)]
let timer_f = unsafe { crate::rcc::get_freqs() }.hrtim.unwrap_or(Self::frequency()).0;
let psc_min = (timer_f / f) / (u16::MAX as u32 / 32); let psc_min = (timer_f / f) / (u16::MAX as u32 / 32);
let psc = if Self::regs().isr().read().dllrdy() { let psc = if Self::regs().isr().read().dllrdy() {
@ -103,10 +105,12 @@ pub(crate) mod sealed {
fn set_channel_frequency(channel: usize, frequency: Hertz) { fn set_channel_frequency(channel: usize, frequency: Hertz) {
let f = frequency.0; let f = frequency.0;
#[cfg(not(stm32f334))]
// TODO: wire up HRTIM to the RCC mux infra.
//#[cfg(stm32f334)]
//let timer_f = unsafe { crate::rcc::get_freqs() }.hrtim.unwrap_or(Self::frequency()).0;
//#[cfg(not(stm32f334))]
let timer_f = Self::frequency().0; let timer_f = Self::frequency().0;
#[cfg(stm32f334)]
let timer_f = unsafe { crate::rcc::get_freqs() }.hrtim.unwrap_or(Self::frequency()).0;
let psc_min = (timer_f / f) / (u16::MAX as u32 / 32); let psc_min = (timer_f / f) / (u16::MAX as u32 / 32);
let psc = if Self::regs().isr().read().dllrdy() { let psc = if Self::regs().isr().read().dllrdy() {

View file

@ -4,7 +4,6 @@ use embassy_hal_internal::into_ref;
use crate::gpio::sealed::{AFType, Pin as _}; use crate::gpio::sealed::{AFType, Pin as _};
use crate::gpio::AnyPin; use crate::gpio::AnyPin;
use crate::pac::spi::vals; use crate::pac::spi::vals;
use crate::rcc::get_freqs;
use crate::spi::{Config as SpiConfig, *}; use crate::spi::{Config as SpiConfig, *};
use crate::time::Hertz; use crate::time::Hertz;
use crate::{Peripheral, PeripheralRef}; use crate::{Peripheral, PeripheralRef};
@ -193,10 +192,10 @@ impl<'d, T: Instance, Tx, Rx> I2S<'d, T, Tx, Rx> {
spi_cfg.frequency = freq; spi_cfg.frequency = freq;
let spi = Spi::new_internal(peri, txdma, rxdma, spi_cfg); let spi = Spi::new_internal(peri, txdma, rxdma, spi_cfg);
#[cfg(all(rcc_f4, not(stm32f410)))] // TODO move i2s to the new mux infra.
let pclk = unsafe { get_freqs() }.plli2s1_q.unwrap(); //#[cfg(all(rcc_f4, not(stm32f410)))]
//let pclk = unsafe { get_freqs() }.plli2s1_q.unwrap();
#[cfg(stm32f410)] //#[cfg(stm32f410)]
let pclk = T::frequency(); let pclk = T::frequency();
let (odd, div) = compute_baud_rate(pclk, freq, config.master_clock, config.format); let (odd, div) = compute_baud_rate(pclk, freq, config.master_clock, config.format);

View file

@ -2,7 +2,6 @@ use crate::pac::flash::vals::Latency;
use crate::pac::rcc::vals::Sw; use crate::pac::rcc::vals::Sw;
pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Hsidiv as HSIPrescaler, Ppre as APBPrescaler}; pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Hsidiv as HSIPrescaler, Ppre as APBPrescaler};
use crate::pac::{FLASH, RCC}; use crate::pac::{FLASH, RCC};
use crate::rcc::{set_freqs, Clocks};
use crate::time::Hertz; use crate::time::Hertz;
/// HSI speed /// HSI speed
@ -133,13 +132,13 @@ pub(crate) unsafe fn init(config: Config) {
} }
}; };
set_freqs(Clocks { set_clocks!(
hsi: None, hsi: None,
lse: None, lse: None,
sys: sys_clk, sys: Some(sys_clk),
hclk1: ahb_freq, hclk1: Some(ahb_freq),
pclk1: apb_freq, pclk1: Some(apb_freq),
pclk1_tim: apb_tim_freq, pclk1_tim: Some(apb_tim_freq),
rtc, rtc: rtc,
}); );
} }

View file

@ -7,7 +7,6 @@ pub use crate::pac::rcc::vals::{
#[cfg(any(stm32f4, stm32f7))] #[cfg(any(stm32f4, stm32f7))]
use crate::pac::PWR; use crate::pac::PWR;
use crate::pac::{FLASH, RCC}; use crate::pac::{FLASH, RCC};
use crate::rcc::{set_freqs, Clocks};
use crate::time::Hertz; use crate::time::Hertz;
// TODO: on some F4s, PLLM is shared between all PLLs. Enforce that. // TODO: on some F4s, PLLM is shared between all PLLs. Enforce that.
@ -183,9 +182,9 @@ pub(crate) unsafe fn init(config: Config) {
}; };
let pll = init_pll(PllInstance::Pll, config.pll, &pll_input); let pll = init_pll(PllInstance::Pll, config.pll, &pll_input);
#[cfg(any(stm32f2, all(stm32f4, not(stm32f410)), stm32f7))] #[cfg(any(stm32f2, all(stm32f4, not(stm32f410)), stm32f7))]
let _plli2s = init_pll(PllInstance::Plli2s, config.plli2s, &pll_input); let plli2s = init_pll(PllInstance::Plli2s, config.plli2s, &pll_input);
#[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))] #[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))]
let _pllsai = init_pll(PllInstance::Pllsai, config.pllsai, &pll_input); let pllsai = init_pll(PllInstance::Pllsai, config.pllsai, &pll_input);
// Configure sysclk // Configure sysclk
let sys = match config.sys { let sys = match config.sys {
@ -257,27 +256,41 @@ pub(crate) unsafe fn init(config: Config) {
}); });
while RCC.cfgr().read().sws() != config.sys {} while RCC.cfgr().read().sws() != config.sys {}
set_freqs(Clocks { set_clocks!(
sys, hsi: hsi,
hclk1: hclk, hse: hse,
hclk2: hclk, lse: None, // TODO
hclk3: hclk, lsi: None, // TODO
pclk1, sys: Some(sys),
pclk2, hclk1: Some(hclk),
pclk1_tim, hclk2: Some(hclk),
pclk2_tim, hclk3: Some(hclk),
rtc, pclk1: Some(pclk1),
pclk2: Some(pclk2),
pclk1_tim: Some(pclk1_tim),
pclk2_tim: Some(pclk2_tim),
rtc: rtc,
pll1_q: pll.q, pll1_q: pll.q,
#[cfg(all(rcc_f4, not(stm32f410)))]
plli2s1_q: _plli2s.q,
#[cfg(all(rcc_f4, not(stm32f410)))]
plli2s1_r: _plli2s.r,
#[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] #[cfg(any(stm32f2, all(stm32f4, not(stm32f410)), stm32f7))]
pllsai1_q: _pllsai.q, plli2s1_p: plli2s.p,
#[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))] #[cfg(any(stm32f2, all(stm32f4, not(stm32f410)), stm32f7))]
pllsai1_r: _pllsai.r, plli2s1_q: plli2s.q,
}); #[cfg(any(stm32f2, all(stm32f4, not(stm32f410)), stm32f7))]
plli2s1_r: plli2s.r,
#[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))]
pllsai1_p: pllsai.p,
#[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))]
pllsai1_q: pllsai.q,
#[cfg(any(stm32f446, stm32f427, stm32f437, stm32f4x9, stm32f7))]
pllsai1_r: pllsai.r,
clk48: pll.q,
hsi_hse: None,
afif: None,
);
} }
struct PllInput { struct PllInput {

View file

@ -1,6 +1,5 @@
use stm32_metapac::flash::vals::Latency; use stm32_metapac::flash::vals::Latency;
use super::{set_freqs, Clocks};
use crate::pac::rcc::vals::{Hpre, Pllmul, Pllsrc, Ppre, Sw, Usbsw}; use crate::pac::rcc::vals::{Hpre, Pllmul, Pllsrc, Ppre, Sw, Usbsw};
use crate::pac::{FLASH, RCC}; use crate::pac::{FLASH, RCC};
use crate::time::Hertz; use crate::time::Hertz;
@ -160,13 +159,15 @@ pub(crate) unsafe fn init(config: Config) {
let rtc = config.ls.init(); let rtc = config.ls.init();
set_freqs(Clocks { set_clocks!(
sys: Hertz(real_sysclk), hsi: None,
pclk1: Hertz(pclk), lse: None,
pclk2: Hertz(pclk), sys: Some(Hertz(real_sysclk)),
pclk1_tim: Hertz(pclk * timer_mul), pclk1: Some(Hertz(pclk)),
pclk2_tim: Hertz(pclk * timer_mul), pclk2: Some(Hertz(pclk)),
hclk1: Hertz(hclk), pclk1_tim: Some(Hertz(pclk * timer_mul)),
rtc, pclk2_tim: Some(Hertz(pclk * timer_mul)),
}); hclk1: Some(Hertz(hclk)),
rtc: rtc,
);
} }

View file

@ -1,6 +1,5 @@
use core::convert::TryFrom; use core::convert::TryFrom;
use super::{set_freqs, Clocks};
use crate::pac::flash::vals::Latency; use crate::pac::flash::vals::Latency;
use crate::pac::rcc::vals::*; use crate::pac::rcc::vals::*;
use crate::pac::{FLASH, RCC}; use crate::pac::{FLASH, RCC};
@ -179,14 +178,14 @@ pub(crate) unsafe fn init(config: Config) {
let rtc = config.ls.init(); let rtc = config.ls.init();
set_freqs(Clocks { set_clocks!(
sys: Hertz(real_sysclk), sys: Some(Hertz(real_sysclk)),
pclk1: Hertz(pclk1), pclk1: Some(Hertz(pclk1)),
pclk2: Hertz(pclk2), pclk2: Some(Hertz(pclk2)),
pclk1_tim: Hertz(pclk1 * timer_mul1), pclk1_tim: Some(Hertz(pclk1 * timer_mul1)),
pclk2_tim: Hertz(pclk2 * timer_mul2), pclk2_tim: Some(Hertz(pclk2 * timer_mul2)),
hclk1: Hertz(hclk), hclk1: Some(Hertz(hclk)),
adc: Some(Hertz(adcclk)), adc: Some(Hertz(adcclk)),
rtc, rtc: rtc,
}); );
} }

View file

@ -4,7 +4,6 @@ use crate::pac::flash::vals::Latency;
pub use crate::pac::rcc::vals::Adcpres; pub use crate::pac::rcc::vals::Adcpres;
use crate::pac::rcc::vals::{Hpre, Pllmul, Pllsrc, Ppre, Prediv, Sw, Usbpre}; use crate::pac::rcc::vals::{Hpre, Pllmul, Pllsrc, Ppre, Prediv, Sw, Usbpre};
use crate::pac::{FLASH, RCC}; use crate::pac::{FLASH, RCC};
use crate::rcc::{set_freqs, Clocks};
use crate::time::Hertz; use crate::time::Hertz;
/// HSI speed /// HSI speed
@ -279,13 +278,16 @@ pub(crate) unsafe fn init(config: Config) {
let rtc = config.ls.init(); let rtc = config.ls.init();
set_freqs(Clocks { set_clocks!(
sys: sysclk, hsi: None,
pclk1: pclk1, lse: None,
pclk2: pclk2, pll1_p: None,
pclk1_tim: pclk1 * timer_mul1, sys: Some(sysclk),
pclk2_tim: pclk2 * timer_mul2, pclk1: Some(pclk1),
hclk1: hclk, pclk2: Some(pclk2),
pclk1_tim: Some(pclk1 * timer_mul1),
pclk2_tim: Some(pclk2 * timer_mul2),
hclk1: Some(hclk),
#[cfg(rcc_f3)] #[cfg(rcc_f3)]
adc: adc, adc: adc,
#[cfg(all(rcc_f3, adc3_common))] #[cfg(all(rcc_f3, adc3_common))]
@ -294,8 +296,8 @@ pub(crate) unsafe fn init(config: Config) {
adc34: None, adc34: None,
#[cfg(stm32f334)] #[cfg(stm32f334)]
hrtim: hrtim, hrtim: hrtim,
rtc, rtc: rtc,
}); );
} }
#[inline] #[inline]

View file

@ -4,7 +4,6 @@ pub use crate::pac::rcc::vals::{
Hpre as AHBPrescaler, Hsidiv as HSIPrescaler, Pllm, Plln, Pllp, Pllq, Pllr, Ppre as APBPrescaler, Hpre as AHBPrescaler, Hsidiv as HSIPrescaler, Pllm, Plln, Pllp, Pllq, Pllr, Ppre as APBPrescaler,
}; };
use crate::pac::{FLASH, PWR, RCC}; use crate::pac::{FLASH, PWR, RCC};
use crate::rcc::{set_freqs, Clocks};
use crate::time::Hertz; use crate::time::Hertz;
/// HSI speed /// HSI speed
@ -352,11 +351,11 @@ pub(crate) unsafe fn init(config: Config) {
#[cfg(not(any(stm32g0b1, stm32g0c1, stm32g0b0)))] #[cfg(not(any(stm32g0b1, stm32g0c1, stm32g0b0)))]
let hsi48_freq: Option<Hertz> = None; let hsi48_freq: Option<Hertz> = None;
set_freqs(Clocks { set_clocks!(
sys: sys_clk, sys: Some(sys_clk),
hclk1: ahb_freq, hclk1: Some(ahb_freq),
pclk1: apb_freq, pclk1: Some(apb_freq),
pclk1_tim: apb_tim_freq, pclk1_tim: Some(apb_tim_freq),
hsi: hsi_freq, hsi: hsi_freq,
hsi48: hsi48_freq, hsi48: hsi48_freq,
hsi_div_8: hsi_div_8_freq, hsi_div_8: hsi_div_8_freq,
@ -365,6 +364,6 @@ pub(crate) unsafe fn init(config: Config) {
lsi: lsi_freq, lsi: lsi_freq,
pll1_q: pll1_q_freq, pll1_q: pll1_q_freq,
pll1_p: pll1_p_freq, pll1_p: pll1_p_freq,
rtc, rtc: rtc,
}); );
} }

View file

@ -7,7 +7,6 @@ pub use crate::pac::rcc::vals::{
Pllp as PllP, Pllq as PllQ, Pllr as PllR, Ppre as APBPrescaler, Pllp as PllP, Pllq as PllQ, Pllr as PllR, Ppre as APBPrescaler,
}; };
use crate::pac::{PWR, RCC}; use crate::pac::{PWR, RCC};
use crate::rcc::{set_freqs, Clocks};
use crate::time::Hertz; use crate::time::Hertz;
/// HSI speed /// HSI speed
@ -307,20 +306,20 @@ pub(crate) unsafe fn init(config: Config) {
let rtc = config.ls.init(); let rtc = config.ls.init();
set_freqs(Clocks { set_clocks!(
sys: sys_clk, sys: Some(sys_clk),
hclk1: ahb_freq, hclk1: Some(ahb_freq),
hclk2: ahb_freq, hclk2: Some(ahb_freq),
hclk3: ahb_freq, hclk3: Some(ahb_freq),
pclk1: apb1_freq, pclk1: Some(apb1_freq),
pclk1_tim: apb1_tim_freq, pclk1_tim: Some(apb1_tim_freq),
pclk2: apb2_freq, pclk2: Some(apb2_freq),
pclk2_tim: apb2_tim_freq, pclk2_tim: Some(apb2_tim_freq),
adc: adc12_ck, adc: adc12_ck,
adc34: adc345_ck, adc34: adc345_ck,
pll1_p: None, pll1_p: None,
pll1_q: None, // TODO pll1_q: None, // TODO
hse: None, // TODO hse: None, // TODO
rtc, rtc: rtc,
}); );
} }

View file

@ -12,7 +12,6 @@ pub use crate::pac::rcc::vals::{
}; };
use crate::pac::rcc::vals::{Ckpersel, Pllrge, Pllvcosel, Timpre}; use crate::pac::rcc::vals::{Ckpersel, Pllrge, Pllvcosel, Timpre};
use crate::pac::{FLASH, PWR, RCC}; use crate::pac::{FLASH, PWR, RCC};
use crate::rcc::{set_freqs, Clocks};
use crate::time::Hertz; use crate::time::Hertz;
/// HSI speed /// HSI speed
@ -430,7 +429,7 @@ pub(crate) unsafe fn init(config: Config) {
}; };
// Configure HSI48. // Configure HSI48.
let _hsi48 = config.hsi48.map(super::init_hsi48); let hsi48 = config.hsi48.map(super::init_hsi48);
// Configure CSI. // Configure CSI.
RCC.cr().modify(|w| w.set_csion(config.csi)); RCC.cr().modify(|w| w.set_csion(config.csi));
@ -614,45 +613,33 @@ pub(crate) unsafe fn init(config: Config) {
while !pac::SYSCFG.cccsr().read().ready() {} while !pac::SYSCFG.cccsr().read().ready() {}
} }
set_freqs(Clocks { set_clocks!(
sys, sys: Some(sys),
hclk1: hclk, hclk1: Some(hclk),
hclk2: hclk, hclk2: Some(hclk),
hclk3: hclk, hclk3: Some(hclk),
hclk4: hclk, hclk4: Some(hclk),
pclk1: apb1, pclk1: Some(apb1),
pclk2: apb2, pclk2: Some(apb2),
pclk3: apb3, pclk3: Some(apb3),
#[cfg(stm32h7)] #[cfg(stm32h7)]
pclk4: apb4, pclk4: Some(apb4),
#[cfg(stm32h5)] pclk1_tim: Some(apb1_tim),
pclk4: Hertz(1), pclk2_tim: Some(apb2_tim),
pclk1_tim: apb1_tim, adc: adc,
pclk2_tim: apb2_tim, rtc: rtc,
adc,
rtc,
#[cfg(any(stm32h5, stm32h7))] hsi: hsi,
hsi: None, hsi48: hsi48,
#[cfg(stm32h5)] csi: csi,
hsi48: None, hse: hse,
#[cfg(stm32h5)]
lsi: None,
#[cfg(any(stm32h5, stm32h7))]
csi: None,
#[cfg(any(stm32h5, stm32h7))]
lse: None, lse: None,
#[cfg(any(stm32h5, stm32h7))] lsi: None,
hse: None,
#[cfg(any(stm32h5, stm32h7))]
pll1_q: pll1.q, pll1_q: pll1.q,
#[cfg(any(stm32h5, stm32h7))]
pll2_p: pll2.p, pll2_p: pll2.p,
#[cfg(any(stm32h5, stm32h7))]
pll2_q: pll2.q, pll2_q: pll2.q,
#[cfg(any(stm32h5, stm32h7))]
pll2_r: pll2.r, pll2_r: pll2.r,
#[cfg(any(rcc_h5, stm32h7))] #[cfg(any(rcc_h5, stm32h7))]
pll3_p: pll3.p, pll3_p: pll3.p,
@ -670,12 +657,8 @@ pub(crate) unsafe fn init(config: Config) {
#[cfg(stm32h5)] #[cfg(stm32h5)]
audioclk: None, audioclk: None,
#[cfg(any(stm32h5, stm32h7))]
per: None, per: None,
);
#[cfg(stm32h7)]
rcc_pclk_d3: None,
});
} }
struct PllInput { struct PllInput {

View file

@ -9,7 +9,6 @@ pub use crate::pac::rcc::vals::Clk48sel as Clk48Src;
pub use crate::pac::rcc::vals::Hsepre as HsePrescaler; pub use crate::pac::rcc::vals::Hsepre as HsePrescaler;
pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Msirange as MSIRange, Ppre as APBPrescaler, Sw as ClockSrc}; pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Msirange as MSIRange, Ppre as APBPrescaler, Sw as ClockSrc};
use crate::pac::{FLASH, RCC}; use crate::pac::{FLASH, RCC};
use crate::rcc::{set_freqs, Clocks};
use crate::time::Hertz; use crate::time::Hertz;
/// HSI speed /// HSI speed
@ -262,7 +261,7 @@ pub(crate) unsafe fn init(config: Config) {
#[cfg(any(stm32l4, stm32l5, stm32wb))] #[cfg(any(stm32l4, stm32l5, stm32wb))]
let pllsai1 = init_pll(PllInstance::Pllsai1, config.pllsai1, &pll_input); let pllsai1 = init_pll(PllInstance::Pllsai1, config.pllsai1, &pll_input);
#[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))] #[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
let _pllsai2 = init_pll(PllInstance::Pllsai2, config.pllsai2, &pll_input); let pllsai2 = init_pll(PllInstance::Pllsai2, config.pllsai2, &pll_input);
let sys_clk = match config.mux { let sys_clk = match config.mux {
ClockSrc::HSE => hse.unwrap(), ClockSrc::HSE => hse.unwrap(),
@ -274,12 +273,12 @@ pub(crate) unsafe fn init(config: Config) {
#[cfg(any(rcc_l0_v2, stm32l4, stm32l5, stm32wb))] #[cfg(any(rcc_l0_v2, stm32l4, stm32l5, stm32wb))]
RCC.ccipr().modify(|w| w.set_clk48sel(config.clk48_src)); RCC.ccipr().modify(|w| w.set_clk48sel(config.clk48_src));
#[cfg(any(rcc_l0_v2))] #[cfg(any(rcc_l0_v2))]
let _clk48 = match config.clk48_src { let clk48 = match config.clk48_src {
Clk48Src::HSI48 => _hsi48, Clk48Src::HSI48 => _hsi48,
Clk48Src::PLL1_VCO_DIV_2 => pll.clk48, Clk48Src::PLL1_VCO_DIV_2 => pll.clk48,
}; };
#[cfg(any(stm32l4, stm32l5, stm32wb))] #[cfg(any(stm32l4, stm32l5, stm32wb))]
let _clk48 = match config.clk48_src { let clk48 = match config.clk48_src {
Clk48Src::HSI48 => _hsi48, Clk48Src::HSI48 => _hsi48,
Clk48Src::MSI => msi, Clk48Src::MSI => msi,
Clk48Src::PLLSAI1_Q => pllsai1.q, Clk48Src::PLLSAI1_Q => pllsai1.q,
@ -376,37 +375,53 @@ pub(crate) unsafe fn init(config: Config) {
while !RCC.extcfgr().read().c2hpref() {} while !RCC.extcfgr().read().c2hpref() {}
} }
set_freqs(Clocks { set_clocks!(
sys: sys_clk, sys: Some(sys_clk),
hclk1, hclk1: Some(hclk1),
#[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))]
hclk2, hclk2: Some(hclk2),
#[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))] #[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))]
hclk3, hclk3: Some(hclk3),
pclk1, pclk1: Some(pclk1),
pclk2, pclk2: Some(pclk2),
pclk1_tim, pclk1_tim: Some(pclk1_tim),
pclk2_tim, pclk2_tim: Some(pclk2_tim),
#[cfg(stm32wl)] #[cfg(stm32wl)]
pclk3: hclk3, pclk3: Some(hclk3),
#[cfg(rcc_l4)] hsi: hsi,
hsi: None, hse: hse,
#[cfg(rcc_l4)] msi: msi,
lse: None, #[cfg(any(rcc_l0_v2, stm32l4, stm32l5, stm32wb))]
#[cfg(rcc_l4)] clk48: clk48,
pllsai1_p: None,
#[cfg(rcc_l4)] #[cfg(not(any(stm32l0, stm32l1)))]
pllsai2_p: None, pll1_p: pll.p,
#[cfg(rcc_l4)] #[cfg(not(any(stm32l0, stm32l1)))]
pll1_p: None, pll1_q: pll.q,
#[cfg(rcc_l4)] pll1_r: pll.r,
pll1_q: None,
#[cfg(rcc_l4)] #[cfg(any(stm32l4, stm32l5, stm32wb))]
pllsai1_p: pllsai1.p,
#[cfg(any(stm32l4, stm32l5, stm32wb))]
pllsai1_q: pllsai1.q,
#[cfg(any(stm32l4, stm32l5, stm32wb))]
pllsai1_r: pllsai1.r,
#[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
pllsai2_p: pllsai2.p,
#[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
pllsai2_q: pllsai2.q,
#[cfg(any(stm32l47x, stm32l48x, stm32l49x, stm32l4ax, rcc_l4plus, stm32l5))]
pllsai2_r: pllsai2.r,
rtc: rtc,
// TODO
sai1_extclk: None, sai1_extclk: None,
#[cfg(rcc_l4)]
sai2_extclk: None, sai2_extclk: None,
rtc, lsi: None,
}); lse: None,
);
} }
#[cfg(any(stm32l0, stm32l1))] #[cfg(any(stm32l0, stm32l1))]

View file

@ -5,8 +5,6 @@
use core::mem::MaybeUninit; use core::mem::MaybeUninit;
use crate::time::Hertz;
mod bd; mod bd;
mod mco; mod mco;
pub use bd::*; pub use bd::*;
@ -32,162 +30,7 @@ mod _version;
pub use _version::*; pub use _version::*;
// Model Clock Configuration pub use crate::_generated::Clocks;
//
// pub struct Clocks {
// hse: Option<Hertz>,
// hsi: bool,
// lse: Option<Hertz>,
// lsi: bool,
// rtc: RtcSource,
// }
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Clocks {
pub sys: Hertz,
// APB
pub pclk1: Hertz,
pub pclk1_tim: Hertz,
#[cfg(not(any(rcc_c0, rcc_g0)))]
pub pclk2: Hertz,
#[cfg(not(any(rcc_c0, rcc_g0)))]
pub pclk2_tim: Hertz,
#[cfg(any(rcc_wl5, rcc_wle, rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab, rcc_u5))]
pub pclk3: Hertz,
#[cfg(any(rcc_h7, rcc_h7rm0433, rcc_h7ab, stm32h5))]
pub pclk4: Hertz,
#[cfg(any(rcc_wba))]
pub pclk7: Hertz,
// AHB
pub hclk1: Hertz,
#[cfg(any(
rcc_l4,
rcc_l4plus,
rcc_l5,
rcc_f2,
rcc_f4,
rcc_f410,
rcc_f7,
rcc_h5,
rcc_h50,
rcc_h7,
rcc_h7rm0433,
rcc_h7ab,
rcc_g4,
rcc_u5,
rcc_wb,
rcc_wba,
rcc_wl5,
rcc_wle
))]
pub hclk2: Hertz,
#[cfg(any(
rcc_l4,
rcc_l4plus,
rcc_l5,
rcc_f2,
rcc_f4,
rcc_f410,
rcc_f7,
rcc_h5,
rcc_h50,
rcc_h7,
rcc_h7rm0433,
rcc_h7ab,
rcc_u5,
rcc_g4,
rcc_wb,
rcc_wl5,
rcc_wle
))]
pub hclk3: Hertz,
#[cfg(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab, rcc_wba))]
pub hclk4: Hertz,
#[cfg(all(rcc_f4, not(stm32f410)))]
pub plli2s1_q: Option<Hertz>,
#[cfg(all(rcc_f4, not(stm32f410)))]
pub plli2s1_r: Option<Hertz>,
#[cfg(rcc_l4)]
pub pllsai1_p: Option<Hertz>,
#[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))]
pub pllsai1_q: Option<Hertz>,
#[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))]
pub pllsai1_r: Option<Hertz>,
#[cfg(rcc_l4)]
pub pllsai2_p: Option<Hertz>,
#[cfg(any(stm32g0, stm32g4, rcc_l4))]
pub pll1_p: Option<Hertz>,
#[cfg(any(stm32h5, stm32h7, stm32f2, stm32f4, stm32f7, rcc_l4, stm32g0, stm32g4))]
pub pll1_q: Option<Hertz>,
#[cfg(any(stm32h5, stm32h7))]
pub pll2_p: Option<Hertz>,
#[cfg(any(stm32h5, stm32h7))]
pub pll2_q: Option<Hertz>,
#[cfg(any(stm32h5, stm32h7))]
pub pll2_r: Option<Hertz>,
#[cfg(any(stm32h5, stm32h7))]
pub pll3_p: Option<Hertz>,
#[cfg(any(stm32h5, stm32h7))]
pub pll3_q: Option<Hertz>,
#[cfg(any(stm32h5, stm32h7))]
pub pll3_r: Option<Hertz>,
#[cfg(any(
rcc_f1,
rcc_f100,
rcc_f1cl,
rcc_h5,
rcc_h50,
rcc_h7,
rcc_h7rm0433,
rcc_h7ab,
rcc_f3,
rcc_g4
))]
pub adc: Option<Hertz>,
#[cfg(any(rcc_f3, rcc_g4))]
pub adc34: Option<Hertz>,
#[cfg(stm32f334)]
pub hrtim: Option<Hertz>,
pub rtc: Option<Hertz>,
#[cfg(any(stm32h5, stm32h7, rcc_l4, rcc_c0, stm32g0))]
pub hsi: Option<Hertz>,
#[cfg(any(stm32h5, stm32g0))]
pub hsi48: Option<Hertz>,
#[cfg(stm32g0)]
pub hsi_div_8: Option<Hertz>,
#[cfg(any(stm32g0, stm32h5))]
pub lsi: Option<Hertz>,
#[cfg(any(stm32h5, stm32h7))]
pub csi: Option<Hertz>,
#[cfg(any(stm32h5, stm32h7, rcc_l4, rcc_c0, stm32g0))]
pub lse: Option<Hertz>,
#[cfg(any(stm32h5, stm32h7, stm32g0, stm32g4))]
pub hse: Option<Hertz>,
#[cfg(stm32h5)]
pub audioclk: Option<Hertz>,
#[cfg(any(stm32h5, stm32h7))]
pub per: Option<Hertz>,
#[cfg(stm32h7)]
pub rcc_pclk_d3: Option<Hertz>,
#[cfg(rcc_l4)]
pub sai1_extclk: Option<Hertz>,
#[cfg(rcc_l4)]
pub sai2_extclk: Option<Hertz>,
}
#[cfg(feature = "low-power")] #[cfg(feature = "low-power")]
/// Must be written within a critical section /// Must be written within a critical section

View file

@ -1,7 +1,6 @@
pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Msirange, Plldiv, Pllm, Plln, Ppre as APBPrescaler}; pub use crate::pac::rcc::vals::{Hpre as AHBPrescaler, Msirange, Plldiv, Pllm, Plln, Ppre as APBPrescaler};
use crate::pac::rcc::vals::{Msirgsel, Pllmboost, Pllrge, Pllsrc, Sw}; use crate::pac::rcc::vals::{Msirgsel, Pllmboost, Pllrge, Pllsrc, Sw};
use crate::pac::{FLASH, PWR, RCC}; use crate::pac::{FLASH, PWR, RCC};
use crate::rcc::{set_freqs, Clocks};
use crate::time::Hertz; use crate::time::Hertz;
/// HSI speed /// HSI speed
@ -338,7 +337,7 @@ pub(crate) unsafe fn init(config: Config) {
} }
}; };
let _hsi48 = config.hsi48.map(super::init_hsi48); let hsi48 = config.hsi48.map(super::init_hsi48);
// The clock source is ready // The clock source is ready
// Calculate and set the flash wait states // Calculate and set the flash wait states
@ -448,18 +447,37 @@ pub(crate) unsafe fn init(config: Config) {
let rtc = config.ls.init(); let rtc = config.ls.init();
set_freqs(Clocks { set_clocks!(
sys: sys_clk, sys: Some(sys_clk),
hclk1: ahb_freq, hclk1: Some(ahb_freq),
hclk2: ahb_freq, hclk2: Some(ahb_freq),
hclk3: ahb_freq, hclk3: Some(ahb_freq),
pclk1: apb1_freq, pclk1: Some(apb1_freq),
pclk2: apb2_freq, pclk2: Some(apb2_freq),
pclk3: apb3_freq, pclk3: Some(apb3_freq),
pclk1_tim: apb1_tim_freq, pclk1_tim: Some(apb1_tim_freq),
pclk2_tim: apb2_tim_freq, pclk2_tim: Some(apb2_tim_freq),
rtc, hsi48: hsi48,
}); rtc: rtc,
// TODO
hse: None,
hsi: None,
audioclk: None,
hsi48_div_2: None,
lse: None,
lsi: None,
msik: None,
pll1_p: None,
pll1_q: None,
pll1_r: None,
pll2_p: None,
pll2_q: None,
pll2_r: None,
pll3_p: None,
pll3_q: None,
pll3_r: None,
);
} }
fn msirange_to_hertz(range: Msirange) -> Hertz { fn msirange_to_hertz(range: Msirange) -> Hertz {

View file

@ -4,7 +4,6 @@ pub use crate::pac::rcc::vals::{
Adcsel as AdcClockSource, Hpre as AHBPrescaler, Hsepre as HsePrescaler, Ppre as APBPrescaler, Sw as ClockSrc, Adcsel as AdcClockSource, Hpre as AHBPrescaler, Hsepre as HsePrescaler, Ppre as APBPrescaler, Sw as ClockSrc,
}; };
use crate::pac::{FLASH, RCC}; use crate::pac::{FLASH, RCC};
use crate::rcc::{set_freqs, Clocks};
use crate::time::Hertz; use crate::time::Hertz;
/// HSI speed /// HSI speed
@ -155,16 +154,23 @@ pub(crate) unsafe fn init(config: Config) {
RCC.ccipr3().modify(|w| w.set_adcsel(config.adc_clock_source)); RCC.ccipr3().modify(|w| w.set_adcsel(config.adc_clock_source));
set_freqs(Clocks { set_clocks!(
sys: sys_clk, sys: Some(sys_clk),
hclk1, hclk1: Some(hclk1),
hclk2, hclk2: Some(hclk2),
hclk4, hclk4: Some(hclk4),
pclk1, pclk1: Some(pclk1),
pclk2, pclk2: Some(pclk2),
pclk7, pclk7: Some(pclk7),
pclk1_tim, pclk1_tim: Some(pclk1_tim),
pclk2_tim, pclk2_tim: Some(pclk2_tim),
rtc, rtc: rtc,
}); hse: hse,
hsi: hsi,
// TODO
lse: None,
lsi: None,
pll1_q: None,
);
} }

View file

@ -670,7 +670,7 @@ impl<'d, T: Instance, Dma: SdmmcDma<T> + 'd> Sdmmc<'d, T, Dma> {
_ => panic!("Invalid Bus Width"), _ => panic!("Invalid Bus Width"),
}; };
let ker_ck = T::kernel_clk(); let ker_ck = T::frequency();
let (_bypass, clkdiv, new_clock) = clk_div(ker_ck, freq)?; let (_bypass, clkdiv, new_clock) = clk_div(ker_ck, freq)?;
// Enforce AHB and SDMMC_CK clock relation. See RM0433 Rev 7 // Enforce AHB and SDMMC_CK clock relation. See RM0433 Rev 7
@ -1023,7 +1023,7 @@ impl<'d, T: Instance, Dma: SdmmcDma<T> + 'd> Sdmmc<'d, T, Dma> {
/// specified frequency. /// specified frequency.
pub async fn init_card(&mut self, freq: Hertz) -> Result<(), Error> { pub async fn init_card(&mut self, freq: Hertz) -> Result<(), Error> {
let regs = T::regs(); let regs = T::regs();
let ker_ck = T::kernel_clk(); let ker_ck = T::frequency();
let bus_width = match self.d3.is_some() { let bus_width = match self.d3.is_some() {
true => BusWidth::Four, true => BusWidth::Four,
@ -1429,7 +1429,6 @@ pub(crate) mod sealed {
fn regs() -> RegBlock; fn regs() -> RegBlock;
fn state() -> &'static AtomicWaker; fn state() -> &'static AtomicWaker;
fn kernel_clk() -> Hertz;
} }
pub trait Pins<T: Instance> {} pub trait Pins<T: Instance> {}
@ -1461,61 +1460,6 @@ pub trait SdmmcDma<T: Instance> {}
#[cfg(sdmmc_v2)] #[cfg(sdmmc_v2)]
impl<T: Instance> SdmmcDma<T> for NoDma {} impl<T: Instance> SdmmcDma<T> for NoDma {}
cfg_if::cfg_if! {
// TODO, these could not be implemented, because required clocks are not exposed in RCC:
// - H7 uses pll1_q_ck or pll2_r_ck depending on SDMMCSEL
// - L1 uses pll48
// - L4 uses clk48(pll48)
// - L4+, L5, U5 uses clk48(pll48) or PLLSAI3CLK(PLLP) depending on SDMMCSEL
if #[cfg(stm32f1)] {
// F1 uses AHB1(HCLK), which is correct in PAC
macro_rules! kernel_clk {
($inst:ident) => {
<peripherals::$inst as crate::rcc::sealed::RccPeripheral>::frequency()
}
}
} else if #[cfg(any(stm32f2, stm32f4))] {
// F2, F4 always use pll48
macro_rules! kernel_clk {
($inst:ident) => {
critical_section::with(|_| unsafe {
unwrap!(crate::rcc::get_freqs().pll1_q)
})
}
}
} else if #[cfg(stm32f7)] {
macro_rules! kernel_clk {
(SDMMC1) => {
critical_section::with(|_| unsafe {
let sdmmcsel = crate::pac::RCC.dckcfgr2().read().sdmmc1sel();
if sdmmcsel == crate::pac::rcc::vals::Sdmmcsel::SYS {
crate::rcc::get_freqs().sys
} else {
unwrap!(crate::rcc::get_freqs().pll1_q)
}
})
};
(SDMMC2) => {
critical_section::with(|_| unsafe {
let sdmmcsel = crate::pac::RCC.dckcfgr2().read().sdmmc2sel();
if sdmmcsel == crate::pac::rcc::vals::Sdmmcsel::SYS {
crate::rcc::get_freqs().sys
} else {
unwrap!(crate::rcc::get_freqs().pll1_q)
}
})
};
}
} else {
// Use default peripheral clock and hope it works
macro_rules! kernel_clk {
($inst:ident) => {
<peripherals::$inst as crate::rcc::sealed::RccPeripheral>::frequency()
}
}
}
}
foreach_peripheral!( foreach_peripheral!(
(sdmmc, $inst:ident) => { (sdmmc, $inst:ident) => {
impl sealed::Instance for peripherals::$inst { impl sealed::Instance for peripherals::$inst {
@ -1529,10 +1473,6 @@ foreach_peripheral!(
static WAKER: ::embassy_sync::waitqueue::AtomicWaker = ::embassy_sync::waitqueue::AtomicWaker::new(); static WAKER: ::embassy_sync::waitqueue::AtomicWaker = ::embassy_sync::waitqueue::AtomicWaker::new();
&WAKER &WAKER
} }
fn kernel_clk() -> Hertz {
kernel_clk!($inst)
}
} }
impl Instance for peripherals::$inst {} impl Instance for peripherals::$inst {}

View file

@ -280,7 +280,7 @@ impl<'d, T: Instance> Driver<'d, T> {
#[cfg(time)] #[cfg(time)]
embassy_time::block_for(embassy_time::Duration::from_millis(100)); embassy_time::block_for(embassy_time::Duration::from_millis(100));
#[cfg(not(time))] #[cfg(not(time))]
cortex_m::asm::delay(unsafe { crate::rcc::get_freqs() }.sys.0 / 10); cortex_m::asm::delay(unsafe { crate::rcc::get_freqs() }.sys.unwrap().0 / 10);
#[cfg(not(usb_v4))] #[cfg(not(usb_v4))]
regs.btable().write(|w| w.set_btable(0)); regs.btable().write(|w| w.set_btable(0));