Skip to content

Commit 0ca7630

Browse files
committed
drive lcd
1 parent ec3fb0c commit 0ca7630

File tree

3 files changed

+176
-0
lines changed

3 files changed

+176
-0
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ experimental = ["esp-idf-svc/experimental"]
2626
log = "0.4"
2727
esp-idf-svc = "0.51"
2828

29+
embedded-graphics = "0.8.1"
30+
embedded-text = "0.7.2"
31+
u8g2-fonts = { version = "0.7.0", features = ["embedded_graphics_textstyle"] }
32+
2933
# --- Optional Embassy Integration ---
3034
# esp-idf-svc = { version = "0.51", features = ["critical-section", "embassy-time-driver", "embassy-sync"] }
3135

src/main.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ use esp_idf_svc::{
66
io::Read,
77
};
88

9+
mod ui;
10+
911
const SAMPLE_RATE: u32 = 16000;
1012

1113
static WAV_DATA: &[u8] = include_bytes!("../assets/hello.wav");
@@ -76,6 +78,10 @@ fn main() {
7678

7779
log::info!("Hello, world!");
7880

81+
ui::init_ui().unwrap();
82+
log::info!("UI initialized");
83+
ui::hello_lcd().unwrap();
84+
7985
let sck = peripherals.pins.gpio5;
8086
let din = peripherals.pins.gpio6;
8187
let ws = peripherals.pins.gpio4;

src/ui.rs

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
use embedded_graphics::prelude::*;
2+
use embedded_graphics::{
3+
draw_target::DrawTarget,
4+
framebuffer::{buffer_size, Framebuffer},
5+
pixelcolor::{raw::LittleEndian, Rgb565},
6+
prelude::Size,
7+
primitives::Rectangle,
8+
Drawable,
9+
};
10+
use embedded_text::TextBox;
11+
use esp_idf_svc::sys::EspError;
12+
use u8g2_fonts::U8g2TextStyle;
13+
14+
const DISPLAY_WIDTH: usize = 240;
15+
const DISPLAY_HEIGHT: usize = 240;
16+
pub type ColorFormat = Rgb565;
17+
18+
static mut ESP_LCD_PANEL_HANDLE: esp_idf_svc::sys::esp_lcd_panel_handle_t = std::ptr::null_mut();
19+
20+
fn init_spi() -> Result<(), EspError> {
21+
use esp_idf_svc::sys::*;
22+
const GPIO_NUM_NC: i32 = -1;
23+
const DISPLAY_MOSI_PIN: i32 = 47;
24+
const DISPLAY_CLK_PIN: i32 = 21;
25+
let mut buscfg = spi_bus_config_t::default();
26+
buscfg.__bindgen_anon_1.mosi_io_num = DISPLAY_MOSI_PIN;
27+
buscfg.__bindgen_anon_2.miso_io_num = GPIO_NUM_NC;
28+
buscfg.sclk_io_num = DISPLAY_CLK_PIN;
29+
buscfg.__bindgen_anon_3.quadwp_io_num = GPIO_NUM_NC;
30+
buscfg.__bindgen_anon_4.quadhd_io_num = GPIO_NUM_NC;
31+
buscfg.max_transfer_sz = (DISPLAY_WIDTH * DISPLAY_HEIGHT * std::mem::size_of::<u16>()) as i32;
32+
esp!(unsafe {
33+
spi_bus_initialize(
34+
spi_host_device_t_SPI3_HOST,
35+
&buscfg,
36+
spi_common_dma_t_SPI_DMA_CH_AUTO,
37+
)
38+
})
39+
}
40+
41+
fn init_lcd() -> Result<(), EspError> {
42+
use esp_idf_svc::sys::*;
43+
const DISPLAY_CS_PIN: i32 = 41;
44+
const DISPLAY_DC_PIN: i32 = 40;
45+
::log::info!("Install panel IO");
46+
let mut panel_io: esp_lcd_panel_io_handle_t = std::ptr::null_mut();
47+
let mut io_config = esp_lcd_panel_io_spi_config_t::default();
48+
io_config.cs_gpio_num = DISPLAY_CS_PIN;
49+
io_config.dc_gpio_num = DISPLAY_DC_PIN;
50+
io_config.spi_mode = 3;
51+
io_config.pclk_hz = 40 * 1000 * 1000;
52+
io_config.trans_queue_depth = 10;
53+
io_config.lcd_cmd_bits = 8;
54+
io_config.lcd_param_bits = 8;
55+
esp!(unsafe {
56+
esp_lcd_new_panel_io_spi(spi_host_device_t_SPI3_HOST as _, &io_config, &mut panel_io)
57+
})?;
58+
59+
::log::info!("Install LCD driver");
60+
const DISPLAY_RST_PIN: i32 = 45;
61+
let mut panel_config = esp_lcd_panel_dev_config_t::default();
62+
let mut panel: esp_lcd_panel_handle_t = std::ptr::null_mut();
63+
64+
panel_config.reset_gpio_num = DISPLAY_RST_PIN;
65+
panel_config.data_endian = lcd_rgb_data_endian_t_LCD_RGB_DATA_ENDIAN_LITTLE;
66+
panel_config.__bindgen_anon_1.rgb_ele_order = lcd_rgb_element_order_t_LCD_RGB_ELEMENT_ORDER_RGB;
67+
panel_config.bits_per_pixel = 16;
68+
69+
esp!(unsafe { esp_lcd_new_panel_st7789(panel_io, &panel_config, &mut panel) })?;
70+
unsafe { ESP_LCD_PANEL_HANDLE = panel };
71+
72+
const DISPLAY_MIRROR_X: bool = false;
73+
const DISPLAY_MIRROR_Y: bool = false;
74+
const DISPLAY_SWAP_XY: bool = false;
75+
const DISPLAY_INVERT_COLOR: bool = true;
76+
77+
::log::info!("Reset LCD panel");
78+
unsafe {
79+
esp!(esp_lcd_panel_reset(panel))?;
80+
esp!(esp_lcd_panel_init(panel))?;
81+
esp!(esp_lcd_panel_invert_color(panel, DISPLAY_INVERT_COLOR))?;
82+
esp!(esp_lcd_panel_swap_xy(panel, DISPLAY_SWAP_XY))?;
83+
esp!(esp_lcd_panel_mirror(
84+
panel,
85+
DISPLAY_MIRROR_X,
86+
DISPLAY_MIRROR_Y
87+
))?;
88+
esp!(esp_lcd_panel_disp_on_off(panel, true))?; /* 启动屏幕 */
89+
}
90+
91+
Ok(())
92+
}
93+
94+
#[inline(always)]
95+
fn get_esp_lcd_panel_handle() -> esp_idf_svc::sys::esp_lcd_panel_handle_t {
96+
unsafe { ESP_LCD_PANEL_HANDLE }
97+
}
98+
99+
pub fn flush_display(color_data: &[u8], x_start: i32, y_start: i32, x_end: i32, y_end: i32) -> i32 {
100+
unsafe {
101+
let e = esp_idf_svc::sys::esp_lcd_panel_draw_bitmap(
102+
get_esp_lcd_panel_handle(),
103+
x_start,
104+
y_start,
105+
x_end,
106+
y_end,
107+
color_data.as_ptr().cast(),
108+
);
109+
if e != 0 {
110+
log::warn!("flush_display error: {}", e);
111+
}
112+
e
113+
}
114+
}
115+
116+
pub fn init_ui() -> Result<(), EspError> {
117+
init_spi()?;
118+
init_lcd()?;
119+
Ok(())
120+
}
121+
122+
pub fn hello_lcd() -> Result<(), EspError> {
123+
let mut display = Box::new(Framebuffer::<
124+
ColorFormat,
125+
_,
126+
LittleEndian,
127+
DISPLAY_WIDTH,
128+
DISPLAY_HEIGHT,
129+
{ buffer_size::<ColorFormat>(DISPLAY_WIDTH, DISPLAY_HEIGHT) },
130+
>::new());
131+
display.clear(ColorFormat::WHITE).unwrap();
132+
133+
let text_area = Rectangle::new(
134+
display.bounding_box().top_left + Point { x: 0, y: 32 },
135+
Size::new(DISPLAY_WIDTH as u32, DISPLAY_HEIGHT as u32 - 32),
136+
);
137+
138+
let text = "Hello, ESP32!\n 请按下k0开始录音";
139+
140+
let textbox_style = embedded_text::style::TextBoxStyleBuilder::new()
141+
.height_mode(embedded_text::style::HeightMode::FitToText)
142+
.alignment(embedded_text::alignment::HorizontalAlignment::Center)
143+
.line_height(embedded_graphics::text::LineHeight::Percent(120))
144+
.paragraph_spacing(16)
145+
.build();
146+
let text_box = TextBox::with_textbox_style(
147+
&text,
148+
text_area,
149+
U8g2TextStyle::new(
150+
u8g2_fonts::fonts::u8g2_font_wqy12_t_gb2312a,
151+
ColorFormat::BLACK,
152+
),
153+
textbox_style,
154+
);
155+
text_box.draw(display.as_mut()).unwrap();
156+
157+
flush_display(
158+
display.data(),
159+
0,
160+
0,
161+
DISPLAY_WIDTH as _,
162+
DISPLAY_HEIGHT as _,
163+
);
164+
165+
Ok(())
166+
}

0 commit comments

Comments
 (0)