use crate::{
command::{WriteCommand, no_param_command},
instr::Instr,
};
no_param_command!(
Nop => NOP
);
no_param_command!(
SoftReset => SWRESET
);
no_param_command!(
SleepIn => SLPIN
);
no_param_command!(
SleepOut => SLPOUT
);
no_param_command!(
PartialOn => PTLON
);
no_param_command!(
PartialOff => PTLOFF
);
no_param_command!(
DisplayInversionOff => INVOFF
);
no_param_command!(
DisplayInversionOn => INVON
);
no_param_command!(
DisplayOff => DISPOFF
);
no_param_command!(
DisplayOn => DISPON
);
no_param_command!(
TearingEffectLineOff => TEOFF
);
no_param_command!(
HighPowerModeOn => HPM
);
no_param_command!(
LowPowerModeOn => LPM
);
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct ColumnAddressSet {
xs: u8,
xe: u8,
}
impl ColumnAddressSet {
pub const DEFAULT: Self = Self { xs: 0, xe: 0 };
pub const fn new(xs: u8, xe: u8) -> Self {
assert!(xs <= xe, "X start must be less or equal than X end");
assert!(xe < 64, "X end out of range");
Self { xs, xe }
}
}
impl Default for ColumnAddressSet {
fn default() -> Self {
Self::DEFAULT
}
}
impl WriteCommand for ColumnAddressSet {
const OPCODE: Instr = Instr::CASET;
type Params = [u8; 2];
fn params(&self) -> Self::Params {
[self.xs, self.xe]
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct RowAddressSet {
ys: u8,
ye: u8,
}
impl RowAddressSet {
pub const DEFAULT: Self = Self { ys: 0, ye: 0 };
pub const fn new(ys: u8, ye: u8) -> Self {
assert!(ys <= ye, "Y start must be less or equal than Y end");
Self { ys, ye }
}
}
impl Default for RowAddressSet {
fn default() -> Self {
Self::DEFAULT
}
}
impl WriteCommand for RowAddressSet {
const OPCODE: Instr = Instr::RASET;
type Params = [u8; 2];
fn params(&self) -> Self::Params {
[self.ys, self.ye]
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct TearingEffectLineOn {
tem: TearingEffectMode,
}
impl TearingEffectLineOn {
pub const DEFAULT: Self = Self {
tem: TearingEffectMode::VBlanking,
};
pub const fn new(tem: TearingEffectMode) -> Self {
Self { tem }
}
const fn bytes(&self) -> [u8; 1] {
[self.tem as u8]
}
}
impl Default for TearingEffectLineOn {
fn default() -> Self {
Self::DEFAULT
}
}
impl WriteCommand for TearingEffectLineOn {
const OPCODE: Instr = Instr::TEON;
type Params = [u8; 1];
fn params(&self) -> Self::Params {
self.bytes()
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum TearingEffectMode {
VBlanking = 0,
Both = 1,
}
const _: () = assert!(matches!(TearingEffectLineOn::DEFAULT.bytes(), [0x00]));
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct MemoryDataAccessControl {
my: PageAddressOrder,
mx: ColumnAddressOrder,
mv: PageOrColumnOrder,
gs: GateScanOrder,
}
impl MemoryDataAccessControl {
pub const DEFAULT: Self = Self {
my: PageAddressOrder::TopToBottom,
mx: ColumnAddressOrder::LeftToRight,
mv: PageOrColumnOrder::ColumnDirectionMode,
gs: GateScanOrder::TopToBottom,
};
#[must_use]
pub const fn with_page_order(mut self, v: PageAddressOrder) -> Self {
self.my = v;
self
}
#[must_use]
pub const fn with_column_order(mut self, v: ColumnAddressOrder) -> Self {
self.mx = v;
self
}
#[must_use]
pub const fn with_page_or_column_order(mut self, v: PageOrColumnOrder) -> Self {
self.mv = v;
self
}
#[must_use]
pub const fn with_gate_scan_order(mut self, v: GateScanOrder) -> Self {
self.gs = v;
self
}
}
impl Default for MemoryDataAccessControl {
fn default() -> Self {
Self::DEFAULT
}
}
impl WriteCommand for MemoryDataAccessControl {
const OPCODE: Instr = Instr::MADCTL;
type Params = [u8; 1];
fn params(&self) -> Self::Params {
let byte = (self.my as u8) << 7
| (self.mx as u8) << 6
| (self.mv as u8) << 5
| (self.mx as u8) << 3
| (self.gs as u8) << 2;
[byte]
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum PageAddressOrder {
TopToBottom = 0,
BottomToTop = 1,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ColumnAddressOrder {
LeftToRight = 0,
RightToLeft = 1,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum PageOrColumnOrder {
ColumnDirectionMode = 0,
PageDirectionMode = 1,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum GateScanOrder {
TopToBottom = 0,
BottomToTop = 1,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct VerticalScrollStartAddressOfRam {
vsp: u16, }
impl VerticalScrollStartAddressOfRam {
pub const DEFAULT: Self = Self { vsp: 0 };
pub const fn new(vsp: u16) -> Self {
assert!(vsp >> 9 == 0, "VSP out of range");
Self { vsp }
}
}
impl Default for VerticalScrollStartAddressOfRam {
fn default() -> Self {
Self::DEFAULT
}
}
impl WriteCommand for VerticalScrollStartAddressOfRam {
const OPCODE: Instr = Instr::VSCSAD;
type Params = [u8; 2];
fn params(&self) -> Self::Params {
[(self.vsp >> 8) as u8, self.vsp as u8]
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct DataFormatSelect {
xde: DataUpDownSwitch,
bps: BytesPerPixelSelect,
}
impl DataFormatSelect {
pub const DEFAULT: Self = Self {
xde: DataUpDownSwitch::On,
bps: BytesPerPixelSelect::FourWriteOps,
};
#[must_use]
pub const fn with_data_up_down_switch(mut self, p: DataUpDownSwitch) -> Self {
self.xde = p;
self
}
#[must_use]
pub const fn with_bytes_per_pixel(mut self, p: BytesPerPixelSelect) -> Self {
self.bps = p;
self
}
const fn bytes(&self) -> [u8; 1] {
[(self.xde as u8) << 4 | self.bps as u8]
}
}
impl Default for DataFormatSelect {
fn default() -> Self {
Self::DEFAULT
}
}
impl WriteCommand for DataFormatSelect {
const OPCODE: Instr = Instr::DTFORM;
type Params = [u8; 1];
fn params(&self) -> Self::Params {
self.bytes()
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum DataUpDownSwitch {
On = 0,
Off = 1,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum BytesPerPixelSelect {
FourWriteOps = 0,
ThreeWriteOps = 1,
}
const _: () = assert!(matches!(DataFormatSelect::DEFAULT.bytes(), [0x00]));
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct SetTearScanline {
n: u16, }
impl SetTearScanline {
pub const DEFAULT: Self = Self { n: 0 };
pub const fn new(n: u16) -> Self {
assert!(n >> 9 == 0, "N out of range");
Self { n }
}
}
impl Default for SetTearScanline {
fn default() -> Self {
Self::DEFAULT
}
}
impl WriteCommand for SetTearScanline {
const OPCODE: Instr = Instr::TESCAN;
type Params = [u8; 2];
fn params(&self) -> Self::Params {
[(self.n >> 8) as u8, self.n as u8]
}
}