Skip to content

Commit e177ef2

Browse files
bors[bot]eldruin
andauthored
Merge #63
63: Update embedded-hal to version 1.0.0-alpha.5 r=ryankurte a=eldruin I will add support for embedded-hal 0.2.x in parallel as described [here](https://github.com/rust-embedded/embedded-hal#adding-support-for-an-embedded-hal--alpha-version-in-a-hal-implementation). This PR contains some preparation for that. Co-authored-by: Diego Barrios Romero <eldruin@gmail.com>
2 parents 0c1a0bb + c4abaf2 commit e177ef2

14 files changed

+372
-339
lines changed

.github/bors.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ required_approvals = 1
44
status = [
55
"CI (stable, x86_64-unknown-linux-gnu)",
66
"CI (stable, armv7-unknown-linux-gnueabihf)",
7-
"CI (1.36.0, x86_64-unknown-linux-gnu)",
7+
"CI (1.46.0, x86_64-unknown-linux-gnu)",
88
]

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121

2222
include:
2323
# Test MSRV
24-
- rust: 1.36.0
24+
- rust: 1.46.0
2525
TARGET: x86_64-unknown-linux-gnu
2626

2727
# Test nightly but don't fail

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1212
- Modified `OutputPin` behavior for active-low pins to match `InputPin` behavior.
1313
- Set default features to build both sysfs and cdev pin types.
1414
- Removed `Pin` export, use `CdevPin` or `SysfsPin`.
15-
- Increased the Minimum Supported Rust Version to `1.36.0` due to an update of `gpio_cdev`.
16-
- Adapted to `embedded-hal` `1.0.0-alpha.3` release.
15+
- Increased the Minimum Supported Rust Version to `1.46.0` due to an update of `bitflags`.
16+
- Adapted to `embedded-hal` `1.0.0-alpha.5` release.
1717
- Updated `nb` to version `1`.
1818

1919
## [v0.3.0] - 2019-11-25

Cargo.toml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,20 @@ async-tokio = ["gpio-cdev/async-tokio"]
2020
default = [ "gpio_cdev", "gpio_sysfs" ]
2121

2222
[dependencies]
23-
embedded-hal = "=1.0.0-alpha.4"
24-
gpio-cdev = { version = "0.4", optional = true }
25-
sysfs_gpio = { version = "0.5", optional = true }
23+
embedded-hal = "=1.0.0-alpha.5"
24+
gpio-cdev = { version = "0.5", optional = true }
25+
sysfs_gpio = { version = "0.6", optional = true }
2626

27-
i2cdev = "0.4.3"
27+
i2cdev = "0.5"
2828
nb = "1"
2929
serial-core = "0.4.0"
3030
serial-unix = "0.4.0"
31-
spidev = "0.4"
31+
spidev = "0.5"
3232

3333
[dev-dependencies]
3434
openpty = "0.1.0"
3535

3636
[dependencies.cast]
3737
# we don't need the `Error` implementation
3838
default-features = false
39-
version = "0.2.2"
39+
version = "0.3"

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ linux-embedded-hal = { version = "0.3", features = ["gpio_cdev"] }
2727

2828
## Minimum Supported Rust Version (MSRV)
2929

30-
This crate is guaranteed to compile on stable Rust 1.36.0 and up. It *might*
30+
This crate is guaranteed to compile on stable Rust 1.46.0 and up. It *might*
3131
compile with older versions but that may change in any new patch release.
3232

3333
## License

examples/transactional-i2c.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
extern crate embedded_hal;
2-
extern crate linux_embedded_hal;
3-
use embedded_hal::blocking::i2c::{Operation as I2cOperation, Transactional};
1+
use embedded_hal::i2c::blocking::{Operation as I2cOperation, Transactional};
42
use linux_embedded_hal::I2cdev;
53

64
const ADDR: u8 = 0x12;
@@ -23,7 +21,7 @@ where
2321
I2cOperation::Write(&[0xAB]),
2422
I2cOperation::Read(&mut read_buffer),
2523
];
26-
self.i2c.try_exec(ADDR, &mut ops).and(Ok(read_buffer[0]))
24+
self.i2c.exec(ADDR, &mut ops).and(Ok(read_buffer[0]))
2725
}
2826
}
2927

src/cdev_pin.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
//! Linux CDev pin type
1+
//! Implementation of [`embedded-hal`] digital input/output traits using a Linux CDev pin
2+
//!
3+
//! [`embedded-hal`]: https://docs.rs/embedded-hal
24
35
/// Newtype around [`gpio_cdev::LineHandle`] that implements the `embedded-hal` traits
46
///
@@ -15,18 +17,18 @@ impl CdevPin {
1517
}
1618
}
1719

