diff --git a/embassy-rp/src/clocks.rs b/embassy-rp/src/clocks.rs
index ddd61d224..acb21dce5 100644
--- a/embassy-rp/src/clocks.rs
+++ b/embassy-rp/src/clocks.rs
@@ -308,6 +308,7 @@ pub(crate) unsafe fn init(config: ClockConfig) {
     // - QSPI (we're using it to run this code!)
     // - PLLs (it may be suicide if that's what's clocking us)
     // - USB, SYSCFG (breaks usb-to-swd on core1)
+    // - RTC (else there would be no more time...)
     let mut peris = reset::ALL_PERIPHERALS;
     peris.set_io_qspi(false);
     // peris.set_io_bank0(false); // might be suicide if we're clocked from gpin
@@ -317,6 +318,7 @@ pub(crate) unsafe fn init(config: ClockConfig) {
     // TODO investigate if usb should be unreset here
     peris.set_usbctrl(false);
     peris.set_syscfg(false);
+    peris.set_rtc(false);
     reset::reset(peris);
 
     // Disable resus that may be enabled from previous software
diff --git a/embassy-rp/src/rtc/datetime_no_deps.rs b/embassy-rp/src/rtc/datetime_no_deps.rs
index 92770e984..ea899c339 100644
--- a/embassy-rp/src/rtc/datetime_no_deps.rs
+++ b/embassy-rp/src/rtc/datetime_no_deps.rs
@@ -25,6 +25,7 @@ pub enum Error {
 }
 
 /// Structure containing date and time information
+#[derive(Clone, Debug)]
 pub struct DateTime {
     /// 0..4095
     pub year: u16,
diff --git a/embassy-rp/src/rtc/mod.rs b/embassy-rp/src/rtc/mod.rs
index b18f12fc4..1b33fdf8d 100644
--- a/embassy-rp/src/rtc/mod.rs
+++ b/embassy-rp/src/rtc/mod.rs
@@ -12,26 +12,24 @@ pub use self::datetime::{DateTime, DayOfWeek, Error as DateTimeError};
 use crate::clocks::clk_rtc_freq;
 
 /// A reference to the real time clock of the system
-pub struct RealTimeClock<'d, T: Instance> {
+pub struct Rtc<'d, T: Instance> {
     inner: PeripheralRef<'d, T>,
 }
 
-impl<'d, T: Instance> RealTimeClock<'d, T> {
+impl<'d, T: Instance> Rtc<'d, T> {
     /// Create a new instance of the real time clock, with the given date as an initial value.
     ///
     /// # Errors
     ///
     /// Will return `RtcError::InvalidDateTime` if the datetime is not a valid range.
-    pub fn new(inner: impl Peripheral<P = T> + 'd, initial_date: DateTime) -> Result<Self, RtcError> {
+    pub fn new(inner: impl Peripheral<P = T> + 'd) -> Self {
         into_ref!(inner);
 
         // Set the RTC divider
         inner.regs().clkdiv_m1().write(|w| w.set_clkdiv_m1(clk_rtc_freq() - 1));
 
-        let mut result = Self { inner };
-        result.set_leap_year_check(true); // should be on by default, make sure this is the case.
-        result.set_datetime(initial_date)?;
-        Ok(result)
+        let result = Self { inner };
+        result
     }
 
     /// Enable or disable the leap year check. The rp2040 chip will always add a Feb 29th on every year that is divisable by 4, but this may be incorrect (e.g. on century years). This function allows you to disable this check.
@@ -43,7 +41,37 @@ impl<'d, T: Instance> RealTimeClock<'d, T> {
         });
     }
 
-    /// Checks to see if this RealTimeClock is running
+    /// 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
     pub fn is_running(&self) -> bool {
         self.inner.regs().ctrl().read().rtc_active()
     }
@@ -113,8 +141,8 @@ impl<'d, T: Instance> RealTimeClock<'d, T> {
     /// # fn main() { }
     /// # #[cfg(not(feature = "chrono"))]
     /// # fn main() {
-    /// # use embassy_rp::rtc::{RealTimeClock, DateTimeFilter};
-    /// # let mut real_time_clock: RealTimeClock<embassy_rp::peripherals::RTC> = unsafe { core::mem::zeroed() };
+    /// # use embassy_rp::rtc::{Rtc, DateTimeFilter};
+    /// # let mut real_time_clock: Rtc<embassy_rp::peripherals::RTC> = unsafe { core::mem::zeroed() };
     /// let now = real_time_clock.now().unwrap();
     /// real_time_clock.schedule_alarm(
     ///     DateTimeFilter::default()
@@ -150,7 +178,7 @@ impl<'d, T: Instance> RealTimeClock<'d, T> {
     }
 }
 
-/// Errors that can occur on methods on [RealTimeClock]
+/// Errors that can occur on methods on [Rtc]
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub enum RtcError {
     /// An invalid DateTime was given or stored on the hardware.
diff --git a/embassy-rp/src/watchdog.rs b/embassy-rp/src/watchdog.rs
index d37795cc9..f1e986ec7 100644
--- a/embassy-rp/src/watchdog.rs
+++ b/embassy-rp/src/watchdog.rs
@@ -107,4 +107,36 @@ impl Watchdog {
             w.set_trigger(true);
         })
     }
+
+    /// Store data in scratch register
+    pub fn set_scratch(&mut self, index: usize, value: u32) {
+        let watchdog = pac::WATCHDOG;
+        match index {
+            0 => watchdog.scratch0().write(|w| *w = value),
+            1 => watchdog.scratch1().write(|w| *w = value),
+            2 => watchdog.scratch2().write(|w| *w = value),
+            3 => watchdog.scratch3().write(|w| *w = value),
+            4 => watchdog.scratch4().write(|w| *w = value),
+            5 => watchdog.scratch5().write(|w| *w = value),
+            6 => watchdog.scratch6().write(|w| *w = value),
+            7 => watchdog.scratch7().write(|w| *w = value),
+            _ => panic!("Invalid watchdog scratch index"),
+        }
+    }
+
+    /// Read data from scratch register
+    pub fn get_scratch(&mut self, index: usize) -> u32 {
+        let watchdog = pac::WATCHDOG;
+        match index {
+            0 => watchdog.scratch0().read(),
+            1 => watchdog.scratch1().read(),
+            2 => watchdog.scratch2().read(),
+            3 => watchdog.scratch3().read(),
+            4 => watchdog.scratch4().read(),
+            5 => watchdog.scratch5().read(),
+            6 => watchdog.scratch6().read(),
+            7 => watchdog.scratch7().read(),
+            _ => panic!("Invalid watchdog scratch index"),
+        }
+    }
 }
diff --git a/examples/rp/src/bin/rtc.rs b/examples/rp/src/bin/rtc.rs
new file mode 100644
index 000000000..d569f598f
--- /dev/null
+++ b/examples/rp/src/bin/rtc.rs
@@ -0,0 +1,44 @@
+#![no_std]
+#![no_main]
+#![feature(type_alias_impl_trait)]
+
+use defmt::*;
+use embassy_executor::Spawner;
+use embassy_rp::rtc::{DateTime, DayOfWeek, Rtc};
+use embassy_time::{Duration, Timer};
+use {defmt_rtt as _, panic_probe as _};
+
+#[embassy_executor::main]
+async fn main(_spawner: Spawner) {
+    let p = embassy_rp::init(Default::default());
+    info!("Wait for 20s");
+
+    let mut rtc = Rtc::new(p.RTC);
+
+    if !rtc.is_running() {
+        info!("Start RTC");
+        let now = DateTime {
+            year: 2000,
+            month: 1,
+            day: 1,
+            day_of_week: DayOfWeek::Saturday,
+            hour: 0,
+            minute: 0,
+            second: 0,
+        };
+        rtc.set_datetime(now).unwrap();
+    }
+
+    Timer::after(Duration::from_millis(20000)).await;
+
+    if let Ok(dt) = rtc.now() {
+        info!(
+            "Now: {}-{:02}-{:02} {}:{:02}:{:02}",
+            dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second,
+        );
+    }
+
+    info!("Reboot.");
+    Timer::after(Duration::from_millis(200)).await;
+    cortex_m::peripheral::SCB::sys_reset();
+}