use display_interface::{DisplayError, WriteOnlyDataCommand};
use embedded_hal::delay::DelayNs;
use crate::command::{
Command, DINVMode, Dbi, Dpi, GSMode, Gamma1, Gamma2, Gamma3, Gamma4, Logical, SSMode,
};
pub trait DisplayDefinition {
const WIDTH: u16;
const HEIGHT: u16;
const OFFSET_X: u16 = 0;
const OFFSET_Y: u16 = 0;
const COLS: u16 = 240;
const ROWS: u16 = 240;
type Buffer: AsMut<[u16]> + NewZeroed;
fn configure(
&self,
iface: &mut impl WriteOnlyDataCommand,
delay: &mut impl DelayNs,
) -> Result<(), DisplayError>;
}
#[derive(Debug, Copy, Clone)]
pub struct DisplayResolution240x240;
impl DisplayDefinition for DisplayResolution240x240 {
const WIDTH: u16 = 240;
const HEIGHT: u16 = 240;
type Buffer = [u16; Self::WIDTH as usize * Self::HEIGHT as usize];
fn configure(
&self,
iface: &mut impl WriteOnlyDataCommand,
delay: &mut impl DelayNs,
) -> Result<(), DisplayError> {
Command::InnerRegisterEnable1.send(iface)?;
Command::InnerRegisterEnable2.send(iface)?;
Command::DispalyFunctionControl(GSMode::G1toG32, SSMode::S1toS360, 0, 0).send(iface)?;
Command::MemoryAccessControl(
Logical::Off,
Logical::Off,
Logical::Off,
Logical::On,
Logical::On,
Logical::Off,
)
.send(iface)?;
Command::PixelFormatSet(Dbi::Pixel16bits, Dpi::Pixel16bits).send(iface)?;
Command::Vreg1aVoltageControl(0x13).send(iface)?;
Command::Vreg1bVoltageControl(0x13).send(iface)?;
Command::Vreg2aVoltageControl(0x22).send(iface)?;
Command::SetGamma1(Gamma1 {
dig2j0_n: 0b1,
vr1_n: 0b00_0101,
dig2j1_n: 0b0,
vr2_n: 0b00_1001,
vr4_n: 0b1000,
vr6_n: 0b1000,
vr0_n: 0b10,
vr13_n: 0b0110,
vr20_n: 0b10_1010,
})
.send(iface)?;
Command::SetGamma2(Gamma2 {
vr43_n: 0b100_0011,
vr27_n: 0b11,
vr57_n: 0b1_0000,
vr36_n: 0b11,
vr59_n: 0b1_0010,
vr61_n: 0b11_0110,
vr62_n: 0b11_0111,
vr50_n: 0b110,
vr63_n: 0b1111,
})
.send(iface)?;
Command::SetGamma3(Gamma3 {
dig2j0_p: 0b1,
vr1_p: 0b00_0101,
dig2j1_p: 0b0,
vr2_p: 0b00_1001,
vr4_p: 0b1000,
vr6_p: 0b1000,
vr0_p: 0b10,
vr13_p: 0b0110,
vr20_p: 0b10_1010,
})
.send(iface)?;
Command::SetGamma4(Gamma4 {
vr43_p: 0b100_0011,
vr27_p: 0b11,
vr57_p: 0b1_0000,
vr36_p: 0b11,
vr59_p: 0b1_0010,
vr61_p: 0b11_0110,
vr62_p: 0b11_0111,
vr50_p: 0b110,
vr63_p: 0b1111,
})
.send(iface)?;
Command::FrameRate(DINVMode::Inversion8Dot).send(iface)?;
Command::DisplayInversion(Logical::On).send(iface)?;
Command::SetUndocumented066h.send(iface)?;
Command::SetUndocumented067h.send(iface)?;
Command::SetUndocumented074h.send(iface)?;
Command::SetUndocumented098h.send(iface)?;
Command::TearingEffectLine(Logical::On).send(iface)?;
Command::DisplayInversion(Logical::On).send(iface)?;
Command::SleepMode(Logical::Off).send(iface)?;
delay.delay_ms(120);
Ok(())
}
}
pub trait NewZeroed {
fn new_zeroed() -> Self;
}
impl<const N: usize> NewZeroed for [u16; N] {
fn new_zeroed() -> Self {
[0u16; N]
}
}