Refactor the LedCycle struct, impl and related enums

This commit is contained in:
Paul van Tilburg 2019-03-15 22:08:12 +01:00
parent 27fe066219
commit 6ab8d98180
2 changed files with 50 additions and 39 deletions

View File

@ -3,45 +3,56 @@ use hal::prelude::*;
pub type Led = hal::gpio::gpiod::PD<Output<PushPull>>; pub type Led = hal::gpio::gpiod::PD<Output<PushPull>>;
pub enum LedDirection { #[derive(Debug, Eq, PartialEq)]
pub enum Direction {
Clockwise, Clockwise,
CounterClockwise, CounterClockwise,
} }
impl LedDirection { impl Direction {
fn flip(&self) -> LedDirection { fn flip(&self) -> Direction {
match self { match self {
LedDirection::Clockwise => LedDirection::CounterClockwise, Direction::Clockwise => Direction::CounterClockwise,
LedDirection::CounterClockwise => LedDirection::Clockwise, Direction::CounterClockwise => Direction::Clockwise,
} }
} }
} }
pub struct LedCycle { #[derive(Debug, Eq, PartialEq)]
pub enabled: bool, pub enum Mode {
pub direction: LedDirection, Off,
Cycle,
}
pub struct LedRing {
pub direction: Direction,
pub mode: Mode,
pub index: usize, pub index: usize,
pub leds: [crate::Led; 4], pub leds: [crate::Led; 4],
} }
impl LedCycle { impl LedRing {
pub const PERIOD: u32 = 8_000_000; pub const PERIOD: u32 = 8_000_000;
pub fn from(leds: [crate::Led; 4]) -> LedCycle { pub fn from(leds: [crate::Led; 4]) -> LedRing {
LedCycle { LedRing {
enabled: true, direction: Direction::Clockwise,
direction: LedDirection::Clockwise, mode: Mode::Cycle,
index: 0, index: 0,
leds, leds,
} }
} }
pub fn disable(&mut self) { pub fn enable_cycle(&mut self) {
self.enabled = false; self.mode = Mode::Cycle;
} }
pub fn enable(&mut self) { pub fn disable(&mut self) {
self.enabled = true; self.mode = Mode::Off;
}
pub fn is_mode_cycle(&self) -> bool {
self.mode == Mode::Cycle
} }
pub fn reverse(&mut self) { pub fn reverse(&mut self) {
@ -55,8 +66,8 @@ impl LedCycle {
self.leds[(self.index + 2) % num_leds].set_low(); self.leds[(self.index + 2) % num_leds].set_low();
self.index = match self.direction { self.index = match self.direction {
LedDirection::Clockwise => (self.index + 1) % num_leds, Direction::Clockwise => (self.index + 1) % num_leds,
LedDirection::CounterClockwise => (self.index + 3) % num_leds, Direction::CounterClockwise => (self.index + 3) % num_leds,
}; };
} }

View File

@ -7,7 +7,7 @@ extern crate panic_semihosting;
mod led; mod led;
use crate::led::{Led, LedCycle}; use crate::led::{Led, LedRing};
use core::fmt::Write; use core::fmt::Write;
use cortex_m_semihosting::hprintln; use cortex_m_semihosting::hprintln;
use hal::block; use hal::block;
@ -27,14 +27,14 @@ type UserButton = hal::gpio::gpioa::PA0<Input<Floating>>;
const APP: () = { const APP: () = {
static mut button: UserButton = (); static mut button: UserButton = ();
static mut buffer: Vec<u8, U8> = (); static mut buffer: Vec<u8, U8> = ();
static mut led_cycle: LedCycle = (); static mut led_ring: LedRing = ();
static mut exti: EXTI = (); static mut exti: EXTI = ();
static mut serial_rx: SerialRx = (); static mut serial_rx: SerialRx = ();
static mut serial_tx: SerialTx = (); static mut serial_tx: SerialTx = ();
#[init(spawn = [switch_leds])] #[init(spawn = [switch_leds])]
fn init() -> init::LateResources { fn init() -> init::LateResources {
// Set up the LED cycle and spawn the LEDs switch task. // Set up the LED ring and spawn the LEDs switch task.
let gpiod = device.GPIOD.split(); let gpiod = device.GPIOD.split();
let leds = [ let leds = [
gpiod.pd12.into_push_pull_output().downgrade(), gpiod.pd12.into_push_pull_output().downgrade(),
@ -42,7 +42,7 @@ const APP: () = {
gpiod.pd14.into_push_pull_output().downgrade(), gpiod.pd14.into_push_pull_output().downgrade(),
gpiod.pd15.into_push_pull_output().downgrade(), gpiod.pd15.into_push_pull_output().downgrade(),
]; ];
let led_cycle = LedCycle::from(leds); let led_ring = LedRing::from(leds);
spawn.switch_leds().unwrap(); spawn.switch_leds().unwrap();
// Set up the EXTI0 interrupt for the user button. // Set up the EXTI0 interrupt for the user button.
@ -69,19 +69,19 @@ const APP: () = {
button, button,
buffer, buffer,
exti, exti,
led_cycle, led_ring,
serial_tx, serial_tx,
serial_rx, serial_rx,
} }
} }
#[task(schedule = [switch_leds], resources = [led_cycle])] #[task(schedule = [switch_leds], resources = [led_ring])]
fn switch_leds() { fn switch_leds() {
resources.led_cycle.lock(|led_cycle| { resources.led_ring.lock(|led_ring| {
if led_cycle.enabled { if led_ring.is_mode_cycle() {
led_cycle.advance(); led_ring.advance();
schedule schedule
.switch_leds(scheduled + LedCycle::PERIOD.cycles()) .switch_leds(scheduled + LedRing::PERIOD.cycles())
.unwrap(); .unwrap();
} }
}); });
@ -89,7 +89,7 @@ const APP: () = {
#[interrupt(binds = EXTI0, resources = [button, exti, led_cycle, serial_tx])] #[interrupt(binds = EXTI0, resources = [button, exti, led_cycle, serial_tx])]
fn button_pressed() { fn button_pressed() {
resources.led_cycle.lock(|led_cycle| led_cycle.reverse()); resources.led_ring.lock(|led_ring| led_ring.reverse());
// Write the fact that the button has been pressed to the serial port. // Write the fact that the button has been pressed to the serial port.
resources resources
@ -102,7 +102,7 @@ const APP: () = {
#[interrupt( #[interrupt(
binds = USART2, binds = USART2,
priority = 2, priority = 2,
resources = [buffer, led_cycle, serial_rx, serial_tx], resources = [buffer, led_ring, serial_rx, serial_tx],
spawn = [switch_leds] spawn = [switch_leds]
)] )]
fn handle_serial() { fn handle_serial() {
@ -119,22 +119,22 @@ const APP: () = {
block!(resources.serial_tx.write(b'\n')).unwrap(); block!(resources.serial_tx.write(b'\n')).unwrap();
match &buffer[..] { match &buffer[..] {
b"flip" => { b"flip" => {
resources.led_cycle.reverse(); resources.led_ring.reverse();
} }
b"stop" => { b"stop" => {
resources.led_cycle.disable(); resources.led_ring.disable();
} }
b"start" => { b"cycle" => {
resources.led_cycle.enable(); resources.led_ring.enable_cycle();
spawn.switch_leds().unwrap(); spawn.switch_leds().unwrap();
} }
b"off" => { b"off" => {
resources.led_cycle.disable(); resources.led_ring.disable();
resources.led_cycle.all_off(); resources.led_ring.all_off();
} }
b"on" => { b"on" => {
resources.led_cycle.disable(); resources.led_ring.disable();
resources.led_cycle.all_on(); resources.led_ring.all_on();
} }
_ => { _ => {
writeln!(resources.serial_tx, "?\r").unwrap(); writeln!(resources.serial_tx, "?\r").unwrap();