Skip to content

Commit b0d99b5

Browse files
bors[bot]eldruin
andauthored
Merge #260
260: Transactional I2C address modes r=ryankurte a=eldruin The transactional I2C traits did not support multiple address modes. Thanks to @ryankurte for noticing this at rust-embedded/linux-embedded-hal#44 Co-authored-by: Diego Barrios Romero <[email protected]>
2 parents a5789bf + ba03c1a commit b0d99b5

File tree

2 files changed

+51
-15
lines changed

2 files changed

+51
-15
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1111

1212
### Changed
1313

14+
### Fixed
15+
- Support for I2C addressing modes in `Transactional` I2C traits.
1416

1517
## [v1.0.0-alpha.3] - 2020-11-04
1618

src/blocking/i2c.rs

+49-15
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ pub enum Operation<'a> {
247247
/// Transactional I2C interface.
248248
///
249249
/// This allows combining operations within an I2C transaction.
250-
pub trait Transactional {
250+
pub trait Transactional<A: AddressMode = SevenBitAddress> {
251251
/// Error type
252252
type Error;
253253

@@ -266,15 +266,15 @@ pub trait Transactional {
266266
/// - `SP` = stop condition
267267
fn try_exec<'a>(
268268
&mut self,
269-
address: u8,
269+
address: A,
270270
operations: &mut [Operation<'a>],
271271
) -> Result<(), Self::Error>;
272272
}
273273

274274
/// Transactional I2C interface (iterator version).
275275
///
276276
/// This allows combining operation within an I2C transaction.
277-
pub trait TransactionalIter {
277+
pub trait TransactionalIter<A: AddressMode = SevenBitAddress> {
278278
/// Error type
279279
type Error;
280280

@@ -291,51 +291,85 @@ pub trait TransactionalIter {
291291
/// - `SAD+R/W` = slave address followed by bit 1 to indicate reading or 0 to indicate writing
292292
/// - `SR` = repeated start condition
293293
/// - `SP` = stop condition
294-
fn try_exec_iter<'a, O>(&mut self, address: u8, operations: O) -> Result<(), Self::Error>
294+
fn try_exec_iter<'a, O>(&mut self, address: A, operations: O) -> Result<(), Self::Error>
295295
where
296296
O: IntoIterator<Item = Operation<'a>>;
297297
}
298298

299299
/// Default implementation of `blocking::i2c::Write`, `blocking::i2c::Read` and
300300
/// `blocking::i2c::WriteRead` traits for `blocking::i2c::Transactional` implementers.
301+
///
302+
/// If you implement `blocking::i2c::Transactional` for your I2C peripheral,
303+
/// you can use this default implementation so that you do not need to implement
304+
/// the `blocking::i2c::Write`, `blocking::i2c::Read` and `blocking::i2c::WriteRead`
305+
/// traits as well.
306+
/// ```
307+
/// use embedded_hal::blocking::i2c;
308+
///
309+
/// struct I2c1;
310+
///
311+
/// impl i2c::Transactional<i2c::SevenBitAddress> for I2c1 {
312+
/// # type Error = ();
313+
/// fn try_exec<'a>(
314+
/// &mut self,
315+
/// address: i2c::SevenBitAddress,
316+
/// operations: &mut [i2c::Operation<'a>],
317+
/// ) -> Result<(), Self::Error> {
318+
/// // ...
319+
/// # Ok(())
320+
/// }
321+
/// }
322+
///
323+
/// // This is all you need to do:
324+
/// impl i2c::transactional::Default<i2c::SevenBitAddress> for I2c1 {};
325+
///
326+
/// // Then you can use `Write` and so on:
327+
/// use i2c::Write;
328+
///
329+
/// let mut i2c1 = I2c1{};
330+
/// i2c1.try_write(0x01, &[0xAB, 0xCD]).unwrap();
331+
/// ```
301332
pub mod transactional {
302-
use super::{Operation, Read, Transactional, Write, WriteRead};
333+
use super::{AddressMode, Operation, Read, Transactional, Write, WriteRead};
303334

304335
/// Default implementation of `blocking::i2c::Write`, `blocking::i2c::Read` and
305336
/// `blocking::i2c::WriteRead` traits for `blocking::i2c::Transactional` implementers.
306-
pub trait Default<E> {}
337+
pub trait Default<A: AddressMode>: Transactional<A> {}
307338

308-
impl<E, S> Write for S
339+
impl<A, E, S> Write<A> for S
309340
where
310-
S: self::Default<E> + Transactional<Error = E>,
341+
A: AddressMode,
342+
S: self::Default<A> + Transactional<A, Error = E>,
311343
{
312344
type Error = E;
313345

314-
fn try_write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> {
346+
fn try_write(&mut self, address: A, bytes: &[u8]) -> Result<(), Self::Error> {
315347
self.try_exec(address, &mut [Operation::Write(bytes)])
316348
}
317349
}
318350

319-
impl<E, S> Read for S
351+
impl<A, E, S> Read<A> for S
320352
where
321-
S: self::Default<E> + Transactional<Error = E>,
353+
A: AddressMode,
354+
S: self::Default<A> + Transactional<A, Error = E>,
322355
{
323356
type Error = E;
324357

325-
fn try_read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
358+
fn try_read(&mut self, address: A, buffer: &mut [u8]) -> Result<(), Self::Error> {
326359
self.try_exec(address, &mut [Operation::Read(buffer)])
327360
}
328361
}
329362

330-
impl<E, S> WriteRead for S
363+
impl<A, E, S> WriteRead<A> for S
331364
where
332-
S: self::Default<E> + Transactional<Error = E>,
365+
A: AddressMode,
366+
S: self::Default<A> + Transactional<A, Error = E>,
333367
{
334368
type Error = E;
335369

336370
fn try_write_read(
337371
&mut self,
338-
address: u8,
372+
address: A,
339373
bytes: &[u8],
340374
buffer: &mut [u8],
341375
) -> Result<(), Self::Error> {

0 commit comments

Comments
 (0)