Skip to content

Commit fe7bda0

Browse files
authored
Try #30:
2 parents e9dce9f + 0e90b03 commit fe7bda0

File tree

5 files changed

+157
-73
lines changed

5 files changed

+157
-73
lines changed

Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ name = "linux-embedded-hal"
88
repository = "https://github.com/japaric/linux-embedded-hal"
99
version = "0.3.0"
1010

11+
[features]
12+
default = []
13+
gpio_cdev = []
14+
1115
[dependencies]
1216
embedded-hal = { version = "0.2.3", features = ["unproven"] }
1317
i2cdev = "0.4.3"
@@ -16,6 +20,7 @@ sysfs_gpio = "0.5"
1620
serial-unix = "0.4.0"
1721
serial-core = "0.4.0"
1822
nb = "0.1.1"
23+
gpio-cdev = "0.2"
1924

2025
[dev-dependencies]
2126
openpty = "0.1.0"

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,17 @@ This project is developed and maintained by the [Embedded Linux team][team].
88

99
## [Documentation](https://docs.rs/linux-embedded-hal)
1010

11+
## GPIO character device
12+
13+
Since Linux kernel v4.4 the use of sysfs GPIO was deprecated and replaced by the character device GPIO.
14+
See [gpio-cdev documentation](https://github.com/rust-embedded/gpio-cdev#sysfs-gpio-vs-gpio-character-device) for details.
15+
16+
This crate includes feature flag `gpio_cdev` that replaces [sysfs_gpio](https://crates.io/crates/sysfs_gpio) by [gpio-cdev](https://crates.io/crates/gpio-cdev).
17+
To enable it update your Cargo.toml.
18+
```
19+
linux-embedded-hal = { version = "0.3", features = ["gpio_cdev"] }
20+
```
21+
1122
## License
1223

1324
Licensed under either of

src/cdev_pin.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
use core::ops;
2+
3+
/// Newtype around [`gpio_cdev::LineHandle`] that implements the `embedded-hal` traits
4+
///
5+
/// [`gpio_cdev::LineHandle`]: https://docs.rs/gpio-cdev/0.2.0/gpio_cdev/struct.LineHandle.html
6+
pub struct Pin(pub gpio_cdev::LineHandle, bool);
7+
8+
impl Pin {
9+
/// See [`gpio_cdev::Line::request`][0] for details.
10+
///
11+
/// [0]: https://docs.rs/gpio-cdev/0.2.0/gpio_cdev/struct.Line.html#method.request
12+
pub fn new(handle: gpio_cdev::LineHandle) -> Result<Pin, gpio_cdev::errors::Error> {
13+
let info = handle.line().info()?;
14+
Ok(Pin(handle, info.is_active_low()))
15+
}
16+
}
17+
18+
impl hal::digital::v2::OutputPin for Pin {
19+
type Error = gpio_cdev::errors::Error;
20+
21+
fn set_low(&mut self) -> Result<(), Self::Error> {
22+
self.0.set_value(0)
23+
}
24+
25+
fn set_high(&mut self) -> Result<(), Self::Error> {
26+
self.0.set_value(1)
27+
}
28+
}
29+
30+
impl hal::digital::v2::InputPin for Pin {
31+
type Error = gpio_cdev::errors::Error;
32+
33+
fn is_high(&self) -> Result<bool, Self::Error> {
34+
if !self.1 {
35+
self.0.get_value().map(|val| val != 0)
36+
} else {
37+
self.0.get_value().map(|val| val == 0)
38+
}
39+
}
40+
41+
fn is_low(&self) -> Result<bool, Self::Error> {
42+
self.is_high().map(|val| !val)
43+
}
44+
}
45+
46+
impl ops::Deref for Pin {
47+
type Target = gpio_cdev::LineHandle;
48+
49+
fn deref(&self) -> &Self::Target {
50+
&self.0
51+
}
52+
}
53+
54+
impl ops::DerefMut for Pin {
55+
fn deref_mut(&mut self) -> &mut Self::Target {
56+
&mut self.0
57+
}
58+
}

src/lib.rs

Lines changed: 15 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@
1313
#![deny(missing_docs)]
1414

1515
extern crate cast;
16+
extern crate core;
1617
extern crate embedded_hal as hal;
18+
pub extern crate gpio_cdev;
1719
pub extern crate i2cdev;
20+
pub extern crate nb;
21+
pub extern crate serial_core;
22+
pub extern crate serial_unix;
1823
pub extern crate spidev;
1924
pub extern crate sysfs_gpio;
20-
pub extern crate serial_unix;
21-
pub extern crate serial_core;
22-
pub extern crate nb;
2325

2426
use std::io::{self, Write};
2527
use std::path::{Path, PathBuf};
@@ -33,7 +35,16 @@ use spidev::SpidevTransfer;
3335

3436
mod serial;
3537

38+
/// Cdev Pin wrapper module
39+
pub mod cdev_pin;
40+
/// Sysfs Pin wrapper module
41+
pub mod sysfs_pin;
42+
43+
#[cfg(feature = "gpio_cdev")]
44+
pub use cdev_pin::Pin;
3645
pub use serial::Serial;
46+
#[cfg(not(feature = "gpio_cdev"))]
47+
pub use sysfs_pin::Pin;
3748

3849
/// Empty struct that provides delay functionality on top of `thread::sleep`
3950
pub struct Delay;
@@ -92,72 +103,6 @@ impl hal::blocking::delay::DelayMs<u64> for Delay {
92103
}
93104
}
94105

95-
/// Newtype around [`sysfs_gpio::Pin`] that implements the `embedded-hal` traits
96-
///
97-
/// [`sysfs_gpio::Pin`]: https://docs.rs/sysfs_gpio/0.5.1/sysfs_gpio/struct.Pin.html
98-
pub struct Pin(pub sysfs_gpio::Pin);
99-
100-
impl Pin {
101-
/// See [`sysfs_gpio::Pin::new`][0] for details.
102-
///
103-
/// [0]: https://docs.rs/sysfs_gpio/0.5.1/sysfs_gpio/struct.Pin.html#method.new
104-
pub fn new(pin_num: u64) -> Pin {
105-
Pin(sysfs_gpio::Pin::new(pin_num))
106-
}
107-
108-
/// See [`sysfs_gpio::Pin::from_path`][0] for details.
109-
///
110-
/// [0]: https://docs.rs/sysfs_gpio/0.5.1/sysfs_gpio/struct.Pin.html#method.from_path
111-
pub fn from_path<P>(path: P) -> sysfs_gpio::Result<Pin>
112-
where
113-
P: AsRef<Path>,
114-
{
115-
sysfs_gpio::Pin::from_path(path).map(Pin)
116-
}
117-
}
118-
119-
impl hal::digital::v2::OutputPin for Pin {
120-
type Error = sysfs_gpio::Error;
121-
122-
fn set_low(&mut self) -> Result<(), Self::Error> {
123-
self.0.set_value(0)
124-
}
125-
126-
fn set_high(&mut self) -> Result<(), Self::Error> {
127-
self.0.set_value(1)
128-
}
129-
}
130-
131-
impl hal::digital::v2::InputPin for Pin {
132-
type Error = sysfs_gpio::Error;
133-
134-
fn is_high(&self) -> Result<bool, Self::Error> {
135-
if !self.0.get_active_low()? {
136-
self.0.get_value().map(|val| val != 0)
137-
} else {
138-
self.0.get_value().map(|val| val == 0)
139-
}
140-
}
141-
142-
fn is_low(&self) -> Result<bool, Self::Error> {
143-
self.is_high().map(|val| !val)
144-
}
145-
}
146-
147-
impl ops::Deref for Pin {
148-
type Target = sysfs_gpio::Pin;
149-
150-
fn deref(&self) -> &Self::Target {
151-
&self.0
152-
}
153-
}
154-
155-
impl ops::DerefMut for Pin {
156-
fn deref_mut(&mut self) -> &mut Self::Target {
157-
&mut self.0
158-
}
159-
}
160-
161106
/// Newtype around [`i2cdev::linux::LinuxI2CDevice`] that implements the `embedded-hal` traits
162107
///
163108
/// [`i2cdev::linux::LinuxI2CDevice`]: https://docs.rs/i2cdev/0.3.1/i2cdev/linux/struct.LinuxI2CDevice.html
@@ -220,10 +165,7 @@ impl hal::blocking::i2c::WriteRead for I2cdev {
220165
buffer: &mut [u8],
221166
) -> Result<(), Self::Error> {
222167
self.set_address(address)?;
223-
let mut messages = [
224-
LinuxI2CMessage::write(bytes),
225-
LinuxI2CMessage::read(buffer),
226-
];
168+
let mut messages = [LinuxI2CMessage::write(bytes), LinuxI2CMessage::read(buffer)];
227169
self.inner.transfer(&mut messages).map(drop)
228170
}
229171
}

