Skip to content

Commit

Permalink
Merge pull request #30 from hawkw/eliza/async
Browse files Browse the repository at this point in the history
Add support for `embedded-hal-async`
  • Loading branch information
psachs authored May 23, 2024
2 parents a77da31 + 6dde55b commit f7b9f3a
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 3 deletions.
6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ edition = "2018"

[dependencies]
embedded-hal = "1.0"

embedded-hal-async = { version = "1.0", optional = true }

[dev-dependencies]
embedded-hal-mock = { version = "0.10", features = ["eh1"] }

[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
4 changes: 2 additions & 2 deletions src/i2c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ use embedded_hal::i2c;

/// All possible errors in this crate
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum Error<I: i2c::I2c> {
pub enum Error<I: i2c::ErrorType> {
I2cWrite(I::Error),
I2cRead(I::Error),
Crc,
}

impl<I: i2c::I2c> From<crc8::Error> for Error<I> {
impl<I: i2c::ErrorType> From<crc8::Error> for Error<I> {
fn from(err: crc8::Error) -> Error<I> {
match err {
crc8::Error::CrcError => Error::Crc,
Expand Down
60 changes: 60 additions & 0 deletions src/i2c_async.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//! [`embedded-hal-async`] helper functions for I²C communication.
//!
//! These functions are identical to the helpers in the [`i2c`](crate::i2c)
//! module, except that they use the async I²C traits from [`embedded-hal-async`]
//! rther than the blocking I²C traits from `embedded-hal`.
//!
//! [`embedded-hal-async`]: https://crates.io/crates/embedded-hal-async
use crate::crc8;
use embedded_hal_async::i2c;

pub use crate::i2c::Error;

/// Write an u8 command to the I²C bus.
pub async fn write_command_u8<I: i2c::I2c>(
i2c: &mut I,
addr: u8,
command: u8,
) -> Result<(), I::Error> {
i2c.write(addr, &command.to_be_bytes()).await
}

/// Write an u16 command to the I²C bus.
pub async fn write_command_u16<I: i2c::I2c>(
i2c: &mut I,
addr: u8,
command: u16,
) -> Result<(), I::Error> {
i2c.write(addr, &command.to_be_bytes()).await
}

/// Read data into the provided buffer and validate the CRC8 checksum.
///
/// If the checksum is wrong, return `Error::Crc`.
///
/// # Panics
///
/// This method will consider every third byte a checksum byte. If the buffer size is not a
/// multiple of 3, then it will panic.
pub async fn read_words_with_crc<I: i2c::I2c>(
i2c: &mut I,
addr: u8,
data: &mut [u8],
) -> Result<(), Error<I>> {
assert!(
data.len() % 3 == 0,
"Buffer must hold a multiple of 3 bytes"
);
i2c.read(addr, data).await.map_err(Error::I2cRead)?;
crc8::validate(data)?;
Ok(())
}

#[cfg(test)]
mod tests {
// TODO: `embedded-hal-mock`'s support for `embedded-hal-async` does not
// currently have a mock I2C implementation. When that's available, we
// should add tests for the async I2C functions here that are analogous to
// the ones in the `i2c` module.
}
13 changes: 13 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,22 @@
//! i2c::write_command_u16(&mut i2c_mock, 0x12, 0x3456);
//! i2c_mock.done();
//! ```
//!
//! #### `embedded-hal-async`
//!
//! The `i2c_async` module provides versions of the I2C helpers in this crate
//! that use the [`embedded-hal-async`
//! crate](https://crates.io/crates/embedded-hal-async), rather than the
//! blocking I2C traits from `embedded-hal`.
//!
//! This module is only available when the `embedded-hal-async`
//! Cargo feature is enabled.
#![deny(unsafe_code)]
#![cfg_attr(not(test), no_std)]
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]

pub mod crc8;
pub mod i2c;
#[cfg(feature = "embedded-hal-async")]
pub mod i2c_async;

0 comments on commit f7b9f3a

Please sign in to comment.