From f7c3005345df07bad5c42612fd73974bd569affb Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 19 Sep 2025 17:38:24 +0200 Subject: add basic RTC driver for nRF --- examples/nrf52840/Cargo.toml | 1 + examples/nrf52840/src/bin/rtc.rs | 57 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 examples/nrf52840/src/bin/rtc.rs (limited to 'examples') diff --git a/examples/nrf52840/Cargo.toml b/examples/nrf52840/Cargo.toml index 452e83b7e..ca3c6f863 100644 --- a/examples/nrf52840/Cargo.toml +++ b/examples/nrf52840/Cargo.toml @@ -35,6 +35,7 @@ embedded-hal-async = { version = "1.0" } embedded-hal-bus = { version = "0.1", features = ["async"] } num-integer = { version = "0.1.45", default-features = false } microfft = "0.5.0" +portable-atomic = "1" [profile.release] debug = 2 diff --git a/examples/nrf52840/src/bin/rtc.rs b/examples/nrf52840/src/bin/rtc.rs new file mode 100644 index 000000000..a3df7da14 --- /dev/null +++ b/examples/nrf52840/src/bin/rtc.rs @@ -0,0 +1,57 @@ +#![no_std] +#![no_main] + +use core::cell::RefCell; + +use embassy_executor::Spawner; +use embassy_nrf::gpio::{Level, Output, OutputDrive}; +use embassy_nrf::interrupt; +use embassy_nrf::rtc::Rtc; +use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; +use embassy_sync::blocking_mutex::Mutex; +use portable_atomic::AtomicU64; +use {defmt_rtt as _, panic_probe as _}; + +// 64 bit counter which will never overflow. +static TICK_COUNTER: AtomicU64 = AtomicU64::new(0); +static RTC: Mutex>>> = + Mutex::new(RefCell::new(None)); + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + defmt::println!("nRF52840 RTC example"); + let p = embassy_nrf::init(Default::default()); + let mut led = Output::new(p.P0_13, Level::High, OutputDrive::Standard); + // Counter resolution is 125 ms. + let mut rtc = Rtc::new(p.RTC0, (1 << 12) - 1).unwrap(); + rtc.enable_interrupt(embassy_nrf::rtc::Interrupt::Tick, true); + rtc.enable_event(embassy_nrf::rtc::Interrupt::Tick); + rtc.enable(); + RTC.lock(|r| { + let mut rtc_borrow = r.borrow_mut(); + *rtc_borrow = Some(rtc); + }); + + let mut last_counter_val = 0; + loop { + let current = TICK_COUNTER.load(core::sync::atomic::Ordering::Relaxed); + if current != last_counter_val { + led.toggle(); + last_counter_val = current; + } + } +} + +#[interrupt] +fn RTC0() { + // For 64-bit, we do not need to worry about overflowing, at least not for realistic program + // lifetimes. + TICK_COUNTER.fetch_add(1, core::sync::atomic::Ordering::Relaxed); + RTC.lock(|r| { + let mut rtc_borrow = r.borrow_mut(); + rtc_borrow + .as_mut() + .unwrap() + .reset_event(embassy_nrf::rtc::Interrupt::Tick); + }); +} -- cgit