Compare commits

...

14 Commits

Author SHA1 Message Date
xoviat
c8aa9c3b98 wip 2023-10-11 20:53:33 -05:00
xoviat
7810ef1c5e wip 2023-10-11 20:22:00 -05:00
xoviat
c1dc1741f6 wip 2023-10-11 20:21:32 -05:00
xoviat
6deec1b853 wip 2023-10-11 20:17:47 -05:00
xoviat
ba5b5e98fe wip 2023-10-11 20:15:43 -05:00
xoviat
158aeac438 wip 2023-10-11 20:12:13 -05:00
xoviat
f27c929cb8 wip 2023-10-11 19:59:42 -05:00
xoviat
0d0fbe957e Merge branch 'rcc-mux' of github.com:xoviat/embassy; branch 'main' of github.com:embassy-rs/embassy into rcc-mux 2023-10-11 19:58:38 -05:00
xoviat
e1a1c51d00 remove disable variant 2023-10-11 19:35:45 -05:00
xoviat
e25c7c23d0 wip 2023-10-09 20:49:44 -05:00
xoviat
4ee39f6dce Merge branch 'main' of github.com:embassy-rs/embassy into rcc-mux 2023-10-09 20:10:16 -05:00
xoviat
a4b6bc31f8 wip 2023-10-08 18:26:27 -05:00
xoviat
2ae9d28d47 wip 2023-10-07 09:34:12 -05:00
xoviat
1457b53e48 wip 2023-10-07 09:31:09 -05:00
3 changed files with 202 additions and 10 deletions

View File

