From a04efb87e5672a2d1d8305d0ce4ee5e0c3627cf3 Mon Sep 17 00:00:00 2001 From: LailaTheElf Date: Wed, 29 Oct 2025 15:44:08 +0100 Subject: [PATCH] make assignment 8.2 work --- report-3/rts10_rust/src/leds.rs | 162 +++++++++++------------ report-3/rts10_rust/src/main.rs | 25 ++-- report-3/rts10_rust/src/state_machine.rs | 119 +++++++++++------ 3 files changed, 163 insertions(+), 143 deletions(-) diff --git a/report-3/rts10_rust/src/leds.rs b/report-3/rts10_rust/src/leds.rs index 8ea991f..ef11537 100644 --- a/report-3/rts10_rust/src/leds.rs +++ b/report-3/rts10_rust/src/leds.rs @@ -1,96 +1,86 @@ -use embedded_hal::digital::{ErrorType as DigitalErrorType, OutputPin, PinState}; +use embedded_hal::digital::{OutputPin, PinState}; -pub trait UpdateLeds { - fn red_toggle(&mut self) -> Result<(), ::Error>; - fn red_on(&mut self) -> Result<(), ::Error>; - fn red_off(&mut self) -> Result<(), ::Error>; - fn green_toggle(&mut self) -> Result<(), ::Error> ; - fn green_on(&mut self) -> Result<(), ::Error>; - fn green_off(&mut self) -> Result<(), ::Error>; - fn blue_toggle(&mut self) -> Result<(), ::Error>; - fn blue_on(&mut self) -> Result<(), ::Error>; - fn blue_off(&mut self) -> Result<(), ::Error>; +pub trait Toggle { + fn toggle(&mut self) -> Result<(), T::Error>; + fn set(&mut self, state: PinState) -> Result<(), T::Error>; + fn get(&self) -> PinState; + + fn high(&mut self) -> Result<(), T::Error> { + self.set(PinState::High) + } + fn low(&mut self) -> Result<(), T::Error> { + self.set(PinState::Low) + } } -pub struct Leds<'a, Red: OutputPin, Green: OutputPin, Blue: OutputPin> { - red: &'a mut Red, - red_state: PinState, - green: &'a mut Green, - green_state: PinState, - blue: &'a mut Blue, - blue_state: PinState, + +pub struct ToggleLed<'a, T: OutputPin> { + pin: &'a mut T, + state: PinState } -impl<'a, Red: OutputPin, Green: OutputPin, Blue: OutputPin> Leds<'a, Red, Green, Blue> { - pub fn new(red: &'a mut Red, green: &'a mut Green, blue: &'a mut Blue) -> Self { - let _ = red.set_low(); - let _ = green.set_low(); - let _ = blue.set_low(); +impl<'a, T: OutputPin> ToggleLed<'a, T> { + pub fn new(pin: &'a mut T) -> Result { + match pin.set_low() { + Ok(_) => Ok(Self { pin, state: PinState::Low }), + Err(e) => Err(e) + } + } +} +impl<'a, T: OutputPin> Toggle for ToggleLed<'a, T> { + fn toggle(&mut self) -> Result<(), T::Error> { + if self.state == PinState::High { + self.state = PinState::Low; + } else { + self.state = PinState::Low; + } + self.pin.set_state(self.state) + } + fn set(&mut self, state: PinState) -> Result<(), T::Error> { + if state != self.state { + self.state = state; + self.pin.set_state(self.state) + } else { + Ok(()) + } + } + fn get(&self) -> PinState { + self.state + } +} + +pub struct Leds<'a, + RP: OutputPin, RT: Toggle, + GP: OutputPin, GT: Toggle, + BP: OutputPin, BT: Toggle +> { + pub red: &'a mut RT, + pub green: &'a mut GT, + pub blue: &'a mut BT, + + // phantom data to convince rustc the generics RP, GP and BP are used. + _r: Option, + _g: Option, + _b: Option, +} +impl<'a, + RP: OutputPin, RT: Toggle, + GP: OutputPin, GT: Toggle, + BP: OutputPin, BT: Toggle +> Leds<'a, RP, RT, GP, GT, BP, BT> { + pub fn new(red: &'a mut RT, green: &'a mut GT, blue: &'a mut BT) -> Self { Self { red, - red_state: PinState::Low, green, - green_state: PinState::Low, blue, - blue_state: PinState::Low, + + _r: None, + _g: None, + _b: None, } - } -} -impl<'a, Red: OutputPin, Green: OutputPin, Blue: OutputPin> - UpdateLeds -for Leds<'a, Red, Green, Blue> { - fn red_toggle(&mut self) -> Result<(), ::Error> { - if self.red_state == PinState::Low { - self.red_state = PinState::High; - } else { - self.red_state = PinState::Low; - } - self.red.set_state(self.red_state) - } - - fn red_on(&mut self) -> Result<(), ::Error> { - self.red_state = PinState::High; - self.red.set_state(self.red_state) - } - - fn red_off(&mut self) -> Result<(), ::Error> { - self.red_state = PinState::Low; - self.red.set_state(self.red_state) - } - - fn green_toggle(&mut self) -> Result<(), ::Error> { - if self.green_state == PinState::Low { - self.green_state = PinState::High; - } else { - self.green_state = PinState::Low; - } - self.green.set_state(self.green_state) - } - - fn green_on(&mut self) -> Result<(), ::Error> { - self.green_state = PinState::High; - self.green.set_state(self.green_state) - } - - fn green_off(&mut self) -> Result<(), ::Error> { - self.green_state = PinState::Low; - self.green.set_state(self.green_state) - } - - fn blue_toggle(&mut self) -> Result<(), ::Error> { - if self.blue_state == PinState::Low { - self.blue_state = PinState::High; - } else { - self.blue_state = PinState::Low; - } - self.blue.set_state(self.blue_state) - } - - fn blue_on(&mut self) -> Result<(), ::Error> { - self.blue_state = PinState::High; - self.blue.set_state(self.blue_state) - } - - fn blue_off(&mut self) -> Result<(), ::Error> { - self.blue_state = PinState::Low; - self.blue.set_state(self.blue_state) + } + + pub fn set_all(&mut self, red: PinState, green: PinState, blue: PinState) { + let _ = self.red.set(red); + let _ = self.blue.set(blue); + let _ = self.green.set(green); } } diff --git a/report-3/rts10_rust/src/main.rs b/report-3/rts10_rust/src/main.rs index da7f84c..e92b8d1 100644 --- a/report-3/rts10_rust/src/main.rs +++ b/report-3/rts10_rust/src/main.rs @@ -10,10 +10,9 @@ use cortex_m_rt::entry; use stm32f4xx_hal::{self as hal}; use crate::hal::{pac, prelude::*}; -use cortex_m_semihosting::hprintln; mod leds; -use crate::leds::{UpdateLeds, Leds}; +use crate::leds::{Leds, ToggleLed}; mod state_machine; use crate::state_machine::StateMachine; @@ -25,11 +24,15 @@ fn main() -> ! { ) { //GPIOD ophalen let gpiod = dp.GPIOD.split(); - //pd12 is pin type - let mut green = gpiod.pd12.into_push_pull_output(); - let mut red = gpiod.pd14.into_push_pull_output(); - let mut blue = gpiod.pd15.into_push_pull_output(); + //led pinnen uphalen + let mut green_pin = &mut gpiod.pd12.into_push_pull_output(); + let mut red_pin = &mut gpiod.pd14.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 blue = ToggleLed::new(&mut blue_pin).expect("faild to set blue led"); let mut leds = Leds::new(&mut red, &mut green, &mut blue); + //leds struct en state machine maken let mut state_machine = StateMachine::new(&mut leds); //Klok instellen @@ -39,17 +42,9 @@ fn main() -> ! { // Create a delay abstraction based on SysTick let mut delay = cp.SYST.delay(&clocks); - let mut status:bool = false; loop { - // On for 1s, off for 1s. - let _ = leds.red_toggle(); - let _ = leds.green_toggle(); - let _ = leds.blue_toggle(); - status ^= true; + let _ = state_machine.second_passed(); delay.delay_ms(1000_u32); - - //dit verschijnt in een van de open terminals in vscode - hprintln!("Led {:?}", status.then(|| "aan!").unwrap_or("uit!")); } } diff --git a/report-3/rts10_rust/src/state_machine.rs b/report-3/rts10_rust/src/state_machine.rs index 72294ab..dd12658 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; +use embedded_hal::digital::{OutputPin, PinState}; -use crate::leds::UpdateLeds; +use crate::leds::{Leds, Toggle}; enum States { Red(StateRed), @@ -8,23 +8,65 @@ enum States { Green(StateGreen), } -trait State { - fn new() -> Self; - fn second_passed(&self) -> States; +trait State< + RP: OutputPin, RT: Toggle, + GP: OutputPin, GT: Toggle, + BP: OutputPin, BT: Toggle +> { + fn new(leds: &mut Leds) -> Self; + fn second_passed(&self, leds: &mut Leds) -> States; } +pub struct StateMachine<'a, + RP: OutputPin, RT: Toggle, + GP: OutputPin, GT: Toggle, + BP: OutputPin, BT: Toggle +> { + state: States, + leds: &'a mut Leds<'a, RP, RT, GP, GT, BP, BT>, +} +impl<'a, + RP: OutputPin, RT: Toggle, + GP: OutputPin, GT: Toggle, + BP: OutputPin, BT: Toggle +> StateMachine<'a, RP, RT, GP, GT, BP, BT> +{ + pub fn new(leds: &'a mut Leds<'a, RP, RT, GP, GT, BP, BT>) -> Self { + Self { + state: States::Red(StateRed::new(leds)), + leds, + } + } + pub fn second_passed(&mut self) { + self.state = match &self.state { + States::Red(state) => state.second_passed(self.leds), + States::Blue(state) => state.second_passed(self.leds), + States::Green(state) => state.second_passed(self.leds), + } + } +} + +// #################################################### +// ## RED ############################################# +// #################################################### + struct StateRed { time_passed: u32 } -impl State for StateRed { - fn new() -> Self { +impl< + RP: OutputPin, RT: Toggle, + GP: OutputPin, GT: Toggle, + BP: OutputPin, BT: Toggle +> State for StateRed { + fn new(leds: &mut Leds) -> Self { + leds.set_all(PinState::High, PinState::Low, PinState::Low); Self { time_passed: 0 } } - fn second_passed(&self) -> States { + fn second_passed(&self, leds: &mut Leds) -> States { if self.time_passed + 1 >= 4 { - States::Green(StateGreen::new()) + States::Green(StateGreen::new(leds)) } else { States::Red(Self { time_passed: self.time_passed + 1 @@ -33,18 +75,27 @@ impl State for StateRed { } } +// #################################################### +// ## GREEN ########################################### +// #################################################### + struct StateGreen { time_passed: u32 } -impl State for StateGreen { - fn new() -> Self { +impl< + RP: OutputPin, RT: Toggle, + GP: OutputPin, GT: Toggle, + BP: OutputPin, BT: Toggle +> State for StateGreen { + fn new(leds: &mut Leds) -> Self { + leds.set_all(PinState::Low, PinState::High, PinState::Low); Self { time_passed: 0 } } - fn second_passed(&self) -> States { + fn second_passed(&self, leds: &mut Leds) -> States { if self.time_passed + 1 >= 3 { - States::Blue(StateBlue::new()) + States::Blue(StateBlue::new(leds)) } else { States::Green(Self { time_passed: self.time_passed + 1 @@ -53,37 +104,21 @@ impl State for StateGreen { } } +// #################################################### +// ## BLUE ############################################ +// #################################################### + struct StateBlue {} -impl State for StateBlue { - fn new() -> Self { +impl< + RP: OutputPin, RT: Toggle, + GP: OutputPin, GT: Toggle, + BP: OutputPin, BT: Toggle +> State for StateBlue { + fn new(leds: &mut Leds) -> Self { + leds.set_all(PinState::Low, PinState::Low, PinState::High); Self {} } - fn second_passed(&self) -> States { - States::Red(StateRed::new()) - } -} - -// trait Leds: UpdateLeds; - -pub struct StateMachine<'a, T: UpdateLeds<_, _, _>> -{ - state: States, - leds: &'a mut T, -} -impl<'a, T: UpdateLeds<_, _, _>> - StateMachine<'a, T> -{ - pub fn new(leds: &'a mut T) -> Self { - Self { - state: States::Red(StateRed::new()), - leds - } - } - pub fn second_passed(&mut self) { - self.state = match &self.state { - States::Red(state) => state.second_passed(), - States::Blue(state) => state.second_passed(), - States::Green(state) => state.second_passed(), - } + fn second_passed(&self, leds: &mut Leds) -> States { + States::Red(StateRed::new(leds)) } }