1use crate::{command::WriteCommand, instr::Instr};
2
3#[derive(Clone, Copy, Debug, PartialEq, Eq)]
7pub struct GateLineSetting {
8 gl: u8,
9}
10
11impl GateLineSetting {
12 pub const fn new(lines: u16) -> Self {
20 assert!(lines != 0, "lines must be not zero");
21 assert!(lines.is_multiple_of(4), "lines must be %4");
22 assert!(lines / 4 < 128, "lines out of range");
23 Self {
24 gl: (lines / 4) as u8,
25 }
26 }
27}
28
29impl WriteCommand for GateLineSetting {
30 const OPCODE: Instr = Instr::GATESET;
31 type Params = [u8; 1];
32 fn params(&self) -> Self::Params {
33 [self.gl]
34 }
35}
36
37#[derive(Clone, Copy, Debug, PartialEq, Eq)]
40pub struct FirstGateSetting {
41 fst: u16,
42}
43
44impl FirstGateSetting {
45 pub const DEFAULT: Self = Self { fst: 0 };
47
48 pub const fn new(fst: u16) -> Self {
54 assert!(fst >> 9 == 0, "FST out of range");
55 Self { fst }
56 }
57}
58
59impl Default for FirstGateSetting {
60 fn default() -> Self {
61 Self::DEFAULT
62 }
63}
64
65impl WriteCommand for FirstGateSetting {
66 const OPCODE: Instr = Instr::FSTCOM;
67 type Params = [u8; 2];
68 fn params(&self) -> Self::Params {
69 [(self.fst >> 8) as u8, self.fst as u8]
70 }
71}
72
73#[derive(Clone, Copy, Debug, PartialEq, Eq)]
75pub struct FrameRateControl {
76 hfra: HpmFrameRate,
77 lfra: LpmFrameRate,
78}
79
80impl FrameRateControl {
81 pub const DEFAULT: Self = Self {
83 hfra: HpmFrameRate::Full,
84 lfra: LpmFrameRate::OneHz,
85 };
86
87 #[must_use]
89 pub const fn with_hpm_frame_rate(mut self, p: HpmFrameRate) -> Self {
90 self.hfra = p;
91 self
92 }
93
94 #[must_use]
96 pub const fn with_lpm_frame_rate(mut self, p: LpmFrameRate) -> Self {
97 self.lfra = p;
98 self
99 }
100
101 const fn bytes(&self) -> [u8; 1] {
102 [(self.hfra as u8) << 4 | (self.lfra as u8)]
103 }
104}
105
106impl Default for FrameRateControl {
107 fn default() -> Self {
108 Self::DEFAULT
109 }
110}
111
112impl WriteCommand for FrameRateControl {
113 const OPCODE: Instr = Instr::FRCTRL;
114 type Params = [u8; 1];
115 fn params(&self) -> Self::Params {
116 self.bytes()
117 }
118}
119
120#[derive(Clone, Copy, Debug, PartialEq, Eq)]
123pub enum HpmFrameRate {
124 Half = 0,
126 Full = 1,
128}
129
130#[derive(Clone, Copy, Debug, PartialEq, Eq)]
132pub enum LpmFrameRate {
133 QuarterHz = 0,
135 HalfHz = 1,
137 OneHz = 2,
139 TwoHz = 3,
141 FourHz = 4,
143 EightHz = 5,
145}
146
147const _: () = assert!(matches!(FrameRateControl::DEFAULT.bytes(), [0x12]));
148
149#[derive(Clone, Copy, Debug, PartialEq, Eq)]
152pub struct UpdatePeriodGateEqControlInHpm {
153 geqen: GateEqEnable,
154 gpchpu: [GateEqVoltage; 16],
155}
156
157impl UpdatePeriodGateEqControlInHpm {
158 pub const DEFAULT: Self = Self {
160 geqen: GateEqEnable::Enable,
161 gpchpu: [
162 GateEqVoltage::Floating,
163 GateEqVoltage::NaVdd,
164 GateEqVoltage::Gnd,
165 GateEqVoltage::AVdd,
166 GateEqVoltage::Vgh,
167 GateEqVoltage::Vgh,
168 GateEqVoltage::Vgh,
169 GateEqVoltage::Vgh,
170 GateEqVoltage::Vgh,
171 GateEqVoltage::Vgh,
172 GateEqVoltage::Vgh,
173 GateEqVoltage::Vgh,
174 GateEqVoltage::Vgh,
175 GateEqVoltage::AVdd,
176 GateEqVoltage::Gnd,
177 GateEqVoltage::NaVdd,
178 ],
179 };
180
181 #[must_use]
183 pub const fn with_gate_eq_enable(mut self, v: GateEqEnable) -> Self {
184 self.geqen = v;
185 self
186 }
187
188 #[must_use]
190 pub const fn with_gate_waveform(mut self, v: [GateEqVoltage; 16]) -> Self {
191 self.gpchpu = v;
192 self
193 }
194
195 const fn bytes(&self) -> [u8; 10] {
196 [
197 0xE5 & !(1 << 6) | (self.geqen as u8) << 6,
198 0xF6,
199 (self.gpchpu[0] as u8) << 4 | (self.gpchpu[1] as u8),
200 (self.gpchpu[2] as u8) << 4 | (self.gpchpu[3] as u8),
201 (self.gpchpu[4] as u8) << 4 | (self.gpchpu[5] as u8),
202 (self.gpchpu[6] as u8) << 4 | (self.gpchpu[7] as u8),
203 (self.gpchpu[8] as u8) << 4 | (self.gpchpu[9] as u8),
204 (self.gpchpu[10] as u8) << 4 | (self.gpchpu[11] as u8),
205 (self.gpchpu[12] as u8) << 4 | (self.gpchpu[13] as u8),
206 (self.gpchpu[14] as u8) << 4 | (self.gpchpu[15] as u8),
207 ]
208 }
209}
210
211impl Default for UpdatePeriodGateEqControlInHpm {
212 fn default() -> Self {
213 Self::DEFAULT
214 }
215}
216
217impl WriteCommand for UpdatePeriodGateEqControlInHpm {
218 const OPCODE: Instr = Instr::GTUPEQH;
219 type Params = [u8; 10];
220 fn params(&self) -> Self::Params {
221 self.bytes()
222 }
223}
224
225#[derive(Clone, Copy, Debug, PartialEq, Eq)]
227pub enum GateEqEnable {
228 Disable = 0,
230 Enable = 1,
232}
233
234#[derive(Clone, Copy, Debug, PartialEq, Eq)]
236pub enum GateEqVoltage {
237 Floating = 0b000,
239 Vgl = 0b001,
241 Gnd = 0b100,
243 NaVdd = 0b101,
245 AVdd = 0b110,
247 Vgh = 0b111,
249}
250
251const _: () = assert!(
252 matches!(
253 UpdatePeriodGateEqControlInHpm::DEFAULT.bytes(),
254 [0xE5, 0xF6, 0x05, 0x46, 0x77, 0x77, 0x77, 0x77, 0x76, 0x45]
255 ),
256 "GTUPEQH DEFAULT must match datasheet's default"
257);
258
259#[derive(Clone, Copy, Debug, PartialEq, Eq)]
263pub struct UpdatePeriodGateEqControlInLpm {
264 gpclpu: [GateEqVoltage; 16],
265}
266
267impl UpdatePeriodGateEqControlInLpm {
268 pub const DEFAULT: Self = Self {
270 gpclpu: [
271 GateEqVoltage::Floating,
272 GateEqVoltage::NaVdd,
273 GateEqVoltage::Gnd,
274 GateEqVoltage::AVdd,
275 GateEqVoltage::Vgh,
276 GateEqVoltage::Vgh,
277 GateEqVoltage::Vgh,
278 GateEqVoltage::Vgh,
279 GateEqVoltage::Vgh,
280 GateEqVoltage::Vgh,
281 GateEqVoltage::Vgh,
282 GateEqVoltage::Vgh,
283 GateEqVoltage::Vgh,
284 GateEqVoltage::AVdd,
285 GateEqVoltage::Gnd,
286 GateEqVoltage::NaVdd,
287 ],
288 };
289
290 #[must_use]
292 pub const fn with_gate_waveform(mut self, v: [GateEqVoltage; 16]) -> Self {
293 self.gpclpu = v;
294 self
295 }
296
297 const fn bytes(&self) -> [u8; 8] {
298 [
299 (self.gpclpu[0] as u8) << 4 | (self.gpclpu[1] as u8),
300 (self.gpclpu[2] as u8) << 4 | (self.gpclpu[3] as u8),
301 (self.gpclpu[4] as u8) << 4 | (self.gpclpu[5] as u8),
302 (self.gpclpu[6] as u8) << 4 | (self.gpclpu[7] as u8),
303 (self.gpclpu[8] as u8) << 4 | (self.gpclpu[9] as u8),
304 (self.gpclpu[10] as u8) << 4 | (self.gpclpu[11] as u8),
305 (self.gpclpu[12] as u8) << 4 | (self.gpclpu[13] as u8),
306 (self.gpclpu[14] as u8) << 4 | (self.gpclpu[15] as u8),
307 ]
308 }
309}
310
311impl Default for UpdatePeriodGateEqControlInLpm {
312 fn default() -> Self {
313 Self::DEFAULT
314 }
315}
316
317impl WriteCommand for UpdatePeriodGateEqControlInLpm {
318 const OPCODE: Instr = Instr::GTUPEQL;
319 type Params = [u8; 8];
320 fn params(&self) -> Self::Params {
321 self.bytes()
322 }
323}
324
325const _: () = assert!(
326 matches!(
327 UpdatePeriodGateEqControlInLpm::DEFAULT.bytes(),
328 [0x05, 0x46, 0x77, 0x77, 0x77, 0x77, 0x76, 0x45]
329 ),
330 "GTUPEQL DEFAULT must match datasheet's default"
331);
332
333#[derive(Clone, Copy, Debug, PartialEq, Eq)]
335pub struct SourceEqEnable {
336 soueq: SourceEq,
337}
338
339impl SourceEqEnable {
340 pub const DEFAULT: Self = Self {
342 soueq: SourceEq::Enable,
343 };
344
345 #[must_use]
347 pub const fn with_source_eq(mut self, v: SourceEq) -> Self {
348 self.soueq = v;
349 self
350 }
351
352 const fn bytes(&self) -> [u8; 1] {
353 [0x13 & !(1 << 4) | (self.soueq as u8) << 4]
354 }
355}
356
357impl Default for SourceEqEnable {
358 fn default() -> Self {
359 Self::DEFAULT
360 }
361}
362
363impl WriteCommand for SourceEqEnable {
364 const OPCODE: Instr = Instr::SOUEQ;
365 type Params = [u8; 1];
366 fn params(&self) -> Self::Params {
367 self.bytes()
368 }
369}
370
371#[derive(Clone, Copy, Debug, PartialEq, Eq)]
373pub enum SourceEq {
374 Disable = 0,
376 Enable = 1,
378}
379
380const _: () = assert!(matches!(SourceEqEnable::DEFAULT.bytes(), [0x13]));
381
382#[derive(Clone, Copy, Debug, PartialEq, Eq)]
384pub struct PanelSetting {
385 dotinv: ColumnDotInversion,
386 dpscn: GateScanMode,
387 lay: PanelLayoutSelect,
388}
389
390impl PanelSetting {
391 pub const DEFAULT: Self = Self {
394 dotinv: ColumnDotInversion::ColumnInversion,
395 dpscn: GateScanMode::FrameInterval,
396 lay: PanelLayoutSelect::NonInterlace,
397 };
398
399 #[must_use]
401 pub const fn with_column_dot_inversion(mut self, v: ColumnDotInversion) -> Self {
402 self.dotinv = v;
403 self
404 }
405
406 #[must_use]
408 pub const fn with_gate_scan_mode(mut self, v: GateScanMode) -> Self {
409 self.dpscn = v;
410 self
411 }
412
413 #[must_use]
415 pub const fn with_panel_layout(mut self, v: PanelLayoutSelect) -> Self {
416 self.lay = v;
417 self
418 }
419
420 const fn bytes(&self) -> [u8; 1] {
421 [(self.dotinv as u8) << 5 | (self.dpscn as u8) << 2 | self.lay as u8]
422 }
423}
424
425impl Default for PanelSetting {
426 fn default() -> Self {
427 Self::DEFAULT
428 }
429}
430
431impl WriteCommand for PanelSetting {
432 const OPCODE: Instr = Instr::PNLSET;
433 type Params = [u8; 1];
434 fn params(&self) -> Self::Params {
435 self.bytes()
436 }
437}
438
439#[derive(Clone, Copy, Debug, PartialEq, Eq)]
441pub enum ColumnDotInversion {
442 ColumnInversion = 0,
444 OneDotInversion = 1,
446 TwoDotInversion = 2,
448}
449
450#[derive(Clone, Copy, Debug, PartialEq, Eq)]
452pub enum GateScanMode {
453 TwoLineInterval = 0,
455 OneLineInterval = 1,
457 FrameInterval = 2,
459}
460
461#[derive(Clone, Copy, Debug, PartialEq, Eq)]
463pub enum PanelLayoutSelect {
464 TwoLineInterlace = 0,
466 OneLineInterlace = 1,
468 NonInterlace = 2,
470}
471
472const _: () = assert!(matches!(PanelSetting::DEFAULT.bytes(), [0x0A]));
473
474#[derive(Clone, Copy, Debug, PartialEq, Eq)]
476pub struct GammaModeSetting {
477 gama: GammaMode,
478}
479
480impl GammaModeSetting {
481 pub const DEFAULT: Self = Self {
483 gama: GammaMode::Mono,
484 };
485
486 pub const fn new(gama: GammaMode) -> Self {
488 Self { gama }
489 }
490
491 const fn bytes(&self) -> [u8; 1] {
492 [(self.gama as u8) << 5]
493 }
494}
495
496impl Default for GammaModeSetting {
497 fn default() -> Self {
498 Self::DEFAULT
499 }
500}
501
502impl WriteCommand for GammaModeSetting {
503 const OPCODE: Instr = Instr::GAMAMS;
504 type Params = [u8; 1];
505 fn params(&self) -> Self::Params {
506 self.bytes()
507 }
508}
509
510#[derive(Clone, Copy, Debug, PartialEq, Eq)]
512pub enum GammaMode {
513 FourGS = 0,
515 Mono = 1,
517}
518
519const _: () = assert!(matches!(GammaModeSetting::DEFAULT.bytes(), [0x20]));
520
521#[derive(Clone, Copy, Debug, PartialEq, Eq)]
523pub struct EnableClearRam {
524 clr: ClearRam,
525}
526
527impl EnableClearRam {
528 pub const fn new(clr: ClearRam) -> Self {
531 Self { clr }
532 }
533
534 const fn bytes(&self) -> [u8; 1] {
535 [0x4F & !(1 << 7) | (self.clr as u8) << 7]
536 }
537}
538
539impl WriteCommand for EnableClearRam {
540 const OPCODE: Instr = Instr::CLRAM;
541 type Params = [u8; 1];
542 fn params(&self) -> Self::Params {
543 self.bytes()
544 }
545}
546
547#[derive(Clone, Copy, Debug, PartialEq, Eq)]
549pub enum ClearRam {
550 Enable = 0,
552 Disable = 1,
554}
555
556const _: () = assert!(matches!(
557 EnableClearRam::new(ClearRam::Enable).bytes(),
558 [0x4F]
559));
560const _: () = assert!(matches!(
561 EnableClearRam::new(ClearRam::Disable).bytes(),
562 [0xCF]
563));
564
565#[derive(Clone, Copy, Debug, PartialEq, Eq)]
568pub struct GateTimingControl {
569 p1: u8,
570 p2: u8,
571 p3: u8,
572}
573
574impl GateTimingControl {
575 pub const fn new(p1: u8, p2: u8, p3: u8) -> Self {
577 Self { p1, p2, p3 }
578 }
579}
580
581impl WriteCommand for GateTimingControl {
582 const OPCODE: Instr = Instr::GTCTRL;
583 type Params = [u8; 3];
584 fn params(&self) -> Self::Params {
585 [self.p1, self.p2, self.p3]
586 }
587}