1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
use std::ops;
use std::path::{Path, PathBuf};
pub struct I2cdev {
inner: i2cdev::linux::LinuxI2CDevice,
path: PathBuf,
address: Option<u8>,
}
impl I2cdev {
pub fn new<P>(path: P) -> Result<Self, i2cdev::linux::LinuxI2CError>
where
P: AsRef<Path>,
{
let dev = I2cdev {
path: path.as_ref().to_path_buf(),
inner: i2cdev::linux::LinuxI2CDevice::new(path, 0)?,
address: None,
};
Ok(dev)
}
fn set_address(&mut self, address: u8) -> Result<(), i2cdev::linux::LinuxI2CError> {
if self.address != Some(address) {
self.inner = i2cdev::linux::LinuxI2CDevice::new(&self.path, u16::from(address))?;
self.address = Some(address);
}
Ok(())
}
}
impl ops::Deref for I2cdev {
type Target = i2cdev::linux::LinuxI2CDevice;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl ops::DerefMut for I2cdev {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
mod embedded_hal_impl {
use super::*;
use embedded_hal::i2c::blocking::{
Operation as I2cOperation, Read, Transactional, Write, WriteRead,
};
use i2cdev::core::{I2CDevice, I2CMessage, I2CTransfer};
use i2cdev::linux::LinuxI2CMessage;
impl Read for I2cdev {
type Error = i2cdev::linux::LinuxI2CError;
fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
self.set_address(address)?;
self.inner.read(buffer)
}
}
impl Write for I2cdev {
type Error = i2cdev::linux::LinuxI2CError;
fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> {
self.set_address(address)?;
self.inner.write(bytes)
}
}
impl WriteRead for I2cdev {
type Error = i2cdev::linux::LinuxI2CError;
fn write_read(
&mut self,
address: u8,
bytes: &[u8],
buffer: &mut [u8],
) -> Result<(), Self::Error> {
self.set_address(address)?;
let mut messages = [LinuxI2CMessage::write(bytes), LinuxI2CMessage::read(buffer)];
self.inner.transfer(&mut messages).map(drop)
}
}
impl Transactional for I2cdev {
type Error = i2cdev::linux::LinuxI2CError;
fn exec(
&mut self,
address: u8,
operations: &mut [I2cOperation],
) -> Result<(), Self::Error> {
let mut messages: Vec<_> = operations
.as_mut()
.iter_mut()
.map(|a| match a {
I2cOperation::Write(w) => LinuxI2CMessage::write(w),
I2cOperation::Read(r) => LinuxI2CMessage::read(r),
})
.collect();
self.set_address(address)?;
self.inner.transfer(&mut messages).map(drop)
}
}
}