use super::Gpio;
use crate::error::Error;
pub trait PinConfig {
fn update_pin_map(&self, pin: u8, gpio: &Gpio) -> Result<(u16, u16), Error>;
}
#[derive(Debug, Copy, Clone)]
pub enum Mode {
Input = 0,
Output = 1,
}
impl PinConfig for Mode {
fn update_pin_map(&self, pin: u8, gpio: &Gpio) -> Result<(u16, u16), Error> {
let pin_map = &mut *gpio.mode_pin_map.lock()?;
Ok((set_pin_config(pin, *self as u16, pin_map), 0))
}
}
#[derive(Debug, Copy, Clone)]
pub enum State {
Off = 0,
On = 1,
}
impl PinConfig for State {
fn update_pin_map(&self, pin: u8, gpio: &Gpio) -> Result<(u16, u16), Error> {
let pin_map = &mut *gpio.state_pin_map.lock()?;
Ok((set_pin_config(pin, *self as u16, pin_map), 1))
}
}
#[derive(Debug, Copy, Clone)]
pub enum Function {
Digital = 0,
Pwm = 1,
}
impl PinConfig for Function {
fn update_pin_map(&self, pin: u8, gpio: &Gpio) -> Result<(u16, u16), Error> {
let pin_map = &mut *gpio.function_pin_map.lock()?;
Ok((set_pin_config(pin, *self as u16, pin_map), 2))
}
}
fn set_pin_config(pin: u8, config: u16, pin_map: &u16) -> u16 {
let mask = 1 << pin;
config << pin | (pin_map & !mask)
}