rust_gpiozero/
devices.rs

1//! Describes generic devices such as `GPIODevice` and `CompositeDevice`
2
3use rppal::gpio::{Gpio, Level, Pin};
4
5/// Represents a single device of any type; GPIO-based, SPI-based, I2C-based,
6/// etc.  It defines the basic services applicable to all devices
7pub trait Device {
8    /// Shut down the device and release all associated resources.
9    fn close(self);
10
11    /// Returns ``True`` if the device is currently active and ``False`` otherwise.
12    fn is_active(&self) -> bool;
13}
14
15#[macro_export]
16macro_rules! impl_device {
17    () => {
18        /// Returns ``True`` if the device is currently active and ``False`` otherwise.
19        pub fn is_active(&self) -> bool {
20            self.value()
21        }
22        /// Shut down the device and release all associated resources.
23        pub fn close(self) {
24            drop(self)
25        }
26    };
27}
28
29/// Represents a generic GPIO device and provides the services common to all single-pin GPIO devices
30#[derive(Debug)]
31pub struct GpioDevice {
32    pin: Pin,
33    active_state: bool,
34    inactive_state: bool,
35}
36
37macro_rules! impl_gpio_device {
38    () => {
39        /// The `Pin` that the device is connected to.
40        pub fn pin(&self) -> u8 {
41            self.pin.pin()
42        }
43    };
44}
45
46impl GpioDevice {
47    /// Returns a GpioDevice with the pin number given
48    /// # Arguments
49    ///
50    /// * `pin` - The GPIO pin which the device is attached to
51    pub fn new(pin: u8) -> GpioDevice {
52        match Gpio::new() {
53            Err(e) => panic!("{:?}", e),
54            Ok(gpio) => match gpio.get(pin) {
55                Err(e) => panic!("{:?}", e),
56                Ok(pin) => GpioDevice {
57                    pin,
58                    active_state: true,
59                    inactive_state: false,
60                },
61            },
62        }
63    }
64
65    /// Returns a value representing the device's state.
66    pub fn value(&self) -> bool {
67        self.state_to_value()
68    }
69
70    fn state_to_value(&self) -> bool {
71        match self.pin.read() {
72            Level::High => self.active_state,
73            Level::Low => !self.active_state,
74        }
75    }
76
77    impl_device!();
78    impl_gpio_device!();
79}