#![no_std]
#![allow(async_fn_in_trait)]
use core::iter::once;
pub use embedded_hal::i2c::{AddressMode, I2c};
#[derive(Debug, PartialEq, Eq)]
#[cfg_attr(feature = "defmt-03", derive(defmt::Format))]
pub enum Operation<'a, B>
where
B: IntoIterator<Item = u8>,
{
Read(&'a mut [u8]),
WriteIter(B),
}
pub trait I2cIter<A: AddressMode>: I2c<A> {
fn transaction_iter<'a, O, B>(&mut self, address: A, operations: O) -> Result<(), Self::Error>
where
O: IntoIterator<Item = Operation<'a, B>>,
B: IntoIterator<Item = u8>;
fn write_iter<B>(&mut self, address: A, bytes: B) -> Result<(), Self::Error>
where
B: IntoIterator<Item = u8>,
{
self.transaction_iter(address, once(Operation::WriteIter(bytes)))
}
fn write_iter_read<B>(
&mut self,
address: A,
bytes: B,
buffer: &mut [u8],
) -> Result<(), Self::Error>
where
B: IntoIterator<Item = u8>,
{
self.transaction_iter(
address,
[Operation::WriteIter(bytes), Operation::Read(buffer)],
)
}
}
#[cfg(feature = "async")]
pub mod non_blocking {
use core::iter::once;
pub use embedded_hal_async::i2c::{AddressMode, I2c};
use crate::Operation;
pub trait I2cIter<A: AddressMode>: I2c<A> {
async fn transaction_iter<'a, O, B>(
&mut self,
address: A,
operations: O,
) -> Result<(), Self::Error>
where
O: IntoIterator<Item = Operation<'a, B>>,
B: IntoIterator<Item = u8>;
async fn write_iter<B>(&mut self, address: A, bytes: B) -> Result<(), Self::Error>
where
B: IntoIterator<Item = u8>,
{
self.transaction_iter(address, once(Operation::WriteIter(bytes)))
.await
}
async fn write_iter_read<B>(
&mut self,
address: A,
bytes: B,
buffer: &mut [u8],
) -> Result<(), Self::Error>
where
B: IntoIterator<Item = u8>,
{
self.transaction_iter(
address,
[Operation::WriteIter(bytes), Operation::Read(buffer)],
)
.await
}
}
}