RP: Add save/restore to Rtc. Example use.
This commit is contained in:
parent
a93714327e
commit
466a391b52
2 changed files with 64 additions and 21 deletions
|
@ -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()
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue