Skip to content

Commit

Permalink
Add new example of ADC with RTIC using SysTick as monotonic
Browse files Browse the repository at this point in the history
  • Loading branch information
ceigel committed Feb 21, 2022
1 parent 9747282 commit 7a32ff6
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 0 deletions.
6 changes: 6 additions & 0 deletions boards/feather_m0/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ nom = { version = "5", default-features = false }
heapless = "0.7"
panic-halt = "0.2"
panic-semihosting = "0.5"
systick-monotonic = "1.0.0"
rtt-target = {version= "0.3.1", features = ["cortex-m"] }

[features]
# ask the HAL to enable atsamd21g support
Expand Down Expand Up @@ -133,6 +135,10 @@ required-features = ["adalogger", "usb", "sdmmc", "unproven"]
name = "blinky_rtic"
required-features = ["rtic", "unproven"]

[[example]]
name = "adc_rtic"
required-features = ["rtic", "unproven"]

[[example]]
name = "uart"
required-features = ["dma"]
79 changes: 79 additions & 0 deletions boards/feather_m0/examples/adc_rtic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//! Uses RTIC with the RTC as time source to read the battery level.
//! This example uses the SysTick as the Monotonic tier.
//!
//! 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 feather_m0 as bsp;

#[cfg(not(feature = "use_semihosting"))]
use panic_halt as _;
#[cfg(feature = "use_semihosting")]
use panic_semihosting as _;

#[rtic::app(device = bsp::pac, peripherals = true, dispatchers = [EVSYS])]
mod app {
use super::*;
use bsp::hal;
use hal::adc::{Adc, Resolution};
use hal::clock::GenericClockController;
use hal::gpio::v2::pin::{self, Alternate, Pin, B};
use hal::pac::{Peripherals, ADC};
use hal::prelude::*;
use hal::time::Hertz;
use rtt_target::{rprintln, rtt_init_print};
use systick_monotonic::*;

#[local]
struct Local {
adc: Adc<ADC>,
adc_pin: Pin<pin::PA07, Alternate<B>>,
}

#[shared]
struct Shared {}

#[monotonic(binds = SysTick, default = true)]
type SysTickMonotonic = Systick<100>;

#[init]
fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
rtt_init_print!();
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 freq: Hertz = gclk.into();
let systick = Systick::new(core.SYST, freq.0);

let mut adc = Adc::adc(peripherals.ADC, &mut peripherals.PM, &mut clocks);
adc.resolution(Resolution::_12BIT);
let adc_pin: Pin<pin::PA07, Alternate<B>> = pins.d9.into();
// We can use the RTC in standby for maximum power savings
core.SCB.set_sleepdeep();

// Start the blink task
read_battery::spawn().unwrap();

(Shared {}, Local { adc, adc_pin }, init::Monotonics(systick))
}

#[task(local = [adc, adc_pin])]
fn read_battery(cx: read_battery::Context) {
let data: u16 = cx.local.adc.read(cx.local.adc_pin).unwrap();
const RESOLUTION_BITS: u32 = 12;
let max_range = 1 << RESOLUTION_BITS;
let voltage = ((data as f32) * 3.3 * 2.0) / (max_range as f32);
rprintln!("Battery level {} - {}", voltage, data);
// If the LED were a local resource, the lock would not be necessary
read_battery::spawn_after(fugit::Duration::<u64, 1, 100>::secs(5)).ok();
}
}

0 comments on commit 7a32ff6

Please sign in to comment.