Update to v0.2.0
- Added Button Abstraction - Added Button IRQ example - Updated va108xx_hal to v0.2.1, adapted API accordingly - Fix for LED API: Now consumes individual pins instead of consuming the whole pin struct
This commit is contained in:
parent
448b18c9ed
commit
a2f9cf9b29
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "vorago-reb1"
|
||||
version = "0.1.1"
|
||||
version = "0.2.0"
|
||||
authors = ["Robin Mueller <robin.mueller.m@gmail.com>"]
|
||||
edition = "2021"
|
||||
description = "Board Support Crate for the Vorago REB1 development board"
|
||||
|
@ -2,17 +2,124 @@
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
use core::cell::{Cell, RefCell};
|
||||
|
||||
use cortex_m::interrupt::Mutex;
|
||||
use cortex_m_rt::entry;
|
||||
use panic_halt as _;
|
||||
use rtt_target::{rprintln, rtt_init_print};
|
||||
use va108xx_hal::pac::interrupt;
|
||||
use va108xx_hal::{
|
||||
clock::{set_clk_div_register, FilterClkSel},
|
||||
gpio::{FilterType, InterruptEdge, PinsA},
|
||||
pac::{self, interrupt},
|
||||
prelude::*,
|
||||
time::Hertz,
|
||||
timer::set_up_ms_timer,
|
||||
};
|
||||
use vorago_reb1::button::Button;
|
||||
use vorago_reb1::leds::Leds;
|
||||
|
||||
static LEDS: Mutex<RefCell<Option<Leds>>> = Mutex::new(RefCell::new(None));
|
||||
static MS_COUNTER: Mutex<Cell<u32>> = Mutex::new(Cell::new(0));
|
||||
static BUTTON: Mutex<RefCell<Option<Button>>> = Mutex::new(RefCell::new(None));
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum PressMode {
|
||||
Toggle,
|
||||
Keep,
|
||||
}
|
||||
|
||||
// You can change the press mode here
|
||||
const PRESS_MODE: PressMode = PressMode::Keep;
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
rtt_init_print!();
|
||||
rprintln!("-- Vorago Button Blinky --");
|
||||
rprintln!("-- Vorago Button IRQ Example --");
|
||||
let mut dp = pac::Peripherals::take().unwrap();
|
||||
let pinsa = PinsA::new(&mut dp.SYSCONFIG, Some(dp.IOCONFIG), dp.PORTA);
|
||||
let edge_irq = match PRESS_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 PRESS_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();
|
||||
// Make both button and LEDs accessible from the IRQ handler as well
|
||||
cortex_m::interrupt::free(|cs| {
|
||||
LEDS.borrow(cs).replace(Some(leds));
|
||||
BUTTON.borrow(cs).replace(Some(button));
|
||||
});
|
||||
loop {}
|
||||
}
|
||||
|
||||
fn unmask_irqs() {
|
||||
unsafe {
|
||||
cortex_m::peripheral::NVIC::unmask(pac::Interrupt::OC0);
|
||||
cortex_m::peripheral::NVIC::unmask(pac::Interrupt::OC15);
|
||||
}
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn OC15() {}
|
||||
fn OC0() {
|
||||
cortex_m::interrupt::free(|cs| {
|
||||
let mut ms = MS_COUNTER.borrow(cs).get();
|
||||
ms += 1;
|
||||
MS_COUNTER.borrow(cs).set(ms);
|
||||
});
|
||||
}
|
||||
|
||||
#[interrupt]
|
||||
fn OC15() {
|
||||
cortex_m::interrupt::free(|cs| {
|
||||
if PRESS_MODE == PressMode::Toggle {
|
||||
if let Some(ref mut leds) = LEDS.borrow(cs).borrow_mut().as_deref_mut() {
|
||||
leds[0].toggle();
|
||||
}
|
||||
} else {
|
||||
if let (Some(ref mut leds), Some(ref button)) = (
|
||||
LEDS.borrow(cs).borrow_mut().as_deref_mut(),
|
||||
BUTTON.borrow(cs).borrow().as_ref(),
|
||||
) {
|
||||
if button.released() {
|
||||
leds[0].off();
|
||||
} else {
|
||||
leds[0].on();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -84,7 +84,12 @@ fn main() -> ! {
|
||||
}
|
||||
}
|
||||
LibType::Bsp => {
|
||||
let mut leds = Leds::new(PinsA::new(&mut dp.SYSCONFIG, Some(dp.IOCONFIG), dp.PORTA));
|
||||
let pinsa = PinsA::new(&mut dp.SYSCONFIG, Some(dp.IOCONFIG), dp.PORTA);
|
||||
let mut leds = Leds::new(
|
||||
pinsa.pa10.into_push_pull_output(),
|
||||
pinsa.pa7.into_push_pull_output(),
|
||||
pinsa.pa6.into_push_pull_output(),
|
||||
);
|
||||
loop {
|
||||
for _ in 0..10 {
|
||||
// Blink all LEDs quickly
|
||||
|
65
src/button.rs
Normal file
65
src/button.rs
Normal file
@ -0,0 +1,65 @@
|
||||
//! # API for the REB1 button
|
||||
//!
|
||||
//! ## Examples
|
||||
//!
|
||||
//! - [Button Blinky with Interrupts](https://github.com/robamu-org/vorago-reb1-rs/blob/main/examples/blinky-button-irq.rs)
|
||||
use va108xx_hal::{
|
||||
gpio::{FilterClkSel, FilterType, InputFloating, InterruptEdge, InterruptLevel, Pin, PA11},
|
||||
pac,
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
pub struct Button {
|
||||
button: Pin<PA11, InputFloating>,
|
||||
}
|
||||
|
||||
impl Button {
|
||||
pub fn new(pin: Pin<PA11, InputFloating>) -> Button {
|
||||
Button { button: pin }
|
||||
}
|
||||
|
||||
pub fn pressed(&self) -> bool {
|
||||
self.button.is_low().ok().unwrap()
|
||||
}
|
||||
|
||||
pub fn released(&self) -> bool {
|
||||
self.button.is_high().ok().unwrap()
|
||||
}
|
||||
|
||||
/// Configures an IRQ on edge.
|
||||
///
|
||||
/// Please note that you still have to unpend the Cortex-M interrupt yourself
|
||||
pub fn edge_irq(
|
||||
mut self,
|
||||
edge_type: InterruptEdge,
|
||||
syscfg: Option<&mut pac::SYSCONFIG>,
|
||||
irqsel: &mut pac::IRQSEL,
|
||||
irq: pac::interrupt,
|
||||
) -> Self {
|
||||
self.button = self.button.interrupt_edge(edge_type, syscfg, irqsel, irq);
|
||||
self
|
||||
}
|
||||
|
||||
/// Configures an IRQ on level.
|
||||
///
|
||||
/// Please note that you still have to unpend the Cortex-M interrupt yourself
|
||||
pub fn level_irq(
|
||||
mut self,
|
||||
level: InterruptLevel,
|
||||
syscfg: Option<&mut pac::SYSCONFIG>,
|
||||
irqsel: &mut pac::IRQSEL,
|
||||
irq: pac::interrupt,
|
||||
) -> Self {
|
||||
self.button = self.button.interrupt_level(level, syscfg, irqsel, irq);
|
||||
self
|
||||
}
|
||||
|
||||
/// Configures a filter on the button. This can be useful for debouncing the switch.
|
||||
///
|
||||
/// Please note that you still have to set a clock divisor yourself using the
|
||||
/// [`va108xx_hal::clock::set_clk_div_register`] function in order for this to work.
|
||||
pub fn filter_type(mut self, filter: FilterType, clksel: FilterClkSel) -> Self {
|
||||
self.button = self.button.filter_type(filter, clksel);
|
||||
self
|
||||
}
|
||||
}
|
22
src/leds.rs
22
src/leds.rs
@ -1,6 +1,11 @@
|
||||
//! # API for using the REB1 LEDs
|
||||
//!
|
||||
//! ## Examples
|
||||
//!
|
||||
//! - [LED example](https://github.com/robamu-org/vorago-reb1-rs/blob/main/examples/blinky-leds.rs)
|
||||
use va108xx_hal::{
|
||||
gpio::dynpins::DynPin,
|
||||
gpio::pins::{Pin, PinsA, PushPullOutput, PA10, PA6, PA7},
|
||||
gpio::pins::{Pin, PushPullOutput, PA10, PA6, PA7},
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
@ -13,12 +18,9 @@ pub struct Leds {
|
||||
}
|
||||
|
||||
impl Leds {
|
||||
pub fn new(led_parts: PinsA) -> Self {
|
||||
let led2 = led_parts.pa10.into_push_pull_output();
|
||||
let led3 = led_parts.pa7.into_push_pull_output();
|
||||
let led4 = led_parts.pa6.into_push_pull_output();
|
||||
pub fn new(led_pin1: LD2, led_pin2: LD3, led_pin3: LD4) -> Leds {
|
||||
Leds {
|
||||
leds: [led2.into(), led3.into(), led4.into()],
|
||||
leds: [led_pin1.into(), led_pin2.into(), led_pin3.into()],
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -72,14 +74,14 @@ macro_rules! ctor {
|
||||
ctor!(LD2, LD3, LD4);
|
||||
|
||||
impl Led {
|
||||
/// Turns the LED off
|
||||
/// Turns the LED off. Setting the pin high actually turns the LED off
|
||||
pub fn off(&mut self) {
|
||||
self.pin.set_low().ok();
|
||||
self.pin.set_high().ok();
|
||||
}
|
||||
|
||||
/// Turns the LED on
|
||||
/// Turns the LED on. Setting the pin low actually turns the LED on
|
||||
pub fn on(&mut self) {
|
||||
self.pin.set_high().ok();
|
||||
self.pin.set_low().ok();
|
||||
}
|
||||
|
||||
/// Toggles the LED
|
||||
|
@ -1,3 +1,4 @@
|
||||
#![no_std]
|
||||
|
||||
pub mod button;
|
||||
pub mod leds;
|
||||
|
Reference in New Issue
Block a user