aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-traits/src/i2c.rs248
1 files changed, 1 insertions, 247 deletions
diff --git a/embassy-traits/src/i2c.rs b/embassy-traits/src/i2c.rs
index 02755b571..f9f462b50 100644
--- a/embassy-traits/src/i2c.rs
+++ b/embassy-traits/src/i2c.rs
@@ -97,6 +97,7 @@ pub trait Read<A: AddressMode = SevenBitAddress> {
97 type Error; 97 type Error;
98 98
99 type ReadFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a; 99 type ReadFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a;
100 type WriteFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a;
100 101
101 /// Reads enough bytes from slave with `address` to fill `buffer` 102 /// Reads enough bytes from slave with `address` to fill `buffer`
102 /// 103 ///
@@ -117,14 +118,6 @@ pub trait Read<A: AddressMode = SevenBitAddress> {
117 /// - `NMAK` = master no acknowledge 118 /// - `NMAK` = master no acknowledge
118 /// - `SP` = stop condition 119 /// - `SP` = stop condition
119 fn read<'a>(self: Pin<&'a mut Self>, address: A, buffer: &mut [u8]) -> Self::ReadFuture<'a>; 120 fn read<'a>(self: Pin<&'a mut Self>, address: A, buffer: &mut [u8]) -> Self::ReadFuture<'a>;
120}
121
122/// Blocking write
123pub trait Write<A: AddressMode = SevenBitAddress> {
124 /// Error type
125 type Error;
126
127 type WriteFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a;
128 121
129 /// Sends bytes to slave with address `address` 122 /// Sends bytes to slave with address `address`
130 /// 123 ///
@@ -144,242 +137,3 @@ pub trait Write<A: AddressMode = SevenBitAddress> {
144 /// - `SP` = stop condition 137 /// - `SP` = stop condition
145 fn write<'a>(self: Pin<&'a mut Self>, address: A, bytes: &[u8]) -> Self::WriteFuture<'a>; 138 fn write<'a>(self: Pin<&'a mut Self>, address: A, bytes: &[u8]) -> Self::WriteFuture<'a>;
146} 139}
147
148/// Blocking write (iterator version)
149pub trait WriteIter<A: AddressMode = SevenBitAddress> {
150 /// Error type
151 type Error;
152
153 type WriteIterFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a;
154
155 /// Sends bytes to slave with address `address`
156 ///
157 /// # I2C Events (contract)
158 ///
159 /// Same as `Write`
160 fn write_iter<'a, B>(
161 self: Pin<&'a mut Self>,
162 address: A,
163 bytes: B,
164 ) -> Self::WriteIterFuture<'a>
165 where
166 B: IntoIterator<Item = u8>;
167}
168
169/// Blocking write + read
170pub trait WriteRead<A: AddressMode = SevenBitAddress> {
171 /// Error type
172 type Error;
173
174 type WriteReadFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a;
175
176 /// Sends bytes to slave with address `address` and then reads enough bytes to fill `buffer` *in a
177 /// single transaction*
178 ///
179 /// # I2C Events (contract)
180 ///
181 /// ``` text
182 /// Master: ST SAD+W O0 O1 ... OM SR SAD+R MAK MAK ... NMAK SP
183 /// Slave: SAK SAK SAK ... SAK SAK I0 I1 ... IN
184 /// ```
185 ///
186 /// Where
187 ///
188 /// - `ST` = start condition
189 /// - `SAD+W` = slave address followed by bit 0 to indicate writing
190 /// - `SAK` = slave acknowledge
191 /// - `Oi` = ith outgoing byte of data
192 /// - `SR` = repeated start condition
193 /// - `SAD+R` = slave address followed by bit 1 to indicate reading
194 /// - `Ii` = ith incoming byte of data
195 /// - `MAK` = master acknowledge
196 /// - `NMAK` = master no acknowledge
197 /// - `SP` = stop condition
198 fn write_read<'a>(
199 self: Pin<&'a mut Self>,
200 address: A,
201 bytes: &[u8],
202 buffer: &mut [u8],
203 ) -> Self::WriteReadFuture<'a>;
204}
205
206/// Blocking write (iterator version) + read
207pub trait WriteIterRead<A: AddressMode = SevenBitAddress> {
208 /// Error type
209 type Error;
210
211 type WriteIterReadFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a;
212
213 /// Sends bytes to slave with address `address` and then reads enough bytes to fill `buffer` *in a
214 /// single transaction*
215 ///
216 /// # I2C Events (contract)
217 ///
218 /// Same as the `WriteRead` trait
219 fn write_iter_read<'a, B>(
220 self: Pin<&'a mut Self>,
221 address: A,
222 bytes: B,
223 buffer: &mut [u8],
224 ) -> Self::WriteIterReadFuture<'a>
225 where
226 B: IntoIterator<Item = u8>;
227}
228
229/// Transactional I2C operation.
230///
231/// Several operations can be combined as part of a transaction.
232#[derive(Debug, PartialEq)]
233pub enum Operation<'a> {
234 /// Read data into the provided buffer
235 Read(&'a mut [u8]),
236 /// Write data from the provided buffer
237 Write(&'a [u8]),
238}
239
240/// Transactional I2C interface.
241///
242/// This allows combining operations within an I2C transaction.
243pub trait Transactional<A: AddressMode = SevenBitAddress> {
244 /// Error type
245 type Error;
246
247 type TransactionalFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a;
248
249 /// Execute the provided operations on the I2C bus.
250 ///
251 /// Transaction contract:
252 /// - Before executing the first operation an ST is sent automatically. This is followed by SAD+R/W as appropriate.
253 /// - Data from adjacent operations of the same type are sent after each other without an SP or SR.
254 /// - Between adjacent operations of a different type an SR and SAD+R/W is sent.
255 /// - After executing the last operation an SP is sent automatically.
256 /// - If the last operation is a `Read` the master does not send an acknowledge for the last byte.
257 ///
258 /// - `ST` = start condition
259 /// - `SAD+R/W` = slave address followed by bit 1 to indicate reading or 0 to indicate writing
260 /// - `SR` = repeated start condition
261 /// - `SP` = stop condition
262 fn exec<'a>(
263 &mut self,
264 address: A,
265 operations: &mut [Operation<'a>],
266 ) -> Self::TransactionalFuture<'a>;
267}
268
269/// Transactional I2C interface (iterator version).
270///
271/// This allows combining operation within an I2C transaction.
272pub trait TransactionalIter<A: AddressMode = SevenBitAddress> {
273 /// Error type
274 type Error;
275
276 type TransactionalIterFuture<'a>: Future<Output = Result<(), Self::Error>> + 'a;
277
278 /// Execute the provided operations on the I2C bus (iterator version).
279 ///
280 /// Transaction contract:
281 /// - Before executing the first operation an ST is sent automatically. This is followed by SAD+R/W as appropriate.
282 /// - Data from adjacent operations of the same type are sent after each other without an SP or SR.
283 /// - Between adjacent operations of a different type an SR and SAD+R/W is sent.
284 /// - After executing the last operation an SP is sent automatically.
285 /// - If the last operation is a `Read` the master does not send an acknowledge for the last byte.
286 ///
287 /// - `ST` = start condition
288 /// - `SAD+R/W` = slave address followed by bit 1 to indicate reading or 0 to indicate writing
289 /// - `SR` = repeated start condition
290 /// - `SP` = stop condition
291 fn exec_iter<'a, O>(&mut self, address: A, operations: O) -> Self::TransactionalIterFuture<'a>
292 where
293 O: IntoIterator<Item = Operation<'a>>;
294}
295
296/// Default implementation of `blocking::i2c::Write`, `blocking::i2c::Read` and
297/// `blocking::i2c::WriteRead` traits for `blocking::i2c::Transactional` implementers.
298///
299/// If you implement `blocking::i2c::Transactional` for your I2C peripheral,
300/// you can use this default implementation so that you do not need to implement
301/// the `blocking::i2c::Write`, `blocking::i2c::Read` and `blocking::i2c::WriteRead`
302/// traits as well.
303/// ```
304/// use embedded_hal::blocking::i2c;
305///
306/// struct I2c1;
307///
308/// impl i2c::Transactional<i2c::SevenBitAddress> for I2c1 {
309/// # type Error = ();
310/// fn try_exec<'a>(
311/// &mut self,
312/// address: i2c::SevenBitAddress,
313/// operations: &mut [i2c::Operation<'a>],
314/// ) -> Result<(), Self::Error> {
315/// // ...
316/// # Ok(())
317/// }
318/// }
319///
320/// // This is all you need to do:
321/// impl i2c::transactional::Default<i2c::SevenBitAddress> for I2c1 {};
322///
323/// // Then you can use `Write` and so on:
324/// use i2c::Write;
325///
326/// let mut i2c1 = I2c1{};
327/// i2c1.try_write(0x01, &[0xAB, 0xCD]).unwrap();
328/// ```
329pub mod transactional {
330 use core::future::Future;
331
332 use super::{AddressMode, Operation, Read, Transactional, Write, WriteRead};
333
334 /// Default implementation of `blocking::i2c::Write`, `blocking::i2c::Read` and
335 /// `blocking::i2c::WriteRead` traits for `blocking::i2c::Transactional` implementers.
336 pub trait Default<A: AddressMode>: Transactional<A> {}
337
338 // impl<A, E, S> Write<A> for S
339 // where
340 // A: AddressMode + 'static,
341 // S: self::Default<A> + Transactional<A, Error = E> + 'static,
342 // E: 'static,
343 // {
344 // type Error = E;
345 //
346 // type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a;
347 //
348 // fn write<'a>(&mut self, address: A, bytes: &[u8]) -> Self::WriteFuture<'a> {
349 // self.exec(address, &mut [Operation::Write(bytes)])
350 // }
351 // }
352 /*
353 impl<A, E, S> Read<A> for S
354 where
355 A: AddressMode,
356 S: self::Default<A> + Transactional<A, Error = E>,
357 {
358 type Error = E;
359
360 fn read(&mut self, address: A, buffer: &mut [u8]) -> Result<(), Self::Error> {
361 self.exec(address, &mut [Operation::Read(buffer)])
362 }
363 }
364
365 impl<A, E, S> WriteRead<A> for S
366 where
367 A: AddressMode,
368 S: self::Default<A> + Transactional<A, Error = E>,
369 {
370 type Error = E;
371
372 fn write_read(
373 &mut self,
374 address: A,
375 bytes: &[u8],
376 buffer: &mut [u8],
377 ) -> Result<(), Self::Error> {
378 self.exec(
379 address,
380 &mut [Operation::Write(bytes), Operation::Read(buffer)],
381 )
382 }
383 }
384 */
385}