1#![no_std]
2#![allow(async_fn_in_trait)]
3
4use core::iter::once;
5
6pub use embedded_hal::i2c::{AddressMode, I2c};
7
8#[derive(Debug, PartialEq, Eq)]
12#[cfg_attr(feature = "defmt-03", derive(defmt::Format))]
13pub enum Operation<'a, B>
14where
15 B: IntoIterator<Item = u8>,
16{
17 Read(&'a mut [u8]),
19 WriteIter(B),
21}
22
23pub trait I2cIter<A: AddressMode>: I2c<A> {
24 fn transaction_iter<'a, O, B>(&mut self, address: A, operations: O) -> Result<(), Self::Error>
28 where
29 O: IntoIterator<Item = Operation<'a, B>>,
30 B: IntoIterator<Item = u8>;
31
32 fn write_iter<B>(&mut self, address: A, bytes: B) -> Result<(), Self::Error>
36 where
37 B: IntoIterator<Item = u8>,
38 {
39 self.transaction_iter(address, once(Operation::WriteIter(bytes)))
40 }
41
42 fn write_iter_read<B>(
47 &mut self,
48 address: A,
49 bytes: B,
50 buffer: &mut [u8],
51 ) -> Result<(), Self::Error>
52 where
53 B: IntoIterator<Item = u8>,
54 {
55 self.transaction_iter(
56 address,
57 [Operation::WriteIter(bytes), Operation::Read(buffer)],
58 )
59 }
60}
61
62#[cfg(feature = "async")]
64pub mod non_blocking {
65 use core::iter::once;
66
67 pub use embedded_hal_async::i2c::{AddressMode, I2c};
68
69 use crate::Operation;
70
71 pub trait I2cIter<A: AddressMode>: I2c<A> {
72 async fn transaction_iter<'a, O, B>(
76 &mut self,
77 address: A,
78 operations: O,
79 ) -> Result<(), Self::Error>
80 where
81 O: IntoIterator<Item = Operation<'a, B>>,
82 B: IntoIterator<Item = u8>;
83
84 async fn write_iter<B>(&mut self, address: A, bytes: B) -> Result<(), Self::Error>
88 where
89 B: IntoIterator<Item = u8>,
90 {
91 self.transaction_iter(address, once(Operation::WriteIter(bytes)))
92 .await
93 }
94
95 async fn write_iter_read<B>(
100 &mut self,
101 address: A,
102 bytes: B,
103 buffer: &mut [u8],
104 ) -> Result<(), Self::Error>
105 where
106 B: IntoIterator<Item = u8>,
107 {
108 self.transaction_iter(
109 address,
110 [Operation::WriteIter(bytes), Operation::Read(buffer)],
111 )
112 .await
113 }
114 }
115}