src/sysfs_pin.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
use std::ops;
2+
use std::path::Path;
3+
4+
/// Newtype around [`sysfs_gpio::Pin`] that implements the `embedded-hal` traits
5+
///
6+
/// [`sysfs_gpio::Pin`]: https://docs.rs/sysfs_gpio/0.5.1/sysfs_gpio/struct.Pin.html
7+
pub struct Pin(pub sysfs_gpio::Pin);
8+
9+
impl Pin {
10+
/// See [`sysfs_gpio::Pin::new`][0] for details.
11+
///
12+
/// [0]: https://docs.rs/sysfs_gpio/0.5.1/sysfs_gpio/struct.Pin.html#method.new
13+
pub fn new(pin_num: u64) -> Pin {
14+
Pin(sysfs_gpio::Pin::new(pin_num))
15+
}
16+
17+
/// See [`sysfs_gpio::Pin::from_path`][0] for details.
18+
///
19+
/// [0]: https://docs.rs/sysfs_gpio/0.5.1/sysfs_gpio/struct.Pin.html#method.from_path
20+
pub fn from_path<P>(path: P) -> sysfs_gpio::Result<Pin>
21+
where
22+
P: AsRef<Path>,
23+
{
24+
sysfs_gpio::Pin::from_path(path).map(Pin)
25+
}
26+
}
27+
28+
impl hal::digital::v2::OutputPin for Pin {
29+
type Error = sysfs_gpio::Error;
30+
31+
fn set_low(&mut self) -> Result<(), Self::Error> {
32+
self.0.set_value(0)
33+
}
34+
35+
fn set_high(&mut self) -> Result<(), Self::Error> {
36+
self.0.set_value(1)
37+
}
38+
}
39+
40+
impl hal::digital::v2::InputPin for Pin {
41+
type Error = sysfs_gpio::Error;
42+
43+
fn is_high(&self) -> Result<bool, Self::Error> {
44+
if !self.0.get_active_low()? {
45+
self.0.get_value().map(|val| val != 0)
46+
} else {
47+
self.0.get_value().map(|val| val == 0)
48+
}
49+
}
50+
51+
fn is_low(&self) -> Result<bool, Self::Error> {
52+
self.is_high().map(|val| !val)
53+
}
54+
}
55+
56+
impl ops::Deref for Pin {
57+
type Target = sysfs_gpio::Pin;
58+
59+
fn deref(&self) -> &Self::Target {
60+
&self.0
61+
}
62+
}
63+
64+
impl ops::DerefMut for Pin {
65+
fn deref_mut(&mut self) -> &mut Self::Target {
66+
&mut self.0
67+
}
68+
}

0 commit comments

Comments
 (0)