use embedded_hal;
pub const RESET_DELAY_MS: u8 = 10;
pub trait DisplayInterface {
type Error;
fn send_command(&mut self, command: u8) -> Result<(), Self::Error>;
fn send_data(&mut self, data: &[u8]) -> Result<(), Self::Error>;
fn reset<D: embedded_hal::delay::DelayNs>(&mut self, delay: &mut D);
fn busy_wait(&mut self);
}
pub struct Interface4Pin<SPI, OUT, IN> {
spi: SPI,
data_command_pin: OUT,
pub reset_pin: OUT,
busy_pin: IN,
}
impl<SPI, OUT, IN> Interface4Pin<SPI, OUT, IN>
where
SPI: embedded_hal::spi::SpiDevice,
OUT: embedded_hal::digital::OutputPin,
IN: embedded_hal::digital::InputPin,
{
pub fn new(spi: SPI, data_command_pin: OUT, reset_pin: OUT, busy_pin: IN) -> Self {
Self {
spi,
data_command_pin,
reset_pin,
busy_pin,
}
}
fn write(&mut self, data: &[u8]) -> Result<(), SPI::Error> {
if cfg!(target_os = "linux") {
for data_chunk in data.chunks(4096) {
self.spi.write(data_chunk)?;
}
} else {
self.spi.write(data)?;
}
Ok(())
}
}
impl<SPI, OUT, IN> DisplayInterface for Interface4Pin<SPI, OUT, IN>
where
SPI: embedded_hal::spi::SpiDevice,
OUT: embedded_hal::digital::OutputPin,
IN: embedded_hal::digital::InputPin,
{
type Error = SPI::Error;
fn reset<D: embedded_hal::delay::DelayNs>(&mut self, delay: &mut D) {
self.reset_pin.set_low().unwrap();
delay.delay_ms(RESET_DELAY_MS.into());
self.reset_pin.set_high().unwrap();
delay.delay_ms(RESET_DELAY_MS.into());
}
fn send_command(&mut self, command: u8) -> Result<(), Self::Error> {
self.data_command_pin.set_low().unwrap();
self.write(&[command])?;
self.busy_wait();
Ok(())
}
fn send_data(&mut self, data: &[u8]) -> Result<(), Self::Error> {
self.data_command_pin.set_high().unwrap();
self.write(data)?;
self.busy_wait();
Ok(())
}
fn busy_wait(&mut self) {
while match self.busy_pin.is_high() {
Ok(x) => x,
_ => false,
} {}
}
}