stm32/rcc: replace generated enable/disable code with runtime info

This commit is contained in:
Jan Špaček 2024-05-24 22:04:04 +02:00
parent 01c1cb2764
commit 081afca3f0
45 changed files with 379 additions and 305 deletions

View File

@ -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

View File

@ -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>();
}
}

View File

@ -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>();
}
}

View File

@ -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>();
}
}

View File

@ -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());

View File

@ -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>();
}
}

View File

@ -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>();
}
}

View File

@ -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);

View File

@ -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());

View File

@ -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>();
}
}

View File

@ -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);

View File

@ -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>();
}
}

View File

@ -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();

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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)

View File

@ -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);

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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,

View File

@ -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 {

View File

@ -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
}

View File

@ -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()
}
}

View File

@ -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();
}
}

View File

@ -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

View File

@ -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.

View File

@ -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);

View File

@ -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>();
}
}

View File

@ -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() {}

View File

@ -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);

View File

@ -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();
}

View File

@ -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();

View File

@ -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")]

View File

@ -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.

View File

@ -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() };

View File

@ -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,
});
};
);

View File

@ -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();

View File

@ -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 }
}

View File

@ -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>();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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,
};

View File

@ -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>();
}

View File

@ -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)]