Skip to content

Commit 599f8bd

Browse files
bors[bot]Dirbaio
andauthored
Merge #339
339: I2c unify r=eldruin a=Dirbaio Depends on #336 Equivalent of #323 but for I2c. I think for i2c unifying everything in a single trait makes the most sense. The i2c bus is specified to be bidirectional, I believe no hardware out there can "only write" or "only read" (and writing requires *reading* ACK bits anyway!). Co-authored-by: Dario Nieuwenhuis <[email protected]>
2 parents 556c1be + a2645bf commit 599f8bd

File tree

2 files changed

+122
-107
lines changed

2 files changed

+122
-107
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
2323

2424
### Changed
2525
- `i2c`: traits now enforce all impls on the same struct have the same `Error` type.
26+
- `i2c`: unify all traits into a single `I2c` trait.
2627

2728
## [v1.0.0-alpha.6] - 2021-11-19
2829

src/i2c.rs

+121-107
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,70 @@
2222
//! Here is an example of an embedded-hal implementation of the `Write` trait
2323
//! for both modes:
2424
//! ```
25-
//! # use embedded_hal::i2c::{ErrorKind, ErrorType, SevenBitAddress, TenBitAddress, blocking::Write};
25+
//! # use embedded_hal::i2c::{ErrorKind, ErrorType, SevenBitAddress, TenBitAddress, blocking::{I2c, Operation}};
2626
//! /// I2C0 hardware peripheral which supports both 7-bit and 10-bit addressing.
2727
//! pub struct I2c0;
2828
//!
2929
//! # impl ErrorType for I2c0 { type Error = ErrorKind; }
30-
//! impl Write<SevenBitAddress> for I2c0
30+
//! impl I2c<SevenBitAddress> for I2c0
3131
//! {
32-
//! fn write(&mut self, addr: u8, output: &[u8]) -> Result<(), Self::Error> {
32+
//! fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
33+
//! // ...
34+
//! # Ok(())
35+
//! }
36+
//! fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> {
37+
//! // ...
38+
//! # Ok(())
39+
//! }
40+
//! fn write_iter<B: IntoIterator<Item = u8>>(&mut self, addr: u8, bytes: B) -> Result<(), Self::Error> {
41+
//! // ...
42+
//! # Ok(())
43+
//! }
44+
//! fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Self::Error> {
45+
//! // ...
46+
//! # Ok(())
47+
//! }
48+
//! fn write_iter_read<B: IntoIterator<Item = u8>>(&mut self, addr: u8, bytes: B, buffer: &mut [u8]) -> Result<(), Self::Error> {
49+
//! // ...
50+
//! # Ok(())
51+
//! }
52+
//! fn transaction<'a>(&mut self, address: u8, operations: &mut [Operation<'a>]) -> Result<(), Self::Error> {
53+
//! // ...
54+
//! # Ok(())
55+
//! }
56+
//! fn transaction_iter<'a, O: IntoIterator<Item = Operation<'a>>>(&mut self, address: u8, operations: O) -> Result<(), Self::Error> {
3357
//! // ...
3458
//! # Ok(())
3559
//! }
3660
//! }
3761
//!
38-
//! impl Write<TenBitAddress> for I2c0
62+
//! impl I2c<TenBitAddress> for I2c0
3963
//! {
40-
//! fn write(&mut self, addr: u16, output: &[u8]) -> Result<(), Self::Error> {
64+
//! fn read(&mut self, addr: u16, buffer: &mut [u8]) -> Result<(), Self::Error> {
65+
//! // ...
66+
//! # Ok(())
67+
//! }
68+
//! fn write(&mut self, addr: u16, bytes: &[u8]) -> Result<(), Self::Error> {
69+
//! // ...
70+
//! # Ok(())
71+
//! }
72+
//! fn write_iter<B: IntoIterator<Item = u8>>(&mut self, addr: u16, bytes: B) -> Result<(), Self::Error> {
73+
//! // ...
74+
//! # Ok(())
75+
//! }
76+
//! fn write_read(&mut self, addr: u16, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Self::Error> {
77+
//! // ...
78+
//! # Ok(())
79+
//! }
80+
//! fn write_iter_read<B: IntoIterator<Item = u8>>(&mut self, addr: u16, bytes: B, buffer: &mut [u8]) -> Result<(), Self::Error> {
81+
//! // ...
82+
//! # Ok(())
83+
//! }
84+
//! fn transaction<'a>(&mut self, address: u16, operations: &mut [Operation<'a>]) -> Result<(), Self::Error> {
85+
//! // ...
86+
//! # Ok(())
87+
//! }
88+
//! fn transaction_iter<'a, O: IntoIterator<Item = Operation<'a>>>(&mut self, address: u16, operations: O) -> Result<(), Self::Error> {
4189
//! // ...
4290
//! # Ok(())
4391
//! }
@@ -49,7 +97,7 @@
4997
//! For demonstration purposes the address mode parameter has been omitted in this example.
5098
//!
5199
//! ```
52-
//! # use embedded_hal::i2c::{blocking::WriteRead, Error};
100+
//! # use embedded_hal::i2c::{blocking::I2c, Error};
53101
//! const ADDR: u8 = 0x15;
54102
//! # const TEMP_REGISTER: u8 = 0x1;
55103
//! pub struct TemperatureSensorDriver<I2C> {
@@ -58,7 +106,7 @@
58106
//!
59107
//! impl<I2C, E: Error> TemperatureSensorDriver<I2C>
60108
//! where
61-
//! I2C: WriteRead<Error = E>,
109+
//! I2C: I2c<Error = E>,
62110
//! {
63111
//! pub fn read_temperature(&mut self) -> Result<u8, E> {
64112
//! let mut temp = [0];
@@ -72,7 +120,7 @@
72120
//! ### Device driver compatible only with 10-bit addresses
73121
//!
74122
//! ```
75-
//! # use embedded_hal::i2c::{Error, TenBitAddress, blocking::WriteRead};
123+
//! # use embedded_hal::i2c::{Error, TenBitAddress, blocking::I2c};
76124
//! const ADDR: u16 = 0x158;
77125
//! # const TEMP_REGISTER: u8 = 0x1;
78126
//! pub struct TemperatureSensorDriver<I2C> {
@@ -81,7 +129,7 @@
81129
//!
82130
//! impl<I2C, E: Error> TemperatureSensorDriver<I2C>
83131
//! where
84-
//! I2C: WriteRead<TenBitAddress, Error = E>,
132+
//! I2C: I2c<TenBitAddress, Error = E>,
85133
//! {
86134
//! pub fn read_temperature(&mut self) -> Result<u8, E> {
87135
//! let mut temp = [0];
@@ -213,8 +261,19 @@ pub mod blocking {
213261

214262
use super::{AddressMode, ErrorType, SevenBitAddress};
215263

216-
/// Blocking read
217-
pub trait Read<A: AddressMode = SevenBitAddress>: ErrorType {
264+
/// Transactional I2C operation.
265+
///
266+
/// Several operations can be combined as part of a transaction.
267+
#[derive(Debug, PartialEq)]
268+
pub enum Operation<'a> {
269+
/// Read data into the provided buffer
270+
Read(&'a mut [u8]),
271+
/// Write data from the provided buffer
272+
Write(&'a [u8]),
273+
}
274+
275+
/// Blocking I2C
276+
pub trait I2c<A: AddressMode = SevenBitAddress>: ErrorType {
218277
/// Reads enough bytes from slave with `address` to fill `buffer`
219278
///
220279
/// # I2C Events (contract)
@@ -234,16 +293,7 @@ pub mod blocking {
234293
/// - `NMAK` = master no acknowledge
235294
/// - `SP` = stop condition
236295
fn read(&mut self, address: A, buffer: &mut [u8]) -> Result<(), Self::Error>;
237-
}
238-
239-
impl<A: AddressMode, T: Read<A>> Read<A> for &mut T {
240-
fn read(&mut self, address: A, buffer: &mut [u8]) -> Result<(), Self::Error> {
241-
T::read(self, address, buffer)
242-
}
243-
}
244296

245-
/// Blocking write
246-
pub trait Write<A: AddressMode = SevenBitAddress>: ErrorType {
247297
/// Writes bytes to slave with address `address`
248298
///
249299
/// # I2C Events (contract)
@@ -261,37 +311,16 @@ pub mod blocking {
261311
/// - `Bi` = ith byte of data
262312
/// - `SP` = stop condition
263313
fn write(&mut self, address: A, bytes: &[u8]) -> Result<(), Self::Error>;
264-
}
265-
266-
impl<A: AddressMode, T: Write<A>> Write<A> for &mut T {
267-
fn write(&mut self, address: A, bytes: &[u8]) -> Result<(), Self::Error> {
268-
T::write(self, address, bytes)
269-
}
270-
}
271314

272-
/// Blocking write (iterator version)
273-
pub trait WriteIter<A: AddressMode = SevenBitAddress>: ErrorType {
274315
/// Writes bytes to slave with address `address`
275316
///
276317
/// # I2C Events (contract)
277318
///
278-
/// Same as `Write`
319+
/// Same as the `write` method
279320
fn write_iter<B>(&mut self, address: A, bytes: B) -> Result<(), Self::Error>
280321
where
281322
B: IntoIterator<Item = u8>;
282-
}
283-
284-
impl<A: AddressMode, T: WriteIter<A>> WriteIter<A> for &mut T {
285-
fn write_iter<B>(&mut self, address: A, bytes: B) -> Result<(), Self::Error>
286-
where
287-
B: IntoIterator<Item = u8>,
288-
{
289-
T::write_iter(self, address, bytes)
290-
}
291-
}
292323

293-
/// Blocking write + read
294-
pub trait WriteRead<A: AddressMode = SevenBitAddress>: ErrorType {
295324
/// Writes bytes to slave with address `address` and then reads enough bytes to fill `buffer` *in a
296325
/// single transaction*
297326
///
@@ -320,27 +349,13 @@ pub mod blocking {
320349
bytes: &[u8],
321350
buffer: &mut [u8],
322351
) -> Result<(), Self::Error>;
323-
}
324-
325-
impl<A: AddressMode, T: WriteRead<A>> WriteRead<A> for &mut T {
326-
fn write_read(
327-
&mut self,
328-
address: A,
329-
bytes: &[u8],
330-
buffer: &mut [u8],
331-
) -> Result<(), Self::Error> {
332-
T::write_read(self, address, bytes, buffer)
333-
}
334-
}
335352

336-
/// Blocking write (iterator version) + read
337-
pub trait WriteIterRead<A: AddressMode = SevenBitAddress>: ErrorType {
338353
/// Writes bytes to slave with address `address` and then reads enough bytes to fill `buffer` *in a
339354
/// single transaction*
340355
///
341356
/// # I2C Events (contract)
342357
///
343-
/// Same as the `WriteRead` trait
358+
/// Same as the `write_read` method
344359
fn write_iter_read<B>(
345360
&mut self,
346361
address: A,
@@ -349,37 +364,7 @@ pub mod blocking {
349364
) -> Result<(), Self::Error>
350365
where
351366
B: IntoIterator<Item = u8>;
352-
}
353-
354-
impl<A: AddressMode, T: WriteIterRead<A>> WriteIterRead<A> for &mut T {
355-
fn write_iter_read<B>(
356-
&mut self,
357-
address: A,
358-
bytes: B,
359-
buffer: &mut [u8],
360-
) -> Result<(), Self::Error>
361-
where
362-
B: IntoIterator<Item = u8>,
363-
{
364-
T::write_iter_read(self, address, bytes, buffer)
365-
}
366-
}
367367

368-
/// Transactional I2C operation.
369-
///
370-
/// Several operations can be combined as part of a transaction.
371-
#[derive(Debug, PartialEq)]
372-
pub enum Operation<'a> {
373-
/// Read data into the provided buffer
374-
Read(&'a mut [u8]),
375-
/// Write data from the provided buffer
376-
Write(&'a [u8]),
377-
}
378-
379-
/// Transactional I2C interface.
380-
///
381-
/// This allows combining operations within an I2C transaction.
382-
pub trait Transactional<A: AddressMode = SevenBitAddress>: ErrorType {
383368
/// Execute the provided operations on the I2C bus.
384369
///
385370
/// Transaction contract:
@@ -393,27 +378,12 @@ pub mod blocking {
393378
/// - `SAD+R/W` = slave address followed by bit 1 to indicate reading or 0 to indicate writing
394379
/// - `SR` = repeated start condition
395380
/// - `SP` = stop condition
396-
fn exec<'a>(
381+
fn transaction<'a>(
397382
&mut self,
398383
address: A,
399384
operations: &mut [Operation<'a>],
400385
) -> Result<(), Self::Error>;
401-
}
402386

403-
impl<A: AddressMode, T: Transactional<A>> Transactional<A> for &mut T {
404-
fn exec<'a>(
405-
&mut self,
406-
address: A,
407-
operations: &mut [Operation<'a>],
408-
) -> Result<(), Self::Error> {
409-
T::exec(self, address, operations)
410-
}
411-
}
412-
413-
/// Transactional I2C interface (iterator version).
414-
///
415-
/// This allows combining operation within an I2C transaction.
416-
pub trait TransactionalIter<A: AddressMode = SevenBitAddress>: ErrorType {
417387
/// Execute the provided operations on the I2C bus (iterator version).
418388
///
419389
/// Transaction contract:
@@ -427,17 +397,61 @@ pub mod blocking {
427397
/// - `SAD+R/W` = slave address followed by bit 1 to indicate reading or 0 to indicate writing
428398
/// - `SR` = repeated start condition
429399
/// - `SP` = stop condition
430-
fn exec_iter<'a, O>(&mut self, address: A, operations: O) -> Result<(), Self::Error>
400+
fn transaction_iter<'a, O>(&mut self, address: A, operations: O) -> Result<(), Self::Error>
431401
where
432402
O: IntoIterator<Item = Operation<'a>>;
433403
}
434404

435-
impl<A: AddressMode, T: TransactionalIter<A>> TransactionalIter<A> for &mut T {
436-
fn exec_iter<'a, O>(&mut self, address: A, operations: O) -> Result<(), Self::Error>
405+
impl<A: AddressMode, T: I2c<A>> I2c<A> for &mut T {
406+
fn read(&mut self, address: A, buffer: &mut [u8]) -> Result<(), Self::Error> {
407+
T::read(self, address, buffer)
408+
}
409+
410+
fn write(&mut self, address: A, bytes: &[u8]) -> Result<(), Self::Error> {
411+
T::write(self, address, bytes)
412+
}
413+
414+
fn write_iter<B>(&mut self, address: A, bytes: B) -> Result<(), Self::Error>
415+
where
416+
B: IntoIterator<Item = u8>,
417+
{
418+
T::write_iter(self, address, bytes)
419+
}
420+
421+
fn write_read(
422+
&mut self,
423+
address: A,
424+
bytes: &[u8],
425+
buffer: &mut [u8],
426+
) -> Result<(), Self::Error> {
427+
T::write_read(self, address, bytes, buffer)
428+
}
429+
430+
fn write_iter_read<B>(
431+
&mut self,
432+
address: A,
433+
bytes: B,
434+
buffer: &mut [u8],
435+
) -> Result<(), Self::Error>
436+
where
437+
B: IntoIterator<Item = u8>,
438+
{
439+
T::write_iter_read(self, address, bytes, buffer)
440+
}
441+
442+
fn transaction<'a>(
443+
&mut self,
444+
address: A,
445+
operations: &mut [Operation<'a>],
446+
) -> Result<(), Self::Error> {
447+
T::transaction(self, address, operations)
448+
}
449+
450+
fn transaction_iter<'a, O>(&mut self, address: A, operations: O) -> Result<(), Self::Error>
437451
where
438452
O: IntoIterator<Item = Operation<'a>>,
439453
{
440-
T::exec_iter(self, address, operations)
454+
T::transaction_iter(self, address, operations)
441455
}
442456
}
443457
}

0 commit comments

Comments
 (0)