Files
RTS10_verslagen/report-3/rts10_rust/src/leds.rs
2025-10-30 18:49:31 +01:00

107 lines
2.9 KiB
Rust

use core::marker::PhantomData;
use embedded_hal::digital::{OutputPin, PinState};
pub trait Toggle<T: OutputPin> {
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 ToggleLed<'a, T: OutputPin> {
pin: &'a mut T,
state: PinState
}
impl<'a, T: OutputPin> ToggleLed<'a, T> {
pub fn new(pin: &'a mut T) -> Result<Self, T::Error> {
match pin.set_low() {
Ok(_) => Ok(Self { pin, state: PinState::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
}
}
#[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>,
OP: OutputPin, OT: Toggle<OP>,
BP: OutputPin, BT: Toggle<BP>
> {
pub red: &'a mut RT,
pub green: &'a mut GT,
pub orange: &'a mut OT,
pub blue: &'a mut BT,
// phantom data to convince rustc the generics RP, GP, OP and BP are used.
_r: PhantomData<RP>,
_g: PhantomData<GP>,
_o: PhantomData<OP>,
_b: PhantomData<BP>,
}
impl<'a,
RP: OutputPin, RT: Toggle<RP>,
GP: OutputPin, GT: Toggle<GP>,
OP: OutputPin, OT: Toggle<OP>,
BP: OutputPin, BT: Toggle<BP>
> Leds<'a, RP, RT, GP, GT, OP, OT, BP, BT> {
pub fn new(red: &'a mut RT, green: &'a mut GT, orange: &'a mut OT, blue: &'a mut BT) -> Self {
Self {
red,
green,
orange,
blue,
_r: PhantomData,
_g: PhantomData,
_o: PhantomData,
_b: PhantomData,
}
}
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(())
}
}