gc9a01/command.rs
1#![allow(clippy::doc_markdown)]
2#![allow(clippy::match_same_arms)]
3//! Commands
4
5use display_interface::{DataFormat::U8, DisplayError, WriteOnlyDataCommand};
6
7/// GC9A01 Commands
8#[derive(Debug, Copy, Clone)]
9pub enum Command {
10 /// Set Sleep mode (10h/11h)
11 ///
12 /// This command turns on/off sleep mode.
13 ///
14 /// ## Description
15 ///
16 /// This command causes the LCD module to enter the minimum power consumption mode.
17 /// In this mode e.g. the DC/DC converter is stopped, Internal oscillator is stopped, and panel scanning is stopped
18 ///
19 /// ## Restriction
20 ///
21 /// ## On Logical On (10h)
22 ///
23 /// It will be necessary to wait 5msec before sending next to command,
24 /// this is to allow time for the supply voltages and clock circuits to
25 /// stabilize.
26 ///
27 /// ## On Logical Off (11h)
28 ///
29 /// It will be necessary to wait 120msec after sending Sleep Out command (when in
30 /// Sleep In Mode) before Sleep In command can be sent.
31 ///
32 SleepMode(Logical),
33
34 /// Set Partial mode (12h)
35 ///
36 /// This command turns on Partial mode.
37 ///
38 /// ## Description
39 ///
40 /// This command turns on partial mode. The Partial mode window is described by the Partial
41 /// Area command (30h). To leave Partial mode, the Normal Display Mode On command (13h) should be written.
42 ///
43 /// ## Restriction
44 ///
45 /// This command has no effect when Partial mode is active.
46 ///
47 PartialMode,
48
49 /// Set Normal Display mode (13h)
50 ///
51 /// This command turns on Normal Display mode.
52 ///
53 /// ## Description
54 ///
55 /// Normal display mode on means Partial mode off.
56 /// Exit from NORON by the Partial mode On command (12h)
57 ///
58 /// ## Restriction
59 ///
60 /// This command has no effect when Normal Display mode is active.
61 ///
62 NormalDisplayMode,
63
64 /// Set Display Inversion (20h/21h)
65 ///
66 /// This command turns on/off Display Inversion
67 ///
68 /// ## Description
69 ///
70 /// This command is used to recover from display inversion mode.
71 /// This command makes no change of the content of frame memory.
72 /// This command doesn't change any other status.
73 ///
74 /// ## Restriction
75 ///
76 /// This command has no effect when module already is inversion OFF mode.
77 ///
78 DisplayInversion(Logical),
79
80 /// Set Display State (28h/29h)
81 ///
82 /// This command turns on/off Display
83 ///
84 /// ## Description
85 ///
86 /// In this mode, the output from Frame Memory is disabled and blank page inserted.
87 ///
88 /// ## Restriction
89 ///
90 /// This command has no effect when module is already in display OFF mode.
91 ///
92 DisplayState(Logical),
93
94 /// Set Column Address (start, end) (2Ah)
95 ///
96 /// ## Parameters
97 ///
98 /// * SC `.0` => Start Column
99 /// * EC `.1` => End Column
100 ///
101 /// This command is used to defined area of frame memory where MCU can access.
102 ///
103 /// ## Description
104 ///
105 /// This command makes no change on the other driver status.
106 /// The values of SC [15:0] and EC [15:0] are referred when RAMWR command comes.
107 /// Each value represents one column line in the frame memory.
108 ///
109 /// ## Restriction
110 ///
111 /// SC [15:0] always must be equal to or less than EC [15:0].
112 ///
113 /// __NOTE__: When SC [15:0] or EC [15:0] is greater than 013Fh (When MADCTL's B5 = 0)
114 /// or 00EFh (When MADCTL's B5 = 1), data of out of range will be ignored.
115 ///
116 ColumnAddressSet(u16, u16),
117
118 /// Set Row Address (start, end) (2Bh)
119 ///
120 /// ## Parameters
121 ///
122 /// * SP `.0` => Start Page/Row
123 /// * EP `.1` => End Page/Row
124 ///
125 /// This command is used to define area of frame memory where MCU can access.
126 ///
127 /// ## Description
128 ///
129 /// This command makes no change on the other driver status.
130 /// The values of SP [15:0] and EP [15:0] are referred when RAMWR command comes.
131 /// Each value represents one Page line in the Frame Memory
132 ///
133 /// ## Restriction
134 ///
135 /// SP [15:0] always must be equal to or less than EP [15:0]
136 ///
137 /// __NOTE__:When SP [15:0] or EP [15:0] is greater than 00EFh (When MADCTL’s B5 = 0)
138 /// or 013Fh (When MADCTL’s B5 = 1), data of out of range will be ignored.
139 ///
140 RowAddressSet(u16, u16),
141 // Partial Area (start, end) (30)
142 // TODO:>
143 // TODO: PartialArea(u16, u16),
144 //
145 /// Vertical Scrolling Definition (33h)
146 ///
147 /// ## Parameters
148 ///
149 /// * TFA `.0` => Top Fixed Area
150 /// * VSA `.1` => Vertical Scrolling Area
151 ///
152 /// This command is used to define area of frame memory where MCU can access.
153 ///
154 /// ## Description
155 ///
156 /// This command defines the Vertical Scrolling Area of the display.
157 ///
158 /// ## When MADCTL B4=0
159 ///
160 /// The 1st & 2nd parameter TFA [15...0] describes the Top Fixed Area (in No. of lines from
161 /// Top of the Frame Memory and Display).
162 /// The 3rd & 4th parameter VSA [15...0] describes the height of the Vertical Scrolling Area
163 /// (in No. of lines of the Frame Memory [not the display]
164 /// from the Vertical Scrolling Start Address).
165 /// The first line read from Frame Memory appears immediately after the bottom most line of the Top Fixed Area.
166 ///
167 /// ## When MADCTL B4=1
168 ///
169 /// The 1st & 2nd parameter TFA [15...0] describes the Top Fixed Area (in No. of lines from
170 /// Bottom of the Frame Memory and Display).
171 /// The 3rd & 4th parameter VSA [15...0] describes the height of the Vertical Scrolling Area
172 /// (in No. of lines of the Frame
173 /// Memory [not the display] from the Vertical Scrolling Start Address). The first line read
174 /// from Frame Memory appears
175 /// immediately after the top most line of the Top Fixed Area
176 ///
177 VertialScrollDef(u16, u16),
178
179 /// Tearing Effect Line OFF (35h)
180 /// Tearing Effect Line OFF (34h)
181 ///
182 /// This command turns on tearing effect line with a parameters.
183 ///
184 /// ## Parameters
185 ///
186 /// * M `.0` => Mode (Logical)
187 ///
188 /// ## Description
189 ///
190 /// This command is used to turn ON the Tearing Effect output signal from the TE signal line.
191 /// This output is not affected by changing MADCTL bit B4. The Tearing Effect Line On has one parameter which describes
192 /// the mode of the Tearing Effect Output Line.
193 ///
194 /// This command is used to turn OFF
195 /// (Active Low) the Tearing Effect output signal from the TE signal line.
196 ///
197 ///
198 /// ## Restriction
199 ///
200 /// This command has no effect when Tearing Effect output is already ON
201 ///
202 TearingEffectLine(Logical),
203
204 /// Memory Access Control (36h)
205 ///
206 /// This command defines read/write scanning direction of frame memory.
207 /// This command makes no change on the other driver status
208 /// ## Parameters
209 ///
210 /// * MY Row Address Order
211 /// * MX Column Address Order These 3 bits control MCU to memory write/read direction.
212 /// * MV Row / Column Exchange
213 /// * ML Vertical Refresh Order LCD vertical refresh direction control.
214 /// * BGR RGB-BGR Order
215 /// * Color selector switch control (0=RGB color filter panel, 1=BGR color filter panel)
216 /// * MH Horizontal Refresh ORDER LCD horizontal refreshing direction control.
217 ///
218 /// ## Description
219 ///
220 /// Note: When BGR bit is changed, the new setting is active immediately without update the content in
221 /// Frame Memory again.
222 ///
223 /// ## Restriction
224 ///
225 /// This command has no effect when Tearing Effect output is already ON
226 ///
227 MemoryAccessControl(Logical, Logical, Logical, Logical, Logical, Logical),
228
229 /// Vertical Scrolling Start Address (37h)
230 ///
231 /// ## Parameters
232 /// * VSP `.0` => Vertical Start Page
233 ///
234 /// ## Description
235 ///
236 /// This command is used together with Vertical Scrolling Definition (33h). These two commands
237 /// describe the scrolling area and the scrolling mode.
238 ///
239 /// The Vertical Scrolling Start Address command has one parameter
240 /// which describes the address of the line in the Frame Memory that will be written as the first line after
241 /// the last line of the Top Fixed Area (TFA) on the display.
242 ///
243 /// ## Restriction
244 ///
245 /// This command has no effect when Tearing Effect output is already ON.
246 ///
247 VerticalScrollStartAddresss(u16),
248
249 /// Set Idle Mode (38h/39h)
250 ///
251 /// This command turns on/off Idle Mode
252 ///
253 /// ## Parameters
254 /// * State `.0` => On/Off
255 ///
256 /// ## Description
257 ///
258 /// In the idle off mode, LCD can display maximum 262,144 colors.
259 ///
260 /// ## Restriction
261 ///
262 /// This command has no effect when module is already in idle same mode.
263 ///
264 IdleMode(Logical),
265
266 /// Pixel Format Set (3Ah) COLMOD
267 ///
268 /// ## Parameters
269 /// * DBI `.0` => MCU Interface Format
270 /// * DPI `.1` => RGB Interface Format
271 ///
272 /// ## Description
273 ///
274 /// This command sets the pixel format for the RGB image data used by the interface. DPI [2:0] is
275 /// the pixel format select of RGB interface and DBI [2:0] is the pixel format of MCU interface. If
276 /// a particular interface, either RGB interface or MCU interface, is not used then the
277 /// corresponding bits in the parameter are ignored. The pixel format is shown in the table below.
278 ///
279 /// ## Restriction
280 ///
281 /// This command has no effect when module is already in idle off mode.
282 PixelFormatSet(Dbi, Dpi),
283
284 /// Set Tear Scanline (44h)
285 ///
286 /// ## Parameters
287 /// * STS => Set Tear Scanline 0-239
288 ///
289 /// ## Description
290 ///
291 /// This command turns on the display Tearing Effect output signal on the TE signal line when the
292 /// display reaches line equal the value of STS[8:0].
293 ///
294 /// __NOTE__: that set_tear_scanline with STS is equivalent to set_tear_on with 8+GateN(N=1、2、3...240)
295 SetTearScanline(u16),
296
297 /// Write Display Brightness (51h)
298 ///
299 /// This command is used to adjust the brightness value of the display
300 ///
301 /// ## Parameters
302 ///
303 /// * DBV `.0` =>
304 ///
305 /// ## Description
306 ///
307 /// It should be checked what is the relationship between this written value and output brightness of the display.
308 /// This relationship between this written value and output brightness of the display. This relationship is defined on the display module specification.
309 /// In principle relationship is that 00h value means the lowest brightness and FFh value means the highest brightness.
310 ///
311 /// ## Math
312 ///
313 /// * DBV[7:0]/255 x period (affected by OSC frequency)
314 ///
315 /// For example: LEDPWM period = 3ms, and DBV[7:0] = ‘200DEC’. Then LEDPWM duty = 200 / 255=78.1%.
316 /// Correspond to the LEDPWM period = 3 ms, the high-level of LEDPWM (high effective) = 2.344ms, and the
317 /// low-level of LEDPWM = 0.656ms.
318 ///
319 DisplayBrightness(u8),
320
321 /// Write CTRL Display (53h)
322 ///
323 /// ## Parameters
324 ///
325 /// * BCTRL `.0` => Brightness Control Block On/Off
326 /// * DD `.1` => Display Dimming On/Off
327 /// * BL `.2` => Backlight On/Off
328 ///
329 /// ## Restriction
330 ///
331 /// The display module is sending 2nd parameter value on the data line if the MCU
332 /// wants to read more than one parameters
333 /// (=more than 2 RDX Cyle) on DBI
334 /// Only 2nd parameter is sent on DSI (The 1st parameter is not sent).
335 CtrlDisplay(Logical, Logical, Logical),
336
337 /// RGB Interface Signal Control (B0h)
338 ///
339 /// ## Parameters
340 ///
341 /// * EPL `.0` => DE polarity (“0”= High enable for RGB interface, “1”= Low enable for RGB interface)
342 /// * DP `.1` => DOTCLK polarity set (“0”= data fetched at the rising time, “1”= data fetched at the falling time)
343 /// * HSP `.2` => HSYNC polarity (“0”= Low level sync clock, “1”= High level sync clock)
344 /// * VSP `.3` => VSYNC polarity (“0”= Low level sync clock, “1”= High level sync clock)
345 /// * RCM `.4` => RGB interface selection (refer to the RGB interface section).
346 ///
347 RGBInterfaceSignalCtrl(DEPolarity, DOTClk, XSpl, XSpl, RCMMode),
348
349 /// Blanking Porch Control (B5h)
350 ///
351 /// ## Parameters
352 ///
353 /// * VFP `.0` => The line number of Vertical Front Porch
354 /// * VBP `.1` => The line number of Vertical Back Porch
355 /// * HBP `.2` => The line number of Horizontal Back Porch
356 ///
357 /// ## Description
358 ///
359 /// __NOTE__: The Third parameter must write,but it is not valid
360 ///
361 BlankingPorchControl(u8, u8, u8),
362
363 /// Display Function Control (B6h)
364 ///
365 /// ## Parameters
366 ///
367 /// * GS `.0` => Sets the direction of scan by the gate driver in the range determined by SCN [4:0]
368 /// * SS `.1` => Select the shift direction of outputs from the source driver.
369 /// * SM `.2` => Sets the gate driver pin arrangement in combination with the GS bit to select the optimal scan mode for the module
370 /// * NL `.3` => Sets the number of lines to drive the LCD at an interval of 8 lines.
371 ///
372 /// ## Restriction
373 ///
374 /// EXTC should be high to enable this command
375 ///
376 DispalyFunctionControl(GSMode, SSMode, u8, u8),
377
378 /// TE Control (BAh)
379 ///
380 /// ## Parameters
381 ///
382 /// * te_pol `.0` => [`TEPolarity`] is used to adjust the Tearing Effect output signal pulse polarity
383 /// * te_width `.1` => TODO
384 ///
385 /// ## Restriction
386 ///
387 /// __NOTE__: During Sleep In Mode with Tearing Effect Line On, Tearing Effect Output pin will be active Low
388 /// This command has no effect when Tearing Effect output is already ON
389 ///
390 TEControl(TEPolarity, u8),
391
392 /// Interface Control (F6h)
393 ///
394 /// ## Parameters
395 ///
396 /// * DM `.0` => TODO
397 /// * RM `.1` => TODO
398 /// * RIM `.2` => TODO
399 ///
400 /// ## Restriction
401 ///
402 /// EXTC should be high to enable this command
403 ///
404 Interface(DMMode, RMMode, RIMMode),
405
406 /// Power Criterion Control (C1h)
407 ///
408 /// ## Parameters
409 ///
410 /// * vcire `.0` => TODO
411 ///
412 PowerCriterioControl(VCIRe),
413
414 /// VCore Voltage Control (A7h)
415 ///
416 /// ## Parameters
417 ///
418 /// * vdd_ad `.0` => TODO
419 ///
420 VCoreVoltageControl(VddAd),
421
422 /// Vreg 1a Voltage Control (C3h)
423 ///
424 /// ## Parameters
425 ///
426 /// * vreg1_vbp_d `.0` => TODO
427 ///
428 /// ## Description
429 ///
430 /// Set the voltage level value to output the VREG1A and VREG1B OUT level, which is a
431 /// reference level for the grayscale voltage level.(Table is valid when vrh=0x28)
432 /// VREG1A=(vrh+vbp_d)*0.02+4
433 /// VREG1B=vbp_d*0.02+0.3
434 ///
435 Vreg1aVoltageControl(u8),
436
437 /// Vreg 1b Voltage Control (C4h)
438 ///
439 /// ## Parameters
440 ///
441 /// * vreg1_vbn_d `.0` => TODO
442 ///
443 /// ## Description
444 ///
445 /// Set the voltage level value to output the VREG2A OUT level, which is a reference level for
446 /// the grayscale voltage level(Table is valid when vrh=0x28)
447 /// VREG2A=(vbn_d-vrh)*0.02-3.4
448 /// VREG2B=vbn_d*0.02+0.3
449 ///
450 Vreg1bVoltageControl(u8),
451
452 /// Vreg 2a Voltage Control (C9h)
453 ///
454 /// ## Parameters
455 ///
456 /// * vrh `.0` => TODO
457 ///
458 /// ## Description
459 ///
460 /// Set the voltage level value to output the VREG1A OUT level, which is a reference level for
461 /// the grayscale voltage level. (Table is valid when vbp_d=0x3C and vbn_d=0x3C)
462 /// VREG1A=(vrh+vbp_d)*0.02+4
463 /// VREG2A=(vbn_d-vrh)*0.02-3.4
464 ///
465 Vreg2aVoltageControl(u8),
466
467 /// Frame Rate (E8h)
468 ///
469 /// ## Parameters
470 ///
471 /// * DINV `.0` => [`DINVMode`]
472 /// * (unused) RTN1 `.1` => TODO
473 /// * (undocumented) RTN2 `.2` => TODO (Misleading information)
474 ///
475 FrameRate(DINVMode),
476
477 /// SPI 2data Control (E9h)
478 ///
479 /// ## Parameters
480 ///
481 /// * 2data_en `.0` => [`Data2EN`]
482 /// * 2data_mdt `.1` => [`DataFormatMDT`]
483 ///
484 /// ## Restriction
485 ///
486 /// Inter command should be set high to enable this command
487 ///
488 Spi2dataControl(Data2EN, DataFormatMDT),
489
490 /// Charge Pump Frequent Control (ECh)
491 ///
492 /// ## Parameters
493 ///
494 /// * avdd_clk_ad `.0` => TODO / Undocumented
495 /// * avee_clk_ad `.1` => TODO / Undocumented
496 /// * vcl_clk_ad `.2` => TODO / Undocumented
497 /// * vgh_clk_ad `.3` => TODO / Undocumented
498 /// * vgl_clk_ad `.4` => TODO / Undocumented
499 ///
500 ChargePumpFrequentControl(u8, u8, u8, u8, u8),
501
502 /// Inner Register Enable 1 (FEh)
503 ///
504 /// ## Description
505 ///
506 /// This command is used for Inter_command controlling.
507 /// To set Inter_command high ,you should write Inter register enable 1 (FEh) and Inter register
508 /// enable 2 (EFh) continuously.
509 /// Once Inter_command is set high, only hardware or software reset can turn it to low.
510 ///
511 InnerRegisterEnable1,
512
513 /// Inner Register Enable 2 (EFh)
514 ///
515 /// ## Description
516 ///
517 /// This command is used for Inter_command controlling.
518 /// To set Inter_command high ,you should write Inter register enable 1 (FEh) and Inter register
519 /// enable 2 (EFh) continuously.
520 /// Once Inter_command is set high, only hardware or software reset can turn it to low.
521 ///
522 InnerRegisterEnable2,
523
524 /// Set GAMMA 1 (F0h)
525 ///
526 /// ## Parameters
527 ///
528 /// * Gamma1 `.0`
529 ///
530 /// ## Restriction
531 ///
532 /// Inter_command should be set high to enable this command
533 ///
534 SetGamma1(Gamma1),
535
536 /// Set GAMMA 2 (F1h)
537 ///
538 /// ## Parameters
539 ///
540 /// * Gamma2 `.0`
541 ///
542 /// ## Restriction
543 ///
544 /// Inter_command should be set high to enable this command
545 ///
546 SetGamma2(Gamma2),
547
548 /// Set GAMMA 3 (F2h)
549 ///
550 /// ## Parameters
551 ///
552 /// * Gamma3 `.0`
553 ///
554 /// ## Restriction
555 ///
556 /// Inter_command should be set high to enable this command
557 ///
558 SetGamma3(Gamma3),
559
560 /// Set GAMMA 4 (F3h)
561 ///
562 /// ## Parameters
563 ///
564 /// * Gamma4 `.0`
565 ///
566 /// ## Restriction
567 ///
568 /// Inter_command should be set high to enable this command
569 ///
570 SetGamma4(Gamma4),
571
572 /// Set Undocumented EBh (EBh)
573 ///
574 SetUndocumented0EBh(u8),
575
576 /// Set Undocumented 084h (084h)
577 ///
578 SetUndocumented084h(u8),
579
580 /// Set Undocumented 085h (085h)
581 ///
582 SetUndocumented085h(u8),
583
584 /// Set Undocumented 086h (086h)
585 ///
586 SetUndocumented086h(u8),
587
588 /// Set Undocumented 087h (087h)
589 ///
590 SetUndocumented087h(u8),
591
592 /// Set Undocumented 088h (088h)
593 ///
594 SetUndocumented088h(u8),
595
596 /// Set Undocumented 089h (089h)
597 ///
598 SetUndocumented089h(u8),
599
600 /// Set Undocumented 08Ah (08Ah)
601 ///
602 SetUndocumented08Ah(u8),
603
604 /// Set Undocumented 08Bh (08Bh)
605 ///
606 SetUndocumented08Bh(u8),
607
608 /// Set Undocumented 08Ch (08Ch)
609 ///
610 SetUndocumented08Ch(u8),
611
612 /// Set Undocumented 08Dh (08Dh)
613 ///
614 SetUndocumented08Dh(u8),
615
616 /// Set Undocumented 08Eh (08Eh)
617 ///
618 SetUndocumented08Eh(u8),
619
620 /// Set Undocumented 08Fh (08Fh)
621 ///
622 SetUndocumented08Fh(u8),
623
624 /// Set Undocumented 090h (090h)
625 ///
626 SetUndocumented090h,
627
628 /// Set Undocumented 062h (0x62h)
629 ///
630 SetUndocumented062h,
631
632 /// Set Undocumented 063h (0x63h)
633 ///
634 SetUndocumented063h,
635
636 /// Set Undocumented 064h (0x64h)
637 ///
638 SetUndocumented064h,
639
640 /// Set Undocumented 066h (0x66h)
641 ///
642 SetUndocumented066h,
643
644 /// Set Undocumented 067h (0x67h)
645 ///
646 SetUndocumented067h,
647
648 /// Set Undocumented 074h (0x74h)
649 ///
650 SetUndocumented074h,
651
652 /// Set Undocumented 098h (0x98h)
653 ///
654 SetUndocumented098h,
655
656 ///Set SUndocumented 0BEh (0xBEh)
657 SetUndocumented0BEh,
658 ///Set SUndocumented 0BCh (0xBCh)
659 SetUndocumented0BCh,
660 ///Set SUndocumented 0BDh (0xBDh)
661 SetUndocumented0BDh,
662 ///Set SUndocumented 0E1h (0xE1h)
663 SetUndocumented0E1h,
664 ///Set SUndocumented 0DFh (0xDFh)
665 SetUndocumented0DFh,
666 ///Set SUndocumented 0EDh (0xEDh)
667 SetUndocumented0EDh,
668 ///Set SUndocumented 0AEh (0xAEh)
669 SetUndocumented0AEh,
670 ///Set SUndocumented 0CDh (0xCDh)
671 SetUndocumented0CDh,
672 ///Set SUndocumented 070h (0x70h)
673 SetUndocumented070h,
674 ///Set SUndocumented 0FFh (0xFFh)
675 SetUndocumented0FFh,
676
677 /// Memory Write (F2Ch)
678 ///
679 /// ## Description
680 ///
681 /// change to the other driver
682 /// status. When this command is accepted, the column register and the page register are reset to
683 /// the Start Column/Start
684 /// Page positions. The Start Column/Start Page positions are different in accordance with
685 /// MADCTL setting.) Then D [17:0] isstored in frame memory and the column register and the
686 /// page register incremented. Sending any other command can stop frame Write. X = Don’t care
687 ///
688 /// ## Restriction
689 ///
690 /// In all color modes, there is no restriction on length of parameters.
691 ///
692 ///
693 MemoryWrite,
694
695 /// Write Memory Contiue (3Ch)
696 ///
697 /// ## Description
698 ///
699 /// This command transfers image data from the host processor to the display module’s frame
700 /// memory continuing from the pixel location following the previous write_memory_continue or write_memory_start
701 /// command.
702 ///
703 /// ### If set_address_mode B5 = 0:
704 /// Data is written continuing from the pixel location after the write range of the previous
705 /// write_memory_start or write_memory_continue. The column register is then incremented and pixels are written to the
706 /// frame memory until the column register equals the End Column (EC) value. The column register is then reset to SC and the page register is
707 /// incremented. Pixels are written to the frame memory until the page register equals the End Page
708 /// (EP) value and the column register equals the EC value, or the host processor sends another command. If the
709 /// number of pixels exceeds (EC –SC + 1) * (EP – SP + 1) the extra pixels are ignored.
710 ///
711 /// ### If set_address_mode B5 = 1:
712 /// Data is written continuing from the pixel location after the write range of the previous
713 /// write_memory_start or write_memory_continue. The page register is then incremented and pixels are written to the
714 /// frame memory until the page register equals the End Page (EP) value. The page register is then
715 /// reset to SP and the column register is incremented. Pixels are written to the frame memory until
716 /// the column register equals the End column (EC) value and the page register equals the EP value,
717 /// or the host processor sends another command. If the number of pixels exceeds (EC – SC + 1) *
718 /// (EP –SP + 1) the extra pixels are ignored.
719 /// Sending any other command can stop frame Write.
720 /// Frame Memory Access and Interface setting (B3h), WEMODE=0
721 /// When the transfer number of data exceeds (EC-SC+1)*(EP-SP+1), the exceeding data will be ignored.
722 /// Frame Memory Access and Interface setting (B3h), WEMODE=1
723 ///
724 /// When the transfer number of data exceeds (EC-SC+1)*(EP-SP+1), the column and page number
725 /// will be reset, and the
726 /// exceeding data will be written into the following column and page
727 ///
728 /// ## Restriction
729 ///
730 /// A write_memory_start should follow a set_column_address, set_page_address or
731 /// set_address_mode to define the write
732 /// address. Otherwise, data written with write_memory_continue is written to undefined addresses
733 MemoryWriteContinue,
734}
735
736impl Command {
737 /// Send command to [`Gc9a01`]
738 ///
739 /// # Errors
740 ///
741 /// This method may return an error if there are communication issues with the display.
742 #[allow(clippy::too_many_lines)]
743 pub fn send<DI>(self, iface: &mut DI) -> Result<(), DisplayError>
744 where
745 DI: WriteOnlyDataCommand,
746 {
747 // 16bits command (2bytes)
748 // 16bits param_1 (2bytes)
749 // 16bits param_2 (2bytes)
750 // 16bits param_3 (2bytes)
751 // 16bits param_4 (2bytes)
752 // Maximum 10 bytes
753 // Array Size 5
754 // Transform everything in 10 bytes array
755 let (data, len): ([u8; 13], usize) = match self {
756 Self::SleepMode(level) => (
757 [
758 match level {
759 Logical::Off => 0x11,
760 Logical::On => 0x10,
761 },
762 0,
763 0,
764 0,
765 0,
766 0,
767 0,
768 0,
769 0,
770 0,
771 0,
772 0,
773 0,
774 ],
775 1,
776 ),
777 Self::PartialMode => ([0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 1),
778 Self::NormalDisplayMode => ([0x13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 1),
779 Self::DisplayInversion(level) => {
780 ([0x20 | level as u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 1)
781 }
782 Self::DisplayState(level) => {
783 ([0x28 | level as u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 1)
784 }
785 Self::ColumnAddressSet(sc, ec) => (
786 [
787 0x2A,
788 (sc >> 8) as u8,
789 (sc & 0xFF) as u8,
790 (ec >> 8) as u8,
791 (ec & 0xFF) as u8,
792 0,
793 0,
794 0,
795 0,
796 0,
797 0,
798 0,
799 0,
800 ],
801 5,
802 ),
803 Self::RowAddressSet(sp, ep) => (
804 [
805 0x2B,
806 (sp >> 8) as u8,
807 (sp & 0xFF) as u8,
808 (ep >> 8) as u8,
809 (ep & 0xFF) as u8,
810 0,
811 0,
812 0,
813 0,
814 0,
815 0,
816 0,
817 0,
818 ],
819 5,
820 ),
821 Self::VertialScrollDef(tfa, vsa) => (
822 [
823 0x33,
824 (tfa >> 8) as u8,
825 (tfa & 0xFF) as u8,
826 (vsa >> 8) as u8,
827 (vsa & 0xFF) as u8,
828 0,
829 0,
830 0,
831 0,
832 0,
833 0,
834 0,
835 0,
836 ],
837 5,
838 ),
839 Self::TearingEffectLine(mode) => {
840 ([0x34 | mode as u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 1)
841 }
842 Self::VerticalScrollStartAddresss(vsp) => (
843 [
844 0x37,
845 (vsp >> 8) as u8,
846 (vsp & 0xFF) as u8,
847 0,
848 0,
849 0,
850 0,
851 0,
852 0,
853 0,
854 0,
855 0,
856 0,
857 ],
858 3,
859 ),
860 Self::IdleMode(mode) => ([0x38 | mode as u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 1),
861 Self::PixelFormatSet(dbi, dpi) => (
862 [
863 0x3A,
864 ((dpi as u8) << 4) | (dbi as u8),
865 0,
866 0,
867 0,
868 0,
869 0,
870 0,
871 0,
872 0,
873 0,
874 0,
875 0,
876 ],
877 2,
878 ),
879 Self::SetTearScanline(sts) => (
880 [
881 0x44,
882 (((sts + 8) & 0x100) >> 8) as u8,
883 ((sts + 8) & 0xFF) as u8,
884 0,
885 0,
886 0,
887 0,
888 0,
889 0,
890 0,
891 0,
892 0,
893 0,
894 ],
895 3,
896 ),
897 Self::DisplayBrightness(dbv) => ([0x51, dbv, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 2),
898 Self::CtrlDisplay(bctrl, dd, bl) => (
899 [
900 0x53,
901 (bctrl as u8) << 5 | (dd as u8) << 3 | (bl as u8) << 2,
902 0,
903 0,
904 0,
905 0,
906 0,
907 0,
908 0,
909 0,
910 0,
911 0,
912 0,
913 ],
914 2,
915 ),
916 Self::RGBInterfaceSignalCtrl(epl, dpl, hsp, vsp, rcm) => (
917 [
918 0xB0,
919 (epl as u8 & 0b1)
920 | ((dpl as u8 & 0b1) << 1)
921 | ((hsp as u8 & 0b1) << 2)
922 | ((vsp as u8 & 0b1) << 3)
923 | ((rcm as u8 & 0b11) << 5),
924 0,
925 0,
926 0,
927 0,
928 0,
929 0,
930 0,
931 0,
932 0,
933 0,
934 0,
935 ],
936 2,
937 ),
938 Self::BlankingPorchControl(vfp, vbp, hbp) => (
939 [
940 0xB5,
941 vfp,
942 vbp & 0b0111_1111,
943 hbp & 0b0001_1111,
944 0,
945 0,
946 0,
947 0,
948 0,
949 0,
950 0,
951 0,
952 0,
953 ],
954 4,
955 ),
956 Self::DispalyFunctionControl(gs, ss, sm, nl) => (
957 [
958 0xB6,
959 ((gs as u8 & 0b1) << 6) | ((ss as u8 & 0b1) << 5) | ((sm & 0b1) << 4),
960 nl & 0b0001_1111,
961 0,
962 0,
963 0,
964 0,
965 0,
966 0,
967 0,
968 0,
969 0,
970 0,
971 ],
972 3,
973 ),
974 Self::TEControl(te_pol, te_width) => (
975 [
976 0xBA,
977 ((te_pol as u8) << 7) | (te_width & 0b0111_1111),
978 0,
979 0,
980 0,
981 0,
982 0,
983 0,
984 0,
985 0,
986 0,
987 0,
988 0,
989 ],
990 2,
991 ),
992 Self::Interface(dm, rm, rim) => (
993 [
994 0xF6,
995 ((dm as u8 & 0b11) << 2) | ((rm as u8 & 0b1) << 1) | (rim as u8 & 0b1),
996 0,
997 0,
998 0,
999 0,
1000 0,
1001 0,
1002 0,
1003 0,
1004 0,
1005 0,
1006 0,
1007 ],
1008 2,
1009 ),
1010 Self::PowerCriterioControl(vcire) => (
1011 [
1012 0xC1,
1013 ((vcire as u8 & 0b1) << 1),
1014 0,
1015 0,
1016 0,
1017 0,
1018 0,
1019 0,
1020 0,
1021 0,
1022 0,
1023 0,
1024 0,
1025 ],
1026 2,
1027 ),
1028 Self::VCoreVoltageControl(vddad) => (
1029 [
1030 0xA7,
1031 0b0100_0000 | vddad as u8,
1032 0,
1033 0,
1034 0,
1035 0,
1036 0,
1037 0,
1038 0,
1039 0,
1040 0,
1041 0,
1042 0,
1043 ],
1044 2,
1045 ),
1046 Self::Vreg1aVoltageControl(value) => {
1047 ([0xC3, value, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 2)
1048 }
1049 Self::Vreg1bVoltageControl(value) => {
1050 ([0xC4, value, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 2)
1051 }
1052 Self::Vreg2aVoltageControl(value) => {
1053 ([0xC9, value, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 2)
1054 }
1055 Self::FrameRate(divn_mode) => (
1056 [
1057 0xE8,
1058 (divn_mode as u8 & 0b111) << 4,
1059 0,
1060 0,
1061 0,
1062 0,
1063 0,
1064 0,
1065 0,
1066 0,
1067 0,
1068 0,
1069 0,
1070 ],
1071 2,
1072 ),
1073 Self::Spi2dataControl(data2_en, data_format) => (
1074 [
1075 0xE9,
1076 (data2_en as u8 & 0b1) << 3 | (data_format as u8 & 0b111),
1077 0,
1078 0,
1079 0,
1080 0,
1081 0,
1082 0,
1083 0,
1084 0,
1085 0,
1086 0,
1087 0,
1088 ],
1089 3,
1090 ),
1091 Self::ChargePumpFrequentControl(
1092 avdd_clk_ad,
1093 avee_clk_ad,
1094 vcl_clk_ad,
1095 vgh_clk_ad,
1096 vgl_clk_ad,
1097 ) => (
1098 [
1099 0xEC,
1100 ((avdd_clk_ad & 0b111) << 4) | avee_clk_ad & 0b111,
1101 vcl_clk_ad & 0b111,
1102 ((vgh_clk_ad & 0b1111) << 4) | vgl_clk_ad & 0b1111,
1103 0,
1104 0,
1105 0,
1106 0,
1107 0,
1108 0,
1109 0,
1110 0,
1111 0,
1112 ],
1113 4,
1114 ),
1115 Self::InnerRegisterEnable1 => ([0xFE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 1),
1116 Self::InnerRegisterEnable2 => ([0xEF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 1),
1117 Self::SetGamma1(gamma) => (
1118 [
1119 0xF0,
1120 // 0b001, 0b000_101
1121 (gamma.dig2j0_n & 0b11) << 6 | (gamma.vr1_n & 0b0011_1111),
1122 (gamma.dig2j1_n & 0b11) << 6 | (gamma.vr2_n & 0b0011_1111),
1123 (gamma.vr4_n & 0b0001_1111),
1124 (gamma.vr6_n & 0b0001_1111),
1125 (gamma.vr0_n & 0b1111) << 4 | (gamma.vr13_n & 0b0000_1111),
1126 (gamma.vr20_n & 0b0111_1111),
1127 0,
1128 0,
1129 0,
1130 0,
1131 0,
1132 0,
1133 ],
1134 7,
1135 ),
1136 Self::SetGamma2(gamma) => (
1137 [
1138 0xF1,
1139 (gamma.vr43_n & 0b0111_1111),
1140 (gamma.vr27_n & 0b111) << 5 | (gamma.vr57_n & 0b0001_1111),
1141 (gamma.vr36_n & 0b111) << 5 | (gamma.vr59_n & 0b0001_1111),
1142 (gamma.vr61_n & 0b0011_1111),
1143 (gamma.vr62_n & 0b0011_1111),
1144 (gamma.vr50_n & 0b1111) << 4 | (gamma.vr63_n & 0b0000_1111),
1145 0,
1146 0,
1147 0,
1148 0,
1149 0,
1150 0,
1151 ],
1152 7,
1153 ),
1154 Self::SetGamma3(gamma) => (
1155 [
1156 0xF2,
1157 (gamma.dig2j0_p & 0b11) << 6 | (gamma.vr1_p & 0b0011_1111),
1158 (gamma.dig2j1_p & 0b11) << 6 | (gamma.vr2_p & 0b0011_1111),
1159 (gamma.vr4_p & 0b0001_1111),
1160 (gamma.vr6_p & 0b0001_1111),
1161 (gamma.vr0_p & 0b1111) << 4 | (gamma.vr13_p & 0b0000_1111),
1162 (gamma.vr20_p & 0b0111_1111),
1163 0,
1164 0,
1165 0,
1166 0,
1167 0,
1168 0,
1169 ],
1170 7,
1171 ),
1172 Self::SetGamma4(gamma) => (
1173 [
1174 0xF3,
1175 (gamma.vr43_p & 0b0111_1111),
1176 (gamma.vr27_p & 0b111) << 5 | (gamma.vr57_p & 0b0001_1111),
1177 (gamma.vr36_p & 0b111) << 5 | (gamma.vr59_p & 0b0001_1111),
1178 (gamma.vr61_p & 0b0011_1111),
1179 (gamma.vr62_p & 0b0011_1111),
1180 (gamma.vr50_p & 0b1111) << 4 | (gamma.vr63_p & 0b0000_1111),
1181 0,
1182 0,
1183 0,
1184 0,
1185 0,
1186 0,
1187 ],
1188 7,
1189 ),
1190 Self::MemoryWrite => ([0x2c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 1),
1191 Self::MemoryWriteContinue => ([0x3c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 1),
1192 Self::SetUndocumented0BEh => ([0xBE, 0x11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 2),
1193 Self::SetUndocumented0BCh => ([0xBC, 0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 2),
1194 Self::SetUndocumented0BDh => ([0xBD, 0x06, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 2),
1195 Self::SetUndocumented0E1h => ([0xE1, 0x10, 0x0E, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 3),
1196 Self::SetUndocumented0DFh => ([0xDF, 0x21, 0x0c, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0], 4),
1197 Self::SetUndocumented0EDh => ([0xED, 0x1B, 0x0B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 3),
1198 Self::SetUndocumented0AEh => ([0xAE, 0x77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 2),
1199 Self::SetUndocumented0CDh => ([0xCD, 0x63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 2),
1200 Self::SetUndocumented070h => (
1201 [
1202 0x70, 0x07, 0x07, 0x04, 0x0E, 0x0F, 0x09, 0x07, 0x08, 0x03, 0, 0, 0,
1203 ],
1204 10,
1205 ),
1206
1207 Self::SetUndocumented0FFh => ([0xFF, 0x60, 0x01, 0x04, 0, 0, 0, 0, 0, 0, 0, 0, 0], 4),
1208 Self::SetUndocumented0EBh(value) => ([0xEB, value, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 2),
1209 Self::SetUndocumented084h(value) => ([0x84, value, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 2),
1210 Self::SetUndocumented085h(value) => ([0x85, value, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 2),
1211 Self::SetUndocumented086h(value) => ([0x86, value, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 2),
1212 Self::SetUndocumented087h(value) => ([0x87, value, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 2),
1213 Self::SetUndocumented088h(value) => ([0x88, value, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 2),
1214 Self::SetUndocumented089h(value) => ([0x89, value, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 2),
1215 Self::SetUndocumented08Ah(value) => ([0x8A, value, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 2),
1216 Self::SetUndocumented08Bh(value) => ([0x8B, value, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 2),
1217 Self::SetUndocumented08Ch(value) => ([0x8C, value, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 2),
1218 Self::SetUndocumented08Dh(value) => ([0x8D, value, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 2),
1219 Self::SetUndocumented08Eh(value) => ([0x8E, value, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 2),
1220 Self::SetUndocumented08Fh(value) => ([0x8F, value, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 2),
1221 Self::SetUndocumented090h => {
1222 ([0x90, 0x08, 0x08, 0x08, 0x08, 0, 0, 0, 0, 0, 0, 0, 0], 5)
1223 }
1224 Self::MemoryAccessControl(my, mx, mv, ml, bgr, mh) => (
1225 [
1226 0x36,
1227 (my as u8) << 7
1228 | (mx as u8) << 6
1229 | (mv as u8) << 5
1230 | (ml as u8) << 4
1231 | (bgr as u8) << 3
1232 | (mh as u8) << 2,
1233 0,
1234 0,
1235 0,
1236 0,
1237 0,
1238 0,
1239 0,
1240 0,
1241 0,
1242 0,
1243 0,
1244 ],
1245 2,
1246 ),
1247 Self::SetUndocumented062h => (
1248 [
1249 0x62, 0x18, 0x0D, 0x71, 0xED, 0x70, 0x70, 0x18, 0x0F, 0x71, 0xEF, 0x70, 0x70,
1250 ],
1251 13,
1252 ),
1253 Self::SetUndocumented063h => (
1254 [
1255 0x63, 0x18, 0x11, 0x71, 0xF1, 0x70, 0x70, 0x18, 0x13, 0x71, 0xF3, 0x70, 0x70,
1256 ],
1257 13,
1258 ),
1259 Self::SetUndocumented064h => (
1260 [
1261 0x64, 0x28, 0x29, 0xF1, 0x01, 0xF1, 0x00, 0x07, 0, 0, 0, 0, 0,
1262 ],
1263 8,
1264 ),
1265 Self::SetUndocumented066h => (
1266 [
1267 0x66, 0x3C, 0x00, 0xCD, 0x67, 0x45, 0x45, 0x10, 0x00, 0x00, 0x00, 0, 0,
1268 ],
1269 11,
1270 ),
1271 Self::SetUndocumented067h => (
1272 [
1273 0x67, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x01, 0x54, 0x10, 0x32, 0x98, 0, 0,
1274 ],
1275 11,
1276 ),
1277 Self::SetUndocumented074h => (
1278 [
1279 0x74, 0x10, 0x85, 0x80, 0x00, 0x00, 0x4E, 0x00, 0, 0, 0, 0, 0,
1280 ],
1281 8,
1282 ),
1283 Self::SetUndocumented098h => ([0x98, 0x3e, 0x07, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 3),
1284 };
1285
1286 // Send command over the interface
1287 // TODO: do something better
1288 iface.send_commands(U8(&[data[0]]))?;
1289 if len > 1 {
1290 iface.send_data(U8(&data[1..len]))?;
1291 }
1292 Ok(())
1293 }
1294}
1295
1296/// Logical On/Off
1297#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1298#[repr(u8)]
1299pub enum Logical {
1300 Off = 0,
1301 On = 1,
1302}
1303
1304impl From<bool> for Logical {
1305 fn from(val: bool) -> Self {
1306 if val {
1307 Self::On
1308 } else {
1309 Self::Off
1310 }
1311 }
1312}
1313
1314impl From<u8> for Logical {
1315 fn from(val: u8) -> Self {
1316 match val {
1317 0 => Self::Off,
1318 _ => Self::On,
1319 }
1320 }
1321}
1322
1323/// Display Enable Polarity (DE Polarity)
1324#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1325#[repr(u8)]
1326pub enum DEPolarity {
1327 /// High enable for RGB interface
1328 HighEnableForRGB = 0,
1329 /// Low enable for RGB interface
1330 LowEnableForRGB = 1,
1331}
1332
1333impl From<bool> for DEPolarity {
1334 fn from(val: bool) -> Self {
1335 if val {
1336 Self::HighEnableForRGB
1337 } else {
1338 Self::LowEnableForRGB
1339 }
1340 }
1341}
1342
1343impl From<u8> for DEPolarity {
1344 fn from(val: u8) -> Self {
1345 match val {
1346 0 => Self::HighEnableForRGB,
1347 _ => Self::LowEnableForRGB,
1348 }
1349 }
1350}
1351
1352/// The Tearing Effect output signal pulse polarity
1353#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1354#[repr(u8)]
1355pub enum TEPolarity {
1356 /// High enable for RGB interface
1357 PositivePulse = 0,
1358 /// Low enable for RGB interface
1359 NegativePulse = 1,
1360}
1361
1362impl From<bool> for TEPolarity {
1363 fn from(val: bool) -> Self {
1364 if val {
1365 Self::PositivePulse
1366 } else {
1367 Self::NegativePulse
1368 }
1369 }
1370}
1371
1372impl From<u8> for TEPolarity {
1373 fn from(val: u8) -> Self {
1374 match val {
1375 0 => Self::PositivePulse,
1376 _ => Self::NegativePulse,
1377 }
1378 }
1379}
1380
1381/// Display Enable Polarity (DOTCLK Polarity)
1382#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1383#[repr(u8)]
1384pub enum DOTClk {
1385 /// Data fetched at the rising time
1386 FetchOnRising = 0,
1387 /// Data fetched at the falling time
1388 FetchOnFalling = 1,
1389}
1390
1391impl From<bool> for DOTClk {
1392 fn from(val: bool) -> Self {
1393 if val {
1394 Self::FetchOnRising
1395 } else {
1396 Self::FetchOnFalling
1397 }
1398 }
1399}
1400
1401impl From<u8> for DOTClk {
1402 fn from(val: u8) -> Self {
1403 match val {
1404 0 => Self::FetchOnRising,
1405 _ => Self::FetchOnFalling,
1406 }
1407 }
1408}
1409
1410/// Polarity Clock Sync
1411#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1412#[repr(u8)]
1413pub enum XSpl {
1414 /// Low level sync clock
1415 LowSyncClock = 0,
1416 /// Low level sync clock
1417 HighSyncClock = 1,
1418}
1419
1420impl From<bool> for XSpl {
1421 fn from(val: bool) -> Self {
1422 if val {
1423 Self::LowSyncClock
1424 } else {
1425 Self::HighSyncClock
1426 }
1427 }
1428}
1429
1430impl From<u8> for XSpl {
1431 fn from(val: u8) -> Self {
1432 match val {
1433 0 => Self::LowSyncClock,
1434 _ => Self::HighSyncClock,
1435 }
1436 }
1437}
1438
1439/// Polarity Clock Sync
1440#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1441#[repr(u8)]
1442pub enum RCMMode {
1443 /// DE Mode Valid data is determined by the DE signal
1444 DEMode = 0b10,
1445 /// SYNC Mode In SYNC mode, DE signal is ignored; blanking porch
1446 /// is determined by B5h command
1447 SyncMode = 0b11,
1448}
1449
1450impl From<u8> for RCMMode {
1451 fn from(val: u8) -> Self {
1452 match val {
1453 0b10 => Self::DEMode,
1454 _ => Self::SyncMode,
1455 }
1456 }
1457}
1458
1459/// Output Scan Direction
1460#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1461#[repr(u8)]
1462pub enum SSMode {
1463 /// To assign R, G, B dots to the source driver pins from S1 to S360, set SS = 0
1464 S1toS360 = 0,
1465 /// To assign R, G, B dots to the source driver pins from S360 to S1, set SS = 1.
1466 S360toS1 = 1,
1467}
1468
1469impl From<u8> for SSMode {
1470 fn from(val: u8) -> Self {
1471 match val {
1472 0 => Self::S1toS360,
1473 _ => Self::S1toS360,
1474 }
1475 }
1476}
1477
1478/// Display Operation Mode
1479/// Select the display operation mode
1480#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1481#[repr(u8)]
1482pub enum DMMode {
1483 /// Internal clock operation
1484 InternalClockOperation = 0,
1485 /// RGB Interface Mode
1486 RGBInterfaceMode = 1,
1487 /// VSYNC Interface Mode
1488 VSYNCInterfaceMode = 2,
1489 /// RGB Interface Mode
1490 SettingDisabled = 3,
1491}
1492
1493impl From<u8> for DMMode {
1494 fn from(val: u8) -> Self {
1495 match val {
1496 0 => Self::InternalClockOperation,
1497 1 => Self::RGBInterfaceMode,
1498 2 => Self::VSYNCInterfaceMode,
1499 _ => Self::SettingDisabled,
1500 }
1501 }
1502}
1503
1504/// Interface for RAM Access
1505/// Select the interface to access the GRAM.
1506#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1507#[repr(u8)]
1508pub enum RMMode {
1509 /// Select System or VSync Interface to write in GRAM
1510 SystemOrVSyncInterface = 0,
1511 /// Select RGB Interface to write in GRAM
1512 RGBInterface = 1,
1513}
1514
1515impl From<u8> for RMMode {
1516 fn from(val: u8) -> Self {
1517 match val {
1518 0 => Self::SystemOrVSyncInterface,
1519 1 => Self::RGBInterface,
1520 _ => Self::RGBInterface,
1521 }
1522 }
1523}
1524
1525/// RGB Interface Mode
1526/// Specify the RGB interface mode when the RGB interface is used.
1527/// These bit should be set before display operation through the RGB interface
1528/// and should not be set during operation.
1529#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1530#[repr(u8)]
1531pub enum RIMMode {
1532 /// 18- bit RGB interface (1 transfer/pixel)
1533 /// 16- bit RGB interface (1 transfer/pixel)
1534 TransferPerPixel1 = 0,
1535 /// 6- bit RGB interface (3 transfer/pixel)
1536 TransferPerPixel3 = 1,
1537}
1538
1539impl From<u8> for RIMMode {
1540 fn from(val: u8) -> Self {
1541 match val {
1542 0 => Self::TransferPerPixel1,
1543 1 => Self::TransferPerPixel3,
1544 _ => Self::TransferPerPixel3,
1545 }
1546 }
1547}
1548
1549/// Display Inversion Mode
1550/// Set display inversion mode
1551#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1552#[repr(u8)]
1553pub enum DINVMode {
1554 /// column inversion
1555 ColumnInversion = 0,
1556 /// 1 dot inversion
1557 Inversion1Dot = 1,
1558 /// 2 dot inversion
1559 Inversion2Dot = 2,
1560 /// 4 dot inversion
1561 Inversion4Dot = 3,
1562 /// 8 dot inversion
1563 Inversion8Dot = 4,
1564}
1565
1566impl From<u8> for DINVMode {
1567 fn from(val: u8) -> Self {
1568 match val {
1569 0 => Self::ColumnInversion,
1570 1 => Self::Inversion1Dot,
1571 2 => Self::Inversion2Dot,
1572 3 => Self::Inversion4Dot,
1573 4 => Self::Inversion8Dot,
1574 _ => Self::Inversion8Dot,
1575 }
1576 }
1577}
1578
1579/// 2 Data Line Mode 3/4-wire SPI
1580#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1581#[repr(u8)]
1582pub enum Data2EN {
1583 /// 3-wire SPI
1584 Data3Wire = 0,
1585 /// 4-wire SPI
1586 Data4Wire = 1,
1587}
1588
1589impl From<u8> for Data2EN {
1590 fn from(val: u8) -> Self {
1591 match val {
1592 0 => Self::Data3Wire,
1593 1 => Self::Data4Wire,
1594 _ => Self::Data4Wire,
1595 }
1596 }
1597}
1598
1599/// `DataFormat` MDT
1600/// Set Pixel Data Format in `2_data_line` mode.
1601#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1602#[repr(u8)]
1603pub enum DataFormatMDT {
1604 /// 65K color 1pixle/transition
1605 Color65k1PixelPerTransition = 0,
1606 /// 262K color 1pixle/transition
1607 Color262k1PixelPerTransition = 1,
1608 /// 262K color 2/3pixle/transition
1609 Color262k2Or3PixelPerTransition = 2,
1610 /// 4M color 1pixle/transition
1611 Color4Mk1PixelPerTransition = 4,
1612 /// 4M color 2/3pixle/transition
1613 Color4M2Or3PixelPerTransition = 5,
1614}
1615
1616impl From<u8> for DataFormatMDT {
1617 fn from(val: u8) -> Self {
1618 match val {
1619 0 => Self::Color65k1PixelPerTransition,
1620 1 => Self::Color262k1PixelPerTransition,
1621 2 => Self::Color262k2Or3PixelPerTransition,
1622 3 => Self::Color4Mk1PixelPerTransition,
1623 4 => Self::Color4M2Or3PixelPerTransition,
1624 _ => Self::Color4M2Or3PixelPerTransition,
1625 }
1626 }
1627}
1628
1629/// External reference voltage Vci or internal reference voltage VCIT
1630#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1631#[repr(u8)]
1632pub enum VCIRe {
1633 /// Internal reference voltage 2.5V (default)
1634 Internal = 0,
1635 /// External reference voltage Vci
1636 External = 1,
1637}
1638
1639impl From<u8> for VCIRe {
1640 fn from(val: u8) -> Self {
1641 match val {
1642 0 => Self::Internal,
1643 1 => Self::External,
1644 _ => Self::External,
1645 }
1646 }
1647}
1648
1649/// Voltage level value to output the VCORE level,
1650#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1651#[repr(u8)]
1652pub enum VddAd {
1653 VCore1_483V = 0x00,
1654 VCore1_545V = 0x01,
1655 VCore1_590V = 0x02,
1656 VCore1_638V = 0x03,
1657 VCore1_714V = 0x04,
1658 VCore1_279V = 0x05,
1659 VCore1_859V = 0x06,
1660 VCore1_925V = 0x07,
1661 VCore1_994V = 0x08,
1662 VCore2_109V = 0x09,
1663 VCore2_193V = 0x0a,
1664 VCore2_286V = 0x0b,
1665 VCore2_385V = 0x0c,
1666 VCore1_713V = 0x0d,
1667 VCore1_713Ve = 0x0e,
1668 VCore1_713Vf = 0x0f,
1669}
1670
1671impl From<u8> for VddAd {
1672 fn from(val: u8) -> Self {
1673 match val {
1674 0x00 => Self::VCore1_483V,
1675 0x01 => Self::VCore1_545V,
1676 0x02 => Self::VCore1_590V,
1677 0x03 => Self::VCore1_638V,
1678 0x04 => Self::VCore1_714V,
1679 0x05 => Self::VCore1_279V,
1680 0x06 => Self::VCore1_859V,
1681 0x07 => Self::VCore1_925V,
1682 0x08 => Self::VCore1_994V,
1683 0x09 => Self::VCore2_109V,
1684 0x0a => Self::VCore2_193V,
1685 0x0b => Self::VCore2_286V,
1686 0x0c => Self::VCore2_385V,
1687 0x0d => Self::VCore1_713V,
1688 0x0e => Self::VCore1_713Ve,
1689 0x0f => Self::VCore1_713Vf,
1690 _ => Self::VCore1_713Vf,
1691 }
1692 }
1693}
1694
1695/// Gate Output Scan Direction
1696/// Sets the direction of scan by the gate driver in the range determined by SCN [4:0] and NL
1697/// [4:0]. The scan direction determined by GS = 0 can be reversed by setting GS = 1.
1698#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1699#[repr(u8)]
1700pub enum GSMode {
1701 G1toG32 = 0,
1702 G32toG1 = 1,
1703}
1704
1705impl From<u8> for GSMode {
1706 fn from(val: u8) -> Self {
1707 match val {
1708 0 => Self::G1toG32,
1709 _ => Self::G32toG1,
1710 }
1711 }
1712}
1713
1714/// Dpi is the pixel format select of RGB interface.
1715#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1716#[repr(u8)]
1717pub enum Dpi {
1718 Pixel16bits = 0b0000_0101,
1719 Pixel18bits = 0b0000_0110,
1720}
1721
1722/// Dbi is the pixel format of MCU interface.
1723#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1724#[repr(u8)]
1725pub enum Dbi {
1726 Pixel12bits = 0b0000_0011,
1727 Pixel16bits = 0b0000_0101,
1728 Pixel18bits = 0b0000_0110,
1729}
1730
1731#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1732pub struct Gamma1 {
1733 /// dig2gam_dig2j0_n
1734 pub dig2j0_n: u8,
1735 /// dig2gam_vr1_n
1736 pub vr1_n: u8,
1737 /// dig2gam_dig2j1_n
1738 pub dig2j1_n: u8,
1739 /// dig2gam_vr2_n
1740 pub vr2_n: u8,
1741 /// dig2gam_vr4_n
1742 pub vr4_n: u8,
1743 /// dig2gam_vr6_n
1744 pub vr6_n: u8,
1745 /// dig2gam_vr0_n
1746 pub vr0_n: u8,
1747 /// dig2gam_vr13_n
1748 pub vr13_n: u8,
1749 /// dig2gam_vr20_n
1750 pub vr20_n: u8,
1751}
1752
1753#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1754pub struct Gamma2 {
1755 /// dig2gam_vr43_n
1756 pub vr43_n: u8,
1757 /// dig2gam_vr27_n
1758 pub vr27_n: u8,
1759 /// dig2gam_vr57_n
1760 pub vr57_n: u8,
1761 /// dig2gam_vr36_n
1762 pub vr36_n: u8,
1763 /// dig2gam_vr59_n
1764 pub vr59_n: u8,
1765 /// dig2gam_vr61_n
1766 pub vr61_n: u8,
1767 /// dig2gam_vr62_n
1768 pub vr62_n: u8,
1769 /// dig2gam_vr50_n
1770 pub vr50_n: u8,
1771 /// dig2gam_vr63_n
1772 pub vr63_n: u8,
1773}
1774
1775#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1776pub struct Gamma3 {
1777 /// dig2gam_dig2j0_p
1778 pub dig2j0_p: u8,
1779 /// dig2gam_vr1_p
1780 pub vr1_p: u8,
1781 /// dig2gam_dig2j1_p
1782 pub dig2j1_p: u8,
1783 /// dig2gam_vr2_p
1784 pub vr2_p: u8,
1785 /// dig2gam_vr4_p
1786 pub vr4_p: u8,
1787 /// dig2gam_vr6_p
1788 pub vr6_p: u8,
1789 /// dig2gam_vr0_p
1790 pub vr0_p: u8,
1791 /// dig2gam_vr13_p
1792 pub vr13_p: u8,
1793 /// dig2gam_vr20_p
1794 pub vr20_p: u8,
1795}
1796
1797#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1798pub struct Gamma4 {
1799 /// dig2gam_vr43_p
1800 pub vr43_p: u8,
1801 /// dig2gam_vr27_p
1802 pub vr27_p: u8,
1803 /// dig2gam_vr57_p
1804 pub vr57_p: u8,
1805 /// dig2gam_vr36_p
1806 pub vr36_p: u8,
1807 /// dig2gam_vr59_p
1808 pub vr59_p: u8,
1809 /// dig2gam_vr61_p
1810 pub vr61_p: u8,
1811 /// dig2gam_vr62_p
1812 pub vr62_p: u8,
1813 /// dig2gam_vr50_p
1814 pub vr50_p: u8,
1815 /// dig2gam_vr63_p
1816 pub vr63_p: u8,
1817}