make assignment 8.2 work

This commit is contained in:
2025-10-29 15:44:08 +01:00
parent 8ddada6531
commit a04efb87e5
3 changed files with 163 additions and 143 deletions

View File

@@ -1,96 +1,86 @@
use embedded_hal::digital::{ErrorType as DigitalErrorType, OutputPin, PinState}; use embedded_hal::digital::{OutputPin, PinState};
pub trait UpdateLeds<Red: OutputPin, Green: OutputPin, Blue: OutputPin> { pub trait Toggle<T: OutputPin> {
fn red_toggle(&mut self) -> Result<(), <Red as DigitalErrorType>::Error>; fn toggle(&mut self) -> Result<(), T::Error>;
fn red_on(&mut self) -> Result<(), <Red as DigitalErrorType>::Error>; fn set(&mut self, state: PinState) -> Result<(), T::Error>;
fn red_off(&mut self) -> Result<(), <Red as DigitalErrorType>::Error>; fn get(&self) -> PinState;
fn green_toggle(&mut self) -> Result<(), <Green as DigitalErrorType>::Error> ;
fn green_on(&mut self) -> Result<(), <Green as DigitalErrorType>::Error>; fn high(&mut self) -> Result<(), T::Error> {
fn green_off(&mut self) -> Result<(), <Green as DigitalErrorType>::Error>; self.set(PinState::High)
fn blue_toggle(&mut self) -> Result<(), <Blue as DigitalErrorType>::Error>; }
fn blue_on(&mut self) -> Result<(), <Blue as DigitalErrorType>::Error>; fn low(&mut self) -> Result<(), T::Error> {
fn blue_off(&mut self) -> Result<(), <Blue as DigitalErrorType>::Error>; self.set(PinState::Low)
}
} }
pub struct Leds<'a, Red: OutputPin, Green: OutputPin, Blue: OutputPin> {
red: &'a mut Red, pub struct ToggleLed<'a, T: OutputPin> {
red_state: PinState, pin: &'a mut T,
green: &'a mut Green, state: PinState
green_state: PinState,
blue: &'a mut Blue,
blue_state: PinState,
} }
impl<'a, Red: OutputPin, Green: OutputPin, Blue: OutputPin> Leds<'a, Red, Green, Blue> { impl<'a, T: OutputPin> ToggleLed<'a, T> {
pub fn new(red: &'a mut Red, green: &'a mut Green, blue: &'a mut Blue) -> Self { pub fn new(pin: &'a mut T) -> Result<Self, T::Error> {
let _ = red.set_low(); match pin.set_low() {
let _ = green.set_low(); Ok(_) => Ok(Self { pin, state: PinState::Low }),
let _ = blue.set_low(); Err(e) => Err(e)
}
}
}
impl<'a, T: OutputPin> Toggle<T> 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<RP>,
GP: OutputPin, GT: Toggle<GP>,
BP: OutputPin, BT: Toggle<BP>
> {
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<RP>,
_g: Option<GP>,
_b: Option<BP>,
}
impl<'a,
RP: OutputPin, RT: Toggle<RP>,
GP: OutputPin, GT: Toggle<GP>,
BP: OutputPin, BT: Toggle<BP>
> 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 { Self {
red, red,
red_state: PinState::Low,
green, green,
green_state: PinState::Low,
blue, blue,
blue_state: PinState::Low,
_r: None,
_g: None,
_b: None,
} }
} }
}
impl<'a, Red: OutputPin, Green: OutputPin, Blue: OutputPin> pub fn set_all(&mut self, red: PinState, green: PinState, blue: PinState) {
UpdateLeds<Red, Green, Blue> let _ = self.red.set(red);
for Leds<'a, Red, Green, Blue> { let _ = self.blue.set(blue);
fn red_toggle(&mut self) -> Result<(), <Red as DigitalErrorType>::Error> { let _ = self.green.set(green);
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<(), <Red as DigitalErrorType>::Error> {
self.red_state = PinState::High;
self.red.set_state(self.red_state)
}
fn red_off(&mut self) -> Result<(), <Red as DigitalErrorType>::Error> {
self.red_state = PinState::Low;
self.red.set_state(self.red_state)
}
fn green_toggle(&mut self) -> Result<(), <Green as DigitalErrorType>::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<(), <Green as DigitalErrorType>::Error> {
self.green_state = PinState::High;
self.green.set_state(self.green_state)
}
fn green_off(&mut self) -> Result<(), <Green as DigitalErrorType>::Error> {
self.green_state = PinState::Low;
self.green.set_state(self.green_state)
}
fn blue_toggle(&mut self) -> Result<(), <Blue as DigitalErrorType>::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<(), <Blue as DigitalErrorType>::Error> {
self.blue_state = PinState::High;
self.blue.set_state(self.blue_state)
}
fn blue_off(&mut self) -> Result<(), <Blue as DigitalErrorType>::Error> {
self.blue_state = PinState::Low;
self.blue.set_state(self.blue_state)
} }
} }

View File

