aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornerwalt <[email protected]>2025-08-08 10:23:22 -0600
committernerwalt <[email protected]>2025-08-08 10:23:22 -0600
commitadc0fc0a974476e0424077c2cf6c652e6c42ea86 (patch)
treec03c4377d929028bb7c77e4d160bfab61cb145b2
parentf2be66a5f94a655696407e2e7bc81c322aab3ea1 (diff)
Adds WDT support for the nrf54l15
-rw-r--r--embassy-nrf/Cargo.toml2
-rw-r--r--embassy-nrf/src/chips/nrf54l15_app.rs9
-rw-r--r--embassy-nrf/src/lib.rs1
-rw-r--r--embassy-nrf/src/wdt.rs8
-rw-r--r--examples/nrf54l15/src/bin/wdt.rs41
5 files changed, 55 insertions, 6 deletions
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"]
88## nRF5340 network core 88## nRF5340 network core
89nrf5340-net = ["_nrf5340-net"] 89nrf5340-net = ["_nrf5340-net"]
90## nRF54L15 application core in Secure mode 90## nRF54L15 application core in Secure mode
91nrf54l15-app-s = ["_nrf54l15-app", "_s"] 91nrf54l15-app-s = ["_nrf54l15-app", "_s", "_multi_wdt"]
92## nRF54L15 application core in Non-Secure mode 92## nRF54L15 application core in Non-Secure mode
93nrf54l15-app-ns = ["_nrf54l15-app", "_ns"] 93nrf54l15-app-ns = ["_nrf54l15-app", "_ns"]
94 94
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;
204//pub const FLASH_SIZE: usize = 1024 * 1024; 204//pub const FLASH_SIZE: usize = 1024 * 1024;
205 205
206embassy_hal_internal::peripherals! { 206embassy_hal_internal::peripherals! {
207 // WDT
208 WDT0,
209 #[cfg(feature = "_s")]
210 WDT1,
211
207 // GPIO port 0 212 // GPIO port 0
208 P0_00, 213 P0_00,
209 P0_01, 214 P0_01,
@@ -285,6 +290,10 @@ impl_pin!(P2_08, 2, 8);
285impl_pin!(P2_09, 2, 9); 290impl_pin!(P2_09, 2, 9);
286impl_pin!(P2_10, 2, 10); 291impl_pin!(P2_10, 2, 10);
287 292
293impl_wdt!(WDT0, WDT31, WDT31, 0);
294#[cfg(feature = "_s")]
295impl_wdt!(WDT1, WDT30, WDT30, 1);
296
288embassy_hal_internal::interrupt_mod!( 297embassy_hal_internal::interrupt_mod!(
289 SWI00, 298 SWI00,
290 SWI01, 299 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;
170 feature = "nrf52840" 170 feature = "nrf52840"
171))] 171))]
172pub mod usb; 172pub mod usb;
173#[cfg(not(feature = "_nrf54l"))] // TODO
174pub mod wdt; 173pub mod wdt;
175 174
176// This mod MUST go last, so that it sees all the `impl_foo!` macros 175// 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 {
37 pub fn try_new<T: Instance>(_wdt: &Peri<'_, T>) -> Option<Self> { 37 pub fn try_new<T: Instance>(_wdt: &Peri<'_, T>) -> Option<Self> {
38 let r = T::REGS; 38 let r = T::REGS;
39 39
40 #[cfg(not(any(feature = "_nrf91", feature = "_nrf5340")))] 40 #[cfg(not(any(feature = "_nrf91", feature = "_nrf5340", feature = "_nrf54l")))]
41 let runstatus = r.runstatus().read().runstatus(); 41 let runstatus = r.runstatus().read().runstatus();
42 #[cfg(any(feature = "_nrf91", feature = "_nrf5340"))] 42 #[cfg(any(feature = "_nrf91", feature = "_nrf5340", feature = "_nrf54l"))]
43 let runstatus = r.runstatus().read().runstatuswdt(); 43 let runstatus = r.runstatus().read().runstatuswdt();
44 44
45 if runstatus { 45 if runstatus {
@@ -90,9 +90,9 @@ impl<T: Instance> Watchdog<T> {
90 let crv = config.timeout_ticks.max(MIN_TICKS); 90 let crv = config.timeout_ticks.max(MIN_TICKS);
91 let rren = crate::pac::wdt::regs::Rren((1u32 << N) - 1); 91 let rren = crate::pac::wdt::regs::Rren((1u32 << N) - 1);
92 92
93 #[cfg(not(any(feature = "_nrf91", feature = "_nrf5340")))] 93 #[cfg(not(any(feature = "_nrf91", feature = "_nrf5340", feature = "_nrf54l")))]
94 let runstatus = r.runstatus().read().runstatus(); 94 let runstatus = r.runstatus().read().runstatus();
95 #[cfg(any(feature = "_nrf91", feature = "_nrf5340"))] 95 #[cfg(any(feature = "_nrf91", feature = "_nrf5340", feature = "_nrf54l"))]
96 let runstatus = r.runstatus().read().runstatuswdt(); 96 let runstatus = r.runstatus().read().runstatuswdt();
97 97
98 if runstatus { 98 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 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_nrf::wdt::{Config, HaltConfig, Watchdog};
7use embassy_time::Timer;
8use {defmt_rtt as _, panic_probe as _};
9
10#[embassy_executor::main]
11async fn main(_spawner: Spawner) {
12 let p = embassy_nrf::init(Default::default());
13 info!("Hello WDT");
14
15 const TIMEOUT_S: u32 = 5;
16
17 let mut config = Config::default();
18 config.timeout_ticks = 32768 * TIMEOUT_S;
19
20 // This is needed for `probe-rs run` to be able to catch the panic message
21 // in the WDT interrupt. The core resets 2 ticks after firing the interrupt.
22 config.action_during_debug_halt = HaltConfig::PAUSE;
23
24 // The nrf54l15 has two watchdogs. Only WDT0 is available in non-secure (ns) mode, as WDT1 is
25 // reserved for the secure (s) environment. In secure mode, both WDT0 and WDT1 are available.
26 info!("Watchdog launched with {} s timeout", TIMEOUT_S);
27 let (_wdt, [mut handle]) = match Watchdog::try_new(p.WDT1, config) {
28 Ok(x) => x,
29 Err(_) => {
30 info!("Watchdog already active with wrong config, waiting for it to timeout...");
31 loop {}
32 }
33 };
34
35 for wait in 1..=TIMEOUT_S {
36 info!("Waiting {} seconds ...", wait);
37 Timer::after_secs(wait as u64).await;
38 handle.pet();
39 info!("Pet watchdog");
40 }
41}