use crate::{command::WriteCommand, instr::Instr};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct GateLineSetting {
gl: u8,
}
impl GateLineSetting {
pub const fn new(lines: u16) -> Self {
assert!(lines != 0, "lines must be not zero");
assert!(lines.is_multiple_of(4), "lines must be %4");
assert!(lines / 4 < 128, "lines out of range");
Self {
gl: (lines / 4) as u8,
}
}
}
impl WriteCommand for GateLineSetting {
const OPCODE: Instr = Instr::GATESET;
type Params = [u8; 1];
fn params(&self) -> Self::Params {
[self.gl]
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct FirstGateSetting {
fst: u16,
}
impl FirstGateSetting {
pub const DEFAULT: Self = Self { fst: 0 };
pub const fn new(fst: u16) -> Self {
assert!(fst >> 9 == 0, "FST out of range");
Self { fst }
}
}
impl Default for FirstGateSetting {
fn default() -> Self {
Self::DEFAULT
}
}
impl WriteCommand for FirstGateSetting {
const OPCODE: Instr = Instr::FSTCOM;
type Params = [u8; 2];
fn params(&self) -> Self::Params {
[(self.fst >> 8) as u8, self.fst as u8]
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct FrameRateControl {
hfra: HpmFrameRate,
lfra: LpmFrameRate,
}
impl FrameRateControl {
pub const DEFAULT: Self = Self {
hfra: HpmFrameRate::Full,
lfra: LpmFrameRate::OneHz,
};
#[must_use]
pub const fn with_hpm_frame_rate(mut self, p: HpmFrameRate) -> Self {
self.hfra = p;
self
}
#[must_use]
pub const fn with_lpm_frame_rate(mut self, p: LpmFrameRate) -> Self {
self.lfra = p;
self
}
const fn bytes(&self) -> [u8; 1] {
[(self.hfra as u8) << 4 | (self.lfra as u8)]
}
}
impl Default for FrameRateControl {
fn default() -> Self {
Self::DEFAULT
}
}
impl WriteCommand for FrameRateControl {
const OPCODE: Instr = Instr::FRCTRL;
type Params = [u8; 1];
fn params(&self) -> Self::Params {
self.bytes()
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum HpmFrameRate {
Half = 0,
Full = 1,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum LpmFrameRate {
QuarterHz = 0,
HalfHz = 1,
OneHz = 2,
TwoHz = 3,
FourHz = 4,
EightHz = 5,
}
const _: () = assert!(matches!(FrameRateControl::DEFAULT.bytes(), [0x12]));
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct UpdatePeriodGateEqControlInHpm {
geqen: GateEqEnable,
gpchpu: [GateEqVoltage; 16],
}
impl UpdatePeriodGateEqControlInHpm {
pub const DEFAULT: Self = Self {
geqen: GateEqEnable::Enable,
gpchpu: [
GateEqVoltage::Floating,
GateEqVoltage::NaVdd,
GateEqVoltage::Gnd,
GateEqVoltage::AVdd,
GateEqVoltage::Vgh,
GateEqVoltage::Vgh,
GateEqVoltage::Vgh,
GateEqVoltage::Vgh,
GateEqVoltage::Vgh,
GateEqVoltage::Vgh,
GateEqVoltage::Vgh,
GateEqVoltage::Vgh,
GateEqVoltage::Vgh,
GateEqVoltage::AVdd,
GateEqVoltage::Gnd,
GateEqVoltage::NaVdd,
],
};
#[must_use]
pub const fn with_gate_eq_enable(mut self, v: GateEqEnable) -> Self {
self.geqen = v;
self
}
#[must_use]
pub const fn with_gate_waveform(mut self, v: [GateEqVoltage; 16]) -> Self {
self.gpchpu = v;
self
}
const fn bytes(&self) -> [u8; 10] {
[
0xE5 & !(1 << 6) | (self.geqen as u8) << 6,
0xF6,
(self.gpchpu[0] as u8) << 4 | (self.gpchpu[1] as u8),
(self.gpchpu[2] as u8) << 4 | (self.gpchpu[3] as u8),
(self.gpchpu[4] as u8) << 4 | (self.gpchpu[5] as u8),
(self.gpchpu[6] as u8) << 4 | (self.gpchpu[7] as u8),
(self.gpchpu[8] as u8) << 4 | (self.gpchpu[9] as u8),
(self.gpchpu[10] as u8) << 4 | (self.gpchpu[11] as u8),
(self.gpchpu[12] as u8) << 4 | (self.gpchpu[13] as u8),
(self.gpchpu[14] as u8) << 4 | (self.gpchpu[15] as u8),
]
}
}
impl Default for UpdatePeriodGateEqControlInHpm {
fn default() -> Self {
Self::DEFAULT
}
}
impl WriteCommand for UpdatePeriodGateEqControlInHpm {
const OPCODE: Instr = Instr::GTUPEQH;
type Params = [u8; 10];
fn params(&self) -> Self::Params {
self.bytes()
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum GateEqEnable {
Disable = 0,
Enable = 1,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum GateEqVoltage {
Floating = 0b000,
Vgl = 0b001,
Gnd = 0b100,
NaVdd = 0b101,
AVdd = 0b110,
Vgh = 0b111,
}
const _: () = assert!(
matches!(
UpdatePeriodGateEqControlInHpm::DEFAULT.bytes(),
[0xE5, 0xF6, 0x05, 0x46, 0x77, 0x77, 0x77, 0x77, 0x76, 0x45]
),
"GTUPEQH DEFAULT must match datasheet's default"
);
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct UpdatePeriodGateEqControlInLpm {
gpclpu: [GateEqVoltage; 16],
}
impl UpdatePeriodGateEqControlInLpm {
pub const DEFAULT: Self = Self {
gpclpu: [
GateEqVoltage::Floating,
GateEqVoltage::NaVdd,
GateEqVoltage::Gnd,
GateEqVoltage::AVdd,
GateEqVoltage::Vgh,
GateEqVoltage::Vgh,
GateEqVoltage::Vgh,
GateEqVoltage::Vgh,
GateEqVoltage::Vgh,
GateEqVoltage::Vgh,
GateEqVoltage::Vgh,
GateEqVoltage::Vgh,
GateEqVoltage::Vgh,
GateEqVoltage::AVdd,
GateEqVoltage::Gnd,
GateEqVoltage::NaVdd,
],
};
#[must_use]
pub const fn with_gate_waveform(mut self, v: [GateEqVoltage; 16]) -> Self {
self.gpclpu = v;
self
}
const fn bytes(&self) -> [u8; 8] {
[
(self.gpclpu[0] as u8) << 4 | (self.gpclpu[1] as u8),
(self.gpclpu[2] as u8) << 4 | (self.gpclpu[3] as u8),
(self.gpclpu[4] as u8) << 4 | (self.gpclpu[5] as u8),
(self.gpclpu[6] as u8) << 4 | (self.gpclpu[7] as u8),
(self.gpclpu[8] as u8) << 4 | (self.gpclpu[9] as u8),
(self.gpclpu[10] as u8) << 4 | (self.gpclpu[11] as u8),
(self.gpclpu[12] as u8) << 4 | (self.gpclpu[13] as u8),
(self.gpclpu[14] as u8) << 4 | (self.gpclpu[15] as u8),
]
}
}
impl Default for UpdatePeriodGateEqControlInLpm {
fn default() -> Self {
Self::DEFAULT
}
}
impl WriteCommand for UpdatePeriodGateEqControlInLpm {
const OPCODE: Instr = Instr::GTUPEQL;
type Params = [u8; 8];
fn params(&self) -> Self::Params {
self.bytes()
}
}
const _: () = assert!(
matches!(
UpdatePeriodGateEqControlInLpm::DEFAULT.bytes(),
[0x05, 0x46, 0x77, 0x77, 0x77, 0x77, 0x76, 0x45]
),
"GTUPEQL DEFAULT must match datasheet's default"
);
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct SourceEqEnable {
soueq: SourceEq,
}
impl SourceEqEnable {
pub const DEFAULT: Self = Self {
soueq: SourceEq::Enable,
};
#[must_use]
pub const fn with_source_eq(mut self, v: SourceEq) -> Self {
self.soueq = v;
self
}
const fn bytes(&self) -> [u8; 1] {
[0x13 & !(1 << 4) | (self.soueq as u8) << 4]
}
}
impl Default for SourceEqEnable {
fn default() -> Self {
Self::DEFAULT
}
}
impl WriteCommand for SourceEqEnable {
const OPCODE: Instr = Instr::SOUEQ;
type Params = [u8; 1];
fn params(&self) -> Self::Params {
self.bytes()
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum SourceEq {
Disable = 0,
Enable = 1,
}
const _: () = assert!(matches!(SourceEqEnable::DEFAULT.bytes(), [0x13]));
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct PanelSetting {
dotinv: ColumnDotInversion,
dpscn: GateScanMode,
lay: PanelLayoutSelect,
}
impl PanelSetting {
pub const DEFAULT: Self = Self {
dotinv: ColumnDotInversion::ColumnInversion,
dpscn: GateScanMode::FrameInterval,
lay: PanelLayoutSelect::NonInterlace,
};
#[must_use]
pub const fn with_column_dot_inversion(mut self, v: ColumnDotInversion) -> Self {
self.dotinv = v;
self
}
#[must_use]
pub const fn with_gate_scan_mode(mut self, v: GateScanMode) -> Self {
self.dpscn = v;
self
}
#[must_use]
pub const fn with_panel_layout(mut self, v: PanelLayoutSelect) -> Self {
self.lay = v;
self
}
const fn bytes(&self) -> [u8; 1] {
[(self.dotinv as u8) << 5 | (self.dpscn as u8) << 2 | self.lay as u8]
}
}
impl Default for PanelSetting {
fn default() -> Self {
Self::DEFAULT
}
}
impl WriteCommand for PanelSetting {
const OPCODE: Instr = Instr::PNLSET;
type Params = [u8; 1];
fn params(&self) -> Self::Params {
self.bytes()
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ColumnDotInversion {
ColumnInversion = 0,
OneDotInversion = 1,
TwoDotInversion = 2,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum GateScanMode {
TwoLineInterval = 0,
OneLineInterval = 1,
FrameInterval = 2,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum PanelLayoutSelect {
TwoLineInterlace = 0,
OneLineInterlace = 1,
NonInterlace = 2,
}
const _: () = assert!(matches!(PanelSetting::DEFAULT.bytes(), [0x0A]));
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct GammaModeSetting {
gama: GammaMode,
}
impl GammaModeSetting {
pub const DEFAULT: Self = Self {
gama: GammaMode::Mono,
};
pub const fn new(gama: GammaMode) -> Self {
Self { gama }
}
const fn bytes(&self) -> [u8; 1] {
[(self.gama as u8) << 5]
}
}
impl Default for GammaModeSetting {
fn default() -> Self {
Self::DEFAULT
}
}
impl WriteCommand for GammaModeSetting {
const OPCODE: Instr = Instr::GAMAMS;
type Params = [u8; 1];
fn params(&self) -> Self::Params {
self.bytes()
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum GammaMode {
FourGS = 0,
Mono = 1,
}
const _: () = assert!(matches!(GammaModeSetting::DEFAULT.bytes(), [0x20]));
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct EnableClearRam {
clr: ClearRam,
}
impl EnableClearRam {
pub const fn new(clr: ClearRam) -> Self {
Self { clr }
}
const fn bytes(&self) -> [u8; 1] {
[0x4F & !(1 << 7) | (self.clr as u8) << 7]
}
}
impl WriteCommand for EnableClearRam {
const OPCODE: Instr = Instr::CLRAM;
type Params = [u8; 1];
fn params(&self) -> Self::Params {
self.bytes()
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ClearRam {
Enable = 0,
Disable = 1,
}
const _: () = assert!(matches!(
EnableClearRam::new(ClearRam::Enable).bytes(),
[0x4F]
));
const _: () = assert!(matches!(
EnableClearRam::new(ClearRam::Disable).bytes(),
[0xCF]
));
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct GateTimingControl {
p1: u8,
p2: u8,
p3: u8,
}
impl GateTimingControl {
pub const fn new(p1: u8, p2: u8, p3: u8) -> Self {
Self { p1, p2, p3 }
}
}
impl WriteCommand for GateTimingControl {
const OPCODE: Instr = Instr::GTCTRL;
type Params = [u8; 3];
fn params(&self) -> Self::Params {
[self.p1, self.p2, self.p3]
}
}