Skip to content

Commit 8edd7d0

Browse files
committed
reconstructs LinuxI2CDevice if slave address has changed
1 parent 272b9d2 commit 8edd7d0

File tree

1 file changed

+33
-13
lines changed

1 file changed

+33
-13
lines changed

src/lib.rs

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub extern crate spidev;
2020
pub extern crate sysfs_gpio;
2121

2222
use std::io::{self, Write};
23-
use std::path::Path;
23+
use std::path::{Path, PathBuf};
2424
use std::time::Duration;
2525
use std::{ops, thread};
2626

@@ -144,33 +144,52 @@ impl ops::DerefMut for Pin {
144144
/// Newtype around [`i2cdev::linux::LinuxI2CDevice`] that implements the `embedded-hal` traits
145145
///
146146
/// [`i2cdev::linux::LinuxI2CDevice`]: https://docs.rs/i2cdev/0.3.1/i2cdev/linux/struct.LinuxI2CDevice.html
147-
pub struct I2cdev(pub i2cdev::linux::LinuxI2CDevice);
147+
pub struct I2cdev {
148+
inner: i2cdev::linux::LinuxI2CDevice,
149+
path: PathBuf,
150+
address: Option<u8>,
151+
}
148152

149153
impl I2cdev {
150154
/// See [`i2cdev::linux::LinuxI2CDevice::new`][0] for details.
151155
///
152156
/// [0]: https://docs.rs/i2cdev/0.3.1/i2cdev/linux/struct.LinuxI2CDevice.html#method.new
153-
pub fn new<P>(path: P, address: u16) -> Result<Self, i2cdev::linux::LinuxI2CError>
157+
pub fn new<P>(path: P) -> Result<Self, i2cdev::linux::LinuxI2CError>
154158
where
155159
P: AsRef<Path>,
156160
{
157-
i2cdev::linux::LinuxI2CDevice::new(path, address).map(I2cdev)
161+
let dev = I2cdev {
162+
path: path.as_ref().to_path_buf(),
163+
inner: i2cdev::linux::LinuxI2CDevice::new(path, 0)?,
164+
address: None,
165+
};
166+
Ok(dev)
167+
}
168+
169+
fn set_address(&mut self, address: u8) -> Result<(), i2cdev::linux::LinuxI2CError> {
170+
if self.address != Some(address) {
171+
self.inner = i2cdev::linux::LinuxI2CDevice::new(&self.path, address as u16)?;
172+
self.address = Some(address);
173+
}
174+
Ok(())
158175
}
159176
}
160177

161178
impl hal::blocking::i2c::Read for I2cdev {
162179
type Error = i2cdev::linux::LinuxI2CError;
163180

164-
fn read(&mut self, _address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
165-
self.0.read(buffer)
181+
fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
182+
self.set_address(address)?;
183+
self.inner.read(buffer)
166184
}
167185
}
168186

169187
impl hal::blocking::i2c::Write for I2cdev {
170188
type Error = i2cdev::linux::LinuxI2CError;
171189

172-
fn write(&mut self, _address: u8, bytes: &[u8]) -> Result<(), Self::Error> {
173-
self.0.write(bytes)
190+
fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> {
191+
self.set_address(address)?;
192+
self.inner.write(bytes)
174193
}
175194
}
176195

@@ -179,26 +198,27 @@ impl hal::blocking::i2c::WriteRead for I2cdev {
179198

180199
fn write_read(
181200
&mut self,
182-
_address: u8,
201+
address: u8,
183202
bytes: &[u8],
184203
buffer: &mut [u8],
185204
) -> Result<(), Self::Error> {
186-
self.0.write(bytes)?;
187-
self.0.read(buffer)
205+
self.set_address(address)?;
206+
self.inner.write(bytes)?;
207+
self.inner.read(buffer)
188208
}
189209
}
190210

191211
impl ops::Deref for I2cdev {
192212
type Target = i2cdev::linux::LinuxI2CDevice;
193213

194214
fn deref(&self) -> &Self::Target {
195-
&self.0
215+
&self.inner
196216
}
197217
}
198218

199219
impl ops::DerefMut for I2cdev {
200220
fn deref_mut(&mut self) -> &mut Self::Target {
201-
&mut self.0
221+
&mut self.inner
202222
}
203223
}
204224

0 commit comments

Comments
 (0)