aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/build.rs115
-rw-r--r--embassy-stm32/src/rcc/h.rs51
-rw-r--r--embassy-stm32/src/rcc/mod.rs46
3 files changed, 202 insertions, 10 deletions
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index fa10b7f77..5b6b22ea1 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -5,7 +5,8 @@ use std::{env, fs};
5 5
6use proc_macro2::{Ident, TokenStream}; 6use proc_macro2::{Ident, TokenStream};
7use quote::{format_ident, quote}; 7use quote::{format_ident, quote};
8use stm32_metapac::metadata::{MemoryRegionKind, METADATA}; 8use stm32_metapac::metadata::ir::{BlockItemInner, Enum};
9use stm32_metapac::metadata::{MemoryRegionKind, PeripheralRccRegister, METADATA};
9 10
10fn main() { 11fn main() {
11 let target = env::var("TARGET").unwrap(); 12 let target = env::var("TARGET").unwrap();
@@ -388,6 +389,51 @@ fn main() {
388 } 389 }
389 390
390 // ======== 391 // ========
392 // Generate rcc fieldset and enum maps
393 let rcc_enum_map: HashMap<&str, HashMap<&str, &Enum>> = {
394 let rcc_registers = METADATA
395 .peripherals
396 .iter()
397 .filter_map(|p| p.registers.as_ref())
398 .find(|r| r.kind == "rcc")
399 .unwrap()
400 .ir;
401
402 let rcc_blocks = rcc_registers.blocks.iter().find(|b| b.name == "Rcc").unwrap().items;
403
404 let rcc_block_item_map: HashMap<&str, &str> = rcc_blocks
405 .iter()
406 .filter_map(|b| match &b.inner {
407 BlockItemInner::Register(register) => register.fieldset.map(|f| (f, b.name)),
408 _ => None,
409 })
410 .collect();
411
412 let rcc_enum_map: HashMap<&str, &Enum> = rcc_registers.enums.iter().map(|e| (e.name, e)).collect();
413
414 rcc_registers
415 .fieldsets
416 .iter()
417 .filter_map(|f| {
418 rcc_block_item_map.get(f.name).map(|b| {
419 (
420 *b,
421 f.fields
422 .iter()
423 .filter_map(|f| {
424 let enumm = f.enumm?;
425 let enumm = rcc_enum_map.get(enumm)?;
426
427 Some((f.name, *enumm))
428 })
429 .collect(),
430 )
431 })
432 })
433 .collect()
434 };
435
436 // ========
391 // Generate RccPeripheral impls 437 // Generate RccPeripheral impls
392 438
393 let refcounted_peripherals = HashSet::from(["usart", "adc"]); 439 let refcounted_peripherals = HashSet::from(["usart", "adc"]);
@@ -454,10 +500,61 @@ fn main() {
454 (TokenStream::new(), TokenStream::new()) 500 (TokenStream::new(), TokenStream::new())
455 }; 501 };
456 502
503 let mux_for = |mux: Option<&'static PeripheralRccRegister>| {
504 // temporary hack to restrict the scope of the implementation to h5
505 if !&chip_name.starts_with("stm32h5") {
506 return None;
507 }
508
509 let mux = mux?;
510 let fieldset = rcc_enum_map.get(mux.register)?;
511 let enumm = fieldset.get(mux.field)?;
512
513 Some((mux, *enumm))
514 };
515
516 let clock_frequency = match mux_for(rcc.mux.as_ref()) {
517 Some((mux, rcc_enumm)) => {
518 let fieldset_name = format_ident!("{}", mux.register);
519 let field_name = format_ident!("{}", mux.field);
520 let enum_name = format_ident!("{}", rcc_enumm.name);
521
522 let match_arms: TokenStream = rcc_enumm
523 .variants
524 .iter()
525 .filter(|v| v.name != "DISABLE")
526 .map(|v| {
527 let variant_name = format_ident!("{}", v.name);
528
529 // temporary hack to restrict the scope of the implementation until clock names can be stabilized
530 let clock_name = format_ident!("mux_{}", v.name.to_ascii_lowercase());
531
532 quote! {
533 #enum_name::#variant_name => unsafe { crate::rcc::get_freqs().#clock_name.unwrap() },
534 }
535 })
536 .collect();
537
538 quote! {
539 use crate::pac::rcc::vals::#enum_name;
540
541 #[allow(unreachable_patterns)]
542 match crate::pac::RCC.#fieldset_name().read().#field_name() {
543 #match_arms
544
545 _ => unreachable!(),
546 }
547 }
548 }
549 None => quote! {
550 unsafe { crate::rcc::get_freqs().#clk }
551 },
552 };
553
457 g.extend(quote! { 554 g.extend(quote! {
458 impl crate::rcc::sealed::RccPeripheral for peripherals::#pname { 555 impl crate::rcc::sealed::RccPeripheral for peripherals::#pname {
459 fn frequency() -> crate::time::Hertz { 556 fn frequency() -> crate::time::Hertz {
460 unsafe { crate::rcc::get_freqs().#clk } 557 #clock_frequency
461 } 558 }
462 fn enable() { 559 fn enable() {
463 critical_section::with(|_cs| { 560 critical_section::with(|_cs| {
@@ -486,12 +583,14 @@ fn main() {
486 } 583 }
487 } 584 }
488 585
489 let mut refcount_mod = TokenStream::new(); 586 let refcount_mod: TokenStream = refcount_statics
490 for refcount_static in refcount_statics { 587 .iter()
491 refcount_mod.extend(quote! { 588 .map(|refcount_static| {
492 pub(crate) static mut #refcount_static: u8 = 0; 589 quote! {
493 }); 590 pub(crate) static mut #refcount_static: u8 = 0;
494 } 591 }
592 })
593 .collect();
495 594
496 g.extend(quote! { 595 g.extend(quote! {
497 mod refcount_statics { 596 mod refcount_statics {
diff --git a/embassy-stm32/src/rcc/h.rs b/embassy-stm32/src/rcc/h.rs
index 7236d82ff..d37dd45d4 100644
--- a/embassy-stm32/src/rcc/h.rs
+++ b/embassy-stm32/src/rcc/h.rs
@@ -388,7 +388,7 @@ pub(crate) unsafe fn init(config: Config) {
388 let pll1 = init_pll(0, config.pll1, &pll_input); 388 let pll1 = init_pll(0, config.pll1, &pll_input);
389 let pll2 = init_pll(1, config.pll2, &pll_input); 389 let pll2 = init_pll(1, config.pll2, &pll_input);
390 #[cfg(any(rcc_h5, stm32h7))] 390 #[cfg(any(rcc_h5, stm32h7))]
391 let _pll3 = init_pll(2, config.pll3, &pll_input); 391 let pll3 = init_pll(2, config.pll3, &pll_input);
392 392
393 // Configure sysclk 393 // Configure sysclk
394 let (sys, sw) = match config.sys { 394 let (sys, sw) = match config.sys {
@@ -447,7 +447,7 @@ pub(crate) unsafe fn init(config: Config) {
447 #[cfg(stm32h7)] 447 #[cfg(stm32h7)]
448 let adc = match config.adc_clock_source { 448 let adc = match config.adc_clock_source {
449 AdcClockSource::PLL2_P => pll2.p, 449 AdcClockSource::PLL2_P => pll2.p,
450 AdcClockSource::PLL3_R => _pll3.r, 450 AdcClockSource::PLL3_R => pll3.r,
451 AdcClockSource::PER => _per_ck, 451 AdcClockSource::PER => _per_ck,
452 _ => unreachable!(), 452 _ => unreachable!(),
453 }; 453 };
@@ -545,6 +545,53 @@ pub(crate) unsafe fn init(config: Config) {
545 apb2_tim, 545 apb2_tim,
546 adc, 546 adc,
547 rtc, 547 rtc,
548
549 #[cfg(stm32h5)]
550 mux_rcc_pclk1: Some(apb1),
551 #[cfg(stm32h5)]
552 mux_pll2_q: None,
553 #[cfg(stm32h5)]
554 mux_pll3_q: None,
555 #[cfg(stm32h5)]
556 mux_hsi_ker: None,
557 #[cfg(stm32h5)]
558 mux_csi_ker: None,
559 #[cfg(stm32h5)]
560 mux_lse: None,
561 #[cfg(stm32h5)]
562 mux_pll1_q: pll1.q,
563 #[cfg(stm32h5)]
564 mux_pll2_p: pll2.p,
565 #[cfg(rcc_h5)]
566 mux_pll3_p: pll3.p,
567 #[cfg(stm32h5)]
568 mux_audioclk: None,
569 #[cfg(stm32h5)]
570 mux_per: None,
571
572 #[cfg(rcc_h5)]
573 mux_pll3_r: pll3.r,
574 #[cfg(all(not(rcc_h5), stm32h5))]
575 mux_pll3_r: None,
576 #[cfg(stm32h5)]
577 mux_rcc_pclk3: Some(apb3),
578 #[cfg(stm32h5)]
579 mux_pll3_1: None,
580 #[cfg(stm32h5)]
581 mux_hsi48_ker: None,
582 #[cfg(stm32h5)]
583 mux_lsi_ker: None,
584 #[cfg(stm32h5)]
585 mux_pll2_r: pll2.r,
586 #[cfg(stm32h5)]
587 mux_rcc_pclk2: Some(apb2),
588 #[cfg(stm32h5)]
589 mux_rcc_pclk4: None,
590 #[cfg(stm32h5)]
591 mux_hse: hse,
592
593 #[cfg(stm32h5)]
594 mux_hsi48: None,
548 }); 595 });
549} 596}
550 597
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs
index abb53fd10..695d41589 100644
--- a/embassy-stm32/src/rcc/mod.rs
+++ b/embassy-stm32/src/rcc/mod.rs
@@ -134,6 +134,52 @@ pub struct Clocks {
134 pub hrtim: Option<Hertz>, 134 pub hrtim: Option<Hertz>,
135 135
136 pub rtc: Option<Hertz>, 136 pub rtc: Option<Hertz>,
137
138 #[cfg(stm32h5)]
139 pub mux_rcc_pclk1: Option<Hertz>,
140 #[cfg(stm32h5)]
141 pub mux_pll2_q: Option<Hertz>,
142 #[cfg(stm32h5)]
143 pub mux_pll3_q: Option<Hertz>,
144 #[cfg(stm32h5)]
145 pub mux_hsi_ker: Option<Hertz>,
146 #[cfg(stm32h5)]
147 pub mux_csi_ker: Option<Hertz>,
148 #[cfg(stm32h5)]
149 pub mux_lse: Option<Hertz>,
150
151 #[cfg(stm32h5)]
152 pub mux_pll1_q: Option<Hertz>,
153 #[cfg(stm32h5)]
154 pub mux_pll2_p: Option<Hertz>,
155 #[cfg(rcc_h5)]
156 pub mux_pll3_p: Option<Hertz>,
157 #[cfg(stm32h5)]
158 pub mux_audioclk: Option<Hertz>,
159 #[cfg(stm32h5)]
160 pub mux_per: Option<Hertz>,
161
162 #[cfg(stm32h5)]
163 pub mux_pll3_r: Option<Hertz>,
164 #[cfg(stm32h5)]
165 pub mux_rcc_pclk3: Option<Hertz>,
166 #[cfg(stm32h5)]
167 pub mux_pll3_1: Option<Hertz>,
168 #[cfg(stm32h5)]
169 pub mux_hsi48_ker: Option<Hertz>,
170 #[cfg(stm32h5)]
171 pub mux_lsi_ker: Option<Hertz>,
172 #[cfg(stm32h5)]
173 pub mux_pll2_r: Option<Hertz>,
174 #[cfg(stm32h5)]
175 pub mux_rcc_pclk2: Option<Hertz>,
176 #[cfg(stm32h5)]
177 pub mux_rcc_pclk4: Option<Hertz>,
178 #[cfg(stm32h5)]
179 pub mux_hse: Option<Hertz>,
180
181 #[cfg(stm32h5)]
182 pub mux_hsi48: Option<Hertz>,
137} 183}
138 184
139#[cfg(feature = "low-power")] 185#[cfg(feature = "low-power")]