From 7aec9f61b3bccf3f6b872162d5e48ed17e1e3d66 Mon Sep 17 00:00:00 2001 From: Ales Musil Date: Fri, 20 Dec 2019 11:53:17 +0100 Subject: [PATCH 1/5] Reformat project with rust fmt --- src/lib.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index e999faf..b1db4ea 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,11 +15,11 @@ extern crate cast; extern crate embedded_hal as hal; pub extern crate i2cdev; +pub extern crate nb; +pub extern crate serial_core; +pub extern crate serial_unix; pub extern crate spidev; pub extern crate sysfs_gpio; -pub extern crate serial_unix; -pub extern crate serial_core; -pub extern crate nb; use std::io::{self, Write}; use std::path::{Path, PathBuf}; @@ -220,10 +220,7 @@ impl hal::blocking::i2c::WriteRead for I2cdev { buffer: &mut [u8], ) -> Result<(), Self::Error> { self.set_address(address)?; - let mut messages = [ - LinuxI2CMessage::write(bytes), - LinuxI2CMessage::read(buffer), - ]; + let mut messages = [LinuxI2CMessage::write(bytes), LinuxI2CMessage::read(buffer)]; self.inner.transfer(&mut messages).map(drop) } } From da2f57a64f14ba161ec453d460ceb4ce67735060 Mon Sep 17 00:00:00 2001 From: Ales Musil Date: Fri, 20 Dec 2019 11:29:38 +0100 Subject: [PATCH 2/5] Move SysfsPin to its own module The SysfsPin export can be enabled with feature flag "gpio_sysfs". --- Cargo.toml | 7 ++++- src/lib.rs | 73 +++++------------------------------------------- src/sysfs_pin.rs | 68 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 67 deletions(-) create mode 100644 src/sysfs_pin.rs diff --git a/Cargo.toml b/Cargo.toml index 9ddf3b5..9c44574 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,11 +8,16 @@ name = "linux-embedded-hal" repository = "https://github.com/japaric/linux-embedded-hal" version = "0.3.0" +[features] +default = [] +gpio_sysfs = ["sysfs_gpio"] + [dependencies] embedded-hal = { version = "0.2.3", features = ["unproven"] } +sysfs_gpio = { version = "0.5", optional = true } + i2cdev = "0.4.3" spidev = "0.4" -sysfs_gpio = "0.5" serial-unix = "0.4.0" serial-core = "0.4.0" nb = "0.1.1" diff --git a/src/lib.rs b/src/lib.rs index b1db4ea..b00fcb0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,6 +19,7 @@ pub extern crate nb; pub extern crate serial_core; pub extern crate serial_unix; pub extern crate spidev; +#[cfg(feature = "gpio_sysfs")] pub extern crate sysfs_gpio; use std::io::{self, Write}; @@ -33,7 +34,13 @@ use spidev::SpidevTransfer; mod serial; +#[cfg(feature = "gpio_sysfs")] +/// Sysfs Pin wrapper module +mod sysfs_pin; + pub use serial::Serial; +#[cfg(feature = "gpio_sysfs")] +pub use sysfs_pin::SysfsPin; /// Empty struct that provides delay functionality on top of `thread::sleep` pub struct Delay; @@ -92,72 +99,6 @@ impl hal::blocking::delay::DelayMs for Delay { } } -/// Newtype around [`sysfs_gpio::Pin`] that implements the `embedded-hal` traits -/// -/// [`sysfs_gpio::Pin`]: https://docs.rs/sysfs_gpio/0.5.1/sysfs_gpio/struct.Pin.html -pub struct Pin(pub sysfs_gpio::Pin); - -impl Pin { - /// See [`sysfs_gpio::Pin::new`][0] for details. - /// - /// [0]: https://docs.rs/sysfs_gpio/0.5.1/sysfs_gpio/struct.Pin.html#method.new - pub fn new(pin_num: u64) -> Pin { - Pin(sysfs_gpio::Pin::new(pin_num)) - } - - /// See [`sysfs_gpio::Pin::from_path`][0] for details. - /// - /// [0]: https://docs.rs/sysfs_gpio/0.5.1/sysfs_gpio/struct.Pin.html#method.from_path - pub fn from_path

