Skip to main content

avr_simulator/
port.rs

1use super::*;
2
3#[derive(Clone, Copy, Debug, PartialEq, Eq)]
4struct Port {
5    port: u8,
6    ddr: u8,
7}
8
9impl Port {
10    fn get(avr: &mut Avr, port: char) -> Self {
11        let mut state = ffi::avr_ioport_state_t {
12            _bitfield_align_1: Default::default(),
13            _bitfield_1: Default::default(),
14            __bindgen_padding_0: Default::default(),
15        };
16
17        // Safety: `IoCtl::IoPortGetState` requires parameter of type
18        // `avr_ioport_state_t`, which is the case here
19        let status =
20            unsafe { avr.ioctl(IoCtl::IoPortGetState { port }, &mut state) };
21
22        if status == -1 {
23            panic!("Current AVR doesn't have port P{}", port);
24        }
25
26        Port {
27            port: state.port() as u8,
28            ddr: state.ddr() as u8,
29        }
30    }
31}
32
33pub struct Pin;
34
35impl Pin {
36    pub fn set(avr: &Avr, port: char, pin: u8, high: bool) {
37        let irq = avr
38            .try_io_getirq(IoCtl::IoPortGetIrq { port }, pin as u32)
39            .unwrap_or_else(|| {
40                panic!("Current AVR doesn't have pin P{}{}", port, pin)
41            });
42
43        // Safety: `IoPortGetIrq` can be raised with a zero or one
44        unsafe {
45            ffi::avr_raise_irq(irq.as_ptr(), if high { 1 } else { 0 });
46        }
47    }
48
49    pub fn get(avr: &mut Avr, port: char, pin: u8) -> bool {
50        Port::get(avr, port).port & (1 << pin) > 0
51    }
52
53    pub fn get_mode(avr: &mut Avr, port: char, pin: u8) -> PinMode {
54        if Port::get(avr, port).ddr & (1 << pin) == 0 {
55            PinMode::Input
56        } else {
57            PinMode::Output
58        }
59    }
60}
61
62#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
63pub enum PinMode {
64    Input,
65    Output,
66}
67
68impl PinMode {
69    pub fn is_input(&self) -> bool {
70        *self == Self::Input
71    }
72
73    pub fn is_output(&self) -> bool {
74        *self == Self::Output
75    }
76}