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 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 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}