diff --git a/src/epaper.rs b/src/epaper.rs new file mode 100644 index 0000000..fe23636 --- /dev/null +++ b/src/epaper.rs @@ -0,0 +1,181 @@ +use embedded_graphics::{ + geometry::{Point, Size}, + mono_font::MonoTextStyleBuilder, + primitives::{Primitive, PrimitiveStyleBuilder, Rectangle}, + text::{Baseline, Text, TextStyleBuilder}, + Drawable, +}; +use embedded_hal::delay::DelayNs; +use embedded_hal_bus::spi::ExclusiveDevice; +use epd_waveshare::epd3in7::*; +use epd_waveshare::prelude::*; +use esp_hal::{ + clock::Clocks, + delay::Delay, + gpio::{Gpio18, Gpio19, Gpio20, Gpio21, Gpio22, Gpio23, Input, Io, Level, Output, NO_PIN}, + peripherals::Peripherals, + prelude::*, + spi::{master::Spi, FullDuplexMode, SpiMode}, +}; + +pub type CS<'b> = Output<'b, Gpio20>; +pub type BUS<'b> = Input<'b, Gpio23>; +pub type RST<'b> = Output<'b, Gpio22>; +pub type DC<'b> = Output<'b, Gpio21>; +pub type SpiBus<'b> = Spi<'b, esp_hal::peripherals::SPI2, FullDuplexMode>; +pub type SPI<'b> = ExclusiveDevice, CS<'b>, Delay>; +pub type Driver<'b> = EPD3in7, BUS<'b>, DC<'b>, RST<'b>, Delay>; + +pub struct Epaper<'d> { + pub display: Display3in7, + pub driver: Driver<'d>, + pub spi: SPI<'d>, + pub delay: Delay, +} + +/** + * Board mapping: + * + * + * _________ + * __| |__ + * | | + * 3.3v O | + * | | + * | | + * | | + * | | + * | O 23 - BUSY + * | O 22 - RESET (RST) + * | O 21 - DC + * | O 20 - CS + * | O 19 - CLK / SCLK + * | O 18 - DIM + * | | + * | | + * | | + * |__ ___ __| + * | | | | + * CH343 ESP32C6 + * + * Cannonical wiring + * * BUSY - purple - Gpio23 + * * RST - white - Gpio22 + * * DC - green - Gpio21 + * * CS - orange - Gpio20 + * * CLK - yellow - Gpio19 + * * DIM - blue - Gpio18 + * * GND - brown - ANY GND + * * VCC - gray - 3.3v + * + */ + +// let mut epaper = epaper::Epaper::new(mosi, sclk, cs, dc, rst, busy, peripherals.SPI2, &clocks); +impl<'d> Epaper<'d> { + pub fn new( + din: Gpio18, + sclk: Gpio19, + cs: Gpio20, + dc: Gpio21, + rst: Gpio22, + busy: Gpio23, + spi: esp_hal::peripherals::SPI2, + clocks: &'d Clocks, + ) -> Self { + let mut delay = Delay::new(&clocks); + + let spi_bus: SpiBus = Spi::new(spi, 4_000.kHz(), SpiMode::Mode0, clocks).with_pins( + Some(sclk), + Some(din), + NO_PIN, + NO_PIN, // cs is handled by the exclusive device + ); + + let cs: CS = Output::new(cs, Level::High); + let busy: BUS = Input::new(busy, esp_hal::gpio::Pull::Up); + let dc: DC = Output::new(dc, Level::High); + let rst = Output::new(rst, Level::High); + + log::info!("Intializing SPI Device..."); + let mut spi: SPI = + ExclusiveDevice::new(spi_bus, cs, delay).expect("SPI device initialize error"); + log::info!("SPI ExclusiveDevice done"); + let mut driver = + EPD3in7::new(&mut spi, busy, dc, rst, &mut delay, None).expect("eink initalize error"); + log::info!("Driver DONE"); + + let mut display = Display3in7::default(); + log::info!("Display DONE"); + display.set_rotation(DisplayRotation::Rotate90); + log::info!("Display ratation DONE"); + driver.set_background_color(Color::White); + driver.clear_frame(&mut spi, &mut delay).unwrap(); + + Self { + display, + driver, + spi, + delay, + } + } + + pub fn full_update(&mut self) { + // self.driver + // .clear_frame(&mut self.spi, &mut self.delay) + // .unwrap(); + self.driver + .update_and_display_frame(&mut self.spi, self.display.buffer(), &mut self.delay) + .expect("display frame new graphics"); + } + + pub fn full_erase(&mut self) { + self.driver + .clear_frame(&mut self.spi, &mut self.delay) + .unwrap(); + log::info!("Clearing display"); + let _ = Rectangle::new(Point::new(0, 0), Size::new(480, 280)) + .into_styled( + PrimitiveStyleBuilder::new() + .fill_color(Color::White) + .build(), + ) + .draw(&mut self.display); + log::info!("Clearing display DONE"); + } + + pub fn print_welcome(&mut self) { + // draw white on black background + let style = MonoTextStyleBuilder::new() + .font(&embedded_graphics::mono_font::ascii::FONT_9X15_BOLD) + .text_color(Color::Black) + .background_color(Color::White) + .build(); + let text_style = TextStyleBuilder::new().baseline(Baseline::Top).build(); + let _ = Text::with_text_style("Booting...", Point::new(90, 10), style, text_style) + .draw(&mut self.display); + self.driver + .update_and_display_frame(&mut self.spi, self.display.buffer(), &mut self.delay) + .expect("display frame new graphics"); + self.delay.delay_ms(500); + } + + pub fn wake_up(&mut self) { + self.driver.wake_up(&mut self.spi, &mut self.delay).unwrap(); + } + + pub fn sleep(&mut self) { + let _ = self.driver.sleep(&mut self.spi, &mut self.delay); + } + + pub fn partial_update(&mut self, pos: Point, size: Size, buffer: &[u8]) { + let _ = self.driver.update_partial_frame( + &mut self.spi, + &mut self.delay, + buffer, + pos.x as u32, + pos.y as u32, + size.width, + size.height, + ); + } +}