2021-06-02 16:34:37 +02:00
|
|
|
#![macro_use]
|
|
|
|
|
2021-05-27 09:50:11 +02:00
|
|
|
use core::mem::MaybeUninit;
|
2021-06-14 10:48:14 +02:00
|
|
|
|
2022-06-12 22:15:44 +02:00
|
|
|
use crate::time::Hertz;
|
|
|
|
|
2023-10-11 03:53:27 +02:00
|
|
|
mod bd;
|
2023-09-19 04:22:57 +02:00
|
|
|
mod mco;
|
2023-10-11 03:53:27 +02:00
|
|
|
pub use bd::*;
|
2023-09-19 04:22:57 +02:00
|
|
|
pub use mco::*;
|
|
|
|
|
2023-11-05 23:35:01 +01:00
|
|
|
#[cfg(crs)]
|
|
|
|
mod hsi48;
|
|
|
|
#[cfg(crs)]
|
|
|
|
pub use hsi48::*;
|
|
|
|
|
2022-02-14 02:12:06 +01:00
|
|
|
#[cfg_attr(rcc_f0, path = "f0.rs")]
|
2022-06-26 23:52:38 +02:00
|
|
|
#[cfg_attr(any(rcc_f1, rcc_f100, rcc_f1cl), path = "f1.rs")]
|
2022-03-27 17:40:49 +02:00
|
|
|
#[cfg_attr(rcc_f2, path = "f2.rs")]
|
2023-08-19 00:59:37 +02:00
|
|
|
#[cfg_attr(any(rcc_f3, rcc_f3_v2), path = "f3.rs")]
|
2023-10-18 04:31:53 +02:00
|
|
|
#[cfg_attr(any(rcc_f4, rcc_f410, rcc_f7), path = "f4f7.rs")]
|
2023-01-17 18:54:23 +01:00
|
|
|
#[cfg_attr(rcc_c0, path = "c0.rs")]
|
2022-01-04 19:25:50 +01:00
|
|
|
#[cfg_attr(rcc_g0, path = "g0.rs")]
|
|
|
|
#[cfg_attr(rcc_g4, path = "g4.rs")]
|
2023-10-03 23:45:05 +02:00
|
|
|
#[cfg_attr(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab), path = "h.rs")]
|
2023-10-11 01:08:01 +02:00
|
|
|
#[cfg_attr(any(rcc_l0, rcc_l0_v2, rcc_l1), path = "l0l1.rs")]
|
2023-10-23 01:09:36 +02:00
|
|
|
#[cfg_attr(any(rcc_l4, rcc_l4plus, rcc_l5, rcc_wl5, rcc_wle, rcc_wb), path = "l4l5.rs")]
|
2022-01-04 19:25:50 +01:00
|
|
|
#[cfg_attr(rcc_u5, path = "u5.rs")]
|
2023-09-16 03:44:01 +02:00
|
|
|
#[cfg_attr(rcc_wba, path = "wba.rs")]
|
2022-01-04 19:25:50 +01:00
|
|
|
mod _version;
|
2023-10-12 01:16:42 +02:00
|
|
|
|
|
|
|
pub use _version::*;
|
2022-01-04 19:25:50 +01:00
|
|
|
|
2023-09-18 01:41:45 +02:00
|
|
|
// Model Clock Configuration
|
|
|
|
//
|
|
|
|
// pub struct Clocks {
|
|
|
|
// hse: Option<Hertz>,
|
|
|
|
// hsi: bool,
|
|
|
|
// lse: Option<Hertz>,
|
|
|
|
// lsi: bool,
|
|
|
|
// rtc: RtcSource,
|
|
|
|
// }
|
|
|
|
|
2023-01-20 16:31:04 +01:00
|
|
|
#[derive(Clone, Copy, Debug)]
|
|
|
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
2021-06-14 10:48:14 +02:00
|
|
|
pub struct Clocks {
|
|
|
|
pub sys: Hertz,
|
2021-07-30 22:48:13 +02:00
|
|
|
|
2022-02-14 02:12:06 +01:00
|
|
|
// APB
|
2023-10-16 02:51:35 +02:00
|
|
|
pub pclk1: Hertz,
|
|
|
|
pub pclk1_tim: Hertz,
|
2023-01-17 18:54:23 +01:00
|
|
|
#[cfg(not(any(rcc_c0, rcc_g0)))]
|
2023-10-16 02:51:35 +02:00
|
|
|
pub pclk2: Hertz,
|
2023-01-17 18:54:23 +01:00
|
|
|
#[cfg(not(any(rcc_c0, rcc_g0)))]
|
2023-10-16 02:51:35 +02:00
|
|
|
pub pclk2_tim: Hertz,
|
2023-10-03 23:45:05 +02:00
|
|
|
#[cfg(any(rcc_wl5, rcc_wle, rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab, rcc_u5))]
|
2023-10-16 02:51:35 +02:00
|
|
|
pub pclk3: Hertz,
|
2023-10-14 19:51:45 +02:00
|
|
|
#[cfg(any(rcc_h7, rcc_h7rm0433, rcc_h7ab, stm32h5))]
|
2023-10-16 02:51:35 +02:00
|
|
|
pub pclk4: Hertz,
|
2023-09-16 03:44:01 +02:00
|
|
|
#[cfg(any(rcc_wba))]
|
2023-10-16 02:51:35 +02:00
|
|
|
pub pclk7: Hertz,
|
2021-06-23 01:07:48 +02:00
|
|
|
|
2022-02-14 02:12:06 +01:00
|
|
|
// AHB
|
2023-10-16 02:51:35 +02:00
|
|
|
pub hclk1: Hertz,
|
2022-01-24 00:50:35 +01:00
|
|
|
#[cfg(any(
|
2023-10-03 23:45:05 +02:00
|
|
|
rcc_l4,
|
2023-10-16 03:09:33 +02:00
|
|
|
rcc_l4plus,
|
2023-10-03 23:45:05 +02:00
|
|
|
rcc_l5,
|
|
|
|
rcc_f2,
|
|
|
|
rcc_f4,
|
|
|
|
rcc_f410,
|
|
|
|
rcc_f7,
|
|
|
|
rcc_h5,
|
|
|
|
rcc_h50,
|
|
|
|
rcc_h7,
|
|
|
|
rcc_h7rm0433,
|
|
|
|
rcc_h7ab,
|
|
|
|
rcc_g4,
|
|
|
|
rcc_u5,
|
|
|
|
rcc_wb,
|
|
|
|
rcc_wba,
|
|
|
|
rcc_wl5,
|
|
|
|
rcc_wle
|
2022-01-24 00:50:35 +01:00
|
|
|
))]
|
2023-10-16 02:51:35 +02:00
|
|
|
pub hclk2: Hertz,
|
2022-02-24 05:59:42 +01:00
|
|
|
#[cfg(any(
|
2023-10-03 23:45:05 +02:00
|
|
|
rcc_l4,
|
2023-10-16 03:09:33 +02:00
|
|
|
rcc_l4plus,
|
2023-10-03 23:45:05 +02:00
|
|
|
rcc_l5,
|
|
|
|
rcc_f2,
|
|
|
|
rcc_f4,
|
|
|
|
rcc_f410,
|
|
|
|
rcc_f7,
|
|
|
|
rcc_h5,
|
|
|
|
rcc_h50,
|
|
|
|
rcc_h7,
|
|
|
|
rcc_h7rm0433,
|
|
|
|
rcc_h7ab,
|
|
|
|
rcc_u5,
|
|
|
|
rcc_wb,
|
|
|
|
rcc_wl5,
|
2023-04-06 18:53:51 +02:00
|
|
|
rcc_wle
|
2022-02-24 05:59:42 +01:00
|
|
|
))]
|
2023-10-16 02:51:35 +02:00
|
|
|
pub hclk3: Hertz,
|
2023-10-03 23:45:05 +02:00
|
|
|
#[cfg(any(rcc_h5, rcc_h50, rcc_h7, rcc_h7rm0433, rcc_h7ab, rcc_wba))]
|
2023-10-16 02:51:35 +02:00
|
|
|
pub hclk4: Hertz,
|
2021-07-09 15:33:17 +02:00
|
|
|
|
2023-04-15 04:28:27 +02:00
|
|
|
#[cfg(all(rcc_f4, not(stm32f410)))]
|
2023-10-15 22:10:42 +02:00
|
|
|
pub plli2s1_q: Option<Hertz>,
|
|
|
|
#[cfg(all(rcc_f4, not(stm32f410)))]
|
|
|
|
pub plli2s1_r: Option<Hertz>,
|
2023-04-14 23:30:36 +02:00
|
|
|
|
2023-10-17 03:04:10 +02:00
|
|
|
#[cfg(rcc_l4)]
|
|
|
|
pub pllsai1_p: Option<Hertz>,
|
2023-04-15 04:28:27 +02:00
|
|
|
#[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))]
|
2023-10-15 22:10:42 +02:00
|
|
|
pub pllsai1_q: Option<Hertz>,
|
|
|
|
#[cfg(any(stm32f427, stm32f429, stm32f437, stm32f439, stm32f446, stm32f469, stm32f479))]
|
|
|
|
pub pllsai1_r: Option<Hertz>,
|
2023-10-17 03:04:10 +02:00
|
|
|
#[cfg(rcc_l4)]
|
|
|
|
pub pllsai2_p: Option<Hertz>,
|
2023-04-15 04:28:27 +02:00
|
|
|
|
2023-10-17 03:04:10 +02:00
|
|
|
#[cfg(any(stm32g4, rcc_l4))]
|
2023-10-15 06:33:57 +02:00
|
|
|
pub pll1_p: Option<Hertz>,
|
2023-10-17 03:04:10 +02:00
|
|
|
#[cfg(any(stm32h5, stm32h7, rcc_f2, rcc_f4, rcc_f410, rcc_f7, rcc_l4))]
|
2023-10-15 06:33:57 +02:00
|
|
|
pub pll1_q: Option<Hertz>,
|
|
|
|
#[cfg(any(stm32h5, stm32h7))]
|
|
|
|
pub pll2_p: Option<Hertz>,
|
|
|
|
#[cfg(any(stm32h5, stm32h7))]
|
2023-10-15 22:10:42 +02:00
|
|
|
pub pll2_q: Option<Hertz>,
|
|
|
|
#[cfg(any(stm32h5, stm32h7))]
|
2023-10-15 06:33:57 +02:00
|
|
|
pub pll2_r: Option<Hertz>,
|
|
|
|
#[cfg(any(stm32h5, stm32h7))]
|
|
|
|
pub pll3_p: Option<Hertz>,
|
|
|
|
#[cfg(any(stm32h5, stm32h7))]
|
|
|
|
pub pll3_q: Option<Hertz>,
|
|
|
|
#[cfg(any(stm32h5, stm32h7))]
|
|
|
|
pub pll3_r: Option<Hertz>,
|
|
|
|
|
2023-10-03 23:45:05 +02:00
|
|
|
#[cfg(any(
|
|
|
|
rcc_f1,
|
|
|
|
rcc_f100,
|
|
|
|
rcc_f1cl,
|
|
|
|
rcc_h5,
|
|
|
|
rcc_h50,
|
|
|
|
rcc_h7,
|
|
|
|
rcc_h7rm0433,
|
|
|
|
rcc_h7ab,
|
|
|
|
rcc_f3,
|
|
|
|
rcc_g4
|
|
|
|
))]
|
2022-03-19 11:05:00 +01:00
|
|
|
pub adc: Option<Hertz>,
|
2023-08-06 18:11:53 +02:00
|
|
|
|
2023-09-06 00:02:28 +02:00
|
|
|
#[cfg(any(rcc_f3, rcc_g4))]
|
2023-09-05 23:46:57 +02:00
|
|
|
pub adc34: Option<Hertz>,
|
2023-08-21 04:31:47 +02:00
|
|
|
|
2023-09-10 20:33:17 +02:00
|
|
|
#[cfg(stm32f334)]
|
|
|
|
pub hrtim: Option<Hertz>,
|
|
|
|
|
2023-08-06 18:11:53 +02:00
|
|
|
pub rtc: Option<Hertz>,
|
2023-10-12 03:59:47 +02:00
|
|
|
|
2023-10-17 03:04:10 +02:00
|
|
|
#[cfg(any(stm32h5, stm32h7, rcc_l4, rcc_c0))]
|
2023-10-14 19:51:45 +02:00
|
|
|
pub hsi: Option<Hertz>,
|
2023-10-14 06:06:32 +02:00
|
|
|
#[cfg(stm32h5)]
|
2023-10-14 19:51:45 +02:00
|
|
|
pub hsi48: Option<Hertz>,
|
2023-10-14 06:06:32 +02:00
|
|
|
#[cfg(stm32h5)]
|
2023-10-14 19:51:45 +02:00
|
|
|
pub lsi: Option<Hertz>,
|
2023-10-15 06:33:57 +02:00
|
|
|
#[cfg(any(stm32h5, stm32h7))]
|
2023-10-14 19:51:45 +02:00
|
|
|
pub csi: Option<Hertz>,
|
2023-10-14 06:06:32 +02:00
|
|
|
|
2023-10-17 03:04:10 +02:00
|
|
|
#[cfg(any(stm32h5, stm32h7, rcc_l4, rcc_c0))]
|
2023-10-14 19:51:45 +02:00
|
|
|
pub lse: Option<Hertz>,
|
2023-10-15 06:33:57 +02:00
|
|
|
#[cfg(any(stm32h5, stm32h7))]
|
2023-10-14 19:51:45 +02:00
|
|
|
pub hse: Option<Hertz>,
|
2023-10-12 03:59:47 +02:00
|
|
|
|
|
|
|
#[cfg(stm32h5)]
|
2023-10-14 19:51:45 +02:00
|
|
|
pub audioclk: Option<Hertz>,
|
2023-10-15 06:33:57 +02:00
|
|
|
#[cfg(any(stm32h5, stm32h7))]
|
2023-10-14 19:51:45 +02:00
|
|
|
pub per: Option<Hertz>,
|
2023-10-15 06:33:57 +02:00
|
|
|
|
|
|
|
#[cfg(stm32h7)]
|
|
|
|
pub rcc_pclk_d3: Option<Hertz>,
|
2023-10-17 03:04:10 +02:00
|
|
|
#[cfg(rcc_l4)]
|
|
|
|
pub sai1_extclk: Option<Hertz>,
|
|
|
|
#[cfg(rcc_l4)]
|
|
|
|
pub sai2_extclk: Option<Hertz>,
|
2021-06-14 10:48:14 +02:00
|
|
|
}
|
2021-05-27 09:50:11 +02:00
|
|
|
|
2023-08-24 03:18:34 +02:00
|
|
|
#[cfg(feature = "low-power")]
|
2023-11-04 19:49:54 +01:00
|
|
|
/// Must be written within a critical section
|
|
|
|
///
|
|
|
|
/// May be read without a critical section
|
|
|
|
pub(crate) static mut REFCOUNT_STOP1: u32 = 0;
|
|
|
|
|
|
|
|
#[cfg(feature = "low-power")]
|
|
|
|
/// Must be written within a critical section
|
|
|
|
///
|
|
|
|
/// May be read without a critical section
|
2023-10-26 02:07:31 +02:00
|
|
|
pub(crate) static mut REFCOUNT_STOP2: u32 = 0;
|
2023-08-24 03:18:34 +02:00
|
|
|
|
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.
|
2022-01-04 19:25:50 +01:00
|
|
|
pub(crate) unsafe fn set_freqs(freqs: Clocks) {
|
2023-01-20 16:31:04 +01:00
|
|
|
debug!("rcc: {:?}", freqs);
|
2023-07-04 23:29:46 +02:00
|
|
|
CLOCK_FREQS = MaybeUninit::new(freqs);
|
2021-05-27 09:50:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Safety: Reads a mutable global.
|
2022-01-04 19:25:50 +01:00
|
|
|
pub(crate) unsafe fn get_freqs() -> &'static Clocks {
|
2023-07-04 23:29:46 +02:00
|
|
|
CLOCK_FREQS.assume_init_ref()
|
2021-05-27 09:50:11 +02:00
|
|
|
}
|
|
|
|
|
2021-12-08 17:38:12 +01:00
|
|
|
#[cfg(feature = "unstable-pac")]
|
|
|
|
pub mod low_level {
|
|
|
|
pub use super::sealed::*;
|
|
|
|
}
|
|
|
|
|
2021-06-02 16:34:37 +02:00
|
|
|
pub(crate) mod sealed {
|
2023-10-12 00:34:47 +02:00
|
|
|
use critical_section::CriticalSection;
|
|
|
|
|
2021-06-02 16:34:37 +02:00
|
|
|
pub trait RccPeripheral {
|
2021-06-11 09:19:02 +02:00
|
|
|
fn frequency() -> crate::time::Hertz;
|
2023-10-12 00:34:47 +02:00
|
|
|
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))
|
|
|
|
}
|
2021-06-02 16:34:37 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub trait RccPeripheral: sealed::RccPeripheral + 'static {}
|
2023-10-23 01:48:09 +02:00
|
|
|
|
|
|
|
#[allow(unused)]
|
|
|
|
mod util {
|
|
|
|
use crate::time::Hertz;
|
|
|
|
|
|
|
|
pub fn calc_pclk<D>(hclk: Hertz, ppre: D) -> (Hertz, Hertz)
|
|
|
|
where
|
|
|
|
Hertz: core::ops::Div<D, Output = Hertz>,
|
|
|
|
{
|
|
|
|
let pclk = hclk / ppre;
|
|
|
|
let pclk_tim = if hclk == pclk { pclk } else { pclk * 2u32 };
|
|
|
|
(pclk, pclk_tim)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn all_equal<T: Eq>(mut iter: impl Iterator<Item = T>) -> bool {
|
|
|
|
let Some(x) = iter.next() else { return true };
|
|
|
|
if !iter.all(|y| y == x) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
true
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_equal<T: Eq>(mut iter: impl Iterator<Item = T>) -> Result<Option<T>, ()> {
|
|
|
|
let Some(x) = iter.next() else { return Ok(None) };
|
|
|
|
if !iter.all(|y| y == x) {
|
|
|
|
return Err(());
|
|
|
|
}
|
|
|
|
Ok(Some(x))
|
|
|
|
}
|
|
|
|
}
|