From 034a6a6399d2fa3908121a9540149083018b4f36 Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Wed, 17 Aug 2022 22:41:23 +0200 Subject: [PATCH] Add I2C exclusive device implementation --- embedded-hal-bus/CHANGELOG.md | 3 +- embedded-hal-bus/Cargo.toml | 3 +- embedded-hal-bus/src/i2c.rs | 57 +++++++++++++++++++++++++++++++++++ embedded-hal-bus/src/lib.rs | 1 + 4 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 embedded-hal-bus/src/i2c.rs diff --git a/embedded-hal-bus/CHANGELOG.md b/embedded-hal-bus/CHANGELOG.md index 168957e6e..f22df5f0c 100644 --- a/embedded-hal-bus/CHANGELOG.md +++ b/embedded-hal-bus/CHANGELOG.md @@ -7,7 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] -... +### Added +- `ExclusiveDevice` implementation for I2C. ## [v0.1.0-alpha.0] - 2022-08-17 diff --git a/embedded-hal-bus/Cargo.toml b/embedded-hal-bus/Cargo.toml index 17037163a..d423f227f 100644 --- a/embedded-hal-bus/Cargo.toml +++ b/embedded-hal-bus/Cargo.toml @@ -14,4 +14,5 @@ repository = "https://github.com/rust-embedded/embedded-hal" version = "0.1.0-alpha.0" [dependencies] -embedded-hal = { version = "=1.0.0-alpha.8", path = ".." } +#embedded-hal = { version = "=1.0.0-alpha.8", path = ".." } +embedded-hal = {git = "http://github.com/Dirbaio/embedded-hal", branch="i2c-bus-device"} diff --git a/embedded-hal-bus/src/i2c.rs b/embedded-hal-bus/src/i2c.rs new file mode 100644 index 000000000..c752560f4 --- /dev/null +++ b/embedded-hal-bus/src/i2c.rs @@ -0,0 +1,57 @@ +//! I2C bus sharing mechanisms. + +/// I2C bus sharing with blocking traits +pub mod blocking { + use embedded_hal::i2c::{ + blocking::{I2cBus, I2cDevice}, + ErrorType, + }; + + /// [`I2cDevice`] implementation with exclusive access to the bus (not shared). + /// + /// This is the most straightforward way of obtaining an [`I2cDevice`] from an [`I2cBus`], + /// ideal for when no sharing is required (only one I2C device is present on the bus). + #[derive(Debug)] + pub struct ExclusiveDevice { + bus: BUS, + } + + impl ExclusiveDevice { + /// Create a new `ExclusiveDevice` + pub fn new(bus: BUS) -> Self { + Self { bus } + } + } + + impl ErrorType for ExclusiveDevice + where + BUS: ErrorType, + { + type Error = BUS::Error; + } + + impl I2cDevice for ExclusiveDevice + where + BUS: I2cBus, + { + type Bus = BUS; + + fn transaction( + &mut self, + f: impl FnOnce(&mut Self::Bus) -> Result::Error>, + ) -> Result { + let f_res = f(&mut self.bus); + + // On failure, it's important to still stop and flush. + let stop_res = self.bus.stop(); + let flush_res = self.bus.flush(); + + // Note that in the case of multiple failures, only one error + // will be returned, in the following order. + let f_ok = f_res?; + stop_res?; + flush_res?; + Ok(f_ok) + } + } +} diff --git a/embedded-hal-bus/src/lib.rs b/embedded-hal-bus/src/lib.rs index 566e74b61..297c05cb8 100644 --- a/embedded-hal-bus/src/lib.rs +++ b/embedded-hal-bus/src/lib.rs @@ -14,4 +14,5 @@ #![warn(missing_docs)] #![no_std] +pub mod i2c; pub mod spi;