Skip to content

Commit 112aa9e

Browse files
Morgan RoffMorganR
Morgan Roff
authored andcommitted
Implement embedded_hal::digital::IoPin
1 parent b930d32 commit 112aa9e

File tree

4 files changed

+86
-4
lines changed

4 files changed

+86
-4
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
99

1010
### Changed
1111

12+
- Implement `embedded_hal::digital::IoPin` for `CdevPin` and `SysfsPin`
1213
- Set default features to build both sysfs and cdev pin types.
1314
- Removed `Pin` export, use `CdevPin` or `SysfsPin`.
1415
- Increased the Minimum Supported Rust Version to `1.36.0` due to an update of `gpio_cdev`.

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ async-tokio = ["gpio-cdev/async-tokio"]
2020
default = [ "gpio_cdev", "gpio_sysfs" ]
2121

2222
[dependencies]
23-
embedded-hal = "=1.0.0-alpha.4"
23+
embedded-hal = { git = "https://github.com/rust-embedded/embedded-hal" }
2424
gpio-cdev = { version = "0.4", optional = true }
2525
sysfs_gpio = { version = "0.5", optional = true }
2626

src/cdev_pin.rs

+64-3
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,33 @@
33
/// Newtype around [`gpio_cdev::LineHandle`] that implements the `embedded-hal` traits
44
///
55
/// [`gpio_cdev::LineHandle`]: https://docs.rs/gpio-cdev/0.2.0/gpio_cdev/struct.LineHandle.html
6-
pub struct CdevPin(pub gpio_cdev::LineHandle, bool);
6+
pub struct CdevPin(pub gpio_cdev::LineHandle, gpio_cdev::LineInfo);
77

88
impl CdevPin {
99
/// See [`gpio_cdev::Line::request`][0] for details.
1010
///
1111
/// [0]: https://docs.rs/gpio-cdev/0.2.0/gpio_cdev/struct.Line.html#method.request
1212
pub fn new(handle: gpio_cdev::LineHandle) -> Result<Self, gpio_cdev::errors::Error> {
1313
let info = handle.line().info()?;
14-
Ok(CdevPin(handle, info.is_active_low()))
14+
Ok(CdevPin(handle, info))
15+
}
16+
17+
fn get_input_flags(&self) -> gpio_cdev::LineRequestFlags {
18+
let mut flags = gpio_cdev::LineRequestFlags::INPUT;
19+
if self.1.is_active_low() {
20+
flags.insert(gpio_cdev::LineRequestFlags::ACTIVE_LOW);
21+
}
22+
return flags;
23+
}
24+
25+
fn get_output_flags(&self) -> gpio_cdev::LineRequestFlags {
26+
let mut flags = gpio_cdev::LineRequestFlags::OUTPUT;
27+
if self.1.is_open_drain() {
28+
flags.insert(gpio_cdev::LineRequestFlags::OPEN_DRAIN);
29+
} else if self.1.is_open_source() {
30+
flags.insert(gpio_cdev::LineRequestFlags::OPEN_SOURCE);
31+
}
32+
return flags;
1533
}
1634
}
1735

@@ -31,7 +49,7 @@ impl embedded_hal::digital::InputPin for CdevPin {
3149
type Error = gpio_cdev::errors::Error;
3250

3351
fn try_is_high(&self) -> Result<bool, Self::Error> {
34-
if !self.1 {
52+
if !self.1.is_active_low() {
3553
self.0.get_value().map(|val| val != 0)
3654
} else {
3755
self.0.get_value().map(|val| val == 0)
@@ -43,6 +61,49 @@ impl embedded_hal::digital::InputPin for CdevPin {
4361
}
4462
}
4563

64+
impl embedded_hal::digital::IoPin<CdevPin, CdevPin> for CdevPin {
65+
type Error = gpio_cdev::errors::Error;
66+
67+
fn try_into_input_pin(self) -> Result<CdevPin, Self::Error> {
68+
if self.1.direction() == gpio_cdev::LineDirection::In {
69+
return Ok(self);
70+
}
71+
let line = self.0.line().clone();
72+
let input_flags = self.get_input_flags();
73+
let consumer = self.1.consumer().unwrap_or("").to_owned();
74+
75+
// Drop self to free the line before re-requesting it in a new mode.
76+
std::mem::drop(self);
77+
78+
CdevPin::new(line.request(input_flags, 0, &consumer)?)
79+
}
80+
81+
fn try_into_output_pin(
82+
self,
83+
state: embedded_hal::digital::PinState,
84+
) -> Result<CdevPin, Self::Error> {
85+
if self.1.direction() == gpio_cdev::LineDirection::Out {
86+
return Ok(self);
87+
}
88+
89+
let line = self.0.line().clone();
90+
let output_flags = self.get_output_flags();
91+
let consumer = self.1.consumer().unwrap_or("").to_owned();
92+
93+
// Drop self to free the line before re-requesting it in a new mode.
94+
std::mem::drop(self);
95+
96+
CdevPin::new(line.request(
97+
output_flags,
98+
match state {
99+
embedded_hal::digital::PinState::High => 1,
100+
embedded_hal::digital::PinState::Low => 0,
101+
},
102+
&consumer,
103+
)?)
104+
}
105+
}
106+
46107
impl core::ops::Deref for CdevPin {
47108
type Target = gpio_cdev::LineHandle;
48109

src/sysfs_pin.rs

+20
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,26 @@ impl embedded_hal::digital::InputPin for SysfsPin {
5454
}
5555
}
5656

57+
impl embedded_hal::digital::IoPin<SysfsPin, SysfsPin> for SysfsPin {
58+
type Error = sysfs_gpio::Error;
59+
60+
fn try_into_input_pin(self) -> Result<SysfsPin, Self::Error> {
61+
self.set_direction(sysfs_gpio::Direction::In)?;
62+
Ok(self)
63+
}
64+
65+
fn try_into_output_pin(
66+
self,
67+
state: embedded_hal::digital::PinState,
68+
) -> Result<SysfsPin, Self::Error> {
69+
self.set_direction(match state {
70+
embedded_hal::digital::PinState::High => sysfs_gpio::Direction::High,
71+
embedded_hal::digital::PinState::Low => sysfs_gpio::Direction::Low,
72+
})?;
73+
Ok(self)
74+
}
75+
}
76+
5777
impl core::ops::Deref for SysfsPin {
5878
type Target = sysfs_gpio::Pin;
5979

0 commit comments

Comments
 (0)