use embedded_hal::blocking::delay::DelayUs;
use embedded_hal::digital::v2::{InputPin, OutputPin};
#[derive(Clone, Debug)]
pub enum DisplayError {
InvalidFormatError,
BusWriteError,
DCError,
CSError,
BUSYError,
}
pub trait DisplayInterface {
fn send_command_data(&mut self, command: u8, data: &[u8]) -> Result<(), DisplayError> {
self.send_command(command)?;
self.send_data(data)?;
Ok(())
}
fn send_command(&mut self, command: u8) -> Result<(), DisplayError>;
fn send_data(&mut self, data: &[u8]) -> Result<(), DisplayError>;
fn send_data_from_iter<'a, I>(&mut self, iter: I) -> Result<(), DisplayError>
where
I: IntoIterator<Item = &'a u8>;
fn busy_wait(&self);
fn reset<D>(&mut self, delay: &mut D, initial_delay: u32, duration: u32)
where
D: DelayUs<u32>;
}
pub struct EPDInterface<SPI, CS, DC, RST, BUSY> {
spi: SPI,
cs: CS,
dc: DC,
rst: RST,
busy: BUSY,
}
impl<SPI, CS, DC, RST, BUSY> EPDInterface<SPI, CS, DC, RST, BUSY>
where
SPI: embedded_hal::blocking::spi::Write<u8>,
DC: OutputPin,
CS: OutputPin,
RST: OutputPin,
BUSY: InputPin,
{
pub fn new(spi: SPI, dc: DC, cs: CS, rst: RST, busy: BUSY) -> Self {
EPDInterface {
spi,
dc,
cs,
rst,
busy,
}
}
pub fn release(self) -> (SPI, DC, CS, BUSY) {
(self.spi, self.dc, self.cs, self.busy)
}
}
impl<SPI, CS, DC, RST, BUSY> DisplayInterface for EPDInterface<SPI, CS, DC, RST, BUSY>
where
SPI: embedded_hal::blocking::spi::Write<u8>,
DC: OutputPin,
CS: OutputPin,
RST: OutputPin,
BUSY: InputPin,
{
fn send_command(&mut self, command: u8) -> Result<(), DisplayError> {
self.cs.set_low().map_err(|_| DisplayError::CSError)?;
self.dc.set_low().map_err(|_| DisplayError::DCError)?;
let ret = self
.spi
.write(&[command])
.map_err(|_| DisplayError::BusWriteError);
self.cs.set_high().ok();
ret
}
fn send_data(&mut self, data: &[u8]) -> Result<(), DisplayError> {
self.cs.set_low().map_err(|_| DisplayError::CSError)?;
self.dc.set_high().map_err(|_| DisplayError::DCError)?;
let ret = self
.spi
.write(data)
.map_err(|_| DisplayError::BusWriteError);
self.cs.set_high().ok();
ret
}
fn send_data_from_iter<'a, I>(&mut self, iter: I) -> Result<(), DisplayError>
where
I: IntoIterator<Item = &'a u8>,
{
self.cs.set_low().map_err(|_| DisplayError::CSError)?;
self.dc.set_high().map_err(|_| DisplayError::DCError)?;
for &d in iter {
let ret = self
.spi
.write(&[d])
.map_err(|_| DisplayError::BusWriteError);
if ret.is_err() {
self.cs.set_high().ok();
return ret;
}
}
self.cs.set_high().ok();
Ok(())
}
fn busy_wait(&self) {
while self.busy.is_high().unwrap_or(false) {}
}
fn reset<D>(&mut self, delay: &mut D, initial_delay: u32, duration: u32)
where
D: DelayUs<u32>,
{
let _ = self.rst.set_high();
delay.delay_us(initial_delay);
let _ = self.rst.set_low();
delay.delay_us(duration);
let _ = self.rst.set_high();
delay.delay_us(200_000);
}
}
pub struct EPDInterfaceNoCS<SPI, DC, RST, BUSY> {
spi: SPI,
dc: DC,
rst: RST,
busy: BUSY,
}
impl<SPI, DC, RST, BUSY> EPDInterfaceNoCS<SPI, DC, RST, BUSY>
where
SPI: embedded_hal::blocking::spi::Write<u8>,
DC: OutputPin,
RST: OutputPin,
BUSY: InputPin,
{
pub fn new(spi: SPI, dc: DC, rst: RST, busy: BUSY) -> Self {
EPDInterfaceNoCS { spi, dc, rst, busy }
}
pub fn release(self) -> (SPI, DC, BUSY) {
(self.spi, self.dc, self.busy)
}
}
impl<SPI, DC, RST, BUSY> DisplayInterface for EPDInterfaceNoCS<SPI, DC, RST, BUSY>
where
SPI: embedded_hal::blocking::spi::Write<u8>,
DC: OutputPin,
RST: OutputPin,
BUSY: InputPin,
{
fn send_command(&mut self, command: u8) -> Result<(), DisplayError> {
self.dc.set_low().map_err(|_| DisplayError::DCError)?;
let ret = self
.spi
.write(&[command])
.map_err(|_| DisplayError::BusWriteError);
ret
}
fn send_data(&mut self, data: &[u8]) -> Result<(), DisplayError> {
self.dc.set_high().map_err(|_| DisplayError::DCError)?;
let ret = self
.spi
.write(data)
.map_err(|_| DisplayError::BusWriteError);
ret
}
fn send_data_from_iter<'a, I>(&mut self, iter: I) -> Result<(), DisplayError>
where
I: IntoIterator<Item = &'a u8>,
{
self.dc.set_high().map_err(|_| DisplayError::DCError)?;
for &d in iter {
self.spi
.write(&[d])
.map_err(|_| DisplayError::BusWriteError)?;
}
Ok(())
}
fn busy_wait(&self) {
while self.busy.is_high().unwrap_or(false) {}
}
fn reset<D>(&mut self, delay: &mut D, initial_delay: u32, duration: u32)
where
D: DelayUs<u32>,
{
let _ = self.rst.set_high();
delay.delay_us(initial_delay);
let _ = self.rst.set_low();
delay.delay_us(duration);
let _ = self.rst.set_high();
delay.delay_us(200_000);
}
}