Skip to content

Commit 7f8f862

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

File tree

3 files changed

+80
-4
lines changed

3 files changed

+80
-4
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
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 = { path = "../embedded-hal" }
2424
gpio-cdev = { version = "0.4", optional = true }
2525
sysfs_gpio = { version = "0.5", optional = true }
2626

src/cdev_pin.rs

Lines changed: 63 additions & 3 deletions
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,48 @@ 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_switch_to_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(
79+
line.request(
80+
input_flags, 0, &consumer)?)
81+
}
82+
83+
fn try_switch_to_output_pin(self, state: embedded_hal::digital::PinState) -> Result<CdevPin, Self::Error> {
84+
if self.1.direction() == gpio_cdev::LineDirection::Out {
85+
return Ok(self);
86+
}
87+
88+
let line = self.0.line().clone();
89+
let output_flags = self.get_output_flags();
90+
let consumer = self.1.consumer().unwrap_or("").to_owned();
91+
92+
// Drop self to free the line before re-requesting it in a new mode.
93+
std::mem::drop(self);
94+
95+
CdevPin::new(
96+
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+
46106
impl core::ops::Deref for CdevPin {
47107
type Target = gpio_cdev::LineHandle;
48108

src/sysfs_pin.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,22 @@ 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_switch_to_input_pin(self) -> Result<SysfsPin, Self::Error> {
61+
self.set_direction(sysfs_gpio::Direction::In)?;
62+
Ok(self)
63+
}
64+
fn try_switch_to_output_pin(self, state: embedded_hal::digital::PinState) -> Result<SysfsPin, Self::Error> {
65+
self.set_direction(match state {
66+
embedded_hal::digital::PinState::High => sysfs_gpio::Direction::High,
67+
embedded_hal::digital::PinState::Low => sysfs_gpio::Direction::Low,
68+
})?;
69+
Ok(self)
70+
}
71+
}
72+
5773
impl core::ops::Deref for SysfsPin {
5874
type Target = sysfs_gpio::Pin;
5975

0 commit comments

Comments
 (0)