use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported
use embedded_graphics::{
mono_font::MonoTextStyleBuilder,
pixelcolor::BinaryColor::On as Black,
pixelcolor::BinaryColor::{self, Off as White},
prelude::*,
primitives::{Circle, Line, PrimitiveStyleBuilder},
text::{Baseline, Text, TextStyleBuilder},
};
use epd_waveshare::{epd2in9_v2::*, graphics::DisplayRotation, prelude::*};
use esp_idf_hal::delay::Ets;
use esp_idf_hal::gpio::*;
use esp_idf_hal::spi::{config::Config, SpiDeviceDriver};
use esp_idf_hal::{peripherals::Peripherals, spi::SpiDriverConfig};
// This is a remake of the example from epd_waveshare (https://github.com/caemor/epd-waveshare/blob/main/examples/epd4in2.rs).
// The idea behind this is to make the example work with Wokwi simulated e-paper module (and to make the example clearer for newbies).
fn main() -> anyhow::Result<()> {
// It is necessary to call this function once. Otherwise some patches to the runtime
// implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71
esp_idf_sys::link_patches();
// Bind the log crate to the ESP Logging facilities
esp_idf_svc::log::EspLogger::initialize_default();
let peripherals = Peripherals::take().unwrap();
let spi = peripherals.spi2;
let sclk = peripherals.pins.gpio18;
let serial_out = peripherals.pins.gpio23; // SDO
let cs = PinDriver::output(peripherals.pins.gpio5)?;
let busy_in = PinDriver::input(peripherals.pins.gpio4)?;
let dc = PinDriver::output(peripherals.pins.gpio22)?;
let rst = PinDriver::output(peripherals.pins.gpio21)?;
let config = Config::new().baudrate(112500.into());
let mut device = SpiDeviceDriver::new_single(
spi,
sclk,
serial_out,
Option::<Gpio2>::None,
Option::<AnyIOPin>::None,
&SpiDriverConfig::default(),
&config,
)?;
// We cannot use the general purpose Delay struct from esp_idf_hal since it's only implemented for u16 and u32, whereas Epd2in9 uses u8
// TODO PR a generic Delay struct (or simply add u8 etc...)
let mut delay = Ets;
// Setup EPD
let mut epd = Epd2in9::new(&mut device, cs, busy_in, dc, rst, &mut delay)?;
println!("Init done!");
let mut display = Display2in9::default();
println!("Clearing display");
display.clear(BinaryColor::Off)?;
println!("Drawing text");
draw_text(&mut display, "Hello World!", 5, 50);
epd.update_frame(&mut device, display.buffer(), &mut delay)?;
epd.display_frame(&mut device, &mut delay)?;
println!("Going to sleep");
epd.sleep(&mut device, &mut delay)?;
Ok(())
}
fn draw_text(display: &mut Display2in9, text: &str, x: i32, y: i32) {
let style = MonoTextStyleBuilder::new()
.font(&embedded_graphics::mono_font::ascii::FONT_6X10)
.text_color(White)
.background_color(Black)
.build();
let text_style = TextStyleBuilder::new().baseline(Baseline::Top).build();
let _ = Text::with_text_style(text, Point::new(x, y), style, text_style).draw(display);
}
esp:VIN
esp:GND.2
esp:D13
esp:D12
esp:D14
esp:D27
esp:D26
esp:D25
esp:D33
esp:D32
esp:D35
esp:D34
esp:VN
esp:VP
esp:EN
esp:3V3
esp:GND.1
esp:D15
esp:D2
esp:D4
esp:RX2
esp:TX2
esp:D5
esp:D18
esp:D19
esp:D21
esp:RX0
esp:TX0
esp:D22
esp:D23
epd1:BUSY
epd1:RST
epd1:DC
epd1:CS
epd1:CLK
epd1:DIN
epd1:VCC
epd1:GND