diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml index 95ec83824..92378db0b 100644 --- a/embassy-nrf/Cargo.toml +++ b/embassy-nrf/Cargo.toml @@ -88,7 +88,7 @@ nrf5340-app-ns = ["_nrf5340-app", "_ns"] ## nRF5340 network core nrf5340-net = ["_nrf5340-net"] ## nRF54L15 application core in Secure mode -nrf54l15-app-s = ["_nrf54l15-app", "_s"] +nrf54l15-app-s = ["_nrf54l15-app", "_s", "_multi_wdt"] ## nRF54L15 application core in Non-Secure mode nrf54l15-app-ns = ["_nrf54l15-app", "_ns"] diff --git a/embassy-nrf/src/chips/nrf54l15_app.rs b/embassy-nrf/src/chips/nrf54l15_app.rs index b133eb565..f8d1befd7 100644 --- a/embassy-nrf/src/chips/nrf54l15_app.rs +++ b/embassy-nrf/src/chips/nrf54l15_app.rs @@ -204,6 +204,11 @@ pub const EASY_DMA_SIZE: usize = (1 << 16) - 1; //pub const FLASH_SIZE: usize = 1024 * 1024; embassy_hal_internal::peripherals! { + // WDT + WDT0, + #[cfg(feature = "_s")] + WDT1, + // GPIO port 0 P0_00, P0_01, @@ -285,6 +290,10 @@ impl_pin!(P2_08, 2, 8); impl_pin!(P2_09, 2, 9); impl_pin!(P2_10, 2, 10); +impl_wdt!(WDT0, WDT31, WDT31, 0); +#[cfg(feature = "_s")] +impl_wdt!(WDT1, WDT30, WDT30, 1); + embassy_hal_internal::interrupt_mod!( SWI00, SWI01, diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index ba8206d13..3d1f2d4c0 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs @@ -170,7 +170,6 @@ pub mod uarte; feature = "nrf52840" ))] pub mod usb; -#[cfg(not(feature = "_nrf54l"))] // TODO pub mod wdt; // This mod MUST go last, so that it sees all the `impl_foo!` macros diff --git a/embassy-nrf/src/wdt.rs b/embassy-nrf/src/wdt.rs index 308071726..7ab9adc29 100644 --- a/embassy-nrf/src/wdt.rs +++ b/embassy-nrf/src/wdt.rs @@ -37,9 +37,9 @@ impl Config { pub fn try_new(_wdt: &Peri<'_, T>) -> Option { let r = T::REGS; - #[cfg(not(any(feature = "_nrf91", feature = "_nrf5340")))] + #[cfg(not(any(feature = "_nrf91", feature = "_nrf5340", feature = "_nrf54l")))] let runstatus = r.runstatus().read().runstatus(); - #[cfg(any(feature = "_nrf91", feature = "_nrf5340"))] + #[cfg(any(feature = "_nrf91", feature = "_nrf5340", feature = "_nrf54l"))] let runstatus = r.runstatus().read().runstatuswdt(); if runstatus { @@ -90,9 +90,9 @@ impl Watchdog { let crv = config.timeout_ticks.max(MIN_TICKS); let rren = crate::pac::wdt::regs::Rren((1u32 << N) - 1); - #[cfg(not(any(feature = "_nrf91", feature = "_nrf5340")))] + #[cfg(not(any(feature = "_nrf91", feature = "_nrf5340", feature = "_nrf54l")))] let runstatus = r.runstatus().read().runstatus(); - #[cfg(any(feature = "_nrf91", feature = "_nrf5340"))] + #[cfg(any(feature = "_nrf91", feature = "_nrf5340", feature = "_nrf54l"))] let runstatus = r.runstatus().read().runstatuswdt(); if runstatus { diff --git a/examples/nrf54l15/src/bin/wdt.rs b/examples/nrf54l15/src/bin/wdt.rs new file mode 100644 index 000000000..28856dad4 --- /dev/null +++ b/examples/nrf54l15/src/bin/wdt.rs @@ -0,0 +1,41 @@ +#![no_std] +#![no_main] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_nrf::wdt::{Config, HaltConfig, Watchdog}; +use embassy_time::Timer; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_nrf::init(Default::default()); + info!("Hello WDT"); + + const TIMEOUT_S: u32 = 5; + + let mut config = Config::default(); + config.timeout_ticks = 32768 * TIMEOUT_S; + + // This is needed for `probe-rs run` to be able to catch the panic message + // in the WDT interrupt. The core resets 2 ticks after firing the interrupt. + config.action_during_debug_halt = HaltConfig::PAUSE; + + // The nrf54l15 has two watchdogs. Only WDT0 is available in non-secure (ns) mode, as WDT1 is + // reserved for the secure (s) environment. In secure mode, both WDT0 and WDT1 are available. + info!("Watchdog launched with {} s timeout", TIMEOUT_S); + let (_wdt, [mut handle]) = match Watchdog::try_new(p.WDT1, config) { + Ok(x) => x, + Err(_) => { + info!("Watchdog already active with wrong config, waiting for it to timeout..."); + loop {} + } + }; + + for wait in 1..=TIMEOUT_S { + info!("Waiting {} seconds ...", wait); + Timer::after_secs(wait as u64).await; + handle.pet(); + info!("Pet watchdog"); + } +}