diff options
| author | Henrik Berg <[email protected]> | 2023-07-12 14:13:19 +0200 |
|---|---|---|
| committer | Henrik Berg <[email protected]> | 2023-07-12 14:22:48 +0200 |
| commit | 466a391b52836f79fafad5780ad2eb0a07d82513 (patch) | |
| tree | 43461b7bfcec9e4ae52a7769c13ca7c633fa745a | |
| parent | a93714327eb85b02c7c4a419f2a76df579258975 (diff) | |
RP: Add save/restore to Rtc. Example use.
| -rw-r--r-- | embassy-rp/src/rtc/mod.rs | 30 | ||||
| -rw-r--r-- | examples/rp/src/bin/rtc.rs | 55 |
2 files changed, 64 insertions, 21 deletions
diff --git a/embassy-rp/src/rtc/mod.rs b/embassy-rp/src/rtc/mod.rs index 90b796a9c..1b33fdf8d 100644 --- a/embassy-rp/src/rtc/mod.rs +++ b/embassy-rp/src/rtc/mod.rs | |||
| @@ -41,6 +41,36 @@ impl<'d, T: Instance> Rtc<'d, T> { | |||
| 41 | }); | 41 | }); |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | /// Set the time from internal format | ||
| 45 | pub fn restore(&mut self, ymd: rp_pac::rtc::regs::Rtc1, hms: rp_pac::rtc::regs::Rtc0) { | ||
| 46 | // disable RTC while we configure it | ||
| 47 | self.inner.regs().ctrl().modify(|w| w.set_rtc_enable(false)); | ||
| 48 | while self.inner.regs().ctrl().read().rtc_active() { | ||
| 49 | core::hint::spin_loop(); | ||
| 50 | } | ||
| 51 | |||
| 52 | self.inner.regs().setup_0().write(|w| { | ||
| 53 | *w = rp_pac::rtc::regs::Setup0(ymd.0); | ||
| 54 | }); | ||
| 55 | self.inner.regs().setup_1().write(|w| { | ||
| 56 | *w = rp_pac::rtc::regs::Setup1(hms.0); | ||
| 57 | }); | ||
| 58 | |||
| 59 | // Load the new datetime and re-enable RTC | ||
| 60 | self.inner.regs().ctrl().write(|w| w.set_load(true)); | ||
| 61 | self.inner.regs().ctrl().write(|w| w.set_rtc_enable(true)); | ||
| 62 | while !self.inner.regs().ctrl().read().rtc_active() { | ||
| 63 | core::hint::spin_loop(); | ||
| 64 | } | ||
| 65 | } | ||
| 66 | |||
| 67 | /// Get the time in internal format | ||
| 68 | pub fn save(&mut self) -> (rp_pac::rtc::regs::Rtc1, rp_pac::rtc::regs::Rtc0) { | ||
| 69 | let rtc_0: rp_pac::rtc::regs::Rtc0 = self.inner.regs().rtc_0().read(); | ||
| 70 | let rtc_1 = self.inner.regs().rtc_1().read(); | ||
| 71 | (rtc_1, rtc_0) | ||
| 72 | } | ||
| 73 | |||
| 44 | /// Checks to see if this Rtc is running | 74 | /// Checks to see if this Rtc is running |
| 45 | pub fn is_running(&self) -> bool { | 75 | pub fn is_running(&self) -> bool { |
| 46 | self.inner.regs().ctrl().read().rtc_active() | 76 | self.inner.regs().ctrl().read().rtc_active() |
diff --git a/examples/rp/src/bin/rtc.rs b/examples/rp/src/bin/rtc.rs index 6300950d4..2ddde3257 100644 --- a/examples/rp/src/bin/rtc.rs +++ b/examples/rp/src/bin/rtc.rs | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | use defmt::*; | 5 | use defmt::*; |
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_rp::pac::rtc::regs::{Rtc0, Rtc1}; | ||
| 7 | use embassy_rp::rtc::{DateTime, DayOfWeek, Rtc}; | 8 | use embassy_rp::rtc::{DateTime, DayOfWeek, Rtc}; |
| 8 | use embassy_time::{Duration, Timer}; | 9 | use embassy_time::{Duration, Timer}; |
| 9 | use {defmt_rtt as _, panic_probe as _}; | 10 | use {defmt_rtt as _, panic_probe as _}; |
| @@ -11,29 +12,41 @@ use {defmt_rtt as _, panic_probe as _}; | |||
| 11 | #[embassy_executor::main] | 12 | #[embassy_executor::main] |
| 12 | async fn main(_spawner: Spawner) { | 13 | async fn main(_spawner: Spawner) { |
| 13 | let p = embassy_rp::init(Default::default()); | 14 | let p = embassy_rp::init(Default::default()); |
| 14 | info!("Hello World!"); | 15 | info!("Wait for 20s"); |
| 15 | |||
| 16 | let now = DateTime { | ||
| 17 | year: 2020, | ||
| 18 | month: 5, | ||
| 19 | day: 15, | ||
| 20 | day_of_week: DayOfWeek::Monday, | ||
| 21 | hour: 10, | ||
| 22 | minute: 30, | ||
| 23 | second: 50, | ||
| 24 | }; | ||
| 25 | 16 | ||
| 17 | let mut watchdog = embassy_rp::watchdog::Watchdog::new(p.WATCHDOG); | ||
| 26 | let mut rtc = Rtc::new(p.RTC); | 18 | let mut rtc = Rtc::new(p.RTC); |
| 27 | if rtc.set_datetime(now).is_ok() { | ||
| 28 | // In reality the delay would be much longer | ||
| 29 | Timer::after(Duration::from_millis(20000)).await; | ||
| 30 | 19 | ||
| 31 | if let Ok(dt) = rtc.now() { | 20 | let rtc0 = Rtc0(watchdog.get_scratch0()); |
| 32 | info!( | 21 | let rtc1 = Rtc1(watchdog.get_scratch1()); |
| 33 | "Now: {}-{}-{} {}:{}:{}", | 22 | if rtc1.year() >= 2020 { |
| 34 | dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, | 23 | rtc.restore(rtc1, rtc0); |
| 35 | ); | 24 | } else { |
| 36 | } | 25 | let now = DateTime { |
| 26 | year: 2020, | ||
| 27 | month: 5, | ||
| 28 | day: 15, | ||
| 29 | day_of_week: DayOfWeek::Monday, | ||
| 30 | hour: 10, | ||
| 31 | minute: 30, | ||
| 32 | second: 50, | ||
| 33 | }; | ||
| 34 | rtc.set_datetime(now).unwrap(); | ||
| 37 | } | 35 | } |
| 38 | info!("Done."); | 36 | |
| 37 | Timer::after(Duration::from_millis(20000)).await; | ||
| 38 | |||
| 39 | if let Ok(dt) = rtc.now() { | ||
| 40 | info!( | ||
| 41 | "Now: {}-{:02}-{:02} {}:{:02}:{:02}", | ||
| 42 | dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, | ||
| 43 | ); | ||
| 44 | let (rtc1, rtc0) = rtc.save(); | ||
| 45 | watchdog.set_scratch0(rtc0.0); | ||
| 46 | watchdog.set_scratch1(rtc1.0); | ||
| 47 | } | ||
| 48 | |||
| 49 | info!("Reboot."); | ||
| 50 | Timer::after(Duration::from_millis(200)).await; | ||
| 51 | cortex_m::peripheral::SCB::sys_reset(); | ||
| 39 | } | 52 | } |
