use crate::Error;
use embedded_hal_async::{i2c, spi::SpiDevice};
#[derive(Debug)]
pub struct AsyncI2cInterface<I2C> {
pub(crate) i2c: I2C,
pub(crate) address: u8,
}
#[derive(Debug)]
pub struct AsyncSpiInterface<SPI> {
pub(crate) spi: SPI,
}
#[allow(async_fn_in_trait)]
pub trait AsyncWriteData {
type Error;
async fn write_data(&mut self, payload: &[u8]) -> Result<(), Self::Error>;
}
#[allow(async_fn_in_trait)]
pub trait AsyncReadData {
type Error;
async fn read_register(&mut self, register: u8) -> Result<u8, Self::Error>;
async fn read_data<'a>(&mut self, payload: &'a mut [u8]) -> Result<&'a [u8], Self::Error>;
}
impl<I2C, E> AsyncWriteData for AsyncI2cInterface<I2C>
where
I2C: i2c::I2c<Error = E>,
{
type Error = Error<E>;
async fn write_data(&mut self, payload: &[u8]) -> Result<(), Self::Error> {
self.i2c.write(self.address, payload).await.map_err(Error::Comm)
}
}
impl<I2C, E> AsyncReadData for AsyncI2cInterface<I2C>
where
I2C: i2c::I2c<Error = E>,
{
type Error = Error<E>;
async fn read_register(&mut self, register: u8) -> Result<u8, Self::Error> {
let mut temp_data = [0u8; 128];
let mut data = [0u8; 2];
self.i2c
.write_read(self.address, &[register], &mut temp_data)
.await
.map_err(Error::Comm)?;
for i in 0..data.len() {
data[i] = temp_data[i + 2];
}
Ok(data[0])
}
async fn read_data<'a>(&mut self, payload: &'a mut [u8]) -> Result<&'a [u8], Self::Error> {
let address = payload[0];
let len = payload.len();
let data = &mut payload[1..len];
let total_len = data.len() + 2;
let mut temp_buf = [0u8; 128];
self.i2c
.write_read(self.address, &[address], &mut temp_buf[..total_len])
.await
.map_err(Error::Comm)?;
data.copy_from_slice(&temp_buf[2..total_len]);
Ok(data)
}
}
impl<SPI, E> AsyncWriteData for AsyncSpiInterface<SPI>
where
SPI: SpiDevice<Error = E>,
{
type Error = Error<E>;
async fn write_data(&mut self, payload: &[u8]) -> Result<(), Self::Error> {
self.spi.write(payload).await.map_err(Error::Comm)
}
}
impl<SPI, E> AsyncReadData for AsyncSpiInterface<SPI>
where
SPI: SpiDevice<Error = E>,
{
type Error = Error<E>;
async fn read_register(&mut self, register: u8) -> Result<u8, Self::Error> {
let mut data = [register | 0x80, 0, 0]; self.spi.transfer_in_place(&mut data).await.map_err(Error::Comm)?;
Ok(data[2]) }
async fn read_data<'a>(&mut self, payload: &'a mut [u8]) -> Result<&'a [u8], Self::Error> {
let len = payload.len();
let mut temp_buf = [0u8; 128]; temp_buf[0] = payload[0] | 0x80;
self.spi
.transfer_in_place(&mut temp_buf[..len + 1])
.await
.map_err(Error::Comm)?;
payload[1..].copy_from_slice(&temp_buf[2..len + 1]);
Ok(&payload[1..])
}
}