use embedded_hal::blocking::delay::{DelayMs, DelayUs};
use embedded_hal::blocking::spi::{self, Operation, Transfer, Write};
use embedded_hal::digital::{InputPin, OutputPin};
use crate::{Busy, Error, ManagedChipSelect, PinState, Ready, Reset};
pub struct Wrapper<Spi, SpiError, CsPin, BusyPin, ReadyPin, ResetPin, PinError, Delay, DelayError> {
spi: Spi,
cs: CsPin,
reset: ResetPin,
busy: BusyPin,
ready: ReadyPin,
delay: Delay,
_e: core::marker::PhantomData<Error<SpiError, PinError, DelayError>>,
}
impl<Spi, SpiError, CsPin, BusyPin, ReadyPin, ResetPin, PinError, Delay, DelayError>
ManagedChipSelect
for Wrapper<Spi, SpiError, CsPin, BusyPin, ReadyPin, ResetPin, PinError, Delay, DelayError>
{
}
impl<Spi, SpiError, CsPin, BusyPin, ReadyPin, ResetPin, PinError, Delay, DelayError>
Wrapper<Spi, SpiError, CsPin, BusyPin, ReadyPin, ResetPin, PinError, Delay, DelayError>
where
Spi: Write<u8, Error = SpiError> + Transfer<u8, Error = SpiError>,
CsPin: OutputPin<Error = PinError>,
{
pub fn new(
spi: Spi,
cs: CsPin,
reset: ResetPin,
busy: BusyPin,
ready: ReadyPin,
delay: Delay,
) -> Self {
Self {
spi,
cs,
reset,
busy,
ready,
delay,
_e: core::marker::PhantomData,
}
}
pub fn inner_spi(&mut self) -> &mut Spi {
&mut self.spi
}
}
impl<Spi, SpiError, CsPin, BusyPin, ReadyPin, ResetPin, PinError, Delay, DelayError>
spi::Transfer<u8>
for Wrapper<Spi, SpiError, CsPin, BusyPin, ReadyPin, ResetPin, PinError, Delay, DelayError>
where
Spi: Transfer<u8, Error = SpiError>,
CsPin: OutputPin<Error = PinError>,
{
type Error = Error<SpiError, PinError, DelayError>;
fn try_transfer<'w>(&mut self, data: &'w mut [u8]) -> Result<&'w [u8], Self::Error> {
self.cs.try_set_low().map_err(Error::Pin)?;
let r = self.spi.try_transfer(data).map_err(Error::Spi);
self.cs.try_set_high().map_err(Error::Pin)?;
r
}
}
impl<Spi, SpiError, CsPin, BusyPin, ReadyPin, ResetPin, PinError, Delay, DelayError> spi::Write<u8>
for Wrapper<Spi, SpiError, CsPin, BusyPin, ReadyPin, ResetPin, PinError, Delay, DelayError>
where
Spi: Write<u8, Error = SpiError>,
CsPin: OutputPin<Error = PinError>,
{
type Error = Error<SpiError, PinError, DelayError>;
fn try_write<'w>(&mut self, data: &'w [u8]) -> Result<(), Self::Error> {
self.cs.try_set_low().map_err(Error::Pin)?;
let r = self.spi.try_write(data).map_err(Error::Spi);
self.cs.try_set_high().map_err(Error::Pin)?;
r
}
}
impl<Spi, SpiError, CsPin, BusyPin, ReadyPin, ResetPin, PinError, Delay, DelayError>
spi::Transactional<u8>
for Wrapper<Spi, SpiError, CsPin, BusyPin, ReadyPin, ResetPin, PinError, Delay, DelayError>
where
Spi: spi::Transactional<u8, Error = SpiError>,
CsPin: OutputPin<Error = PinError>,
{
type Error = Error<SpiError, PinError, DelayError>;
fn try_exec<'a>(&mut self, operations: &mut [Operation<'a, u8>]) -> Result<(), Self::Error> {
self.cs.try_set_low().map_err(Error::Pin)?;
let r = spi::Transactional::try_exec(&mut self.spi, operations).map_err(Error::Spi);
self.cs.try_set_high().map_err(Error::Pin)?;
r
}
}
impl<Spi, SpiError, CsPin, BusyPin, ReadyPin, ResetPin, PinError, Delay, DelayError> Reset
for Wrapper<Spi, SpiError, CsPin, BusyPin, ReadyPin, ResetPin, PinError, Delay, DelayError>
where
ResetPin: OutputPin<Error = PinError>,
{
type Error = Error<SpiError, PinError, DelayError>;
fn set_reset(&mut self, state: PinState) -> Result<(), Self::Error> {
match state {
PinState::High => self.reset.try_set_high().map_err(Error::Pin)?,
PinState::Low => self.reset.try_set_low().map_err(Error::Pin)?,
};
Ok(())
}
}
impl<Spi, SpiError, CsPin, BusyPin, ReadyPin, ResetPin, PinError, Delay, DelayError> Busy
for Wrapper<Spi, SpiError, CsPin, BusyPin, ReadyPin, ResetPin, PinError, Delay, DelayError>
where
BusyPin: InputPin<Error = PinError>,
{
type Error = Error<SpiError, PinError, DelayError>;
fn get_busy(&mut self) -> Result<PinState, Self::Error> {
match self.busy.try_is_high().map_err(Error::Pin)? {
true => Ok(PinState::High),
false => Ok(PinState::Low),
}
}
}
impl<Spi, SpiError, CsPin, BusyPin, ReadyPin, ResetPin, PinError, Delay, DelayError> Ready
for Wrapper<Spi, SpiError, CsPin, BusyPin, ReadyPin, ResetPin, PinError, Delay, DelayError>
where
ReadyPin: InputPin<Error = PinError>,
{
type Error = Error<SpiError, PinError, DelayError>;
fn get_ready(&mut self) -> Result<PinState, Self::Error> {
match self.ready.try_is_high().map_err(Error::Pin)? {
true => Ok(PinState::High),
false => Ok(PinState::Low),
}
}
}
impl<Spi, SpiError, CsPin, BusyPin, ReadyPin, ResetPin, PinError, Delay, DelayError> DelayMs<u32>
for Wrapper<Spi, SpiError, CsPin, BusyPin, ReadyPin, ResetPin, PinError, Delay, DelayError>
where
Delay: DelayMs<u32, Error = DelayError>,
{
type Error = DelayError;
fn try_delay_ms(&mut self, ms: u32) -> Result<(), Self::Error> {
self.delay.try_delay_ms(ms)
}
}
impl<Spi, SpiError, CsPin, BusyPin, ReadyPin, ResetPin, PinError, Delay, DelayError> DelayUs<u32>
for Wrapper<Spi, SpiError, CsPin, BusyPin, ReadyPin, ResetPin, PinError, Delay, DelayError>
where
Delay: DelayUs<u32, Error = DelayError>,
{
type Error = DelayError;
fn try_delay_us(&mut self, us: u32) -> Result<(), Self::Error> {
self.delay.try_delay_us(us)
}
}