2023-09-07 00:33:56 +02:00
|
|
|
#[allow(dead_code)]
|
|
|
|
#[derive(Default)]
|
|
|
|
pub enum LseDrive {
|
|
|
|
#[cfg(any(rtc_v2f7, rtc_v2l4))]
|
|
|
|
Low = 0,
|
|
|
|
MediumLow = 0x01,
|
|
|
|
#[default]
|
|
|
|
MediumHigh = 0x02,
|
|
|
|
#[cfg(any(rtc_v2f7, rtc_v2l4))]
|
|
|
|
High = 0x03,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(any(rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l4))]
|
|
|
|
impl From<LseDrive> for crate::pac::rcc::vals::Lsedrv {
|
|
|
|
fn from(value: LseDrive) -> Self {
|
|
|
|
use crate::pac::rcc::vals::Lsedrv;
|
|
|
|
|
|
|
|
match value {
|
|
|
|
#[cfg(any(rtc_v2f7, rtc_v2l4))]
|
|
|
|
LseDrive::Low => Lsedrv::LOW,
|
|
|
|
LseDrive::MediumLow => Lsedrv::MEDIUMLOW,
|
|
|
|
LseDrive::MediumHigh => Lsedrv::MEDIUMHIGH,
|
|
|
|
#[cfg(any(rtc_v2f7, rtc_v2l4))]
|
|
|
|
LseDrive::High => Lsedrv::HIGH,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-16 03:44:01 +02:00
|
|
|
pub use crate::pac::rcc::vals::Rtcsel as RtcClockSource;
|
2023-08-27 16:07:34 +02:00
|
|
|
|
2023-08-27 22:18:34 +02:00
|
|
|
#[cfg(not(any(rtc_v2l0, rtc_v2l1, stm32c0)))]
|
|
|
|
#[allow(dead_code)]
|
2023-08-27 22:01:09 +02:00
|
|
|
type Bdcr = crate::pac::rcc::regs::Bdcr;
|
|
|
|
|
|
|
|
#[cfg(any(rtc_v2l0, rtc_v2l1))]
|
2023-08-27 22:18:34 +02:00
|
|
|
#[allow(dead_code)]
|
2023-08-27 22:01:09 +02:00
|
|
|
type Bdcr = crate::pac::rcc::regs::Csr;
|
|
|
|
|
2023-08-27 16:12:04 +02:00
|
|
|
#[allow(dead_code)]
|
2023-08-27 16:07:34 +02:00
|
|
|
pub struct BackupDomain {}
|
|
|
|
|
|
|
|
impl BackupDomain {
|
|
|
|
#[cfg(any(
|
2023-08-27 22:01:09 +02:00
|
|
|
rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3,
|
|
|
|
rtc_v3u5
|
2023-08-27 16:07:34 +02:00
|
|
|
))]
|
2023-08-27 22:18:34 +02:00
|
|
|
#[allow(dead_code, unused_variables)]
|
2023-08-27 22:01:09 +02:00
|
|
|
fn modify<R>(f: impl FnOnce(&mut Bdcr) -> R) -> R {
|
2023-09-15 01:53:27 +02:00
|
|
|
#[cfg(any(rtc_v2f2, rtc_v2f3, rtc_v2l1, rtc_v2l0))]
|
2023-08-27 16:07:34 +02:00
|
|
|
let cr = crate::pac::PWR.cr();
|
2023-08-27 22:01:09 +02:00
|
|
|
#[cfg(any(rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))]
|
2023-08-27 16:07:34 +02:00
|
|
|
let cr = crate::pac::PWR.cr1();
|
|
|
|
|
|
|
|
// TODO: Missing from PAC for l0 and f0?
|
2023-09-15 01:53:27 +02:00
|
|
|
#[cfg(not(any(rtc_v2f0, rtc_v3u5)))]
|
2023-08-27 16:07:34 +02:00
|
|
|
{
|
2023-08-27 22:01:09 +02:00
|
|
|
cr.modify(|w| w.set_dbp(true));
|
|
|
|
while !cr.read().dbp() {}
|
2023-08-27 16:07:34 +02:00
|
|
|
}
|
|
|
|
|
2023-08-27 22:18:34 +02:00
|
|
|
#[cfg(any(rtc_v2l0, rtc_v2l1))]
|
|
|
|
let cr = crate::pac::RCC.csr();
|
|
|
|
|
|
|
|
#[cfg(not(any(rtc_v2l0, rtc_v2l1)))]
|
|
|
|
let cr = crate::pac::RCC.bdcr();
|
|
|
|
|
|
|
|
cr.modify(|w| f(w))
|
2023-08-27 16:07:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(any(
|
2023-08-27 22:01:09 +02:00
|
|
|
rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3,
|
|
|
|
rtc_v3u5
|
2023-08-27 16:07:34 +02:00
|
|
|
))]
|
2023-08-27 16:12:04 +02:00
|
|
|
#[allow(dead_code)]
|
2023-08-27 22:01:09 +02:00
|
|
|
fn read() -> Bdcr {
|
2023-08-27 16:07:34 +02:00
|
|
|
#[cfg(any(rtc_v2l0, rtc_v2l1))]
|
2023-08-27 22:01:09 +02:00
|
|
|
let r = crate::pac::RCC.csr().read();
|
2023-08-27 16:07:34 +02:00
|
|
|
|
2023-08-27 22:01:09 +02:00
|
|
|
#[cfg(not(any(rtc_v2l0, rtc_v2l1)))]
|
|
|
|
let r = crate::pac::RCC.bdcr().read();
|
2023-08-27 16:07:34 +02:00
|
|
|
|
2023-08-27 22:01:09 +02:00
|
|
|
r
|
2023-08-27 16:07:34 +02:00
|
|
|
}
|
|
|
|
|
2023-09-09 01:20:58 +02:00
|
|
|
#[cfg(any(
|
|
|
|
rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb, rtc_v3,
|
|
|
|
rtc_v3u5
|
|
|
|
))]
|
2023-09-07 00:33:56 +02:00
|
|
|
#[allow(dead_code, unused_variables)]
|
2023-09-09 01:20:58 +02:00
|
|
|
pub fn configure_ls(clock_source: RtcClockSource, lse_drive: Option<LseDrive>) {
|
|
|
|
match clock_source {
|
|
|
|
RtcClockSource::LSI => {
|
|
|
|
#[cfg(rtc_v3u5)]
|
|
|
|
let csr = crate::pac::RCC.bdcr();
|
|
|
|
|
|
|
|
#[cfg(not(rtc_v3u5))]
|
|
|
|
let csr = crate::pac::RCC.csr();
|
|
|
|
|
|
|
|
Self::modify(|_| {
|
2023-09-16 03:44:01 +02:00
|
|
|
#[cfg(not(any(rcc_wb, rcc_wba)))]
|
2023-09-09 01:20:58 +02:00
|
|
|
csr.modify(|w| w.set_lsion(true));
|
|
|
|
|
2023-09-16 03:44:01 +02:00
|
|
|
#[cfg(any(rcc_wb, rcc_wba))]
|
2023-09-09 01:20:58 +02:00
|
|
|
csr.modify(|w| w.set_lsi1on(true));
|
|
|
|
});
|
|
|
|
|
2023-09-16 03:44:01 +02:00
|
|
|
#[cfg(not(any(rcc_wb, rcc_wba)))]
|
2023-09-09 01:20:58 +02:00
|
|
|
while !csr.read().lsirdy() {}
|
|
|
|
|
2023-09-16 03:44:01 +02:00
|
|
|
#[cfg(any(rcc_wb, rcc_wba))]
|
2023-09-09 01:20:58 +02:00
|
|
|
while !csr.read().lsi1rdy() {}
|
|
|
|
}
|
|
|
|
RtcClockSource::LSE => {
|
|
|
|
let lse_drive = lse_drive.unwrap_or_default();
|
|
|
|
|
|
|
|
Self::modify(|w| {
|
|
|
|
#[cfg(any(rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l4))]
|
|
|
|
w.set_lsedrv(lse_drive.into());
|
|
|
|
w.set_lseon(true);
|
|
|
|
});
|
|
|
|
|
|
|
|
while !Self::read().lserdy() {}
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
};
|
2023-09-07 00:33:56 +02:00
|
|
|
|
2023-09-16 03:44:01 +02:00
|
|
|
if clock_source == RtcClockSource::NOCLOCK {
|
|
|
|
// disable it
|
|
|
|
Self::modify(|w| {
|
|
|
|
#[cfg(not(rcc_wba))]
|
|
|
|
w.set_rtcen(false);
|
|
|
|
w.set_rtcsel(clock_source);
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
// check if it's already enabled and in the source we want.
|
|
|
|
let reg = Self::read();
|
|
|
|
let ok = reg.rtcsel() == clock_source;
|
|
|
|
#[cfg(not(rcc_wba))]
|
|
|
|
let ok = ok & reg.rtcen();
|
2023-08-27 16:07:34 +02:00
|
|
|
|
2023-09-16 03:44:01 +02:00
|
|
|
// if not, configure it.
|
|
|
|
if !ok {
|
|
|
|
#[cfg(any(rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))]
|
|
|
|
assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet.");
|
2023-08-27 16:07:34 +02:00
|
|
|
|
2023-09-16 03:44:01 +02:00
|
|
|
#[cfg(not(any(rcc_l0, rcc_l1)))]
|
|
|
|
Self::modify(|w| w.set_bdrst(true));
|
2023-08-27 16:07:34 +02:00
|
|
|
|
2023-09-16 03:44:01 +02:00
|
|
|
Self::modify(|w| {
|
|
|
|
// Reset
|
|
|
|
#[cfg(not(any(rcc_l0, rcc_l1)))]
|
|
|
|
w.set_bdrst(false);
|
2023-08-27 16:07:34 +02:00
|
|
|
|
2023-09-16 03:44:01 +02:00
|
|
|
#[cfg(not(rcc_wba))]
|
|
|
|
w.set_rtcen(true);
|
|
|
|
w.set_rtcsel(clock_source);
|
2023-08-27 16:07:34 +02:00
|
|
|
|
2023-09-16 03:44:01 +02:00
|
|
|
// Restore bcdr
|
|
|
|
#[cfg(any(rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))]
|
|
|
|
w.set_lscosel(reg.lscosel());
|
|
|
|
#[cfg(any(rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))]
|
|
|
|
w.set_lscoen(reg.lscoen());
|
2023-08-27 16:07:34 +02:00
|
|
|
|
2023-09-16 03:44:01 +02:00
|
|
|
w.set_lseon(reg.lseon());
|
2023-08-27 16:07:34 +02:00
|
|
|
|
2023-09-16 03:44:01 +02:00
|
|
|
#[cfg(any(rtc_v2f0, rtc_v2f7, rtc_v2h7, rtc_v2l4, rtc_v2wb, rtc_v3, rtc_v3u5))]
|
|
|
|
w.set_lsedrv(reg.lsedrv());
|
|
|
|
w.set_lsebyp(reg.lsebyp());
|
|
|
|
});
|
|
|
|
}
|
2023-08-27 16:07:34 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|