#![no_std] use embedded_hal::{ delay::DelayNs, digital::{InputPin, OutputPin}, spi::{Operation, SpiDevice}, }; const EPD_WIDTH: u32 = 240; const EPD_HEIGHT: u32 = 320; const EPD_ARRAY: u32 = EPD_WIDTH * EPD_HEIGHT / 8; pub struct EPaperDisplay { busy: BusyPin, reset: ResetPin, dc: DcPin, spi: SpiDevice, delay: Delay, } pub enum InitError { ResetError(ResetError), WriteError(WriteError), } pub enum WriteError { DcError(DcError), SpiError(SpiError), } impl< BusyPin: InputPin, ResetPin: OutputPin, DcPin: OutputPin, Spi: SpiDevice, Delay: DelayNs, > EPaperDisplay { pub fn new( busy: BusyPin, reset: ResetPin, dc: DcPin, spi: Spi, delay: Delay, ) -> Result> { let mut display = Self { busy, reset, dc, spi, delay, }; display.init().map(|_| display) } fn write_command(&mut self, byte: u8) -> Result<(), WriteError> { self.dc.set_low().map_err(WriteError::DcError)?; self.spi.transaction(&mut [ Operation::DelayNs(60), Operation::Write(&[byte]), Operation::DelayNs(20), ]).map_err(WriteError::SpiError)?; self.delay.delay_ns(40); Ok(()) } fn write_data(&mut self, byte: u8) -> Result<(), WriteError> { self.dc.set_high().map_err(WriteError::DcError)?; self.spi.transaction(&mut [ Operation::DelayNs(60), Operation::Write(&[byte]), Operation::DelayNs(20), ]).map_err(WriteError::SpiError)?; self.delay.delay_ns(40); Ok(()) } fn wait_for_display(&mut self) { while self.busy.is_low().expect("Failed to read busy pin") {} } fn init(&mut self) -> Result<(), InitError> { self.reset.set_low().map_err(InitError::ResetError)?; self.delay.delay_ms(10); self.reset.set_high().map_err(InitError::ResetError)?; self.delay.delay_ms(10); self.write_command(0x00).map_err(InitError::WriteError)?; self.write_data(0x1f).map_err(InitError::WriteError)?; self.write_command(0x04).map_err(InitError::WriteError)?; self.wait_for_display(); Ok(()) } fn clear_display(&mut self) { self.write_command(0x10); for _ in 0..EPD_ARRAY { self.write_data(0xff); } self.write_command(0x13); for _ in 0..EPD_ARRAY { self.write_data(0xff); } self.write_command(0x12); self.delay.delay_ms(1); self.wait_for_display(); } }