Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 1d74e89

Browse files
bors[bot]Dirbaio
andauthoredMar 28, 2023
Merge #440
440: I2c: simplify, expand docs, document shared bus usage. r=eldruin a=Dirbaio ~Depends on #441 -- check that one out first.~ This does some simplifications to the trait that I think we should do: - Implement all methods in terms of `transaction`. This way HALs have to implement just that. - Removed byte-wise-iteration methods: `write_iter` and `write_iter_read`. The reason is that they're quite inefficient, especially with DMA implementations. We've already removed these on other traits, so I think we should do as well here. - Removed `transaction_iter`. I don't think it's much useful in practice, because the way iterators work all the yielded `Operation`s must have the same lifetime. This means that, even if the user can generate the `Operation`s on the fly, they can't allocate buffers for these on the fly, all buffers must be pre-allocated. So it's not useful for, say, streaming a large transfer by reusing some small buffer repeatedly. See #367 - Removed useless lifetimes - Standardized buffer names on `read` and `write`, I think they're clearer. It also specifies how i2c bus sharing is supposed to work. This is an alternative to #392 . After the discussions there, I don't think we should split I2C into Bus and Device anymore. For SPI it makes sense, because drivers want to enforce that there's a CS pin (`SpiDevice`) or not (`SpiBus`). This is not the case with I2C, the API is exactly the same in the shared and non-shared case. Drivers shouldn't care which case it is. So all we have to do to "support" bus sharing is docs, This PR does: - Document that it's allowed for implementations to be either shared or not. - Document some guidelines for drivers and HALs on how to best use the traits, expand the examples. Co-authored-by: Dario Nieuwenhuis <[email protected]>
2 parents 3250073 + 7b42f24 commit 1d74e89

File tree

5 files changed

+178
-213
lines changed

5 files changed

+178
-213
lines changed
 

‎embedded-hal-async/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1212

1313
### Changed
1414
- delay: make infallible.
15+
- i2c: remove `_iter()` methods.
16+
- i2c: add default implementations for all methods based on `transaction()`.
1517

1618
## [v0.2.0-alpha.0] - 2022-11-23
1719

