use core::convert::Infallible;
use regiface::{
errors::Error as RegifaceError, ByteArray, Command, FromByteArray, ReadableRegister,
ToByteArray, WritableRegister,
};
pub struct Device<SPI> {
spi: SPI,
}
impl<SPI> Device<SPI> {
pub fn new(spi: SPI) -> Self {
Self { spi }
}
pub fn release(self) -> SPI {
self.spi
}
}
impl<SPI> Device<SPI>
where
SPI: embedded_hal::spi::SpiDevice,
{
pub fn read_register<R>(&mut self) -> Result<R, RegifaceError>
where
R: ReadableRegister<IdType = u16>,
{
let header = &mut [0x1D, 0x00, 0x00, 0x00];
header[1..=2].copy_from_slice(&R::id().to_be_bytes());
let mut raw_value = R::Array::new();
self.spi
.transaction(&mut [
embedded_hal::spi::Operation::Write(header.as_slice()),
embedded_hal::spi::Operation::Read(raw_value.as_mut()),
])
.map_err(|_| RegifaceError::BusError)?;
R::from_bytes(raw_value).map_err(|_| RegifaceError::DeserializationError)
}
pub fn write_register<R>(&mut self, register: R) -> Result<(), RegifaceError>
where
R: WritableRegister<IdType = u16, Error = Infallible>,
{
let header = &mut [0x0D, 0x00, 0x00];
header[1..].copy_from_slice(&R::id().to_be_bytes());
let raw_value = register.to_bytes().unwrap();
self.spi
.transaction(&mut [
embedded_hal::spi::Operation::Write(header.as_slice()),
embedded_hal::spi::Operation::Write(raw_value.as_ref()),
])
.map_err(|_| RegifaceError::BusError)
}
pub fn write_buffer(&mut self, offset: u8, bytes: &[u8]) -> Result<(), RegifaceError> {
let header = &mut [0x0E, offset];
self.spi
.transaction(&mut [
embedded_hal::spi::Operation::Write(header.as_slice()),
embedded_hal::spi::Operation::Write(bytes),
])
.map_err(|_| RegifaceError::BusError)
}
pub fn read_buffer(&mut self, offset: u8, bytes: &mut [u8]) -> Result<(), RegifaceError> {
let header = &mut [0x1E, offset, 0x00];
self.spi
.transaction(&mut [
embedded_hal::spi::Operation::Write(header.as_slice()),
embedded_hal::spi::Operation::Read(bytes),
])
.map_err(|_| RegifaceError::BusError)
}
pub fn execute_command<C>(&mut self, command: C) -> Result<C::ResponseParameters, RegifaceError>
where
C: Command<IdType = u8>,
C::CommandParameters: ToByteArray<Error = Infallible>,
{
let request = command.invoking_parameters().to_bytes().unwrap();
let mut raw_response = <C::ResponseParameters as FromByteArray>::Array::new();
self.spi
.transaction(&mut [
embedded_hal::spi::Operation::Write(&[C::id()]),
embedded_hal::spi::Operation::Write(request.as_ref()),
embedded_hal::spi::Operation::Read(raw_response.as_mut()),
])
.map_err(|_| RegifaceError::BusError)?;
C::ResponseParameters::from_bytes(raw_response)
.map_err(|_| RegifaceError::DeserializationError)
}
}
impl<SPI> Device<SPI>
where
SPI: embedded_hal_async::spi::SpiDevice,
{
pub async fn read_register_async<R>(&mut self) -> Result<R, RegifaceError>
where
R: ReadableRegister<IdType = u16>,
{
let header = &mut [0x1D, 0x00, 0x00, 0x00];
header[1..=2].copy_from_slice(&R::id().to_be_bytes());
let mut raw_value = R::Array::new();
self.spi
.transaction(&mut [
embedded_hal_async::spi::Operation::Write(header.as_slice()),
embedded_hal_async::spi::Operation::Read(raw_value.as_mut()),
])
.await
.map_err(|_| RegifaceError::BusError)?;
R::from_bytes(raw_value).map_err(|_| RegifaceError::DeserializationError)
}
pub async fn write_register_async<R>(&mut self, register: R) -> Result<(), RegifaceError>
where
R: WritableRegister<IdType = u16, Error = Infallible>,
{
let header = &mut [0x0D, 0x00, 0x00];
header[1..].copy_from_slice(&R::id().to_be_bytes());
let raw_value = register.to_bytes().unwrap();
self.spi
.transaction(&mut [
embedded_hal_async::spi::Operation::Write(header.as_slice()),
embedded_hal_async::spi::Operation::Write(raw_value.as_ref()),
])
.await
.map_err(|_| RegifaceError::BusError)
}
pub async fn write_buffer_async(
&mut self,
offset: u8,
bytes: &[u8],
) -> Result<(), RegifaceError> {
let header = &mut [0x0E, offset];
self.spi
.transaction(&mut [
embedded_hal_async::spi::Operation::Write(header.as_slice()),
embedded_hal_async::spi::Operation::Write(bytes),
])
.await
.map_err(|_| RegifaceError::BusError)
}
pub async fn read_buffer_async(
&mut self,
offset: u8,
bytes: &mut [u8],
) -> Result<(), RegifaceError> {
let header = &mut [0x1E, offset, 0x00];
self.spi
.transaction(&mut [
embedded_hal_async::spi::Operation::Write(header.as_slice()),
embedded_hal_async::spi::Operation::Read(bytes),
])
.await
.map_err(|_| RegifaceError::BusError)
}
pub async fn execute_command_async<C>(
&mut self,
command: C,
) -> Result<C::ResponseParameters, RegifaceError>
where
C: Command<IdType = u8>,
C::CommandParameters: ToByteArray<Error = Infallible>,
{
let request = command.invoking_parameters().to_bytes().unwrap();
let mut raw_response = <C::ResponseParameters as FromByteArray>::Array::new();
self.spi
.transaction(&mut [
embedded_hal_async::spi::Operation::Write(&[C::id()]),
embedded_hal_async::spi::Operation::Write(request.as_ref()),
embedded_hal_async::spi::Operation::Read(raw_response.as_mut()),
])
.await
.map_err(|_| RegifaceError::BusError)?;
C::ResponseParameters::from_bytes(raw_response)
.map_err(|_| RegifaceError::DeserializationError)
}
}