lcd_async/models/
gc9a01.rs

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
15/// GC9A01 display in Rgb565 color mode.
16pub 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?; // inter register enable 2
46        di.write_raw(0xEB, &[0x14]).await?;
47        di.write_raw(0xFE, &[]).await?; // inter register enable 1
48        di.write_raw(0xEF, &[]).await?; // inter register enable 2
49        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?; // display function control
65
66        di.write_command(madctl).await?; // set memory data access control, Top -> Bottom, RGB, Left -> Right
67
68        let pf = PixelFormat::with_all(BitsPerPixel::from_rgb_color::<Self::ColorFormat>());
69        di.write_command(SetPixelFormat::new(pf)).await?; // set interface pixel format, 16bit pixel into frame memory
70
71        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?; // power control 2
77        di.write_raw(0xC4, &[0x13]).await?; // power control 3
78        di.write_raw(0xC9, &[0x22]).await?; // power control 4
79
80        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?; // gamma 1
86        di.write_raw(0xF1, &[0x43, 0x70, 0x72, 0x36, 0x37, 0x6f])
87            .await?; // gamma 2
88        di.write_raw(0xF2, &[0x45, 0x09, 0x08, 0x08, 0x26, 0x2A])
89            .await?; // gamma 3
90        di.write_raw(0xF3, &[0x43, 0x70, 0x72, 0x36, 0x37, 0x6f])
91            .await?; // gamma 4
92
93        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?; // framerate
104
105        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?; // set color inversion
138
139        di.write_command(ExitSleepMode).await?; // turn off sleep
140        delay.delay_us(120_000).await;
141
142        di.write_command(SetDisplayOn).await?; // turn on display
143
144        Ok(madctl)
145    }
146}