diff options
| author | Haobo Gu <[email protected]> | 2025-10-14 23:39:52 +0800 |
|---|---|---|
| committer | Haobo Gu <[email protected]> | 2025-10-14 23:52:32 +0800 |
| commit | 6fef28da94d133ce0cd36b5fb6ef2ef302c8eea0 (patch) | |
| tree | 98b1d4292c21d403b9c22895b96a7ebb9db54df0 | |
| parent | 4d6763364d0eab3858eebfea9d98c4fdd208faf9 (diff) | |
feat(nrf): add rtc support for nRF54L
Signed-off-by: Haobo Gu <[email protected]>
| -rw-r--r-- | embassy-nrf/Cargo.toml | 2 | ||||
| -rw-r--r-- | embassy-nrf/src/chips/nrf54l15_app.rs | 42 | ||||
| -rw-r--r-- | embassy-nrf/src/lib.rs | 1 | ||||
| -rw-r--r-- | examples/nrf54l15/Cargo.toml | 2 | ||||
| -rw-r--r-- | examples/nrf54l15/src/bin/rtc.rs | 56 |
5 files changed, 102 insertions, 1 deletions
diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml index 17ffaf439..28f137d5c 100644 --- a/embassy-nrf/Cargo.toml +++ b/embassy-nrf/Cargo.toml | |||
| @@ -80,6 +80,8 @@ unstable-pac = [] | |||
| 80 | gpiote = [] | 80 | gpiote = [] |
| 81 | 81 | ||
| 82 | ## Use RTC1 as the time driver for `embassy-time`, with a tick rate of 32.768khz | 82 | ## Use RTC1 as the time driver for `embassy-time`, with a tick rate of 32.768khz |
| 83 | ## | ||
| 84 | ## Note: For nRF54L, it's actually RTC30 | ||
| 83 | time-driver-rtc1 = ["_time-driver"] | 85 | time-driver-rtc1 = ["_time-driver"] |
| 84 | 86 | ||
| 85 | ## Enable embassy-net 802.15.4 driver | 87 | ## Enable embassy-net 802.15.4 driver |
diff --git a/embassy-nrf/src/chips/nrf54l15_app.rs b/embassy-nrf/src/chips/nrf54l15_app.rs index 82d30104f..901c5e7fc 100644 --- a/embassy-nrf/src/chips/nrf54l15_app.rs +++ b/embassy-nrf/src/chips/nrf54l15_app.rs | |||
| @@ -249,6 +249,45 @@ embassy_hal_internal::peripherals! { | |||
| 249 | P2_09, | 249 | P2_09, |
| 250 | P2_10, | 250 | P2_10, |
| 251 | 251 | ||
| 252 | // RTC | ||
| 253 | RTC10, | ||
| 254 | RTC30, | ||
| 255 | |||
| 256 | // SERIAL | ||
| 257 | SERIAL00, | ||
| 258 | SERIAL20, | ||
| 259 | SERIAL21, | ||
| 260 | SERIAL22, | ||
| 261 | SERIAL30, | ||
| 262 | |||
| 263 | // SAADC | ||
| 264 | SAADC, | ||
| 265 | |||
| 266 | // RADIO | ||
| 267 | RADIO, | ||
| 268 | |||
| 269 | // TIMER | ||
| 270 | TIMER00, | ||
| 271 | TIMER10, | ||
| 272 | TIMER20, | ||
| 273 | |||
| 274 | // PPI BRIDGE | ||
| 275 | PPIB00, | ||
| 276 | PPIB01, | ||
| 277 | PPIB10, | ||
| 278 | PPIB11, | ||
| 279 | PPIB20, | ||
| 280 | PPIB21, | ||
| 281 | PPIB22, | ||
| 282 | PPIB30, | ||
| 283 | |||
| 284 | // GPIOTE | ||
| 285 | GPIOTE20, | ||
| 286 | GPIOTE30, | ||
| 287 | |||
| 288 | // CRACEN | ||
| 289 | CRACEN, | ||
| 290 | |||
| 252 | #[cfg(feature = "_s")] | 291 | #[cfg(feature = "_s")] |
| 253 | // RRAMC | 292 | // RRAMC |
| 254 | RRAMC, | 293 | RRAMC, |
| @@ -303,6 +342,9 @@ impl_pin!(P2_08, 2, 8); | |||
| 303 | impl_pin!(P2_09, 2, 9); | 342 | impl_pin!(P2_09, 2, 9); |
| 304 | impl_pin!(P2_10, 2, 10); | 343 | impl_pin!(P2_10, 2, 10); |
| 305 | 344 | ||
| 345 | impl_rtc!(RTC10, RTC10, RTC10); | ||
| 346 | impl_rtc!(RTC30, RTC30, RTC30); | ||
| 347 | |||
| 306 | #[cfg(feature = "_ns")] | 348 | #[cfg(feature = "_ns")] |
| 307 | impl_wdt!(WDT, WDT31, WDT31, 0); | 349 | impl_wdt!(WDT, WDT31, WDT31, 0); |
| 308 | #[cfg(feature = "_s")] | 350 | #[cfg(feature = "_s")] |
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 1b7fb7e7f..705c77453 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs | |||
| @@ -155,7 +155,6 @@ pub mod reset; | |||
| 155 | #[cfg(not(feature = "_nrf54l"))] // TODO | 155 | #[cfg(not(feature = "_nrf54l"))] // TODO |
| 156 | #[cfg(not(any(feature = "_nrf5340-app", feature = "_nrf91")))] | 156 | #[cfg(not(any(feature = "_nrf5340-app", feature = "_nrf91")))] |
| 157 | pub mod rng; | 157 | pub mod rng; |
| 158 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 159 | pub mod rtc; | 158 | pub mod rtc; |
| 160 | #[cfg(not(feature = "_nrf54l"))] // TODO | 159 | #[cfg(not(feature = "_nrf54l"))] // TODO |
| 161 | #[cfg(not(any(feature = "_nrf51", feature = "nrf52820", feature = "_nrf5340-net")))] | 160 | #[cfg(not(any(feature = "_nrf51", feature = "nrf52820", feature = "_nrf5340-net")))] |
diff --git a/examples/nrf54l15/Cargo.toml b/examples/nrf54l15/Cargo.toml index a053dd0ec..541e79fcb 100644 --- a/examples/nrf54l15/Cargo.toml +++ b/examples/nrf54l15/Cargo.toml | |||
| @@ -8,6 +8,7 @@ publish = false | |||
| 8 | [dependencies] | 8 | [dependencies] |
| 9 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } | 9 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } |
| 10 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } | 10 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } |
| 11 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] } | ||
| 11 | embassy-nrf = { version = "0.8.0", path = "../../embassy-nrf", features = ["defmt", "nrf54l15-app-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } | 12 | embassy-nrf = { version = "0.8.0", path = "../../embassy-nrf", features = ["defmt", "nrf54l15-app-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } |
| 12 | 13 | ||
| 13 | defmt = "1.0.1" | 14 | defmt = "1.0.1" |
| @@ -18,6 +19,7 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing | |||
| 18 | cortex-m-rt = "0.7.0" | 19 | cortex-m-rt = "0.7.0" |
| 19 | 20 | ||
| 20 | embedded-storage = "0.3.1" | 21 | embedded-storage = "0.3.1" |
| 22 | portable-atomic = "1" | ||
| 21 | 23 | ||
| 22 | [profile.release] | 24 | [profile.release] |
| 23 | debug = 2 | 25 | debug = 2 |
diff --git a/examples/nrf54l15/src/bin/rtc.rs b/examples/nrf54l15/src/bin/rtc.rs new file mode 100644 index 000000000..a45aaca52 --- /dev/null +++ b/examples/nrf54l15/src/bin/rtc.rs | |||
| @@ -0,0 +1,56 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use core::cell::RefCell; | ||
| 5 | |||
| 6 | use embassy_executor::Spawner; | ||
| 7 | use embassy_nrf::gpio::{Level, Output, OutputDrive}; | ||
| 8 | use embassy_nrf::interrupt; | ||
| 9 | use embassy_nrf::rtc::Rtc; | ||
| 10 | use embassy_sync::blocking_mutex::Mutex; | ||
| 11 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | ||
| 12 | use portable_atomic::AtomicU64; | ||
| 13 | use {defmt_rtt as _, panic_probe as _}; | ||
| 14 | |||
| 15 | // 64 bit counter which will never overflow. | ||
| 16 | static TICK_COUNTER: AtomicU64 = AtomicU64::new(0); | ||
| 17 | static RTC: Mutex<CriticalSectionRawMutex, RefCell<Option<Rtc<'static>>>> = Mutex::new(RefCell::new(None)); | ||
| 18 | |||
| 19 | #[embassy_executor::main] | ||
| 20 | async fn main(_spawner: Spawner) { | ||
| 21 | defmt::println!("nRF54L15 RTC example"); | ||
| 22 | let p = embassy_nrf::init(Default::default()); | ||
| 23 | let mut led = Output::new(p.P2_09, Level::High, OutputDrive::Standard); | ||
| 24 | // Counter resolution is 125 ms. | ||
| 25 | let mut rtc = Rtc::new(p.RTC10, (1 << 12) - 1).unwrap(); | ||
| 26 | rtc.enable_interrupt(embassy_nrf::rtc::Interrupt::Tick, true); | ||
| 27 | rtc.enable_event(embassy_nrf::rtc::Interrupt::Tick); | ||
| 28 | rtc.enable(); | ||
| 29 | RTC.lock(|r| { | ||
| 30 | let mut rtc_borrow = r.borrow_mut(); | ||
| 31 | *rtc_borrow = Some(rtc); | ||
| 32 | }); | ||
| 33 | |||
| 34 | let mut last_counter_val = 0; | ||
| 35 | loop { | ||
| 36 | let current = TICK_COUNTER.load(core::sync::atomic::Ordering::Relaxed); | ||
| 37 | if current != last_counter_val { | ||
| 38 | led.toggle(); | ||
| 39 | last_counter_val = current; | ||
| 40 | } | ||
| 41 | } | ||
| 42 | } | ||
| 43 | |||
| 44 | #[interrupt] | ||
| 45 | fn RTC10() { | ||
| 46 | // For 64-bit, we do not need to worry about overflowing, at least not for realistic program | ||
| 47 | // lifetimes. | ||
| 48 | TICK_COUNTER.fetch_add(1, core::sync::atomic::Ordering::Relaxed); | ||
| 49 | RTC.lock(|r| { | ||
| 50 | let mut rtc_borrow = r.borrow_mut(); | ||
| 51 | rtc_borrow | ||
| 52 | .as_mut() | ||
| 53 | .unwrap() | ||
| 54 | .reset_event(embassy_nrf::rtc::Interrupt::Tick); | ||
| 55 | }); | ||
| 56 | } | ||
