Skip to content

Commit 1c7312d

Browse files
committed
Extract i2c into separate module
1 parent 0c1a0bb commit 1c7312d

File tree

2 files changed

+120
-107
lines changed

2 files changed

+120
-107
lines changed

src/i2c.rs

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

src/lib.rs

Lines changed: 3 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,11 @@ pub use gpio_cdev;
2727

2828
use core::convert::Infallible;
2929
use std::io::{self, Write};
30-
use std::path::{Path, PathBuf};
30+
use std::path::Path;
3131
use std::time::Duration;
3232
use std::{ops, thread};
3333

3434
use cast::{u32, u64};
35-
use embedded_hal::blocking::i2c::Operation as I2cOperation;
36-
use i2cdev::core::{I2CDevice, I2CMessage, I2CTransfer};
37-
use i2cdev::linux::LinuxI2CMessage;
3835
use spidev::SpidevTransfer;
3936

4037
mod serial;
@@ -139,109 +136,8 @@ impl embedded_hal::blocking::delay::DelayMs<u64> for Delay {
139136
}
140137
}
141138

142-
/// Newtype around [`i2cdev::linux::LinuxI2CDevice`] that implements the `embedded-hal` traits
143-
///
144-
/// [`i2cdev::linux::LinuxI2CDevice`]: https://docs.rs/i2cdev/0.3.1/i2cdev/linux/struct.LinuxI2CDevice.html
145-
pub struct I2cdev {
146-
inner: i2cdev::linux::LinuxI2CDevice,
147-
path: PathBuf,
148-
address: Option<u8>,
149-
}
150-
151-
impl I2cdev {
152-
/// See [`i2cdev::linux::LinuxI2CDevice::new`][0] for details.
153-
///
154-
/// [0]: https://docs.rs/i2cdev/0.3.1/i2cdev/linux/struct.LinuxI2CDevice.html#method.new
155-
pub fn new<P>(path: P) -> Result<Self, i2cdev::linux::LinuxI2CError>
156-
where
157-
P: AsRef<Path>,
158-
{
159-
let dev = I2cdev {
160-
path: path.as_ref().to_path_buf(),
161-
inner: i2cdev::linux::LinuxI2CDevice::new(path, 0)?,
162-
address: None,
163-
};
164-
Ok(dev)
165-
}
166-
167-
fn set_address(&mut self, address: u8) -> Result<(), i2cdev::linux::LinuxI2CError> {
168-
if self.address != Some(address) {
169-
self.inner = i2cdev::linux::LinuxI2CDevice::new(&self.path, u16::from(address))?;
170-
self.address = Some(address);
171-
}
172-
Ok(())
173-
}
174-
}
175-
176-
impl embedded_hal::blocking::i2c::Read for I2cdev {
177-
type Error = i2cdev::linux::LinuxI2CError;
178-
179-
fn try_read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
180-
self.set_address(address)?;
181-
self.inner.read(buffer)
182-
}
183-
}
184-
185-
impl embedded_hal::blocking::i2c::Write for I2cdev {
186-
type Error = i2cdev::linux::LinuxI2CError;
187-
188-
fn try_write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> {
189-
self.set_address(address)?;
190-
self.inner.write(bytes)
191-
}
192-
}
193-
194-
impl embedded_hal::blocking::i2c::WriteRead for I2cdev {
195-
type Error = i2cdev::linux::LinuxI2CError;
196-
197-
fn try_write_read(
198-
&mut self,
199-
address: u8,
200-
bytes: &[u8],
201-
buffer: &mut [u8],
202-
) -> Result<(), Self::Error> {
203-
self.set_address(address)?;
204-
let mut messages = [LinuxI2CMessage::write(bytes), LinuxI2CMessage::read(buffer)];
205-
self.inner.transfer(&mut messages).map(drop)
206-
}
207-
}
208-
209-
impl embedded_hal::blocking::i2c::Transactional for I2cdev {
210-
type Error = i2cdev::linux::LinuxI2CError;
211-
212-
fn try_exec(
213-
&mut self,
214-
address: u8,
215-
operations: &mut [I2cOperation],
216-
) -> Result<(), Self::Error> {
217-
// Map operations from generic to linux objects
218-
let mut messages: Vec<_> = operations
219-
.as_mut()
220-
.iter_mut()
221-
.map(|a| match a {
222-
I2cOperation::Write(w) => LinuxI2CMessage::write(w),
223-
I2cOperation::Read(r) => LinuxI2CMessage::read(r),
224-
})
225-
.collect();
226-
227-
self.set_address(address)?;
228-
self.inner.transfer(&mut messages).map(drop)
229-
}
230-
}
231-
232-
impl ops::Deref for I2cdev {
233-
type Target = i2cdev::linux::LinuxI2CDevice;
234-
235-
fn deref(&self) -> &Self::Target {
236-
&self.inner
237-
}
238-
}
239-
240-
impl ops::DerefMut for I2cdev {
241-
fn deref_mut(&mut self) -> &mut Self::Target {
242-
&mut self.inner
243-
}
244-
}
139+
mod i2c;
140+
pub use crate::i2c::I2cdev;
245141

246142
/// Newtype around [`spidev::Spidev`] that implements the `embedded-hal` traits
247143
///

0 commit comments

Comments
 (0)