(path: P) -> sysfs_gpio::Result - where - P: AsRef, - { - sysfs_gpio::Pin::from_path(path).map(Pin) - } -} - -impl hal::digital::v2::OutputPin for Pin { - type Error = sysfs_gpio::Error; - - fn set_low(&mut self) -> Result<(), Self::Error> { - self.0.set_value(0) - } - - fn set_high(&mut self) -> Result<(), Self::Error> { - self.0.set_value(1) - } -} - -impl hal::digital::v2::InputPin for Pin { - type Error = sysfs_gpio::Error; - - fn is_high(&self) -> Result { - if !self.0.get_active_low()? { - self.0.get_value().map(|val| val != 0) - } else { - self.0.get_value().map(|val| val == 0) - } - } - - fn is_low(&self) -> Result { - self.is_high().map(|val| !val) - } -} - -impl ops::Deref for Pin { - type Target = sysfs_gpio::Pin; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl ops::DerefMut for Pin { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - /// Newtype around [`i2cdev::linux::LinuxI2CDevice`] that implements the `embedded-hal` traits /// /// [`i2cdev::linux::LinuxI2CDevice`]: https://docs.rs/i2cdev/0.3.1/i2cdev/linux/struct.LinuxI2CDevice.html diff --git a/src/sysfs_pin.rs b/src/sysfs_pin.rs new file mode 100644 index 0000000..cfb4638 --- /dev/null +++ b/src/sysfs_pin.rs @@ -0,0 +1,68 @@ +use std::ops; +use std::path::Path; + +/// Newtype around [`sysfs_gpio::Pin`] that implements the `embedded-hal` traits +/// +/// [`sysfs_gpio::Pin`]: https://docs.rs/sysfs_gpio/0.5.1/sysfs_gpio/struct.Pin.html +pub struct SysfsPin(pub sysfs_gpio::Pin); + +impl SysfsPin { + /// See [`sysfs_gpio::Pin::new`][0] for details. + /// + /// [0]: https://docs.rs/sysfs_gpio/0.5.1/sysfs_gpio/struct.Pin.html#method.new + pub fn new(pin_num: u64) -> Self { + SysfsPin(sysfs_gpio::Pin::new(pin_num)) + } + + /// See [`sysfs_gpio::Pin::from_path`][0] for details. + /// + /// [0]: https://docs.rs/sysfs_gpio/0.5.1/sysfs_gpio/struct.Pin.html#method.from_path + pub fn from_path

(path: P) -> sysfs_gpio::Result + where + P: AsRef, + { + sysfs_gpio::Pin::from_path(path).map(SysfsPin) + } +} + +impl hal::digital::v2::OutputPin for SysfsPin { + type Error = sysfs_gpio::Error; + + fn set_low(&mut self) -> Result<(), Self::Error> { + self.0.set_value(0) + } + + fn set_high(&mut self) -> Result<(), Self::Error> { + self.0.set_value(1) + } +} + +impl hal::digital::v2::InputPin for SysfsPin { + type Error = sysfs_gpio::Error; + + fn is_high(&self) -> Result { + if !self.0.get_active_low()? { + self.0.get_value().map(|val| val != 0) + } else { + self.0.get_value().map(|val| val == 0) + } + } + + fn is_low(&self) -> Result { + self.is_high().map(|val| !val) + } +} + +impl ops::Deref for SysfsPin { + type Target = sysfs_gpio::Pin; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl ops::DerefMut for SysfsPin { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} From 1d0f3688688562697c566aaf20eeb8de796427a5 Mon Sep 17 00:00:00 2001 From: Ales Musil Date: Fri, 20 Dec 2019 11:40:45 +0100 Subject: [PATCH 3/5] Add CdevPin module The CdevPin export can be enabled with feature flag "gpio_cdev". --- Cargo.toml | 2 ++ src/cdev_pin.rs | 58 +++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 8 +++++++ 3 files changed, 68 insertions(+) create mode 100644 src/cdev_pin.rs diff --git a/Cargo.toml b/Cargo.toml index 9c44574..080a254 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,9 +11,11 @@ version = "0.3.0" [features] default = [] gpio_sysfs = ["sysfs_gpio"] +gpio_cdev = ["gpio-cdev"] [dependencies] embedded-hal = { version = "0.2.3", features = ["unproven"] } +gpio-cdev = { version = "0.2", optional = true } sysfs_gpio = { version = "0.5", optional = true } i2cdev = "0.4.3" diff --git a/src/cdev_pin.rs b/src/cdev_pin.rs new file mode 100644 index 0000000..69e27bb --- /dev/null +++ b/src/cdev_pin.rs @@ -0,0 +1,58 @@ +use core::ops; + +/// Newtype around [`gpio_cdev::LineHandle`] that implements the `embedded-hal` traits +/// +/// [`gpio_cdev::LineHandle`]: https://docs.rs/gpio-cdev/0.2.0/gpio_cdev/struct.LineHandle.html +pub struct CdevPin(pub gpio_cdev::LineHandle, bool); + +impl CdevPin { + /// See [`gpio_cdev::Line::request`][0] for details. + /// + /// [0]: https://docs.rs/gpio-cdev/0.2.0/gpio_cdev/struct.Line.html#method.request + pub fn new(handle: gpio_cdev::LineHandle) -> Result { + let info = handle.line().info()?; + Ok(CdevPin(handle, info.is_active_low())) + } +} + +impl hal::digital::v2::OutputPin for CdevPin { + type Error = gpio_cdev::errors::Error; + + fn set_low(&mut self) -> Result<(), Self::Error> { + self.0.set_value(0) + } + + fn set_high(&mut self) -> Result<(), Self::Error> { + self.0.set_value(1) + } +} + +impl hal::digital::v2::InputPin for CdevPin { + type Error = gpio_cdev::errors::Error; + + fn is_high(&self) -> Result { + if !self.1 { + self.0.get_value().map(|val| val != 0) + } else { + self.0.get_value().map(|val| val == 0) + } + } + + fn is_low(&self) -> Result { + self.is_high().map(|val| !val) + } +} + +impl ops::Deref for CdevPin { + type Target = gpio_cdev::LineHandle; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl ops::DerefMut for CdevPin { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} diff --git a/src/lib.rs b/src/lib.rs index b00fcb0..f5e55a9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,7 +13,10 @@ #![deny(missing_docs)] extern crate cast; +extern crate core; extern crate embedded_hal as hal; +#[cfg(feature = "gpio_cdev")] +pub extern crate gpio_cdev; pub extern crate i2cdev; pub extern crate nb; pub extern crate serial_core; @@ -34,10 +37,15 @@ use spidev::SpidevTransfer; mod serial; +#[cfg(feature = "gpio_cdev")] +/// Cdev Pin wrapper module +mod cdev_pin; #[cfg(feature = "gpio_sysfs")] /// Sysfs Pin wrapper module mod sysfs_pin; +#[cfg(feature = "gpio_cdev")] +pub use cdev_pin::CdevPin; pub use serial::Serial; #[cfg(feature = "gpio_sysfs")] pub use sysfs_pin::SysfsPin; From 6809164be7646717b2c511fece4ba4f353aeccc1 Mon Sep 17 00:00:00 2001 From: Ales Musil Date: Fri, 20 Dec 2019 11:44:36 +0100 Subject: [PATCH 4/5] Add documentation for the cdev feature --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index c51c950..59ec208 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,19 @@ This project is developed and maintained by the [Embedded Linux team][team]. ## [Documentation](https://docs.rs/linux-embedded-hal) +## GPIO character device + +Since Linux kernel v4.4 the use of sysfs GPIO was deprecated and replaced by the character device GPIO. +See [gpio-cdev documentation](https://github.com/rust-embedded/gpio-cdev#sysfs-gpio-vs-gpio-character-device) for details. + +This crate includes feature flag `gpio_cdev` that exposes `CdevPin` as wrapper around `LineHandle` from [gpio-cdev](https://crates.io/crates/gpio-cdev). +To enable it update your Cargo.toml. +``` +linux-embedded-hal = { version = "0.3", features = ["gpio_cdev"] } +``` + +`SysfsPin` can be still used with feature flag `gpio_sysfs`. + ## License Licensed under either of From 0b8e37331ca470df289cf4e4468b7c440c8f8cf8 Mon Sep 17 00:00:00 2001 From: Ales Musil Date: Wed, 22 Jan 2020 18:24:17 +0100 Subject: [PATCH 5/5] Update documentation and change log for cdev feature --- CHANGELOG.md | 2 ++ README.md | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 78de5de..be0fee6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added - Added serial::Read/Write implementation. +- Added feature flag for Chardev GPIO ### Fixed @@ -23,6 +24,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Use embedded-hal::digital::v2 traits. - Updated to i2cdev 0.4.3 (necessary for trasactional write-read). - Updated to spidev 0.4 +- Added feature flag for Sysfs GPIO ## [v0.2.2] - 2018-12-21 diff --git a/README.md b/README.md index 59ec208..22e0d3f 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,9 @@ This project is developed and maintained by the [Embedded Linux team][team]. Since Linux kernel v4.4 the use of sysfs GPIO was deprecated and replaced by the character device GPIO. See [gpio-cdev documentation](https://github.com/rust-embedded/gpio-cdev#sysfs-gpio-vs-gpio-character-device) for details. -This crate includes feature flag `gpio_cdev` that exposes `CdevPin` as wrapper around `LineHandle` from [gpio-cdev](https://crates.io/crates/gpio-cdev). -To enable it update your Cargo.toml. +This crate includes feature flag `gpio_cdev` that exposes `CdevPin` as wrapper around `LineHandle` from [gpio-cdev](https://crates.io/crates/gpio-cdev). +To enable it update your Cargo.toml. Please note that in order to prevent `LineHandle` fd from closing you should +assign to a variable, see [cdev issue](https://github.com/rust-embedded/gpio-cdev/issues/29) for more details. ``` linux-embedded-hal = { version = "0.3", features = ["gpio_cdev"] } ```