Skip to content

Update embedded-hal to version 1.0.0-alpha.5 #63

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Sep 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/bors.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ required_approvals = 1
status = [
"CI (stable, x86_64-unknown-linux-gnu)",
"CI (stable, armv7-unknown-linux-gnueabihf)",
"CI (1.36.0, x86_64-unknown-linux-gnu)",
"CI (1.46.0, x86_64-unknown-linux-gnu)",
]
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:

include:
# Test MSRV
- rust: 1.36.0
- rust: 1.46.0
TARGET: x86_64-unknown-linux-gnu

# Test nightly but don't fail
Expand Down
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Modified `OutputPin` behavior for active-low pins to match `InputPin` behavior.
- Set default features to build both sysfs and cdev pin types.
- Removed `Pin` export, use `CdevPin` or `SysfsPin`.
- Increased the Minimum Supported Rust Version to `1.36.0` due to an update of `gpio_cdev`.
- Adapted to `embedded-hal` `1.0.0-alpha.3` release.
- Increased the Minimum Supported Rust Version to `1.46.0` due to an update of `bitflags`.
- Adapted to `embedded-hal` `1.0.0-alpha.5` release.
- Updated `nb` to version `1`.

## [v0.3.0] - 2019-11-25
Expand Down
12 changes: 6 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,20 @@ async-tokio = ["gpio-cdev/async-tokio"]
default = [ "gpio_cdev", "gpio_sysfs" ]

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

i2cdev = "0.4.3"
i2cdev = "0.5"
nb = "1"
serial-core = "0.4.0"
serial-unix = "0.4.0"
spidev = "0.4"
spidev = "0.5"

[dev-dependencies]
openpty = "0.1.0"

[dependencies.cast]
# we don't need the `Error` implementation
default-features = false
version = "0.2.2"
version = "0.3"
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ linux-embedded-hal = { version = "0.3", features = ["gpio_cdev"] }

## Minimum Supported Rust Version (MSRV)

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

## License
Expand Down
6 changes: 2 additions & 4 deletions examples/transactional-i2c.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
extern crate embedded_hal;
extern crate linux_embedded_hal;
use embedded_hal::blocking::i2c::{Operation as I2cOperation, Transactional};
use embedded_hal::i2c::blocking::{Operation as I2cOperation, Transactional};
use linux_embedded_hal::I2cdev;

const ADDR: u8 = 0x12;
Expand All @@ -23,7 +21,7 @@ where
I2cOperation::Write(&[0xAB]),
I2cOperation::Read(&mut read_buffer),
];
self.i2c.try_exec(ADDR, &mut ops).and(Ok(read_buffer[0]))
self.i2c.exec(ADDR, &mut ops).and(Ok(read_buffer[0]))
}
}

Expand Down
18 changes: 10 additions & 8 deletions src/cdev_pin.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
//! Linux CDev pin type
//! Implementation of [`embedded-hal`] digital input/output traits using a Linux CDev pin
//!
//! [`embedded-hal`]: https://docs.rs/embedded-hal

/// Newtype around [`gpio_cdev::LineHandle`] that implements the `embedded-hal` traits
///
Expand All @@ -15,18 +17,18 @@ impl CdevPin {
}
}

