stm32/rcc: replace generated enable/disable code with runtime info
This commit is contained in:
		
							parent
							
								
									01c1cb2764
								
							
						
					
					
						commit
						081afca3f0
					
				| @ -367,9 +367,6 @@ fn main() { | ||||
|         .filter_map(|p| p.registers.as_ref()) | ||||
|         .find(|r| r.kind == "rcc") | ||||
|         .unwrap(); | ||||
|     for b in rcc_registers.ir.blocks { | ||||
|         eprintln!("{}", b.name); | ||||
|     } | ||||
|     let rcc_block = rcc_registers.ir.blocks.iter().find(|b| b.name == "Rcc").unwrap(); | ||||
| 
 | ||||
|     // ========
 | ||||
| @ -388,7 +385,6 @@ fn main() { | ||||
|         rcc_registers: &'a PeripheralRegisters, | ||||
|         chained_muxes: HashMap<&'a str, &'a PeripheralRccRegister>, | ||||
| 
 | ||||
|         refcount_statics: BTreeSet<Ident>, | ||||
|         clock_names: BTreeSet<String>, | ||||
|         muxes: BTreeSet<(Ident, Ident, Ident)>, | ||||
|     } | ||||
| @ -397,7 +393,6 @@ fn main() { | ||||
|         rcc_registers, | ||||
|         chained_muxes: HashMap::new(), | ||||
| 
 | ||||
|         refcount_statics: BTreeSet::new(), | ||||
|         clock_names: BTreeSet::new(), | ||||
|         muxes: BTreeSet::new(), | ||||
|     }; | ||||
| @ -516,80 +511,64 @@ fn main() { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     let mut refcount_idxs = HashMap::new(); | ||||
| 
 | ||||
|     for p in METADATA.peripherals { | ||||
|         if !singletons.contains(&p.name.to_string()) { | ||||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|         if let Some(rcc) = &p.rcc { | ||||
|             let en = rcc.enable.as_ref().unwrap(); | ||||
| 
 | ||||
|             let (start_rst, end_rst) = match &rcc.reset { | ||||
|                 Some(rst) => { | ||||
|                     let rst_reg = format_ident!("{}", rst.register.to_ascii_lowercase()); | ||||
|                     let set_rst_field = format_ident!("set_{}", rst.field.to_ascii_lowercase()); | ||||
|                     ( | ||||
|                         quote! { | ||||
|                             crate::pac::RCC.#rst_reg().modify(|w| w.#set_rst_field(true)); | ||||
|                         }, | ||||
|                         quote! { | ||||
|                             crate::pac::RCC.#rst_reg().modify(|w| w.#set_rst_field(false)); | ||||
|                         }, | ||||
|                     ) | ||||
|                 } | ||||
|                 None => (TokenStream::new(), TokenStream::new()), | ||||
|             }; | ||||
| 
 | ||||
|             let rst_reg = rcc.reset.as_ref(); | ||||
|             let en_reg = rcc.enable.as_ref().unwrap(); | ||||
|             let pname = format_ident!("{}", p.name); | ||||
|             let en_reg = format_ident!("{}", en.register.to_ascii_lowercase()); | ||||
|             let set_en_field = format_ident!("set_{}", en.field.to_ascii_lowercase()); | ||||
|             let en_reg_offs = rcc_block | ||||
| 
 | ||||
|             let get_offset_and_bit = |reg: &PeripheralRccRegister| -> TokenStream { | ||||
|                 let reg_offset = rcc_block | ||||
|                     .items | ||||
|                     .iter() | ||||
|                 .find(|i| i.name.eq_ignore_ascii_case(en.register)) | ||||
|                     .find(|i| i.name.eq_ignore_ascii_case(reg.register)) | ||||
|                     .unwrap() | ||||
|                     .byte_offset; | ||||
|             let en_reg_offs: u8 = (en_reg_offs / 4).try_into().unwrap(); | ||||
|                 let reg_offset: u8 = (reg_offset / 4).try_into().unwrap(); | ||||
| 
 | ||||
|             let en_bit_offs = &rcc_registers | ||||
|                 let bit_offset = &rcc_registers | ||||
|                     .ir | ||||
|                     .fieldsets | ||||
|                     .iter() | ||||
|                 .find(|i| i.name.eq_ignore_ascii_case(en.register)) | ||||
|                     .find(|i| i.name.eq_ignore_ascii_case(reg.register)) | ||||
|                     .unwrap() | ||||
|                     .fields | ||||
|                     .iter() | ||||
|                 .find(|i| i.name.eq_ignore_ascii_case(en.field)) | ||||
|                     .find(|i| i.name.eq_ignore_ascii_case(reg.field)) | ||||
|                     .unwrap() | ||||
|                     .bit_offset; | ||||
|             let BitOffset::Regular(en_bit_offs) = en_bit_offs else { | ||||
|                 let BitOffset::Regular(bit_offset) = bit_offset else { | ||||
|                     panic!("cursed bit offset") | ||||
|                 }; | ||||
|             let en_bit_offs: u8 = en_bit_offs.offset.try_into().unwrap(); | ||||
|                 let bit_offset: u8 = bit_offset.offset.try_into().unwrap(); | ||||
| 
 | ||||
|             let refcount = *rcc_field_count.get(&(en.register, en.field)).unwrap() > 1; | ||||
|             let (before_enable, before_disable) = if refcount { | ||||
|                 let refcount_static = | ||||
|                     format_ident!("{}_{}", en.register.to_ascii_uppercase(), en.field.to_ascii_uppercase()); | ||||
|                 quote! { (#reg_offset, #bit_offset) } | ||||
|             }; | ||||
| 
 | ||||
|                 clock_gen.refcount_statics.insert(refcount_static.clone()); | ||||
| 
 | ||||
|                 ( | ||||
|                     quote! { | ||||
|                         unsafe { refcount_statics::#refcount_static += 1 }; | ||||
|                         if unsafe { refcount_statics::#refcount_static } > 1 { | ||||
|                             return; | ||||
|             let reset_offset_and_bit = match rst_reg { | ||||
|                 Some(rst_reg) => { | ||||
|                     let reset_offset_and_bit = get_offset_and_bit(rst_reg); | ||||
|                     quote! { Some(#reset_offset_and_bit) } | ||||
|                 } | ||||
|                     }, | ||||
|                     quote! { | ||||
|                         unsafe { refcount_statics::#refcount_static -= 1 }; | ||||
|                         if unsafe { refcount_statics::#refcount_static } > 0  { | ||||
|                             return; | ||||
|                         } | ||||
|                     }, | ||||
|                 ) | ||||
|                 None => quote! { None }, | ||||
|             }; | ||||
|             let enable_offset_and_bit = get_offset_and_bit(en_reg); | ||||
| 
 | ||||
|             let needs_refcount = *rcc_field_count.get(&(en_reg.register, en_reg.field)).unwrap() > 1; | ||||
|             let refcount_idx = if needs_refcount { | ||||
|                 let next_refcount_idx = refcount_idxs.len() as u8; | ||||
|                 let refcount_idx = *refcount_idxs | ||||
|                     .entry((en_reg.register, en_reg.field)) | ||||
|                     .or_insert(next_refcount_idx); | ||||
|                 quote! { Some(#refcount_idx) } | ||||
|             } else { | ||||
|                 (TokenStream::new(), TokenStream::new()) | ||||
|                 quote! { None } | ||||
|             }; | ||||
| 
 | ||||
|             let clock_frequency = match &rcc.kernel_clock { | ||||
| @ -599,24 +578,10 @@ fn main() { | ||||
| 
 | ||||
|             // A refcount leak can result if the same field is shared by peripherals with different stop modes
 | ||||
|             // This condition should be checked in stm32-data
 | ||||
|             let stop_refcount = match rcc.stop_mode { | ||||
|                 StopMode::Standby => None, | ||||
|                 StopMode::Stop2 => Some(quote! { REFCOUNT_STOP2 }), | ||||
|                 StopMode::Stop1 => Some(quote! { REFCOUNT_STOP1 }), | ||||
|             }; | ||||
| 
 | ||||
|             let (incr_stop_refcount, decr_stop_refcount) = match stop_refcount { | ||||
|                 Some(stop_refcount) => ( | ||||
|                     quote! { | ||||
|                         #[cfg(feature = "low-power")] | ||||
|                         unsafe { crate::rcc::#stop_refcount += 1 }; | ||||
|                     }, | ||||
|                     quote! { | ||||
|                         #[cfg(feature = "low-power")] | ||||
|                         unsafe { crate::rcc::#stop_refcount -= 1 }; | ||||
|                     }, | ||||
|                 ), | ||||
|                 None => (TokenStream::new(), TokenStream::new()), | ||||
|             let stop_mode = match rcc.stop_mode { | ||||
|                 StopMode::Standby => quote! { crate::rcc::StopMode::Standby }, | ||||
|                 StopMode::Stop2 => quote! { crate::rcc::StopMode::Stop2 }, | ||||
|                 StopMode::Stop1 => quote! { crate::rcc::StopMode::Stop1 }, | ||||
|             }; | ||||
| 
 | ||||
|             g.extend(quote! { | ||||
| @ -624,34 +589,16 @@ fn main() { | ||||
|                     fn frequency() -> crate::time::Hertz { | ||||
|                         #clock_frequency | ||||
|                     } | ||||
|                     fn enable_and_reset_with_cs(_cs: critical_section::CriticalSection) { | ||||
|                         #before_enable | ||||
|                         #incr_stop_refcount | ||||
| 
 | ||||
|                         #start_rst | ||||
| 
 | ||||
|                         crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(true)); | ||||
| 
 | ||||
|                         // we must wait two peripheral clock cycles before the clock is active
 | ||||
|                         // this seems to work, but might be incorrect
 | ||||
|                         // see http://efton.sk/STM32/gotcha/g183.html
 | ||||
| 
 | ||||
|                         // dummy read (like in the ST HALs)
 | ||||
|                         let _ = crate::pac::RCC.#en_reg().read(); | ||||
| 
 | ||||
|                         // DSB for good measure
 | ||||
|                         cortex_m::asm::dsb(); | ||||
| 
 | ||||
|                         #end_rst | ||||
|                     } | ||||
|                     fn disable_with_cs(_cs: critical_section::CriticalSection) { | ||||
|                         #before_disable | ||||
|                         crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(false)); | ||||
|                         #decr_stop_refcount | ||||
|                     } | ||||
| 
 | ||||
|                     const ENABLE_BIT: crate::rcc::ClockEnableBit = | ||||
|                         unsafe { crate::rcc::ClockEnableBit::new(#en_reg_offs, #en_bit_offs) }; | ||||
|                     const RCC_INFO: crate::rcc::RccInfo = unsafe { | ||||
|                         crate::rcc::RccInfo::new( | ||||
|                             #reset_offset_and_bit, | ||||
|                             #enable_offset_and_bit, | ||||
|                             #refcount_idx, | ||||
|                             #[cfg(feature = "low-power")] | ||||
|                             #stop_mode, | ||||
|                         ) | ||||
|                     }; | ||||
|                 } | ||||
| 
 | ||||
|                 impl crate::rcc::RccPeripheral for peripherals::#pname {} | ||||
| @ -659,6 +606,14 @@ fn main() { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     g.extend({ | ||||
|         let refcounts_len = refcount_idxs.len(); | ||||
|         let refcount_zeros: TokenStream = refcount_idxs.iter().map(|_| quote! { 0u8, }).collect(); | ||||
|         quote! { | ||||
|             pub(crate) static mut REFCOUNTS: [u8; #refcounts_len] = [#refcount_zeros]; | ||||
|         } | ||||
|     }); | ||||
| 
 | ||||
|     let struct_fields: Vec<_> = clock_gen | ||||
|         .muxes | ||||
|         .iter() | ||||
| @ -762,22 +717,6 @@ fn main() { | ||||
|         } | ||||
|     ); | ||||
| 
 | ||||
|     let refcount_mod: TokenStream = clock_gen | ||||
|         .refcount_statics | ||||
|         .iter() | ||||
|         .map(|refcount_static| { | ||||
|             quote! { | ||||
|                 pub(crate) static mut #refcount_static: u8 = 0; | ||||
|             } | ||||
|         }) | ||||
|         .collect(); | ||||
| 
 | ||||
|     g.extend(quote! { | ||||
|         mod refcount_statics { | ||||
|             #refcount_mod | ||||
|         } | ||||
|     }); | ||||
| 
 | ||||
|     // ========
 | ||||
|     // Generate fns to enable GPIO, DMA in RCC
 | ||||
| 
 | ||||
|  | ||||
| @ -7,7 +7,7 @@ use embassy_hal_internal::into_ref; | ||||
| use super::blocking_delay_us; | ||||
| use crate::adc::{Adc, AdcChannel, Instance, SampleTime}; | ||||
| use crate::time::Hertz; | ||||
| use crate::{interrupt, Peripheral}; | ||||
| use crate::{interrupt, rcc, Peripheral}; | ||||
| 
 | ||||
| pub const VDDA_CALIB_MV: u32 = 3300; | ||||
| pub const ADC_MAX: u32 = (1 << 12) - 1; | ||||
| @ -50,7 +50,7 @@ impl<T: Instance> super::SealedAdcChannel<T> for Temperature { | ||||
| impl<'d, T: Instance> Adc<'d, T> { | ||||
|     pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self { | ||||
|         into_ref!(adc); | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
|         T::regs().cr2().modify(|reg| reg.set_adon(true)); | ||||
| 
 | ||||
|         // 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> { | ||||
|     fn drop(&mut self) { | ||||
|         T::regs().cr2().modify(|reg| reg.set_adon(false)); | ||||
| 
 | ||||
|         T::disable(); | ||||
|         rcc::disable::<T>(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -8,7 +8,7 @@ use super::blocking_delay_us; | ||||
| use crate::adc::{Adc, AdcChannel, Instance, SampleTime}; | ||||
| use crate::interrupt::typelevel::Interrupt; | ||||
| use crate::time::Hertz; | ||||
| use crate::{interrupt, Peripheral}; | ||||
| use crate::{interrupt, rcc, Peripheral}; | ||||
| 
 | ||||
| pub const VDDA_CALIB_MV: u32 = 3300; | ||||
| pub const ADC_MAX: u32 = (1 << 12) - 1; | ||||
| @ -63,7 +63,7 @@ impl<'d, T: Instance> Adc<'d, T> { | ||||
| 
 | ||||
|         into_ref!(adc); | ||||
| 
 | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         // Enable the adc regulator
 | ||||
|         T::regs().cr().modify(|w| w.set_advregen(vals::Advregen::INTERMEDIATE)); | ||||
| @ -188,6 +188,6 @@ impl<'d, T: Instance> Drop for Adc<'d, T> { | ||||
|         T::regs().cr().modify(|w| w.set_advregen(vals::Advregen::INTERMEDIATE)); | ||||
|         T::regs().cr().modify(|w| w.set_advregen(vals::Advregen::DISABLED)); | ||||
| 
 | ||||
|         T::disable(); | ||||
|         rcc::disable::<T>(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -10,7 +10,7 @@ use super::Resolution; | ||||
| use crate::adc::{Adc, AdcChannel, Instance, SampleTime}; | ||||
| use crate::interrupt::typelevel::Interrupt; | ||||
| use crate::time::Hertz; | ||||
| use crate::{interrupt, Peripheral}; | ||||
| use crate::{interrupt, rcc, Peripheral}; | ||||
| 
 | ||||
| const ADC_FREQ: Hertz = crate::rcc::HSI_FREQ; | ||||
| 
 | ||||
| @ -143,7 +143,7 @@ impl<'d, T: Instance> Adc<'d, T> { | ||||
|     ) -> Self { | ||||
|         into_ref!(adc); | ||||
| 
 | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         //let r = T::regs();
 | ||||
|         //r.cr2().write(|w| w.set_align(true));
 | ||||
| @ -403,6 +403,6 @@ impl<'d, T: Instance> Drop for Adc<'d, T> { | ||||
| 
 | ||||
|         T::regs().cr2().modify(|w| w.set_adon(false)); | ||||
| 
 | ||||
|         T::disable(); | ||||
|         rcc::disable::<T>(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -4,7 +4,7 @@ use pac::adccommon::vals::Presc; | ||||
| 
 | ||||
| use super::{blocking_delay_us, Adc, AdcChannel, Instance, Resolution, SampleTime}; | ||||
| use crate::time::Hertz; | ||||
| use crate::{pac, Peripheral}; | ||||
| use crate::{pac, rcc, Peripheral}; | ||||
| 
 | ||||
| /// Default VREF voltage used for sample conversion to millivolts.
 | ||||
| pub const VREF_DEFAULT_MV: u32 = 3300; | ||||
| @ -130,7 +130,7 @@ impl<'d, T: Instance> Adc<'d, T> { | ||||
|     /// Create a new ADC driver.
 | ||||
|     pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self { | ||||
|         embassy_hal_internal::into_ref!(adc); | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         let prescaler = Prescaler::from_ker_ck(T::frequency()); | ||||
| 
 | ||||
|  | ||||
| @ -10,7 +10,7 @@ use super::blocking_delay_us; | ||||
| use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime}; | ||||
| use crate::interrupt::typelevel::Interrupt; | ||||
| use crate::peripherals::ADC1; | ||||
| use crate::{interrupt, Peripheral}; | ||||
| use crate::{interrupt, rcc, Peripheral}; | ||||
| 
 | ||||
| pub const VDDA_CALIB_MV: u32 = 3300; | ||||
| pub const VREF_INT: u32 = 1230; | ||||
| @ -67,7 +67,7 @@ impl<'d, T: Instance> Adc<'d, T> { | ||||
|         _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | ||||
|     ) -> Self { | ||||
|         into_ref!(adc); | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         // Delay 1μs when using HSI14 as the ADC clock.
 | ||||
|         //
 | ||||
| @ -199,6 +199,6 @@ impl<'d, T: Instance> Drop for Adc<'d, T> { | ||||
|         T::regs().cr().modify(|reg| reg.set_addis(true)); | ||||
|         while T::regs().cr().read().aden() {} | ||||
| 
 | ||||
|         T::disable(); | ||||
|         rcc::disable::<T>(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -4,7 +4,7 @@ use super::blocking_delay_us; | ||||
| use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime}; | ||||
| use crate::peripherals::ADC1; | ||||
| use crate::time::Hertz; | ||||
| use crate::Peripheral; | ||||
| use crate::{rcc, Peripheral}; | ||||
| 
 | ||||
| /// Default VREF voltage used for sample conversion to millivolts.
 | ||||
| pub const VREF_DEFAULT_MV: u32 = 3300; | ||||
| @ -96,7 +96,7 @@ where | ||||
| { | ||||
|     pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self { | ||||
|         into_ref!(adc); | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         let presc = Prescaler::from_pclk2(T::frequency()); | ||||
|         T::common_regs().ccr().modify(|w| w.set_adcpre(presc.adcpre())); | ||||
| @ -206,6 +206,6 @@ impl<'d, T: Instance> Drop for Adc<'d, T> { | ||||
|             reg.set_adon(false); | ||||
|         }); | ||||
| 
 | ||||
|         T::disable(); | ||||
|         rcc::disable::<T>(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -3,7 +3,7 @@ use embassy_hal_internal::into_ref; | ||||
| 
 | ||||
| use super::blocking_delay_us; | ||||
| use crate::adc::{Adc, AdcChannel, Instance, Resolution, SampleTime}; | ||||
| use crate::Peripheral; | ||||
| use crate::{rcc, Peripheral}; | ||||
| 
 | ||||
| /// Default VREF voltage used for sample conversion to millivolts.
 | ||||
| pub const VREF_DEFAULT_MV: u32 = 3300; | ||||
| @ -94,7 +94,7 @@ cfg_if! { | ||||
| impl<'d, T: Instance> Adc<'d, T> { | ||||
|     pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self { | ||||
|         into_ref!(adc); | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
|         T::regs().cr().modify(|reg| { | ||||
|             #[cfg(not(any(adc_g0, adc_u0)))] | ||||
|             reg.set_deeppwd(false); | ||||
|  | ||||
| @ -4,7 +4,7 @@ use pac::adccommon::vals::Presc; | ||||
| 
 | ||||
| use super::{blocking_delay_us, Adc, AdcChannel, Instance, Resolution, SampleTime}; | ||||
| use crate::time::Hertz; | ||||
| use crate::{pac, Peripheral}; | ||||
| use crate::{pac, rcc, Peripheral}; | ||||
| 
 | ||||
| /// Default VREF voltage used for sample conversion to millivolts.
 | ||||
| pub const VREF_DEFAULT_MV: u32 = 3300; | ||||
| @ -130,7 +130,7 @@ impl<'d, T: Instance> Adc<'d, T> { | ||||
|     /// Create a new ADC driver.
 | ||||
|     pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self { | ||||
|         embassy_hal_internal::into_ref!(adc); | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         let prescaler = Prescaler::from_ker_ck(T::frequency()); | ||||
| 
 | ||||
|  | ||||
| @ -19,7 +19,7 @@ use super::util; | ||||
| use crate::can::enums::{BusError, TryReadError}; | ||||
| use crate::gpio::AFType; | ||||
| use crate::interrupt::typelevel::Interrupt; | ||||
| use crate::rcc::RccPeripheral; | ||||
| use crate::rcc::{self, RccPeripheral}; | ||||
| use crate::{interrupt, peripherals, Peripheral}; | ||||
| 
 | ||||
| /// Interrupt handler.
 | ||||
| @ -183,7 +183,7 @@ impl<'d, T: Instance> Can<'d, T> { | ||||
|         rx.set_as_af(rx.af_num(), AFType::Input); | ||||
|         tx.set_as_af(tx.af_num(), AFType::OutputPushPull); | ||||
| 
 | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         { | ||||
|             T::regs().ier().write(|w| { | ||||
| @ -720,7 +720,7 @@ impl<'d, T: Instance> Drop for Can<'d, T> { | ||||
|         // Cannot call `free()` because it moves the instance.
 | ||||
|         // Manually reset the peripheral.
 | ||||
|         T::regs().mcr().write(|w| w.set_reset(true)); | ||||
|         T::disable(); | ||||
|         rcc::disable::<T>(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -11,7 +11,7 @@ use embassy_sync::waitqueue::AtomicWaker; | ||||
| use crate::can::fd::peripheral::Registers; | ||||
| use crate::gpio::AFType; | ||||
| use crate::interrupt::typelevel::Interrupt; | ||||
| use crate::rcc::RccPeripheral; | ||||
| use crate::rcc::{self, RccPeripheral}; | ||||
| use crate::{interrupt, peripherals, Peripheral}; | ||||
| 
 | ||||
| pub(crate) mod fd; | ||||
| @ -180,7 +180,7 @@ impl<'d, T: Instance> CanConfigurator<'d, T> { | ||||
|         rx.set_as_af(rx.af_num(), AFType::Input); | ||||
|         tx.set_as_af(tx.af_num(), AFType::OutputPushPull); | ||||
| 
 | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         let mut config = crate::can::fd::config::FdCanConfig::default(); | ||||
|         config.timestamp_source = TimestampSource::Prescaler(TimestampPrescaler::_1); | ||||
|  | ||||
| @ -4,7 +4,7 @@ use embassy_hal_internal::drop::OnDrop; | ||||
| use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; | ||||
| 
 | ||||
| use crate::pac::cordic::vals; | ||||
| use crate::{dma, peripherals}; | ||||
| use crate::{dma, peripherals, rcc}; | ||||
| 
 | ||||
| mod enums; | ||||
| pub use enums::*; | ||||
| @ -199,7 +199,7 @@ impl<'d, T: Instance> Cordic<'d, T> { | ||||
|     /// If you need a peripheral -> CORDIC -> peripheral mode,  
 | ||||
|     /// you may want to set Cordic into [Mode::ZeroOverhead] mode, and add extra arguments with [Self::extra_config]
 | ||||
|     pub fn new(peri: impl Peripheral<P = T> + 'd, config: Config) -> Self { | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         into_ref!(peri); | ||||
| 
 | ||||
| @ -259,7 +259,7 @@ impl<'d, T: Instance> Cordic<'d, T> { | ||||
| 
 | ||||
| impl<'d, T: Instance> Drop for Cordic<'d, T> { | ||||
|     fn drop(&mut self) { | ||||
|         T::disable(); | ||||
|         rcc::disable::<T>(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -2,8 +2,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef}; | ||||
| 
 | ||||
| use crate::pac::CRC as PAC_CRC; | ||||
| use crate::peripherals::CRC; | ||||
| use crate::rcc::SealedRccPeripheral; | ||||
| use crate::Peripheral; | ||||
| use crate::{rcc, Peripheral}; | ||||
| 
 | ||||
| /// CRC driver.
 | ||||
| pub struct Crc<'d> { | ||||
| @ -17,7 +16,7 @@ impl<'d> Crc<'d> { | ||||
| 
 | ||||
|         // Note: enable and reset come from RccPeripheral.
 | ||||
|         // enable CRC clock in RCC.
 | ||||
|         CRC::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<CRC>(); | ||||
|         // Peripheral the peripheral
 | ||||
|         let mut instance = Self { _peri: peripheral }; | ||||
|         instance.reset(); | ||||
|  | ||||
| @ -3,8 +3,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef}; | ||||
| use crate::pac::crc::vals; | ||||
| use crate::pac::CRC as PAC_CRC; | ||||
| use crate::peripherals::CRC; | ||||
| use crate::rcc::SealedRccPeripheral; | ||||
| use crate::Peripheral; | ||||
| use crate::{rcc, Peripheral}; | ||||
| 
 | ||||
| /// CRC driver.
 | ||||
| pub struct Crc<'d> { | ||||
| @ -84,7 +83,7 @@ impl<'d> Crc<'d> { | ||||
|     pub fn new(peripheral: impl Peripheral<P = CRC> + 'd, config: Config) -> Self { | ||||
|         // Note: enable and reset come from RccPeripheral.
 | ||||
|         // reset to default values and enable CRC clock in RCC.
 | ||||
|         CRC::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<CRC>(); | ||||
|         into_ref!(peripheral); | ||||
|         let mut instance = Self { | ||||
|             _peripheral: peripheral, | ||||
|  | ||||
| @ -9,7 +9,7 @@ use embassy_sync::waitqueue::AtomicWaker; | ||||
| 
 | ||||
| use crate::dma::{NoDma, Transfer, TransferOptions}; | ||||
| use crate::interrupt::typelevel::Interrupt; | ||||
| use crate::{interrupt, pac, peripherals, Peripheral}; | ||||
| use crate::{interrupt, pac, peripherals, rcc, Peripheral}; | ||||
| 
 | ||||
| const DES_BLOCK_SIZE: usize = 8; // 64 bits
 | ||||
| const AES_BLOCK_SIZE: usize = 16; // 128 bits
 | ||||
| @ -1029,7 +1029,7 @@ impl<'d, T: Instance, DmaIn, DmaOut> Cryp<'d, T, DmaIn, DmaOut> { | ||||
|         outdma: impl Peripheral<P = DmaOut> + 'd, | ||||
|         _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | ||||
|     ) -> Self { | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
|         into_ref!(peri, indma, outdma); | ||||
|         let instance = Self { | ||||
|             _peripheral: peri, | ||||
|  | ||||
| @ -8,7 +8,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef}; | ||||
| use crate::dma::NoDma; | ||||
| #[cfg(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7))] | ||||
| use crate::pac::dac; | ||||
| use crate::rcc::RccPeripheral; | ||||
| use crate::rcc::{self, RccPeripheral}; | ||||
| use crate::{peripherals, Peripheral}; | ||||
| 
 | ||||
| mod tsel; | ||||
| @ -131,7 +131,7 @@ impl<'d, T: Instance, const N: u8, DMA> DacChannel<'d, T, N, DMA> { | ||||
|     ) -> Self { | ||||
|         into_ref!(dma, pin); | ||||
|         pin.set_as_analog(); | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
|         let mut dac = Self { | ||||
|             phantom: PhantomData, | ||||
|             dma, | ||||
| @ -157,7 +157,7 @@ impl<'d, T: Instance, const N: u8, DMA> DacChannel<'d, T, N, DMA> { | ||||
|     #[cfg(all(any(dac_v3, dac_v4, dac_v5, dac_v6, dac_v7), not(any(stm32h56x, stm32h57x))))] | ||||
|     pub fn new_internal(_peri: impl Peripheral<P = T> + 'd, dma: impl Peripheral<P = DMA> + 'd) -> Self { | ||||
|         into_ref!(dma); | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
|         let mut dac = Self { | ||||
|             phantom: PhantomData, | ||||
|             dma, | ||||
| @ -356,7 +356,7 @@ impl_dma_methods!(2, DacDma2); | ||||
| 
 | ||||
| impl<'d, T: Instance, const N: u8, DMA> Drop for DacChannel<'d, T, N, DMA> { | ||||
|     fn drop(&mut self) { | ||||
|         T::disable(); | ||||
|         rcc::disable::<T>(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -400,8 +400,8 @@ impl<'d, T: Instance, DMACh1, DMACh2> Dac<'d, T, DMACh1, DMACh2> { | ||||
|         pin_ch2.set_as_analog(); | ||||
| 
 | ||||
|         // Enable twice to increment the DAC refcount for each channel.
 | ||||
|         T::enable_and_reset(); | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         let mut ch1 = DacCh1 { | ||||
|             phantom: PhantomData, | ||||
| @ -444,8 +444,8 @@ impl<'d, T: Instance, DMACh1, DMACh2> Dac<'d, T, DMACh1, DMACh2> { | ||||
|     ) -> Self { | ||||
|         into_ref!(dma_ch1, dma_ch2); | ||||
|         // Enable twice to increment the DAC refcount for each channel.
 | ||||
|         T::enable_and_reset(); | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         let mut ch1 = DacCh1 { | ||||
|             phantom: PhantomData, | ||||
|  | ||||
| @ -9,7 +9,7 @@ use embassy_sync::waitqueue::AtomicWaker; | ||||
| use crate::dma::Transfer; | ||||
| use crate::gpio::{AFType, Speed}; | ||||
| use crate::interrupt::typelevel::Interrupt; | ||||
| use crate::{interrupt, Peripheral}; | ||||
| use crate::{interrupt, rcc, Peripheral}; | ||||
| 
 | ||||
| /// Interrupt handler.
 | ||||
| pub struct InterruptHandler<T: Instance> { | ||||
| @ -350,7 +350,7 @@ where | ||||
|         use_embedded_synchronization: bool, | ||||
|         edm: u8, | ||||
|     ) -> Self { | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         peri.regs().cr().modify(|r| { | ||||
|             r.set_cm(true); // disable continuous mode (snapshot mode)
 | ||||
|  | ||||
| @ -6,7 +6,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef}; | ||||
| 
 | ||||
| //use crate::gpio::{AnyPin, SealedPin};
 | ||||
| use crate::gpio::{AFType, AnyPin, Pull, Speed}; | ||||
| use crate::rcc::RccPeripheral; | ||||
| use crate::rcc::{self, RccPeripheral}; | ||||
| use crate::{peripherals, Peripheral}; | ||||
| 
 | ||||
| /// Performs a busy-wait delay for a specified number of microseconds.
 | ||||
| @ -77,7 +77,7 @@ impl<'d, T: Instance> DsiHost<'d, T> { | ||||
|     pub fn new(_peri: impl Peripheral<P = T> + 'd, te: impl Peripheral<P = impl TePin<T>> + 'd) -> Self { | ||||
|         into_ref!(te); | ||||
| 
 | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         // Set Tearing Enable pin according to CubeMx example
 | ||||
|         te.set_as_af_pull(te.af_num(), AFType::OutputPushPull, Pull::None); | ||||
|  | ||||
| @ -4,7 +4,7 @@ use core::marker::PhantomData; | ||||
| use embassy_hal_internal::into_ref; | ||||
| 
 | ||||
| use crate::gpio::{AFType, Pull, Speed}; | ||||
| use crate::Peripheral; | ||||
| use crate::{rcc, Peripheral}; | ||||
| 
 | ||||
| /// FMC driver
 | ||||
| pub struct Fmc<'d, T: Instance> { | ||||
| @ -27,7 +27,7 @@ where | ||||
| 
 | ||||
|     /// Enable the FMC peripheral and reset it.
 | ||||
|     pub fn enable(&mut self) { | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
|     } | ||||
| 
 | ||||
|     /// Enable the memory controller on applicable chips.
 | ||||
| @ -54,7 +54,7 @@ where | ||||
|     const REGISTERS: *const () = T::REGS.as_ptr() as *const _; | ||||
| 
 | ||||
|     fn enable(&mut self) { | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
|     } | ||||
| 
 | ||||
|     fn memory_controller_enable(&mut self) { | ||||
| @ -200,7 +200,7 @@ impl<'d, T: Instance> Fmc<'d, T> { | ||||
|     )); | ||||
| } | ||||
| 
 | ||||
| trait SealedInstance: crate::rcc::SealedRccPeripheral { | ||||
| trait SealedInstance: crate::rcc::RccPeripheral { | ||||
|     const REGS: crate::pac::fmc::Fmc; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -813,7 +813,7 @@ foreach_pin!( | ||||
| 
 | ||||
| pub(crate) unsafe fn init(_cs: CriticalSection) { | ||||
|     #[cfg(afio)] | ||||
|     <crate::peripherals::AFIO as crate::rcc::SealedRccPeripheral>::enable_and_reset_with_cs(_cs); | ||||
|     crate::rcc::enable_and_reset_with_cs::<crate::peripherals::AFIO>(_cs); | ||||
| 
 | ||||
|     crate::_generated::init_gpio(); | ||||
| } | ||||
|  | ||||
| @ -17,8 +17,7 @@ use crate::dma::NoDma; | ||||
| use crate::dma::Transfer; | ||||
| use crate::interrupt::typelevel::Interrupt; | ||||
| use crate::peripherals::HASH; | ||||
| use crate::rcc::SealedRccPeripheral; | ||||
| use crate::{interrupt, pac, peripherals, Peripheral}; | ||||
| use crate::{interrupt, pac, peripherals, rcc, Peripheral}; | ||||
| 
 | ||||
| #[cfg(hash_v1)] | ||||
| const NUM_CONTEXT_REGS: usize = 51; | ||||
| @ -130,7 +129,7 @@ impl<'d, T: Instance, D> Hash<'d, T, D> { | ||||
|         dma: impl Peripheral<P = D> + 'd, | ||||
|         _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | ||||
|     ) -> Self { | ||||
|         HASH::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<HASH>(); | ||||
|         into_ref!(peripheral, dma); | ||||
|         let instance = Self { | ||||
|             _peripheral: peripheral, | ||||
|  | ||||
| @ -9,7 +9,7 @@ pub use traits::Instance; | ||||
| 
 | ||||
| use crate::gpio::{AFType, AnyPin}; | ||||
| use crate::time::Hertz; | ||||
| use crate::Peripheral; | ||||
| use crate::{rcc, Peripheral}; | ||||
| 
 | ||||
| /// HRTIM burst controller instance.
 | ||||
| pub struct BurstController<T: Instance> { | ||||
| @ -172,7 +172,7 @@ impl<'d, T: Instance> AdvancedPwm<'d, T> { | ||||
|     fn new_inner(tim: impl Peripheral<P = T> + 'd) -> Self { | ||||
|         into_ref!(tim); | ||||
| 
 | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         #[cfg(stm32f334)] | ||||
|         if crate::pac::RCC.cfgr3().read().hrtim1sw() == crate::pac::rcc::vals::Timsw::PLL1_P { | ||||
|  | ||||
| @ -18,7 +18,7 @@ use crate::dma::ChannelAndRequest; | ||||
| use crate::gpio::{AFType, Pull}; | ||||
| use crate::interrupt::typelevel::Interrupt; | ||||
| use crate::mode::{Async, Blocking, Mode}; | ||||
| use crate::rcc::{ClockEnableBit, SealedRccPeripheral}; | ||||
| use crate::rcc::{self, RccInfo, SealedRccPeripheral}; | ||||
| use crate::time::Hertz; | ||||
| use crate::{interrupt, peripherals}; | ||||
| 
 | ||||
| @ -128,7 +128,7 @@ impl<'d, M: Mode> I2c<'d, M> { | ||||
|     ) -> Self { | ||||
|         into_ref!(scl, sda); | ||||
| 
 | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         scl.set_as_af_pull( | ||||
|             scl.af_num(), | ||||
| @ -224,7 +224,7 @@ impl State { | ||||
| 
 | ||||
| struct Info { | ||||
|     regs: crate::pac::i2c::I2c, | ||||
|     pub(crate) enable_bit: ClockEnableBit, | ||||
|     rcc: RccInfo, | ||||
| } | ||||
| 
 | ||||
| peri_trait!( | ||||
| @ -265,7 +265,7 @@ foreach_peripheral!( | ||||
|             fn info() -> &'static Info { | ||||
|                 static INFO: Info = Info{ | ||||
|                     regs: crate::pac::$inst, | ||||
|                     enable_bit: crate::peripherals::$inst::ENABLE_BIT, | ||||
|                     rcc: crate::peripherals::$inst::RCC_INFO, | ||||
|                 }; | ||||
|                 &INFO | ||||
|             } | ||||
|  | ||||
| @ -702,7 +702,7 @@ impl<'d> I2c<'d, Async> { | ||||
| 
 | ||||
| impl<'d, M: PeriMode> Drop for I2c<'d, M> { | ||||
|     fn drop(&mut self) { | ||||
|         self.info.enable_bit.disable() | ||||
|         self.info.rcc.disable() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -673,7 +673,7 @@ impl<'d> I2c<'d, Async> { | ||||
| 
 | ||||
| impl<'d, M: Mode> Drop for I2c<'d, M> { | ||||
|     fn drop(&mut self) { | ||||
|         self.info.enable_bit.disable(); | ||||
|         self.info.rcc.disable(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -6,10 +6,9 @@ use core::task::Poll; | ||||
| 
 | ||||
| use embassy_sync::waitqueue::AtomicWaker; | ||||
| 
 | ||||
| use crate::interrupt; | ||||
| use crate::interrupt::typelevel::Interrupt; | ||||
| use crate::peripherals::IPCC; | ||||
| use crate::rcc::SealedRccPeripheral; | ||||
| use crate::{interrupt, rcc}; | ||||
| 
 | ||||
| /// Interrupt handler.
 | ||||
| pub struct ReceiveInterruptHandler {} | ||||
| @ -102,7 +101,7 @@ pub struct Ipcc; | ||||
| impl Ipcc { | ||||
|     /// Enable IPCC.
 | ||||
|     pub fn enable(_config: Config) { | ||||
|         IPCC::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<IPCC>(); | ||||
|         IPCC::set_cpu2(true); | ||||
| 
 | ||||
|         // set RF wake-up clock = LSE
 | ||||
|  | ||||
| @ -194,7 +194,6 @@ pub(crate) use stm32_metapac as pac; | ||||
| use crate::interrupt::Priority; | ||||
| #[cfg(feature = "rt")] | ||||
| pub use crate::pac::NVIC_PRIO_BITS; | ||||
| use crate::rcc::SealedRccPeripheral; | ||||
| 
 | ||||
| /// `embassy-stm32` global configuration.
 | ||||
| #[non_exhaustive] | ||||
| @ -310,11 +309,11 @@ pub fn init(config: Config) -> Peripherals { | ||||
|         }); | ||||
| 
 | ||||
|         #[cfg(not(any(stm32f1, stm32wb, stm32wl)))] | ||||
|         peripherals::SYSCFG::enable_and_reset_with_cs(cs); | ||||
|         rcc::enable_and_reset_with_cs::<peripherals::SYSCFG>(cs); | ||||
|         #[cfg(not(any(stm32h5, stm32h7, stm32h7rs, stm32wb, stm32wl)))] | ||||
|         peripherals::PWR::enable_and_reset_with_cs(cs); | ||||
|         rcc::enable_and_reset_with_cs::<peripherals::PWR>(cs); | ||||
|         #[cfg(not(any(stm32f2, stm32f4, stm32f7, stm32l0, stm32h5, stm32h7, stm32h7rs)))] | ||||
|         peripherals::FLASH::enable_and_reset_with_cs(cs); | ||||
|         rcc::enable_and_reset_with_cs::<peripherals::FLASH>(cs); | ||||
| 
 | ||||
|         // Enable the VDDIO2 power supply on chips that have it.
 | ||||
|         // Note that this requires the PWR peripheral to be enabled first.
 | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| //! LTDC
 | ||||
| use core::marker::PhantomData; | ||||
| 
 | ||||
| use crate::rcc::RccPeripheral; | ||||
| use crate::rcc::{self, RccPeripheral}; | ||||
| use crate::{peripherals, Peripheral}; | ||||
| 
 | ||||
| /// LTDC driver.
 | ||||
| @ -60,7 +60,7 @@ impl<'d, T: Instance> Ltdc<'d, T> { | ||||
|                 .modify(|w| w.set_pllsaidivr(stm32_metapac::rcc::vals::Pllsaidivr::DIV2)); | ||||
|         }); | ||||
| 
 | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         //new_pin!(clk, AFType::OutputPushPull, Speed::VeryHigh,  Pull::None);
 | ||||
| 
 | ||||
|  | ||||
| @ -16,7 +16,7 @@ use crate::dma::{word, ChannelAndRequest}; | ||||
| use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _, Speed}; | ||||
| use crate::mode::{Async, Blocking, Mode as PeriMode}; | ||||
| use crate::pac::octospi::{vals, Octospi as Regs}; | ||||
| use crate::rcc::RccPeripheral; | ||||
| use crate::rcc::{self, RccPeripheral}; | ||||
| use crate::{peripherals, Peripheral}; | ||||
| 
 | ||||
| /// OPSI driver config.
 | ||||
| @ -198,7 +198,7 @@ impl<'d, T: Instance, M: PeriMode> Ospi<'d, T, M> { | ||||
|         into_ref!(peri); | ||||
| 
 | ||||
|         // System configuration
 | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
|         while T::REGS.sr().read().busy() {} | ||||
| 
 | ||||
|         // Device configuration
 | ||||
| @ -1013,7 +1013,7 @@ impl<'d, T: Instance, M: PeriMode> Drop for Ospi<'d, T, M> { | ||||
|         self.nss.as_ref().map(|x| x.set_as_disconnected()); | ||||
|         self.dqs.as_ref().map(|x| x.set_as_disconnected()); | ||||
| 
 | ||||
|         T::disable(); | ||||
|         rcc::disable::<T>(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -13,7 +13,7 @@ use crate::dma::ChannelAndRequest; | ||||
| use crate::gpio::{AFType, AnyPin, Pull, Speed}; | ||||
| use crate::mode::{Async, Blocking, Mode as PeriMode}; | ||||
| use crate::pac::quadspi::Quadspi as Regs; | ||||
| use crate::rcc::RccPeripheral; | ||||
| use crate::rcc::{self, RccPeripheral}; | ||||
| use crate::{peripherals, Peripheral}; | ||||
| 
 | ||||
| /// QSPI transfer configuration.
 | ||||
| @ -102,7 +102,7 @@ impl<'d, T: Instance, M: PeriMode> Qspi<'d, T, M> { | ||||
|     ) -> Self { | ||||
|         into_ref!(peri); | ||||
| 
 | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         while T::REGS.sr().read().busy() {} | ||||
| 
 | ||||
|  | ||||
| @ -2,7 +2,7 @@ | ||||
| 
 | ||||
| use crate::pac::crs::vals::Syncsrc; | ||||
| use crate::pac::{CRS, RCC}; | ||||
| use crate::rcc::SealedRccPeripheral; | ||||
| use crate::rcc::{self, SealedRccPeripheral}; | ||||
| use crate::time::Hertz; | ||||
| 
 | ||||
| /// HSI48 speed
 | ||||
| @ -44,7 +44,7 @@ pub(crate) fn init_hsi48(config: Hsi48Config) -> Hertz { | ||||
|     while r.read().hsi48rdy() == false {} | ||||
| 
 | ||||
|     if config.sync_from_usb { | ||||
|         crate::peripherals::CRS::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<crate::peripherals::CRS>(); | ||||
| 
 | ||||
|         CRS.cfgr().modify(|w| { | ||||
|             w.set_syncsrc(Syncsrc::USB); | ||||
|  | ||||
| @ -67,23 +67,185 @@ pub(crate) unsafe fn get_freqs() -> &'static Clocks { | ||||
| } | ||||
| 
 | ||||
| pub(crate) trait SealedRccPeripheral { | ||||
|     const ENABLE_BIT: ClockEnableBit; | ||||
| 
 | ||||
|     fn frequency() -> Hertz; | ||||
|     fn enable_and_reset_with_cs(cs: CriticalSection); | ||||
|     fn disable_with_cs(cs: CriticalSection); | ||||
| 
 | ||||
|     fn enable_and_reset() { | ||||
|         critical_section::with(|cs| Self::enable_and_reset_with_cs(cs)) | ||||
|     } | ||||
|     fn disable() { | ||||
|         critical_section::with(|cs| Self::disable_with_cs(cs)) | ||||
|     } | ||||
|     const RCC_INFO: RccInfo; | ||||
| } | ||||
| 
 | ||||
| #[allow(private_bounds)] | ||||
| pub trait RccPeripheral: SealedRccPeripheral + 'static {} | ||||
| 
 | ||||
| /// Runtime information necessary to reset, enable and disable a peripheral.
 | ||||
| pub(crate) struct RccInfo { | ||||
|     /// Offset in 32-bit words of the xxxRSTR register into the RCC register block, or 0xff if the
 | ||||
|     /// peripheral has no reset bit (we don't use an `Option` to save one byte of storage).
 | ||||
|     reset_offset_or_0xff: u8, | ||||
|     /// Position of the xxxRST bit within the xxxRSTR register (0..=31).
 | ||||
|     reset_bit: u8, | ||||
|     /// Offset in 32-bit words of the xxxENR register into the RCC register block.
 | ||||
|     enable_offset: u8, | ||||
|     /// Position of the xxxEN bit within the xxxENR register (0..=31).
 | ||||
|     enable_bit: u8, | ||||
|     /// If this peripheral shares the same xxxRSTR bit and xxxEN bit with other peripherals, we
 | ||||
|     /// maintain a refcount in `crate::_generated::REFCOUNTS` at this index. If the bit is not
 | ||||
|     /// shared, this is 0xff (we don't use an `Option` to save one byte of storage).
 | ||||
|     refcount_idx_or_0xff: u8, | ||||
|     /// Stop mode of the peripheral, used to maintain `REFCOUNT_STOP1` and `REFCOUNT_STOP2`.
 | ||||
|     #[cfg(feature = "low-power")] | ||||
|     stop_mode: StopMode, | ||||
| } | ||||
| 
 | ||||
| #[cfg(feature = "low-power")] | ||||
| #[allow(dead_code)] | ||||
| pub(crate) enum StopMode { | ||||
|     Standby, | ||||
|     Stop2, | ||||
|     Stop1, | ||||
| } | ||||
| 
 | ||||
| impl RccInfo { | ||||
|     /// Safety:
 | ||||
|     /// - `reset_offset_and_bit`, if set, must correspond to valid xxxRST bit
 | ||||
|     /// - `enable_offset_and_bit` must correspond to valid xxxEN bit
 | ||||
|     /// - `refcount_idx`, if set, must correspond to valid refcount in `_generated::REFCOUNTS`
 | ||||
|     /// - `stop_mode` must be valid
 | ||||
|     pub(crate) const unsafe fn new( | ||||
|         reset_offset_and_bit: Option<(u8, u8)>, | ||||
|         enable_offset_and_bit: (u8, u8), | ||||
|         refcount_idx: Option<u8>, | ||||
|         #[cfg(feature = "low-power")] stop_mode: StopMode, | ||||
|     ) -> Self { | ||||
|         let (reset_offset_or_0xff, reset_bit) = match reset_offset_and_bit { | ||||
|             Some((offset, bit)) => (offset, bit), | ||||
|             None => (0xff, 0xff), | ||||
|         }; | ||||
|         let (enable_offset, enable_bit) = enable_offset_and_bit; | ||||
|         let refcount_idx_or_0xff = match refcount_idx { | ||||
|             Some(idx) => idx, | ||||
|             None => 0xff, | ||||
|         }; | ||||
|         Self { | ||||
|             reset_offset_or_0xff, | ||||
|             reset_bit, | ||||
|             enable_offset, | ||||
|             enable_bit, | ||||
|             refcount_idx_or_0xff, | ||||
|             #[cfg(feature = "low-power")] | ||||
|             stop_mode, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // TODO: should this be `unsafe`?
 | ||||
|     pub(crate) fn enable_and_reset_with_cs(&self, _cs: CriticalSection) { | ||||
|         if self.refcount_idx_or_0xff != 0xff { | ||||
|             let refcount_idx = self.refcount_idx_or_0xff as usize; | ||||
|             unsafe { | ||||
|                 crate::_generated::REFCOUNTS[refcount_idx] += 1; | ||||
|             } | ||||
|             if unsafe { crate::_generated::REFCOUNTS[refcount_idx] } > 1 { | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         #[cfg(feature = "low-power")] | ||||
|         match self.stop_mode { | ||||
|             StopMode::Standby => {} | ||||
|             StopMode::Stop2 => unsafe { | ||||
|                 REFCOUNT_STOP2 += 1; | ||||
|             }, | ||||
|             StopMode::Stop1 => unsafe { | ||||
|                 REFCOUNT_STOP1 += 1; | ||||
|             }, | ||||
|         } | ||||
| 
 | ||||
|         // set the xxxRST bit
 | ||||
|         let reset_ptr = self.reset_ptr(); | ||||
|         if let Some(reset_ptr) = reset_ptr { | ||||
|             unsafe { | ||||
|                 let val = reset_ptr.read_volatile(); | ||||
|                 reset_ptr.write_volatile(val | 1u32 << self.reset_bit); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // set the xxxEN bit
 | ||||
|         let enable_ptr = self.enable_ptr(); | ||||
|         unsafe { | ||||
|             let val = enable_ptr.read_volatile(); | ||||
|             enable_ptr.write_volatile(val | 1u32 << self.enable_bit); | ||||
|         } | ||||
| 
 | ||||
|         // we must wait two peripheral clock cycles before the clock is active
 | ||||
|         // this seems to work, but might be incorrect
 | ||||
|         // see http://efton.sk/STM32/gotcha/g183.html
 | ||||
| 
 | ||||
|         // dummy read (like in the ST HALs)
 | ||||
|         let _ = unsafe { enable_ptr.read_volatile() }; | ||||
| 
 | ||||
|         // DSB for good measure
 | ||||
|         cortex_m::asm::dsb(); | ||||
| 
 | ||||
|         // clear the xxxRST bit
 | ||||
|         if let Some(reset_ptr) = reset_ptr { | ||||
|             unsafe { | ||||
|                 let val = reset_ptr.read_volatile(); | ||||
|                 reset_ptr.write_volatile(val & !(1u32 << self.reset_bit)); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // TODO: should this be `unsafe`?
 | ||||
|     pub(crate) fn disable_with_cs(&self, _cs: CriticalSection) { | ||||
|         if self.refcount_idx_or_0xff != 0xff { | ||||
|             let refcount_idx = self.refcount_idx_or_0xff as usize; | ||||
|             unsafe { | ||||
|                 crate::_generated::REFCOUNTS[refcount_idx] -= 1; | ||||
|             } | ||||
|             if unsafe { crate::_generated::REFCOUNTS[refcount_idx] } > 0 { | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         #[cfg(feature = "low-power")] | ||||
|         match self.stop_mode { | ||||
|             StopMode::Standby => {} | ||||
|             StopMode::Stop2 => unsafe { | ||||
|                 REFCOUNT_STOP2 -= 1; | ||||
|             }, | ||||
|             StopMode::Stop1 => unsafe { | ||||
|                 REFCOUNT_STOP1 -= 1; | ||||
|             }, | ||||
|         } | ||||
| 
 | ||||
|         // clear the xxxEN bit
 | ||||
|         let enable_ptr = self.enable_ptr(); | ||||
|         unsafe { | ||||
|             let val = enable_ptr.read_volatile(); | ||||
|             enable_ptr.write_volatile(val & !(1u32 << self.enable_bit)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // TODO: should this be `unsafe`?
 | ||||
|     pub(crate) fn enable_and_reset(&self) { | ||||
|         critical_section::with(|cs| self.enable_and_reset_with_cs(cs)) | ||||
|     } | ||||
| 
 | ||||
|     // TODO: should this be `unsafe`?
 | ||||
|     pub(crate) fn disable(&self) { | ||||
|         critical_section::with(|cs| self.disable_with_cs(cs)) | ||||
|     } | ||||
| 
 | ||||
|     fn reset_ptr(&self) -> Option<*mut u32> { | ||||
|         if self.reset_offset_or_0xff != 0xff { | ||||
|             Some(unsafe { (RCC.as_ptr() as *mut u32).add(self.reset_offset_or_0xff as _) }) | ||||
|         } else { | ||||
|             None | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn enable_ptr(&self) -> *mut u32 { | ||||
|         unsafe { (RCC.as_ptr() as *mut u32).add(self.enable_offset as _) } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[allow(unused)] | ||||
| mod util { | ||||
|     use crate::time::Hertz; | ||||
| @ -128,8 +290,9 @@ pub fn frequency<T: RccPeripheral>() -> Hertz { | ||||
| /// # Safety
 | ||||
| ///
 | ||||
| /// Peripheral must not be in use.
 | ||||
| pub unsafe fn enable_and_reset<T: RccPeripheral>() { | ||||
|     T::enable_and_reset(); | ||||
| // TODO: should this be `unsafe`?
 | ||||
| pub fn enable_and_reset_with_cs<T: RccPeripheral>(cs: CriticalSection) { | ||||
|     T::RCC_INFO.enable_and_reset_with_cs(cs); | ||||
| } | ||||
| 
 | ||||
| /// Disables peripheral `T`.
 | ||||
| @ -137,52 +300,27 @@ pub unsafe fn enable_and_reset<T: RccPeripheral>() { | ||||
| /// # Safety
 | ||||
| ///
 | ||||
| /// Peripheral must not be in use.
 | ||||
| pub unsafe fn disable<T: RccPeripheral>() { | ||||
|     T::disable(); | ||||
| // TODO: should this be `unsafe`?
 | ||||
| pub fn disable_with_cs<T: RccPeripheral>(cs: CriticalSection) { | ||||
|     T::RCC_INFO.disable_with_cs(cs); | ||||
| } | ||||
| 
 | ||||
| /// Struct representing some clock enable bit (xxxENR.xxEN), only known at runtime.
 | ||||
| #[derive(Clone, Copy)] | ||||
| pub(crate) struct ClockEnableBit { | ||||
|     /// offset in 32bit words of the xxxENR register into the RCC register block.
 | ||||
|     offset: u8, | ||||
|     /// bit within the register (0..=31)
 | ||||
|     bit: u8, | ||||
| /// Enables and resets peripheral `T`.
 | ||||
| ///
 | ||||
| /// # Safety
 | ||||
| ///
 | ||||
| /// Peripheral must not be in use.
 | ||||
| // TODO: should this be `unsafe`?
 | ||||
| pub fn enable_and_reset<T: RccPeripheral>() { | ||||
|     T::RCC_INFO.enable_and_reset(); | ||||
| } | ||||
| 
 | ||||
| impl ClockEnableBit { | ||||
|     /// Safety: offset+bit must correspond to a valid xxxEN bit.
 | ||||
|     pub(crate) const unsafe fn new(offset: u8, bit: u8) -> Self { | ||||
|         Self { offset, bit } | ||||
|     } | ||||
| 
 | ||||
|     fn ptr(self) -> *mut u32 { | ||||
|         unsafe { (RCC.as_ptr() as *mut u32).add(self.offset as _) } | ||||
|     } | ||||
| 
 | ||||
|     #[allow(unused)] | ||||
|     pub(crate) fn enable_with_cs(self, _cs: CriticalSection) { | ||||
|         let p = self.ptr(); | ||||
|         unsafe { | ||||
|             let val = p.read_volatile(); | ||||
|             p.write_volatile(val | 1u32 << self.bit); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub(crate) fn disable_with_cs(self, _cs: CriticalSection) { | ||||
|         let p = self.ptr(); | ||||
|         unsafe { | ||||
|             let val = p.read_volatile(); | ||||
|             p.write_volatile(val & !(1u32 << self.bit)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[allow(unused)] | ||||
|     pub(crate) fn enable(self) { | ||||
|         critical_section::with(|cs| self.enable_with_cs(cs)) | ||||
|     } | ||||
| 
 | ||||
|     pub(crate) fn disable(self) { | ||||
|         critical_section::with(|cs| self.disable_with_cs(cs)) | ||||
|     } | ||||
| /// Disables peripheral `T`.
 | ||||
| ///
 | ||||
| /// # Safety
 | ||||
| ///
 | ||||
| /// Peripheral must not be in use.
 | ||||
| // TODO: should this be `unsafe`?
 | ||||
| pub fn disable<T: RccPeripheral>() { | ||||
|     T::RCC_INFO.disable(); | ||||
| } | ||||
|  | ||||
| @ -10,7 +10,7 @@ use embassy_sync::waitqueue::AtomicWaker; | ||||
| use rand_core::{CryptoRng, RngCore}; | ||||
| 
 | ||||
| use crate::interrupt::typelevel::Interrupt; | ||||
| use crate::{interrupt, pac, peripherals, Peripheral}; | ||||
| use crate::{interrupt, pac, peripherals, rcc, Peripheral}; | ||||
| 
 | ||||
| static RNG_WAKER: AtomicWaker = AtomicWaker::new(); | ||||
| 
 | ||||
| @ -52,7 +52,7 @@ impl<'d, T: Instance> Rng<'d, T> { | ||||
|         inner: impl Peripheral<P = T> + 'd, | ||||
|         _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | ||||
|     ) -> Self { | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
|         into_ref!(inner); | ||||
|         let mut random = Self { _inner: inner }; | ||||
|         random.reset(); | ||||
|  | ||||
| @ -205,7 +205,7 @@ impl Rtc { | ||||
|     /// Create a new RTC instance.
 | ||||
|     pub fn new(_rtc: impl Peripheral<P = RTC>, rtc_config: RtcConfig) -> Self { | ||||
|         #[cfg(not(any(stm32l0, stm32f3, stm32l1, stm32f0, stm32f2)))] | ||||
|         <RTC as crate::rcc::SealedRccPeripheral>::enable_and_reset(); | ||||
|         crate::rcc::enable_and_reset::<RTC>(); | ||||
| 
 | ||||
|         let mut this = Self { | ||||
|             #[cfg(feature = "low-power")] | ||||
|  | ||||
| @ -11,7 +11,7 @@ pub use crate::dma::word; | ||||
| use crate::dma::{ringbuffer, Channel, ReadableRingBuffer, Request, TransferOptions, WritableRingBuffer}; | ||||
| use crate::gpio::{AFType, AnyPin, SealedPin as _}; | ||||
| use crate::pac::sai::{vals, Sai as Regs}; | ||||
| use crate::rcc::RccPeripheral; | ||||
| use crate::rcc::{self, RccPeripheral}; | ||||
| use crate::{peripherals, Peripheral}; | ||||
| 
 | ||||
| /// SAI error
 | ||||
| @ -722,7 +722,7 @@ pub struct SubBlock<'d, T, S: SubBlockInstance> { | ||||
| /// You can then create a [`Sai`] driver for each each half.
 | ||||
| pub fn split_subblocks<'d, T: Instance>(peri: impl Peripheral<P = T> + 'd) -> (SubBlock<'d, T, A>, SubBlock<'d, T, B>) { | ||||
|     into_ref!(peri); | ||||
|     T::enable_and_reset(); | ||||
|     rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|     ( | ||||
|         SubBlock { | ||||
| @ -978,7 +978,7 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> { | ||||
| 
 | ||||
|     /// Reset SAI operation.
 | ||||
|     pub fn reset() { | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
|     } | ||||
| 
 | ||||
|     /// Flush.
 | ||||
|  | ||||
| @ -16,7 +16,7 @@ use crate::dma::NoDma; | ||||
| use crate::gpio::{AFType, AnyPin, Pull, SealedPin, Speed}; | ||||
| use crate::interrupt::typelevel::Interrupt; | ||||
| use crate::pac::sdmmc::Sdmmc as RegBlock; | ||||
| use crate::rcc::RccPeripheral; | ||||
| use crate::rcc::{self, RccPeripheral}; | ||||
| use crate::time::Hertz; | ||||
| use crate::{interrupt, peripherals, Peripheral}; | ||||
| 
 | ||||
| @ -468,7 +468,7 @@ impl<'d, T: Instance, Dma: SdmmcDma<T> + 'd> Sdmmc<'d, T, Dma> { | ||||
|     ) -> Self { | ||||
|         into_ref!(sdmmc, dma); | ||||
| 
 | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         T::Interrupt::unpend(); | ||||
|         unsafe { T::Interrupt::enable() }; | ||||
|  | ||||
| @ -13,7 +13,7 @@ use crate::dma::{slice_ptr_parts, word, ChannelAndRequest}; | ||||
| use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _, Speed}; | ||||
| use crate::mode::{Async, Blocking, Mode as PeriMode}; | ||||
| use crate::pac::spi::{regs, vals, Spi as Regs}; | ||||
| use crate::rcc::{ClockEnableBit, SealedRccPeripheral}; | ||||
| use crate::rcc::{self, RccInfo, SealedRccPeripheral}; | ||||
| use crate::time::Hertz; | ||||
| use crate::Peripheral; | ||||
| 
 | ||||
| @ -129,7 +129,7 @@ impl<'d, M: PeriMode> Spi<'d, M> { | ||||
| 
 | ||||
|         let lsbfirst = config.raw_byte_order(); | ||||
| 
 | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         #[cfg(any(spi_v1, spi_f1))] | ||||
|         { | ||||
| @ -738,7 +738,7 @@ impl<'d, M: PeriMode> Drop for Spi<'d, M> { | ||||
|         self.mosi.as_ref().map(|x| x.set_as_disconnected()); | ||||
|         self.miso.as_ref().map(|x| x.set_as_disconnected()); | ||||
| 
 | ||||
|         self.info.enable_bit.disable(); | ||||
|         self.info.rcc.disable(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -1118,7 +1118,7 @@ mod word_impl { | ||||
| 
 | ||||
| pub(crate) struct Info { | ||||
|     pub(crate) regs: Regs, | ||||
|     pub(crate) enable_bit: ClockEnableBit, | ||||
|     pub(crate) rcc: RccInfo, | ||||
| } | ||||
| 
 | ||||
| struct State {} | ||||
| @ -1145,7 +1145,7 @@ foreach_peripheral!( | ||||
|     (spi, $inst:ident) => { | ||||
|         peri_trait_impl!($inst, Info { | ||||
|             regs: crate::pac::$inst, | ||||
|             enable_bit: crate::peripherals::$inst::ENABLE_BIT, | ||||
|             rcc: crate::peripherals::$inst::RCC_INFO, | ||||
|         }); | ||||
|     }; | ||||
| ); | ||||
|  | ||||
| @ -12,7 +12,7 @@ use stm32_metapac::timer::{regs, TimGp16}; | ||||
| 
 | ||||
| use crate::interrupt::typelevel::Interrupt; | ||||
| use crate::pac::timer::vals; | ||||
| use crate::rcc::SealedRccPeripheral; | ||||
| use crate::rcc::{self, SealedRccPeripheral}; | ||||
| #[cfg(feature = "low-power")] | ||||
| use crate::rtc::Rtc; | ||||
| use crate::timer::{CoreInstance, GeneralInstance1Channel}; | ||||
| @ -276,7 +276,7 @@ impl RtcDriver { | ||||
|     fn init(&'static self, cs: critical_section::CriticalSection) { | ||||
|         let r = regs_gp16(); | ||||
| 
 | ||||
|         <T as SealedRccPeripheral>::enable_and_reset_with_cs(cs); | ||||
|         rcc::enable_and_reset_with_cs::<T>(cs); | ||||
| 
 | ||||
|         let timer_freq = T::frequency(); | ||||
| 
 | ||||
|  | ||||
| @ -10,6 +10,7 @@ use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; | ||||
| 
 | ||||
| use super::*; | ||||
| use crate::pac::timer::vals; | ||||
| use crate::rcc; | ||||
| use crate::time::Hertz; | ||||
| 
 | ||||
| /// Input capture mode.
 | ||||
| @ -181,7 +182,7 @@ pub struct Timer<'d, T: CoreInstance> { | ||||
| 
 | ||||
| impl<'d, T: CoreInstance> Drop for Timer<'d, T> { | ||||
|     fn drop(&mut self) { | ||||
|         T::disable() | ||||
|         rcc::disable::<T>(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -190,7 +191,7 @@ impl<'d, T: CoreInstance> Timer<'d, T> { | ||||
|     pub fn new(tim: impl Peripheral<P = T> + 'd) -> Self { | ||||
|         into_ref!(tim); | ||||
| 
 | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         Self { tim } | ||||
|     } | ||||
|  | ||||
| @ -72,7 +72,7 @@ pub use enums::*; | ||||
| 
 | ||||
| use crate::gpio::{AFType, AnyPin}; | ||||
| use crate::pac::tsc::Tsc as Regs; | ||||
| use crate::rcc::RccPeripheral; | ||||
| use crate::rcc::{self, RccPeripheral}; | ||||
| use crate::{peripherals, Peripheral}; | ||||
| 
 | ||||
| #[cfg(tsc_v1)] | ||||
| @ -649,7 +649,7 @@ impl<'d, T: Instance> Tsc<'d, T> { | ||||
|     ) -> Self { | ||||
|         into_ref!(peri); | ||||
| 
 | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         T::REGS.cr().modify(|w| { | ||||
|             w.set_tsce(true); | ||||
| @ -880,7 +880,7 @@ impl<'d, T: Instance> Tsc<'d, T> { | ||||
| 
 | ||||
| impl<'d, T: Instance> Drop for Tsc<'d, T> { | ||||
|     fn drop(&mut self) { | ||||
|         T::disable(); | ||||
|         rcc::disable::<T>(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -28,7 +28,7 @@ use crate::interrupt; | ||||
| use crate::interrupt::typelevel::Interrupt; | ||||
| use crate::pac::ucpd::vals::{Anamode, Ccenable, PscUsbpdclk, Txmode}; | ||||
| pub use crate::pac::ucpd::vals::{Phyccsel as CcSel, TypecVstateCc as CcVState}; | ||||
| use crate::rcc::RccPeripheral; | ||||
| use crate::rcc::{self, RccPeripheral}; | ||||
| 
 | ||||
| pub(crate) fn init( | ||||
|     _cs: critical_section::CriticalSection, | ||||
| @ -103,7 +103,7 @@ impl<'d, T: Instance> Ucpd<'d, T> { | ||||
|         cc1.set_as_analog(); | ||||
|         cc2.set_as_analog(); | ||||
| 
 | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
|         T::Interrupt::unpend(); | ||||
|         unsafe { T::Interrupt::enable() }; | ||||
| 
 | ||||
| @ -212,7 +212,7 @@ impl<'d, T: Instance> Drop for CcPhy<'d, T> { | ||||
|             drop_not_ready.store(true, Ordering::Relaxed); | ||||
|         } else { | ||||
|             r.cfgr1().write(|w| w.set_ucpden(false)); | ||||
|             T::disable(); | ||||
|             rcc::disable::<T>(); | ||||
|             T::Interrupt::disable(); | ||||
|         } | ||||
|     } | ||||
| @ -325,7 +325,7 @@ impl<'d, T: Instance> Drop for PdPhy<'d, T> { | ||||
|             drop_not_ready.store(true, Ordering::Relaxed); | ||||
|         } else { | ||||
|             T::REGS.cfgr1().write(|w| w.set_ucpden(false)); | ||||
|             T::disable(); | ||||
|             rcc::disable::<T>(); | ||||
|             T::Interrupt::disable(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -18,6 +18,7 @@ use super::{ | ||||
| use crate::gpio::AFType; | ||||
| use crate::interrupt::typelevel::Interrupt as _; | ||||
| use crate::interrupt::{self, InterruptExt}; | ||||
| use crate::rcc; | ||||
| use crate::time::Hertz; | ||||
| 
 | ||||
| /// Interrupt handler.
 | ||||
| @ -206,7 +207,7 @@ impl<'d> BufferedUart<'d> { | ||||
|         rx_buffer: &'d mut [u8], | ||||
|         config: Config, | ||||
|     ) -> Result<Self, ConfigError> { | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         Self::new_inner(peri, rx, tx, tx_buffer, rx_buffer, config) | ||||
|     } | ||||
| @ -225,7 +226,7 @@ impl<'d> BufferedUart<'d> { | ||||
|     ) -> Result<Self, ConfigError> { | ||||
|         into_ref!(cts, rts); | ||||
| 
 | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         rts.set_as_af(rts.af_num(), AFType::OutputPushPull); | ||||
|         cts.set_as_af(cts.af_num(), AFType::Input); | ||||
| @ -251,7 +252,7 @@ impl<'d> BufferedUart<'d> { | ||||
|     ) -> Result<Self, ConfigError> { | ||||
|         into_ref!(de); | ||||
| 
 | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         de.set_as_af(de.af_num(), AFType::OutputPushPull); | ||||
|         T::info().regs.cr3().write(|w| { | ||||
| @ -545,7 +546,7 @@ fn drop_tx_rx(info: &Info, state: &State) { | ||||
|         refcount == 1 | ||||
|     }); | ||||
|     if is_last_drop { | ||||
|         info.enable_bit.disable(); | ||||
|         info.rcc.disable(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -28,7 +28,7 @@ use crate::pac::usart::Lpuart as Regs; | ||||
| #[cfg(any(usart_v1, usart_v2))] | ||||
| use crate::pac::usart::Usart as Regs; | ||||
| use crate::pac::usart::{regs, vals}; | ||||
| use crate::rcc::{ClockEnableBit, SealedRccPeripheral}; | ||||
| use crate::rcc::{self, RccInfo, SealedRccPeripheral}; | ||||
| use crate::time::Hertz; | ||||
| use crate::Peripheral; | ||||
| 
 | ||||
| @ -429,7 +429,7 @@ impl<'d, M: Mode> UartTx<'d, M> { | ||||
|         tx_dma: Option<ChannelAndRequest<'d>>, | ||||
|         config: Config, | ||||
|     ) -> Result<Self, ConfigError> { | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         let info = T::info(); | ||||
|         let state = T::state(); | ||||
| @ -775,7 +775,7 @@ impl<'d, M: Mode> UartRx<'d, M> { | ||||
|         rx_dma: Option<ChannelAndRequest<'d>>, | ||||
|         config: Config, | ||||
|     ) -> Result<Self, ConfigError> { | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         let info = T::info(); | ||||
|         let state = T::state(); | ||||
| @ -916,7 +916,7 @@ fn drop_tx_rx(info: &Info, state: &State) { | ||||
|         refcount == 1 | ||||
|     }); | ||||
|     if is_last_drop { | ||||
|         info.enable_bit.disable(); | ||||
|         info.rcc.disable(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -1228,7 +1228,7 @@ impl<'d, M: Mode> Uart<'d, M> { | ||||
|         rx_dma: Option<ChannelAndRequest<'d>>, | ||||
|         config: Config, | ||||
|     ) -> Result<Self, ConfigError> { | ||||
|         T::enable_and_reset(); | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         let info = T::info(); | ||||
|         let state = T::state(); | ||||
| @ -1718,7 +1718,7 @@ impl State { | ||||
| 
 | ||||
| struct Info { | ||||
|     regs: Regs, | ||||
|     enable_bit: ClockEnableBit, | ||||
|     rcc: RccInfo, | ||||
|     interrupt: Interrupt, | ||||
|     kind: Kind, | ||||
| } | ||||
| @ -1754,7 +1754,7 @@ macro_rules! impl_usart { | ||||
|             fn info() -> &'static Info { | ||||
|                 static INFO: Info = Info { | ||||
|                     regs: unsafe { Regs::from_ptr(crate::pac::$inst.as_ptr()) }, | ||||
|                     enable_bit: crate::peripherals::$inst::ENABLE_BIT, | ||||
|                     rcc: crate::peripherals::$inst::RCC_INFO, | ||||
|                     interrupt: crate::interrupt::typelevel::$irq::IRQ, | ||||
|                     kind: $kind, | ||||
|                 }; | ||||
|  | ||||
| @ -6,7 +6,7 @@ mod _version; | ||||
| pub use _version::*; | ||||
| 
 | ||||
| use crate::interrupt::typelevel::Interrupt; | ||||
| use crate::rcc::SealedRccPeripheral; | ||||
| use crate::rcc; | ||||
| 
 | ||||
| /// clock, power initialization stuff that's common for USB and OTG.
 | ||||
| fn common_init<T: Instance>() { | ||||
| @ -65,5 +65,5 @@ fn common_init<T: Instance>() { | ||||
|     T::Interrupt::unpend(); | ||||
|     unsafe { T::Interrupt::enable() }; | ||||
| 
 | ||||
|     <T as SealedRccPeripheral>::enable_and_reset(); | ||||
|     rcc::enable_and_reset::<T>(); | ||||
| } | ||||
|  | ||||
| @ -13,7 +13,7 @@ use embassy_usb_synopsys_otg::{ | ||||
| use crate::gpio::AFType; | ||||
| use crate::interrupt; | ||||
| use crate::interrupt::typelevel::Interrupt; | ||||
| use crate::rcc::{RccPeripheral, SealedRccPeripheral}; | ||||
| use crate::rcc::{self, RccPeripheral}; | ||||
| 
 | ||||
| const MAX_EP_COUNT: usize = 9; | ||||
| 
 | ||||
| @ -246,7 +246,7 @@ impl<'d, T: Instance> Bus<'d, T> { | ||||
|     fn disable(&mut self) { | ||||
|         T::Interrupt::disable(); | ||||
| 
 | ||||
|         <T as SealedRccPeripheral>::disable(); | ||||
|         rcc::disable::<T>(); | ||||
|         self.inited = false; | ||||
| 
 | ||||
|         #[cfg(stm32l4)] | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user