lcd_async/models/
st7735s.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/// ST7735s display in Rgb565 color mode.
16pub struct ST7735s;
17
18impl Model for ST7735s {
19    type ColorFormat = Rgb565;
20    const FRAMEBUFFER_SIZE: (u16, u16) = (132, 162);
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_command(ExitSleepMode).await?; // turn off sleep
46        delay.delay_us(120_000).await;
47
48        di.write_command(SetInvertMode::new(options.invert_colors))
49            .await?; // set color inversion
50        di.write_raw(0xB1, &[0x05, 0x3A, 0x3A]).await?; // set frame rate
51        di.write_raw(0xB2, &[0x05, 0x3A, 0x3A]).await?; // set frame rate
52        di.write_raw(0xB3, &[0x05, 0x3A, 0x3A, 0x05, 0x3A, 0x3A])
53            .await?; // set frame rate
54        di.write_raw(0xB4, &[0b0000_0011]).await?; // set inversion control
55        di.write_raw(0xC0, &[0x62, 0x02, 0x04]).await?; // set power control 1
56        di.write_raw(0xC1, &[0xC0]).await?; // set power control 2
57        di.write_raw(0xC2, &[0x0D, 0x00]).await?; // set power control 3
58        di.write_raw(0xC3, &[0x8D, 0x6A]).await?; // set power control 4
59        di.write_raw(0xC4, &[0x8D, 0xEE]).await?; // set power control 5
60        di.write_raw(0xC5, &[0x0E]).await?; // set VCOM control 1
61        di.write_raw(
62            0xE0,
63            &[
64                0x10, 0x0E, 0x02, 0x03, 0x0E, 0x07, 0x02, 0x07, 0x0A, 0x12, 0x27, 0x37, 0x00, 0x0D,
65                0x0E, 0x10,
66            ],
67        )
68        .await?; // set GAMMA +Polarity characteristics
69        di.write_raw(
70            0xE1,
71            &[
72                0x10, 0x0E, 0x03, 0x03, 0x0F, 0x06, 0x02, 0x08, 0x0A, 0x13, 0x26, 0x36, 0x00, 0x0D,
73                0x0E, 0x10,
74            ],
75        )
76        .await?; // set GAMMA -Polarity characteristics
77
78        let pf = PixelFormat::with_all(BitsPerPixel::from_rgb_color::<Self::ColorFormat>());
79        di.write_command(SetPixelFormat::new(pf)).await?; // set interface pixel format, 16bit pixel into frame memory
80
81        di.write_command(madctl).await?; // set memory data access control, Top -> Bottom, RGB, Left -> Right
82        di.write_command(SetDisplayOn).await?; // turn on display
83
84        Ok(madctl)
85    }
86}