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,
RP: OutputPin, RT: Toggle<RP>,
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) {
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<RP::Error,GP::Error,OP::Error,BP::Error>>
{
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(())
}
}

View File

@@ -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<T: OutputPin>(led: &mut ToggleLed<T>, 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 {}
}
}

View File

@@ -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<OP>,
BP: OutputPin, BT: Toggle<BP>
> {
fn new(leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> Self;
fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States;
fn button_press(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States;
fn button_release(&self, leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States;
fn new(leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>)
-> Result<Self, LedError<RP::Error, GP::Error, OP::Error, BP::Error>>
where
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,
@@ -35,37 +41,49 @@ impl<'a,
GP: OutputPin, GT: Toggle<GP>,
OP: OutputPin, OT: Toggle<OP>,
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 {
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<Self, LedError<RP::Error, GP::Error, OP::Error, BP::Error>> {
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 {
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<RP::Error, GP::Error, OP::Error, BP::Error>> {
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<RP::Error, GP::Error, OP::Error, BP::Error>> {
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<RP>,
GP: OutputPin, GT: Toggle<GP>,
OP: OutputPin, OT: Toggle<OP>,
BP: OutputPin, BT: Toggle<BP>
> 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);
Self {
time_passed: 0
}
> State<RP, RT, GP, GT, OP, OT, BP, BT> for StateRed
{
fn new(
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::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 {
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<RP, RT, GP, GT, OP, OT, BP, BT>) -> States {
States::BridgeOpen(StateBridgeOpen::new(leds))
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>> {
Ok(States::BridgeOpen(StateBridgeOpen::new(leds)?))
}
fn button_release(&self, _leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States {
States::Red(Self {
time_passed: self.time_passed
})
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>> {
Ok(States::Red(Self {
time_passed: self.time_passed,
}))
}
}
@@ -120,32 +148,42 @@ impl<
GP: OutputPin, GT: Toggle<GP>,
OP: OutputPin, OT: Toggle<OP>,
BP: OutputPin, BT: Toggle<BP>
> 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);
Self {
time_passed: 0
}
> State<RP, RT, GP, GT, OP, OT, BP, BT> for StateGreen
{
fn new(
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::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 {
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<RP, RT, GP, GT, OP, OT, BP, BT>) -> States {
States::Green(Self {
time_passed: self.time_passed
})
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>> {
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 {
States::Green(Self {
time_passed: self.time_passed
})
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>> {
Ok(States::Green(Self {
time_passed: self.time_passed,
}))
}
}
@@ -159,20 +197,32 @@ impl<
GP: OutputPin, GT: Toggle<GP>,
OP: OutputPin, OT: Toggle<OP>,
BP: OutputPin, BT: Toggle<BP>
> 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);
Self {}
> State<RP, RT, GP, GT, OP, OT, BP, BT> for StateOrange
{
fn new(
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 {
States::Red(StateRed::new(leds))
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>> {
Ok(States::Red(StateRed::new(leds)?))
}
fn button_press(&self, _leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States {
States::Orange(Self {})
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>> {
Ok(States::Orange(Self {}))
}
fn button_release(&self, _leds: &mut Leds<RP, RT, GP, GT, OP, OT, BP, BT>) -> States {
States::Orange(Self {})
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>> {
Ok(States::Orange(Self {}))
}
}
@@ -188,37 +238,49 @@ impl<
GP: OutputPin, GT: Toggle<GP>,
OP: OutputPin, OT: Toggle<OP>,
BP: OutputPin, BT: Toggle<BP>
> 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);
Self {
time_passed: 0
}
> State<RP, RT, GP, GT, OP, OT, BP, BT> for StateBridgeOpen
{
fn new(
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::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 {
let _ = leds.blue.low();
States::BridgeOpen(Self {
time_passed: self.time_passed + 1
})
leds.blue.low().or_else(|err| {
Err(LedError::<RP::Error, GP::Error, OP::Error, BP::Error>::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::<RP::Error, GP::Error, OP::Error, BP::Error>::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<RP, RT, GP, GT, OP, OT, BP, BT>) -> States {
States::BridgeOpen(Self {
time_passed: self.time_passed
})
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>> {
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 {
States::Red(StateRed::new(leds))
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>> {
Ok(States::Red(StateRed::new(leds)?))
}
}