use crate::spi::{InnerDelay, SpiBusWrapper, SpiDev, SpiInitError, make_device};
use esp_hal::gpio::{DriveMode, Level, Output, OutputConfig, Pull};
use mipidsi::interface::SpiInterface;
use mipidsi::models::ST7789;
use mipidsi::options::{ColorInversion, Orientation, RefreshOrder, Rotation, TearingEffect};
use mipidsi::{Builder, Display, NoResetPin};
use static_cell::StaticCell;
#[cfg(feature = "display_buffer_512")]
static DISPLAY_BUFFER_CELL: StaticCell<[u8; 512]> = StaticCell::new();
#[cfg(feature = "display_buffer_1024")]
static DISPLAY_BUFFER_CELL: StaticCell<[u8; 1024]> = StaticCell::new();
#[cfg(feature = "display_buffer_8192")]
static DISPLAY_BUFFER_CELL: StaticCell<[u8; 8192]> = StaticCell::new();
pub type LilkaDisplay =
Display<SpiInterface<'static, SpiDev<'static>, Output<'static>>, ST7789, NoResetPin>;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DisplayInitError {
SpiDevice(SpiInitError),
ControllerInitFailed,
TearingConfigFailed,
}
impl DisplayInitError {
pub const fn as_str(self) -> &'static str {
match self {
Self::SpiDevice(err) => err.as_str(),
Self::ControllerInitFailed => "Display init failed",
Self::TearingConfigFailed => "Display tearing config failed",
}
}
}
pub fn init_display(
dp: esp_hal::peripherals::GPIO46,
dc: esp_hal::peripherals::GPIO15<'static>,
cs: esp_hal::peripherals::GPIO7<'static>,
spi_bus: &'static SpiBusWrapper,
mut delay: InnerDelay,
refresh_order: RefreshOrder,
rotation: Rotation,
tearing: TearingEffect,
) -> Result<LilkaDisplay, DisplayInitError> {
let mut display_power = Output::new(
dp,
Level::High,
OutputConfig::default()
.with_drive_mode(DriveMode::PushPull)
.with_pull(Pull::Down),
);
display_power.set_high();
let dc: Output<'static> = Output::new(
dc,
Level::Low,
OutputConfig::default().with_drive_mode(DriveMode::PushPull),
);
let disp_cs: Output<'static> = Output::new(
cs,
Level::Low,
OutputConfig::default().with_drive_mode(DriveMode::PushPull),
);
let spi_dev =
make_device(spi_bus, disp_cs, delay.clone()).map_err(DisplayInitError::SpiDevice)?;
cfg_if::cfg_if! {
if #[cfg(feature = "display_buffer_512")] {
let di = SpiInterface::new(spi_dev, dc, DISPLAY_BUFFER_CELL.init([0_u8; 512]));
} else if #[cfg(feature = "display_buffer_1024")] {
let di = SpiInterface::new(spi_dev, dc, DISPLAY_BUFFER_CELL.init([0_u8; 1024]));
} else if #[cfg(feature = "display_buffer_8192")] {
let di = SpiInterface::new(spi_dev, dc, DISPLAY_BUFFER_CELL.init([0_u8; 8192]));
} else {
compile_error!("Один з display_buffer_512, display_buffer_1024, або display_buffer_8192 має бути активний");
}
}
let mut display = Builder::new(ST7789, di)
.refresh_order(refresh_order)
.invert_colors(ColorInversion::Inverted)
.display_size(240, 280)
.orientation(Orientation::new().rotate(rotation))
.display_offset(0, 20)
.color_order(mipidsi::options::ColorOrder::Rgb)
.init(&mut delay)
.map_err(|_| DisplayInitError::ControllerInitFailed)?;
display
.set_tearing_effect(tearing)
.map_err(|_| DisplayInitError::TearingConfigFailed)?;
Ok(display)
}