docker-watcher-esp/src/main.rs
CanadianBaconBoi 36484f1735
Major Rewrite
No more blinking :D
2025-05-10 22:37:10 +02:00

159 lines
4.9 KiB
Rust

///#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<C: RgbColor, BO, const W: usize, const H: usize, const N: usize, const X: usize> = [fn(index: &mut usize, frame_counter: &mut usize, dirty: &mut bool, display: &mut Framebuffer<C, C::Raw, BO, W, H, N>) -> anyhow::Result<(), <Framebuffer<C, C::Raw, BO, W, H, N> as DrawTarget>::Error>; X];
const SCREENS: ScreenHolder<Rgb565, BigEndian, W, H, {buffer_size::<Rgb565>(W, H)}, 3> = [
SuccessScreen::show,
StandardScreen::show,
ErrorScreen::show
];
static mut DISPLAYBUFFER: [u8; W*H] = [0; W*H];
static mut FRAMEBUFFER: Framebuffer<Rgb565, <Rgb565 as PixelColor>::Raw, BigEndian, {W}, {H}, { buffer_size::<Rgb565>(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;
}
}
}