Skip to content

Commit a127f4f

Browse files
committed
Backport transactional I2C and add example using it
1 parent 60c2c41 commit a127f4f

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

examples/transactional-i2c.rs

Lines changed: 35 additions & 0 deletions
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.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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ use std::time::Duration;
3232
use std::{ops, thread};
3333

3434
use cast::{u32, u64};
35+
use hal::blocking::i2c::Operation as I2cOperation;
3536
use i2cdev::core::{I2CDevice, I2CMessage, I2CTransfer};
3637
use i2cdev::linux::LinuxI2CMessage;
3738
use spidev::SpidevTransfer;
@@ -181,6 +182,25 @@ impl hal::blocking::i2c::WriteRead for I2cdev {
181182
}
182183
}
183184

185+
impl hal::blocking::i2c::Transactional for I2cdev {
186+
type Error = i2cdev::linux::LinuxI2CError;
187+
188+
fn exec(&mut self, address: u8, operations: &mut [I2cOperation]) -> Result<(), Self::Error> {
189+
// Map operations from generic to linux objects
190+
let mut messages: Vec<_> = operations
191+
.as_mut()
192+
.iter_mut()
193+
.map(|a| match a {
194+
I2cOperation::Write(w) => LinuxI2CMessage::write(w),
195+
I2cOperation::Read(r) => LinuxI2CMessage::read(r),
196+
})
197+
.collect();
198+
199+
self.set_address(address)?;
200+
self.inner.transfer(&mut messages).map(drop)
201+
}
202+
}
203+
184204
impl ops::Deref for I2cdev {
185205
type Target = i2cdev::linux::LinuxI2CDevice;
186206

0 commit comments

Comments
 (0)