Skip to content

Commit 1d74e89

Browse files
bors[bot]Dirbaio
andauthored
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

+2
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

+34-22
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

+3
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

+4
Loading

0 commit comments

Comments
 (0)