pub trait EpdHw {
type Spi: SpiDevice;
type Dc: OutputPin;
type Reset: OutputPin;
type Busy: InputPin + Wait;
type Delay: DelayNs;
type Error: CoreError + From<<Self::Spi as SpiErrorType>::Error> + From<<Self::Dc as PinErrorType>::Error> + From<<Self::Reset as PinErrorType>::Error> + From<<Self::Busy as PinErrorType>::Error> + From<Error>;
// Required methods
fn dc(&mut self) -> &mut Self::Dc;
fn reset(&mut self) -> &mut Self::Reset;
fn busy(&mut self) -> &mut Self::Busy;
fn delay(&mut self) -> &mut Self::Delay;
}Expand description
Provides access to the hardware needed to control an EPD.
This greatly simplifies the generics needed by the Epd trait and implementing types at the cost of implementing this trait.
In this example, we make the EPD generic over just the SPI type, but can drop generics for the pins and delay type.
use core::convert::Infallible;
use embassy_embedded_hal::shared_bus::asynch::spi::SpiDevice;
use embassy_embedded_hal::shared_bus::SpiDeviceError;
use embassy_rp::gpio::{Input, Output};
use embassy_rp::spi::{self, Spi};
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_time::Delay;
use epd_waveshare_async::{EpdHw, Error as EpdError};
use thiserror::Error as ThisError;
/// Define an error type that can convert from the SPI and GPIO errors.
#[derive(Debug, ThisError)]
enum Error {
#[error("SPI error: {0:?}")]
SpiError(SpiDeviceError<spi::Error, Infallible>),
#[error("Display error: {0:?}")]
DisplayError(EpdError),
}
impl From<Infallible> for Error {
fn from(_: Infallible) -> Self {
// GPIO errors are infallible, i.e. they can't occur, so this should be unreachable.
unreachable!()
}
}
impl From<SpiDeviceError<spi::Error, Infallible>> for Error {
fn from(e: SpiDeviceError<spi::Error, Infallible>) -> Self {
Error::SpiError(e)
}
}
impl From<EpdError> for Error {
fn from(e: EpdError) -> Self {
Error::DisplayError(e)
}
}
struct RpEpdHw<'a, SPI: spi::Instance + 'a> {
dc: Output<'a>,
reset: Output<'a>,
busy: Input<'a>,
delay: Delay,
_phantom: core::marker::PhantomData<SPI>,
}
impl <'a, SPI: spi::Instance + 'a> EpdHw for RpEpdHw<'a, SPI> {
type Spi = SpiDevice<'a, CriticalSectionRawMutex, Spi<'a, SPI, spi::Async>, Output<'a>>;
type Dc = Output<'a>;
type Reset = Output<'a>;
type Busy = Input<'a>;
type Delay = Delay;
type Error = Error;
fn dc(&mut self) -> &mut Self::Dc {
&mut self.dc
}
fn reset(&mut self) -> &mut Self::Reset {
&mut self.reset
}
fn busy(&mut self) -> &mut Self::Busy {
&mut self.busy
}
fn delay(&mut self) -> &mut Self::Delay {
&mut self.delay
}
}