From 91cde804966cc98fb73d6328dd99e048ab23dbbf Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 4 Dec 2021 20:51:47 +0100 Subject: [PATCH] added RTIC example --- Cargo.toml | 8 ++ examples/blinky-button-irq.rs | 2 +- examples/blinky-button-rtic.rs | 157 +++++++++++++++++++++++++++++++++ src/button.rs | 1 + 4 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 examples/blinky-button-rtic.rs diff --git a/Cargo.toml b/Cargo.toml index e6b887c..b53a2b9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,15 @@ embedded-hal = "0.2.6" version = "0.2.2" features = ["rt"] +[features] +rt = ["va108xx-hal/rt"] + [dev-dependencies] +cortex-m-rtic = "0.6.0-rc.4" panic-rtt-target = { version = "0.1", features = ["cortex-m"] } rtt-target = { version = "0.3", features = ["cortex-m"] } panic-halt = "0.2" + +[[example]] +name = "blinky-button-rtic" +required-features = ["rt"] diff --git a/examples/blinky-button-irq.rs b/examples/blinky-button-irq.rs index 366db2a..9fdec79 100644 --- a/examples/blinky-button-irq.rs +++ b/examples/blinky-button-irq.rs @@ -1,4 +1,4 @@ -//! Minimal blinky for the REB1 board using only PAC features +//! Blinky button application for the REB1 board #![no_main] #![no_std] diff --git a/examples/blinky-button-rtic.rs b/examples/blinky-button-rtic.rs new file mode 100644 index 0000000..a25e85f --- /dev/null +++ b/examples/blinky-button-rtic.rs @@ -0,0 +1,157 @@ +//! Blinky button application for the REB1 board using RTIC +#![no_main] +#![no_std] + +#[rtic::app(device = pac)] +mod app { + use panic_rtt_target as _; + use rtt_target::{rprintln, rtt_init_default, set_print_channel}; + use va108xx_hal::{ + clock::{set_clk_div_register, FilterClkSel}, + gpio::{FilterType, InterruptEdge, PinsA}, + pac::{self, interrupt}, + prelude::*, + time::Hertz, + timer::{default_ms_irq_handler, set_up_ms_timer}, + }; + use vorago_reb1::button::Button; + use vorago_reb1::leds::Leds; + + #[derive(Debug, PartialEq)] + pub enum PressMode { + Toggle, + Keep, + } + + #[derive(Debug, PartialEq)] + pub enum CfgMode { + Prompt, + Fixed, + } + + const CFG_MODE: CfgMode = CfgMode::Fixed; + // You can change the press mode here + const DEFAULT_MODE: PressMode = PressMode::Toggle; + + #[local] + struct Local { + leds: Leds, + button: Button, + mode: PressMode, + } + + #[shared] + struct Shared {} + + #[init] + fn init(ctx: init::Context) -> (Shared, Local, init::Monotonics) { + let channels = rtt_init_default!(); + set_print_channel(channels.up.0); + rprintln!("-- Vorago Button IRQ Example --"); + let mode = match CFG_MODE { + // Ask mode from user via RTT + CfgMode::Prompt => prompt_mode(channels.down.0), + // Use mode hardcoded in `DEFAULT_MODE` + CfgMode::Fixed => DEFAULT_MODE, + }; + rprintln!("Using {:?} mode", mode); + + let mut dp = ctx.device; + let pinsa = PinsA::new(&mut dp.SYSCONFIG, Some(dp.IOCONFIG), dp.PORTA); + let edge_irq = match mode { + PressMode::Toggle => InterruptEdge::HighToLow, + PressMode::Keep => InterruptEdge::BothEdges, + }; + + // Configure an edge interrupt on the button and route it to interrupt vector 15 + let mut button = Button::new(pinsa.pa11.into_floating_input()).edge_irq( + edge_irq, + Some(&mut dp.SYSCONFIG), + &mut dp.IRQSEL, + pac::interrupt::OC15, + ); + + if mode == PressMode::Toggle { + // This filter debounces the switch for edge based interrupts + button = button.filter_type(FilterType::FilterFourClockCycles, FilterClkSel::Clk1); + set_clk_div_register( + &mut dp.SYSCONFIG, + FilterClkSel::Clk1, + Hertz::from(50.khz()).0, + ); + } + + set_up_ms_timer( + &mut dp.SYSCONFIG, + &mut dp.IRQSEL, + 50.mhz().into(), + dp.TIM0, + interrupt::OC0, + ); + let mut leds = Leds::new( + pinsa.pa10.into_push_pull_output(), + pinsa.pa7.into_push_pull_output(), + pinsa.pa6.into_push_pull_output(), + ); + for led in leds.iter_mut() { + led.off(); + } + // Activate the IRQs so the processors sees them as well + unmask_irqs(); + (Shared {}, Local { leds, button, mode }, init::Monotonics()) + } + + // `shared` cannot be accessed from this context + #[idle] + fn idle(_cx: idle::Context) -> ! { + loop {} + } + + #[task(binds = OC15, local=[button, leds, mode])] + fn button_task(cx: button_task::Context) { + let leds = cx.local.leds; + let button = cx.local.button; + let mode = cx.local.mode; + if *mode == PressMode::Toggle { + leds[0].toggle(); + } else { + if button.released() { + leds[0].off(); + } else { + leds[0].on(); + } + } + } + + #[task(binds = OC0)] + fn ms_tick(_cx: ms_tick::Context) { + default_ms_irq_handler(); + } + + fn unmask_irqs() { + unsafe { + cortex_m::peripheral::NVIC::unmask(pac::Interrupt::OC0); + cortex_m::peripheral::NVIC::unmask(pac::Interrupt::OC15); + } + } + + fn prompt_mode(mut down_channel: rtt_target::DownChannel) -> PressMode { + rprintln!("Using prompt mode"); + rprintln!("Please enter the mode [0: Toggle, 1: Keep]"); + let mut read_buf: [u8; 16] = [0; 16]; + let mut read; + loop { + read = down_channel.read(&mut read_buf); + for i in 0..read { + let val = read_buf[i] as char; + if val == '0' || val == '1' { + if val == '0' { + return PressMode::Toggle; + } else { + return PressMode::Keep; + } + } + } + } + } +} diff --git a/src/button.rs b/src/button.rs index dab5f44..d297124 100644 --- a/src/button.rs +++ b/src/button.rs @@ -3,6 +3,7 @@ //! ## Examples //! //! - [Button Blinky with Interrupts](https://github.com/robamu-org/vorago-reb1-rs/blob/main/examples/blinky-button-irq.rs) +//! - [Button Blinky with Interrupts using RTIC](https://github.com/robamu-org/vorago-reb1-rs/blob/main/examples/blinky-button-rtic.rs) use va108xx_hal::{ gpio::{FilterClkSel, FilterType, InputFloating, InterruptEdge, InterruptLevel, Pin, PA11}, pac,