@@ -10,10 +10,9 @@ use cortex_m_rt::entry;
use stm32f4xx_hal::{self as hal}; use stm32f4xx_hal::{self as hal};
use crate::hal::{pac, prelude::*}; use crate::hal::{pac, prelude::*};
use cortex_m_semihosting::hprintln;
mod leds; mod leds;
use crate::leds::{UpdateLeds, Leds}; use crate::leds::{Leds, ToggleLed};
mod state_machine; mod state_machine;
use crate::state_machine::StateMachine; use crate::state_machine::StateMachine;
@@ -25,11 +24,15 @@ fn main() -> ! {
) { ) {
//GPIOD ophalen //GPIOD ophalen
let gpiod = dp.GPIOD.split(); let gpiod = dp.GPIOD.split();
//pd12 is pin type //led pinnen uphalen
let mut green = gpiod.pd12.into_push_pull_output(); let mut green_pin = &mut gpiod.pd12.into_push_pull_output();
let mut red = gpiod.pd14.into_push_pull_output(); let mut red_pin = &mut gpiod.pd14.into_push_pull_output();
let mut blue = 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 blue = ToggleLed::new(&mut blue_pin).expect("faild to set blue led");
let mut leds = Leds::new(&mut red, &mut green, &mut blue); 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); let mut state_machine = StateMachine::new(&mut leds);
//Klok instellen //Klok instellen
@@ -39,17 +42,9 @@ fn main() -> ! {
// Create a delay abstraction based on SysTick // Create a delay abstraction based on SysTick
let mut delay = cp.SYST.delay(&clocks); let mut delay = cp.SYST.delay(&clocks);
let mut status:bool = false;
loop { loop {
// On for 1s, off for 1s. let _ = state_machine.second_passed();
let _ = leds.red_toggle();
let _ = leds.green_toggle();
let _ = leds.blue_toggle();
status ^= true;
delay.delay_ms(1000_u32); delay.delay_ms(1000_u32);
//dit verschijnt in een van de open terminals in vscode
hprintln!("Led {:?}", status.then(|| "aan!").unwrap_or("uit!"));
} }
} }

View File

@@ -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 { enum States {
Red(StateRed), Red(StateRed),
@@ -8,23 +8,65 @@ enum States {
Green(StateGreen), Green(StateGreen),
} }
trait State { trait State<
fn new() -> Self; RP: OutputPin, RT: Toggle<RP>,
fn second_passed(&self) -> States; GP: OutputPin, GT: Toggle<GP>,
BP: OutputPin, BT: Toggle<BP>
> {
fn new(leds: &mut Leds<RP, RT, GP, GT, BP, BT>) -> Self;
fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, BP, BT>) -> States;
} }
pub struct StateMachine<'a,
RP: OutputPin, RT: Toggle<RP>,
GP: OutputPin, GT: Toggle<GP>,
BP: OutputPin, BT: Toggle<BP>
> {
state: States,
leds: &'a mut Leds<'a, RP, RT, GP, GT, BP, BT>,
}
impl<'a,
RP: OutputPin, RT: Toggle<RP>,
GP: OutputPin, GT: Toggle<GP>,
BP: OutputPin, BT: Toggle<BP>
> 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 { struct StateRed {
time_passed: u32 time_passed: u32
} }
impl State for StateRed { impl<
fn new() -> Self { RP: OutputPin, RT: Toggle<RP>,
GP: OutputPin, GT: Toggle<GP>,
BP: OutputPin, BT: Toggle<BP>
> State<RP, RT, GP, GT, BP, BT> for StateRed {
fn new(leds: &mut Leds<RP, RT, GP, GT, BP, BT>) -> Self {
leds.set_all(PinState::High, PinState::Low, PinState::Low);
Self { Self {
time_passed: 0 time_passed: 0
} }
} }
fn second_passed(&self) -> States { fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, BP, BT>) -> States {
if self.time_passed + 1 >= 4 { if self.time_passed + 1 >= 4 {
States::Green(StateGreen::new()) States::Green(StateGreen::new(leds))
} else { } else {
States::Red(Self { States::Red(Self {
time_passed: self.time_passed + 1 time_passed: self.time_passed + 1
@@ -33,18 +75,27 @@ impl State for StateRed {
} }
} }
// ####################################################
// ## GREEN ###########################################
// ####################################################
struct StateGreen { struct StateGreen {
time_passed: u32 time_passed: u32
} }
impl State for StateGreen { impl<
fn new() -> Self { RP: OutputPin, RT: Toggle<RP>,
GP: OutputPin, GT: Toggle<GP>,
BP: OutputPin, BT: Toggle<BP>
> State<RP, RT, GP, GT, BP, BT> for StateGreen {
fn new(leds: &mut Leds<RP, RT, GP, GT, BP, BT>) -> Self {
leds.set_all(PinState::Low, PinState::High, PinState::Low);
Self { Self {
time_passed: 0 time_passed: 0
} }
} }
fn second_passed(&self) -> States { fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, BP, BT>) -> States {
if self.time_passed + 1 >= 3 { if self.time_passed + 1 >= 3 {
States::Blue(StateBlue::new()) States::Blue(StateBlue::new(leds))
} else { } else {
States::Green(Self { States::Green(Self {
time_passed: self.time_passed + 1 time_passed: self.time_passed + 1
@@ -53,37 +104,21 @@ impl State for StateGreen {
} }
} }
// ####################################################
// ## BLUE ############################################
// ####################################################
struct StateBlue {} struct StateBlue {}
impl State for StateBlue { impl<
fn new() -> Self { RP: OutputPin, RT: Toggle<RP>,
GP: OutputPin, GT: Toggle<GP>,
BP: OutputPin, BT: Toggle<BP>
> State<RP, RT, GP, GT, BP, BT> for StateBlue {
fn new(leds: &mut Leds<RP, RT, GP, GT, BP, BT>) -> Self {
leds.set_all(PinState::Low, PinState::Low, PinState::High);
Self {} Self {}
} }
fn second_passed(&self) -> States { fn second_passed(&self, leds: &mut Leds<RP, RT, GP, GT, BP, BT>) -> States {
States::Red(StateRed::new()) States::Red(StateRed::new(leds))
}
}
// trait Leds<Red: OutputPin, Green: OutputPin, Blue: OutputPin>: UpdateLeds<Red, Green, Blue>;
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(),
}
} }
} }