error checking

This commit is contained in:
2025-10-30 18:49:31 +01:00
parent a0547743e7
commit 7ff8a08fcb
3 changed files with 220 additions and 121 deletions

View File

@@ -49,6 +49,14 @@ impl<'a, T: OutputPin> Toggle<T> for ToggleLed<'a, T> {
} }
} }
#[derive(Debug)]
pub enum LedError<R, G, O, B> {
Red(R),
Green(G),
Orange(O),
Blue(B)
}
pub struct Leds<'a, pub struct Leds<'a,
RP: OutputPin, RT: Toggle<RP>, RP: OutputPin, RT: Toggle<RP>,
GP: OutputPin, GT: Toggle<GP>, GP: OutputPin, GT: Toggle<GP>,
@@ -86,10 +94,13 @@ impl<'a,
} }
} }
pub fn set_all(&mut self, red: PinState, green: PinState, orange: PinState, blue: PinState) { pub fn set_all(&mut self, red: PinState, green: PinState, orange: PinState, blue: PinState)
let _ = self.red.set(red); -> Result<(), LedError<RP::Error,GP::Error,OP::Error,BP::Error>>
let _ = self.orange.set(orange); {
let _ = self.green.set(green); self.red.set(red).or_else(|err| { Err(LedError::Red(err)) })?;
let _ = self.blue.set(blue); 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(())
} }
} }

View File