18-
impl embedded_hal::digital::OutputPin for CdevPin {
20+
impl embedded_hal::digital::blocking::OutputPin for CdevPin {
1921
type Error = gpio_cdev::errors::Error;
2022

21-
fn try_set_low(&mut self) -> Result<(), Self::Error> {
23+
fn set_low(&mut self) -> Result<(), Self::Error> {
2224
if self.1 {
2325
self.0.set_value(1)
2426
} else {
2527
self.0.set_value(0)
2628
}
2729
}
2830

29-
fn try_set_high(&mut self) -> Result<(), Self::Error> {
31+
fn set_high(&mut self) -> Result<(), Self::Error> {
3032
if self.1 {
3133
self.0.set_value(0)
3234
} else {
@@ -35,19 +37,19 @@ impl embedded_hal::digital::OutputPin for CdevPin {
3537
}
3638
}
3739

38-
impl embedded_hal::digital::InputPin for CdevPin {
40+
impl embedded_hal::digital::blocking::InputPin for CdevPin {
3941
type Error = gpio_cdev::errors::Error;
4042

41-
fn try_is_high(&self) -> Result<bool, Self::Error> {
43+
fn is_high(&self) -> Result<bool, Self::Error> {
4244
if !self.1 {
4345
self.0.get_value().map(|val| val != 0)
4446
} else {
4547
self.0.get_value().map(|val| val == 0)
4648
}
4749
}
4850

49-
fn try_is_low(&self) -> Result<bool, Self::Error> {
50-
self.try_is_high().map(|val| !val)
51+
fn is_low(&self) -> Result<bool, Self::Error> {
52+
self.is_high().map(|val| !val)
5153
}
5254
}
5355

src/delay.rs

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
//! Implementation of [`embedded-hal`] delay traits
2+
//!
3+
//! [`embedded-hal`]: https://docs.rs/embedded-hal
4+
5+
use cast::{u32, u64};
6+
use core::convert::Infallible;
7+
use embedded_hal::delay::blocking::{DelayMs, DelayUs};
8+
use std::thread;
9+
use std::time::Duration;
10+
11+
/// Empty struct that provides delay functionality on top of `thread::sleep`
12+
pub struct Delay;
13+
14+
impl DelayUs<u8> for Delay {
15+
type Error = Infallible;
16+
17+
fn delay_us(&mut self, n: u8) -> Result<(), Self::Error> {
18+
thread::sleep(Duration::new(0, u32(n) * 1000));
19+
Ok(())
20+
}
21+
}
22+
23+
impl DelayUs<u16> for Delay {
24+
type Error = Infallible;
25+
26+
fn delay_us(&mut self, n: u16) -> Result<(), Self::Error> {
27+
thread::sleep(Duration::new(0, u32(n) * 1000));
28+
Ok(())
29+
}
30+
}
31+
32+
impl DelayUs<u32> for Delay {
33+
type Error = Infallible;
34+
35+
fn delay_us(&mut self, n: u32) -> Result<(), Self::Error> {
36+
let secs = n / 1_000_000;
37+
let nsecs = (n % 1_000_000) * 1_000;
38+
39+
thread::sleep(Duration::new(u64(secs), nsecs));
40+
Ok(())
41+
}
42+
}
43+
44+
impl DelayUs<u64> for Delay {
45+
type Error = Infallible;
46+
47+
fn delay_us(&mut self, n: u64) -> Result<(), Self::Error> {
48+
let secs = n / 1_000_000;
49+
let nsecs = ((n % 1_000_000) * 1_000) as u32;
50+
51+
thread::sleep(Duration::new(secs, nsecs));
52+
Ok(())
53+
}
54+
}
55+
56+
impl DelayMs<u8> for Delay {
57+
type Error = Infallible;
58+
59+
fn delay_ms(&mut self, n: u8) -> Result<(), Self::Error> {
60+
thread::sleep(Duration::from_millis(u64(n)));
61+
Ok(())
62+
}
63+
}
64+
65+
impl DelayMs<u16> for Delay {
66+
type Error = Infallible;
67+
68+
fn delay_ms(&mut self, n: u16) -> Result<(), Self::Error> {
69+
thread::sleep(Duration::from_millis(u64(n)));
70+
Ok(())
71+
}
72+
}
73+
74+
impl DelayMs<u32> for Delay {
75+
type Error = Infallible;
76+
77+
fn delay_ms(&mut self, n: u32) -> Result<(), Self::Error> {
78+
thread::sleep(Duration::from_millis(u64(n)));
79+
Ok(())
80+
}
81+
}
82+
83+
impl DelayMs<u64> for Delay {
84+
type Error = Infallible;
85+
86+
fn delay_ms(&mut self, n: u64) -> Result<(), Self::Error> {
87+
thread::sleep(Duration::from_millis(n));
88+
Ok(())
89+
}
90+
}

src/i2c.rs

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
//! Implementation of [`embedded-hal`] I2C traits
2+
//!
3+
//! [`embedded-hal`]: https://docs.rs/embedded-hal
4+
5+
use std::ops;
6+
use std::path::{Path, PathBuf};
7+
8+
/// Newtype around [`i2cdev::linux::LinuxI2CDevice`] that implements the `embedded-hal` traits
9+
///
10+
/// [`i2cdev::linux::LinuxI2CDevice`]: https://docs.rs/i2cdev/0.3.1/i2cdev/linux/struct.LinuxI2CDevice.html
11+
pub struct I2cdev {
12+
inner: i2cdev::linux::LinuxI2CDevice,
13+
path: PathBuf,
14+
address: Option<u8>,
15+
}
16+
17+
impl I2cdev {
18+
/// See [`i2cdev::linux::LinuxI2CDevice::new`][0] for details.
19+
///
20+
/// [0]: https://docs.rs/i2cdev/0.3.1/i2cdev/linux/struct.LinuxI2CDevice.html#method.new
21+
pub fn new<P>(path: P) -> Result<Self, i2cdev::linux::LinuxI2CError>
22+
where
23+
P: AsRef<Path>,
24+
{
25+
let dev = I2cdev {
26+
path: path.as_ref().to_path_buf(),
27+
inner: i2cdev::linux::LinuxI2CDevice::new(path, 0)?,
28+
address: None,
29+
};
30+
Ok(dev)
31+
}
32+
33+
fn set_address(&mut self, address: u8) -> Result<(), i2cdev::linux::LinuxI2CError> {
34+
if self.address != Some(address) {
35+
self.inner = i2cdev::linux::LinuxI2CDevice::new(&self.path, u16::from(address))?;
36+
self.address = Some(address);
37+
}
38+
Ok(())
39+
}
40+
}
41+
42+
impl ops::Deref for I2cdev {
43+
type Target = i2cdev::linux::LinuxI2CDevice;
44+
45+
fn deref(&self) -> &Self::Target {
46+
&self.inner
47+
}
48+
}
49+
50+
impl ops::DerefMut for I2cdev {
51+
fn deref_mut(&mut self) -> &mut Self::Target {
52+
&mut self.inner
53+
}
54+
}
55+
56+
mod embedded_hal_impl {
57+
use super::*;
58+
use embedded_hal::i2c::blocking::{
59+
Operation as I2cOperation, Read, Transactional, Write, WriteRead,
60+
};
61+
use i2cdev::core::{I2CDevice, I2CMessage, I2CTransfer};
62+
use i2cdev::linux::LinuxI2CMessage;
63+
64+
impl Read for I2cdev {
65+
type Error = i2cdev::linux::LinuxI2CError;
66+
67+
fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
68+
self.set_address(address)?;
69+
self.inner.read(buffer)
70+
}
71+
}
72+
73+
impl Write for I2cdev {
74+
type Error = i2cdev::linux::LinuxI2CError;
75+
76+
fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> {
77+
self.set_address(address)?;
78+
self.inner.write(bytes)
79+
}
80+
}
81+
82+
impl WriteRead for I2cdev {
83+
type Error = i2cdev::linux::LinuxI2CError;
84+
85+
fn write_read(
86+
&mut self,
87+
address: u8,
88+
bytes: &[u8],
89+
buffer: &mut [u8],
90+
) -> Result<(), Self::Error> {
91+
self.set_address(address)?;
92+
let mut messages = [LinuxI2CMessage::write(bytes), LinuxI2CMessage::read(buffer)];
93+
self.inner.transfer(&mut messages).map(drop)
94+
}
95+
}
96+
97+
impl Transactional for I2cdev {
98+
type Error = i2cdev::linux::LinuxI2CError;
99+
100+
fn exec(
101+
&mut self,
102+
address: u8,
103+
operations: &mut [I2cOperation],
104+
) -> Result<(), Self::Error> {
105+
// Map operations from generic to linux objects
106+
let mut messages: Vec<_> = operations
107+
.as_mut()
108+
.iter_mut()
109+
.map(|a| match a {
110+
I2cOperation::Write(w) => LinuxI2CMessage::write(w),
111+
I2cOperation::Read(r) => LinuxI2CMessage::read(r),
112+
})
113+
.collect();
114+
115+
self.set_address(address)?;
116+
self.inner.transfer(&mut messages).map(drop)
117+
}
118+
}
119+
}

0 commit comments

Comments
 (0)