@ -5,7 +5,8 @@ use std::{env, fs};
use proc_macro2::{Ident, TokenStream}; use proc_macro2::{Ident, TokenStream};
use quote::{format_ident, quote}; use quote::{format_ident, quote};
use stm32_metapac::metadata::{MemoryRegionKind, METADATA}; use stm32_metapac::metadata::ir::{BlockItemInner, Enum};
use stm32_metapac::metadata::{MemoryRegionKind, PeripheralRccRegister, METADATA};
fn main() { fn main() {
let target = env::var("TARGET").unwrap(); let target = env::var("TARGET").unwrap();
@ -387,6 +388,51 @@ fn main() {
}); });
} }
// ========
// Generate rcc fieldset and enum maps
let rcc_enum_map: HashMap<&str, HashMap<&str, &Enum>> = {
let rcc_registers = METADATA
.peripherals
.iter()
.filter_map(|p| p.registers.as_ref())
.find(|r| r.kind == "rcc")
.unwrap()
.ir;
let rcc_blocks = rcc_registers.blocks.iter().find(|b| b.name == "Rcc").unwrap().items;
let rcc_block_item_map: HashMap<&str, &str> = rcc_blocks
.iter()
.filter_map(|b| match &b.inner {
BlockItemInner::Register(register) => register.fieldset.map(|f| (f, b.name)),
_ => None,
})
.collect();
let rcc_enum_map: HashMap<&str, &Enum> = rcc_registers.enums.iter().map(|e| (e.name, e)).collect();
rcc_registers
.fieldsets
.iter()
.filter_map(|f| {
rcc_block_item_map.get(f.name).map(|b| {
(
*b,
f.fields
.iter()
.filter_map(|f| {
let enumm = f.enumm?;
let enumm = rcc_enum_map.get(enumm)?;
Some((f.name, *enumm))
})
.collect(),
)
})
})
.collect()
};
// ======== // ========
// Generate RccPeripheral impls // Generate RccPeripheral impls
@ -454,10 +500,61 @@ fn main() {
(TokenStream::new(), TokenStream::new()) (TokenStream::new(), TokenStream::new())
}; };
let mux_for = |mux: Option<&'static PeripheralRccRegister>| {
// temporary hack to restrict the scope of the implementation to h5
if !&chip_name.starts_with("stm32h5") {
return None;
}
let mux = mux?;
let fieldset = rcc_enum_map.get(mux.register)?;
let enumm = fieldset.get(mux.field)?;
Some((mux, *enumm))
};
let clock_frequency = match mux_for(rcc.mux.as_ref()) {
Some((mux, rcc_enumm)) => {
let fieldset_name = format_ident!("{}", mux.register);
let field_name = format_ident!("{}", mux.field);
let enum_name = format_ident!("{}", rcc_enumm.name);
let match_arms: TokenStream = rcc_enumm
.variants
.iter()
.filter(|v| v.name != "DISABLE")
.map(|v| {
let variant_name = format_ident!("{}", v.name);
// temporary hack to restrict the scope of the implementation until clock names can be stabilized
let clock_name = format_ident!("mux_{}", v.name.to_ascii_lowercase());
quote! {
#enum_name::#variant_name => unsafe { crate::rcc::get_freqs().#clock_name.unwrap() },
}
})
.collect();
quote! {
use crate::pac::rcc::vals::#enum_name;
#[allow(unreachable_patterns)]
match crate::pac::RCC.#fieldset_name().read().#field_name() {
#match_arms
_ => unreachable!(),
}
}
}
None => quote! {
unsafe { crate::rcc::get_freqs().#clk }
},
};
g.extend(quote! { g.extend(quote! {
impl crate::rcc::sealed::RccPeripheral for peripherals::#pname { impl crate::rcc::sealed::RccPeripheral for peripherals::#pname {
fn frequency() -> crate::time::Hertz { fn frequency() -> crate::time::Hertz {
unsafe { crate::rcc::get_freqs().#clk } #clock_frequency
} }
fn enable() { fn enable() {
critical_section::with(|_cs| { critical_section::with(|_cs| {
@ -486,12 +583,14 @@ fn main() {
} }
} }
let mut refcount_mod = TokenStream::new(); let refcount_mod: TokenStream = refcount_statics
for refcount_static in refcount_statics { .iter()
refcount_mod.extend(quote! { .map(|refcount_static| {
quote! {
pub(crate) static mut #refcount_static: u8 = 0; pub(crate) static mut #refcount_static: u8 = 0;
});
} }
})
.collect();
g.extend(quote! { g.extend(quote! {
mod refcount_statics { mod refcount_statics {

View File

@ -388,7 +388,7 @@ pub(crate) unsafe fn init(config: Config) {
let pll1 = init_pll(0, config.pll1, &pll_input); let pll1 = init_pll(0, config.pll1, &pll_input);
let pll2 = init_pll(1, config.pll2, &pll_input); let pll2 = init_pll(1, config.pll2, &pll_input);
#[cfg(any(rcc_h5, stm32h7))] #[cfg(any(rcc_h5, stm32h7))]
let _pll3 = init_pll(2, config.pll3, &pll_input); let pll3 = init_pll(2, config.pll3, &pll_input);
// Configure sysclk // Configure sysclk
let (sys, sw) = match config.sys { let (sys, sw) = match config.sys {
@ -447,7 +447,7 @@ pub(crate) unsafe fn init(config: Config) {
#[cfg(stm32h7)] #[cfg(stm32h7)]
let adc = match config.adc_clock_source { let adc = match config.adc_clock_source {
AdcClockSource::PLL2_P => pll2.p, AdcClockSource::PLL2_P => pll2.p,
AdcClockSource::PLL3_R => _pll3.r, AdcClockSource::PLL3_R => pll3.r,
AdcClockSource::PER => _per_ck, AdcClockSource::PER => _per_ck,
_ => unreachable!(), _ => unreachable!(),
}; };
@ -545,6 +545,53 @@ pub(crate) unsafe fn init(config: Config) {
apb2_tim, apb2_tim,
adc, adc,
rtc, rtc,
#[cfg(stm32h5)]
mux_rcc_pclk1: Some(apb1),
#[cfg(stm32h5)]
mux_pll2_q: None,
#[cfg(stm32h5)]
mux_pll3_q: None,
#[cfg(stm32h5)]
mux_hsi_ker: None,
#[cfg(stm32h5)]
mux_csi_ker: None,
#[cfg(stm32h5)]
mux_lse: None,
#[cfg(stm32h5)]
mux_pll1_q: pll1.q,
#[cfg(stm32h5)]
mux_pll2_p: pll2.p,
#[cfg(rcc_h5)]
mux_pll3_p: pll3.p,
#[cfg(stm32h5)]
mux_audioclk: None,
#[cfg(stm32h5)]
mux_per: None,
#[cfg(rcc_h5)]
mux_pll3_r: pll3.r,
#[cfg(all(not(rcc_h5), stm32h5))]
mux_pll3_r: None,
#[cfg(stm32h5)]
mux_rcc_pclk3: Some(apb3),
#[cfg(stm32h5)]
mux_pll3_1: None,
#[cfg(stm32h5)]
mux_hsi48_ker: None,
#[cfg(stm32h5)]
mux_lsi_ker: None,
#[cfg(stm32h5)]
mux_pll2_r: pll2.r,
#[cfg(stm32h5)]
mux_rcc_pclk2: Some(apb2),
#[cfg(stm32h5)]
mux_rcc_pclk4: None,
#[cfg(stm32h5)]
mux_hse: hse,
#[cfg(stm32h5)]
mux_hsi48: None,
}); });
} }

View File

@ -134,6 +134,52 @@ pub struct Clocks {
pub hrtim: Option<Hertz>, pub hrtim: Option<Hertz>,
pub rtc: Option<Hertz>, pub rtc: Option<Hertz>,
#[cfg(stm32h5)]
pub mux_rcc_pclk1: Option<Hertz>,
#[cfg(stm32h5)]
pub mux_pll2_q: Option<Hertz>,
#[cfg(stm32h5)]
pub mux_pll3_q: Option<Hertz>,
#[cfg(stm32h5)]
pub mux_hsi_ker: Option<Hertz>,
#[cfg(stm32h5)]
pub mux_csi_ker: Option<Hertz>,
#[cfg(stm32h5)]
pub mux_lse: Option<Hertz>,
#[cfg(stm32h5)]
pub mux_pll1_q: Option<Hertz>,
#[cfg(stm32h5)]
pub mux_pll2_p: Option<Hertz>,
#[cfg(rcc_h5)]
pub mux_pll3_p: Option<Hertz>,
#[cfg(stm32h5)]
pub mux_audioclk: Option<Hertz>,
#[cfg(stm32h5)]
pub mux_per: Option<Hertz>,
#[cfg(stm32h5)]
pub mux_pll3_r: Option<Hertz>,
#[cfg(stm32h5)]
pub mux_rcc_pclk3: Option<Hertz>,
#[cfg(stm32h5)]
pub mux_pll3_1: Option<Hertz>,
#[cfg(stm32h5)]
pub mux_hsi48_ker: Option<Hertz>,
#[cfg(stm32h5)]
pub mux_lsi_ker: Option<Hertz>,
#[cfg(stm32h5)]
pub mux_pll2_r: Option<Hertz>,
#[cfg(stm32h5)]
pub mux_rcc_pclk2: Option<Hertz>,
#[cfg(stm32h5)]
pub mux_rcc_pclk4: Option<Hertz>,
#[cfg(stm32h5)]
pub mux_hse: Option<Hertz>,
#[cfg(stm32h5)]
pub mux_hsi48: Option<Hertz>,
} }
#[cfg(feature = "low-power")] #[cfg(feature = "low-power")]