|
1 | 1 | //! Describes generic devices such as `GPIODevice` and `CompositeDevice`
|
2 |
| -use crate::traits::Device; |
3 |
| -use sysfs_gpio::Pin; |
| 2 | +
|
| 3 | +use 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 |
| 7 | +pub 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 | +#[macro_export] |
| 15 | +macro_rules! impl_device { |
| 16 | + () => { |
| 17 | + /// Returns ``True`` if the device is currently active and ``False`` otherwise. |
| 18 | + pub fn is_active(&self) -> bool { |
| 19 | + self.value() |
| 20 | + } |
| 21 | + /// Shut down the device and release all associated resources. |
| 22 | + pub fn close(self) { |
| 23 | + drop(self) |
| 24 | + } |
| 25 | + } |
| 26 | +} |
4 | 27 |
|
5 | 28 | /// Represents a generic GPIO device and provides the services common to all single-pin GPIO devices
|
6 | 29 | #[derive(Debug)]
|
7 |
| -pub struct GPIODevice { |
8 |
| - pub pin: Pin, |
| 30 | +pub struct GpioDevice { |
| 31 | + pin: Pin, |
| 32 | + active_state: bool, |
| 33 | + inactive_state: bool, |
9 | 34 | }
|
10 | 35 |
|
11 |
| -impl GPIODevice { |
12 |
| - pub fn new(pin: u64) -> GPIODevice { |
13 |
| - //Create a new Pin with the provided pin_num |
14 |
| - let gpio = Pin::new(pin); |
15 |
| - //check if pin is not already exported |
| 36 | +macro_rules! impl_gpio_device { |
| 37 | + () => { |
| 38 | + /// The `Pin` that the device is connected to. |
| 39 | + pub fn pin(&self) -> u8 { |
| 40 | + self.pin.pin() |
| 41 | + } |
16 | 42 |
|
17 |
| - //try to export the selected pin |
18 |
| - //Todo implement better error handling |
19 |
| - gpio.export().expect("Could not export the selected gpio"); |
20 |
| - GPIODevice { pin: gpio } |
21 | 43 | }
|
22 | 44 | }
|
23 | 45 |
|
24 |
| -impl Device for GPIODevice { |
25 |
| - fn pin(&self) -> Pin { |
26 |
| - self.pin |
| 46 | +impl 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 | + /// |
| 52 | + pub fn new(pin: u8) -> GpioDevice { |
| 53 | + match Gpio::new() { |
| 54 | + Err(e) => panic!("{:?}", e), |
| 55 | + Ok(gpio) => match gpio.get(pin) { |
| 56 | + Err(e) => panic!("{:?}", e), |
| 57 | + Ok(pin) => GpioDevice { |
| 58 | + pin, |
| 59 | + active_state: true, |
| 60 | + inactive_state: false, |
| 61 | + }, |
| 62 | + }, |
| 63 | + } |
27 | 64 | }
|
28 | 65 |
|
29 | 66 | /// Returns a value representing the device's state.
|
30 |
| - fn value(&self) -> i8 { |
31 |
| - let value = self |
32 |
| - .pin |
33 |
| - .get_value() |
34 |
| - .expect("Could not check if device is active"); |
35 |
| - value as i8 |
| 67 | + pub fn value(&self) -> bool { |
| 68 | + self.state_to_value() |
36 | 69 | }
|
37 |
| -} |
38 | 70 |
|
39 |
| -//Todo CompositeDevice |
| 71 | + fn state_to_value(&self) -> bool { |
| 72 | + match self.pin.read() { |
| 73 | + Level::High => self.active_state, |
| 74 | + Level::Low => !self.active_state, |
| 75 | + } |
| 76 | + } |
| 77 | + |
| 78 | + impl_device!(); |
| 79 | + impl_gpio_device!(); |
| 80 | +} |
0 commit comments