Compare commits
	
		
			14 Commits
		
	
	
		
			jamesmunns
			...
			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 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