lcd_async/models/
st7789.rs

1use embedded_graphics_core::pixelcolor::Rgb565;
2use embedded_hal_async::delay::DelayNs;
3
4use crate::{
5    dcs::{
6        BitsPerPixel, EnterNormalMode, ExitSleepMode, InterfaceExt, PixelFormat, SetAddressMode,
7        SetDisplayOn, SetInvertMode, SetPixelFormat,
8    },
9    interface::{Interface, InterfaceKind},
10    models::{Model, ModelInitError},
11    options::ModelOptions,
12    ConfigurationError,
13};
14
15/// ST7789 display in Rgb565 color mode.
16pub struct ST7789;
17
18impl Model for ST7789 {
19    type ColorFormat = Rgb565;
20    const FRAMEBUFFER_SIZE: (u16, u16) = (240, 320);
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(150_000).await;
44
45        di.write_command(ExitSleepMode).await?;
46        delay.delay_us(10_000).await;
47
48        // set hw scroll area based on framebuffer size
49        di.write_command(madctl).await?;
50
51        di.write_command(SetInvertMode::new(options.invert_colors))
52            .await?;
53
54        let pf = PixelFormat::with_all(BitsPerPixel::from_rgb_color::<Self::ColorFormat>());
55        di.write_command(SetPixelFormat::new(pf)).await?;
56        delay.delay_us(10_000).await;
57        di.write_command(EnterNormalMode).await?;
58        delay.delay_us(10_000).await;
59        di.write_command(SetDisplayOn).await?;
60
61        // DISPON requires some time otherwise we risk SPI data issues
62        delay.delay_us(120_000).await;
63
64        Ok(madctl)
65    }
66}