From afcf7255196c4362df72b9e675813cf40876750a Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Thu, 24 Sep 2020 22:46:00 +0200 Subject: [PATCH] Add rtc_async example --- examples/Cargo.toml | 1 + examples/src/bin/rtc_async.rs | 88 +++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 examples/src/bin/rtc_async.rs diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 5194e4f44..4e81d1daa 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -28,3 +28,4 @@ embassy = { version = "0.1.0", path = "../embassy" } embassy-nrf = { version = "0.1.0", path = "../embassy-nrf", features = ["defmt-trace", "52840"] } static-executor = { version = "0.1.0", features=["defmt"]} futures = { version = "0.3.5", default-features = false } +futures-intrusive = { version = "0.3.1", default-features = false } \ No newline at end of file diff --git a/examples/src/bin/rtc_async.rs b/examples/src/bin/rtc_async.rs new file mode 100644 index 000000000..838a0faef --- /dev/null +++ b/examples/src/bin/rtc_async.rs @@ -0,0 +1,88 @@ +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +#[path = "../example_common.rs"] +mod example_common; +use example_common::*; + +use core::mem::MaybeUninit; +use cortex_m_rt::entry; +use embassy_nrf::rtc; +use futures_intrusive::timer::{Clock, LocalTimer, LocalTimerService}; +use nrf52840_hal::clocks; +use static_executor::{task, Executor}; + +struct RtcClock(rtc::RTC); + +impl Clock for RtcClock { + fn now(&self) -> u64 { + self.0.now() + } +} + +#[task] +async fn run1(rtc: &'static rtc::RTC, timer: &'static LocalTimerService) { + loop { + info!("tick 1"); + timer.deadline(rtc.now() + 64000).await; + } +} + +#[task] +async fn run2(rtc: &'static rtc::RTC, timer: &'static LocalTimerService) { + loop { + info!("tick 2"); + timer.deadline(rtc.now() + 23000).await; + } +} + +static EXECUTOR: Executor = Executor::new(cortex_m::asm::sev); +static mut RTC: MaybeUninit> = MaybeUninit::uninit(); +static mut TIMER: MaybeUninit = MaybeUninit::uninit(); + +#[entry] +fn main() -> ! { + info!("Hello World!"); + + let p = embassy_nrf::pac::Peripherals::take().dewrap(); + + clocks::Clocks::new(p.CLOCK) + .enable_ext_hfosc() + .set_lfclk_src_external(clocks::LfOscConfiguration::NoExternalNoBypass) + .start_lfclk(); + + let rtc: &'static _ = unsafe { + let ptr = RTC.as_mut_ptr(); + ptr.write(RtcClock(rtc::RTC::new(p.RTC1))); + &*ptr + }; + + rtc.0.start(); + + let timer: &'static _ = unsafe { + let ptr = TIMER.as_mut_ptr(); + ptr.write(LocalTimerService::new(rtc)); + &*ptr + }; + + unsafe { + EXECUTOR.spawn(run1(&rtc.0, timer)).dewrap(); + EXECUTOR.spawn(run2(&rtc.0, timer)).dewrap(); + + loop { + timer.check_expirations(); + + EXECUTOR.run(); + + match timer.next_expiration() { + // If this is in the past, set_alarm will immediately trigger the alarm, + // which will make the wfe immediately return so we do another loop iteration. + Some(at) => rtc.0.set_alarm(at, cortex_m::asm::sev), + None => rtc.0.clear_alarm(), + } + + cortex_m::asm::wfe(); + } + } +}