Skip to content

Commit

Permalink
Update to embedded-hal 1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
eldruin committed Jul 27, 2024
1 parent 94e0e1b commit 53e5b85
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 74 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## [Unreleased] - ReleaseDate

### Changed
- Update to `embedded-hal` 1.0.
- The MSRV is now 1.62.0.

## [0.2.1] - 2020-08-13
Expand Down
9 changes: 3 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,11 @@ include = [
]

[dependencies]
embedded-hal = "0.2"
embedded-hal = "1"

[dev-dependencies]
linux-embedded-hal = "0.3"
embedded-hal-mock = "0.7"
linux-embedded-hal = "0.4"
embedded-hal-mock = { version = "0.11", default-features = false, features = ["eh1"] }

[profile.release]
lto = true

[features]
default = []
5 changes: 3 additions & 2 deletions examples/linux.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use embedded_hal::blocking::i2c::{Read, Write, WriteRead};
use embedded_hal::i2c::I2c;
use linux_embedded_hal::I2cdev;
use xca9548a::{Error, SlaveAddr, Xca9548a};

Expand Down Expand Up @@ -51,7 +51,8 @@ struct Driver<I2C> {

impl<I2C, E> Driver<I2C>
where
I2C: Write<Error = E> + Read<Error = E> + WriteRead<Error = E>,
I2C: I2c<Error = E>,
E: core::fmt::Debug,
{
pub fn new(i2c: I2C) -> Self {
Driver { i2c }
Expand Down
89 changes: 54 additions & 35 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
//! ### Reading and writing to device connected to channel 0 (SD0/SC0 pins)
//!
//! ```no_run
//! use embedded_hal::blocking::i2c::{ Read, Write };
//! use embedded_hal::i2c::I2c;
//! use linux_embedded_hal::I2cdev;
//! use xca9548a::{Xca9548a, SlaveAddr};
//!
Expand Down Expand Up @@ -111,7 +111,7 @@
//! Switching will be done automatically as necessary.
//!
//! ```no_run
//! use embedded_hal::blocking::i2c::{Read, Write, WriteRead};
//! use embedded_hal::i2c::I2c;
//! use linux_embedded_hal::I2cdev;
//! use xca9548a::{Xca9548a, SlaveAddr};
//!
Expand All @@ -122,7 +122,7 @@
//! }
//!
//! impl<I2C, E> Driver<I2C>
//! where I2C: Write<Error = E> + Read<Error = E> + WriteRead<Error = E> {
//! where I2C: I2c<Error = E> {
//! pub fn new(i2c: I2C) -> Self {
//! Driver { i2c }
//! }
Expand All @@ -143,7 +143,7 @@
//! Switching will be done automatically as necessary.
//!
//! ```no_run
//! use embedded_hal::blocking::i2c::{ Read, Write };
//! use embedded_hal::i2c::I2c;
//! use linux_embedded_hal::I2cdev;
//! use xca9548a::{Xca9548a, SlaveAddr};
//!
Expand All @@ -169,11 +169,11 @@
#![no_std]

use core::cell;
use embedded_hal::blocking::i2c;
use embedded_hal::i2c as ehal;

/// All possible errors in this crate
#[derive(Debug)]
pub enum Error<E> {
pub enum Error<E: core::fmt::Debug> {
/// I²C bus error
I2C(E),
/// Could not acquire device. Maybe it is already acquired.
Expand Down Expand Up @@ -221,7 +221,8 @@ pub struct Xca954xaData<I2C> {

impl<I2C, E> SelectChannels for Xca954xaData<I2C>
where
I2C: i2c::Write<Error = E>,
I2C: ehal::I2c<Error = E>,
E: core::fmt::Debug,
{
type Error = Error<E>;
fn select_channels(&mut self, channels: u8) -> Result<(), Self::Error> {
Expand All @@ -235,7 +236,7 @@ where

#[doc(hidden)]
pub trait DoOnAcquired<I2C>: private::Sealed {
fn do_on_acquired<R, E>(
fn do_on_acquired<R, E: ehal::Error>(
&self,
f: impl FnOnce(cell::RefMut<Xca954xaData<I2C>>) -> Result<R, Error<E>>,
) -> Result<R, Error<E>>;
Expand All @@ -260,14 +261,27 @@ pub struct Xca9543a<I2C> {
}

/// Device driver for T/PCA9545A
#[derive(Debug, Default)]
pub struct Xca9545a<I2C> {
pub(crate) data: cell::RefCell<Xca954xaData<I2C>>,
}

impl<E> ehal::Error for Error<E>
where
E: ehal::Error,
{
fn kind(&self) -> ehal::ErrorKind {
match self {
Error::I2C(e) => e.kind(),
Error::CouldNotAcquireDevice => ehal::ErrorKind::Other,
}
}
}

macro_rules! i2c_traits {
( $name:ident ) => {
impl<I2C> DoOnAcquired<I2C> for $name<I2C> {
fn do_on_acquired<R, E>(
fn do_on_acquired<R, E: ehal::Error>(
&self,
f: impl FnOnce(cell::RefMut<Xca954xaData<I2C>>) -> Result<R, Error<E>>,
) -> Result<R, Error<E>> {
Expand All @@ -279,44 +293,45 @@ macro_rules! i2c_traits {
}
}

impl<I2C, E> i2c::Write for $name<I2C>
impl<I2C, E> ehal::ErrorType for $name<I2C>
where
I2C: i2c::Write<Error = E>,
I2C: ehal::I2c<Error = E>,
E: ehal::Error,
{
type Error = Error<E>;

fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> {
self.do_on_acquired(|mut dev| dev.i2c.write(address, bytes).map_err(Error::I2C))
}
}

impl<I2C, E> i2c::Read for $name<I2C>
impl<I2C, E> ehal::I2c for $name<I2C>
where
I2C: i2c::Read<Error = E>,
I2C: ehal::I2c<Error = E>,
E: ehal::Error,
{
type Error = Error<E>;
fn transaction(
&mut self,
address: u8,
operations: &mut [ehal::Operation<'_>],
) -> Result<(), Error<E>> {
self.do_on_acquired(|mut dev| {
dev.i2c.transaction(address, operations).map_err(Error::I2C)
})
}

fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
self.do_on_acquired(|mut dev| dev.i2c.read(address, buffer).map_err(Error::I2C))
fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> {
self.do_on_acquired(|mut dev| dev.i2c.read(address, read).map_err(Error::I2C))
}
}

impl<I2C, E> i2c::WriteRead for $name<I2C>
where
I2C: i2c::WriteRead<Error = E>,
{
type Error = Error<E>;
fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> {
self.do_on_acquired(|mut dev| dev.i2c.write(address, write).map_err(Error::I2C))
}

fn write_read(
&mut self,
address: u8,
bytes: &[u8],
buffer: &mut [u8],
write: &[u8],
read: &mut [u8],
) -> Result<(), Self::Error> {
self.do_on_acquired(|mut dev| {
dev.i2c
.write_read(address, bytes, buffer)
.map_err(Error::I2C)
dev.i2c.write_read(address, write, read).map_err(Error::I2C)
})
}
}
Expand Down Expand Up @@ -358,7 +373,8 @@ macro_rules! impl_device {

impl<I2C, E> $name<I2C>
where
I2C: i2c::Read<Error = E>,
I2C: ehal::I2c<Error = E>,
E: ehal::Error,
{
/// Get status of channels.
///
Expand All @@ -380,7 +396,8 @@ macro_rules! impl_device {

impl<I2C, E> $name<I2C>
where
I2C: i2c::Write<Error = E>,
I2C: ehal::I2c<Error = E>,
E: ehal::Error,
{
/// Select which channels are enabled.
///
Expand All @@ -399,7 +416,8 @@ macro_rules! impl_device {

impl<I2C, E> $name<I2C>
where
I2C: i2c::Read<Error = E>,
I2C: ehal::I2c<Error = E>,
E: ehal::Error,
{
/// Get status of channels.
///
Expand Down Expand Up @@ -437,7 +455,8 @@ macro_rules! impl_device {

impl<I2C, E> $name<I2C>
where
I2C: i2c::Write<Error = E>,
I2C: ehal::I2c<Error = E>,
E: ehal::Error,
{
/// Select which channels are enabled.
///
Expand Down
57 changes: 30 additions & 27 deletions src/parts.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{DoOnAcquired, Error, SelectChannels};
use core::marker::PhantomData;
use embedded_hal::blocking::i2c;
use embedded_hal::i2c as ehal;

/// Slave I2C device
pub struct I2cSlave<'a, DEV: 'a, I2C>(&'a DEV, u8, PhantomData<I2C>);
Expand Down Expand Up @@ -37,60 +37,63 @@ parts!(
Parts4; i2c0, 0x01, i2c1, 0x02, i2c2, 0x04, i2c3, 0x08
);

impl<'a, DEV, I2C, E> i2c::Write for I2cSlave<'a, DEV, I2C>
impl<'a, DEV, I2C, E> ehal::ErrorType for I2cSlave<'a, DEV, I2C>
where
DEV: DoOnAcquired<I2C>,
I2C: i2c::Write<Error = E>,
I2C: ehal::I2c<Error = E>,
E: ehal::Error,
{
type Error = Error<E>;
}

fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> {
impl<'a, DEV, I2C, E> ehal::I2c for I2cSlave<'a, DEV, I2C>
where
DEV: DoOnAcquired<I2C>,
I2C: ehal::I2c<Error = E>,
E: ehal::Error,
{
fn transaction(
&mut self,
address: u8,
operations: &mut [ehal::Operation<'_>],
) -> Result<(), Self::Error> {
self.0.do_on_acquired(|mut dev| {
if dev.selected_channel_mask != self.1 {
dev.select_channels(self.1)?;
}
dev.i2c.write(address, bytes).map_err(Error::I2C)
dev.i2c.transaction(address, operations).map_err(Error::I2C)
})
}
}

impl<'a, DEV, I2C, E> i2c::Read for I2cSlave<'a, DEV, I2C>
where
DEV: DoOnAcquired<I2C>,
I2C: i2c::Write<Error = E> + i2c::Read<Error = E>,
{
type Error = Error<E>;

fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> {
self.0.do_on_acquired(|mut dev| {
if dev.selected_channel_mask != self.1 {
dev.select_channels(self.1)?;
}
dev.i2c.read(address, buffer).map_err(Error::I2C)
dev.i2c.read(address, read).map_err(Error::I2C)
})
}
}

impl<'a, DEV, I2C, E> i2c::WriteRead for I2cSlave<'a, DEV, I2C>
where
DEV: DoOnAcquired<I2C>,
I2C: i2c::Write<Error = E> + i2c::WriteRead<Error = E>,
{
type Error = Error<E>;
fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> {
self.0.do_on_acquired(|mut dev| {
if dev.selected_channel_mask != self.1 {
dev.select_channels(self.1)?;
}
dev.i2c.write(address, write).map_err(Error::I2C)
})
}

fn write_read(
&mut self,
address: u8,
bytes: &[u8],
buffer: &mut [u8],
write: &[u8],
read: &mut [u8],
) -> Result<(), Self::Error> {
self.0.do_on_acquired(|mut dev| {
if dev.selected_channel_mask != self.1 {
dev.select_channels(self.1)?;
}
dev.i2c
.write_read(address, bytes, buffer)
.map_err(Error::I2C)
dev.i2c.write_read(address, write, read).map_err(Error::I2C)
})
}
}
8 changes: 4 additions & 4 deletions tests/tests.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use embedded_hal_mock::i2c::{Mock as I2cMock, Transaction as I2cTrans};
use embedded_hal_mock::eh1::i2c::{Mock as I2cMock, Transaction as I2cTrans};
use xca9548a::{SlaveAddr, Xca9543a, Xca9545a, Xca9548a};

const DEV_ADDR: u8 = 0b111_0000;
Expand Down Expand Up @@ -159,14 +159,14 @@ macro_rules! test_device {

mod test_xca9548a {
use super::*;
use embedded_hal::blocking::i2c::{Read, Write, WriteRead};
use embedded_hal::i2c::I2c;

test_device!(Xca9548a, 0xff);
}

mod test_xca9545a {
use super::*;
use embedded_hal::blocking::i2c::{Read, Write, WriteRead};
use embedded_hal::i2c::I2c;

test_device!(Xca9545a, 0x0f);
test_interrupt!(Xca9545a, 0x0f);
Expand All @@ -175,7 +175,7 @@ mod test_xca9545a {

mod test_xca9543a {
use super::*;
use embedded_hal::blocking::i2c::{Read, Write, WriteRead};
use embedded_hal::i2c::I2c;

test_device!(Xca9543a, 0x03);
test_interrupt!(Xca9543a, 0x03);
Expand Down

0 comments on commit 53e5b85

Please sign in to comment.