1use embedded_graphics_core::pixelcolor::Rgb565;
2use embedded_hal_async::delay::DelayNs;
3
4use crate::{
5 dcs::{
6 BitsPerPixel, ExitSleepMode, InterfaceExt, PixelFormat, SetAddressMode, SetDisplayOn,
7 SetInvertMode, SetPixelFormat,
8 },
9 interface::{Interface, InterfaceKind},
10 models::{Model, ModelInitError},
11 options::ModelOptions,
12 ConfigurationError,
13};
14
15pub struct GC9A01;
17
18impl Model for GC9A01 {
19 type ColorFormat = Rgb565;
20 const FRAMEBUFFER_SIZE: (u16, u16) = (240, 240);
21
22 async fn init<DELAY, DI>(
23 &mut self,
24 di: &mut DI,
25 delay: &mut DELAY,
26 options: &ModelOptions,
27 ) -> Result<SetAddressMode, ModelInitError<DI::Error>>
28 where
29 DELAY: DelayNs,
30 DI: Interface,
31 {
32 if !matches!(
33 DI::KIND,
34 InterfaceKind::Serial4Line | InterfaceKind::Parallel8Bit | InterfaceKind::Parallel16Bit
35 ) {
36 return Err(ModelInitError::InvalidConfiguration(
37 ConfigurationError::UnsupportedInterface,
38 ));
39 }
40
41 let madctl = SetAddressMode::from(options);
42
43 delay.delay_us(200_000).await;
44
45 di.write_raw(0xEF, &[]).await?; di.write_raw(0xEB, &[0x14]).await?;
47 di.write_raw(0xFE, &[]).await?; di.write_raw(0xEF, &[]).await?; di.write_raw(0xEB, &[0x14]).await?;
50
51 di.write_raw(0x84, &[0x40]).await?;
52 di.write_raw(0x85, &[0xFF]).await?;
53 di.write_raw(0x86, &[0xFF]).await?;
54 di.write_raw(0x87, &[0xFF]).await?;
55 di.write_raw(0x88, &[0x0A]).await?;
56 di.write_raw(0x89, &[0x21]).await?;
57 di.write_raw(0x8A, &[0x00]).await?;
58 di.write_raw(0x8B, &[0x80]).await?;
59 di.write_raw(0x8C, &[0x01]).await?;
60 di.write_raw(0x8D, &[0x01]).await?;
61 di.write_raw(0x8E, &[0xFF]).await?;
62 di.write_raw(0x8F, &[0xFF]).await?;
63
64 di.write_raw(0xB6, &[0x00, 0x20]).await?; di.write_command(madctl).await?; let pf = PixelFormat::with_all(BitsPerPixel::from_rgb_color::<Self::ColorFormat>());
69 di.write_command(SetPixelFormat::new(pf)).await?; di.write_raw(0x90, &[0x08, 0x08, 0x08, 0x08]).await?;
72 di.write_raw(0xBD, &[0x06]).await?;
73 di.write_raw(0xBC, &[0x00]).await?;
74 di.write_raw(0xFF, &[0x60, 0x01, 0x04]).await?;
75
76 di.write_raw(0xC3, &[0x13]).await?; di.write_raw(0xC4, &[0x13]).await?; di.write_raw(0xC9, &[0x22]).await?; di.write_raw(0xBE, &[0x11]).await?;
81 di.write_raw(0xE1, &[0x10, 0x0E]).await?;
82 di.write_raw(0xDF, &[0x20, 0x0c, 0x02]).await?;
83
84 di.write_raw(0xF0, &[0x45, 0x09, 0x08, 0x08, 0x26, 0x2A])
85 .await?; di.write_raw(0xF1, &[0x43, 0x70, 0x72, 0x36, 0x37, 0x6f])
87 .await?; di.write_raw(0xF2, &[0x45, 0x09, 0x08, 0x08, 0x26, 0x2A])
89 .await?; di.write_raw(0xF3, &[0x43, 0x70, 0x72, 0x36, 0x37, 0x6f])
91 .await?; di.write_raw(0xED, &[0x18, 0x0B]).await?;
94 di.write_raw(0xAE, &[0x77]).await?;
95 di.write_raw(0xCD, &[0x63]).await?;
96
97 di.write_raw(
98 0x70,
99 &[0x07, 0x07, 0x04, 0x0E, 0x0F, 0x09, 0x07, 0x08, 0x03],
100 )
101 .await?;
102
103 di.write_raw(0xE8, &[0x34]).await?; di.write_raw(
106 0x62,
107 &[
108 0x18, 0x0D, 0x71, 0xED, 0x70, 0x70, 0x18, 0x0F, 0x71, 0xEF, 0x70, 0x70,
109 ],
110 )
111 .await?;
112 di.write_raw(
113 0x63,
114 &[
115 0x18, 0x11, 0x71, 0xF1, 0x70, 0x70, 0x18, 0x13, 0x71, 0xF3, 0x70, 0x70,
116 ],
117 )
118 .await?;
119 di.write_raw(0x64, &[0x28, 0x29, 0xF1, 0x01, 0xF1, 0x00, 0x07])
120 .await?;
121 di.write_raw(
122 0x66,
123 &[0x3C, 0x00, 0xCD, 0x67, 0x45, 0x45, 0x10, 0x00, 0x00, 0x00],
124 )
125 .await?;
126 di.write_raw(
127 0x67,
128 &[0x00, 0x3C, 0x00, 0x00, 0x00, 0x01, 0x54, 0x10, 0x32, 0x98],
129 )
130 .await?;
131
132 di.write_raw(0x74, &[0x10, 0x85, 0x80, 0x00, 0x00, 0x4E, 0x00])
133 .await?;
134 di.write_raw(0x98, &[0x3e, 0x07]).await?;
135
136 di.write_command(SetInvertMode::new(options.invert_colors))
137 .await?; di.write_command(ExitSleepMode).await?; delay.delay_us(120_000).await;
141
142 di.write_command(SetDisplayOn).await?; Ok(madctl)
145 }
146}