@@ -3,26 +3,40 @@
#![no_main] #![no_main]
#![no_std] #![no_std]
use embedded_hal::digital::PinState;
// Halt on panic // Halt on panic
use panic_halt as _; // panic handler use panic_halt as _; // panic handler
use cortex_m_rt::entry; use cortex_m_rt::entry;
use embedded_hal::digital::OutputPin;
use stm32f4xx_hal::timer::SysDelay;
use stm32f4xx_hal::{self as hal}; use stm32f4xx_hal::{self as hal};
use crate::hal::{pac, prelude::*}; use crate::hal::{pac, prelude::*};
mod leds; mod leds;
use crate::leds::{Leds, ToggleLed}; use crate::leds::{Leds, Toggle, ToggleLed};
mod state_machine; mod state_machine;
use crate::state_machine::StateMachine; use crate::state_machine::StateMachine;
fn error_blink<T: OutputPin>(led: &mut ToggleLed<T>, delay: &mut SysDelay) -> ! {
loop {
let _ = led.toggle();
delay.delay_ms(10_u32);
}
}
#[entry] #[entry]
fn main() -> ! { fn main() -> ! {
if let (Some(dp), Some(cp)) = ( if let (Some(dp), Some(cp)) = (
pac::Peripherals::take(), pac::Peripherals::take(),
cortex_m::peripheral::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 //GPIOD ophalen
let gpiod = dp.GPIOD.split(); let gpiod = dp.GPIOD.split();
//led pinnen uphalen //led pinnen uphalen
@@ -30,33 +44,45 @@ fn main() -> ! {
let mut red_pin = &mut gpiod.pd14.into_push_pull_output(); let mut red_pin = &mut gpiod.pd14.into_push_pull_output();
let mut orange_pin = &mut gpiod.pd13.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 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 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); let mut leds = Leds::new(&mut red, &mut green, &mut orange, &mut blue);
//user knop //user knop
let gpioa = dp.GPIOA.split(); let gpioa = dp.GPIOA.split();
let button = &mut gpioa.pa0.into_floating_input(); let button = &mut gpioa.pa0.into_floating_input();
//leds struct en state machine maken //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(); let mut button_high = button.is_high();
loop { loop {
let _ = state_machine.second_passed(); if let Err(_) = state_machine.second_passed() {
error_blink(&mut blue, &mut delay);
}
for _ in 0..99 { for _ in 0..99 {
if button_high != button.is_high() { if button_high != button.is_high() {
button_high = button.is_high(); button_high = button.is_high();
if button_high { if button_high {
state_machine.button_press(); if let Err(_) = state_machine.button_press() {
error_blink(&mut blue, &mut delay);
}
} else { } else {
state_machine.button_release(); if let Err(_) = state_machine.button_release() {
error_blink(&mut blue, &mut delay);
}
} }
} }
delay.delay_ms(10_u32); delay.delay_ms(10_u32);

View File

@@ -1,6 +1,6 @@
use embedded_hal::digital::{OutputPin, PinState}; use embedded_hal::digital::{OutputPin, PinState};
use crate::leds::{Leds, Toggle}; use crate::leds::{LedError, Leds, Toggle};
enum States { enum States {
Red(StateRed), Red(StateRed),
@@ -15,10 +15,16 @@ trait State<
OP: OutputPin, OT: Toggle<OP>, OP: OutputPin, OT: Toggle<OP>,
BP: OutputPin, BT: Toggle<BP> BP: OutputPin, BT: Toggle<BP>
> { > {
fn new(leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> Self; fn new(leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>)
fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States; -> Result<Self, LedError<RP::Error, GP::Error, OP::Error, BP::Error>>
fn button_press(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States; where
fn button_release(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States; Self: Sized;
fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>)
-> Result<States, LedError<RP::Error, GP::Error, OP::Error, BP::Error>>;
fn button_press(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>)
-> Result<States, LedError<RP::Error, GP::Error, OP::Error, BP::Error>>;
fn button_release(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>)
-> Result<States, LedError<RP::Error, GP::Error, OP::Error, BP::Error>>;
} }
pub struct StateMachine<'a, pub struct StateMachine<'a,
@@ -37,35 +43,47 @@ impl<'a,
BP: OutputPin, BT: Toggle<BP> BP: OutputPin, BT: Toggle<BP>
> 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 { pub fn new(
Self { leds: &'a mut Leds<'a, RP, RT, GP, GT, OP, OT, BP, BT>,
state: States::Red(StateRed::new(leds)), ) -> Result<Self, LedError<RP::Error, GP::Error, OP::Error, BP::Error>> {
leds 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<RP::Error, GP::Error, OP::Error, BP::Error>> {
self.state = match &self.state { self.state = match &self.state {
States::Red(state) => state.second_passed(self.leds), States::Red(state) => state.second_passed(self.leds)?,
States::Orange(state) => state.second_passed(self.leds), States::Orange(state) => state.second_passed(self.leds)?,
States::Green(state) => state.second_passed(self.leds), States::Green(state) => state.second_passed(self.leds)?,
States::BridgeOpen(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<RP::Error, GP::Error, OP::Error, BP::Error>> {
self.state = match &self.state { self.state = match &self.state {
States::Red(state) => state.button_press(self.leds), States::Red(state) => state.button_press(self.leds)?,
States::Orange(state) => state.button_press(self.leds), States::Orange(state) => state.button_press(self.leds)?,
States::Green(state) => state.button_press(self.leds), States::Green(state) => state.button_press(self.leds)?,
States::BridgeOpen(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<RP::Error, GP::Error, OP::Error, BP::Error>> {
self.state = match &self.state { self.state = match &self.state {
States::Red(state) => state.button_release(self.leds), States::Red(state) => state.button_release(self.leds)?,
States::Orange(state) => state.button_release(self.leds), States::Orange(state) => state.button_release(self.leds)?,
States::Green(state) => state.button_release(self.leds), States::Green(state) => state.button_release(self.leds)?,
States::BridgeOpen(state) => state.button_release(self.leds), States::BridgeOpen(state) => state.button_release(self.leds)?,
} };
Ok(())
} }
} }
@@ -74,37 +92,47 @@ impl<'a,
// #################################################### // ####################################################
struct StateRed { struct StateRed {
time_passed: u32 time_passed: u32,
} }
impl< impl<
RP: OutputPin, RT: Toggle<RP>, RP: OutputPin, RT: Toggle<RP>,
GP: OutputPin, GT: Toggle<GP>, GP: OutputPin, GT: Toggle<GP>,
OP: OutputPin, OT: Toggle<OP>, OP: OutputPin, OT: Toggle<OP>,
BP: OutputPin, BT: Toggle<BP> BP: OutputPin, BT: Toggle<BP>
> State<RP, RT, GP, GT, OP, OT, BP, BT> for StateRed { > State<RP, RT, GP, GT, OP, OT, BP, BT> for StateRed
fn new(leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> Self { {
leds.set_all(PinState::High, PinState::Low, PinState::Low, PinState::Low); fn new(
Self { leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>,
time_passed: 0 ) -> Result<Self, LedError<RP::Error, GP::Error, OP::Error, BP::Error>> {
} leds.set_all(PinState::High, PinState::Low, PinState::Low, PinState::Low)?;
Ok(Self { time_passed: 0 })
} }
fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States { fn second_passed(
&self,
leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>,
) -> Result<States, LedError<RP::Error, GP::Error, OP::Error, BP::Error>> {
if self.time_passed + 1 >= 4 { if self.time_passed + 1 >= 4 {
States::Green(StateGreen::new(leds)) Ok(States::Green(StateGreen::new(leds)?))
} else { } else {
States::Red(Self { Ok(States::Red(Self {
time_passed: self.time_passed + 1 time_passed: self.time_passed + 1,
}) }))
} }
} }
fn button_press(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States { fn button_press(
States::BridgeOpen(StateBridgeOpen::new(leds)) &self,
leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>,
) -> Result<States, LedError<RP::Error, GP::Error, OP::Error, BP::Error>> {
Ok(States::BridgeOpen(StateBridgeOpen::new(leds)?))
} }
fn button_release(&self, _leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States { fn button_release(
States::Red(Self { &self,
time_passed: self.time_passed _leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>,
}) ) -> Result<States, LedError<RP::Error, GP::Error, OP::Error, BP::Error>> {
Ok(States::Red(Self {
time_passed: self.time_passed,
}))
} }
} }
@@ -120,32 +148,42 @@ impl<
GP: OutputPin, GT: Toggle<GP>, GP: OutputPin, GT: Toggle<GP>,
OP: OutputPin, OT: Toggle<OP>, OP: OutputPin, OT: Toggle<OP>,
BP: OutputPin, BT: Toggle<BP> BP: OutputPin, BT: Toggle<BP>
> State<RP, RT, GP, GT, OP, OT, BP, BT> for StateGreen { > State<RP, RT, GP, GT, OP, OT, BP, BT> for StateGreen
fn new(leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> Self { {
leds.set_all(PinState::Low, PinState::High, PinState::Low, PinState::Low); fn new(
Self { leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>,
time_passed: 0 ) -> Result<Self, LedError<RP::Error, GP::Error, OP::Error, BP::Error>> {
} leds.set_all(PinState::Low, PinState::High, PinState::Low, PinState::Low)?;
Ok(Self { time_passed: 0 })
} }
fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States { fn second_passed(
&self,
leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>,
) -> Result<States, LedError<RP::Error, GP::Error, OP::Error, BP::Error>> {
if self.time_passed + 1 >= 3 { if self.time_passed + 1 >= 3 {
States::Orange(StateOrange::new(leds)) Ok(States::Orange(StateOrange::new(leds)?))
} else { } else {
States::Green(Self { Ok(States::Green(Self {
time_passed: self.time_passed + 1 time_passed: self.time_passed + 1,
}) }))
} }
} }
fn button_press(&self, _leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States { fn button_press(
States::Green(Self { &self,
time_passed: self.time_passed _leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>,
}) ) -> Result<States, LedError<RP::Error, GP::Error, OP::Error, BP::Error>> {
Ok(States::Green(Self {
time_passed: self.time_passed,
}))
} }
fn button_release(&self, _leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States { fn button_release(
States::Green(Self { &self,
time_passed: self.time_passed _leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>,
}) ) -> Result<States, LedError<RP::Error, GP::Error, OP::Error, BP::Error>> {
Ok(States::Green(Self {
time_passed: self.time_passed,
}))
} }
} }
@@ -159,20 +197,32 @@ impl<
GP: OutputPin, GT: Toggle<GP>, GP: OutputPin, GT: Toggle<GP>,
OP: OutputPin, OT: Toggle<OP>, OP: OutputPin, OT: Toggle<OP>,
BP: OutputPin, BT: Toggle<BP> BP: OutputPin, BT: Toggle<BP>
> State<RP, RT, GP, GT, OP, OT, BP, BT> for StateOrange { > State<RP, RT, GP, GT, OP, OT, BP, BT> for StateOrange
fn new(leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> Self { {
leds.set_all(PinState::Low, PinState::Low, PinState::High, PinState::Low); fn new(
Self {} leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>,
) -> Result<Self, LedError<RP::Error, GP::Error, OP::Error, BP::Error>> {
leds.set_all(PinState::Low, PinState::Low, PinState::High, PinState::Low)?;
Ok(Self {})
} }
fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States { fn second_passed(
States::Red(StateRed::new(leds)) &self,
leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>,
) -> Result<States, LedError<RP::Error, GP::Error, OP::Error, BP::Error>> {
Ok(States::Red(StateRed::new(leds)?))
} }
fn button_press(&self, _leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States { fn button_press(
States::Orange(Self {}) &self,
_leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>,
) -> Result<States, LedError<RP::Error, GP::Error, OP::Error, BP::Error>> {
Ok(States::Orange(Self {}))
} }
fn button_release(&self, _leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States { fn button_release(
States::Orange(Self {}) &self,
_leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>,
) -> Result<States, LedError<RP::Error, GP::Error, OP::Error, BP::Error>> {
Ok(States::Orange(Self {}))
} }
} }
@@ -188,37 +238,49 @@ impl<
GP: OutputPin, GT: Toggle<GP>, GP: OutputPin, GT: Toggle<GP>,
OP: OutputPin, OT: Toggle<OP>, OP: OutputPin, OT: Toggle<OP>,
BP: OutputPin, BT: Toggle<BP> BP: OutputPin, BT: Toggle<BP>
> State<RP, RT, GP, GT, OP, OT, BP, BT> for StateBridgeOpen { > State<RP, RT, GP, GT, OP, OT, BP, BT> for StateBridgeOpen
fn new(leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> Self { {
leds.set_all(PinState::Low, PinState::Low, PinState::Low, PinState::High); fn new(
Self { leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>,
time_passed: 0 ) -> Result<Self, LedError<RP::Error, GP::Error, OP::Error, BP::Error>> {
} leds.set_all(PinState::Low, PinState::Low, PinState::Low, PinState::High)?;
Ok(Self { time_passed: 0 })
} }
fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States { fn second_passed(
&self,
leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>,
) -> Result<States, LedError<RP::Error, GP::Error, OP::Error, BP::Error>> {
if self.time_passed + 1 == 2 { if self.time_passed + 1 == 2 {
let _ = leds.blue.low(); leds.blue.low().or_else(|err| {
States::BridgeOpen(Self { Err(LedError::<RP::Error, GP::Error, OP::Error, BP::Error>::Blue(err))
time_passed: self.time_passed + 1 });
}) Ok(States::BridgeOpen(Self {
time_passed: self.time_passed + 1,
}))
} else if self.time_passed + 1 >= 3 { } else if self.time_passed + 1 >= 3 {
let _ = leds.blue.high(); leds.blue.high().or_else(|err| {
States::BridgeOpen(Self { Err(LedError::<RP::Error, GP::Error, OP::Error, BP::Error>::Blue(err))
time_passed: 0 });
}) Ok(States::BridgeOpen(Self { time_passed: 0 }))
} else { } else {
States::BridgeOpen(Self { Ok(States::BridgeOpen(Self {
time_passed: self.time_passed + 1 time_passed: self.time_passed + 1,
}) }))
} }
} }
fn button_press(&self, _leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States { fn button_press(
States::BridgeOpen(Self { &self,
time_passed: self.time_passed _leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>,
}) ) -> Result<States, LedError<RP::Error, GP::Error, OP::Error, BP::Error>> {
Ok(States::BridgeOpen(Self {
time_passed: self.time_passed,
}))
} }
fn button_release(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States { fn button_release(
States::Red(StateRed::new(leds)) &self,
leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>,
) -> Result<States, LedError<RP::Error, GP::Error, OP::Error, BP::Error>> {
Ok(States::Red(StateRed::new(leds)?))
} }
} }