Compare commits
	
		
			14 Commits
		
	
	
		
			apidoc-emb
			...
			rcc-mux
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | c8aa9c3b98 | ||
|  | 7810ef1c5e | ||
|  | c1dc1741f6 | ||
|  | 6deec1b853 | ||
|  | ba5b5e98fe | ||
|  | 158aeac438 | ||
|  | f27c929cb8 | ||
|  | 0d0fbe957e | ||
|  | e1a1c51d00 | ||
|  | e25c7c23d0 | ||
|  | 4ee39f6dce | ||
|  | a4b6bc31f8 | ||
|  | 2ae9d28d47 | ||
|  | 1457b53e48 | 
| @@ -5,7 +5,8 @@ use std::{env, fs}; | ||||
|  | ||||
| use proc_macro2::{Ident, TokenStream}; | ||||
| 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() { | ||||
|     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 | ||||
|  | ||||
| @@ -454,10 +500,61 @@ fn main() { | ||||
|                 (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! { | ||||
|                 impl crate::rcc::sealed::RccPeripheral for peripherals::#pname { | ||||
|                     fn frequency() -> crate::time::Hertz { | ||||
|                         unsafe { crate::rcc::get_freqs().#clk } | ||||
|                         #clock_frequency | ||||
|                     } | ||||
|                     fn enable() { | ||||
|                         critical_section::with(|_cs| { | ||||
| @@ -486,12 +583,14 @@ fn main() { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     let mut refcount_mod = TokenStream::new(); | ||||
|     for refcount_static in refcount_statics { | ||||
|         refcount_mod.extend(quote! { | ||||
|             pub(crate) static mut #refcount_static: u8 = 0; | ||||
|         }); | ||||
|     } | ||||
|     let refcount_mod: TokenStream = refcount_statics | ||||
|         .iter() | ||||
|         .map(|refcount_static| { | ||||
|             quote! { | ||||
|                 pub(crate) static mut #refcount_static: u8 = 0; | ||||
|             } | ||||
|         }) | ||||
|         .collect(); | ||||
|  | ||||
|     g.extend(quote! { | ||||
|         mod refcount_statics { | ||||
|   | ||||
| @@ -388,7 +388,7 @@ pub(crate) unsafe fn init(config: Config) { | ||||
|     let pll1 = init_pll(0, config.pll1, &pll_input); | ||||
|     let pll2 = init_pll(1, config.pll2, &pll_input); | ||||
|     #[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 | ||||
|     let (sys, sw) = match config.sys { | ||||
| @@ -447,7 +447,7 @@ pub(crate) unsafe fn init(config: Config) { | ||||
|     #[cfg(stm32h7)] | ||||
|     let adc = match config.adc_clock_source { | ||||
|         AdcClockSource::PLL2_P => pll2.p, | ||||
|         AdcClockSource::PLL3_R => _pll3.r, | ||||
|         AdcClockSource::PLL3_R => pll3.r, | ||||
|         AdcClockSource::PER => _per_ck, | ||||
|         _ => unreachable!(), | ||||
|     }; | ||||
| @@ -545,6 +545,53 @@ pub(crate) unsafe fn init(config: Config) { | ||||
|         apb2_tim, | ||||
|         adc, | ||||
|         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 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")] | ||||
|   | ||||
		Reference in New Issue
	
	Block a user