This commit is contained in:
xoviat 2023-10-07 09:31:09 -05:00
parent 7a2b8481f7
commit 1457b53e48
3 changed files with 175 additions and 2 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::{Enum, Field};
use stm32_metapac::metadata::{MemoryRegionKind, PeripheralRccRegister, METADATA};
fn main() { fn main() {
let chip_name = match env::vars() let chip_name = match env::vars()
@ -361,6 +362,32 @@ fn main() {
}); });
} }
// ========
// Generate rcc fieldset and enum maps
let rcc_registers = METADATA
.peripherals
.iter()
.filter_map(|p| p.registers.as_ref())
.find(|r| r.kind == "rcc")
.unwrap()
.ir;
let rcc_fieldset_map: HashMap<String, HashMap<String, &Field>> = rcc_registers
.fieldsets
.iter()
.map(|f| {
(
f.name.to_ascii_uppercase(),
f.fields.iter().map(|f| (f.name.to_ascii_uppercase(), f)).collect(),
)
})
.collect();
let rcc_enum_map: HashMap<String, &Enum> = rcc_registers
.enums
.iter()
.map(|e| (e.name.to_ascii_uppercase(), e))
.collect();
// ======== // ========
// Generate RccPeripheral impls // Generate RccPeripheral impls
@ -428,10 +455,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_fieldset_map.get(mux.register)?;
let field = fieldset.get(mux.field)?;
let enum_name = field.enumm?;
let enumm = rcc_enum_map.get(enum_name.to_ascii_uppercase().as_str())?;
Some((mux, enumm))
};
let clock_frequency = match mux_for(rcc.mux.as_ref()) {
Some((mux, rcc_enumm)) => {
let fieldset_name = format_ident!("{}", mux.register.to_ascii_lowercase());
let field_name = format_ident!("{}", mux.field.to_ascii_lowercase());
let enum_name = format_ident!("{}", rcc_enumm.name);
let match_arms: TokenStream = rcc_enumm
.variants
.iter()
.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;
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(|_| { critical_section::with(|_| {

View File

@ -577,6 +577,53 @@ pub(crate) unsafe fn init(config: Config) {
rtc: rtc_clk, rtc: rtc_clk,
#[cfg(stm32h7)] #[cfg(stm32h7)]
rtc_hse: None, rtc_hse: None,
#[cfg(stm32h5)]
mux_rcc_pclk1: None,
#[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: None,
#[cfg(stm32h5)]
mux_pll2_p: None,
#[cfg(stm32h5)]
mux_pll3_p: None,
#[cfg(stm32h5)]
mux_audioclk: None,
#[cfg(stm32h5)]
mux_per: None,
#[cfg(stm32h5)]
mux_pll3_r: None,
#[cfg(stm32h5)]
mux_rcc_pclk3: None,
#[cfg(stm32h5)]
mux_pll3_1: None,
#[cfg(stm32h5)]
mux_hsi48_ker: None,
#[cfg(stm32h5)]
mux_lsi_ker: None,
#[cfg(stm32h5)]
mux_pll2_r: None,
#[cfg(stm32h5)]
mux_rcc_pclk2: None,
#[cfg(stm32h5)]
mux_rcc_pclk4: None,
#[cfg(stm32h5)]
mux_hse: None,
#[cfg(stm32h5)]
mux_disable: None,
#[cfg(stm32h5)]
mux_hsi48: None,
}); });
} }

View File

@ -141,6 +141,54 @@ pub struct Clocks {
#[cfg(any(rcc_wb, rcc_f4, rcc_f410, rcc_h7, rcc_h7rm0433, rcc_h7ab))] #[cfg(any(rcc_wb, rcc_f4, rcc_f410, rcc_h7, rcc_h7rm0433, rcc_h7ab))]
/// Set if the hse is configured, indicates stop is not supported /// Set if the hse is configured, indicates stop is not supported
pub rtc_hse: Option<Hertz>, pub rtc_hse: 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(stm32h5)]
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_disable: Option<Hertz>,
#[cfg(stm32h5)]
pub mux_hsi48: Option<Hertz>,
} }
#[cfg(feature = "low-power")] #[cfg(feature = "low-power")]