embedded_wg_display/display/
mod.rs1use alloc::boxed::Box;
4use defmt::info;
5use embedded_graphics::Drawable;
6use embedded_graphics::draw_target::DrawTarget;
7use embedded_graphics::mono_font::MonoTextStyle;
8use embedded_graphics::mono_font::iso_8859_1::FONT_8X13;
9use embedded_graphics::pixelcolor::Rgb565;
10use embedded_graphics::prelude::{Point, RgbColor};
11use embedded_graphics::text::Text;
12use embedded_hal_bus::spi::ExclusiveDevice;
13use esp_hal::delay::Delay;
14use esp_hal::gpio::DriveMode;
15use esp_hal::peripherals;
16use esp_hal::{
17 Blocking,
18 dma::{DmaRxBuf, DmaTxBuf},
19 dma_buffers,
20 gpio::{Level, Output, OutputConfig},
21 spi::master::{Spi, SpiDmaBus},
22 time::Rate,
23};
24use mipidsi::Builder;
25use mipidsi::interface::SpiInterface;
26use mipidsi::models::ILI9342CRgb565;
27use mipidsi::options::ColorOrder;
28
29type MyDisplay = mipidsi::Display<
31 SpiInterface<
32 'static,
33 ExclusiveDevice<SpiDmaBus<'static, Blocking>, Output<'static>, Delay>,
34 Output<'static>,
35 >,
36 ILI9342CRgb565,
37 Output<'static>,
38>;
39
40const CONSOLE_X: i32 = 10;
41const CONSOLE_LINE_HEIGHT: i32 = 15;
42const CONSOLE_INITIAL_Y: i32 = 20;
43
44pub struct Display {
45 display: MyDisplay,
46 console_y: i32,
47}
48
49pub struct DisplayPeripherals {
50 pub spi2: peripherals::SPI2<'static>,
51 pub dma_ch0: peripherals::DMA_CH0<'static>,
52 pub gpio4: peripherals::GPIO4<'static>,
53 pub gpio5: peripherals::GPIO5<'static>,
54 pub gpio6: peripherals::GPIO6<'static>,
55 pub gpio7: peripherals::GPIO7<'static>,
56 pub gpio47: peripherals::GPIO47<'static>,
57 pub gpio48: peripherals::GPIO48<'static>,
58}
59
60impl Display {
61 pub fn new(display_peripherals: DisplayPeripherals) -> Self {
63 let (rx_buffer, rx_descriptors, tx_buffer, tx_descriptors) = dma_buffers!(8912);
65 let dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap();
66 let dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
67
68 let spi = Spi::<Blocking>::new(
70 display_peripherals.spi2,
71 esp_hal::spi::master::Config::default()
72 .with_frequency(Rate::from_mhz(40))
73 .with_mode(esp_hal::spi::Mode::_0),
74 )
75 .unwrap()
76 .with_sck(display_peripherals.gpio7)
77 .with_mosi(display_peripherals.gpio6)
78 .with_dma(display_peripherals.dma_ch0)
79 .with_buffers(dma_rx_buf, dma_tx_buf);
80
81 let cs_output = Output::new(
82 display_peripherals.gpio5,
83 Level::High,
84 OutputConfig::default(),
85 );
86 let spi_delay = Delay::new();
87 let spi_device = ExclusiveDevice::new(spi, cs_output, spi_delay).unwrap();
88
89 let lcd_dc = Output::new(
90 display_peripherals.gpio4,
91 Level::Low,
92 OutputConfig::default(),
93 );
94 let buffer: &'static mut [u8; 512] = Box::leak(Box::new([0_u8; 512]));
95 let di = SpiInterface::new(spi_device, lcd_dc, buffer);
96
97 let reset = Output::new(
100 display_peripherals.gpio48,
101 Level::High,
102 OutputConfig::default().with_drive_mode(DriveMode::OpenDrain),
103 );
104
105 let mut display_delay = Delay::new();
106
107 let mut display: MyDisplay = Builder::new(ILI9342CRgb565, di)
109 .reset_pin(reset)
110 .display_size(320, 240)
111 .color_order(ColorOrder::Bgr)
112 .orientation(
113 mipidsi::options::Orientation::new()
114 .flip_vertical()
115 .flip_horizontal(),
116 )
117 .init(&mut display_delay)
119 .unwrap();
120
121 display.clear(Rgb565::BLACK).unwrap();
123
124 let mut backlight = Output::new(
126 display_peripherals.gpio47,
127 Level::High,
128 OutputConfig::default(),
129 );
130 backlight.set_high();
131
132 info!("Display initialized successfully");
133
134 Self {
135 display,
136 console_y: CONSOLE_INITIAL_Y,
137 }
138 }
139
140 pub fn display_mut(&mut self) -> &mut MyDisplay {
141 &mut self.display
142 }
143
144 pub fn console_println(&mut self, text: &str) {
145 Text::new(
146 text,
147 Point::new(CONSOLE_X, self.console_y),
148 MonoTextStyle::new(&FONT_8X13, Rgb565::WHITE),
149 )
150 .draw(&mut self.display)
151 .unwrap();
152 self.console_y += CONSOLE_LINE_HEIGHT;
153 }
154}