RP: Add save/restore to Rtc. Example use.

This commit is contained in:
Henrik Berg 2023-07-12 14:13:19 +02:00
parent a93714327e
commit 466a391b52
2 changed files with 64 additions and 21 deletions

View file

@ -41,6 +41,36 @@ impl<'d, T: Instance> Rtc<'d, T> {
}); });
} }
/// Set the time from internal format
pub fn restore(&mut self, ymd: rp_pac::rtc::regs::Rtc1, hms: rp_pac::rtc::regs::Rtc0) {
// disable RTC while we configure it
self.inner.regs().ctrl().modify(|w| w.set_rtc_enable(false));
while self.inner.regs().ctrl().read().rtc_active() {
core::hint::spin_loop();
}
self.inner.regs().setup_0().write(|w| {
*w = rp_pac::rtc::regs::Setup0(ymd.0);
});
self.inner.regs().setup_1().write(|w| {
*w = rp_pac::rtc::regs::Setup1(hms.0);
});
// Load the new datetime and re-enable RTC
self.inner.regs().ctrl().write(|w| w.set_load(true));
self.inner.regs().ctrl().write(|w| w.set_rtc_enable(true));
while !self.inner.regs().ctrl().read().rtc_active() {
core::hint::spin_loop();
}
}
/// Get the time in internal format
pub fn save(&mut self) -> (rp_pac::rtc::regs::Rtc1, rp_pac::rtc::regs::Rtc0) {
let rtc_0: rp_pac::rtc::regs::Rtc0 = self.inner.regs().rtc_0().read();
let rtc_1 = self.inner.regs().rtc_1().read();
(rtc_1, rtc_0)
}
/// Checks to see if this Rtc is running /// Checks to see if this Rtc is running
pub fn is_running(&self) -> bool { pub fn is_running(&self) -> bool {
self.inner.regs().ctrl().read().rtc_active() self.inner.regs().ctrl().read().rtc_active()

View file

@ -4,6 +4,7 @@
use defmt::*; use defmt::*;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_rp::pac::rtc::regs::{Rtc0, Rtc1};
use embassy_rp::rtc::{DateTime, DayOfWeek, Rtc}; use embassy_rp::rtc::{DateTime, DayOfWeek, Rtc};
use embassy_time::{Duration, Timer}; use embassy_time::{Duration, Timer};
use {defmt_rtt as _, panic_probe as _}; use {defmt_rtt as _, panic_probe as _};
@ -11,8 +12,16 @@ use {defmt_rtt as _, panic_probe as _};
#[embassy_executor::main] #[embassy_executor::main]
async fn main(_spawner: Spawner) { async fn main(_spawner: Spawner) {
let p = embassy_rp::init(Default::default()); let p = embassy_rp::init(Default::default());
info!("Hello World!"); info!("Wait for 20s");
let mut watchdog = embassy_rp::watchdog::Watchdog::new(p.WATCHDOG);
let mut rtc = Rtc::new(p.RTC);
let rtc0 = Rtc0(watchdog.get_scratch0());
let rtc1 = Rtc1(watchdog.get_scratch1());
if rtc1.year() >= 2020 {
rtc.restore(rtc1, rtc0);
} else {
let now = DateTime { let now = DateTime {
year: 2020, year: 2020,
month: 5, month: 5,
@ -22,18 +31,22 @@ async fn main(_spawner: Spawner) {
minute: 30, minute: 30,
second: 50, second: 50,
}; };
rtc.set_datetime(now).unwrap();
}
let mut rtc = Rtc::new(p.RTC);
if rtc.set_datetime(now).is_ok() {
// In reality the delay would be much longer
Timer::after(Duration::from_millis(20000)).await; Timer::after(Duration::from_millis(20000)).await;
if let Ok(dt) = rtc.now() { if let Ok(dt) = rtc.now() {
info!( info!(
"Now: {}-{}-{} {}:{}:{}", "Now: {}-{:02}-{:02} {}:{:02}:{:02}",
dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second,
); );
let (rtc1, rtc0) = rtc.save();
watchdog.set_scratch0(rtc0.0);
watchdog.set_scratch1(rtc1.0);
} }
}
info!("Done."); info!("Reboot.");
Timer::after(Duration::from_millis(200)).await;
cortex_m::peripheral::SCB::sys_reset();
} }