impl embedded_hal::digital::OutputPin for CdevPin {
impl embedded_hal::digital::blocking::OutputPin for CdevPin {
type Error = gpio_cdev::errors::Error;

fn try_set_low(&mut self) -> Result<(), Self::Error> {
fn set_low(&mut self) -> Result<(), Self::Error> {
if self.1 {
self.0.set_value(1)
} else {
self.0.set_value(0)
}
}

fn try_set_high(&mut self) -> Result<(), Self::Error> {
fn set_high(&mut self) -> Result<(), Self::Error> {
if self.1 {
self.0.set_value(0)
} else {
Expand All @@ -35,19 +37,19 @@ impl embedded_hal::digital::OutputPin for CdevPin {
}
}

impl embedded_hal::digital::InputPin for CdevPin {
impl embedded_hal::digital::blocking::InputPin for CdevPin {
type Error = gpio_cdev::errors::Error;

fn try_is_high(&self) -> Result<bool, Self::Error> {
fn is_high(&self) -> Result<bool, Self::Error> {
if !self.1 {
self.0.get_value().map(|val| val != 0)
} else {
self.0.get_value().map(|val| val == 0)
}
}

fn try_is_low(&self) -> Result<bool, Self::Error> {
self.try_is_high().map(|val| !val)
fn is_low(&self) -> Result<bool, Self::Error> {
self.is_high().map(|val| !val)
}
}

Expand Down
90 changes: 90 additions & 0 deletions src/delay.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
//! Implementation of [`embedded-hal`] delay traits
//!
//! [`embedded-hal`]: https://docs.rs/embedded-hal

use cast::{u32, u64};
use core::convert::Infallible;
use embedded_hal::delay::blocking::{DelayMs, DelayUs};
use std::thread;
use std::time::Duration;

/// Empty struct that provides delay functionality on top of `thread::sleep`
pub struct Delay;

impl DelayUs<u8> for Delay {
type Error = Infallible;

fn delay_us(&mut self, n: u8) -> Result<(), Self::Error> {
thread::sleep(Duration::new(0, u32(n) * 1000));
Ok(())
}
}

impl DelayUs<u16> for Delay {
type Error = Infallible;

fn delay_us(&mut self, n: u16) -> Result<(), Self::Error> {
thread::sleep(Duration::new(0, u32(n) * 1000));
Ok(())
}
}

impl DelayUs<u32> for Delay {
type Error = Infallible;

fn delay_us(&mut self, n: u32) -> Result<(), Self::Error> {
let secs = n / 1_000_000;
let nsecs = (n % 1_000_000) * 1_000;

thread::sleep(Duration::new(u64(secs), nsecs));
Ok(())
}
}

impl DelayUs<u64> for Delay {
type Error = Infallible;

fn delay_us(&mut self, n: u64) -> Result<(), Self::Error> {
let secs = n / 1_000_000;
let nsecs = ((n % 1_000_000) * 1_000) as u32;

thread::sleep(Duration::new(secs, nsecs));
Ok(())
}
}

impl DelayMs<u8> for Delay {
type Error = Infallible;

fn delay_ms(&mut self, n: u8) -> Result<(), Self::Error> {
thread::sleep(Duration::from_millis(u64(n)));
Ok(())
}
}

impl DelayMs<u16> for Delay {
type Error = Infallible;

fn delay_ms(&mut self, n: u16) -> Result<(), Self::Error> {
thread::sleep(Duration::from_millis(u64(n)));
Ok(())
}
}

impl DelayMs<u32> for Delay {
type Error = Infallible;

fn delay_ms(&mut self, n: u32) -> Result<(), Self::Error> {
thread::sleep(Duration::from_millis(u64(n)));
Ok(())
}
}

impl DelayMs<u64> for Delay {
type Error = Infallible;

fn delay_ms(&mut self, n: u64) -> Result<(), Self::Error> {
thread::sleep(Duration::from_millis(n));
Ok(())
}
}
119 changes: 119 additions & 0 deletions src/i2c.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
//! Implementation of [`embedded-hal`] I2C traits
//!
//! [`embedded-hal`]: https://docs.rs/embedded-hal

use std::ops;
use std::path::{Path, PathBuf};

/// 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
pub struct I2cdev {
inner: i2cdev::linux::LinuxI2CDevice,
path: PathBuf,
address: Option<u8>,
}

impl I2cdev {
/// See [`i2cdev::linux::LinuxI2CDevice::new`][0] for details.
///
/// [0]: https://docs.rs/i2cdev/0.3.1/i2cdev/linux/struct.LinuxI2CDevice.html#method.new
pub fn new<P>(path: P) -> Result<Self, i2cdev::linux::LinuxI2CError>
where
P: AsRef<Path>,
{
let dev = I2cdev {
path: path.as_ref().to_path_buf(),
inner: i2cdev::linux::LinuxI2CDevice::new(path, 0)?,
address: None,
};
Ok(dev)
}

fn set_address(&mut self, address: u8) -> Result<(), i2cdev::linux::LinuxI2CError> {
if self.address != Some(address) {
self.inner = i2cdev::linux::LinuxI2CDevice::new(&self.path, u16::from(address))?;
self.address = Some(address);
}
Ok(())
}
}

impl ops::Deref for I2cdev {
type Target = i2cdev::linux::LinuxI2CDevice;

fn deref(&self) -> &Self::Target {
&self.inner
}
}

impl ops::DerefMut for I2cdev {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}

mod embedded_hal_impl {
use super::*;
use embedded_hal::i2c::blocking::{
Operation as I2cOperation, Read, Transactional, Write, WriteRead,
};
use i2cdev::core::{I2CDevice, I2CMessage, I2CTransfer};
use i2cdev::linux::LinuxI2CMessage;

impl Read for I2cdev {
type Error = i2cdev::linux::LinuxI2CError;

fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
self.set_address(address)?;
self.inner.read(buffer)
}
}

impl Write for I2cdev {
type Error = i2cdev::linux::LinuxI2CError;

fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> {
self.set_address(address)?;
self.inner.write(bytes)
}
}

impl WriteRead for I2cdev {
type Error = i2cdev::linux::LinuxI2CError;

fn write_read(
&mut self,
address: u8,
bytes: &[u8],
buffer: &mut [u8],
) -> Result<(), Self::Error> {
self.set_address(address)?;
let mut messages = [LinuxI2CMessage::write(bytes), LinuxI2CMessage::read(buffer)];
self.inner.transfer(&mut messages).map(drop)
}
}

impl Transactional for I2cdev {
type Error = i2cdev::linux::LinuxI2CError;

fn exec(
&mut self,
address: u8,
operations: &mut [I2cOperation],
) -> Result<(), Self::Error> {
// Map operations from generic to linux objects
let mut messages: Vec<_> = operations
.as_mut()
.iter_mut()
.map(|a| match a {
I2cOperation::Write(w) => LinuxI2CMessage::write(w),
I2cOperation::Read(r) => LinuxI2CMessage::read(r),
})
.collect();

self.set_address(address)?;
self.inner.transfer(&mut messages).map(drop)
}
}
}
Loading