1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
//! GPIO interface //! //! The GPIO crate allows easy and fast access to GPIO pins. It aims to provide //! an ergonomic interface while being lower overhead, enabling high-frequency //! output without complicating simple tasks. //! //! The core interface is defined using `GpioValue` and the `GpioOut`/`GpioIn` //! traits. All backends implement at least some of these traits, making them //! interchangeable, e.g. for testing. //! //! The most commonly used implementation is based on the //! [Linux GPIO Sysfs](https://www.kernel.org/doc/Documentation/gpio/sysfs.txt) //! interface, found inside the `sysfs` crate. //! //! ## Example //! //! ```rust,no_run //! use gpio::{GpioIn, GpioOut}; //! use std::{thread, time}; //! //! // Let's open GPIO23 and -24, e.g. on a Raspberry Pi 2. //! let mut gpio23 = gpio::sysfs::SysFsGpioInput::open(23).unwrap(); //! let mut gpio24 = gpio::sysfs::SysFsGpioOutput::open(24).unwrap(); //! //! // GPIO24 will be toggled every second in the background by a different thread //! let mut value = false; //! thread::spawn(move || loop { //! gpio24.set_value(value).expect("could not set gpio24"); //! thread::sleep(time::Duration::from_millis(1000)); //! value = !value; //! }); //! //! // The main thread will simply display the current value of GPIO23 every 100ms. //! loop { //! println!("GPIO23: {:?}", gpio23.read_value().unwrap()); //! thread::sleep(time::Duration::from_millis(100)); //! } //! ``` //! //! ## TODO //! //! * `/dev/mem` interface: Higher frequency port usage //! pub mod sysfs; pub mod dummy; /// A value read from or written to a GPIO port #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub enum GpioValue { /// A low value, usually 0 V Low, /// A high value, commonly 3.3V or 5V High, } impl From<bool> for GpioValue { #[inline] fn from(val: bool) -> GpioValue { if val { GpioValue::High } else { GpioValue::Low } } } impl From<u8> for GpioValue { #[inline] fn from(val: u8) -> GpioValue { if val != 0 { GpioValue::High } else { GpioValue::Low } } } impl From<GpioValue> for bool { #[inline] fn from(val: GpioValue) -> bool { match val { GpioValue::Low => false, GpioValue::High => true, } } } impl From<GpioValue> for u8 { #[inline] fn from(val: GpioValue) -> u8 { match val { GpioValue::Low => 0, GpioValue::High => 1, } } } /// Supports sending `GPIOValue`s pub trait GpioOut { /// Errors that can occur during initialization of or writing to GPIO type Error; /// Sets the output value of the GPIO port #[inline(always)] fn set_value<T: Into<GpioValue> + Copy>(&mut self, value: T) -> Result<(), Self::Error> { match value.into() { GpioValue::High => self.set_high(), GpioValue::Low => self.set_low(), } } /// Set the GPIO port to a low output value directly #[inline(always)] fn set_low(&mut self) -> Result<(), Self::Error>; /// Set the GPIO port to a high output value directly #[inline(always)] fn set_high(&mut self) -> Result<(), Self::Error>; } /// Supports reading `GPIOValue`s pub trait GpioIn { /// Errors that can occur during initialization of or reading from GPIO type Error; /// Perform a single reading of a GPIO port fn read_value(&mut self) -> Result<GpioValue, Self::Error>; }