aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-05-30 11:50:40 +0000
committerGitHub <[email protected]>2024-05-30 11:50:40 +0000
commit39c5a6c3f7fe294bc7c5e6beaa0eac67399e62f9 (patch)
tree8ad437fee738bd7a76382cb5835739539618b179
parent7bc71a82623c706c294e25a7b97b385f77170e43 (diff)
parent081afca3f065dfd91e157d7c9a9477e2d914c99d (diff)
Merge pull request #3002 from honzasp/rcc-info
stm32/rcc: replace generated enable/disable code with runtime info
-rw-r--r--embassy-stm32/build.rs197
-rw-r--r--embassy-stm32/src/adc/f1.rs6
-rw-r--r--embassy-stm32/src/adc/f3.rs6
-rw-r--r--embassy-stm32/src/adc/f3_v1_1.rs6
-rw-r--r--embassy-stm32/src/adc/g4.rs4
-rw-r--r--embassy-stm32/src/adc/v1.rs6
-rw-r--r--embassy-stm32/src/adc/v2.rs6
-rw-r--r--embassy-stm32/src/adc/v3.rs4
-rw-r--r--embassy-stm32/src/adc/v4.rs4
-rw-r--r--embassy-stm32/src/can/bxcan/mod.rs6
-rw-r--r--embassy-stm32/src/can/fdcan.rs4
-rw-r--r--embassy-stm32/src/cordic/mod.rs6
-rw-r--r--embassy-stm32/src/crc/v1.rs5
-rw-r--r--embassy-stm32/src/crc/v2v3.rs5
-rw-r--r--embassy-stm32/src/cryp/mod.rs4
-rw-r--r--embassy-stm32/src/dac/mod.rs16
-rw-r--r--embassy-stm32/src/dcmi.rs4
-rw-r--r--embassy-stm32/src/dsihost.rs4
-rw-r--r--embassy-stm32/src/fmc.rs8
-rw-r--r--embassy-stm32/src/gpio.rs2
-rw-r--r--embassy-stm32/src/hash/mod.rs5
-rw-r--r--embassy-stm32/src/hrtim/mod.rs4
-rw-r--r--embassy-stm32/src/i2c/mod.rs8
-rw-r--r--embassy-stm32/src/i2c/v1.rs2
-rw-r--r--embassy-stm32/src/i2c/v2.rs2
-rw-r--r--embassy-stm32/src/ipcc.rs5
-rw-r--r--embassy-stm32/src/lib.rs7
-rw-r--r--embassy-stm32/src/ltdc.rs4
-rw-r--r--embassy-stm32/src/ospi/mod.rs6
-rw-r--r--embassy-stm32/src/qspi/mod.rs4
-rw-r--r--embassy-stm32/src/rcc/hsi48.rs4
-rw-r--r--embassy-stm32/src/rcc/mod.rs252
-rw-r--r--embassy-stm32/src/rng.rs4
-rw-r--r--embassy-stm32/src/rtc/mod.rs2
-rw-r--r--embassy-stm32/src/sai/mod.rs6
-rw-r--r--embassy-stm32/src/sdmmc/mod.rs4
-rw-r--r--embassy-stm32/src/spi/mod.rs10
-rw-r--r--embassy-stm32/src/time_driver.rs4
-rw-r--r--embassy-stm32/src/timer/low_level.rs5
-rw-r--r--embassy-stm32/src/tsc/mod.rs6
-rw-r--r--embassy-stm32/src/ucpd.rs8
-rw-r--r--embassy-stm32/src/usart/buffered.rs9
-rw-r--r--embassy-stm32/src/usart/mod.rs14
-rw-r--r--embassy-stm32/src/usb/mod.rs4
-rw-r--r--embassy-stm32/src/usb/otg.rs4
45 files changed, 380 insertions, 306 deletions
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index 7bf6ffba2..6c524ced6 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -367,9 +367,6 @@ fn main() {
367 .filter_map(|p| p.registers.as_ref()) 367 .filter_map(|p| p.registers.as_ref())
368 .find(|r| r.kind == "rcc") 368 .find(|r| r.kind == "rcc")
369 .unwrap(); 369 .unwrap();
370 for b in rcc_registers.ir.blocks {
371 eprintln!("{}", b.name);
372 }
373 let rcc_block = rcc_registers.ir.blocks.iter().find(|b| b.name == "Rcc").unwrap(); 370 let rcc_block = rcc_registers.ir.blocks.iter().find(|b| b.name == "Rcc").unwrap();
374 371
375 // ======== 372 // ========
@@ -388,7 +385,6 @@ fn main() {
388 rcc_registers: &'a PeripheralRegisters, 385 rcc_registers: &'a PeripheralRegisters,
389 chained_muxes: HashMap<&'a str, &'a PeripheralRccRegister>, 386 chained_muxes: HashMap<&'a str, &'a PeripheralRccRegister>,
390 387
391 refcount_statics: BTreeSet<Ident>,
392 clock_names: BTreeSet<String>, 388 clock_names: BTreeSet<String>,
393 muxes: BTreeSet<(Ident, Ident, Ident)>, 389 muxes: BTreeSet<(Ident, Ident, Ident)>,
394 } 390 }
@@ -397,7 +393,6 @@ fn main() {
397 rcc_registers, 393 rcc_registers,
398 chained_muxes: HashMap::new(), 394 chained_muxes: HashMap::new(),
399 395
400 refcount_statics: BTreeSet::new(),
401 clock_names: BTreeSet::new(), 396 clock_names: BTreeSet::new(),
402 muxes: BTreeSet::new(), 397 muxes: BTreeSet::new(),
403 }; 398 };
@@ -516,80 +511,64 @@ fn main() {
516 } 511 }
517 } 512 }
518 513
514 let mut refcount_idxs = HashMap::new();
515
519 for p in METADATA.peripherals { 516 for p in METADATA.peripherals {
520 if !singletons.contains(&p.name.to_string()) { 517 if !singletons.contains(&p.name.to_string()) {
521 continue; 518 continue;
522 } 519 }
523 520
524 if let Some(rcc) = &p.rcc { 521 if let Some(rcc) = &p.rcc {
525 let en = rcc.enable.as_ref().unwrap(); 522 let rst_reg = rcc.reset.as_ref();
526 523 let en_reg = rcc.enable.as_ref().unwrap();
527 let (start_rst, end_rst) = match &rcc.reset {
528 Some(rst) => {
529 let rst_reg = format_ident!("{}", rst.register.to_ascii_lowercase());
530 let set_rst_field = format_ident!("set_{}", rst.field.to_ascii_lowercase());
531 (
532 quote! {
533 crate::pac::RCC.#rst_reg().modify(|w| w.#set_rst_field(true));
534 },
535 quote! {
536 crate::pac::RCC.#rst_reg().modify(|w| w.#set_rst_field(false));
537 },
538 )
539 }
540 None => (TokenStream::new(), TokenStream::new()),
541 };
542
543 let pname = format_ident!("{}", p.name); 524 let pname = format_ident!("{}", p.name);
544 let en_reg = format_ident!("{}", en.register.to_ascii_lowercase());
545 let set_en_field = format_ident!("set_{}", en.field.to_ascii_lowercase());
546 let en_reg_offs = rcc_block
547 .items
548 .iter()
549 .find(|i| i.name.eq_ignore_ascii_case(en.register))
550 .unwrap()
551 .byte_offset;
552 let en_reg_offs: u8 = (en_reg_offs / 4).try_into().unwrap();
553
554 let en_bit_offs = &rcc_registers
555 .ir
556 .fieldsets
557 .iter()
558 .find(|i| i.name.eq_ignore_ascii_case(en.register))
559 .unwrap()
560 .fields
561 .iter()
562 .find(|i| i.name.eq_ignore_ascii_case(en.field))
563 .unwrap()
564 .bit_offset;
565 let BitOffset::Regular(en_bit_offs) = en_bit_offs else {
566 panic!("cursed bit offset")
567 };
568 let en_bit_offs: u8 = en_bit_offs.offset.try_into().unwrap();
569 525
570 let refcount = *rcc_field_count.get(&(en.register, en.field)).unwrap() > 1; 526 let get_offset_and_bit = |reg: &PeripheralRccRegister| -> TokenStream {
571 let (before_enable, before_disable) = if refcount { 527 let reg_offset = rcc_block
572 let refcount_static = 528 .items
573 format_ident!("{}_{}", en.register.to_ascii_uppercase(), en.field.to_ascii_uppercase()); 529 .iter()
530 .find(|i| i.name.eq_ignore_ascii_case(reg.register))
531 .unwrap()
532 .byte_offset;
533 let reg_offset: u8 = (reg_offset / 4).try_into().unwrap();
534
535 let bit_offset = &rcc_registers
536 .ir
537 .fieldsets
538 .iter()
539 .find(|i| i.name.eq_ignore_ascii_case(reg.register))
540 .unwrap()
541 .fields
542 .iter()
543 .find(|i| i.name.eq_ignore_ascii_case(reg.field))
544 .unwrap()
545 .bit_offset;
546 let BitOffset::Regular(bit_offset) = bit_offset else {
547 panic!("cursed bit offset")
548 };
549 let bit_offset: u8 = bit_offset.offset.try_into().unwrap();
574 550
575 clock_gen.refcount_statics.insert(refcount_static.clone()); 551 quote! { (#reg_offset, #bit_offset) }
552 };
576 553
577 ( 554 let reset_offset_and_bit = match rst_reg {
578 quote! { 555 Some(rst_reg) => {
579 unsafe { refcount_statics::#refcount_static += 1 }; 556 let reset_offset_and_bit = get_offset_and_bit(rst_reg);
580 if unsafe { refcount_statics::#refcount_static } > 1 { 557 quote! { Some(#reset_offset_and_bit) }
581 return; 558 }
582 } 559 None => quote! { None },
583 }, 560 };
584 quote! { 561 let enable_offset_and_bit = get_offset_and_bit(en_reg);
585 unsafe { refcount_statics::#refcount_static -= 1 }; 562
586 if unsafe { refcount_statics::#refcount_static } > 0 { 563 let needs_refcount = *rcc_field_count.get(&(en_reg.register, en_reg.field)).unwrap() > 1;
587 return; 564 let refcount_idx = if needs_refcount {
588 } 565 let next_refcount_idx = refcount_idxs.len() as u8;
589 }, 566 let refcount_idx = *refcount_idxs
590 ) 567 .entry((en_reg.register, en_reg.field))
568 .or_insert(next_refcount_idx);
569 quote! { Some(#refcount_idx) }
591 } else { 570 } else {
592 (TokenStream::new(), TokenStream::new()) 571 quote! { None }
593 }; 572 };
594 573
595 let clock_frequency = match &rcc.kernel_clock { 574 let clock_frequency = match &rcc.kernel_clock {
@@ -599,24 +578,10 @@ fn main() {
599 578
600 // A refcount leak can result if the same field is shared by peripherals with different stop modes 579 // A refcount leak can result if the same field is shared by peripherals with different stop modes
601 // This condition should be checked in stm32-data 580 // This condition should be checked in stm32-data
602 let stop_refcount = match rcc.stop_mode { 581 let stop_mode = match rcc.stop_mode {
603 StopMode::Standby => None, 582 StopMode::Standby => quote! { crate::rcc::StopMode::Standby },
604 StopMode::Stop2 => Some(quote! { REFCOUNT_STOP2 }), 583 StopMode::Stop2 => quote! { crate::rcc::StopMode::Stop2 },
605 StopMode::Stop1 => Some(quote! { REFCOUNT_STOP1 }), 584 StopMode::Stop1 => quote! { crate::rcc::StopMode::Stop1 },
606 };
607
608 let (incr_stop_refcount, decr_stop_refcount) = match stop_refcount {
609 Some(stop_refcount) => (
610 quote! {
611 #[cfg(feature = "low-power")]
612 unsafe { crate::rcc::#stop_refcount += 1 };
613 },
614 quote! {
615 #[cfg(feature = "low-power")]
616 unsafe { crate::rcc::#stop_refcount -= 1 };
617 },
618 ),
619 None => (TokenStream::new(), TokenStream::new()),
620 }; 585 };
621 586
622 g.extend(quote! { 587 g.extend(quote! {
@@ -624,34 +589,16 @@ fn main() {
624 fn frequency() -> crate::time::Hertz { 589 fn frequency() -> crate::time::Hertz {
625 #clock_frequency 590 #clock_frequency
626 } 591 }
627 fn enable_and_reset_with_cs(_cs: critical_section::CriticalSection) {
628 #before_enable
629 #incr_stop_refcount
630
631 #start_rst
632
633 crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(true));
634
635 // we must wait two peripheral clock cycles before the clock is active
636 // this seems to work, but might be incorrect
637 // see http://efton.sk/STM32/gotcha/g183.html
638
639 // dummy read (like in the ST HALs)
640 let _ = crate::pac::RCC.#en_reg().read();
641 592
642 // DSB for good measure 593 const RCC_INFO: crate::rcc::RccInfo = unsafe {
643 cortex_m::asm::dsb(); 594 crate::rcc::RccInfo::new(
644 595 #reset_offset_and_bit,
645 #end_rst 596 #enable_offset_and_bit,
646 } 597 #refcount_idx,
647 fn disable_with_cs(_cs: critical_section::CriticalSection) { 598 #[cfg(feature = "low-power")]
648 #before_disable 599 #stop_mode,
649 crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(false)); 600 )
650 #decr_stop_refcount 601 };
651 }
652
653 const ENABLE_BIT: crate::rcc::ClockEnableBit =
654 unsafe { crate::rcc::ClockEnableBit::new(#en_reg_offs, #en_bit_offs) };
655 } 602 }
656 603
657 impl crate::rcc::RccPeripheral for peripherals::#pname {} 604 impl crate::rcc::RccPeripheral for peripherals::#pname {}
@@ -659,6 +606,14 @@ fn main() {
659 } 606 }
660 } 607 }
661 608
609 g.extend({
610 let refcounts_len = refcount_idxs.len();
611 let refcount_zeros: TokenStream = refcount_idxs.iter().map(|_| quote! { 0u8, }).collect();
612 quote! {
613 pub(crate) static mut REFCOUNTS: [u8; #refcounts_len] = [#refcount_zeros];
614 }
615 });
616
662 let struct_fields: Vec<_> = clock_gen 617 let struct_fields: Vec<_> = clock_gen
663 .muxes 618 .muxes
664 .iter() 619 .iter()
@@ -762,22 +717,6 @@ fn main() {
762 } 717 }
763 ); 718 );
764 719
765 let refcount_mod: TokenStream = clock_gen
766 .refcount_statics
767 .iter()
768 .map(|refcount_static| {
769 quote! {
770 pub(crate) static mut #refcount_static: u8 = 0;
771 }
772 })
773 .collect();
774
775 g.extend(quote! {
776 mod refcount_statics {
777 #refcount_mod
778 }
779 });
780
781 // ======== 720 // ========
782 // Generate fns to enable GPIO, DMA in RCC 721 // Generate fns to enable GPIO, DMA in RCC
783 722
diff --git a/embassy-stm32/src/adc/f1.rs b/embassy-stm32/src/adc/f1.rs
index 3822d5032..b37ec260f 100644
--- a/embassy-stm32/src/adc/f1.rs
+++ b/embassy-stm32/src/adc/f1.rs
@@ -7,7 +7,7 @@ use embassy_hal_internal::into_ref;
7use super::blocking_delay_us; 7use super::blocking_delay_us;
8use crate::adc::{Adc, AdcChannel, Instance, SampleTime}; 8use crate::adc::{Adc, AdcChannel, Instance, SampleTime};
9use crate::time::Hertz; 9use crate::time::Hertz;
10use crate::{interrupt, Peripheral}; 10use crate::{interrupt, rcc, Peripheral};
11 11
12pub const VDDA_CALIB_MV: u32 = 3300; 12pub const VDDA_CALIB_MV: u32 = 3300;
13pub const ADC_MAX: u32 = (1 << 12) - 1; 13pub const ADC_MAX: u32 = (1 << 12) - 1;
@@ -50,7 +50,7 @@ impl<T: Instance> super::SealedAdcChannel<T> for Temperature {
50impl<'d, T: Instance> Adc<'d, T> { 50impl<'d, T: Instance> Adc<'d, T> {
51 pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self { 51 pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self {
52 into_ref!(adc); 52 into_ref!(adc);
53 T::enable_and_reset(); 53 rcc::enable_and_reset::<T>();
54 T::regs().cr2().modify(|reg| reg.set_adon(true)); 54 T::regs().cr2().modify(|reg| reg.set_adon(true));
55 55
56 // 11.4: Before starting a calibration, the ADC must have been in power-on state (ADON bit = ‘1’) 56 // 11.4: Before starting a calibration, the ADC must have been in power-on state (ADON bit = ‘1’)
@@ -169,6 +169,6 @@ impl<'d, T: Instance> Drop for Adc<'d, T> {
169 fn drop(&mut self) { 169 fn drop(&mut self) {
170 T::regs().cr2().modify(|reg| reg.set_adon(false)); 170 T::regs().cr2().modify(|reg| reg.set_adon(false));
171 171
172 T::disable(); 172 rcc::disable::<T>();
173 } 173 }
174} 174}
diff --git a/embassy-stm32/src/adc/f3.rs b/embassy-stm32/src/adc/f3.rs
index 3f076d64b..ac88c9742 100644
--- a/embassy-stm32/src/adc/f3.rs
+++ b/embassy-stm32/src/adc/f3.rs
@@ -8,7 +8,7 @@ use super::blocking_delay_us;
8use crate::adc::{Adc, AdcChannel, Instance, SampleTime}; 8use crate::adc::{Adc, AdcChannel, Instance, SampleTime};
9use crate::interrupt::typelevel::Interrupt; 9use crate::interrupt::typelevel::Interrupt;
10use crate::time::Hertz; 10use crate::time::Hertz;
11use crate::{interrupt, Peripheral}; 11use crate::{interrupt, rcc, Peripheral};
12 12
13pub const VDDA_CALIB_MV: u32 = 3300; 13pub const VDDA_CALIB_MV: u32 = 3300;
14pub const ADC_MAX: u32 = (1 << 12) - 1; 14pub const ADC_MAX: u32 = (1 << 12) - 1;
@@ -63,7 +63,7 @@ impl<'d, T: Instance> Adc<'d, T> {
63 63
64 into_ref!(adc); 64 into_ref!(adc);
65 65
66 T::enable_and_reset(); 66 rcc::enable_and_reset::<T>();
67 67
68 // Enable the adc regulator 68 // Enable the adc regulator
69 T::regs().cr().modify(|w| w.set_advregen(vals::Advregen::INTERMEDIATE)); 69 T::regs().cr().modify(|w| w.set_advregen(vals::Advregen::INTERMEDIATE));
@@ -188,6 +188,6 @@ impl<'d, T: Instance> Drop for Adc<'d, T> {
188 T::regs().cr().modify(|w| w.set_advregen(vals::Advregen::INTERMEDIATE)); 188 T::regs().cr().modify(|w| w.set_advregen(vals::Advregen::INTERMEDIATE));
189 T::regs().cr().modify(|w| w.set_advregen(vals::Advregen::DISABLED)); 189 T::regs().cr().modify(|w| w.set_advregen(vals::Advregen::DISABLED));
190 190
191 T::disable(); 191 rcc::disable::<T>();
192 } 192 }
193} 193}
diff --git a/embassy-stm32/src/adc/f3_v1_1.rs b/embassy-stm32/src/adc/f3_v1_1.rs
index 106956989..689c2871d 100644
--- a/embassy-stm32/src/adc/f3_v1_1.rs
+++ b/embassy-stm32/src/adc/f3_v1_1.rs
@@ -10,7 +10,7 @@ use super::Resolution;
10use crate::adc::{Adc, AdcChannel, Instance, SampleTime}; 10use crate::adc::{Adc, AdcChannel, Instance, SampleTime};
11use crate::interrupt::typelevel::Interrupt; 11use crate::interrupt::typelevel::Interrupt;
12use crate::time::Hertz; 12use crate::time::Hertz;
13use crate::{interrupt, Peripheral}; 13use crate::{interrupt, rcc, Peripheral};
14 14
15const ADC_FREQ: Hertz = crate::rcc::HSI_FREQ; 15const ADC_FREQ: Hertz = crate::rcc::HSI_FREQ;
16 16
@@ -143,7 +143,7 @@ impl<'d, T: Instance> Adc<'d, T> {
143 ) -> Self { 143 ) -> Self {
144 into_ref!(adc); 144 into_ref!(adc);
145 145
146 T::enable_and_reset(); 146 rcc::enable_and_reset::<T>();
147 147
148 //let r = T::regs(); 148 //let r = T::regs();
149 //r.cr2().write(|w| w.set_align(true)); 149 //r.cr2().write(|w| w.set_align(true));
@@ -403,6 +403,6 @@ impl<'d, T: Instance> Drop for Adc<'d, T> {
403 403
404 T::regs().cr2().modify(|w| w.set_adon(false)); 404 T::regs().cr2().modify(|w| w.set_adon(false));
405 405
406 T::disable(); 406 rcc::disable::<T>();
407 } 407 }
408} 408}
diff --git a/embassy-stm32/src/adc/g4.rs b/embassy-stm32/src/adc/g4.rs
index ce7f5db70..6569361fe 100644
--- a/embassy-stm32/src/adc/g4.rs
+++ b/embassy-stm32/src/adc/g4.rs
@@ -4,7 +4,7 @@ use pac::adccommon::vals::Presc;
4 4
5use super::{blocking_delay_us, Adc, AdcChannel, Instance, Resolution, SampleTime}; 5use super::{blocking_delay_us, Adc, AdcChannel, Instance, Resolution, SampleTime};
6use crate::time::Hertz; 6use crate::time::Hertz;
7use crate::{pac, Peripheral}; 7use crate::{pac, rcc, Peripheral};
8 8
9/// Default VREF voltage used for sample conversion to millivolts. 9/// Default VREF voltage used for sample conversion to millivolts.
10pub const VREF_DEFAULT_MV: u32 = 3300; 10pub const VREF_DEFAULT_MV: u32 = 3300;
@@ -130,7 +130,7 @@ impl<'d, T: Instance> Adc<'d, T> {
130 /// Create a new ADC driver. 130 /// Create a new ADC driver.
131 pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self { 131 pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self {
132 embassy_hal_internal::into_ref!(adc); 132 embassy_hal_internal::into_ref!(adc);
133 T::enable_and_reset(); 133 rcc::enable_and_reset::<T>();
134 134
135 let prescaler = Prescaler::from_ker_ck(T::frequency()); 135 let prescaler = Prescaler::from_ker_ck(T::frequency());
136 136
diff --git a/embassy-stm32/src/adc/v1.rs b/embassy-stm32/src/adc/v1.rs
index 090790c39..9bec2e13b 100644
--- a/embassy-stm32/src/adc/v1.rs
+++ b/embassy-stm32/src/adc/v1.rs
@@ -10,7 +10,7 @@ use super::blocking_delay_us;
10use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime}; 10use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime};
11use crate::interrupt::typelevel::Interrupt; 11use crate::interrupt::typelevel::Interrupt;
12use crate::peripherals::ADC1; 12use crate::peripherals::ADC1;
13use crate::{interrupt, Peripheral}; 13use crate::{interrupt, rcc, Peripheral};
14 14
15pub const VDDA_CALIB_MV: u32 = 3300; 15pub const VDDA_CALIB_MV: u32 = 3300;
16pub const VREF_INT: u32 = 1230; 16pub const VREF_INT: u32 = 1230;
@@ -67,7 +67,7 @@ impl<'d, T: Instance> Adc<'d, T> {
67 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 67 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
68 ) -> Self { 68 ) -> Self {
69 into_ref!(adc); 69 into_ref!(adc);
70 T::enable_and_reset(); 70 rcc::enable_and_reset::<T>();
71 71
72 // Delay 1μs when using HSI14 as the ADC clock. 72 // Delay 1μs when using HSI14 as the ADC clock.
73 // 73 //
@@ -199,6 +199,6 @@ impl<'d, T: Instance> Drop for Adc<'d, T> {
199 T::regs().cr().modify(|reg| reg.set_addis(true)); 199 T::regs().cr().modify(|reg| reg.set_addis(true));
200 while T::regs().cr().read().aden() {} 200 while T::regs().cr().read().aden() {}
201 201
202 T::disable(); 202 rcc::disable::<T>();
203 } 203 }
204} 204}
diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs
index 033108195..77e8bb56f 100644
--- a/embassy-stm32/src/adc/v2.rs
+++ b/embassy-stm32/src/adc/v2.rs
@@ -4,7 +4,7 @@ use super::blocking_delay_us;
4use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime}; 4use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime};
5use crate::peripherals::ADC1; 5use crate::peripherals::ADC1;
6use crate::time::Hertz; 6use crate::time::Hertz;
7use crate::Peripheral; 7use crate::{rcc, Peripheral};
8 8
9/// Default VREF voltage used for sample conversion to millivolts. 9/// Default VREF voltage used for sample conversion to millivolts.
10pub const VREF_DEFAULT_MV: u32 = 3300; 10pub const VREF_DEFAULT_MV: u32 = 3300;
@@ -96,7 +96,7 @@ where
96{ 96{
97 pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self { 97 pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self {
98 into_ref!(adc); 98 into_ref!(adc);
99 T::enable_and_reset(); 99 rcc::enable_and_reset::<T>();
100 100
101 let presc = Prescaler::from_pclk2(T::frequency()); 101 let presc = Prescaler::from_pclk2(T::frequency());
102 T::common_regs().ccr().modify(|w| w.set_adcpre(presc.adcpre())); 102 T::common_regs().ccr().modify(|w| w.set_adcpre(presc.adcpre()));
@@ -206,6 +206,6 @@ impl<'d, T: Instance> Drop for Adc<'d, T> {
206 reg.set_adon(false); 206 reg.set_adon(false);
207 }); 207 });
208 208
209 T::disable(); 209 rcc::disable::<T>();
210 } 210 }
211} 211}
diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs
index be857f4dd..398c57a92 100644
--- a/embassy-stm32/src/adc/v3.rs
+++ b/embassy-stm32/src/adc/v3.rs
@@ -3,7 +3,7 @@ use embassy_hal_internal::into_ref;
3 3
4use super::blocking_delay_us; 4use super::blocking_delay_us;
5use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime}; 5use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime};
6use crate::Peripheral; 6use crate::{rcc, Peripheral};
7 7
8/// Default VREF voltage used for sample conversion to millivolts. 8/// Default VREF voltage used for sample conversion to millivolts.
9pub const VREF_DEFAULT_MV: u32 = 3300; 9pub const VREF_DEFAULT_MV: u32 = 3300;
@@ -94,7 +94,7 @@ cfg_if! {
94impl<'d, T: Instance> Adc<'d, T> { 94impl<'d, T: Instance> Adc<'d, T> {
95 pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self { 95 pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self {
96 into_ref!(adc); 96 into_ref!(adc);
97 T::enable_and_reset(); 97 rcc::enable_and_reset::<T>();
98 T::regs().cr().modify(|reg| { 98 T::regs().cr().modify(|reg| {
99 #[cfg(not(any(adc_g0, adc_u0)))] 99 #[cfg(not(any(adc_g0, adc_u0)))]
100 reg.set_deeppwd(false); 100 reg.set_deeppwd(false);
diff --git a/embassy-stm32/src/adc/v4.rs b/embassy-stm32/src/adc/v4.rs
index f564114c2..50db646fe 100644
--- a/embassy-stm32/src/adc/v4.rs
+++ b/embassy-stm32/src/adc/v4.rs
@@ -4,7 +4,7 @@ use pac::adccommon::vals::Presc;
4 4
5use super::{blocking_delay_us, Adc, AdcChannel, Instance, Resolution, SampleTime}; 5use super::{blocking_delay_us, Adc, AdcChannel, Instance, Resolution, SampleTime};
6use crate::time::Hertz; 6use crate::time::Hertz;
7use crate::{pac, Peripheral}; 7use crate::{pac, rcc, Peripheral};
8 8
9/// Default VREF voltage used for sample conversion to millivolts. 9/// Default VREF voltage used for sample conversion to millivolts.
10pub const VREF_DEFAULT_MV: u32 = 3300; 10pub const VREF_DEFAULT_MV: u32 = 3300;
@@ -130,7 +130,7 @@ impl<'d, T: Instance> Adc<'d, T> {
130 /// Create a new ADC driver. 130 /// Create a new ADC driver.
131 pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self { 131 pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self {
132 embassy_hal_internal::into_ref!(adc); 132 embassy_hal_internal::into_ref!(adc);
133 T::enable_and_reset(); 133 rcc::enable_and_reset::<T>();
134 134
135 let prescaler = Prescaler::from_ker_ck(T::frequency()); 135 let prescaler = Prescaler::from_ker_ck(T::frequency());
136 136
diff --git a/embassy-stm32/src/can/bxcan/mod.rs b/embassy-stm32/src/can/bxcan/mod.rs
index 0ac4cdab6..ac225d7d2 100644
--- a/embassy-stm32/src/can/bxcan/mod.rs
+++ b/embassy-stm32/src/can/bxcan/mod.rs
@@ -19,7 +19,7 @@ use super::util;
19use crate::can::enums::{BusError, TryReadError}; 19use crate::can::enums::{BusError, TryReadError};
20use crate::gpio::AFType; 20use crate::gpio::AFType;
21use crate::interrupt::typelevel::Interrupt; 21use crate::interrupt::typelevel::Interrupt;
22use crate::rcc::RccPeripheral; 22use crate::rcc::{self, RccPeripheral};
23use crate::{interrupt, peripherals, Peripheral}; 23use crate::{interrupt, peripherals, Peripheral};
24 24
25/// Interrupt handler. 25/// Interrupt handler.
@@ -183,7 +183,7 @@ impl<'d, T: Instance> Can<'d, T> {
183 rx.set_as_af(rx.af_num(), AFType::Input); 183 rx.set_as_af(rx.af_num(), AFType::Input);
184 tx.set_as_af(tx.af_num(), AFType::OutputPushPull); 184 tx.set_as_af(tx.af_num(), AFType::OutputPushPull);
185 185
186 T::enable_and_reset(); 186 rcc::enable_and_reset::<T>();
187 187
188 { 188 {
189 T::regs().ier().write(|w| { 189 T::regs().ier().write(|w| {
@@ -759,7 +759,7 @@ impl<'d, T: Instance> Drop for Can<'d, T> {
759 // Cannot call `free()` because it moves the instance. 759 // Cannot call `free()` because it moves the instance.
760 // Manually reset the peripheral. 760 // Manually reset the peripheral.
761 T::regs().mcr().write(|w| w.set_reset(true)); 761 T::regs().mcr().write(|w| w.set_reset(true));
762 T::disable(); 762 rcc::disable::<T>();
763 } 763 }
764} 764}
765 765
diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs
index d0c8db090..a838d0412 100644
--- a/embassy-stm32/src/can/fdcan.rs
+++ b/embassy-stm32/src/can/fdcan.rs
@@ -12,7 +12,7 @@ use embassy_sync::waitqueue::AtomicWaker;
12use crate::can::fd::peripheral::Registers; 12use crate::can::fd::peripheral::Registers;
13use crate::gpio::AFType; 13use crate::gpio::AFType;
14use crate::interrupt::typelevel::Interrupt; 14use crate::interrupt::typelevel::Interrupt;
15use crate::rcc::RccPeripheral; 15use crate::rcc::{self, RccPeripheral};
16use crate::{interrupt, peripherals, Peripheral}; 16use crate::{interrupt, peripherals, Peripheral};
17 17
18pub(crate) mod fd; 18pub(crate) mod fd;
@@ -184,7 +184,7 @@ impl<'d, T: Instance> CanConfigurator<'d, T> {
184 rx.set_as_af(rx.af_num(), AFType::Input); 184 rx.set_as_af(rx.af_num(), AFType::Input);
185 tx.set_as_af(tx.af_num(), AFType::OutputPushPull); 185 tx.set_as_af(tx.af_num(), AFType::OutputPushPull);
186 186
187 T::enable_and_reset(); 187 rcc::enable_and_reset::<T>();
188 188
189 let mut config = crate::can::fd::config::FdCanConfig::default(); 189 let mut config = crate::can::fd::config::FdCanConfig::default();
190 config.timestamp_source = TimestampSource::Prescaler(TimestampPrescaler::_1); 190 config.timestamp_source = TimestampSource::Prescaler(TimestampPrescaler::_1);
diff --git a/embassy-stm32/src/cordic/mod.rs b/embassy-stm32/src/cordic/mod.rs
index 29b11735e..fb342d2e7 100644
--- a/embassy-stm32/src/cordic/mod.rs
+++ b/embassy-stm32/src/cordic/mod.rs
@@ -4,7 +4,7 @@ use embassy_hal_internal::drop::OnDrop;
4use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; 4use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
5 5
6use crate::pac::cordic::vals; 6use crate::pac::cordic::vals;
7use crate::{dma, peripherals}; 7use crate::{dma, peripherals, rcc};
8 8
9mod enums; 9mod enums;
10pub use enums::*; 10pub use enums::*;
@@ -199,7 +199,7 @@ impl<'d, T: Instance> Cordic<'d, T> {
199 /// If you need a peripheral -> CORDIC -> peripheral mode, 199 /// If you need a peripheral -> CORDIC -> peripheral mode,
200 /// you may want to set Cordic into [Mode::ZeroOverhead] mode, and add extra arguments with [Self::extra_config] 200 /// you may want to set Cordic into [Mode::ZeroOverhead] mode, and add extra arguments with [Self::extra_config]
201 pub fn new(peri: impl Peripheral<P = T> + 'd, config: Config) -> Self { 201 pub fn new(peri: impl Peripheral<P = T> + 'd, config: Config) -> Self {
202 T::enable_and_reset(); 202 rcc::enable_and_reset::<T>();
203 203
204 into_ref!(peri); 204 into_ref!(peri);
205 205
@@ -259,7 +259,7 @@ impl<'d, T: Instance> Cordic<'d, T> {
259 259
260impl<'d, T: Instance> Drop for Cordic<'d, T> { 260impl<'d, T: Instance> Drop for Cordic<'d, T> {
261 fn drop(&mut self) { 261 fn drop(&mut self) {
262 T::disable(); 262 rcc::disable::<T>();
263 } 263 }
264} 264}
265 265
diff --git a/embassy-stm32/src/crc/v1.rs b/embassy-stm32/src/crc/v1.rs
index e8e0270af..f3d13de7c 100644
--- a/embassy-stm32/src/crc/v1.rs
+++ b/embassy-stm32/src/crc/v1.rs
@@ -2,8 +2,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
2 2
3use crate::pac::CRC as PAC_CRC; 3use crate::pac::CRC as PAC_CRC;
4use crate::peripherals::CRC; 4use crate::peripherals::CRC;
5use crate::rcc::SealedRccPeripheral; 5use crate::{rcc, Peripheral};
6use crate::Peripheral;
7 6
8/// CRC driver. 7/// CRC driver.
9pub struct Crc<'d> { 8pub struct Crc<'d> {
@@ -17,7 +16,7 @@ impl<'d> Crc<'d> {
17 16
18 // Note: enable and reset come from RccPeripheral. 17 // Note: enable and reset come from RccPeripheral.
19 // enable CRC clock in RCC. 18 // enable CRC clock in RCC.
20 CRC::enable_and_reset(); 19 rcc::enable_and_reset::<CRC>();
21 // Peripheral the peripheral 20 // Peripheral the peripheral
22 let mut instance = Self { _peri: peripheral }; 21 let mut instance = Self { _peri: peripheral };
23 instance.reset(); 22 instance.reset();
diff --git a/embassy-stm32/src/crc/v2v3.rs b/embassy-stm32/src/crc/v2v3.rs
index ad7c79f12..09d956d7c 100644
--- a/embassy-stm32/src/crc/v2v3.rs
+++ b/embassy-stm32/src/crc/v2v3.rs
@@ -3,8 +3,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
3use crate::pac::crc::vals; 3use crate::pac::crc::vals;
4use crate::pac::CRC as PAC_CRC; 4use crate::pac::CRC as PAC_CRC;
5use crate::peripherals::CRC; 5use crate::peripherals::CRC;
6use crate::rcc::SealedRccPeripheral; 6use crate::{rcc, Peripheral};
7use crate::Peripheral;
8 7
9/// CRC driver. 8/// CRC driver.
10pub struct Crc<'d> { 9pub struct Crc<'d> {
@@ -84,7 +83,7 @@ impl<'d> Crc<'d> {
84 pub fn new(peripheral: impl Peripheral<P = CRC> + 'd, config: Config) -> Self { 83 pub fn new(peripheral: impl Peripheral<P = CRC> + 'd, config: Config) -> Self {
85 // Note: enable and reset come from RccPeripheral. 84 // Note: enable and reset come from RccPeripheral.
86 // reset to default values and enable CRC clock in RCC. 85 // reset to default values and enable CRC clock in RCC.
87 CRC::enable_and_reset(); 86 rcc::enable_and_reset::<CRC>();
88 into_ref!(peripheral); 87 into_ref!(peripheral);
89 let mut instance = Self { 88 let mut instance = Self {
90 _peripheral: peripheral, 89 _peripheral: peripheral,
diff --git a/embassy-stm32/src/cryp/mod.rs b/embassy-stm32/src/cryp/mod.rs
index e7808b454..ad118ef6e 100644
--- a/embassy-stm32/src/cryp/mod.rs
+++ b/embassy-stm32/src/cryp/mod.rs
@@ -9,7 +9,7 @@ use embassy_sync::waitqueue::AtomicWaker;
9 9
10use crate::dma::{NoDma, Transfer, TransferOptions}; 10use crate::dma::{NoDma, Transfer, TransferOptions};
11use crate::interrupt::typelevel::Interrupt; 11use crate::interrupt::typelevel::Interrupt;
12use crate::{interrupt, pac, peripherals, Peripheral}; 12use crate::{interrupt, pac, peripherals, rcc, Peripheral};
13 13
14const DES_BLOCK_SIZE: usize = 8; // 64 bits 14const DES_BLOCK_SIZE: usize = 8; // 64 bits
15const AES_BLOCK_SIZE: usize = 16; // 128 bits 15const AES_BLOCK_SIZE: usize = 16; // 128 bits
@@ -1021,7 +1021,7 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> {
1021 outdma: impl Peripheral<P = DmaOut> + 'd, 1021 outdma: impl Peripheral<P = DmaOut> + 'd,
1022 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 1022 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
1023 ) -> Self { 1023 ) -> Self {
1024 T::enable_and_reset(); 1024 rcc::enable_and_reset::<T>();
1025 into_ref!(peri, indma, outdma); 1025 into_ref!(peri, indma, outdma);
1026 let instance = Self { 1026 let instance = Self {
1027 _peripheral: peri, 1027 _peripheral: peri,
diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs
index 489342a4a..8bba5ded0 100644
--- a/embassy-stm32/src/dac/mod.rs
+++ b/embassy-stm32/src/dac/mod.rs
@@ -8,7 +8,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
8use crate::dma::NoDma; 8use crate::dma::NoDma;
9#[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] 9#[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))]
10use crate::pac::dac; 10use crate::pac::dac;
11use crate::rcc::RccPeripheral; 11use crate::rcc::{self, RccPeripheral};
12use crate::{peripherals, Peripheral}; 12use crate::{peripherals, Peripheral};
13 13
14mod tsel; 14mod tsel;
@@ -131,7 +131,7 @@ impl<'d, T: Instance, const N: u8, DMA> DacChannel<'d, T, N, DMA> {
131 ) -> Self { 131 ) -> Self {
132 into_ref!(dma, pin); 132 into_ref!(dma, pin);
133 pin.set_as_analog(); 133 pin.set_as_analog();
134 T::enable_and_reset(); 134 rcc::enable_and_reset::<T>();
135 let mut dac = Self { 135 let mut dac = Self {
136 phantom: PhantomData, 136 phantom: PhantomData,
137 dma, 137 dma,
@@ -157,7 +157,7 @@ impl<'d, T: Instance, const N: u8, DMA> DacChannel<'d, T, N, DMA> {
157 #[cfg(all(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7), not(any(stm32h56x, stm32h57x))))] 157 #[cfg(all(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7), not(any(stm32h56x, stm32h57x))))]
158 pub fn new_internal(_peri: impl Peripheral<P = T> + 'd, dma: impl Peripheral<P = DMA> + 'd) -> Self { 158 pub fn new_internal(_peri: impl Peripheral<P = T> + 'd, dma: impl Peripheral<P = DMA> + 'd) -> Self {
159 into_ref!(dma); 159 into_ref!(dma);
160 T::enable_and_reset(); 160 rcc::enable_and_reset::<T>();
161 let mut dac = Self { 161 let mut dac = Self {
162 phantom: PhantomData, 162 phantom: PhantomData,
163 dma, 163 dma,
@@ -356,7 +356,7 @@ impl_dma_methods!(2, DacDma2);
356 356
357impl<'d, T: Instance, const N: u8, DMA> Drop for DacChannel<'d, T, N, DMA> { 357impl<'d, T: Instance, const N: u8, DMA> Drop for DacChannel<'d, T, N, DMA> {
358 fn drop(&mut self) { 358 fn drop(&mut self) {
359 T::disable(); 359 rcc::disable::<T>();
360 } 360 }
361} 361}
362 362
@@ -400,8 +400,8 @@ impl<'d, T: Instance, DMACh1, DMACh2> Dac<'d, T, DMACh1, DMACh2> {
400 pin_ch2.set_as_analog(); 400 pin_ch2.set_as_analog();
401 401
402 // Enable twice to increment the DAC refcount for each channel. 402 // Enable twice to increment the DAC refcount for each channel.
403 T::enable_and_reset(); 403 rcc::enable_and_reset::<T>();
404 T::enable_and_reset(); 404 rcc::enable_and_reset::<T>();
405 405
406 let mut ch1 = DacCh1 { 406 let mut ch1 = DacCh1 {
407 phantom: PhantomData, 407 phantom: PhantomData,
@@ -444,8 +444,8 @@ impl<'d, T: Instance, DMACh1, DMACh2> Dac<'d, T, DMACh1, DMACh2> {
444 ) -> Self { 444 ) -> Self {
445 into_ref!(dma_ch1, dma_ch2); 445 into_ref!(dma_ch1, dma_ch2);
446 // Enable twice to increment the DAC refcount for each channel. 446 // Enable twice to increment the DAC refcount for each channel.
447 T::enable_and_reset(); 447 rcc::enable_and_reset::<T>();
448 T::enable_and_reset(); 448 rcc::enable_and_reset::<T>();
449 449
450 let mut ch1 = DacCh1 { 450 let mut ch1 = DacCh1 {
451 phantom: PhantomData, 451 phantom: PhantomData,
diff --git a/embassy-stm32/src/dcmi.rs b/embassy-stm32/src/dcmi.rs
index 646ee2ce2..858ae49ca 100644
--- a/embassy-stm32/src/dcmi.rs
+++ b/embassy-stm32/src/dcmi.rs
@@ -9,7 +9,7 @@ use embassy_sync::waitqueue::AtomicWaker;
9use crate::dma::Transfer; 9use crate::dma::Transfer;
10use crate::gpio::{AFType, Speed}; 10use crate::gpio::{AFType, Speed};
11use crate::interrupt::typelevel::Interrupt; 11use crate::interrupt::typelevel::Interrupt;
12use crate::{interrupt, Peripheral}; 12use crate::{interrupt, rcc, Peripheral};
13 13
14/// Interrupt handler. 14/// Interrupt handler.
15pub struct InterruptHandler<T: Instance> { 15pub struct InterruptHandler<T: Instance> {
@@ -350,7 +350,7 @@ where
350 use_embedded_synchronization: bool, 350 use_embedded_synchronization: bool,
351 edm: u8, 351 edm: u8,
352 ) -> Self { 352 ) -> Self {
353 T::enable_and_reset(); 353 rcc::enable_and_reset::<T>();
354 354
355 peri.regs().cr().modify(|r| { 355 peri.regs().cr().modify(|r| {
356 r.set_cm(true); // disable continuous mode (snapshot mode) 356 r.set_cm(true); // disable continuous mode (snapshot mode)
diff --git a/embassy-stm32/src/dsihost.rs b/embassy-stm32/src/dsihost.rs
index 253939394..dc58bca92 100644
--- a/embassy-stm32/src/dsihost.rs
+++ b/embassy-stm32/src/dsihost.rs
@@ -6,7 +6,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
6 6
7//use crate::gpio::{AnyPin, SealedPin}; 7//use crate::gpio::{AnyPin, SealedPin};
8use crate::gpio::{AFType, AnyPin, Pull, Speed}; 8use crate::gpio::{AFType, AnyPin, Pull, Speed};
9use crate::rcc::RccPeripheral; 9use crate::rcc::{self, RccPeripheral};
10use crate::{peripherals, Peripheral}; 10use crate::{peripherals, Peripheral};
11 11
12/// Performs a busy-wait delay for a specified number of microseconds. 12/// Performs a busy-wait delay for a specified number of microseconds.
@@ -77,7 +77,7 @@ impl<'d, T: Instance> DsiHost<'d, T> {
77 pub fn new(_peri: impl Peripheral<P = T> + 'd, te: impl Peripheral<P = impl TePin<T>> + 'd) -> Self { 77 pub fn new(_peri: impl Peripheral<P = T> + 'd, te: impl Peripheral<P = impl TePin<T>> + 'd) -> Self {
78 into_ref!(te); 78 into_ref!(te);
79 79
80 T::enable_and_reset(); 80 rcc::enable_and_reset::<T>();
81 81
82 // Set Tearing Enable pin according to CubeMx example 82 // Set Tearing Enable pin according to CubeMx example
83 te.set_as_af_pull(te.af_num(), AFType::OutputPushPull, Pull::None); 83 te.set_as_af_pull(te.af_num(), AFType::OutputPushPull, Pull::None);
diff --git a/embassy-stm32/src/fmc.rs b/embassy-stm32/src/fmc.rs
index aced69878..0df64f711 100644
--- a/embassy-stm32/src/fmc.rs
+++ b/embassy-stm32/src/fmc.rs
@@ -4,7 +4,7 @@ use core::marker::PhantomData;
4use embassy_hal_internal::into_ref; 4use embassy_hal_internal::into_ref;
5 5
6use crate::gpio::{AFType, Pull, Speed}; 6use crate::gpio::{AFType, Pull, Speed};
7use crate::Peripheral; 7use crate::{rcc, Peripheral};
8 8
9/// FMC driver 9/// FMC driver
10pub struct Fmc<'d, T: Instance> { 10pub struct Fmc<'d, T: Instance> {
@@ -27,7 +27,7 @@ where
27 27
28 /// Enable the FMC peripheral and reset it. 28 /// Enable the FMC peripheral and reset it.
29 pub fn enable(&mut self) { 29 pub fn enable(&mut self) {
30 T::enable_and_reset(); 30 rcc::enable_and_reset::<T>();
31 } 31 }
32 32
33 /// Enable the memory controller on applicable chips. 33 /// Enable the memory controller on applicable chips.
@@ -54,7 +54,7 @@ where
54 const REGISTERS: *const () = T::REGS.as_ptr() as *const _; 54 const REGISTERS: *const () = T::REGS.as_ptr() as *const _;
55 55
56 fn enable(&mut self) { 56 fn enable(&mut self) {
57 T::enable_and_reset(); 57 rcc::enable_and_reset::<T>();
58 } 58 }
59 59
60 fn memory_controller_enable(&mut self) { 60 fn memory_controller_enable(&mut self) {
@@ -200,7 +200,7 @@ impl<'d, T: Instance> Fmc<'d, T> {
200 )); 200 ));
201} 201}
202 202
203trait SealedInstance: crate::rcc::SealedRccPeripheral { 203trait SealedInstance: crate::rcc::RccPeripheral {
204 const REGS: crate::pac::fmc::Fmc; 204 const REGS: crate::pac::fmc::Fmc;
205} 205}
206 206
diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs
index d60a857ef..de08127cf 100644
--- a/embassy-stm32/src/gpio.rs
+++ b/embassy-stm32/src/gpio.rs
@@ -822,7 +822,7 @@ foreach_pin!(
822 822
823pub(crate) unsafe fn init(_cs: CriticalSection) { 823pub(crate) unsafe fn init(_cs: CriticalSection) {
824 #[cfg(afio)] 824 #[cfg(afio)]
825 <crate::peripherals::AFIO as crate::rcc::SealedRccPeripheral>::enable_and_reset_with_cs(_cs); 825 crate::rcc::enable_and_reset_with_cs::<crate::peripherals::AFIO>(_cs);
826 826
827 crate::_generated::init_gpio(); 827 crate::_generated::init_gpio();
828} 828}
diff --git a/embassy-stm32/src/hash/mod.rs b/embassy-stm32/src/hash/mod.rs
index 787d5b1c9..4d4a8ec5b 100644
--- a/embassy-stm32/src/hash/mod.rs
+++ b/embassy-stm32/src/hash/mod.rs
@@ -17,8 +17,7 @@ use crate::dma::NoDma;
17use crate::dma::Transfer; 17use crate::dma::Transfer;
18use crate::interrupt::typelevel::Interrupt; 18use crate::interrupt::typelevel::Interrupt;
19use crate::peripherals::HASH; 19use crate::peripherals::HASH;
20use crate::rcc::SealedRccPeripheral; 20use crate::{interrupt, pac, peripherals, rcc, Peripheral};
21use crate::{interrupt, pac, peripherals, Peripheral};
22 21
23#[cfg(hash_v1)] 22#[cfg(hash_v1)]
24const NUM_CONTEXT_REGS: usize = 51; 23const NUM_CONTEXT_REGS: usize = 51;
@@ -130,7 +129,7 @@ impl<'d, T: Instance, D> Hash<'d, T, D> {
130 dma: impl Peripheral<P = D> + 'd, 129 dma: impl Peripheral<P = D> + 'd,
131 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 130 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
132 ) -> Self { 131 ) -> Self {
133 HASH::enable_and_reset(); 132 rcc::enable_and_reset::<HASH>();
134 into_ref!(peripheral, dma); 133 into_ref!(peripheral, dma);
135 let instance = Self { 134 let instance = Self {
136 _peripheral: peripheral, 135 _peripheral: peripheral,
diff --git a/embassy-stm32/src/hrtim/mod.rs b/embassy-stm32/src/hrtim/mod.rs
index 02e45819c..c9d5bff17 100644
--- a/embassy-stm32/src/hrtim/mod.rs
+++ b/embassy-stm32/src/hrtim/mod.rs
@@ -9,7 +9,7 @@ pub use traits::Instance;
9 9
10use crate::gpio::{AFType, AnyPin}; 10use crate::gpio::{AFType, AnyPin};
11use crate::time::Hertz; 11use crate::time::Hertz;
12use crate::Peripheral; 12use crate::{rcc, Peripheral};
13 13
14/// HRTIM burst controller instance. 14/// HRTIM burst controller instance.
15pub struct BurstController<T: Instance> { 15pub struct BurstController<T: Instance> {
@@ -172,7 +172,7 @@ impl<'d, T: Instance> AdvancedPwm<'d, T> {
172 fn new_inner(tim: impl Peripheral<P = T> + 'd) -> Self { 172 fn new_inner(tim: impl Peripheral<P = T> + 'd) -> Self {
173 into_ref!(tim); 173 into_ref!(tim);
174 174
175 T::enable_and_reset(); 175 rcc::enable_and_reset::<T>();
176 176
177 #[cfg(stm32f334)] 177 #[cfg(stm32f334)]
178 if crate::pac::RCC.cfgr3().read().hrtim1sw() == crate::pac::rcc::vals::Timsw::PLL1_P { 178 if crate::pac::RCC.cfgr3().read().hrtim1sw() == crate::pac::rcc::vals::Timsw::PLL1_P {
diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs
index ef5fd0972..0bf57ef8a 100644
--- a/embassy-stm32/src/i2c/mod.rs
+++ b/embassy-stm32/src/i2c/mod.rs
@@ -18,7 +18,7 @@ use crate::dma::ChannelAndRequest;
18use crate::gpio::{AFType, Pull}; 18use crate::gpio::{AFType, Pull};
19use crate::interrupt::typelevel::Interrupt; 19use crate::interrupt::typelevel::Interrupt;
20use crate::mode::{Async, Blocking, Mode}; 20use crate::mode::{Async, Blocking, Mode};
21use crate::rcc::{ClockEnableBit, SealedRccPeripheral}; 21use crate::rcc::{self, RccInfo, SealedRccPeripheral};
22use crate::time::Hertz; 22use crate::time::Hertz;
23use crate::{interrupt, peripherals}; 23use crate::{interrupt, peripherals};
24 24
@@ -128,7 +128,7 @@ impl<'d, M: Mode> I2c<'d, M> {
128 ) -> Self { 128 ) -> Self {
129 into_ref!(scl, sda); 129 into_ref!(scl, sda);
130 130
131 T::enable_and_reset(); 131 rcc::enable_and_reset::<T>();
132 132
133 scl.set_as_af_pull( 133 scl.set_as_af_pull(
134 scl.af_num(), 134 scl.af_num(),
@@ -224,7 +224,7 @@ impl State {
224 224
225struct Info { 225struct Info {
226 regs: crate::pac::i2c::I2c, 226 regs: crate::pac::i2c::I2c,
227 pub(crate) enable_bit: ClockEnableBit, 227 rcc: RccInfo,
228} 228}
229 229
230peri_trait!( 230peri_trait!(
@@ -265,7 +265,7 @@ foreach_peripheral!(
265 fn info() -> &'static Info { 265 fn info() -> &'static Info {
266 static INFO: Info = Info{ 266 static INFO: Info = Info{
267 regs: crate::pac::$inst, 267 regs: crate::pac::$inst,
268 enable_bit: crate::peripherals::$inst::ENABLE_BIT, 268 rcc: crate::peripherals::$inst::RCC_INFO,
269 }; 269 };
270 &INFO 270 &INFO
271 } 271 }
diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs
index 0269e53aa..0e2bd2e40 100644
--- a/embassy-stm32/src/i2c/v1.rs
+++ b/embassy-stm32/src/i2c/v1.rs
@@ -702,7 +702,7 @@ impl<'d> I2c<'d, Async> {
702 702
703impl<'d, M: PeriMode> Drop for I2c<'d, M> { 703impl<'d, M: PeriMode> Drop for I2c<'d, M> {
704 fn drop(&mut self) { 704 fn drop(&mut self) {
705 self.info.enable_bit.disable() 705 self.info.rcc.disable()
706 } 706 }
707} 707}
708 708
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index aa6daf786..193f29733 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -673,7 +673,7 @@ impl<'d> I2c<'d, Async> {
673 673
674impl<'d, M: Mode> Drop for I2c<'d, M> { 674impl<'d, M: Mode> Drop for I2c<'d, M> {
675 fn drop(&mut self) { 675 fn drop(&mut self) {
676 self.info.enable_bit.disable(); 676 self.info.rcc.disable();
677 } 677 }
678} 678}
679 679
diff --git a/embassy-stm32/src/ipcc.rs b/embassy-stm32/src/ipcc.rs
index 4d535cce2..6c8347311 100644
--- a/embassy-stm32/src/ipcc.rs
+++ b/embassy-stm32/src/ipcc.rs
@@ -6,10 +6,9 @@ use core::task::Poll;
6 6
7use embassy_sync::waitqueue::AtomicWaker; 7use embassy_sync::waitqueue::AtomicWaker;
8 8
9use crate::interrupt;
10use crate::interrupt::typelevel::Interrupt; 9use crate::interrupt::typelevel::Interrupt;
11use crate::peripherals::IPCC; 10use crate::peripherals::IPCC;
12use crate::rcc::SealedRccPeripheral; 11use crate::{interrupt, rcc};
13 12
14/// Interrupt handler. 13/// Interrupt handler.
15pub struct ReceiveInterruptHandler {} 14pub struct ReceiveInterruptHandler {}
@@ -102,7 +101,7 @@ pub struct Ipcc;
102impl Ipcc { 101impl Ipcc {
103 /// Enable IPCC. 102 /// Enable IPCC.
104 pub fn enable(_config: Config) { 103 pub fn enable(_config: Config) {
105 IPCC::enable_and_reset(); 104 rcc::enable_and_reset::<IPCC>();
106 IPCC::set_cpu2(true); 105 IPCC::set_cpu2(true);
107 106
108 // set RF wake-up clock = LSE 107 // set RF wake-up clock = LSE
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs
index 81ee60c1c..fe9c0dcb5 100644
--- a/embassy-stm32/src/lib.rs
+++ b/embassy-stm32/src/lib.rs
@@ -194,7 +194,6 @@ pub(crate) use stm32_metapac as pac;
194use crate::interrupt::Priority; 194use crate::interrupt::Priority;
195#[cfg(feature = "rt")] 195#[cfg(feature = "rt")]
196pub use crate::pac::NVIC_PRIO_BITS; 196pub use crate::pac::NVIC_PRIO_BITS;
197use crate::rcc::SealedRccPeripheral;
198 197
199/// `embassy-stm32` global configuration. 198/// `embassy-stm32` global configuration.
200#[non_exhaustive] 199#[non_exhaustive]
@@ -310,11 +309,11 @@ pub fn init(config: Config) -> Peripherals {
310 }); 309 });
311 310
312 #[cfg(not(any(stm32f1, stm32wb, stm32wl)))] 311 #[cfg(not(any(stm32f1, stm32wb, stm32wl)))]
313 peripherals::SYSCFG::enable_and_reset_with_cs(cs); 312 rcc::enable_and_reset_with_cs::<peripherals::SYSCFG>(cs);
314 #[cfg(not(any(stm32h5, stm32h7, stm32h7rs, stm32wb, stm32wl)))] 313 #[cfg(not(any(stm32h5, stm32h7, stm32h7rs, stm32wb, stm32wl)))]
315 peripherals::PWR::enable_and_reset_with_cs(cs); 314 rcc::enable_and_reset_with_cs::<peripherals::PWR>(cs);
316 #[cfg(not(any(stm32f2, stm32f4, stm32f7, stm32l0, stm32h5, stm32h7, stm32h7rs)))] 315 #[cfg(not(any(stm32f2, stm32f4, stm32f7, stm32l0, stm32h5, stm32h7, stm32h7rs)))]
317 peripherals::FLASH::enable_and_reset_with_cs(cs); 316 rcc::enable_and_reset_with_cs::<peripherals::FLASH>(cs);
318 317
319 // Enable the VDDIO2 power supply on chips that have it. 318 // Enable the VDDIO2 power supply on chips that have it.
320 // Note that this requires the PWR peripheral to be enabled first. 319 // Note that this requires the PWR peripheral to be enabled first.
diff --git a/embassy-stm32/src/ltdc.rs b/embassy-stm32/src/ltdc.rs
index a2d6a3cee..c262e7a0c 100644
--- a/embassy-stm32/src/ltdc.rs
+++ b/embassy-stm32/src/ltdc.rs
@@ -1,7 +1,7 @@
1//! LTDC 1//! LTDC
2use core::marker::PhantomData; 2use core::marker::PhantomData;
3 3
4use crate::rcc::RccPeripheral; 4use crate::rcc::{self, RccPeripheral};
5use crate::{peripherals, Peripheral}; 5use crate::{peripherals, Peripheral};
6 6
7/// LTDC driver. 7/// LTDC driver.
@@ -60,7 +60,7 @@ impl<'d, T: Instance> Ltdc<'d, T> {
60 .modify(|w| w.set_pllsaidivr(stm32_metapac::rcc::vals::Pllsaidivr::DIV2)); 60 .modify(|w| w.set_pllsaidivr(stm32_metapac::rcc::vals::Pllsaidivr::DIV2));
61 }); 61 });
62 62
63 T::enable_and_reset(); 63 rcc::enable_and_reset::<T>();
64 64
65 //new_pin!(clk, AFType::OutputPushPull, Speed::VeryHigh, Pull::None); 65 //new_pin!(clk, AFType::OutputPushPull, Speed::VeryHigh, Pull::None);
66 66
diff --git a/embassy-stm32/src/ospi/mod.rs b/embassy-stm32/src/ospi/mod.rs
index 536da4ca0..882781cce 100644
--- a/embassy-stm32/src/ospi/mod.rs
+++ b/embassy-stm32/src/ospi/mod.rs
@@ -16,7 +16,7 @@ use crate::dma::{word, ChannelAndRequest};
16use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _, Speed}; 16use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _, Speed};
17use crate::mode::{Async, Blocking, Mode as PeriMode}; 17use crate::mode::{Async, Blocking, Mode as PeriMode};
18use crate::pac::octospi::{vals, Octospi as Regs}; 18use crate::pac::octospi::{vals, Octospi as Regs};
19use crate::rcc::RccPeripheral; 19use crate::rcc::{self, RccPeripheral};
20use crate::{peripherals, Peripheral}; 20use crate::{peripherals, Peripheral};
21 21
22/// OPSI driver config. 22/// OPSI driver config.
@@ -198,7 +198,7 @@ impl<'d, T: Instance, M: PeriMode> Ospi<'d, T, M> {
198 into_ref!(peri); 198 into_ref!(peri);
199 199
200 // System configuration 200 // System configuration
201 T::enable_and_reset(); 201 rcc::enable_and_reset::<T>();
202 while T::REGS.sr().read().busy() {} 202 while T::REGS.sr().read().busy() {}
203 203
204 // Device configuration 204 // Device configuration
@@ -1013,7 +1013,7 @@ impl<'d, T: Instance, M: PeriMode> Drop for Ospi<'d, T, M> {
1013 self.nss.as_ref().map(|x| x.set_as_disconnected()); 1013 self.nss.as_ref().map(|x| x.set_as_disconnected());
1014 self.dqs.as_ref().map(|x| x.set_as_disconnected()); 1014 self.dqs.as_ref().map(|x| x.set_as_disconnected());
1015 1015
1016 T::disable(); 1016 rcc::disable::<T>();
1017 } 1017 }
1018} 1018}
1019 1019
diff --git a/embassy-stm32/src/qspi/mod.rs b/embassy-stm32/src/qspi/mod.rs
index a82e93b5b..06c8f4812 100644
--- a/embassy-stm32/src/qspi/mod.rs
+++ b/embassy-stm32/src/qspi/mod.rs
@@ -13,7 +13,7 @@ use crate::dma::ChannelAndRequest;
13use crate::gpio::{AFType, AnyPin, Pull, Speed}; 13use crate::gpio::{AFType, AnyPin, Pull, Speed};
14use crate::mode::{Async, Blocking, Mode as PeriMode}; 14use crate::mode::{Async, Blocking, Mode as PeriMode};
15use crate::pac::quadspi::Quadspi as Regs; 15use crate::pac::quadspi::Quadspi as Regs;
16use crate::rcc::RccPeripheral; 16use crate::rcc::{self, RccPeripheral};
17use crate::{peripherals, Peripheral}; 17use crate::{peripherals, Peripheral};
18 18
19/// QSPI transfer configuration. 19/// QSPI transfer configuration.
@@ -102,7 +102,7 @@ impl<'d, T: Instance, M: PeriMode> Qspi<'d, T, M> {
102 ) -> Self { 102 ) -> Self {
103 into_ref!(peri); 103 into_ref!(peri);
104 104
105 T::enable_and_reset(); 105 rcc::enable_and_reset::<T>();
106 106
107 while T::REGS.sr().read().busy() {} 107 while T::REGS.sr().read().busy() {}
108 108
diff --git a/embassy-stm32/src/rcc/hsi48.rs b/embassy-stm32/src/rcc/hsi48.rs
index da81abc34..efabd059f 100644
--- a/embassy-stm32/src/rcc/hsi48.rs
+++ b/embassy-stm32/src/rcc/hsi48.rs
@@ -2,7 +2,7 @@
2 2
3use crate::pac::crs::vals::Syncsrc; 3use crate::pac::crs::vals::Syncsrc;
4use crate::pac::{CRS, RCC}; 4use crate::pac::{CRS, RCC};
5use crate::rcc::SealedRccPeripheral; 5use crate::rcc::{self, SealedRccPeripheral};
6use crate::time::Hertz; 6use crate::time::Hertz;
7 7
8/// HSI48 speed 8/// HSI48 speed
@@ -44,7 +44,7 @@ pub(crate) fn init_hsi48(config: Hsi48Config) -> Hertz {
44 while r.read().hsi48rdy() == false {} 44 while r.read().hsi48rdy() == false {}
45 45
46 if config.sync_from_usb { 46 if config.sync_from_usb {
47 crate::peripherals::CRS::enable_and_reset(); 47 rcc::enable_and_reset::<crate::peripherals::CRS>();
48 48
49 CRS.cfgr().modify(|w| { 49 CRS.cfgr().modify(|w| {
50 w.set_syncsrc(Syncsrc::USB); 50 w.set_syncsrc(Syncsrc::USB);
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs
index 28816256c..0bf344c40 100644
--- a/embassy-stm32/src/rcc/mod.rs
+++ b/embassy-stm32/src/rcc/mod.rs
@@ -67,23 +67,185 @@ pub(crate) unsafe fn get_freqs() -> &'static Clocks {
67} 67}
68 68
69pub(crate) trait SealedRccPeripheral { 69pub(crate) trait SealedRccPeripheral {
70 const ENABLE_BIT: ClockEnableBit;
71
72 fn frequency() -> Hertz; 70 fn frequency() -> Hertz;
73 fn enable_and_reset_with_cs(cs: CriticalSection); 71 const RCC_INFO: RccInfo;
74 fn disable_with_cs(cs: CriticalSection);
75
76 fn enable_and_reset() {
77 critical_section::with(|cs| Self::enable_and_reset_with_cs(cs))
78 }
79 fn disable() {
80 critical_section::with(|cs| Self::disable_with_cs(cs))
81 }
82} 72}
83 73
84#[allow(private_bounds)] 74#[allow(private_bounds)]
85pub trait RccPeripheral: SealedRccPeripheral + 'static {} 75pub trait RccPeripheral: SealedRccPeripheral + 'static {}
86 76
77/// Runtime information necessary to reset, enable and disable a peripheral.
78pub(crate) struct RccInfo {
79 /// Offset in 32-bit words of the xxxRSTR register into the RCC register block, or 0xff if the
80 /// peripheral has no reset bit (we don't use an `Option` to save one byte of storage).
81 reset_offset_or_0xff: u8,
82 /// Position of the xxxRST bit within the xxxRSTR register (0..=31).
83 reset_bit: u8,
84 /// Offset in 32-bit words of the xxxENR register into the RCC register block.
85 enable_offset: u8,
86 /// Position of the xxxEN bit within the xxxENR register (0..=31).
87 enable_bit: u8,
88 /// If this peripheral shares the same xxxRSTR bit and xxxEN bit with other peripherals, we
89 /// maintain a refcount in `crate::_generated::REFCOUNTS` at this index. If the bit is not
90 /// shared, this is 0xff (we don't use an `Option` to save one byte of storage).
91 refcount_idx_or_0xff: u8,
92 /// Stop mode of the peripheral, used to maintain `REFCOUNT_STOP1` and `REFCOUNT_STOP2`.
93 #[cfg(feature = "low-power")]
94 stop_mode: StopMode,
95}
96
97#[cfg(feature = "low-power")]
98#[allow(dead_code)]
99pub(crate) enum StopMode {
100 Standby,
101 Stop2,
102 Stop1,
103}
104
105impl RccInfo {
106 /// Safety:
107 /// - `reset_offset_and_bit`, if set, must correspond to valid xxxRST bit
108 /// - `enable_offset_and_bit` must correspond to valid xxxEN bit
109 /// - `refcount_idx`, if set, must correspond to valid refcount in `_generated::REFCOUNTS`
110 /// - `stop_mode` must be valid
111 pub(crate) const unsafe fn new(
112 reset_offset_and_bit: Option<(u8, u8)>,
113 enable_offset_and_bit: (u8, u8),
114 refcount_idx: Option<u8>,
115 #[cfg(feature = "low-power")] stop_mode: StopMode,
116 ) -> Self {
117 let (reset_offset_or_0xff, reset_bit) = match reset_offset_and_bit {
118 Some((offset, bit)) => (offset, bit),
119 None => (0xff, 0xff),
120 };
121 let (enable_offset, enable_bit) = enable_offset_and_bit;
122 let refcount_idx_or_0xff = match refcount_idx {
123 Some(idx) => idx,
124 None => 0xff,
125 };
126 Self {
127 reset_offset_or_0xff,
128 reset_bit,
129 enable_offset,
130 enable_bit,
131 refcount_idx_or_0xff,
132 #[cfg(feature = "low-power")]
133 stop_mode,
134 }
135 }
136
137 // TODO: should this be `unsafe`?
138 pub(crate) fn enable_and_reset_with_cs(&self, _cs: CriticalSection) {
139 if self.refcount_idx_or_0xff != 0xff {
140 let refcount_idx = self.refcount_idx_or_0xff as usize;
141 unsafe {
142 crate::_generated::REFCOUNTS[refcount_idx] += 1;
143 }
144 if unsafe { crate::_generated::REFCOUNTS[refcount_idx] } > 1 {
145 return;
146 }
147 }
148
149 #[cfg(feature = "low-power")]
150 match self.stop_mode {
151 StopMode::Standby => {}
152 StopMode::Stop2 => unsafe {
153 REFCOUNT_STOP2 += 1;
154 },
155 StopMode::Stop1 => unsafe {
156 REFCOUNT_STOP1 += 1;
157 },
158 }
159
160 // set the xxxRST bit
161 let reset_ptr = self.reset_ptr();
162 if let Some(reset_ptr) = reset_ptr {
163 unsafe {
164 let val = reset_ptr.read_volatile();
165 reset_ptr.write_volatile(val | 1u32 << self.reset_bit);
166 }
167 }
168
169 // set the xxxEN bit
170 let enable_ptr = self.enable_ptr();
171 unsafe {
172 let val = enable_ptr.read_volatile();
173 enable_ptr.write_volatile(val | 1u32 << self.enable_bit);
174 }
175
176 // we must wait two peripheral clock cycles before the clock is active
177 // this seems to work, but might be incorrect
178 // see http://efton.sk/STM32/gotcha/g183.html
179
180 // dummy read (like in the ST HALs)
181 let _ = unsafe { enable_ptr.read_volatile() };
182
183 // DSB for good measure
184 cortex_m::asm::dsb();
185
186 // clear the xxxRST bit
187 if let Some(reset_ptr) = reset_ptr {
188 unsafe {
189 let val = reset_ptr.read_volatile();
190 reset_ptr.write_volatile(val & !(1u32 << self.reset_bit));
191 }
192 }
193 }
194
195 // TODO: should this be `unsafe`?
196 pub(crate) fn disable_with_cs(&self, _cs: CriticalSection) {
197 if self.refcount_idx_or_0xff != 0xff {
198 let refcount_idx = self.refcount_idx_or_0xff as usize;
199 unsafe {
200 crate::_generated::REFCOUNTS[refcount_idx] -= 1;
201 }
202 if unsafe { crate::_generated::REFCOUNTS[refcount_idx] } > 0 {
203 return;
204 }
205 }
206
207 #[cfg(feature = "low-power")]
208 match self.stop_mode {
209 StopMode::Standby => {}
210 StopMode::Stop2 => unsafe {
211 REFCOUNT_STOP2 -= 1;
212 },
213 StopMode::Stop1 => unsafe {
214 REFCOUNT_STOP1 -= 1;
215 },
216 }
217
218 // clear the xxxEN bit
219 let enable_ptr = self.enable_ptr();
220 unsafe {
221 let val = enable_ptr.read_volatile();
222 enable_ptr.write_volatile(val & !(1u32 << self.enable_bit));
223 }
224 }
225
226 // TODO: should this be `unsafe`?
227 pub(crate) fn enable_and_reset(&self) {
228 critical_section::with(|cs| self.enable_and_reset_with_cs(cs))
229 }
230
231 // TODO: should this be `unsafe`?
232 pub(crate) fn disable(&self) {
233 critical_section::with(|cs| self.disable_with_cs(cs))
234 }
235
236 fn reset_ptr(&self) -> Option<*mut u32> {
237 if self.reset_offset_or_0xff != 0xff {
238 Some(unsafe { (RCC.as_ptr() as *mut u32).add(self.reset_offset_or_0xff as _) })
239 } else {
240 None
241 }
242 }
243
244 fn enable_ptr(&self) -> *mut u32 {
245 unsafe { (RCC.as_ptr() as *mut u32).add(self.enable_offset as _) }
246 }
247}
248
87#[allow(unused)] 249#[allow(unused)]
88mod util { 250mod util {
89 use crate::time::Hertz; 251 use crate::time::Hertz;
@@ -128,8 +290,9 @@ pub fn frequency<T: RccPeripheral>() -> Hertz {
128/// # Safety 290/// # Safety
129/// 291///
130/// Peripheral must not be in use. 292/// Peripheral must not be in use.
131pub unsafe fn enable_and_reset<T: RccPeripheral>() { 293// TODO: should this be `unsafe`?
132 T::enable_and_reset(); 294pub fn enable_and_reset_with_cs<T: RccPeripheral>(cs: CriticalSection) {
295 T::RCC_INFO.enable_and_reset_with_cs(cs);
133} 296}
134 297
135/// Disables peripheral `T`. 298/// Disables peripheral `T`.
@@ -137,52 +300,27 @@ pub unsafe fn enable_and_reset<T: RccPeripheral>() {
137/// # Safety 300/// # Safety
138/// 301///
139/// Peripheral must not be in use. 302/// Peripheral must not be in use.
140pub unsafe fn disable<T: RccPeripheral>() { 303// TODO: should this be `unsafe`?
141 T::disable(); 304pub fn disable_with_cs<T: RccPeripheral>(cs: CriticalSection) {
305 T::RCC_INFO.disable_with_cs(cs);
142} 306}
143 307
144/// Struct representing some clock enable bit (xxxENR.xxEN), only known at runtime. 308/// Enables and resets peripheral `T`.
145#[derive(Clone, Copy)] 309///
146pub(crate) struct ClockEnableBit { 310/// # Safety
147 /// offset in 32bit words of the xxxENR register into the RCC register block. 311///
148 offset: u8, 312/// Peripheral must not be in use.
149 /// bit within the register (0..=31) 313// TODO: should this be `unsafe`?
150 bit: u8, 314pub fn enable_and_reset<T: RccPeripheral>() {
315 T::RCC_INFO.enable_and_reset();
151} 316}
152 317
153impl ClockEnableBit { 318/// Disables peripheral `T`.
154 /// Safety: offset+bit must correspond to a valid xxxEN bit. 319///
155 pub(crate) const unsafe fn new(offset: u8, bit: u8) -> Self { 320/// # Safety
156 Self { offset, bit } 321///
157 } 322/// Peripheral must not be in use.
158 323// TODO: should this be `unsafe`?
159 fn ptr(self) -> *mut u32 { 324pub fn disable<T: RccPeripheral>() {
160 unsafe { (RCC.as_ptr() as *mut u32).add(self.offset as _) } 325 T::RCC_INFO.disable();
161 }
162
163 #[allow(unused)]
164 pub(crate) fn enable_with_cs(self, _cs: CriticalSection) {
165 let p = self.ptr();
166 unsafe {
167 let val = p.read_volatile();
168 p.write_volatile(val | 1u32 << self.bit);
169 }
170 }
171
172 pub(crate) fn disable_with_cs(self, _cs: CriticalSection) {
173 let p = self.ptr();
174 unsafe {
175 let val = p.read_volatile();
176 p.write_volatile(val & !(1u32 << self.bit));
177 }
178 }
179
180 #[allow(unused)]
181 pub(crate) fn enable(self) {
182 critical_section::with(|cs| self.enable_with_cs(cs))
183 }
184
185 pub(crate) fn disable(self) {
186 critical_section::with(|cs| self.disable_with_cs(cs))
187 }
188} 326}
diff --git a/embassy-stm32/src/rng.rs b/embassy-stm32/src/rng.rs
index 7a228e4a4..94491c32f 100644
--- a/embassy-stm32/src/rng.rs
+++ b/embassy-stm32/src/rng.rs
@@ -10,7 +10,7 @@ use embassy_sync::waitqueue::AtomicWaker;
10use rand_core::{CryptoRng, RngCore}; 10use rand_core::{CryptoRng, RngCore};
11 11
12use crate::interrupt::typelevel::Interrupt; 12use crate::interrupt::typelevel::Interrupt;
13use crate::{interrupt, pac, peripherals, Peripheral}; 13use crate::{interrupt, pac, peripherals, rcc, Peripheral};
14 14
15static RNG_WAKER: AtomicWaker = AtomicWaker::new(); 15static RNG_WAKER: AtomicWaker = AtomicWaker::new();
16 16
@@ -52,7 +52,7 @@ impl<'d, T: Instance> Rng<'d, T> {
52 inner: impl Peripheral<P = T> + 'd, 52 inner: impl Peripheral<P = T> + 'd,
53 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 53 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
54 ) -> Self { 54 ) -> Self {
55 T::enable_and_reset(); 55 rcc::enable_and_reset::<T>();
56 into_ref!(inner); 56 into_ref!(inner);
57 let mut random = Self { _inner: inner }; 57 let mut random = Self { _inner: inner };
58 random.reset(); 58 random.reset();
diff --git a/embassy-stm32/src/rtc/mod.rs b/embassy-stm32/src/rtc/mod.rs
index cb9c10676..a7f70b153 100644
--- a/embassy-stm32/src/rtc/mod.rs
+++ b/embassy-stm32/src/rtc/mod.rs
@@ -142,7 +142,7 @@ impl Rtc {
142 /// Create a new RTC instance. 142 /// Create a new RTC instance.
143 pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self { 143 pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self {
144 #[cfg(not(any(stm32l0, stm32f3, stm32l1, stm32f0, stm32f2)))] 144 #[cfg(not(any(stm32l0, stm32f3, stm32l1, stm32f0, stm32f2)))]
145 <RTC as crate::rcc::SealedRccPeripheral>::enable_and_reset(); 145 crate::rcc::enable_and_reset::<RTC>();
146 146
147 let mut this = Self { 147 let mut this = Self {
148 #[cfg(feature = "low-power")] 148 #[cfg(feature = "low-power")]
diff --git a/embassy-stm32/src/sai/mod.rs b/embassy-stm32/src/sai/mod.rs
index 54dd81524..3faecdc33 100644
--- a/embassy-stm32/src/sai/mod.rs
+++ b/embassy-stm32/src/sai/mod.rs
@@ -11,7 +11,7 @@ pub use crate::dma::word;
11use crate::dma::{ringbuffer, Channel, ReadableRingBuffer, Request, TransferOptions, WritableRingBuffer}; 11use crate::dma::{ringbuffer, Channel, ReadableRingBuffer, Request, TransferOptions, WritableRingBuffer};
12use crate::gpio::{AFType, AnyPin, SealedPin as _}; 12use crate::gpio::{AFType, AnyPin, SealedPin as _};
13use crate::pac::sai::{vals, Sai as Regs}; 13use crate::pac::sai::{vals, Sai as Regs};
14use crate::rcc::RccPeripheral; 14use crate::rcc::{self, RccPeripheral};
15use crate::{peripherals, Peripheral}; 15use crate::{peripherals, Peripheral};
16 16
17/// SAI error 17/// SAI error
@@ -722,7 +722,7 @@ pub struct SubBlock<'d, T, S: SubBlockInstance> {
722/// You can then create a [`Sai`] driver for each each half. 722/// You can then create a [`Sai`] driver for each each half.
723pub fn split_subblocks<'d, T: Instance>(peri: impl Peripheral<P = T> + 'd) -> (SubBlock<'d, T, A>, SubBlock<'d, T, B>) { 723pub fn split_subblocks<'d, T: Instance>(peri: impl Peripheral<P = T> + 'd) -> (SubBlock<'d, T, A>, SubBlock<'d, T, B>) {
724 into_ref!(peri); 724 into_ref!(peri);
725 T::enable_and_reset(); 725 rcc::enable_and_reset::<T>();
726 726
727 ( 727 (
728 SubBlock { 728 SubBlock {
@@ -978,7 +978,7 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> {
978 978
979 /// Reset SAI operation. 979 /// Reset SAI operation.
980 pub fn reset() { 980 pub fn reset() {
981 T::enable_and_reset(); 981 rcc::enable_and_reset::<T>();
982 } 982 }
983 983
984 /// Flush. 984 /// Flush.
diff --git a/embassy-stm32/src/sdmmc/mod.rs b/embassy-stm32/src/sdmmc/mod.rs
index f79a11606..9c14837e1 100644
--- a/embassy-stm32/src/sdmmc/mod.rs
+++ b/embassy-stm32/src/sdmmc/mod.rs
@@ -16,7 +16,7 @@ use crate::dma::NoDma;
16use crate::gpio::{AFType, AnyPin, Pull, SealedPin, Speed}; 16use crate::gpio::{AFType, AnyPin, Pull, SealedPin, Speed};
17use crate::interrupt::typelevel::Interrupt; 17use crate::interrupt::typelevel::Interrupt;
18use crate::pac::sdmmc::Sdmmc as RegBlock; 18use crate::pac::sdmmc::Sdmmc as RegBlock;
19use crate::rcc::RccPeripheral; 19use crate::rcc::{self, RccPeripheral};
20use crate::time::Hertz; 20use crate::time::Hertz;
21use crate::{interrupt, peripherals, Peripheral}; 21use crate::{interrupt, peripherals, Peripheral};
22 22
@@ -468,7 +468,7 @@ impl<'d, T: Instance, Dma: SdmmcDma<T> + 'd> Sdmmc<'d, T, Dma> {
468 ) -> Self { 468 ) -> Self {
469 into_ref!(sdmmc, dma); 469 into_ref!(sdmmc, dma);
470 470
471 T::enable_and_reset(); 471 rcc::enable_and_reset::<T>();
472 472
473 T::Interrupt::unpend(); 473 T::Interrupt::unpend();
474 unsafe { T::Interrupt::enable() }; 474 unsafe { T::Interrupt::enable() };
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs
index 7fb8da5ac..af8e3fc30 100644
--- a/embassy-stm32/src/spi/mod.rs
+++ b/embassy-stm32/src/spi/mod.rs
@@ -13,7 +13,7 @@ use crate::dma::{slice_ptr_parts, word, ChannelAndRequest};
13use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _, Speed}; 13use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _, Speed};
14use crate::mode::{Async, Blocking, Mode as PeriMode}; 14use crate::mode::{Async, Blocking, Mode as PeriMode};
15use crate::pac::spi::{regs, vals, Spi as Regs}; 15use crate::pac::spi::{regs, vals, Spi as Regs};
16use crate::rcc::{ClockEnableBit, SealedRccPeripheral}; 16use crate::rcc::{self, RccInfo, SealedRccPeripheral};
17use crate::time::Hertz; 17use crate::time::Hertz;
18use crate::Peripheral; 18use crate::Peripheral;
19 19
@@ -129,7 +129,7 @@ impl<'d, M: PeriMode> Spi<'d, M> {
129 129
130 let lsbfirst = config.raw_byte_order(); 130 let lsbfirst = config.raw_byte_order();
131 131
132 T::enable_and_reset(); 132 rcc::enable_and_reset::<T>();
133 133
134 #[cfg(any(spi_v1, spi_f1))] 134 #[cfg(any(spi_v1, spi_f1))]
135 { 135 {
@@ -830,7 +830,7 @@ impl<'d, M: PeriMode> Drop for Spi<'d, M> {
830 self.mosi.as_ref().map(|x| x.set_as_disconnected()); 830 self.mosi.as_ref().map(|x| x.set_as_disconnected());
831 self.miso.as_ref().map(|x| x.set_as_disconnected()); 831 self.miso.as_ref().map(|x| x.set_as_disconnected());
832 832
833 self.info.enable_bit.disable(); 833 self.info.rcc.disable();
834 } 834 }
835} 835}
836 836
@@ -1216,7 +1216,7 @@ mod word_impl {
1216 1216
1217pub(crate) struct Info { 1217pub(crate) struct Info {
1218 pub(crate) regs: Regs, 1218 pub(crate) regs: Regs,
1219 pub(crate) enable_bit: ClockEnableBit, 1219 pub(crate) rcc: RccInfo,
1220} 1220}
1221 1221
1222struct State {} 1222struct State {}
@@ -1243,7 +1243,7 @@ foreach_peripheral!(
1243 (spi, $inst:ident) => { 1243 (spi, $inst:ident) => {
1244 peri_trait_impl!($inst, Info { 1244 peri_trait_impl!($inst, Info {
1245 regs: crate::pac::$inst, 1245 regs: crate::pac::$inst,
1246 enable_bit: crate::peripherals::$inst::ENABLE_BIT, 1246 rcc: crate::peripherals::$inst::RCC_INFO,
1247 }); 1247 });
1248 }; 1248 };
1249); 1249);
diff --git a/embassy-stm32/src/time_driver.rs b/embassy-stm32/src/time_driver.rs
index e592fbf7d..f8041bf1e 100644
--- a/embassy-stm32/src/time_driver.rs
+++ b/embassy-stm32/src/time_driver.rs
@@ -12,7 +12,7 @@ use stm32_metapac::timer::{regs, TimGp16};
12 12
13use crate::interrupt::typelevel::Interrupt; 13use crate::interrupt::typelevel::Interrupt;
14use crate::pac::timer::vals; 14use crate::pac::timer::vals;
15use crate::rcc::SealedRccPeripheral; 15use crate::rcc::{self, SealedRccPeripheral};
16#[cfg(feature = "low-power")] 16#[cfg(feature = "low-power")]
17use crate::rtc::Rtc; 17use crate::rtc::Rtc;
18use crate::timer::{CoreInstance, GeneralInstance1Channel}; 18use crate::timer::{CoreInstance, GeneralInstance1Channel};
@@ -276,7 +276,7 @@ impl RtcDriver {
276 fn init(&'static self, cs: critical_section::CriticalSection) { 276 fn init(&'static self, cs: critical_section::CriticalSection) {
277 let r = regs_gp16(); 277 let r = regs_gp16();
278 278
279 <T as SealedRccPeripheral>::enable_and_reset_with_cs(cs); 279 rcc::enable_and_reset_with_cs::<T>(cs);
280 280
281 let timer_freq = T::frequency(); 281 let timer_freq = T::frequency();
282 282
diff --git a/embassy-stm32/src/timer/low_level.rs b/embassy-stm32/src/timer/low_level.rs
index 7f533b75c..9932c04cd 100644
--- a/embassy-stm32/src/timer/low_level.rs
+++ b/embassy-stm32/src/timer/low_level.rs
@@ -10,6 +10,7 @@ use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
10 10
11use super::*; 11use super::*;
12use crate::pac::timer::vals; 12use crate::pac::timer::vals;
13use crate::rcc;
13use crate::time::Hertz; 14use crate::time::Hertz;
14 15
15/// Input capture mode. 16/// Input capture mode.
@@ -181,7 +182,7 @@ pub struct Timer<'d, T: CoreInstance> {
181 182
182impl<'d, T: CoreInstance> Drop for Timer<'d, T> { 183impl<'d, T: CoreInstance> Drop for Timer<'d, T> {
183 fn drop(&mut self) { 184 fn drop(&mut self) {
184 T::disable() 185 rcc::disable::<T>();
185 } 186 }
186} 187}
187 188
@@ -190,7 +191,7 @@ impl<'d, T: CoreInstance> Timer<'d, T> {
190 pub fn new(tim: impl Peripheral<P = T> + 'd) -> Self { 191 pub fn new(tim: impl Peripheral<P = T> + 'd) -> Self {
191 into_ref!(tim); 192 into_ref!(tim);
192 193
193 T::enable_and_reset(); 194 rcc::enable_and_reset::<T>();
194 195
195 Self { tim } 196 Self { tim }
196 } 197 }
diff --git a/embassy-stm32/src/tsc/mod.rs b/embassy-stm32/src/tsc/mod.rs
index bf583f04c..045d6317c 100644
--- a/embassy-stm32/src/tsc/mod.rs
+++ b/embassy-stm32/src/tsc/mod.rs
@@ -72,7 +72,7 @@ pub use enums::*;
72 72
73use crate::gpio::{AFType, AnyPin}; 73use crate::gpio::{AFType, AnyPin};
74use crate::pac::tsc::Tsc as Regs; 74use crate::pac::tsc::Tsc as Regs;
75use crate::rcc::RccPeripheral; 75use crate::rcc::{self, RccPeripheral};
76use crate::{peripherals, Peripheral}; 76use crate::{peripherals, Peripheral};
77 77
78#[cfg(tsc_v1)] 78#[cfg(tsc_v1)]
@@ -649,7 +649,7 @@ impl<'d, T: Instance> Tsc<'d, T> {
649 ) -> Self { 649 ) -> Self {
650 into_ref!(peri); 650 into_ref!(peri);
651 651
652 T::enable_and_reset(); 652 rcc::enable_and_reset::<T>();
653 653
654 T::REGS.cr().modify(|w| { 654 T::REGS.cr().modify(|w| {
655 w.set_tsce(true); 655 w.set_tsce(true);
@@ -880,7 +880,7 @@ impl<'d, T: Instance> Tsc<'d, T> {
880 880
881impl<'d, T: Instance> Drop for Tsc<'d, T> { 881impl<'d, T: Instance> Drop for Tsc<'d, T> {
882 fn drop(&mut self) { 882 fn drop(&mut self) {
883 T::disable(); 883 rcc::disable::<T>();
884 } 884 }
885} 885}
886 886
diff --git a/embassy-stm32/src/ucpd.rs b/embassy-stm32/src/ucpd.rs
index d6d0682b9..89e2f5d49 100644
--- a/embassy-stm32/src/ucpd.rs
+++ b/embassy-stm32/src/ucpd.rs
@@ -28,7 +28,7 @@ use crate::interrupt;
28use crate::interrupt::typelevel::Interrupt; 28use crate::interrupt::typelevel::Interrupt;
29use crate::pac::ucpd::vals::{Anamode, Ccenable, PscUsbpdclk, Txmode}; 29use crate::pac::ucpd::vals::{Anamode, Ccenable, PscUsbpdclk, Txmode};
30pub use crate::pac::ucpd::vals::{Phyccsel as CcSel, TypecVstateCc as CcVState}; 30pub use crate::pac::ucpd::vals::{Phyccsel as CcSel, TypecVstateCc as CcVState};
31use crate::rcc::RccPeripheral; 31use crate::rcc::{self, RccPeripheral};
32 32
33pub(crate) fn init( 33pub(crate) fn init(
34 _cs: critical_section::CriticalSection, 34 _cs: critical_section::CriticalSection,
@@ -103,7 +103,7 @@ impl<'d, T: Instance> Ucpd<'d, T> {
103 cc1.set_as_analog(); 103 cc1.set_as_analog();
104 cc2.set_as_analog(); 104 cc2.set_as_analog();
105 105
106 T::enable_and_reset(); 106 rcc::enable_and_reset::<T>();
107 T::Interrupt::unpend(); 107 T::Interrupt::unpend();
108 unsafe { T::Interrupt::enable() }; 108 unsafe { T::Interrupt::enable() };
109 109
@@ -212,7 +212,7 @@ impl<'d, T: Instance> Drop for CcPhy<'d, T> {
212 drop_not_ready.store(true, Ordering::Relaxed); 212 drop_not_ready.store(true, Ordering::Relaxed);
213 } else { 213 } else {
214 r.cfgr1().write(|w| w.set_ucpden(false)); 214 r.cfgr1().write(|w| w.set_ucpden(false));
215 T::disable(); 215 rcc::disable::<T>();
216 T::Interrupt::disable(); 216 T::Interrupt::disable();
217 } 217 }
218 } 218 }
@@ -325,7 +325,7 @@ impl<'d, T: Instance> Drop for PdPhy<'d, T> {
325 drop_not_ready.store(true, Ordering::Relaxed); 325 drop_not_ready.store(true, Ordering::Relaxed);
326 } else { 326 } else {
327 T::REGS.cfgr1().write(|w| w.set_ucpden(false)); 327 T::REGS.cfgr1().write(|w| w.set_ucpden(false));
328 T::disable(); 328 rcc::disable::<T>();
329 T::Interrupt::disable(); 329 T::Interrupt::disable();
330 } 330 }
331 } 331 }
diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs
index 492ad334b..eacf95002 100644
--- a/embassy-stm32/src/usart/buffered.rs
+++ b/embassy-stm32/src/usart/buffered.rs
@@ -18,6 +18,7 @@ use super::{
18use crate::gpio::AFType; 18use crate::gpio::AFType;
19use crate::interrupt::typelevel::Interrupt as _; 19use crate::interrupt::typelevel::Interrupt as _;
20use crate::interrupt::{self, InterruptExt}; 20use crate::interrupt::{self, InterruptExt};
21use crate::rcc;
21use crate::time::Hertz; 22use crate::time::Hertz;
22 23
23/// Interrupt handler. 24/// Interrupt handler.
@@ -206,7 +207,7 @@ impl<'d> BufferedUart<'d> {
206 rx_buffer: &'d mut [u8], 207 rx_buffer: &'d mut [u8],
207 config: Config, 208 config: Config,
208 ) -> Result<Self, ConfigError> { 209 ) -> Result<Self, ConfigError> {
209 T::enable_and_reset(); 210 rcc::enable_and_reset::<T>();
210 211
211 Self::new_inner(peri, rx, tx, tx_buffer, rx_buffer, config) 212 Self::new_inner(peri, rx, tx, tx_buffer, rx_buffer, config)
212 } 213 }
@@ -225,7 +226,7 @@ impl<'d> BufferedUart<'d> {
225 ) -> Result<Self, ConfigError> { 226 ) -> Result<Self, ConfigError> {
226 into_ref!(cts, rts); 227 into_ref!(cts, rts);
227 228
228 T::enable_and_reset(); 229 rcc::enable_and_reset::<T>();
229 230
230 rts.set_as_af(rts.af_num(), AFType::OutputPushPull); 231 rts.set_as_af(rts.af_num(), AFType::OutputPushPull);
231 cts.set_as_af(cts.af_num(), AFType::Input); 232 cts.set_as_af(cts.af_num(), AFType::Input);
@@ -251,7 +252,7 @@ impl<'d> BufferedUart<'d> {
251 ) -> Result<Self, ConfigError> { 252 ) -> Result<Self, ConfigError> {
252 into_ref!(de); 253 into_ref!(de);
253 254
254 T::enable_and_reset(); 255 rcc::enable_and_reset::<T>();
255 256
256 de.set_as_af(de.af_num(), AFType::OutputPushPull); 257 de.set_as_af(de.af_num(), AFType::OutputPushPull);
257 T::info().regs.cr3().write(|w| { 258 T::info().regs.cr3().write(|w| {
@@ -545,7 +546,7 @@ fn drop_tx_rx(info: &Info, state: &State) {
545 refcount == 1 546 refcount == 1
546 }); 547 });
547 if is_last_drop { 548 if is_last_drop {
548 info.enable_bit.disable(); 549 info.rcc.disable();
549 } 550 }
550} 551}
551 552
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs
index b24335f3a..2a39c6301 100644
--- a/embassy-stm32/src/usart/mod.rs
+++ b/embassy-stm32/src/usart/mod.rs
@@ -28,7 +28,7 @@ use crate::pac::usart::Lpuart as Regs;
28#[cfg(any(usart_v1, usart_v2))] 28#[cfg(any(usart_v1, usart_v2))]
29use crate::pac::usart::Usart as Regs; 29use crate::pac::usart::Usart as Regs;
30use crate::pac::usart::{regs, vals}; 30use crate::pac::usart::{regs, vals};
31use crate::rcc::{ClockEnableBit, SealedRccPeripheral}; 31use crate::rcc::{self, RccInfo, SealedRccPeripheral};
32use crate::time::Hertz; 32use crate::time::Hertz;
33use crate::Peripheral; 33use crate::Peripheral;
34 34
@@ -429,7 +429,7 @@ impl<'d, M: Mode> UartTx<'d, M> {
429 tx_dma: Option<ChannelAndRequest<'d>>, 429 tx_dma: Option<ChannelAndRequest<'d>>,
430 config: Config, 430 config: Config,
431 ) -> Result<Self, ConfigError> { 431 ) -> Result<Self, ConfigError> {
432 T::enable_and_reset(); 432 rcc::enable_and_reset::<T>();
433 433
434 let info = T::info(); 434 let info = T::info();
435 let state = T::state(); 435 let state = T::state();
@@ -775,7 +775,7 @@ impl<'d, M: Mode> UartRx<'d, M> {
775 rx_dma: Option<ChannelAndRequest<'d>>, 775 rx_dma: Option<ChannelAndRequest<'d>>,
776 config: Config, 776 config: Config,
777 ) -> Result<Self, ConfigError> { 777 ) -> Result<Self, ConfigError> {
778 T::enable_and_reset(); 778 rcc::enable_and_reset::<T>();
779 779
780 let info = T::info(); 780 let info = T::info();
781 let state = T::state(); 781 let state = T::state();
@@ -916,7 +916,7 @@ fn drop_tx_rx(info: &Info, state: &State) {
916 refcount == 1 916 refcount == 1
917 }); 917 });
918 if is_last_drop { 918 if is_last_drop {
919 info.enable_bit.disable(); 919 info.rcc.disable();
920 } 920 }
921} 921}
922 922
@@ -1228,7 +1228,7 @@ impl<'d, M: Mode> Uart<'d, M> {
1228 rx_dma: Option<ChannelAndRequest<'d>>, 1228 rx_dma: Option<ChannelAndRequest<'d>>,
1229 config: Config, 1229 config: Config,
1230 ) -> Result<Self, ConfigError> { 1230 ) -> Result<Self, ConfigError> {
1231 T::enable_and_reset(); 1231 rcc::enable_and_reset::<T>();
1232 1232
1233 let info = T::info(); 1233 let info = T::info();
1234 let state = T::state(); 1234 let state = T::state();
@@ -1718,7 +1718,7 @@ impl State {
1718 1718
1719struct Info { 1719struct Info {
1720 regs: Regs, 1720 regs: Regs,
1721 enable_bit: ClockEnableBit, 1721 rcc: RccInfo,
1722 interrupt: Interrupt, 1722 interrupt: Interrupt,
1723 kind: Kind, 1723 kind: Kind,
1724} 1724}
@@ -1754,7 +1754,7 @@ macro_rules! impl_usart {
1754 fn info() -> &'static Info { 1754 fn info() -> &'static Info {
1755 static INFO: Info = Info { 1755 static INFO: Info = Info {
1756 regs: unsafe { Regs::from_ptr(crate::pac::$inst.as_ptr()) }, 1756 regs: unsafe { Regs::from_ptr(crate::pac::$inst.as_ptr()) },
1757 enable_bit: crate::peripherals::$inst::ENABLE_BIT, 1757 rcc: crate::peripherals::$inst::RCC_INFO,
1758 interrupt: crate::interrupt::typelevel::$irq::IRQ, 1758 interrupt: crate::interrupt::typelevel::$irq::IRQ,
1759 kind: $kind, 1759 kind: $kind,
1760 }; 1760 };
diff --git a/embassy-stm32/src/usb/mod.rs b/embassy-stm32/src/usb/mod.rs
index 349438ec5..ce9fe0a9b 100644
--- a/embassy-stm32/src/usb/mod.rs
+++ b/embassy-stm32/src/usb/mod.rs
@@ -6,7 +6,7 @@ mod _version;
6pub use _version::*; 6pub use _version::*;
7 7
8use crate::interrupt::typelevel::Interrupt; 8use crate::interrupt::typelevel::Interrupt;
9use crate::rcc::SealedRccPeripheral; 9use crate::rcc;
10 10
11/// clock, power initialization stuff that's common for USB and OTG. 11/// clock, power initialization stuff that's common for USB and OTG.
12fn common_init<T: Instance>() { 12fn common_init<T: Instance>() {
@@ -65,5 +65,5 @@ fn common_init<T: Instance>() {
65 T::Interrupt::unpend(); 65 T::Interrupt::unpend();
66 unsafe { T::Interrupt::enable() }; 66 unsafe { T::Interrupt::enable() };
67 67
68 <T as SealedRccPeripheral>::enable_and_reset(); 68 rcc::enable_and_reset::<T>();
69} 69}
diff --git a/embassy-stm32/src/usb/otg.rs b/embassy-stm32/src/usb/otg.rs
index 3debd5079..e5131250a 100644
--- a/embassy-stm32/src/usb/otg.rs
+++ b/embassy-stm32/src/usb/otg.rs
@@ -13,7 +13,7 @@ use embassy_usb_synopsys_otg::{
13use crate::gpio::AFType; 13use crate::gpio::AFType;
14use crate::interrupt; 14use crate::interrupt;
15use crate::interrupt::typelevel::Interrupt; 15use crate::interrupt::typelevel::Interrupt;
16use crate::rcc::{RccPeripheral, SealedRccPeripheral}; 16use crate::rcc::{self, RccPeripheral};
17 17
18const MAX_EP_COUNT: usize = 9; 18const MAX_EP_COUNT: usize = 9;
19 19
@@ -246,7 +246,7 @@ impl<'d, T: Instance> Bus<'d, T> {
246 fn disable(&mut self) { 246 fn disable(&mut self) {
247 T::Interrupt::disable(); 247 T::Interrupt::disable();
248 248
249 <T as SealedRccPeripheral>::disable(); 249 rcc::disable::<T>();
250 self.inited = false; 250 self.inited = false;
251 251
252 #[cfg(stm32l4)] 252 #[cfg(stm32l4)]