diff --git a/boards/xiao_m0/CHANGELOG.md b/boards/xiao_m0/CHANGELOG.md index 3b34aa512b2..45798bf6afa 100644 --- a/boards/xiao_m0/CHANGELOG.md +++ b/boards/xiao_m0/CHANGELOG.md @@ -1,6 +1,9 @@ # Unreleased - Updated to 2021 edition, updated dependencies, removed unused dependencies (#562) +- added `rtic` feature flag to enable `rtic` feature in the hal +- added `blinky_rtic` example to demonstrate a simple rtic app on the xiao_m0 + # 0.12.0 - bump hal dependency to 0.14.0 diff --git a/boards/xiao_m0/Cargo.toml b/boards/xiao_m0/Cargo.toml index 0753ec4e7e3..db2c0f8d182 100644 --- a/boards/xiao_m0/Cargo.toml +++ b/boards/xiao_m0/Cargo.toml @@ -15,7 +15,7 @@ version = "0.7" optional = true [dependencies.atsamd-hal] -version = "0.14" +version = "0.15.1" default-features = false [dependencies.usb-device] @@ -23,6 +23,7 @@ version = "0.2" optional = true [dev-dependencies] +cortex-m-rtic = "1.0.0" cortex-m = "0.7" usbd-serial = "0.1" panic-halt = "0.2" @@ -36,11 +37,16 @@ default = ["rt", "atsamd-hal/samd21g", "atsamd-hal/unproven"] rt = ["cortex-m-rt", "atsamd-hal/samd21g-rt"] unproven = ["atsamd-hal/unproven"] usb = ["atsamd-hal/usb", "usb-device"] +rtic = [ "atsamd-hal/rtic"] [[example]] name = "blink" required-features = ["unproven"] +[[example]] +name = "blinky_rtic" +required-features = ["rtic","unproven"] + [[example]] name = "eic" required-features = ["unproven"] diff --git a/boards/xiao_m0/examples/blinky_rtic.rs b/boards/xiao_m0/examples/blinky_rtic.rs new file mode 100644 index 00000000000..5c67add2be2 --- /dev/null +++ b/boards/xiao_m0/examples/blinky_rtic.rs @@ -0,0 +1,74 @@ +//! Uses RTIC with the RTC as time source to blink an LED. +//! +//! The idle task is sleeping the CPU, so in practice this gives similar power +//! figure as the "sleeping_timer_rtc" example. +#![no_std] +#![no_main] + +use xiao_m0 as bsp; + +#[cfg(not(feature = "use_semihosting"))] +use panic_halt as _; +#[cfg(feature = "use_semihosting")] +use panic_semihosting as _; + +use rtic; + +#[rtic::app(device = bsp::pac, peripherals = true, dispatchers = [EVSYS])] +mod app { + use super::*; + use bsp::hal; + use hal::clock::{ClockGenId, ClockSource, GenericClockController}; + use hal::pac::Peripherals; + use hal::prelude::*; + use hal::rtc::{Count32Mode, Duration, Rtc}; + + #[local] + struct Local {} + + #[shared] + struct Shared { + // The LED could be a local resource, since it is only used in one task + // But we want to showcase shared resources and locking + led: bsp::Led0, + } + + #[monotonic(binds = RTC, default = true)] + type RtcMonotonic = Rtc; + + #[init] + fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) { + let mut peripherals: Peripherals = cx.device; + let pins = bsp::Pins::new(peripherals.PORT); + let mut core: rtic::export::Peripherals = cx.core; + let mut clocks = GenericClockController::with_external_32kosc( + peripherals.GCLK, + &mut peripherals.PM, + &mut peripherals.SYSCTRL, + &mut peripherals.NVMCTRL, + ); + let _gclk = clocks.gclk0(); + let rtc_clock_src = clocks + .configure_gclk_divider_and_source(ClockGenId::GCLK2, 1, ClockSource::XOSC32K, false) + .unwrap(); + clocks.configure_standby(ClockGenId::GCLK2, true); + let rtc_clock = clocks.rtc(&rtc_clock_src).unwrap(); + let rtc = Rtc::count32_mode(peripherals.RTC, rtc_clock.freq(), &mut peripherals.PM); + let led: bsp::Led0 = pins.led0.into(); + + // We can use the RTC in standby for maximum power savings + core.SCB.set_sleepdeep(); + + // Start the blink task + blink::spawn().unwrap(); + + (Shared { led }, Local {}, init::Monotonics(rtc)) + } + + #[task(shared = [led])] + fn blink(mut cx: blink::Context) { + // If the LED were a local resource, the lock would not be necessary + cx.shared.led.lock(|led| led.toggle().unwrap()); + blink::spawn_after(Duration::secs(1)).ok(); + } +}