From be760456359ec7cd4e701df47d3ec3b93feba602 Mon Sep 17 00:00:00 2001 From: Paul van Tilburg Date: Thu, 7 Mar 2019 22:40:41 +0100 Subject: [PATCH] Introduce the LedCycle struct to bundle a lot of led cycle functionality --- src/main.rs | 89 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 68 insertions(+), 21 deletions(-) diff --git a/src/main.rs b/src/main.rs index b575a5d..5f929e1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,8 +14,6 @@ use rtfm::app; type Led = hal::gpio::gpiod::PD>; type UserButton = hal::gpio::gpioa::PA0>; -const PERIOD: u32 = 8_000_000; - pub enum LedDirection { Clockwise, CounterClockwise, @@ -30,12 +28,66 @@ impl LedDirection { } } +pub struct LedCycle { + pub enabled: bool, + pub direction: LedDirection, + pub index: usize, + pub leds: [Led; 4] +} + +impl LedCycle { + const PERIOD: u32 = 8_000_000; + + fn from(leds: [Led; 4]) -> LedCycle { + LedCycle { + enabled: true, + direction: LedDirection::Clockwise, + index: 0, + leds + } + } + + fn disable(&mut self) { + self.enabled = false; + } + + fn enable(&mut self) { + self.enabled = true; + } + + fn reverse(&mut self) { + self.direction = self.direction.flip(); + } + + fn advance(&mut self) { + let num_leds = self.leds.len(); + + self.leds[self.index].set_high(); + self.leds[(self.index + 2) % num_leds].set_low(); + + self.index = match self.direction { + LedDirection::Clockwise => (self.index + 1) % num_leds, + LedDirection::CounterClockwise => (self.index + 3) % num_leds, + }; + } + + fn all_on(&mut self) { + for led in self.leds.iter_mut() { + led.set_high(); + } + } + + fn all_off(&mut self) { + for led in self.leds.iter_mut() { + led.set_low(); + } + } +} + #[app(device = hal::stm32)] const APP: () = { static mut button: UserButton = (); - static mut leds: [Led; 4] = (); - static mut led_cycle_direction: LedDirection = LedDirection::Clockwise; - static mut led_index: usize = 0; + static mut led_cycle: LedCycle = (); static mut exti: EXTI = (); #[init(spawn = [switch_leds])] @@ -48,6 +100,7 @@ const APP: () = { gpiod.pd14.into_push_pull_output().downgrade(), gpiod.pd15.into_push_pull_output().downgrade(), ]; + let led_cycle = LedCycle::from(leds); spawn.switch_leds().unwrap(); // Set up the EXTI0 interrup for the user button. @@ -57,28 +110,22 @@ const APP: () = { button.enable_interrupt(&mut exti); button.trigger_on_edge(&mut exti, Edge::RISING); - init::LateResources { button, exti, leds } + init::LateResources { button, exti, led_cycle } } - #[task(schedule = [switch_leds], - resources = [led_index, led_cycle_direction, leds])] + #[task(schedule = [switch_leds], resources = [led_cycle])] fn switch_leds() { - let led_index = *resources.led_index; - let num_leds = resources.leds.len(); - - resources.leds[led_index].set_high(); - resources.leds[(led_index + 2) % num_leds].set_low(); - *resources.led_index = match *resources.led_cycle_direction { - LedDirection::Clockwise => (led_index + 1) % num_leds, - LedDirection::CounterClockwise => (led_index + 3) % num_leds, - }; - - schedule.switch_leds(scheduled + PERIOD.cycles()).unwrap(); + resources.led_cycle.lock(|led_cycle| { + if led_cycle.enabled { + led_cycle.advance(); + schedule.switch_leds(scheduled + LedCycle::PERIOD.cycles()).unwrap(); + } + }); } - #[interrupt(binds = EXTI0, resources = [button, exti, led_cycle_direction])] + #[interrupt(binds = EXTI0, resources = [button, exti, led_cycle])] fn button_pressed() { - *resources.led_cycle_direction = resources.led_cycle_direction.flip(); + resources.led_cycle.lock(|led_cycle| led_cycle.reverse()); resources.button.clear_interrupt_pending_bit(resources.exti); }