From 4ec2b6260428cdb27875f801227680e2142dfd5f Mon Sep 17 00:00:00 2001 From: Gustavo Henrique Nihei Date: Mon, 8 Aug 2022 11:47:11 -0300 Subject: [PATCH] rtc: Add RWDT examples for ESP32, ESP32-S2 and ESP32-S3 Signed-off-by: Gustavo Henrique Nihei --- esp32-hal/examples/rtc_watchdog.rs | 66 +++++++++++++++++++++++++++ esp32s2-hal/examples/rtc_watchdog.rs | 66 +++++++++++++++++++++++++++ esp32s3-hal/examples/rtc_watchdog.rs | 67 ++++++++++++++++++++++++++++ 3 files changed, 199 insertions(+) create mode 100644 esp32-hal/examples/rtc_watchdog.rs create mode 100644 esp32s2-hal/examples/rtc_watchdog.rs create mode 100644 esp32s3-hal/examples/rtc_watchdog.rs diff --git a/esp32-hal/examples/rtc_watchdog.rs b/esp32-hal/examples/rtc_watchdog.rs new file mode 100644 index 00000000000..9aa3f9df461 --- /dev/null +++ b/esp32-hal/examples/rtc_watchdog.rs @@ -0,0 +1,66 @@ +//! This demos the RTC Watchdog Timer (RWDT). +//! The RWDT is initially configured to trigger an interrupt after a given +//! timeout. Then, upon expiration, the RWDT is restarted and then reconfigured +//! to reset both the main system and the RTC. + +#![no_std] +#![no_main] + +use core::cell::RefCell; + +use esp32_hal::{ + clock::ClockControl, + interrupt, + pac::{self, Peripherals}, + prelude::*, + Rtc, +}; +use esp_hal_common::Rwdt; +use panic_halt as _; +use xtensa_lx::mutex::{CriticalSectionMutex, Mutex}; +use xtensa_lx_rt::entry; + +static mut RWDT: CriticalSectionMutex>> = + CriticalSectionMutex::new(RefCell::new(None)); + +#[entry] +fn main() -> ! { + let peripherals = Peripherals::take().unwrap(); + let system = peripherals.DPORT.split(); + let _clocks = ClockControl::boot_defaults(system.clock_control).freeze(); + + let mut rtc = Rtc::new(peripherals.RTC_CNTL); + + // Disable watchdog timer + rtc.rwdt.disable(); + + rtc.rwdt.start(2000u64.millis()); + rtc.rwdt.listen(); + + interrupt::enable(pac::Interrupt::RTC_CORE, interrupt::Priority::Priority1).unwrap(); + + unsafe { + (&RWDT).lock(|data| (*data).replace(Some(rtc.rwdt))); + } + + loop {} +} + +#[interrupt] +fn RTC_CORE() { + unsafe { + (&RWDT).lock(|data| { + esp_println::println!("RWDT Interrupt"); + + let mut rwdt = data.borrow_mut(); + let rwdt = rwdt.as_mut().unwrap(); + + rwdt.clear_interrupt(); + + esp_println::println!("Restarting in 5 seconds..."); + + rwdt.start(5000u64.millis()); + rwdt.unlisten(); + }); + } +} diff --git a/esp32s2-hal/examples/rtc_watchdog.rs b/esp32s2-hal/examples/rtc_watchdog.rs new file mode 100644 index 00000000000..205f16a6fef --- /dev/null +++ b/esp32s2-hal/examples/rtc_watchdog.rs @@ -0,0 +1,66 @@ +//! This demos the RTC Watchdog Timer (RWDT). +//! The RWDT is initially configured to trigger an interrupt after a given +//! timeout. Then, upon expiration, the RWDT is restarted and then reconfigured +//! to reset both the main system and the RTC. + +#![no_std] +#![no_main] + +use core::cell::RefCell; + +use esp32s2_hal::{ + clock::ClockControl, + interrupt, + pac::{self, Peripherals}, + prelude::*, + Rtc, +}; +use esp_hal_common::Rwdt; +use panic_halt as _; +use xtensa_lx::mutex::{CriticalSectionMutex, Mutex}; +use xtensa_lx_rt::entry; + +static mut RWDT: CriticalSectionMutex>> = + CriticalSectionMutex::new(RefCell::new(None)); + +#[entry] +fn main() -> ! { + let peripherals = Peripherals::take().unwrap(); + let system = peripherals.SYSTEM.split(); + let _clocks = ClockControl::boot_defaults(system.clock_control).freeze(); + + let mut rtc = Rtc::new(peripherals.RTC_CNTL); + + // Disable watchdog timer + rtc.rwdt.disable(); + + rtc.rwdt.start(2000u64.millis()); + rtc.rwdt.listen(); + + interrupt::enable(pac::Interrupt::RTC_CORE, interrupt::Priority::Priority1).unwrap(); + + unsafe { + (&RWDT).lock(|data| (*data).replace(Some(rtc.rwdt))); + } + + loop {} +} + +#[interrupt] +fn RTC_CORE() { + unsafe { + (&RWDT).lock(|data| { + esp_println::println!("RWDT Interrupt"); + + let mut rwdt = data.borrow_mut(); + let rwdt = rwdt.as_mut().unwrap(); + + rwdt.clear_interrupt(); + + esp_println::println!("Restarting in 5 seconds..."); + + rwdt.start(5000u64.millis()); + rwdt.unlisten(); + }); + } +} diff --git a/esp32s3-hal/examples/rtc_watchdog.rs b/esp32s3-hal/examples/rtc_watchdog.rs new file mode 100644 index 00000000000..35196e47544 --- /dev/null +++ b/esp32s3-hal/examples/rtc_watchdog.rs @@ -0,0 +1,67 @@ +//! This demos the RTC Watchdog Timer (RWDT). +//! The RWDT is initially configured to trigger an interrupt after a given +//! timeout. Then, upon expiration, the RWDT is restarted and then reconfigured +//! to reset both the main system and the RTC. + +#![no_std] +#![no_main] + +use core::cell::RefCell; + +use esp32s3_hal::{ + clock::ClockControl, + interrupt, + pac::{self, Peripherals}, + prelude::*, + Rtc, +}; +use esp_hal_common::Rwdt; +use panic_halt as _; +use xtensa_lx::mutex::{CriticalSectionMutex, Mutex}; +use xtensa_lx_rt::entry; + +static mut RWDT: CriticalSectionMutex>> = + CriticalSectionMutex::new(RefCell::new(None)); + +#[entry] +fn main() -> ! { + let peripherals = Peripherals::take().unwrap(); + let system = peripherals.SYSTEM.split(); + let _clocks = ClockControl::boot_defaults(system.clock_control).freeze(); + + let mut rtc = Rtc::new(peripherals.RTC_CNTL); + + // Disable watchdog timers + rtc.swd.disable(); + rtc.rwdt.disable(); + + rtc.rwdt.start(2000u64.millis()); + rtc.rwdt.listen(); + + interrupt::enable(pac::Interrupt::RTC_CORE, interrupt::Priority::Priority1).unwrap(); + + unsafe { + (&RWDT).lock(|data| (*data).replace(Some(rtc.rwdt))); + } + + loop {} +} + +#[interrupt] +fn RTC_CORE() { + unsafe { + (&RWDT).lock(|data| { + esp_println::println!("RWDT Interrupt"); + + let mut rwdt = data.borrow_mut(); + let rwdt = rwdt.as_mut().unwrap(); + + rwdt.clear_interrupt(); + + esp_println::println!("Restarting in 5 seconds..."); + + rwdt.start(5000u64.millis()); + rwdt.unlisten(); + }); + } +}