use alloc::{vec, vec::Vec};
use core::fmt;
use crate::Transport;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum AdapterError<E> {
Backend(E),
PayloadTooLong {
requested: usize,
maximum: usize,
},
}
impl<E> AdapterError<E> {
pub fn backend_cause(&self) -> Option<&E> {
match self {
Self::Backend(source) => Some(source),
Self::PayloadTooLong { .. } => None,
}
}
}
impl<E: fmt::Display> fmt::Display for AdapterError<E> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Backend(source) => write!(f, "embedded-hal backend error: {source}"),
Self::PayloadTooLong { requested, maximum } => write!(
f,
"adapter payload too long: requested {requested} bytes, maximum {maximum}"
),
}
}
}
#[cfg(feature = "std")]
impl<E> std::error::Error for AdapterError<E>
where
E: std::error::Error + 'static,
{
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Backend(source) => Some(source),
Self::PayloadTooLong { .. } => None,
}
}
}
pub struct SpiTransport<SPI, D> {
spi: SPI,
delay: D,
buf: [u8; 12],
}
impl<SPI, D> SpiTransport<SPI, D>
where
SPI: embedded_hal::spi::SpiDevice,
D: embedded_hal::delay::DelayNs,
{
pub fn new(spi: SPI, delay: D) -> Self {
Self {
spi,
delay,
buf: [0u8; 12],
}
}
}
impl<SPI, D> Transport for SpiTransport<SPI, D>
where
SPI: embedded_hal::spi::SpiDevice,
D: embedded_hal::delay::DelayNs,
{
type Error = AdapterError<SPI::Error>;
fn read_register(&mut self, reg: u8, len: u8) -> Result<Vec<u8>, Self::Error> {
let addr = crate::registers::spi::read_cmd(reg);
let mut read_buf = vec![0u8; len as usize];
let mut ops = [
embedded_hal::spi::Operation::Write(&[addr]),
embedded_hal::spi::Operation::Read(&mut read_buf),
];
self.spi
.transaction(&mut ops)
.map_err(AdapterError::Backend)?;
Ok(read_buf)
}
fn write_register(&mut self, reg: u8, data: &[u8]) -> Result<(), Self::Error> {
let maximum = self.buf.len() - 1;
if data.len() > maximum {
return Err(AdapterError::PayloadTooLong {
requested: data.len(),
maximum,
});
}
self.buf[0] = crate::registers::spi::write_cmd(reg);
self.buf[1..=data.len()].copy_from_slice(data);
let mut ops = [embedded_hal::spi::Operation::Write(
&self.buf[..=data.len()],
)];
self.spi
.transaction(&mut ops)
.map_err(AdapterError::Backend)?;
Ok(())
}
fn delay_ms(&mut self, ms: u32) {
self.delay.delay_ms(ms);
}
}
pub struct I2cTransport<I2C> {
i2c: I2C,
addr: u8,
}
impl<I2C> I2cTransport<I2C>
where
I2C: embedded_hal::i2c::I2c,
{
pub fn new(i2c: I2C, addr: u8) -> Self {
Self { i2c, addr }
}
}
impl<I2C> Transport for I2cTransport<I2C>
where
I2C: embedded_hal::i2c::I2c,
{
type Error = AdapterError<I2C::Error>;
fn read_register(&mut self, reg: u8, len: u8) -> Result<Vec<u8>, Self::Error> {
let mut buf = vec![0u8; len as usize];
self.i2c
.write_read(self.addr, &[reg], &mut buf)
.map_err(AdapterError::Backend)?;
Ok(buf)
}
fn write_register(&mut self, reg: u8, data: &[u8]) -> Result<(), Self::Error> {
let mut buf = Vec::with_capacity(1 + data.len());
buf.push(reg);
buf.extend_from_slice(data);
self.i2c
.write(self.addr, &buf)
.map_err(AdapterError::Backend)?;
Ok(())
}
fn delay_ms(&mut self, _ms: u32) {
}
}