use epd_waveshare::{epd7in3f::Epd7in3f, prelude::WaveshareDisplay}; use linux_embedded_hal::spidev::SpiModeFlags; use linux_embedded_hal::spidev::SpidevOptions; use linux_embedded_hal::{CdevPin, Delay, SpidevDevice}; use tracing::instrument; use tracing::{debug, debug_span, warn}; use anyhow::Result; use linux_embedded_hal::gpio_cdev::{Chip, LineRequestFlags}; pub trait EInkPanel { fn display(&mut self, buf: &[u8]) -> Result<()>; } pub struct Wrapper { spi: SpidevDevice, gpiochip: Chip, delay: Delay, panel: Epd7in3f, } impl Wrapper { pub fn new() -> Result { let mut spi = SpidevDevice::open("/dev/spidev0.0")?; let spi_options = SpidevOptions::new() .bits_per_word(8) .max_speed_hz(10_000_000) .mode(SpiModeFlags::SPI_MODE_0) .build(); spi.configure(&spi_options)?; let mut gpiochip = Chip::new("/dev/gpiochip0")?; let busy_pin = CdevPin::new(gpiochip.get_line(24)?.request( LineRequestFlags::INPUT, 0, "frametool", )?)?; let dc_pin = CdevPin::new(gpiochip.get_line(25)?.request( LineRequestFlags::OUTPUT, 0, "frametool", )?)?; let rst_pin = CdevPin::new(gpiochip.get_line(17)?.request( LineRequestFlags::OUTPUT, 0, "frametool", )?)?; let mut delay = Delay {}; let panel = Epd7in3f::new(&mut spi, busy_pin, dc_pin, rst_pin, &mut delay, None)?; Ok(Self { spi, gpiochip, delay, panel, }) } pub fn test(&mut self) -> Result<()> { self.panel.show_7block(&mut self.spi, &mut self.delay)?; self.panel.sleep(&mut self.spi, &mut self.delay)?; Ok(()) } } impl EInkPanel for Wrapper { #[instrument(skip_all)] fn display(&mut self, buf: &[u8]) -> Result<()> { self.panel .update_and_display_frame(&mut self.spi, buf, &mut self.delay)?; debug!("Finished updating frame"); self.panel.sleep(&mut self.spi, &mut self.delay)?; debug!("Display entered sleep mode"); Ok(()) } } pub struct FakeEInk(); impl EInkPanel for FakeEInk { fn display(&mut self, _buf: &[u8]) -> Result<()> { // Do nothing. warn!("Fake display was called"); Ok(()) } }