use super::*;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
struct Port {
port: u8,
ddr: u8,
}
impl Port {
fn get(avr: &mut Avr, port: char) -> Self {
let mut state = ffi::avr_ioport_state_t {
_bitfield_align_1: Default::default(),
_bitfield_1: Default::default(),
__bindgen_padding_0: Default::default(),
};
let status =
unsafe { avr.ioctl(IoCtl::IoPortGetState { port }, &mut state) };
if status == -1 {
panic!("Current AVR doesn't have port P{}", port);
}
Port {
port: state.port() as u8,
ddr: state.ddr() as u8,
}
}
}
pub struct Pin;
impl Pin {
pub fn set(avr: &Avr, port: char, pin: u8, high: bool) {
let irq = avr
.try_io_getirq(IoCtl::IoPortGetIrq { port }, pin as u32)
.unwrap_or_else(|| {
panic!("Current AVR doesn't have pin P{}{}", port, pin)
});
unsafe {
ffi::avr_raise_irq(irq.as_ptr(), if high { 1 } else { 0 });
}
}
pub fn get(avr: &mut Avr, port: char, pin: u8) -> bool {
Port::get(avr, port).port & (1 << pin) > 0
}
pub fn get_mode(avr: &mut Avr, port: char, pin: u8) -> PinMode {
if Port::get(avr, port).ddr & (1 << pin) == 0 {
PinMode::Input
} else {
PinMode::Output
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
pub enum PinMode {
Input,
Output,
}
impl PinMode {
pub fn is_input(&self) -> bool {
*self == Self::Input
}
pub fn is_output(&self) -> bool {
*self == Self::Output
}
}