‎embedded-hal-async/src/i2c.rs

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,10 @@ pub trait I2c<A: AddressMode = SevenBitAddress>: ErrorType {
4141
/// - `MAK` = master acknowledge
4242
/// - `NMAK` = master no acknowledge
4343
/// - `SP` = stop condition
44-
async fn read<'a>(&'a mut self, address: A, read: &'a mut [u8]) -> Result<(), Self::Error>;
44+
async fn read(&mut self, address: A, read: &mut [u8]) -> Result<(), Self::Error> {
45+
self.transaction(address, &mut [Operation::Read(read)])
46+
.await
47+
}
4548

4649
/// Writes bytes to slave with address `address`
4750
///
@@ -59,7 +62,10 @@ pub trait I2c<A: AddressMode = SevenBitAddress>: ErrorType {
5962
/// - `SAK` = slave acknowledge
6063
/// - `Bi` = ith byte of data
6164
/// - `SP` = stop condition
62-
async fn write<'a>(&'a mut self, address: A, write: &'a [u8]) -> Result<(), Self::Error>;
65+
async fn write(&mut self, address: A, write: &[u8]) -> Result<(), Self::Error> {
66+
self.transaction(address, &mut [Operation::Write(write)])
67+
.await
68+
}
6369

6470
/// Writes bytes to slave with address `address` and then reads enough bytes to fill `read` *in a
6571
/// single transaction*.
@@ -83,12 +89,18 @@ pub trait I2c<A: AddressMode = SevenBitAddress>: ErrorType {
8389
/// - `MAK` = master acknowledge
8490
/// - `NMAK` = master no acknowledge
8591
/// - `SP` = stop condition
86-
async fn write_read<'a>(
87-
&'a mut self,
92+
async fn write_read(
93+
&mut self,
8894
address: A,
89-
write: &'a [u8],
90-
read: &'a mut [u8],
91-
) -> Result<(), Self::Error>;
95+
write: &[u8],
96+
read: &mut [u8],
97+
) -> Result<(), Self::Error> {
98+
self.transaction(
99+
address,
100+
&mut [Operation::Write(write), Operation::Read(read)],
101+
)
102+
.await
103+
}
92104

93105
/// Execute the provided operations on the I2C bus as a single transaction.
94106
///
@@ -103,35 +115,35 @@ pub trait I2c<A: AddressMode = SevenBitAddress>: ErrorType {
103115
/// - `SAD+R/W` = slave address followed by bit 1 to indicate reading or 0 to indicate writing
104116
/// - `SR` = repeated start condition
105117
/// - `SP` = stop condition
106-
async fn transaction<'a, 'b>(
107-
&'a mut self,
118+
async fn transaction(
119+
&mut self,
108120
address: A,
109-
operations: &'a mut [Operation<'b>],
121+
operations: &mut [Operation<'_>],
110122
) -> Result<(), Self::Error>;
111123
}
112124

113125
impl<A: AddressMode, T: I2c<A>> I2c<A> for &mut T {
114-
async fn read<'a>(&'a mut self, address: A, buffer: &'a mut [u8]) -> Result<(), Self::Error> {
115-
T::read(self, address, buffer).await
126+
async fn read(&mut self, address: A, read: &mut [u8]) -> Result<(), Self::Error> {
127+
T::read(self, address, read).await
116128
}
117129

118-
async fn write<'a>(&'a mut self, address: A, bytes: &'a [u8]) -> Result<(), Self::Error> {
119-
T::write(self, address, bytes).await
130+
async fn write(&mut self, address: A, write: &[u8]) -> Result<(), Self::Error> {
131+
T::write(self, address, write).await
120132
}
121133

122-
async fn write_read<'a>(
123-
&'a mut self,
134+
async fn write_read(
135+
&mut self,
124136
address: A,
125-
bytes: &'a [u8],
126-
buffer: &'a mut [u8],
137+
write: &[u8],
138+
read: &mut [u8],
127139
) -> Result<(), Self::Error> {
128-
T::write_read(self, address, bytes, buffer).await
140+
T::write_read(self, address, write, read).await
129141
}
130142

131-
async fn transaction<'a, 'b>(
132-
&'a mut self,
143+
async fn transaction(
144+
&mut self,
133145
address: A,
134-
operations: &'a mut [Operation<'b>],
146+
operations: &mut [Operation<'_>],
135147
) -> Result<(), Self::Error> {
136148
T::transaction(self, address, operations).await
137149
}

‎embedded-hal/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1313
### Changed
1414
- gpio: add `ErrorKind` enum for consistency with other traits and for future extensibility. No kinds are defined for now.
1515
- delay: make infallible.
16+
- i2c: remove `_iter()` methods.
17+
- i2c: add default implementations for all methods based on `transaction()`.
18+
- i2c: document guidelines for shared bus usage.
1619

1720
## [v1.0.0-alpha.9] - 2022-09-28
1821

‎embedded-hal/src/i2c-shared-bus.svg

Lines changed: 4 additions & 0 deletions
Loading

‎embedded-hal/src/i2c.rs

Lines changed: 135 additions & 191 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
//! Blocking I2C API
22
//!
3-
//! This API supports 7-bit and 10-bit addresses. Traits feature an `AddressMode`
4-
//! marker type parameter. Two implementation of the `AddressMode` exist:
5-
//! `SevenBitAddress` and `TenBitAddress`.
3+
//! This API supports 7-bit and 10-bit addresses. Traits feature an [`AddressMode`]
4+
//! marker type parameter. Two implementation of the [`AddressMode`] exist:
5+
//! [`SevenBitAddress`] and [`TenBitAddress`].
66
//!
77
//! Through this marker types it is possible to implement each address mode for
88
//! the traits independently in `embedded-hal` implementations and device drivers
@@ -14,128 +14,140 @@
1414
//! is not supported by the hardware.
1515
//!
1616
//! Since 7-bit addressing is the mode of the majority of I2C devices,
17-
//! `SevenBitAddress` has been set as default mode and thus can be omitted if desired.
17+
//! [`SevenBitAddress`] has been set as default mode and thus can be omitted if desired.
1818
//!
19-
//! ## Examples
19+
//! # Bus sharing
2020
//!
21-
//! ### `embedded-hal` implementation for an MCU
22-
//! Here is an example of an embedded-hal implementation of the `Write` trait
23-
//! for both modes:
24-
//! ```
25-
//! # use embedded_hal::i2c::{ErrorKind, ErrorType, SevenBitAddress, TenBitAddress, I2c, Operation};
26-
//! /// I2C0 hardware peripheral which supports both 7-bit and 10-bit addressing.
27-
//! pub struct I2c0;
21+
//! I2C allows sharing a single bus between many I2C devices. The SDA and SCL lines are
22+
//! wired in parallel to all devices. When starting a transfer an "address" is sent
23+
//! so that the addressed device can respond and all the others can ignore the transfer.
2824
//!
29-
//! # impl ErrorType for I2c0 { type Error = ErrorKind; }
30-
//! impl I2c<SevenBitAddress> for I2c0
31-
//! {
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> {
57-
//! // ...
58-
//! # Ok(())
59-
//! }
60-
//! }
25+
#![doc = include_str!("i2c-shared-bus.svg")]
6126
//!
62-
//! impl I2c<TenBitAddress> for I2c0
63-
//! {
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> {
89-
//! // ...
90-
//! # Ok(())
91-
//! }
92-
//! }
93-
//! ```
27+
//! This bus sharing is common when having multiple I2C devices in the same board, since it uses fewer MCU
28+
//! pins (`2` instead of `2*n`), and fewer MCU I2C peripherals (`1` instead of `n`).
9429
//!
95-
//! ### Device driver compatible only with 7-bit addresses
30+
//! This API supports bus sharing natively. Types implementing [`I2c`] are allowed
31+
//! to represent either exclusive or shared access to an I2C bus. HALs typically
32+
//! provide exclusive access implementations. Drivers shouldn't care which
33+
//! kind they receive, they just do transactions on it and let the
34+
//! underlying implementation share or not.
35+
//!
36+
//! The [`embedded-hal-bus`](https://docs.rs/embedded-hal-bus) crate provides several
37+
//! implementations for sharing I2C buses. You can use them to take an exclusive instance
38+
//! you've received from a HAL and "split" it into mulitple shared ones, to instantiate
39+
//! several drivers on the same bus.
40+
//!
41+
//! # For driver authors
42+
//!
43+
//! Drivers can select the adequate address length with `I2c<SevenBitAddress>` or `I2c<TenBitAddress>` depending
44+
//! on the target device. If it can use either, the driver can
45+
//! be generic over the address kind as well, though this is rare.
46+
//!
47+
//! Drivers should take the `I2c` instance as an argument to `new()`, and store it in their
48+
//! struct. They **should not** take `&mut I2c`, the trait has a blanket impl for all `&mut T`
49+
//! so taking just `I2c` ensures the user can still pass a `&mut`, but is not forced to.
50+
//!
51+
//! Drivers **should not** try to enable bus sharing by taking `&mut I2c` at every method.
52+
//! This is much less ergonomic than owning the `I2c`, which still allows the user to pass an
53+
//! implementation that does sharing behind the scenes
54+
//! (from [`embedded-hal-bus`](https://docs.rs/embedded-hal-bus), or others).
55+
//!
56+
//! ## Device driver compatible only with 7-bit addresses
9657
//!
9758
//! For demonstration purposes the address mode parameter has been omitted in this example.
9859
//!
9960
//! ```
100-
//! # use embedded_hal::i2c::{I2c, Error};
101-
//! const ADDR: u8 = 0x15;
61+
//! use embedded_hal::i2c::{I2c, Error};
62+
//!
63+
//! const ADDR: u8 = 0x15;
10264
//! # const TEMP_REGISTER: u8 = 0x1;
10365
//! pub struct TemperatureSensorDriver<I2C> {
10466
//! i2c: I2C,
10567
//! }
10668
//!
107-
//! impl<I2C, E: Error> TemperatureSensorDriver<I2C>
108-
//! where
109-
//! I2C: I2c<Error = E>,
110-
//! {
111-
//! pub fn read_temperature(&mut self) -> Result<u8, E> {
69+
//! impl<I2C: I2c> TemperatureSensorDriver<I2C> {
70+
//! pub fn new(i2c: I2C) -> Self {
71+
//! Self { i2c }
72+
//! }
73+
//!
74+
//! pub fn read_temperature(&mut self) -> Result<u8, I2C::Error> {
11275
//! let mut temp = [0];
113-
//! self.i2c
114-
//! .write_read(ADDR, &[TEMP_REGISTER], &mut temp)
115-
//! .and(Ok(temp[0]))
76+
//! self.i2c.write_read(ADDR, &[TEMP_REGISTER], &mut temp)?;
77+
//! Ok(temp[0])
11678
//! }
11779
//! }
11880
//! ```
11981
//!
120-
//! ### Device driver compatible only with 10-bit addresses
82+
//! ## Device driver compatible only with 10-bit addresses
12183
//!
12284
//! ```
123-
//! # use embedded_hal::i2c::{Error, TenBitAddress, I2c};
124-
//! const ADDR: u16 = 0x158;
85+
//! use embedded_hal::i2c::{Error, TenBitAddress, I2c};
86+
//!
87+
//! const ADDR: u16 = 0x158;
12588
//! # const TEMP_REGISTER: u8 = 0x1;
12689
//! pub struct TemperatureSensorDriver<I2C> {
12790
//! i2c: I2C,
12891
//! }
12992
//!
130-
//! impl<I2C, E: Error> TemperatureSensorDriver<I2C>
131-
//! where
132-
//! I2C: I2c<TenBitAddress, Error = E>,
133-
//! {
134-
//! pub fn read_temperature(&mut self) -> Result<u8, E> {
93+
//! impl<I2C: I2c<TenBitAddress>> TemperatureSensorDriver<I2C> {
94+
//! pub fn new(i2c: I2C) -> Self {
95+
//! Self { i2c }
96+
//! }
97+
//!
98+
//! pub fn read_temperature(&mut self) -> Result<u8, I2C::Error> {
13599
//! let mut temp = [0];
136-
//! self.i2c
137-
//! .write_read(ADDR, &[TEMP_REGISTER], &mut temp)
138-
//! .and(Ok(temp[0]))
100+
//! self.i2c.write_read(ADDR, &[TEMP_REGISTER], &mut temp)?;
101+
//! Ok(temp[0])
102+
//! }
103+
//! }
104+
//! ```
105+
//!
106+
//! # For HAL authors
107+
//!
108+
//! HALs **should not** include bus sharing mechanisms. They should expose a single type representing
109+
//! exclusive ownership over the bus, and let the user use [`embedded-hal-bus`](https://docs.rs/embedded-hal-bus)
110+
//! if they want to share it. (One exception is if the underlying platform already
111+
//! supports sharing, such as Linux or some RTOSs.)
112+
//!
113+
//! Here is an example of an embedded-hal implementation of the `I2C` trait
114+
//! for both addressing modes. All trait methods have have default implementations in terms of `transaction`.
115+
//! As such, that is the only method that requires implementation in the HAL.
116+
//!
117+
//! ```
118+
//! use embedded_hal::i2c::{self, SevenBitAddress, TenBitAddress, I2c, Operation};
119+
//!
120+
//! /// I2C0 hardware peripheral which supports both 7-bit and 10-bit addressing.
121+
//! pub struct I2c0;
122+
//!
123+
//! #[derive(Debug, Copy, Clone, Eq, PartialEq)]
124+
//! pub enum Error {
125+
//! // ...
126+
//! }
127+
//!
128+
//! impl i2c::Error for Error {
129+
//! fn kind(&self) -> i2c::ErrorKind {
130+
//! match *self {
131+
//! // ...
132+
//! }
133+
//! }
134+
//! }
135+
//!
136+
//! impl i2c::ErrorType for I2c0 {
137+
//! type Error = Error;
138+
//! }
139+
//!
140+
//! impl I2c<SevenBitAddress> for I2c0 {
141+
//! fn transaction(&mut self, address: u8, operations: &mut [Operation<'_>]) -> Result<(), Self::Error> {
142+
//! // ...
143+
//! # Ok(())
144+
//! }
145+
//! }
146+
//!
147+
//! impl I2c<TenBitAddress> for I2c0 {
148+
//! fn transaction(&mut self, address: u16, operations: &mut [Operation<'_>]) -> Result<(), Self::Error> {
149+
//! // ...
150+
//! # Ok(())
139151
//! }
140152
//! }
141153
//! ```
@@ -256,7 +268,7 @@ impl AddressMode for SevenBitAddress {}
256268

257269
impl AddressMode for TenBitAddress {}
258270

259-
/// Transactional I2C operation.
271+
/// I2C operation.
260272
///
261273
/// Several operations can be combined as part of a transaction.
262274
#[derive(Debug, PartialEq, Eq)]
@@ -269,7 +281,7 @@ pub enum Operation<'a> {
269281

270282
/// Blocking I2C
271283
pub trait I2c<A: AddressMode = SevenBitAddress>: ErrorType {
272-
/// Reads enough bytes from slave with `address` to fill `buffer`
284+
/// Reads enough bytes from slave with `address` to fill `read`
273285
///
274286
/// # I2C Events (contract)
275287
///
@@ -287,7 +299,9 @@ pub trait I2c<A: AddressMode = SevenBitAddress>: ErrorType {
287299
/// - `MAK` = master acknowledge
288300
/// - `NMAK` = master no acknowledge
289301
/// - `SP` = stop condition
290-
fn read(&mut self, address: A, buffer: &mut [u8]) -> Result<(), Self::Error>;
302+
fn read(&mut self, address: A, read: &mut [u8]) -> Result<(), Self::Error> {
303+
self.transaction(address, &mut [Operation::Read(read)])
304+
}
291305

292306
/// Writes bytes to slave with address `address`
293307
///
@@ -305,18 +319,11 @@ pub trait I2c<A: AddressMode = SevenBitAddress>: ErrorType {
305319
/// - `SAK` = slave acknowledge
306320
/// - `Bi` = ith byte of data
307321
/// - `SP` = stop condition
308-
fn write(&mut self, address: A, bytes: &[u8]) -> Result<(), Self::Error>;
309-
310-
/// Writes bytes to slave with address `address`
311-
///
312-
/// # I2C Events (contract)
313-
///
314-
/// Same as the `write` method
315-
fn write_iter<B>(&mut self, address: A, bytes: B) -> Result<(), Self::Error>
316-
where
317-
B: IntoIterator<Item = u8>;
322+
fn write(&mut self, address: A, write: &[u8]) -> Result<(), Self::Error> {
323+
self.transaction(address, &mut [Operation::Write(write)])
324+
}
318325

319-
/// Writes bytes to slave with address `address` and then reads enough bytes to fill `buffer` *in a
326+
/// Writes bytes to slave with address `address` and then reads enough bytes to fill `read` *in a
320327
/// single transaction*
321328
///
322329
/// # I2C Events (contract)
@@ -338,27 +345,12 @@ pub trait I2c<A: AddressMode = SevenBitAddress>: ErrorType {
338345
/// - `MAK` = master acknowledge
339346
/// - `NMAK` = master no acknowledge
340347
/// - `SP` = stop condition
341-
fn write_read(
342-
&mut self,
343-
address: A,
344-
bytes: &[u8],
345-
buffer: &mut [u8],
346-
) -> Result<(), Self::Error>;
347-
348-
/// Writes bytes to slave with address `address` and then reads enough bytes to fill `buffer` *in a
349-
/// single transaction*
350-
///
351-
/// # I2C Events (contract)
352-
///
353-
/// Same as the `write_read` method
354-
fn write_iter_read<B>(
355-
&mut self,
356-
address: A,
357-
bytes: B,
358-
buffer: &mut [u8],
359-
) -> Result<(), Self::Error>
360-
where
361-
B: IntoIterator<Item = u8>;
348+
fn write_read(&mut self, address: A, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> {
349+
self.transaction(
350+
address,
351+
&mut [Operation::Write(write), Operation::Read(read)],
352+
)
353+
}
362354

363355
/// Execute the provided operations on the I2C bus.
364356
///
@@ -373,79 +365,31 @@ pub trait I2c<A: AddressMode = SevenBitAddress>: ErrorType {
373365
/// - `SAD+R/W` = slave address followed by bit 1 to indicate reading or 0 to indicate writing
374366
/// - `SR` = repeated start condition
375367
/// - `SP` = stop condition
376-
fn transaction<'a>(
368+
fn transaction(
377369
&mut self,
378370
address: A,
379-
operations: &mut [Operation<'a>],
371+
operations: &mut [Operation<'_>],
380372
) -> Result<(), Self::Error>;
381-
382-
/// Execute the provided operations on the I2C bus (iterator version).
383-
///
384-
/// Transaction contract:
385-
/// - Before executing the first operation an ST is sent automatically. This is followed by SAD+R/W as appropriate.
386-
/// - Data from adjacent operations of the same type are sent after each other without an SP or SR.
387-
/// - Between adjacent operations of a different type an SR and SAD+R/W is sent.
388-
/// - After executing the last operation an SP is sent automatically.
389-
/// - If the last operation is a `Read` the master does not send an acknowledge for the last byte.
390-
///
391-
/// - `ST` = start condition
392-
/// - `SAD+R/W` = slave address followed by bit 1 to indicate reading or 0 to indicate writing
393-
/// - `SR` = repeated start condition
394-
/// - `SP` = stop condition
395-
fn transaction_iter<'a, O>(&mut self, address: A, operations: O) -> Result<(), Self::Error>
396-
where
397-
O: IntoIterator<Item = Operation<'a>>;
398373
}
399374

400375
impl<A: AddressMode, T: I2c<A>> I2c<A> for &mut T {
401-
fn read(&mut self, address: A, buffer: &mut [u8]) -> Result<(), Self::Error> {
402-
T::read(self, address, buffer)
403-
}
404-
405-
fn write(&mut self, address: A, bytes: &[u8]) -> Result<(), Self::Error> {
406-
T::write(self, address, bytes)
407-
}
408-
409-
fn write_iter<B>(&mut self, address: A, bytes: B) -> Result<(), Self::Error>
410-
where
411-
B: IntoIterator<Item = u8>,
412-
{
413-
T::write_iter(self, address, bytes)
376+
fn read(&mut self, address: A, read: &mut [u8]) -> Result<(), Self::Error> {
377+
T::read(self, address, read)
414378
}
415379

416-
fn write_read(
417-
&mut self,
418-
address: A,
419-
bytes: &[u8],
420-
buffer: &mut [u8],
421-
) -> Result<(), Self::Error> {
422-
T::write_read(self, address, bytes, buffer)
380+
fn write(&mut self, address: A, write: &[u8]) -> Result<(), Self::Error> {
381+
T::write(self, address, write)
423382
}
424383

425-
fn write_iter_read<B>(
426-
&mut self,
427-
address: A,
428-
bytes: B,
429-
buffer: &mut [u8],
430-
) -> Result<(), Self::Error>
431-
where
432-
B: IntoIterator<Item = u8>,
433-
{
434-
T::write_iter_read(self, address, bytes, buffer)
384+
fn write_read(&mut self, address: A, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> {
385+
T::write_read(self, address, write, read)
435386
}
436387

437-
fn transaction<'a>(
388+
fn transaction(
438389
&mut self,
439390
address: A,
440-
operations: &mut [Operation<'a>],
391+
operations: &mut [Operation<'_>],
441392
) -> Result<(), Self::Error> {
442393
T::transaction(self, address, operations)
443394
}
444-
445-
fn transaction_iter<'a, O>(&mut self, address: A, operations: O) -> Result<(), Self::Error>
446-
where
447-
O: IntoIterator<Item = Operation<'a>>,
448-
{
449-
T::transaction_iter(self, address, operations)
450-
}
451395
}

0 commit comments

Comments
 (0)
Please sign in to comment.