diff --git a/report-3/rts10_rust/src/leds.rs b/report-3/rts10_rust/src/leds.rs index 3eeeb23..ff66d7b 100644 --- a/report-3/rts10_rust/src/leds.rs +++ b/report-3/rts10_rust/src/leds.rs @@ -49,6 +49,14 @@ impl<'a, T: OutputPin> Toggle for ToggleLed<'a, T> { } } +#[derive(Debug)] +pub enum LedError { + Red(R), + Green(G), + Orange(O), + Blue(B) +} + pub struct Leds<'a, RP: OutputPin, RT: Toggle, GP: OutputPin, GT: Toggle, @@ -86,10 +94,13 @@ impl<'a, } } - pub fn set_all(&mut self, red: PinState, green: PinState, orange: PinState, blue: PinState) { - let _ = self.red.set(red); - let _ = self.orange.set(orange); - let _ = self.green.set(green); - let _ = self.blue.set(blue); + pub fn set_all(&mut self, red: PinState, green: PinState, orange: PinState, blue: PinState) + -> Result<(), LedError> + { + self.red.set(red).or_else(|err| { Err(LedError::Red(err)) })?; + self.orange.set(orange).or_else(|err| { Err(LedError::Orange(err)) })?; + self.green.set(green).or_else(|err| { Err(LedError::Green(err)) })?; + self.blue.set(blue).or_else(|err| { Err(LedError::Blue(err)) })?; + Ok(()) } } diff --git a/report-3/rts10_rust/src/main.rs b/report-3/rts10_rust/src/main.rs index 3e0549f..e12276c 100644 --- a/report-3/rts10_rust/src/main.rs +++ b/report-3/rts10_rust/src/main.rs @@ -3,26 +3,40 @@ #![no_main] #![no_std] -use embedded_hal::digital::PinState; // Halt on panic use panic_halt as _; // panic handler use cortex_m_rt::entry; +use embedded_hal::digital::OutputPin; +use stm32f4xx_hal::timer::SysDelay; use stm32f4xx_hal::{self as hal}; use crate::hal::{pac, prelude::*}; mod leds; -use crate::leds::{Leds, ToggleLed}; +use crate::leds::{Leds, Toggle, ToggleLed}; mod state_machine; use crate::state_machine::StateMachine; +fn error_blink(led: &mut ToggleLed, delay: &mut SysDelay) -> ! { + loop { + let _ = led.toggle(); + delay.delay_ms(10_u32); + } +} + #[entry] fn main() -> ! { if let (Some(dp), Some(cp)) = ( pac::Peripherals::take(), cortex_m::peripheral::Peripherals::take(), ) { + //Klok instellen + let rcc = dp.RCC.constrain(); + let clocks = rcc.cfgr.sysclk(48.MHz()).freeze(); + // Create a delay abstraction based on SysTick + let mut delay = cp.SYST.delay(&clocks); + //GPIOD ophalen let gpiod = dp.GPIOD.split(); //led pinnen uphalen @@ -30,33 +44,45 @@ fn main() -> ! { let mut red_pin = &mut gpiod.pd14.into_push_pull_output(); let mut orange_pin = &mut gpiod.pd13.into_push_pull_output(); let mut blue_pin = &mut gpiod.pd15.into_push_pull_output(); - let mut green = ToggleLed::new(&mut green_pin).expect("faild to set green led"); - let mut red = ToggleLed::new(&mut red_pin).expect("faild to set red led"); - let mut orange = ToggleLed::new(&mut orange_pin).expect("faild to set orange led"); let mut blue = ToggleLed::new(&mut blue_pin).expect("faild to set blue led"); + let mut green = match ToggleLed::new(&mut green_pin) { + Err(_) => error_blink(&mut blue, &mut delay), + Ok(green) => green + }; + let mut red = match ToggleLed::new(&mut red_pin) { + Err(_) => error_blink(&mut blue, &mut delay), + Ok(red) => red + }; + let mut orange = match ToggleLed::new(&mut orange_pin) { + Err(_) => error_blink(&mut blue, &mut delay), + Ok(orange) => orange + }; let mut leds = Leds::new(&mut red, &mut green, &mut orange, &mut blue); //user knop let gpioa = dp.GPIOA.split(); let button = &mut gpioa.pa0.into_floating_input(); //leds struct en state machine maken - let mut state_machine = StateMachine::new(&mut leds); + let mut state_machine = match StateMachine::new(&mut leds) { + Err(_err) => error_blink(&mut blue, &mut delay), + Ok(state_machine) => state_machine, + }; - //Klok instellen - let rcc = dp.RCC.constrain(); - let clocks = rcc.cfgr.sysclk(48.MHz()).freeze(); - - // Create a delay abstraction based on SysTick - let mut delay = cp.SYST.delay(&clocks); let mut button_high = button.is_high(); loop { - let _ = state_machine.second_passed(); + if let Err(_) = state_machine.second_passed() { + error_blink(&mut blue, &mut delay); + } for _ in 0..99 { if button_high != button.is_high() { button_high = button.is_high(); if button_high { - state_machine.button_press(); + if let Err(_) = state_machine.button_press() { + error_blink(&mut blue, &mut delay); + } } else { - state_machine.button_release(); + if let Err(_) = state_machine.button_release() { + error_blink(&mut blue, &mut delay); + } } } delay.delay_ms(10_u32); @@ -65,4 +91,4 @@ fn main() -> ! { } loop {} -} \ No newline at end of file +} diff --git a/report-3/rts10_rust/src/state_machine.rs b/report-3/rts10_rust/src/state_machine.rs index e240870..7300128 100644 --- a/report-3/rts10_rust/src/state_machine.rs +++ b/report-3/rts10_rust/src/state_machine.rs @@ -1,6 +1,6 @@ use embedded_hal::digital::{OutputPin, PinState}; -use crate::leds::{Leds, Toggle}; +use crate::leds::{LedError, Leds, Toggle}; enum States { Red(StateRed), @@ -15,10 +15,16 @@ trait State< OP: OutputPin, OT: Toggle, BP: OutputPin, BT: Toggle > { - fn new(leds: &mut Leds) -> Self; - fn second_passed(&self, leds: &mut Leds) -> States; - fn button_press(&self, leds: &mut Leds) -> States; - fn button_release(&self, leds: &mut Leds) -> States; + fn new(leds: &mut Leds) + -> Result> + where + Self: Sized; + fn second_passed(&self, leds: &mut Leds) + -> Result>; + fn button_press(&self, leds: &mut Leds) + -> Result>; + fn button_release(&self, leds: &mut Leds) + -> Result>; } pub struct StateMachine<'a, @@ -35,37 +41,49 @@ impl<'a, GP: OutputPin, GT: Toggle, OP: OutputPin, OT: Toggle, BP: OutputPin, BT: Toggle -> StateMachine<'a, RP, RT, GP, GT, OP, OT, BP, BT> +> StateMachine<'a, RP, RT, GP, GT, OP, OT, BP, BT> { - pub fn new(leds: &'a mut Leds<'a, RP, RT, GP, GT, OP, OT, BP, BT>) -> Self { - Self { - state: States::Red(StateRed::new(leds)), - leds - } + pub fn new( + leds: &'a mut Leds<'a, RP, RT, GP, GT, OP, OT, BP, BT>, + ) -> Result> { + let state = StateRed::new(leds)?; + Ok(Self { + state: States::Red(state), + leds, + }) } - pub fn second_passed(&mut self) { + pub fn second_passed( + &mut self, + ) -> Result<(), LedError> { self.state = match &self.state { - States::Red(state) => state.second_passed(self.leds), - States::Orange(state) => state.second_passed(self.leds), - States::Green(state) => state.second_passed(self.leds), - States::BridgeOpen(state) => state.second_passed(self.leds), - } + States::Red(state) => state.second_passed(self.leds)?, + States::Orange(state) => state.second_passed(self.leds)?, + States::Green(state) => state.second_passed(self.leds)?, + States::BridgeOpen(state) => state.second_passed(self.leds)?, + }; + Ok(()) } - pub fn button_press(&mut self) { + pub fn button_press( + &mut self, + ) -> Result<(), LedError> { self.state = match &self.state { - States::Red(state) => state.button_press(self.leds), - States::Orange(state) => state.button_press(self.leds), - States::Green(state) => state.button_press(self.leds), - States::BridgeOpen(state) => state.button_press(self.leds), - } + States::Red(state) => state.button_press(self.leds)?, + States::Orange(state) => state.button_press(self.leds)?, + States::Green(state) => state.button_press(self.leds)?, + States::BridgeOpen(state) => state.button_press(self.leds)?, + }; + Ok(()) } - pub fn button_release(&mut self) { + pub fn button_release( + &mut self, + ) -> Result<(), LedError> { self.state = match &self.state { - States::Red(state) => state.button_release(self.leds), - States::Orange(state) => state.button_release(self.leds), - States::Green(state) => state.button_release(self.leds), - States::BridgeOpen(state) => state.button_release(self.leds), - } + States::Red(state) => state.button_release(self.leds)?, + States::Orange(state) => state.button_release(self.leds)?, + States::Green(state) => state.button_release(self.leds)?, + States::BridgeOpen(state) => state.button_release(self.leds)?, + }; + Ok(()) } } @@ -74,37 +92,47 @@ impl<'a, // #################################################### struct StateRed { - time_passed: u32 + time_passed: u32, } impl< RP: OutputPin, RT: Toggle, GP: OutputPin, GT: Toggle, OP: OutputPin, OT: Toggle, BP: OutputPin, BT: Toggle -> State for StateRed { - fn new(leds: &mut Leds) -> Self { - leds.set_all(PinState::High, PinState::Low, PinState::Low, PinState::Low); - Self { - time_passed: 0 - } +> State for StateRed +{ + fn new( + leds: &mut Leds, + ) -> Result> { + leds.set_all(PinState::High, PinState::Low, PinState::Low, PinState::Low)?; + Ok(Self { time_passed: 0 }) } - fn second_passed(&self, leds: &mut Leds) -> States { + fn second_passed( + &self, + leds: &mut Leds, + ) -> Result> { if self.time_passed + 1 >= 4 { - States::Green(StateGreen::new(leds)) + Ok(States::Green(StateGreen::new(leds)?)) } else { - States::Red(Self { - time_passed: self.time_passed + 1 - }) + Ok(States::Red(Self { + time_passed: self.time_passed + 1, + })) } } - fn button_press(&self, leds: &mut Leds) -> States { - States::BridgeOpen(StateBridgeOpen::new(leds)) + fn button_press( + &self, + leds: &mut Leds, + ) -> Result> { + Ok(States::BridgeOpen(StateBridgeOpen::new(leds)?)) } - fn button_release(&self, _leds: &mut Leds) -> States { - States::Red(Self { - time_passed: self.time_passed - }) + fn button_release( + &self, + _leds: &mut Leds, + ) -> Result> { + Ok(States::Red(Self { + time_passed: self.time_passed, + })) } } @@ -120,32 +148,42 @@ impl< GP: OutputPin, GT: Toggle, OP: OutputPin, OT: Toggle, BP: OutputPin, BT: Toggle -> State for StateGreen { - fn new(leds: &mut Leds) -> Self { - leds.set_all(PinState::Low, PinState::High, PinState::Low, PinState::Low); - Self { - time_passed: 0 - } +> State for StateGreen +{ + fn new( + leds: &mut Leds, + ) -> Result> { + leds.set_all(PinState::Low, PinState::High, PinState::Low, PinState::Low)?; + Ok(Self { time_passed: 0 }) } - fn second_passed(&self, leds: &mut Leds) -> States { + fn second_passed( + &self, + leds: &mut Leds, + ) -> Result> { if self.time_passed + 1 >= 3 { - States::Orange(StateOrange::new(leds)) + Ok(States::Orange(StateOrange::new(leds)?)) } else { - States::Green(Self { - time_passed: self.time_passed + 1 - }) + Ok(States::Green(Self { + time_passed: self.time_passed + 1, + })) } } - fn button_press(&self, _leds: &mut Leds) -> States { - States::Green(Self { - time_passed: self.time_passed - }) + fn button_press( + &self, + _leds: &mut Leds, + ) -> Result> { + Ok(States::Green(Self { + time_passed: self.time_passed, + })) } - fn button_release(&self, _leds: &mut Leds) -> States { - States::Green(Self { - time_passed: self.time_passed - }) + fn button_release( + &self, + _leds: &mut Leds, + ) -> Result> { + Ok(States::Green(Self { + time_passed: self.time_passed, + })) } } @@ -159,20 +197,32 @@ impl< GP: OutputPin, GT: Toggle, OP: OutputPin, OT: Toggle, BP: OutputPin, BT: Toggle -> State for StateOrange { - fn new(leds: &mut Leds) -> Self { - leds.set_all(PinState::Low, PinState::Low, PinState::High, PinState::Low); - Self {} +> State for StateOrange +{ + fn new( + leds: &mut Leds, + ) -> Result> { + leds.set_all(PinState::Low, PinState::Low, PinState::High, PinState::Low)?; + Ok(Self {}) } - fn second_passed(&self, leds: &mut Leds) -> States { - States::Red(StateRed::new(leds)) + fn second_passed( + &self, + leds: &mut Leds, + ) -> Result> { + Ok(States::Red(StateRed::new(leds)?)) } - fn button_press(&self, _leds: &mut Leds) -> States { - States::Orange(Self {}) + fn button_press( + &self, + _leds: &mut Leds, + ) -> Result> { + Ok(States::Orange(Self {})) } - fn button_release(&self, _leds: &mut Leds) -> States { - States::Orange(Self {}) + fn button_release( + &self, + _leds: &mut Leds, + ) -> Result> { + Ok(States::Orange(Self {})) } } @@ -188,37 +238,49 @@ impl< GP: OutputPin, GT: Toggle, OP: OutputPin, OT: Toggle, BP: OutputPin, BT: Toggle -> State for StateBridgeOpen { - fn new(leds: &mut Leds) -> Self { - leds.set_all(PinState::Low, PinState::Low, PinState::Low, PinState::High); - Self { - time_passed: 0 - } +> State for StateBridgeOpen +{ + fn new( + leds: &mut Leds, + ) -> Result> { + leds.set_all(PinState::Low, PinState::Low, PinState::Low, PinState::High)?; + Ok(Self { time_passed: 0 }) } - fn second_passed(&self, leds: &mut Leds) -> States { + fn second_passed( + &self, + leds: &mut Leds, + ) -> Result> { if self.time_passed + 1 == 2 { - let _ = leds.blue.low(); - States::BridgeOpen(Self { - time_passed: self.time_passed + 1 - }) + leds.blue.low().or_else(|err| { + Err(LedError::::Blue(err)) + }); + Ok(States::BridgeOpen(Self { + time_passed: self.time_passed + 1, + })) } else if self.time_passed + 1 >= 3 { - let _ = leds.blue.high(); - States::BridgeOpen(Self { - time_passed: 0 - }) + leds.blue.high().or_else(|err| { + Err(LedError::::Blue(err)) + }); + Ok(States::BridgeOpen(Self { time_passed: 0 })) } else { - States::BridgeOpen(Self { - time_passed: self.time_passed + 1 - }) + Ok(States::BridgeOpen(Self { + time_passed: self.time_passed + 1, + })) } } - fn button_press(&self, _leds: &mut Leds) -> States { - States::BridgeOpen(Self { - time_passed: self.time_passed - }) + fn button_press( + &self, + _leds: &mut Leds, + ) -> Result> { + Ok(States::BridgeOpen(Self { + time_passed: self.time_passed, + })) } - fn button_release(&self, leds: &mut Leds) -> States { - States::Red(StateRed::new(leds)) + fn button_release( + &self, + leds: &mut Leds, + ) -> Result> { + Ok(States::Red(StateRed::new(leds)?)) } }