stm32/rtc: cleanup and consolidate
This commit is contained in:
parent
46227bec1e
commit
f589247c1f
15 changed files with 110 additions and 438 deletions
|
@ -1,85 +0,0 @@
|
||||||
use chrono::{Datelike, Timelike};
|
|
||||||
|
|
||||||
use super::byte_to_bcd2;
|
|
||||||
use crate::pac::rtc::Rtc;
|
|
||||||
|
|
||||||
/// Alias for [`chrono::NaiveDateTime`]
|
|
||||||
pub type DateTime = chrono::NaiveDateTime;
|
|
||||||
/// Alias for [`chrono::Weekday`]
|
|
||||||
pub type DayOfWeek = chrono::Weekday;
|
|
||||||
|
|
||||||
/// Errors regarding the [`DateTime`] and [`DateTimeFilter`] structs.
|
|
||||||
///
|
|
||||||
/// [`DateTimeFilter`]: struct.DateTimeFilter.html
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
|
||||||
pub enum Error {
|
|
||||||
/// The [DateTime] has an invalid year. The year must be between 0 and 4095.
|
|
||||||
InvalidYear,
|
|
||||||
/// The [DateTime] contains an invalid date.
|
|
||||||
InvalidDate,
|
|
||||||
/// The [DateTime] contains an invalid time.
|
|
||||||
InvalidTime,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn day_of_week_to_u8(dotw: DayOfWeek) -> u8 {
|
|
||||||
dotw.num_days_from_monday() as u8
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn validate_datetime(dt: &DateTime) -> Result<(), Error> {
|
|
||||||
if dt.year() < 0 || dt.year() > 4095 {
|
|
||||||
// rp2040 can't hold these years
|
|
||||||
Err(Error::InvalidYear)
|
|
||||||
} else {
|
|
||||||
// The rest of the chrono date is assumed to be valid
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn write_date_time(rtc: &Rtc, t: DateTime) {
|
|
||||||
let (ht, hu) = byte_to_bcd2(t.hour() as u8);
|
|
||||||
let (mnt, mnu) = byte_to_bcd2(t.minute() as u8);
|
|
||||||
let (st, su) = byte_to_bcd2(t.second() as u8);
|
|
||||||
|
|
||||||
let (dt, du) = byte_to_bcd2(t.day() as u8);
|
|
||||||
let (mt, mu) = byte_to_bcd2(t.month() as u8);
|
|
||||||
let yr = t.year() as u16;
|
|
||||||
let yr_offset = (yr - 1970_u16) as u8;
|
|
||||||
let (yt, yu) = byte_to_bcd2(yr_offset);
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
rtc.tr().write(|w| {
|
|
||||||
w.set_ht(ht);
|
|
||||||
w.set_hu(hu);
|
|
||||||
w.set_mnt(mnt);
|
|
||||||
w.set_mnu(mnu);
|
|
||||||
w.set_st(st);
|
|
||||||
w.set_su(su);
|
|
||||||
w.set_pm(stm32_metapac::rtc::vals::Ampm::AM);
|
|
||||||
});
|
|
||||||
|
|
||||||
rtc.dr().write(|w| {
|
|
||||||
w.set_dt(dt);
|
|
||||||
w.set_du(du);
|
|
||||||
w.set_mt(mt > 0);
|
|
||||||
w.set_mu(mu);
|
|
||||||
w.set_yt(yt);
|
|
||||||
w.set_yu(yu);
|
|
||||||
w.set_wdu(day_of_week_to_u8(t.weekday()));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn datetime(
|
|
||||||
year: u16,
|
|
||||||
month: u8,
|
|
||||||
day: u8,
|
|
||||||
_day_of_week: u8,
|
|
||||||
hour: u8,
|
|
||||||
minute: u8,
|
|
||||||
second: u8,
|
|
||||||
) -> Result<DateTime, Error> {
|
|
||||||
let date = chrono::NaiveDate::from_ymd_opt(year.into(), month.try_into().unwrap(), day.into())
|
|
||||||
.ok_or(Error::InvalidDate)?;
|
|
||||||
let time = chrono::NaiveTime::from_hms_opt(hour.into(), minute.into(), second.into()).ok_or(Error::InvalidTime)?;
|
|
||||||
Ok(DateTime::new(date, time))
|
|
||||||
}
|
|
|
@ -10,7 +10,7 @@ pub use self::datetime::{DateTime, DayOfWeek, Error as DateTimeError};
|
||||||
any(
|
any(
|
||||||
rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb
|
rtc_v2f0, rtc_v2f2, rtc_v2f3, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l0, rtc_v2l1, rtc_v2l4, rtc_v2wb
|
||||||
),
|
),
|
||||||
path = "v2/mod.rs"
|
path = "v2.rs"
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(any(rtc_v3, rtc_v3u5), path = "v3.rs")]
|
#[cfg_attr(any(rtc_v3, rtc_v3u5), path = "v3.rs")]
|
||||||
mod versions;
|
mod versions;
|
||||||
|
|
|
@ -3,20 +3,6 @@ use stm32_metapac::rtc::vals::{Init, Osel, Pol};
|
||||||
use super::{Instance, RtcConfig};
|
use super::{Instance, RtcConfig};
|
||||||
use crate::pac::rtc::Rtc;
|
use crate::pac::rtc::Rtc;
|
||||||
|
|
||||||
#[cfg_attr(rtc_v2f0, path = "v2f0.rs")]
|
|
||||||
#[cfg_attr(rtc_v2f2, path = "v2f2.rs")]
|
|
||||||
#[cfg_attr(rtc_v2f3, path = "v2f3.rs")]
|
|
||||||
#[cfg_attr(rtc_v2f4, path = "v2f4.rs")]
|
|
||||||
#[cfg_attr(rtc_v2f7, path = "v2f7.rs")]
|
|
||||||
#[cfg_attr(rtc_v2h7, path = "v2h7.rs")]
|
|
||||||
#[cfg_attr(rtc_v2l0, path = "v2l0.rs")]
|
|
||||||
#[cfg_attr(rtc_v2l1, path = "v2l1.rs")]
|
|
||||||
#[cfg_attr(rtc_v2l4, path = "v2l4.rs")]
|
|
||||||
#[cfg_attr(rtc_v2wb, path = "v2wb.rs")]
|
|
||||||
mod family;
|
|
||||||
|
|
||||||
pub use family::*;
|
|
||||||
|
|
||||||
impl<'d, T: Instance> super::Rtc<'d, T> {
|
impl<'d, T: Instance> super::Rtc<'d, T> {
|
||||||
/// Applies the RTC config
|
/// Applies the RTC config
|
||||||
/// It this changes the RTC clock source the time will be reset
|
/// It this changes the RTC clock source the time will be reset
|
||||||
|
@ -169,3 +155,81 @@ pub fn write_backup_register(rtc: &Rtc, register: usize, value: u32) {
|
||||||
unsafe { rtc.bkpr(register).write(|w| w.set_bkp(value)) }
|
unsafe { rtc.bkpr(register).write(|w| w.set_bkp(value)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) unsafe fn enable_peripheral_clk() {
|
||||||
|
#[cfg(any(rtc_v2f0, rtc_v2f7, rtc_v2l4, rtc_v2wb))]
|
||||||
|
{
|
||||||
|
// enable peripheral clock for communication
|
||||||
|
crate::pac::RCC.apb1enr1().modify(|w| w.set_rtcapben(true));
|
||||||
|
|
||||||
|
// read to allow the pwr clock to enable
|
||||||
|
crate::pac::PWR.cr1().read();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const BACKUP_REGISTER_COUNT: usize = 20;
|
||||||
|
|
||||||
|
pub(super) unsafe fn unlock_backup_domain(clock_config: u8) {
|
||||||
|
#[cfg(not(rtc_v2wb))]
|
||||||
|
use stm32_metapac::rcc::vals::Rtcsel;
|
||||||
|
|
||||||
|
#[cfg(any(rtc_v2f2, rtc_v2f3, rtc_v2l1))]
|
||||||
|
let cr = crate::pac::PWR.cr();
|
||||||
|
#[cfg(any(rtc_v2f0, rtc_v2f4, rtc_v2f7, rtc_v2h7, rtc_v2l4, rtc_v2wb))]
|
||||||
|
let cr = crate::pac::PWR.cr1();
|
||||||
|
|
||||||
|
// TODO: Missing from PAC for l0?
|
||||||
|
#[cfg(not(rtc_v2l0))]
|
||||||
|
{
|
||||||
|
cr.modify(|w| w.set_dbp(true));
|
||||||
|
while !cr.read().dbp() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(any(rtc_v2l0, rtc_v2l1)))]
|
||||||
|
let reg = crate::pac::RCC.bdcr().read();
|
||||||
|
#[cfg(any(rtc_v2l0, rtc_v2l1))]
|
||||||
|
let reg = crate::pac::RCC.csr().read();
|
||||||
|
|
||||||
|
#[cfg(any(rtc_v2f0, rtc_v2f7, rtc_v2h7, rtc_v2l4, rtc_v2wb))]
|
||||||
|
assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet.");
|
||||||
|
|
||||||
|
#[cfg(rtc_v2wb)]
|
||||||
|
let rtcsel = reg.rtcsel();
|
||||||
|
#[cfg(not(rtc_v2wb))]
|
||||||
|
let rtcsel = reg.rtcsel().0;
|
||||||
|
|
||||||
|
if !reg.rtcen() || rtcsel != clock_config {
|
||||||
|
#[cfg(not(any(rtc_v2l0, rtc_v2l1)))]
|
||||||
|
crate::pac::RCC.bdcr().modify(|w| w.set_bdrst(true));
|
||||||
|
|
||||||
|
#[cfg(not(any(rtc_v2l0, rtc_v2l1)))]
|
||||||
|
let cr = crate::pac::RCC.bdcr();
|
||||||
|
#[cfg(any(rtc_v2l0, rtc_v2l1))]
|
||||||
|
let cr = crate::pac::RCC.csr();
|
||||||
|
|
||||||
|
cr.modify(|w| {
|
||||||
|
// Reset
|
||||||
|
#[cfg(not(any(rtc_v2l0, rtc_v2l1)))]
|
||||||
|
w.set_bdrst(false);
|
||||||
|
|
||||||
|
// Select RTC source
|
||||||
|
#[cfg(not(rtc_v2wb))]
|
||||||
|
w.set_rtcsel(Rtcsel(clock_config));
|
||||||
|
#[cfg(rtc_v2wb)]
|
||||||
|
w.set_rtcsel(clock_config);
|
||||||
|
w.set_rtcen(true);
|
||||||
|
|
||||||
|
// Restore bcdr
|
||||||
|
#[cfg(any(rtc_v2f0, rtc_v2f7, rtc_v2l4, rtc_v2wb))]
|
||||||
|
w.set_lscosel(reg.lscosel());
|
||||||
|
#[cfg(any(rtc_v2f0, rtc_v2f7, rtc_v2l4, rtc_v2wb))]
|
||||||
|
w.set_lscoen(reg.lscoen());
|
||||||
|
|
||||||
|
w.set_lseon(reg.lseon());
|
||||||
|
|
||||||
|
#[cfg(any(rtc_v2f0, rtc_v2f7, rtc_v2h7, rtc_v2l4, rtc_v2wb))]
|
||||||
|
w.set_lsedrv(reg.lsedrv());
|
||||||
|
w.set_lsebyp(reg.lsebyp());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,41 +0,0 @@
|
||||||
use stm32_metapac::rcc::vals::Rtcsel;
|
|
||||||
|
|
||||||
pub const BACKUP_REGISTER_COUNT: usize = 20;
|
|
||||||
|
|
||||||
/// Unlock the backup domain
|
|
||||||
pub(super) unsafe fn unlock_backup_domain(clock_config: u8) {
|
|
||||||
crate::pac::PWR.cr1().modify(|w| w.set_dbp(true));
|
|
||||||
while !crate::pac::PWR.cr1().read().dbp() {}
|
|
||||||
|
|
||||||
let reg = crate::pac::RCC.bdcr().read();
|
|
||||||
assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet.");
|
|
||||||
|
|
||||||
if !reg.rtcen() || reg.rtcsel().0 != clock_config {
|
|
||||||
crate::pac::RCC.bdcr().modify(|w| w.set_bdrst(true));
|
|
||||||
|
|
||||||
crate::pac::RCC.bdcr().modify(|w| {
|
|
||||||
// Reset
|
|
||||||
w.set_bdrst(false);
|
|
||||||
|
|
||||||
// Select RTC source
|
|
||||||
w.set_rtcsel(Rtcsel(clock_config));
|
|
||||||
w.set_rtcen(true);
|
|
||||||
|
|
||||||
// Restore bcdr
|
|
||||||
w.set_lscosel(reg.lscosel());
|
|
||||||
w.set_lscoen(reg.lscoen());
|
|
||||||
|
|
||||||
w.set_lseon(reg.lseon());
|
|
||||||
w.set_lsedrv(reg.lsedrv());
|
|
||||||
w.set_lsebyp(reg.lsebyp());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) unsafe fn enable_peripheral_clk() {
|
|
||||||
// enable peripheral clock for communication
|
|
||||||
crate::pac::RCC.apb1enr1().modify(|w| w.set_rtcapben(true));
|
|
||||||
|
|
||||||
// read to allow the pwr clock to enable
|
|
||||||
crate::pac::PWR.cr1().read();
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
use stm32_metapac::rcc::vals::Rtcsel;
|
|
||||||
|
|
||||||
pub const BACKUP_REGISTER_COUNT: usize = 20;
|
|
||||||
|
|
||||||
/// Unlock the backup domain
|
|
||||||
pub(super) unsafe fn unlock_backup_domain(clock_config: u8) {
|
|
||||||
crate::pac::PWR.cr().modify(|w| w.set_dbp(true));
|
|
||||||
while !crate::pac::PWR.cr().read().dbp() {}
|
|
||||||
|
|
||||||
let reg = crate::pac::RCC.bdcr().read();
|
|
||||||
|
|
||||||
if !reg.rtcen() || reg.rtcsel().0 != clock_config {
|
|
||||||
crate::pac::RCC.bdcr().modify(|w| w.set_bdrst(true));
|
|
||||||
|
|
||||||
crate::pac::RCC.bdcr().modify(|w| {
|
|
||||||
// Reset
|
|
||||||
w.set_bdrst(false);
|
|
||||||
|
|
||||||
// Select RTC source
|
|
||||||
w.set_rtcsel(Rtcsel(clock_config));
|
|
||||||
w.set_rtcen(true);
|
|
||||||
|
|
||||||
w.set_lseon(reg.lseon());
|
|
||||||
w.set_lsebyp(reg.lsebyp());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) unsafe fn enable_peripheral_clk() {
|
|
||||||
// Nothing to do
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
use stm32_metapac::rcc::vals::Rtcsel;
|
|
||||||
|
|
||||||
pub const BACKUP_REGISTER_COUNT: usize = 20;
|
|
||||||
|
|
||||||
/// Unlock the backup domain
|
|
||||||
pub(super) unsafe fn unlock_backup_domain(clock_config: u8) {
|
|
||||||
crate::pac::PWR.cr().modify(|w| w.set_dbp(true));
|
|
||||||
while !crate::pac::PWR.cr().read().dbp() {}
|
|
||||||
|
|
||||||
let reg = crate::pac::RCC.bdcr().read();
|
|
||||||
|
|
||||||
if !reg.rtcen() || reg.rtcsel().0 != clock_config {
|
|
||||||
crate::pac::RCC.bdcr().modify(|w| w.set_bdrst(true));
|
|
||||||
|
|
||||||
crate::pac::RCC.bdcr().modify(|w| {
|
|
||||||
// Reset
|
|
||||||
w.set_bdrst(false);
|
|
||||||
|
|
||||||
// Select RTC source
|
|
||||||
w.set_rtcsel(Rtcsel(clock_config));
|
|
||||||
w.set_rtcen(true);
|
|
||||||
|
|
||||||
w.set_lseon(reg.lseon());
|
|
||||||
w.set_lsebyp(reg.lsebyp());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) unsafe fn enable_peripheral_clk() {
|
|
||||||
// Nothing to do
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
use stm32_metapac::rcc::vals::Rtcsel;
|
|
||||||
|
|
||||||
pub const BACKUP_REGISTER_COUNT: usize = 20;
|
|
||||||
|
|
||||||
/// Unlock the backup domain
|
|
||||||
pub(super) unsafe fn unlock_backup_domain(clock_config: u8) {
|
|
||||||
crate::pac::PWR.cr1().modify(|w| w.set_dbp(true));
|
|
||||||
while !crate::pac::PWR.cr1().read().dbp() {}
|
|
||||||
|
|
||||||
let reg = crate::pac::RCC.bdcr().read();
|
|
||||||
|
|
||||||
if !reg.rtcen() || reg.rtcsel().0 != clock_config {
|
|
||||||
crate::pac::RCC.bdcr().modify(|w| w.set_bdrst(true));
|
|
||||||
|
|
||||||
crate::pac::RCC.bdcr().modify(|w| {
|
|
||||||
// Reset
|
|
||||||
w.set_bdrst(false);
|
|
||||||
|
|
||||||
// Select RTC source
|
|
||||||
w.set_rtcsel(Rtcsel(clock_config));
|
|
||||||
w.set_rtcen(true);
|
|
||||||
|
|
||||||
w.set_lseon(reg.lseon());
|
|
||||||
w.set_lsebyp(reg.lsebyp());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) unsafe fn enable_peripheral_clk() {
|
|
||||||
// Nothing to do
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
use stm32_metapac::rcc::vals::Rtcsel;
|
|
||||||
|
|
||||||
pub const BACKUP_REGISTER_COUNT: usize = 20;
|
|
||||||
|
|
||||||
/// Unlock the backup domain
|
|
||||||
pub(super) unsafe fn unlock_backup_domain(clock_config: u8) {
|
|
||||||
crate::pac::PWR.cr1().modify(|w| w.set_dbp(true));
|
|
||||||
while !crate::pac::PWR.cr1().read().dbp() {}
|
|
||||||
|
|
||||||
let reg = crate::pac::RCC.bdcr().read();
|
|
||||||
assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet.");
|
|
||||||
|
|
||||||
if !reg.rtcen() || reg.rtcsel().0 != clock_config {
|
|
||||||
crate::pac::RCC.bdcr().modify(|w| w.set_bdrst(true));
|
|
||||||
|
|
||||||
crate::pac::RCC.bdcr().modify(|w| {
|
|
||||||
// Reset
|
|
||||||
w.set_bdrst(false);
|
|
||||||
|
|
||||||
// Select RTC source
|
|
||||||
w.set_rtcsel(Rtcsel(clock_config));
|
|
||||||
w.set_rtcen(true);
|
|
||||||
|
|
||||||
// Restore bcdr
|
|
||||||
w.set_lscosel(reg.lscosel());
|
|
||||||
w.set_lscoen(reg.lscoen());
|
|
||||||
|
|
||||||
w.set_lseon(reg.lseon());
|
|
||||||
w.set_lsedrv(reg.lsedrv());
|
|
||||||
w.set_lsebyp(reg.lsebyp());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) unsafe fn enable_peripheral_clk() {
|
|
||||||
// enable peripheral clock for communication
|
|
||||||
crate::pac::RCC.apb1enr1().modify(|w| w.set_rtcapben(true));
|
|
||||||
|
|
||||||
// read to allow the pwr clock to enable
|
|
||||||
crate::pac::PWR.cr1().read();
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
use stm32_metapac::rcc::vals::Rtcsel;
|
|
||||||
|
|
||||||
pub const BACKUP_REGISTER_COUNT: usize = 20;
|
|
||||||
|
|
||||||
/// Unlock the backup domain
|
|
||||||
pub(super) unsafe fn unlock_backup_domain(clock_config: u8) {
|
|
||||||
crate::pac::PWR.cr1().modify(|w| w.set_dbp(true));
|
|
||||||
while !crate::pac::PWR.cr1().read().dbp() {}
|
|
||||||
|
|
||||||
let reg = crate::pac::RCC.bdcr().read();
|
|
||||||
assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet.");
|
|
||||||
|
|
||||||
if !reg.rtcen() || reg.rtcsel().0 != clock_config {
|
|
||||||
crate::pac::RCC.bdcr().modify(|w| w.set_bdrst(true));
|
|
||||||
|
|
||||||
crate::pac::RCC.bdcr().modify(|w| {
|
|
||||||
// Reset
|
|
||||||
w.set_bdrst(false);
|
|
||||||
|
|
||||||
// Select RTC source
|
|
||||||
w.set_rtcsel(Rtcsel(clock_config));
|
|
||||||
w.set_rtcen(true);
|
|
||||||
|
|
||||||
w.set_lseon(reg.lseon());
|
|
||||||
w.set_lsedrv(reg.lsedrv());
|
|
||||||
w.set_lsebyp(reg.lsebyp());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) unsafe fn enable_peripheral_clk() {
|
|
||||||
// Nothing to do
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
pub const BACKUP_REGISTER_COUNT: usize = 20;
|
|
||||||
|
|
||||||
/// Unlock the backup domain
|
|
||||||
pub(super) unsafe fn unlock_backup_domain(clock_config: u8) {
|
|
||||||
// TODO: Missing from PAC?
|
|
||||||
// crate::pac::PWR.cr().modify(|w| w.set_dbp(true));
|
|
||||||
// while !crate::pac::PWR.cr().read().dbp() {}
|
|
||||||
|
|
||||||
let reg = crate::pac::RCC.csr().read();
|
|
||||||
|
|
||||||
if !reg.rtcen() || reg.rtcsel().0 != clock_config {
|
|
||||||
crate::pac::RCC.csr().modify(|w| {
|
|
||||||
// Select RTC source
|
|
||||||
w.set_rtcsel(crate::pac::rcc::vals::Rtcsel(clock_config));
|
|
||||||
w.set_rtcen(true);
|
|
||||||
|
|
||||||
w.set_lseon(reg.lseon());
|
|
||||||
w.set_lsedrv(reg.lsedrv());
|
|
||||||
w.set_lsebyp(reg.lsebyp());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) unsafe fn enable_peripheral_clk() {
|
|
||||||
// Nothing to do
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
pub const BACKUP_REGISTER_COUNT: usize = 20;
|
|
||||||
|
|
||||||
/// Unlock the backup domain
|
|
||||||
pub(super) unsafe fn unlock_backup_domain(clock_config: u8) {
|
|
||||||
crate::pac::PWR.cr().modify(|w| w.set_dbp(true));
|
|
||||||
while !crate::pac::PWR.cr().read().dbp() {}
|
|
||||||
|
|
||||||
let reg = crate::pac::RCC.csr().read();
|
|
||||||
|
|
||||||
if !reg.rtcen() || reg.rtcsel().0 != clock_config {
|
|
||||||
crate::pac::RCC.csr().modify(|w| {
|
|
||||||
// Select RTC source
|
|
||||||
w.set_rtcsel(crate::pac::rcc::vals::Rtcsel(clock_config));
|
|
||||||
w.set_rtcen(true);
|
|
||||||
|
|
||||||
w.set_lseon(reg.lseon());
|
|
||||||
w.set_lsebyp(reg.lsebyp());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) unsafe fn enable_peripheral_clk() {
|
|
||||||
// Nothing to do
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
use stm32_metapac::rcc::vals::Rtcsel;
|
|
||||||
|
|
||||||
pub const BACKUP_REGISTER_COUNT: usize = 20;
|
|
||||||
|
|
||||||
/// Unlock the backup domain
|
|
||||||
pub(super) unsafe fn unlock_backup_domain(clock_config: u8) {
|
|
||||||
crate::pac::PWR.cr1().modify(|w| w.set_dbp(true));
|
|
||||||
while !crate::pac::PWR.cr1().read().dbp() {}
|
|
||||||
|
|
||||||
let reg = crate::pac::RCC.bdcr().read();
|
|
||||||
assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet.");
|
|
||||||
|
|
||||||
if !reg.rtcen() || reg.rtcsel().0 != clock_config {
|
|
||||||
crate::pac::RCC.bdcr().modify(|w| w.set_bdrst(true));
|
|
||||||
|
|
||||||
crate::pac::RCC.bdcr().modify(|w| {
|
|
||||||
// Reset
|
|
||||||
w.set_bdrst(false);
|
|
||||||
|
|
||||||
// Select RTC source
|
|
||||||
w.set_rtcsel(Rtcsel(clock_config));
|
|
||||||
w.set_rtcen(true);
|
|
||||||
|
|
||||||
// Restore bcdr
|
|
||||||
w.set_lscosel(reg.lscosel());
|
|
||||||
w.set_lscoen(reg.lscoen());
|
|
||||||
|
|
||||||
w.set_lseon(reg.lseon());
|
|
||||||
w.set_lsedrv(reg.lsedrv());
|
|
||||||
w.set_lsebyp(reg.lsebyp());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) unsafe fn enable_peripheral_clk() {
|
|
||||||
// enable peripheral clock for communication
|
|
||||||
crate::pac::RCC.apb1enr1().modify(|w| w.set_rtcapben(true));
|
|
||||||
|
|
||||||
// read to allow the pwr clock to enable
|
|
||||||
crate::pac::PWR.cr1().read();
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
pub const BACKUP_REGISTER_COUNT: usize = 20;
|
|
||||||
|
|
||||||
/// Unlock the backup domain
|
|
||||||
pub(super) unsafe fn unlock_backup_domain(clock_config: u8) {
|
|
||||||
crate::pac::PWR.cr1().modify(|w| w.set_dbp(true));
|
|
||||||
while !crate::pac::PWR.cr1().read().dbp() {}
|
|
||||||
|
|
||||||
let reg = crate::pac::RCC.bdcr().read();
|
|
||||||
assert!(!reg.lsecsson(), "RTC is not compatible with LSE CSS, yet.");
|
|
||||||
|
|
||||||
if !reg.rtcen() || reg.rtcsel() != clock_config {
|
|
||||||
crate::pac::RCC.bdcr().modify(|w| w.set_bdrst(true));
|
|
||||||
|
|
||||||
crate::pac::RCC.bdcr().modify(|w| {
|
|
||||||
// Reset
|
|
||||||
w.set_bdrst(false);
|
|
||||||
|
|
||||||
// Select RTC source
|
|
||||||
w.set_rtcsel(clock_config);
|
|
||||||
w.set_rtcen(true);
|
|
||||||
|
|
||||||
// Restore bcdr
|
|
||||||
w.set_lscosel(reg.lscosel());
|
|
||||||
w.set_lscoen(reg.lscoen());
|
|
||||||
|
|
||||||
w.set_lseon(reg.lseon());
|
|
||||||
w.set_lsedrv(reg.lsedrv());
|
|
||||||
w.set_lsebyp(reg.lsebyp());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) unsafe fn enable_peripheral_clk() {
|
|
||||||
// enable peripheral clock for communication
|
|
||||||
crate::pac::RCC.apb1enr1().modify(|w| w.set_rtcapben(true));
|
|
||||||
|
|
||||||
// read to allow the pwr clock to enable
|
|
||||||
crate::pac::PWR.cr1().read();
|
|
||||||
}
|
|
|
@ -26,6 +26,7 @@ nb = "1.0.0"
|
||||||
embedded-storage = "0.3.0"
|
embedded-storage = "0.3.0"
|
||||||
micromath = "2.0.0"
|
micromath = "2.0.0"
|
||||||
static_cell = "1.0"
|
static_cell = "1.0"
|
||||||
|
chrono = { version = "^0.4", default-features = false}
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
debug = 2
|
debug = 2
|
||||||
|
|
30
examples/stm32f4/src/bin/rtc.rs
Normal file
30
examples/stm32f4/src/bin/rtc.rs
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
|
use chrono::{NaiveDate, NaiveDateTime};
|
||||||
|
use defmt::*;
|
||||||
|
use embassy_executor::Spawner;
|
||||||
|
use embassy_stm32::rtc::{Rtc, RtcConfig};
|
||||||
|
use embassy_time::{Duration, Timer};
|
||||||
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
|
#[embassy_executor::main]
|
||||||
|
async fn main(_spawner: Spawner) {
|
||||||
|
let p = embassy_stm32::init(Default::default());
|
||||||
|
info!("Hello World!");
|
||||||
|
|
||||||
|
let now = NaiveDate::from_ymd_opt(2020, 5, 15)
|
||||||
|
.unwrap()
|
||||||
|
.and_hms_opt(10, 30, 15)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut rtc = Rtc::new(p.RTC, RtcConfig::default());
|
||||||
|
|
||||||
|
rtc.set_datetime(now.into()).expect("datetime not set");
|
||||||
|
|
||||||
|
// In reality the delay would be much longer
|
||||||
|
Timer::after(Duration::from_millis(20000)).await;
|
||||||
|
|
||||||
|
let _then: NaiveDateTime = rtc.now().unwrap().into();
|
||||||
|
}
|
Loading…
Reference in a new issue