stm32: add initial rcc mux for h5
This commit is contained in:
		@@ -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 {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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")]
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user