aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf/src
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-nrf/src')
-rw-r--r--embassy-nrf/src/chips/nrf51.rs2
-rw-r--r--embassy-nrf/src/chips/nrf52805.rs2
-rw-r--r--embassy-nrf/src/chips/nrf52810.rs2
-rw-r--r--embassy-nrf/src/chips/nrf52811.rs2
-rw-r--r--embassy-nrf/src/chips/nrf52820.rs2
-rw-r--r--embassy-nrf/src/chips/nrf52832.rs2
-rw-r--r--embassy-nrf/src/chips/nrf52833.rs2
-rw-r--r--embassy-nrf/src/chips/nrf52840.rs2
-rw-r--r--embassy-nrf/src/chips/nrf5340_app.rs6
-rw-r--r--embassy-nrf/src/chips/nrf5340_net.rs2
-rw-r--r--embassy-nrf/src/chips/nrf9120.rs2
-rw-r--r--embassy-nrf/src/chips/nrf9160.rs2
-rw-r--r--embassy-nrf/src/lib.rs1
-rw-r--r--embassy-nrf/src/wdt.rs110
14 files changed, 100 insertions, 39 deletions
diff --git a/embassy-nrf/src/chips/nrf51.rs b/embassy-nrf/src/chips/nrf51.rs
index a0365a6ee..fd13ae5c4 100644
--- a/embassy-nrf/src/chips/nrf51.rs
+++ b/embassy-nrf/src/chips/nrf51.rs
@@ -145,6 +145,8 @@ impl_pin!(P0_31, 0, 31);
145 145
146impl_radio!(RADIO, RADIO, RADIO); 146impl_radio!(RADIO, RADIO, RADIO);
147 147
148impl_wdt!(WDT, WDT, WDT, 0);
149
148embassy_hal_internal::interrupt_mod!( 150embassy_hal_internal::interrupt_mod!(
149 CLOCK_POWER, 151 CLOCK_POWER,
150 RADIO, 152 RADIO,
diff --git a/embassy-nrf/src/chips/nrf52805.rs b/embassy-nrf/src/chips/nrf52805.rs
index a9cbccec4..7e72df8fc 100644
--- a/embassy-nrf/src/chips/nrf52805.rs
+++ b/embassy-nrf/src/chips/nrf52805.rs
@@ -221,6 +221,8 @@ impl_radio!(RADIO, RADIO, RADIO);
221impl_egu!(EGU0, EGU0, EGU0_SWI0); 221impl_egu!(EGU0, EGU0, EGU0_SWI0);
222impl_egu!(EGU1, EGU1, EGU1_SWI1); 222impl_egu!(EGU1, EGU1, EGU1_SWI1);
223 223
224impl_wdt!(WDT, WDT, WDT, 0);
225
224embassy_hal_internal::interrupt_mod!( 226embassy_hal_internal::interrupt_mod!(
225 CLOCK_POWER, 227 CLOCK_POWER,
226 RADIO, 228 RADIO,
diff --git a/embassy-nrf/src/chips/nrf52810.rs b/embassy-nrf/src/chips/nrf52810.rs
index ca31c35e1..e388e44e8 100644
--- a/embassy-nrf/src/chips/nrf52810.rs
+++ b/embassy-nrf/src/chips/nrf52810.rs
@@ -247,6 +247,8 @@ impl_radio!(RADIO, RADIO, RADIO);
247impl_egu!(EGU0, EGU0, EGU0_SWI0); 247impl_egu!(EGU0, EGU0, EGU0_SWI0);
248impl_egu!(EGU1, EGU1, EGU1_SWI1); 248impl_egu!(EGU1, EGU1, EGU1_SWI1);
249 249
250impl_wdt!(WDT, WDT, WDT, 0);
251
250embassy_hal_internal::interrupt_mod!( 252embassy_hal_internal::interrupt_mod!(
251 CLOCK_POWER, 253 CLOCK_POWER,
252 RADIO, 254 RADIO,
diff --git a/embassy-nrf/src/chips/nrf52811.rs b/embassy-nrf/src/chips/nrf52811.rs
index caf3fdcf8..96b8df30b 100644
--- a/embassy-nrf/src/chips/nrf52811.rs
+++ b/embassy-nrf/src/chips/nrf52811.rs
@@ -249,6 +249,8 @@ impl_radio!(RADIO, RADIO, RADIO);
249impl_egu!(EGU0, EGU0, EGU0_SWI0); 249impl_egu!(EGU0, EGU0, EGU0_SWI0);
250impl_egu!(EGU1, EGU1, EGU1_SWI1); 250impl_egu!(EGU1, EGU1, EGU1_SWI1);
251 251
252impl_wdt!(WDT, WDT, WDT, 0);
253
252embassy_hal_internal::interrupt_mod!( 254embassy_hal_internal::interrupt_mod!(
253 CLOCK_POWER, 255 CLOCK_POWER,
254 RADIO, 256 RADIO,
diff --git a/embassy-nrf/src/chips/nrf52820.rs b/embassy-nrf/src/chips/nrf52820.rs
index 39573e4a5..ad461b153 100644
--- a/embassy-nrf/src/chips/nrf52820.rs
+++ b/embassy-nrf/src/chips/nrf52820.rs
@@ -244,6 +244,8 @@ impl_egu!(EGU3, EGU3, EGU3_SWI3);
244impl_egu!(EGU4, EGU4, EGU4_SWI4); 244impl_egu!(EGU4, EGU4, EGU4_SWI4);
245impl_egu!(EGU5, EGU5, EGU5_SWI5); 245impl_egu!(EGU5, EGU5, EGU5_SWI5);
246 246
247impl_wdt!(WDT, WDT, WDT, 0);
248
247embassy_hal_internal::interrupt_mod!( 249embassy_hal_internal::interrupt_mod!(
248 CLOCK_POWER, 250 CLOCK_POWER,
249 RADIO, 251 RADIO,
diff --git a/embassy-nrf/src/chips/nrf52832.rs b/embassy-nrf/src/chips/nrf52832.rs
index 2d9346229..cf2abf23a 100644
--- a/embassy-nrf/src/chips/nrf52832.rs
+++ b/embassy-nrf/src/chips/nrf52832.rs
@@ -287,6 +287,8 @@ impl_egu!(EGU3, EGU3, EGU3_SWI3);
287impl_egu!(EGU4, EGU4, EGU4_SWI4); 287impl_egu!(EGU4, EGU4, EGU4_SWI4);
288impl_egu!(EGU5, EGU5, EGU5_SWI5); 288impl_egu!(EGU5, EGU5, EGU5_SWI5);
289 289
290impl_wdt!(WDT, WDT, WDT, 0);
291
290embassy_hal_internal::interrupt_mod!( 292embassy_hal_internal::interrupt_mod!(
291 CLOCK_POWER, 293 CLOCK_POWER,
292 RADIO, 294 RADIO,
diff --git a/embassy-nrf/src/chips/nrf52833.rs b/embassy-nrf/src/chips/nrf52833.rs
index 4e4915c32..e46eb1d2b 100644
--- a/embassy-nrf/src/chips/nrf52833.rs
+++ b/embassy-nrf/src/chips/nrf52833.rs
@@ -329,6 +329,8 @@ impl_egu!(EGU3, EGU3, EGU3_SWI3);
329impl_egu!(EGU4, EGU4, EGU4_SWI4); 329impl_egu!(EGU4, EGU4, EGU4_SWI4);
330impl_egu!(EGU5, EGU5, EGU5_SWI5); 330impl_egu!(EGU5, EGU5, EGU5_SWI5);
331 331
332impl_wdt!(WDT, WDT, WDT, 0);
333
332embassy_hal_internal::interrupt_mod!( 334embassy_hal_internal::interrupt_mod!(
333 CLOCK_POWER, 335 CLOCK_POWER,
334 RADIO, 336 RADIO,
diff --git a/embassy-nrf/src/chips/nrf52840.rs b/embassy-nrf/src/chips/nrf52840.rs
index 70a56971b..88747843d 100644
--- a/embassy-nrf/src/chips/nrf52840.rs
+++ b/embassy-nrf/src/chips/nrf52840.rs
@@ -334,6 +334,8 @@ impl_egu!(EGU3, EGU3, EGU3_SWI3);
334impl_egu!(EGU4, EGU4, EGU4_SWI4); 334impl_egu!(EGU4, EGU4, EGU4_SWI4);
335impl_egu!(EGU5, EGU5, EGU5_SWI5); 335impl_egu!(EGU5, EGU5, EGU5_SWI5);
336 336
337impl_wdt!(WDT, WDT, WDT, 0);
338
337embassy_hal_internal::interrupt_mod!( 339embassy_hal_internal::interrupt_mod!(
338 CLOCK_POWER, 340 CLOCK_POWER,
339 RADIO, 341 RADIO,
diff --git a/embassy-nrf/src/chips/nrf5340_app.rs b/embassy-nrf/src/chips/nrf5340_app.rs
index 86274bf48..0103fa7ae 100644
--- a/embassy-nrf/src/chips/nrf5340_app.rs
+++ b/embassy-nrf/src/chips/nrf5340_app.rs
@@ -171,7 +171,8 @@ embassy_hal_internal::peripherals! {
171 RTC1, 171 RTC1,
172 172
173 // WDT 173 // WDT
174 WDT, 174 WDT0,
175 WDT1,
175 176
176 // NVMC 177 // NVMC
177 NVMC, 178 NVMC,
@@ -473,6 +474,9 @@ impl_egu!(EGU3, EGU3, EGU3);
473impl_egu!(EGU4, EGU4, EGU4); 474impl_egu!(EGU4, EGU4, EGU4);
474impl_egu!(EGU5, EGU5, EGU5); 475impl_egu!(EGU5, EGU5, EGU5);
475 476
477impl_wdt!(WDT0, WDT0, WDT0, 0);
478impl_wdt!(WDT1, WDT1, WDT1, 1);
479
476embassy_hal_internal::interrupt_mod!( 480embassy_hal_internal::interrupt_mod!(
477 FPU, 481 FPU,
478 CACHE, 482 CACHE,
diff --git a/embassy-nrf/src/chips/nrf5340_net.rs b/embassy-nrf/src/chips/nrf5340_net.rs
index 6c6ac3fbb..22d33d080 100644
--- a/embassy-nrf/src/chips/nrf5340_net.rs
+++ b/embassy-nrf/src/chips/nrf5340_net.rs
@@ -299,6 +299,8 @@ impl_radio!(RADIO, RADIO, RADIO);
299 299
300impl_egu!(EGU0, EGU0, EGU0); 300impl_egu!(EGU0, EGU0, EGU0);
301 301
302impl_wdt!(WDT, WDT, WDT, 0);
303
302embassy_hal_internal::interrupt_mod!( 304embassy_hal_internal::interrupt_mod!(
303 CLOCK_POWER, 305 CLOCK_POWER,
304 RADIO, 306 RADIO,
diff --git a/embassy-nrf/src/chips/nrf9120.rs b/embassy-nrf/src/chips/nrf9120.rs
index b02b8c6d8..e8ddbf86f 100644
--- a/embassy-nrf/src/chips/nrf9120.rs
+++ b/embassy-nrf/src/chips/nrf9120.rs
@@ -342,6 +342,8 @@ impl_egu!(EGU3, EGU3, EGU3);
342impl_egu!(EGU4, EGU4, EGU4); 342impl_egu!(EGU4, EGU4, EGU4);
343impl_egu!(EGU5, EGU5, EGU5); 343impl_egu!(EGU5, EGU5, EGU5);
344 344
345impl_wdt!(WDT, WDT, WDT, 0);
346
345embassy_hal_internal::interrupt_mod!( 347embassy_hal_internal::interrupt_mod!(
346 SPU, 348 SPU,
347 CLOCK_POWER, 349 CLOCK_POWER,
diff --git a/embassy-nrf/src/chips/nrf9160.rs b/embassy-nrf/src/chips/nrf9160.rs
index b0981e3b5..5d04a72e5 100644
--- a/embassy-nrf/src/chips/nrf9160.rs
+++ b/embassy-nrf/src/chips/nrf9160.rs
@@ -342,6 +342,8 @@ impl_egu!(EGU3, EGU3, EGU3);
342impl_egu!(EGU4, EGU4, EGU4); 342impl_egu!(EGU4, EGU4, EGU4);
343impl_egu!(EGU5, EGU5, EGU5); 343impl_egu!(EGU5, EGU5, EGU5);
344 344
345impl_wdt!(WDT, WDT, WDT, 0);
346
345embassy_hal_internal::interrupt_mod!( 347embassy_hal_internal::interrupt_mod!(
346 SPU, 348 SPU,
347 CLOCK_POWER, 349 CLOCK_POWER,
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs
index d2ff054f4..07ba2f6d4 100644
--- a/embassy-nrf/src/lib.rs
+++ b/embassy-nrf/src/lib.rs
@@ -169,7 +169,6 @@ pub mod uarte;
169))] 169))]
170pub mod usb; 170pub mod usb;
171#[cfg(not(feature = "_nrf54l"))] // TODO 171#[cfg(not(feature = "_nrf54l"))] // TODO
172#[cfg(not(feature = "_nrf5340"))]
173pub mod wdt; 172pub mod wdt;
174 173
175// This mod MUST go last, so that it sees all the `impl_foo!` macros 174// 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 11cfa398e..baaf1c801 100644
--- a/embassy-nrf/src/wdt.rs
+++ b/embassy-nrf/src/wdt.rs
@@ -3,11 +3,15 @@
3//! This HAL implements a basic watchdog timer with 1..=8 handles. 3//! This HAL implements a basic watchdog timer with 1..=8 handles.
4//! Once the watchdog has been started, it cannot be stopped. 4//! Once the watchdog has been started, it cannot be stopped.
5 5
6use core::marker::PhantomData; 6#![macro_use]
7
8use core::hint::unreachable_unchecked;
9
10use embassy_hal_internal::PeripheralType;
7 11
8use crate::pac::wdt::vals; 12use crate::pac::wdt::vals;
9pub use crate::pac::wdt::vals::{Halt as HaltConfig, Sleep as SleepConfig}; 13pub use crate::pac::wdt::vals::{Halt as HaltConfig, Sleep as SleepConfig};
10use crate::{peripherals, Peri}; 14use crate::{interrupt, pac, peripherals, Peri};
11 15
12const MIN_TICKS: u32 = 15; 16const MIN_TICKS: u32 = 15;
13 17
@@ -30,12 +34,12 @@ pub struct Config {
30impl Config { 34impl Config {
31 /// Create a config structure from the current configuration of the WDT 35 /// Create a config structure from the current configuration of the WDT
32 /// peripheral. 36 /// peripheral.
33 pub fn try_new(_wdt: &peripherals::WDT) -> Option<Self> { 37 pub fn try_new<T: Instance>(_wdt: &Peri<'_, T>) -> Option<Self> {
34 let r = crate::pac::WDT; 38 let r = T::REGS;
35 39
36 #[cfg(not(feature = "_nrf91"))] 40 #[cfg(not(any(feature = "_nrf91", feature = "_nrf5340")))]
37 let runstatus = r.runstatus().read().runstatus(); 41 let runstatus = r.runstatus().read().runstatus();
38 #[cfg(feature = "_nrf91")] 42 #[cfg(any(feature = "_nrf91", feature = "_nrf5340"))]
39 let runstatus = r.runstatus().read().runstatuswdt(); 43 let runstatus = r.runstatus().read().runstatuswdt();
40 44
41 if runstatus { 45 if runstatus {
@@ -62,11 +66,11 @@ impl Default for Config {
62} 66}
63 67
64/// Watchdog driver. 68/// Watchdog driver.
65pub struct Watchdog { 69pub struct Watchdog<T: Instance> {
66 _wdt: Peri<'static, peripherals::WDT>, 70 _wdt: Peri<'static, T>,
67} 71}
68 72
69impl Watchdog { 73impl<T: Instance> Watchdog<T> {
70 /// Try to create a new watchdog driver. 74 /// Try to create a new watchdog driver.
71 /// 75 ///
72 /// This function will return an error if the watchdog is already active 76 /// This function will return an error if the watchdog is already active
@@ -76,19 +80,19 @@ impl Watchdog {
76 /// `N` must be between 1 and 8, inclusive. 80 /// `N` must be between 1 and 8, inclusive.
77 #[inline] 81 #[inline]
78 pub fn try_new<const N: usize>( 82 pub fn try_new<const N: usize>(
79 wdt: Peri<'static, peripherals::WDT>, 83 wdt: Peri<'static, T>,
80 config: Config, 84 config: Config,
81 ) -> Result<(Self, [WatchdogHandle; N]), Peri<'static, peripherals::WDT>> { 85 ) -> Result<(Self, [WatchdogHandle; N]), Peri<'static, T>> {
82 assert!(N >= 1 && N <= 8); 86 assert!(N >= 1 && N <= 8);
83 87
84 let r = crate::pac::WDT; 88 let r = T::REGS;
85 89
86 let crv = config.timeout_ticks.max(MIN_TICKS); 90 let crv = config.timeout_ticks.max(MIN_TICKS);
87 let rren = crate::pac::wdt::regs::Rren((1u32 << N) - 1); 91 let rren = crate::pac::wdt::regs::Rren((1u32 << N) - 1);
88 92
89 #[cfg(not(feature = "_nrf91"))] 93 #[cfg(not(any(feature = "_nrf91", feature = "_nrf5340")))]
90 let runstatus = r.runstatus().read().runstatus(); 94 let runstatus = r.runstatus().read().runstatus();
91 #[cfg(feature = "_nrf91")] 95 #[cfg(any(feature = "_nrf91", feature = "_nrf5340"))]
92 let runstatus = r.runstatus().read().runstatuswdt(); 96 let runstatus = r.runstatus().read().runstatuswdt();
93 97
94 if runstatus { 98 if runstatus {
@@ -114,17 +118,9 @@ impl Watchdog {
114 118
115 let this = Self { _wdt: wdt }; 119 let this = Self { _wdt: wdt };
116 120
117 let mut handles = [const { 121 let mut handles = [const { WatchdogHandle { index: 0 } }; N];
118 WatchdogHandle {
119 _wdt: PhantomData,
120 index: 0,
121 }
122 }; N];
123 for i in 0..N { 122 for i in 0..N {
124 handles[i] = WatchdogHandle { 123 handles[i] = unsafe { WatchdogHandle::steal(T::INDEX, i as u8) };
125 _wdt: PhantomData,
126 index: i as u8,
127 };
128 handles[i].pet(); 124 handles[i].pet();
129 } 125 }
130 126
@@ -139,7 +135,7 @@ impl Watchdog {
139 /// interrupt has been enabled. 135 /// interrupt has been enabled.
140 #[inline(always)] 136 #[inline(always)]
141 pub fn enable_interrupt(&mut self) { 137 pub fn enable_interrupt(&mut self) {
142 crate::pac::WDT.intenset().write(|w| w.set_timeout(true)); 138 T::REGS.intenset().write(|w| w.set_timeout(true));
143 } 139 }
144 140
145 /// Disable the watchdog interrupt. 141 /// Disable the watchdog interrupt.
@@ -147,7 +143,7 @@ impl Watchdog {
147 /// NOTE: This has no effect on the reset caused by the Watchdog. 143 /// NOTE: This has no effect on the reset caused by the Watchdog.
148 #[inline(always)] 144 #[inline(always)]
149 pub fn disable_interrupt(&mut self) { 145 pub fn disable_interrupt(&mut self) {
150 crate::pac::WDT.intenclr().write(|w| w.set_timeout(true)); 146 T::REGS.intenclr().write(|w| w.set_timeout(true));
151 } 147 }
152 148
153 /// Is the watchdog still awaiting pets from any handle? 149 /// Is the watchdog still awaiting pets from any handle?
@@ -156,7 +152,7 @@ impl Watchdog {
156 /// handles to prevent a reset this time period. 152 /// handles to prevent a reset this time period.
157 #[inline(always)] 153 #[inline(always)]
158 pub fn awaiting_pets(&self) -> bool { 154 pub fn awaiting_pets(&self) -> bool {
159 let r = crate::pac::WDT; 155 let r = T::REGS;
160 let enabled = r.rren().read().0; 156 let enabled = r.rren().read().0;
161 let status = r.reqstatus().read().0; 157 let status = r.reqstatus().read().0;
162 (status & enabled) == 0 158 (status & enabled) == 0
@@ -165,11 +161,26 @@ impl Watchdog {
165 161
166/// Watchdog handle. 162/// Watchdog handle.
167pub struct WatchdogHandle { 163pub struct WatchdogHandle {
168 _wdt: PhantomData<Peri<'static, peripherals::WDT>>,
169 index: u8, 164 index: u8,
170} 165}
171 166
172impl WatchdogHandle { 167impl WatchdogHandle {
168 fn regs(&self) -> pac::wdt::Wdt {
169 match self.index / 8 {
170 #[cfg(not(feature = "_multi_wdt"))]
171 peripherals::WDT::INDEX => peripherals::WDT::REGS,
172 #[cfg(feature = "_multi_wdt")]
173 peripherals::WDT0::INDEX => peripherals::WDT0::REGS,
174 #[cfg(feature = "_multi_wdt")]
175 peripherals::WDT1::INDEX => peripherals::WDT1::REGS,
176 _ => unsafe { unreachable_unchecked() },
177 }
178 }
179
180 fn rr_index(&self) -> usize {
181 usize::from(self.index % 8)
182 }
183
173 /// Pet the watchdog. 184 /// Pet the watchdog.
174 /// 185 ///
175 /// This function pets the given watchdog handle. 186 /// This function pets the given watchdog handle.
@@ -178,25 +189,50 @@ impl WatchdogHandle {
178 /// prevent a reset from occurring. 189 /// prevent a reset from occurring.
179 #[inline] 190 #[inline]
180 pub fn pet(&mut self) { 191 pub fn pet(&mut self) {
181 let r = crate::pac::WDT; 192 let r = self.regs();
182 r.rr(self.index as usize).write(|w| w.set_rr(vals::Rr::RELOAD)); 193 r.rr(self.rr_index()).write(|w| w.set_rr(vals::Rr::RELOAD));
183 } 194 }
184 195
185 /// Has this handle been pet within the current window? 196 /// Has this handle been pet within the current window?
186 pub fn is_pet(&self) -> bool { 197 pub fn is_pet(&self) -> bool {
187 let r = crate::pac::WDT; 198 let r = self.regs();
188 !r.reqstatus().read().rr(self.index as usize) 199 !r.reqstatus().read().rr(self.rr_index())
189 } 200 }
190 201
191 /// Steal a watchdog handle by index. 202 /// Steal a watchdog handle by index.
192 /// 203 ///
193 /// # Safety 204 /// # Safety
194 /// Watchdog must be initialized and `index` must be between `0` and `N-1` 205 /// Watchdog must be initialized, `instance_index` must be the index
195 /// where `N` is the handle count when initializing. 206 /// [`Instance::INDEX`], and `index` must be between `0` and `N-1` where `N`
196 pub unsafe fn steal(index: u8) -> Self { 207 /// is the handle count when initializing.
208 pub unsafe fn steal(instance_index: u8, index: u8) -> Self {
197 Self { 209 Self {
198 _wdt: PhantomData, 210 index: instance_index * 8 + index,
199 index,
200 } 211 }
201 } 212 }
202} 213}
214
215pub(crate) trait SealedInstance {
216 const REGS: pac::wdt::Wdt;
217}
218
219/// WDT instance.
220#[allow(private_bounds)]
221pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
222 /// Interrupt for this peripheral.
223 type Interrupt: interrupt::typelevel::Interrupt;
224 /// Index of the watchdog instance.
225 const INDEX: u8;
226}
227
228macro_rules! impl_wdt {
229 ($type:ident, $pac_type:ident, $irq:ident, $index:literal) => {
230 impl crate::wdt::SealedInstance for peripherals::$type {
231 const REGS: pac::wdt::Wdt = pac::$pac_type;
232 }
233 impl crate::wdt::Instance for peripherals::$type {
234 type Interrupt = crate::interrupt::typelevel::$irq;
235 const INDEX: u8 = $index;
236 }
237 };
238}