embassy/embassy-stm32/src/rcc/mod.rs

120 lines
3.0 KiB
Rust
Raw Normal View History

#![macro_use]
use crate::peripherals;
2021-06-14 10:48:14 +02:00
use crate::time::Hertz;
2021-05-27 09:50:11 +02:00
use core::mem::MaybeUninit;
2021-06-14 11:24:09 +02:00
mod types;
2021-06-14 10:48:14 +02:00
#[derive(Clone, Copy)]
pub struct Clocks {
pub sys: Hertz,
pub apb1: Hertz,
pub apb2: Hertz,
2021-06-15 16:07:23 +02:00
pub apb1_tim: Hertz,
pub apb2_tim: Hertz,
2021-06-14 10:48:14 +02:00
#[cfg(any(rcc_l0))]
pub ahb: Hertz,
#[cfg(any(rcc_l4, rcc_f4, rcc_h7, rcc_wb55, rcc_wl5x))]
2021-06-14 10:48:14 +02:00
pub ahb1: Hertz,
#[cfg(any(rcc_l4, rcc_f4, rcc_h7, rcc_wb55, rcc_wl5x))]
2021-06-14 10:48:14 +02:00
pub ahb2: Hertz,
#[cfg(any(rcc_l4, rcc_f4, rcc_h7, rcc_wb55, rcc_wl5x))]
2021-06-14 11:41:02 +02:00
pub ahb3: Hertz,
2021-06-14 10:48:14 +02:00
#[cfg(any(rcc_h7))]
pub apb4: Hertz,
}
2021-05-27 09:50:11 +02:00
/// Frozen clock frequencies
///
/// The existence of this value indicates that the clock configuration can no longer be changed
static mut CLOCK_FREQS: MaybeUninit<Clocks> = MaybeUninit::uninit();
/// Sets the clock frequencies
///
/// Safety: Sets a mutable global.
pub unsafe fn set_freqs(freqs: Clocks) {
CLOCK_FREQS.as_mut_ptr().write(freqs);
}
/// Safety: Reads a mutable global.
pub unsafe fn get_freqs() -> &'static Clocks {
&*CLOCK_FREQS.as_ptr()
}
cfg_if::cfg_if! {
if #[cfg(rcc_h7)] {
mod h7;
pub use h7::*;
} else if #[cfg(rcc_l0)] {
mod l0;
pub use l0::*;
2021-06-11 17:45:07 +02:00
} else if #[cfg(rcc_l4)] {
2021-06-14 10:48:14 +02:00
mod l4;
pub use l4::*;
2021-06-11 17:45:07 +02:00
} else if #[cfg(rcc_f4)] {
2021-06-14 10:48:14 +02:00
mod f4;
pub use f4::*;
2021-06-14 11:41:02 +02:00
} else if #[cfg(rcc_wb55)] {
mod wb55;
pub use wb55::*;
} else if #[cfg(rcc_wl5x)] {
mod wl5x;
pub use wl5x::*;
}
}
pub(crate) mod sealed {
pub trait RccPeripheral {
fn frequency() -> crate::time::Hertz;
fn reset();
fn enable();
fn disable();
}
}
pub trait RccPeripheral: sealed::RccPeripheral + 'static {}
crate::pac::peripheral_rcc!(
($inst:ident, $clk:ident, $enable:ident, $reset:ident, $perien:ident, $perirst:ident) => {
impl sealed::RccPeripheral for peripherals::$inst {
fn frequency() -> crate::time::Hertz {
critical_section::with(|_| {
unsafe {
let freqs = get_freqs();
freqs.$clk
}
})
}
fn enable() {
2021-06-08 13:10:40 +02:00
critical_section::with(|_| {
unsafe {
crate::pac::RCC.$enable().modify(|w| w.$perien(true));
}
})
}
fn disable() {
2021-06-08 13:10:40 +02:00
critical_section::with(|_| {
unsafe {
crate::pac::RCC.$enable().modify(|w| w.$perien(false));
}
})
}
fn reset() {
2021-06-08 13:10:40 +02:00
critical_section::with(|_| {
unsafe {
crate::pac::RCC.$reset().modify(|w| w.$perirst(true));
crate::pac::RCC.$reset().modify(|w| w.$perirst(false));
}
})
}
}
impl RccPeripheral for peripherals::$inst {}
};
);