159 lines
4.9 KiB
Rust
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;
|
|
}
|
|
}
|
|
} |