///#region Imports mod display; use std::{ thread, time::Duration }; use embedded_graphics::{ framebuffer::{ buffer_size, Framebuffer }, pixelcolor::{ PixelColor, Rgb565 } }; use embedded_graphics::draw_target::DrawTarget; use embedded_graphics::image::ImageDrawable; use embedded_graphics::pixelcolor::raw::BigEndian; use embedded_graphics::pixelcolor::RgbColor; use esp_idf_svc::hal::{ delay::Ets, gpio::{Gpio16, Gpio18, Gpio19, Gpio20, Gpio21, Gpio23, Gpio4, Gpio5, PinDriver}, peripherals::Peripherals, spi::{ config, SpiDeviceDriver, SpiDriverConfig}, spi::config::MODE_3, units::* }; use mipidsi::{Builder, interface::SpiInterface, models::ST7789, options::{ Orientation, ColorOrder, Rotation, ColorInversion }}; use crate::display::screens::{ base::DisplayScreen, error::ErrorScreen, home::StandardScreen, success::SuccessScreen }; ///#endregion ///#region Constants // Display const H: usize = 135; const H_I: i32 = 135; const X_OFF: i32 = 52; const W: usize = 240; const W_I: i32 = 240; const Y_OFF: i32 = 40; const FRAMERATE: usize = 30; type ScreenHolder = [fn(index: &mut usize, frame_counter: &mut usize, dirty: &mut bool, display: &mut Framebuffer) -> anyhow::Result<(), as DrawTarget>::Error>; X]; const SCREENS: ScreenHolder(W, H)}, 3> = [ SuccessScreen::show, StandardScreen::show, ErrorScreen::show ]; static mut DISPLAYBUFFER: [u8; W*H] = [0; W*H]; static mut FRAMEBUFFER: Framebuffer::Raw, BigEndian, {W}, {H}, { buffer_size::(W, H) }> = Framebuffer::new(); //#endregion fn main() -> anyhow::Result<()> { let peripherals: Peripherals = Peripherals::take()?; let pin_rst: Gpio23 = peripherals.pins.gpio23; let pin_dc: Gpio16 = peripherals.pins.gpio16; let pin_bl: Gpio4 = peripherals.pins.gpio4; let pin_sclk: Gpio18 = peripherals.pins.gpio18; let pin_mosi: Gpio19 = peripherals.pins.gpio19; #[cfg(debug_assertions)] let pin_miso: Gpio21 = peripherals.pins.gpio21; #[cfg(not(debug_assertions))] let pin_miso: Gpio20 = peripherals.pins.gpio20; let pin_cs: Gpio5 = peripherals.pins.gpio5; unsafe { esp_idf_svc::sys::link_patches(); esp_idf_svc::log::EspLogger::initialize_default(); log::info!("Hello, world!"); let spi = peripherals.spi2; let mut backlight = PinDriver::output(pin_bl)?; let mut delay = Ets; // configuring the spi interface, note that in order for the ST7789 to work, the data_mode needs to be set to MODE_3 let config = config::Config::new() .baudrate(MegaHertz(26).into()) .data_mode(MODE_3); let device = SpiDeviceDriver::new_single( spi, pin_sclk, pin_mosi, Some(pin_miso), Some(pin_cs), &SpiDriverConfig::new(), &config, )?; // display interface abstraction from SPI and DC let di = SpiInterface::new(device, PinDriver::output(pin_dc)?, &mut *&raw mut DISPLAYBUFFER); #[cfg(debug_assertions)] // create driver let mut display = Builder::new(ST7789, di) .display_size(H as u16, W as u16) .orientation(Orientation::new().flip_horizontal().rotate(Rotation::Deg90)) .reset_pin(PinDriver::output(pin_rst)?) .color_order(ColorOrder::Bgr) .display_offset(X_OFF as u16, Y_OFF as u16) .init(&mut delay) .unwrap(); #[cfg(not(debug_assertions))] // create driver let mut display = Builder::new(ST7789, di) .display_size(H as u16, W as u16) .orientation(Orientation::new().rotate(Rotation::Deg270)) .reset_pin(PinDriver::output(pin_rst)?) .invert_colors(ColorInversion::Inverted) .color_order(ColorOrder::Rgb) .display_offset(X_OFF as u16, Y_OFF as u16) .init(&mut delay) .unwrap(); // turn on the backlight backlight.set_high()?; let mut screen_index: usize = 0; let mut frame_counter: usize = 0; let mut dirty: bool = true; loop { SCREENS[screen_index](&mut screen_index, &mut frame_counter, &mut dirty, &mut FRAMEBUFFER)?; if screen_index == SCREENS.len() { screen_index = 0; } else if screen_index >= SCREENS.len() + 1 { screen_index = SCREENS.len() - 1; } FRAMEBUFFER.as_image().draw(&mut display).unwrap(); thread::sleep(Duration::from_millis((1000 / FRAMERATE) as u64)); frame_counter += 1; } } }