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}