Skip to content

Commit 23fa418

Browse files
committed
Implement transactional I2C and add example using it
1 parent 4e55504 commit 23fa418

File tree

3 files changed

+60
-0
lines changed

3 files changed

+60
-0
lines changed

Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,7 @@ openpty = "0.1.0"
3232
# we don't need the `Error` implementation
3333
default-features = false
3434
version = "0.2.2"
35+
36+
37+
[patch.crates-io]
38+
embedded-hal = { git = "https://github.com/eldruin/embedded-hal", branch="transactional-i2c-address-modes" }

examples/transactional-i2c.rs

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
extern crate embedded_hal;
2+
extern crate linux_embedded_hal;
3+
use embedded_hal::blocking::i2c::{Operation as I2cOperation, Transactional};
4+
use linux_embedded_hal::I2cdev;
5+
6+
const ADDR: u8 = 0x12;
7+
8+
struct Driver<I2C> {
9+
i2c: I2C,
10+
}
11+
12+
impl<I2C> Driver<I2C>
13+
where
14+
I2C: Transactional,
15+
{
16+
pub fn new(i2c: I2C) -> Self {
17+
Driver { i2c }
18+
}
19+
20+
fn read_something(&mut self) -> Result<u8, I2C::Error> {
21+
let mut read_buffer = [0];
22+
let mut ops = [
23+
I2cOperation::Write(&[0xAB]),
24+
I2cOperation::Read(&mut read_buffer),
25+
];
26+
self.i2c.try_exec(ADDR, &mut ops).and(Ok(read_buffer[0]))
27+
}
28+
}
29+
30+
fn main() {
31+
let dev = I2cdev::new("/dev/i2c-1").unwrap();
32+
let mut driver = Driver::new(dev);
33+
let value = driver.read_something().unwrap();
34+
println!("Read value: {}", value);
35+
}

src/lib.rs

+21
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ use std::time::Duration;
3434
use std::{ops, thread};
3535

3636
use cast::{u32, u64};
37+
use hal::blocking::i2c::Operation as I2cOperation;
3738
use i2cdev::core::{I2CDevice, I2CMessage, I2CTransfer};
3839
use i2cdev::linux::LinuxI2CMessage;
3940
use spidev::SpidevTransfer;
@@ -207,6 +208,26 @@ impl hal::blocking::i2c::WriteRead for I2cdev {
207208
}
208209
}
209210

211+
impl hal::blocking::i2c::Transactional for I2cdev {
212+
type Error = i2cdev::linux::LinuxI2CError;
213+
214+
fn try_exec(&mut self, address: u8, operations: &mut [I2cOperation]) -> Result<(), Self::Error>
215+
{
216+
// Map operations from generic to linux objects
217+
let mut messages: Vec<_> = operations
218+
.as_mut()
219+
.iter_mut()
220+
.map(|a| match a {
221+
I2cOperation::Write(w) => LinuxI2CMessage::write(w),
222+
I2cOperation::Read(r) => LinuxI2CMessage::read(r),
223+
})
224+
.collect();
225+
226+
self.set_address(address)?;
227+
self.inner.transfer(&mut messages).map(drop)
228+
}
229+
}
230+
210231
impl ops::Deref for I2cdev {
211232
type Target = i2cdev::linux::LinuxI2CDevice;
212233

0 commit comments

Comments
 (0)