mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-25 08:12:30 +00:00
Merge pull request #2521 from embassy-rs/rcc-mux
stm32: autogenerate clocks struct, enable mux for all chips.
This commit is contained in:
commit
88e7e1ceb9
@ -68,7 +68,7 @@ rand_core = "0.6.3"
|
||||
sdio-host = "0.5.0"
|
||||
critical-section = "1.1"
|
||||
#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"
|
||||
bxcan = "0.7.0"
|
||||
nb = "1.0.0"
|
||||
@ -89,7 +89,7 @@ critical-section = { version = "1.1", features = ["std"] }
|
||||
proc-macro2 = "1.0.36"
|
||||
quote = "1.0.15"
|
||||
#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]
|
||||
|
@ -461,6 +461,8 @@ fn main() {
|
||||
let force_refcount = HashSet::from(["usart"]);
|
||||
let mut refcount_statics = BTreeSet::new();
|
||||
|
||||
let mut clock_names = BTreeSet::new();
|
||||
|
||||
for p in METADATA.peripherals {
|
||||
if !singletons.contains(&p.name.to_string()) {
|
||||
continue;
|
||||
@ -492,7 +494,6 @@ fn main() {
|
||||
|
||||
let ptype = if let Some(reg) = &p.registers { reg.kind } else { "" };
|
||||
let pname = format_ident!("{}", p.name);
|
||||
let clk = format_ident!("{}", rcc.clock);
|
||||
let en_reg = format_ident!("{}", en.register);
|
||||
let set_en_field = format_ident!("set_{}", en.field);
|
||||
|
||||
@ -522,14 +523,7 @@ fn main() {
|
||||
(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>| {
|
||||
// restrict mux implementation to supported versions
|
||||
if !mux_supported {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mux = mux?;
|
||||
let fieldset = rcc_enum_map.get(mux.register)?;
|
||||
let enumm = fieldset.get(mux.field)?;
|
||||
@ -550,15 +544,9 @@ fn main() {
|
||||
.map(|v| {
|
||||
let variant_name = format_ident!("{}", v.name);
|
||||
let clock_name = format_ident!("{}", v.name.to_ascii_lowercase());
|
||||
|
||||
if v.name.starts_with("HCLK") || v.name.starts_with("PCLK") || v.name == "SYS" {
|
||||
quote! {
|
||||
#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() },
|
||||
}
|
||||
clock_names.insert(v.name.to_ascii_lowercase());
|
||||
quote! {
|
||||
#enum_name::#variant_name => unsafe { crate::rcc::get_freqs().#clock_name.unwrap() },
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
@ -569,19 +557,21 @@ fn main() {
|
||||
#[allow(unreachable_patterns)]
|
||||
match crate::pac::RCC.#fieldset_name().read().#field_name() {
|
||||
#match_arms
|
||||
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
None => quote! {
|
||||
unsafe { crate::rcc::get_freqs().#clk }
|
||||
},
|
||||
None => {
|
||||
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
|
||||
|
||||
This condition should be checked in stm32-data
|
||||
*/
|
||||
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
|
||||
.iter()
|
||||
.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.
|
||||
// These turned to be a bad idea!
|
||||
|
@ -6,7 +6,6 @@ use embassy_hal_internal::into_ref;
|
||||
use embedded_hal_02::blocking::delay::DelayUs;
|
||||
|
||||
use crate::adc::{Adc, AdcPin, Instance, SampleTime};
|
||||
use crate::rcc::get_freqs;
|
||||
use crate::time::Hertz;
|
||||
use crate::{interrupt, Peripheral};
|
||||
|
||||
@ -80,7 +79,7 @@ impl<'d, T: Instance> Adc<'d, T> {
|
||||
}
|
||||
|
||||
fn freq() -> Hertz {
|
||||
unsafe { get_freqs() }.adc.unwrap()
|
||||
T::frequency()
|
||||
}
|
||||
|
||||
pub fn sample_time_for_us(&self, us: u32) -> SampleTime {
|
||||
|
@ -102,7 +102,7 @@ impl<'d, T: Instance> Adc<'d, T> {
|
||||
}
|
||||
|
||||
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 {
|
||||
|
@ -61,8 +61,6 @@ pub(crate) mod sealed {
|
||||
fn regs() -> crate::pac::adc::Adc;
|
||||
#[cfg(not(any(adc_f1, adc_v1, adc_f3_v2, adc_f3_v1_1, adc_g0)))]
|
||||
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))]
|
||||
fn state() -> &'static State;
|
||||
}
|
||||
@ -103,11 +101,6 @@ foreach_adc!(
|
||||
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))]
|
||||
fn state() -> &'static sealed::State {
|
||||
static STATE: sealed::State = sealed::State::new();
|
||||
|
@ -13,6 +13,7 @@ use embassy_net_driver::{Capabilities, HardwareAddress, LinkState};
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
|
||||
pub use self::_version::{InterruptHandler, *};
|
||||
use crate::rcc::RccPeripheral;
|
||||
|
||||
#[allow(unused)]
|
||||
const MTU: usize = 1514;
|
||||
@ -183,7 +184,7 @@ pub(crate) mod sealed {
|
||||
}
|
||||
|
||||
/// Ethernet instance.
|
||||
pub trait Instance: sealed::Instance + Send + 'static {}
|
||||
pub trait Instance: sealed::Instance + RccPeripheral + Send + 'static {}
|
||||
|
||||
impl sealed::Instance for crate::peripherals::ETH {
|
||||
fn regs() -> crate::pac::eth::Eth {
|
||||
|
@ -20,6 +20,7 @@ use crate::pac::AFIO;
|
||||
#[cfg(any(eth_v1b, eth_v1c))]
|
||||
use crate::pac::SYSCFG;
|
||||
use crate::pac::{ETH, RCC};
|
||||
use crate::rcc::sealed::RccPeripheral;
|
||||
use crate::{interrupt, Peripheral};
|
||||
|
||||
/// 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
|
||||
|
||||
// NOTE(unsafe) We got the peripheral singleton, which means that `rcc::init` was called
|
||||
let hclk = unsafe { crate::rcc::get_freqs() }.hclk1;
|
||||
let hclk = <T as RccPeripheral>::frequency();
|
||||
let hclk_mhz = hclk.0 / 1_000_000;
|
||||
|
||||
// Set the MDC clock frequency in the range 1MHz - 2.5MHz
|
||||
|
@ -11,6 +11,7 @@ use crate::gpio::sealed::{AFType, Pin as _};
|
||||
use crate::gpio::{AnyPin, Speed};
|
||||
use crate::interrupt::InterruptExt;
|
||||
use crate::pac::ETH;
|
||||
use crate::rcc::sealed::RccPeripheral;
|
||||
use crate::{interrupt, Peripheral};
|
||||
|
||||
/// Interrupt handler.
|
||||
@ -264,8 +265,7 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
|
||||
w.set_rbsz(RX_BUFFER_SIZE as u16);
|
||||
});
|
||||
|
||||
// NOTE(unsafe) We got the peripheral singleton, which means that `rcc::init` was called
|
||||
let hclk = unsafe { crate::rcc::get_freqs() }.hclk1;
|
||||
let hclk = <T as RccPeripheral>::frequency();
|
||||
let hclk_mhz = hclk.0 / 1_000_000;
|
||||
|
||||
// Set the MDC clock frequency in the range 1MHz - 2.5MHz
|
||||
|
@ -10,8 +10,6 @@ pub use traits::Instance;
|
||||
#[allow(unused_imports)]
|
||||
use crate::gpio::sealed::{AFType, Pin};
|
||||
use crate::gpio::AnyPin;
|
||||
#[cfg(stm32f334)]
|
||||
use crate::rcc::get_freqs;
|
||||
use crate::time::Hertz;
|
||||
use crate::Peripheral;
|
||||
|
||||
@ -182,7 +180,7 @@ impl<'d, T: Instance> AdvancedPwm<'d, T> {
|
||||
T::enable_and_reset();
|
||||
|
||||
#[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
|
||||
T::regs().dllcr().modify(|w| {
|
||||
w.set_cal(true);
|
||||
|
@ -80,10 +80,12 @@ pub(crate) mod sealed {
|
||||
|
||||
fn set_master_frequency(frequency: Hertz) {
|
||||
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;
|
||||
#[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 = if Self::regs().isr().read().dllrdy() {
|
||||
@ -103,10 +105,12 @@ pub(crate) mod sealed {
|
||||
|
||||
fn set_channel_frequency(channel: usize, frequency: Hertz) {
|
||||
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;
|
||||
#[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 = if Self::regs().isr().read().dllrdy() {
|
||||
|
@ -4,7 +4,6 @@ use embassy_hal_internal::into_ref;
|
||||
use crate::gpio::sealed::{AFType, Pin as _};
|
||||
use crate::gpio::AnyPin;
|
||||
use crate::pac::spi::vals;
|
||||
use crate::rcc::get_freqs;
|
||||
use crate::spi::{Config as SpiConfig, *};
|
||||
use crate::time::Hertz;
|
||||
use crate::{Peripheral, PeripheralRef};
|
||||
@ -193,10 +192,10 @@ impl<'d, T: Instance, Tx, Rx> I2S<'d, T, Tx, Rx> {
|
||||
spi_cfg.frequency = freq;
|
||||
let spi = Spi::new_internal(peri, txdma, rxdma, spi_cfg);
|
||||
|
||||
#[cfg(all(rcc_f4, not(stm32f410)))]
|
||||
let pclk = unsafe { get_freqs() }.plli2s1_q.unwrap();
|
||||
|
||||
#[cfg(stm32f410)]
|
||||
// TODO move i2s to the new mux infra.
|
||||
//#[cfg(all(rcc_f4, not(stm32f410)))]
|
||||
//let pclk = unsafe { get_freqs() }.plli2s1_q.unwrap();
|
||||
//#[cfg(stm32f410)]
|
||||
let pclk = T::frequency();
|
||||
|
||||
let (odd, div) = compute_baud_rate(pclk, freq, config.master_clock, config.format);
|
||||
|
@ -2,7 +2,6 @@ use crate::pac::flash::vals::Latency;
|
||||
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;
|
||||
|
||||
/// HSI speed
|
||||
@ -133,13 +132,13 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
}
|
||||
};
|
||||
|
||||
set_freqs(Clocks {
|
||||
set_clocks!(
|
||||
hsi: None,
|
||||
lse: None,
|
||||
sys: sys_clk,
|
||||
hclk1: ahb_freq,
|
||||
pclk1: apb_freq,
|
||||
pclk1_tim: apb_tim_freq,
|
||||
rtc,
|
||||
});
|
||||
sys: Some(sys_clk),
|
||||
hclk1: Some(ahb_freq),
|
||||
pclk1: Some(apb_freq),
|
||||
pclk1_tim: Some(apb_tim_freq),
|
||||
rtc: rtc,
|
||||
);
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ pub use crate::pac::rcc::vals::{
|
||||
#[cfg(any(stm32f4, stm32f7))]
|
||||
use crate::pac::PWR;
|
||||
use crate::pac::{FLASH, RCC};
|
||||
use crate::rcc::{set_freqs, Clocks};
|
||||
use crate::time::Hertz;
|
||||
|
||||
// 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);
|
||||
#[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))]
|
||||
let _pllsai = init_pll(PllInstance::Pllsai, config.pllsai, &pll_input);
|
||||
let pllsai = init_pll(PllInstance::Pllsai, config.pllsai, &pll_input);
|
||||
|
||||
// Configure sysclk
|
||||
let sys = match config.sys {
|
||||
@ -257,27 +256,41 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
});
|
||||
while RCC.cfgr().read().sws() != config.sys {}
|
||||
|
||||
set_freqs(Clocks {
|
||||
sys,
|
||||
hclk1: hclk,
|
||||
hclk2: hclk,
|
||||
hclk3: hclk,
|
||||
pclk1,
|
||||
pclk2,
|
||||
pclk1_tim,
|
||||
pclk2_tim,
|
||||
rtc,
|
||||
set_clocks!(
|
||||
hsi: hsi,
|
||||
hse: hse,
|
||||
lse: None, // TODO
|
||||
lsi: None, // TODO
|
||||
sys: Some(sys),
|
||||
hclk1: Some(hclk),
|
||||
hclk2: Some(hclk),
|
||||
hclk3: Some(hclk),
|
||||
pclk1: Some(pclk1),
|
||||
pclk2: Some(pclk2),
|
||||
pclk1_tim: Some(pclk1_tim),
|
||||
pclk2_tim: Some(pclk2_tim),
|
||||
rtc: rtc,
|
||||
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))]
|
||||
pllsai1_q: _pllsai.q,
|
||||
#[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))]
|
||||
pllsai1_r: _pllsai.r,
|
||||
});
|
||||
#[cfg(any(stm32f2, all(stm32f4, not(stm32f410)), stm32f7))]
|
||||
plli2s1_p: plli2s.p,
|
||||
#[cfg(any(stm32f2, all(stm32f4, not(stm32f410)), stm32f7))]
|
||||
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 {
|
||||
|
@ -1,6 +1,5 @@
|
||||
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::{FLASH, RCC};
|
||||
use crate::time::Hertz;
|
||||
@ -160,13 +159,15 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
|
||||
let rtc = config.ls.init();
|
||||
|
||||
set_freqs(Clocks {
|
||||
sys: Hertz(real_sysclk),
|
||||
pclk1: Hertz(pclk),
|
||||
pclk2: Hertz(pclk),
|
||||
pclk1_tim: Hertz(pclk * timer_mul),
|
||||
pclk2_tim: Hertz(pclk * timer_mul),
|
||||
hclk1: Hertz(hclk),
|
||||
rtc,
|
||||
});
|
||||
set_clocks!(
|
||||
hsi: None,
|
||||
lse: None,
|
||||
sys: Some(Hertz(real_sysclk)),
|
||||
pclk1: Some(Hertz(pclk)),
|
||||
pclk2: Some(Hertz(pclk)),
|
||||
pclk1_tim: Some(Hertz(pclk * timer_mul)),
|
||||
pclk2_tim: Some(Hertz(pclk * timer_mul)),
|
||||
hclk1: Some(Hertz(hclk)),
|
||||
rtc: rtc,
|
||||
);
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
use core::convert::TryFrom;
|
||||
|
||||
use super::{set_freqs, Clocks};
|
||||
use crate::pac::flash::vals::Latency;
|
||||
use crate::pac::rcc::vals::*;
|
||||
use crate::pac::{FLASH, RCC};
|
||||
@ -179,14 +178,14 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
|
||||
let rtc = config.ls.init();
|
||||
|
||||
set_freqs(Clocks {
|
||||
sys: Hertz(real_sysclk),
|
||||
pclk1: Hertz(pclk1),
|
||||
pclk2: Hertz(pclk2),
|
||||
pclk1_tim: Hertz(pclk1 * timer_mul1),
|
||||
pclk2_tim: Hertz(pclk2 * timer_mul2),
|
||||
hclk1: Hertz(hclk),
|
||||
set_clocks!(
|
||||
sys: Some(Hertz(real_sysclk)),
|
||||
pclk1: Some(Hertz(pclk1)),
|
||||
pclk2: Some(Hertz(pclk2)),
|
||||
pclk1_tim: Some(Hertz(pclk1 * timer_mul1)),
|
||||
pclk2_tim: Some(Hertz(pclk2 * timer_mul2)),
|
||||
hclk1: Some(Hertz(hclk)),
|
||||
adc: Some(Hertz(adcclk)),
|
||||
rtc,
|
||||
});
|
||||
rtc: rtc,
|
||||
);
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ use crate::pac::flash::vals::Latency;
|
||||
pub use crate::pac::rcc::vals::Adcpres;
|
||||
use crate::pac::rcc::vals::{Hpre, Pllmul, Pllsrc, Ppre, Prediv, Sw, Usbpre};
|
||||
use crate::pac::{FLASH, RCC};
|
||||
use crate::rcc::{set_freqs, Clocks};
|
||||
use crate::time::Hertz;
|
||||
|
||||
/// HSI speed
|
||||
@ -279,13 +278,16 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
|
||||
let rtc = config.ls.init();
|
||||
|
||||
set_freqs(Clocks {
|
||||
sys: sysclk,
|
||||
pclk1: pclk1,
|
||||
pclk2: pclk2,
|
||||
pclk1_tim: pclk1 * timer_mul1,
|
||||
pclk2_tim: pclk2 * timer_mul2,
|
||||
hclk1: hclk,
|
||||
set_clocks!(
|
||||
hsi: None,
|
||||
lse: None,
|
||||
pll1_p: None,
|
||||
sys: Some(sysclk),
|
||||
pclk1: Some(pclk1),
|
||||
pclk2: Some(pclk2),
|
||||
pclk1_tim: Some(pclk1 * timer_mul1),
|
||||
pclk2_tim: Some(pclk2 * timer_mul2),
|
||||
hclk1: Some(hclk),
|
||||
#[cfg(rcc_f3)]
|
||||
adc: adc,
|
||||
#[cfg(all(rcc_f3, adc3_common))]
|
||||
@ -294,8 +296,8 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
adc34: None,
|
||||
#[cfg(stm32f334)]
|
||||
hrtim: hrtim,
|
||||
rtc,
|
||||
});
|
||||
rtc: rtc,
|
||||
);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -4,7 +4,6 @@ pub use crate::pac::rcc::vals::{
|
||||
Hpre as AHBPrescaler, Hsidiv as HSIPrescaler, Pllm, Plln, Pllp, Pllq, Pllr, Ppre as APBPrescaler,
|
||||
};
|
||||
use crate::pac::{FLASH, PWR, RCC};
|
||||
use crate::rcc::{set_freqs, Clocks};
|
||||
use crate::time::Hertz;
|
||||
|
||||
/// HSI speed
|
||||
@ -352,11 +351,11 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
#[cfg(not(any(stm32g0b1, stm32g0c1, stm32g0b0)))]
|
||||
let hsi48_freq: Option<Hertz> = None;
|
||||
|
||||
set_freqs(Clocks {
|
||||
sys: sys_clk,
|
||||
hclk1: ahb_freq,
|
||||
pclk1: apb_freq,
|
||||
pclk1_tim: apb_tim_freq,
|
||||
set_clocks!(
|
||||
sys: Some(sys_clk),
|
||||
hclk1: Some(ahb_freq),
|
||||
pclk1: Some(apb_freq),
|
||||
pclk1_tim: Some(apb_tim_freq),
|
||||
hsi: hsi_freq,
|
||||
hsi48: hsi48_freq,
|
||||
hsi_div_8: hsi_div_8_freq,
|
||||
@ -365,6 +364,6 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
lsi: lsi_freq,
|
||||
pll1_q: pll1_q_freq,
|
||||
pll1_p: pll1_p_freq,
|
||||
rtc,
|
||||
});
|
||||
rtc: rtc,
|
||||
);
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ pub use crate::pac::rcc::vals::{
|
||||
Pllp as PllP, Pllq as PllQ, Pllr as PllR, Ppre as APBPrescaler,
|
||||
};
|
||||
use crate::pac::{PWR, RCC};
|
||||
use crate::rcc::{set_freqs, Clocks};
|
||||
use crate::time::Hertz;
|
||||
|
||||
/// HSI speed
|
||||
@ -307,20 +306,20 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
|
||||
let rtc = config.ls.init();
|
||||
|
||||
set_freqs(Clocks {
|
||||
sys: sys_clk,
|
||||
hclk1: ahb_freq,
|
||||
hclk2: ahb_freq,
|
||||
hclk3: ahb_freq,
|
||||
pclk1: apb1_freq,
|
||||
pclk1_tim: apb1_tim_freq,
|
||||
pclk2: apb2_freq,
|
||||
pclk2_tim: apb2_tim_freq,
|
||||
set_clocks!(
|
||||
sys: Some(sys_clk),
|
||||
hclk1: Some(ahb_freq),
|
||||
hclk2: Some(ahb_freq),
|
||||
hclk3: Some(ahb_freq),
|
||||
pclk1: Some(apb1_freq),
|
||||
pclk1_tim: Some(apb1_tim_freq),
|
||||
pclk2: Some(apb2_freq),
|
||||
pclk2_tim: Some(apb2_tim_freq),
|
||||
adc: adc12_ck,
|
||||
adc34: adc345_ck,
|
||||
pll1_p: None,
|
||||
pll1_q: None, // TODO
|
||||
hse: None, // TODO
|
||||
rtc,
|
||||
});
|
||||
rtc: rtc,
|
||||
);
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ pub use crate::pac::rcc::vals::{
|
||||
};
|
||||
use crate::pac::rcc::vals::{Ckpersel, Pllrge, Pllvcosel, Timpre};
|
||||
use crate::pac::{FLASH, PWR, RCC};
|
||||
use crate::rcc::{set_freqs, Clocks};
|
||||
use crate::time::Hertz;
|
||||
|
||||
/// HSI speed
|
||||
@ -430,7 +429,7 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
};
|
||||
|
||||
// Configure HSI48.
|
||||
let _hsi48 = config.hsi48.map(super::init_hsi48);
|
||||
let hsi48 = config.hsi48.map(super::init_hsi48);
|
||||
|
||||
// Configure 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() {}
|
||||
}
|
||||
|
||||
set_freqs(Clocks {
|
||||
sys,
|
||||
hclk1: hclk,
|
||||
hclk2: hclk,
|
||||
hclk3: hclk,
|
||||
hclk4: hclk,
|
||||
pclk1: apb1,
|
||||
pclk2: apb2,
|
||||
pclk3: apb3,
|
||||
set_clocks!(
|
||||
sys: Some(sys),
|
||||
hclk1: Some(hclk),
|
||||
hclk2: Some(hclk),
|
||||
hclk3: Some(hclk),
|
||||
hclk4: Some(hclk),
|
||||
pclk1: Some(apb1),
|
||||
pclk2: Some(apb2),
|
||||
pclk3: Some(apb3),
|
||||
#[cfg(stm32h7)]
|
||||
pclk4: apb4,
|
||||
#[cfg(stm32h5)]
|
||||
pclk4: Hertz(1),
|
||||
pclk1_tim: apb1_tim,
|
||||
pclk2_tim: apb2_tim,
|
||||
adc,
|
||||
rtc,
|
||||
pclk4: Some(apb4),
|
||||
pclk1_tim: Some(apb1_tim),
|
||||
pclk2_tim: Some(apb2_tim),
|
||||
adc: adc,
|
||||
rtc: rtc,
|
||||
|
||||
#[cfg(any(stm32h5, stm32h7))]
|
||||
hsi: None,
|
||||
#[cfg(stm32h5)]
|
||||
hsi48: None,
|
||||
#[cfg(stm32h5)]
|
||||
lsi: None,
|
||||
#[cfg(any(stm32h5, stm32h7))]
|
||||
csi: None,
|
||||
hsi: hsi,
|
||||
hsi48: hsi48,
|
||||
csi: csi,
|
||||
hse: hse,
|
||||
|
||||
#[cfg(any(stm32h5, stm32h7))]
|
||||
lse: None,
|
||||
#[cfg(any(stm32h5, stm32h7))]
|
||||
hse: None,
|
||||
lsi: None,
|
||||
|
||||
#[cfg(any(stm32h5, stm32h7))]
|
||||
pll1_q: pll1.q,
|
||||
#[cfg(any(stm32h5, stm32h7))]
|
||||
pll2_p: pll2.p,
|
||||
#[cfg(any(stm32h5, stm32h7))]
|
||||
pll2_q: pll2.q,
|
||||
#[cfg(any(stm32h5, stm32h7))]
|
||||
pll2_r: pll2.r,
|
||||
#[cfg(any(rcc_h5, stm32h7))]
|
||||
pll3_p: pll3.p,
|
||||
@ -670,12 +657,8 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
|
||||
#[cfg(stm32h5)]
|
||||
audioclk: None,
|
||||
#[cfg(any(stm32h5, stm32h7))]
|
||||
per: None,
|
||||
|
||||
#[cfg(stm32h7)]
|
||||
rcc_pclk_d3: None,
|
||||
});
|
||||
);
|
||||
}
|
||||
|
||||
struct PllInput {
|
||||
|
@ -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::{Hpre as AHBPrescaler, Msirange as MSIRange, Ppre as APBPrescaler, Sw as ClockSrc};
|
||||
use crate::pac::{FLASH, RCC};
|
||||
use crate::rcc::{set_freqs, Clocks};
|
||||
use crate::time::Hertz;
|
||||
|
||||
/// HSI speed
|
||||
@ -262,7 +261,7 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
#[cfg(any(stm32l4, stm32l5, stm32wb))]
|
||||
let pllsai1 = init_pll(PllInstance::Pllsai1, config.pllsai1, &pll_input);
|
||||
#[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 {
|
||||
ClockSrc::HSE => hse.unwrap(),
|
||||
@ -274,12 +273,12 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
#[cfg(any(rcc_l0_v2, stm32l4, stm32l5, stm32wb))]
|
||||
RCC.ccipr().modify(|w| w.set_clk48sel(config.clk48_src));
|
||||
#[cfg(any(rcc_l0_v2))]
|
||||
let _clk48 = match config.clk48_src {
|
||||
let clk48 = match config.clk48_src {
|
||||
Clk48Src::HSI48 => _hsi48,
|
||||
Clk48Src::PLL1_VCO_DIV_2 => pll.clk48,
|
||||
};
|
||||
#[cfg(any(stm32l4, stm32l5, stm32wb))]
|
||||
let _clk48 = match config.clk48_src {
|
||||
let clk48 = match config.clk48_src {
|
||||
Clk48Src::HSI48 => _hsi48,
|
||||
Clk48Src::MSI => msi,
|
||||
Clk48Src::PLLSAI1_Q => pllsai1.q,
|
||||
@ -376,37 +375,53 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
while !RCC.extcfgr().read().c2hpref() {}
|
||||
}
|
||||
|
||||
set_freqs(Clocks {
|
||||
sys: sys_clk,
|
||||
hclk1,
|
||||
set_clocks!(
|
||||
sys: Some(sys_clk),
|
||||
hclk1: Some(hclk1),
|
||||
#[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))]
|
||||
hclk2,
|
||||
hclk2: Some(hclk2),
|
||||
#[cfg(any(stm32l4, stm32l5, stm32wb, stm32wl))]
|
||||
hclk3,
|
||||
pclk1,
|
||||
pclk2,
|
||||
pclk1_tim,
|
||||
pclk2_tim,
|
||||
hclk3: Some(hclk3),
|
||||
pclk1: Some(pclk1),
|
||||
pclk2: Some(pclk2),
|
||||
pclk1_tim: Some(pclk1_tim),
|
||||
pclk2_tim: Some(pclk2_tim),
|
||||
#[cfg(stm32wl)]
|
||||
pclk3: hclk3,
|
||||
#[cfg(rcc_l4)]
|
||||
hsi: None,
|
||||
#[cfg(rcc_l4)]
|
||||
lse: None,
|
||||
#[cfg(rcc_l4)]
|
||||
pllsai1_p: None,
|
||||
#[cfg(rcc_l4)]
|
||||
pllsai2_p: None,
|
||||
#[cfg(rcc_l4)]
|
||||
pll1_p: None,
|
||||
#[cfg(rcc_l4)]
|
||||
pll1_q: None,
|
||||
#[cfg(rcc_l4)]
|
||||
pclk3: Some(hclk3),
|
||||
hsi: hsi,
|
||||
hse: hse,
|
||||
msi: msi,
|
||||
#[cfg(any(rcc_l0_v2, stm32l4, stm32l5, stm32wb))]
|
||||
clk48: clk48,
|
||||
|
||||
#[cfg(not(any(stm32l0, stm32l1)))]
|
||||
pll1_p: pll.p,
|
||||
#[cfg(not(any(stm32l0, stm32l1)))]
|
||||
pll1_q: pll.q,
|
||||
pll1_r: pll.r,
|
||||
|
||||
#[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,
|
||||
#[cfg(rcc_l4)]
|
||||
sai2_extclk: None,
|
||||
rtc,
|
||||
});
|
||||
lsi: None,
|
||||
lse: None,
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(any(stm32l0, stm32l1))]
|
||||
|
@ -5,8 +5,6 @@
|
||||
|
||||
use core::mem::MaybeUninit;
|
||||
|
||||
use crate::time::Hertz;
|
||||
|
||||
mod bd;
|
||||
mod mco;
|
||||
pub use bd::*;
|
||||
@ -32,162 +30,7 @@ mod _version;
|
||||
|
||||
pub use _version::*;
|
||||
|
||||
// Model Clock Configuration
|
||||
//
|
||||
// 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>,
|
||||
}
|
||||
pub use crate::_generated::Clocks;
|
||||
|
||||
#[cfg(feature = "low-power")]
|
||||
/// Must be written within a critical section
|
||||
|
@ -1,7 +1,6 @@
|
||||
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::{FLASH, PWR, RCC};
|
||||
use crate::rcc::{set_freqs, Clocks};
|
||||
use crate::time::Hertz;
|
||||
|
||||
/// 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
|
||||
// Calculate and set the flash wait states
|
||||
@ -448,18 +447,37 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
|
||||
let rtc = config.ls.init();
|
||||
|
||||
set_freqs(Clocks {
|
||||
sys: sys_clk,
|
||||
hclk1: ahb_freq,
|
||||
hclk2: ahb_freq,
|
||||
hclk3: ahb_freq,
|
||||
pclk1: apb1_freq,
|
||||
pclk2: apb2_freq,
|
||||
pclk3: apb3_freq,
|
||||
pclk1_tim: apb1_tim_freq,
|
||||
pclk2_tim: apb2_tim_freq,
|
||||
rtc,
|
||||
});
|
||||
set_clocks!(
|
||||
sys: Some(sys_clk),
|
||||
hclk1: Some(ahb_freq),
|
||||
hclk2: Some(ahb_freq),
|
||||
hclk3: Some(ahb_freq),
|
||||
pclk1: Some(apb1_freq),
|
||||
pclk2: Some(apb2_freq),
|
||||
pclk3: Some(apb3_freq),
|
||||
pclk1_tim: Some(apb1_tim_freq),
|
||||
pclk2_tim: Some(apb2_tim_freq),
|
||||
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 {
|
||||
|
@ -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,
|
||||
};
|
||||
use crate::pac::{FLASH, RCC};
|
||||
use crate::rcc::{set_freqs, Clocks};
|
||||
use crate::time::Hertz;
|
||||
|
||||
/// HSI speed
|
||||
@ -155,16 +154,23 @@ pub(crate) unsafe fn init(config: Config) {
|
||||
|
||||
RCC.ccipr3().modify(|w| w.set_adcsel(config.adc_clock_source));
|
||||
|
||||
set_freqs(Clocks {
|
||||
sys: sys_clk,
|
||||
hclk1,
|
||||
hclk2,
|
||||
hclk4,
|
||||
pclk1,
|
||||
pclk2,
|
||||
pclk7,
|
||||
pclk1_tim,
|
||||
pclk2_tim,
|
||||
rtc,
|
||||
});
|
||||
set_clocks!(
|
||||
sys: Some(sys_clk),
|
||||
hclk1: Some(hclk1),
|
||||
hclk2: Some(hclk2),
|
||||
hclk4: Some(hclk4),
|
||||
pclk1: Some(pclk1),
|
||||
pclk2: Some(pclk2),
|
||||
pclk7: Some(pclk7),
|
||||
pclk1_tim: Some(pclk1_tim),
|
||||
pclk2_tim: Some(pclk2_tim),
|
||||
rtc: rtc,
|
||||
hse: hse,
|
||||
hsi: hsi,
|
||||
|
||||
// TODO
|
||||
lse: None,
|
||||
lsi: None,
|
||||
pll1_q: None,
|
||||
);
|
||||
}
|
||||
|
@ -670,7 +670,7 @@ impl<'d, T: Instance, Dma: SdmmcDma<T> + 'd> Sdmmc<'d, T, Dma> {
|
||||
_ => 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)?;
|
||||
|
||||
// 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.
|
||||
pub async fn init_card(&mut self, freq: Hertz) -> Result<(), Error> {
|
||||
let regs = T::regs();
|
||||
let ker_ck = T::kernel_clk();
|
||||
let ker_ck = T::frequency();
|
||||
|
||||
let bus_width = match self.d3.is_some() {
|
||||
true => BusWidth::Four,
|
||||
@ -1429,7 +1429,6 @@ pub(crate) mod sealed {
|
||||
|
||||
fn regs() -> RegBlock;
|
||||
fn state() -> &'static AtomicWaker;
|
||||
fn kernel_clk() -> Hertz;
|
||||
}
|
||||
|
||||
pub trait Pins<T: Instance> {}
|
||||
@ -1461,61 +1460,6 @@ pub trait SdmmcDma<T: Instance> {}
|
||||
#[cfg(sdmmc_v2)]
|
||||
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!(
|
||||
(sdmmc, $inst:ident) => {
|
||||
impl sealed::Instance for peripherals::$inst {
|
||||
@ -1529,10 +1473,6 @@ foreach_peripheral!(
|
||||
static WAKER: ::embassy_sync::waitqueue::AtomicWaker = ::embassy_sync::waitqueue::AtomicWaker::new();
|
||||
&WAKER
|
||||
}
|
||||
|
||||
fn kernel_clk() -> Hertz {
|
||||
kernel_clk!($inst)
|
||||
}
|
||||
}
|
||||
|
||||
impl Instance for peripherals::$inst {}
|
||||
|
@ -280,7 +280,7 @@ impl<'d, T: Instance> Driver<'d, T> {
|
||||
#[cfg(time)]
|
||||
embassy_time::block_for(embassy_time::Duration::from_millis(100));
|
||||
#[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))]
|
||||
regs.btable().write(|w| w.set_btable(0));
|
||||
|
Loading…
Reference in New Issue
Block a user