perf: optimize ST7789 LVGL touch responsiveness

This commit is contained in:
2026-07-13 18:49:05 +08:00
parent 6c537e99a2
commit 02950ea0aa
2 changed files with 40 additions and 71 deletions

View File

@@ -30,13 +30,13 @@
static const char *TAG = "lvgl_touch"; static const char *TAG = "lvgl_touch";
#define LCD_SPI_HOST SPI2_HOST #define LCD_SPI_HOST SPI2_HOST
#define EXAMPLE_LCD_PIXEL_CLOCK_HZ (10 * 1000 * 1000) #define EXAMPLE_LCD_PIXEL_CLOCK_HZ (40 * 1000 * 1000)
#define EXAMPLE_LCD_CMD_BITS 8 #define EXAMPLE_LCD_CMD_BITS 8
#define EXAMPLE_LCD_PARAM_BITS 8 #define EXAMPLE_LCD_PARAM_BITS 8
#define EXAMPLE_LVGL_TICK_PERIOD_MS 2 #define EXAMPLE_LVGL_TICK_PERIOD_MS 2
#define EXAMPLE_LVGL_BUFFER_LINES 80 #define EXAMPLE_LVGL_BUFFER_LINES 120
#define EXAMPLE_TOUCH_I2C_FREQ_HZ (100 * 1000) #define EXAMPLE_TOUCH_I2C_FREQ_HZ (400 * 1000)
#define EXAMPLE_TOUCH_LOG_PERIOD_MS 120 #define EXAMPLE_TOUCH_LOG_PERIOD_MS 500
#define EXAMPLE_TOUCH_PROBE_TIMEOUT_MS 30 #define EXAMPLE_TOUCH_PROBE_TIMEOUT_MS 30
// Current adapter wiring: // Current adapter wiring:
@@ -85,6 +85,12 @@ static bool notify_lvgl_flush_ready(esp_lcd_panel_io_handle_t panel_io, esp_lcd_
static void lvgl_flush_cb(lv_display_t *disp, const lv_area_t *area, uint8_t *px_map) static void lvgl_flush_cb(lv_display_t *disp, const lv_area_t *area, uint8_t *px_map)
{ {
size_t pixel_count = (size_t)(area->x2 - area->x1 + 1) * (area->y2 - area->y1 + 1);
// LVGL stores RGB565 pixels in the ESP32's native little-endian byte order,
// while this ST7789 panel expects the high byte on the SPI bus first.
lv_draw_sw_rgb565_swap(px_map, pixel_count);
esp_err_t ret = esp_lcd_panel_draw_bitmap(s_panel, area->x1, area->y1, area->x2 + 1, area->y2 + 1, px_map); esp_err_t ret = esp_lcd_panel_draw_bitmap(s_panel, area->x1, area->y1, area->x2 + 1, area->y2 + 1, px_map);
if (ret != ESP_OK) { if (ret != ESP_OK) {
ESP_LOGE(TAG, "LCD flush failed: %s", esp_err_to_name(ret)); ESP_LOGE(TAG, "LCD flush failed: %s", esp_err_to_name(ret));
@@ -159,10 +165,10 @@ static void lvgl_task(void *arg)
(void)arg; (void)arg;
while (1) { while (1) {
uint32_t delay_ms = lv_timer_handler(); uint32_t delay_ms = lv_timer_handler();
if (delay_ms < 2) { if (delay_ms < 1) {
delay_ms = 2; delay_ms = 1;
} else if (delay_ms > 8) { } else if (delay_ms > 5) {
delay_ms = 8; delay_ms = 5;
} }
vTaskDelay(pdMS_TO_TICKS(delay_ms)); vTaskDelay(pdMS_TO_TICKS(delay_ms));
} }
@@ -396,60 +402,11 @@ static esp_err_t init_i2c_bus(void)
return ESP_OK; return ESP_OK;
} }
static esp_err_t release_touch_reset_before_i2c(void) static void log_gt911_i2c_idle_levels(void)
{ {
gpio_config_t rst_gpio_config = { ESP_LOGI(TAG, "GT911 I2C idle levels: SCL(IO%d)=%d SDA(IO%d)=%d",
.mode = GPIO_MODE_OUTPUT, EXAMPLE_PIN_NUM_TOUCH_SCL, gpio_get_level(EXAMPLE_PIN_NUM_TOUCH_SCL),
.pin_bit_mask = 1ULL << EXAMPLE_PIN_NUM_TOUCH_RST, EXAMPLE_PIN_NUM_TOUCH_SDA, gpio_get_level(EXAMPLE_PIN_NUM_TOUCH_SDA));
};
ESP_LOGI(TAG, "Release GT911 reset on IO%d before I2C bus init", EXAMPLE_PIN_NUM_TOUCH_RST);
esp_err_t ret = gpio_config(&rst_gpio_config);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "GPIO%d configuration failed: %s (0x%x)", EXAMPLE_PIN_NUM_TOUCH_RST,
esp_err_to_name(ret), ret);
return ret;
}
ret = gpio_set_level(EXAMPLE_PIN_NUM_TOUCH_RST, 1);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "GPIO%d release failed: %s (0x%x)", EXAMPLE_PIN_NUM_TOUCH_RST,
esp_err_to_name(ret), ret);
return ret;
}
vTaskDelay(pdMS_TO_TICKS(120));
return ESP_OK;
}
static bool scan_i2c_bus_handle(i2c_master_bus_handle_t bus, const char *label, int scl, int sda)
{
bool found = false;
ESP_LOGI(TAG, "Scan I2C devices on %s: SCL=IO%d SDA=IO%d", label, scl, sda);
for (uint8_t addr = 0x08; addr < 0x78; addr++) {
esp_err_t ret = i2c_master_probe(bus, addr, 10);
if (ret == ESP_OK) {
ESP_LOGI(TAG, "I2C device found on %s at 0x%02x", label, addr);
found = true;
}
}
if (!found) {
ESP_LOGW(TAG, "No I2C device found on %s: SCL=IO%d SDA=IO%d", label, scl, sda);
}
return found;
}
static bool scan_i2c_bus(void)
{
bool found = scan_i2c_bus_handle(s_i2c_bus, "configured GT911 bus", EXAMPLE_PIN_NUM_TOUCH_SCL,
EXAMPLE_PIN_NUM_TOUCH_SDA);
if (!found) {
ESP_LOGW(TAG, "Check T_SCL/T_SDA wiring, touch power, common GND, and I2C pull-ups");
}
return found;
} }
static esp_err_t select_gt911_address(uint8_t dev_addr) static esp_err_t select_gt911_address(uint8_t dev_addr)
@@ -473,16 +430,23 @@ static esp_err_t select_gt911_address(uint8_t dev_addr)
ESP_RETURN_ON_ERROR(gpio_set_level(EXAMPLE_PIN_NUM_TOUCH_IRQ, 0), TAG, "drive GT911 INT low failed"); ESP_RETURN_ON_ERROR(gpio_set_level(EXAMPLE_PIN_NUM_TOUCH_IRQ, 0), TAG, "drive GT911 INT low failed");
vTaskDelay(pdMS_TO_TICKS(10)); vTaskDelay(pdMS_TO_TICKS(10));
ESP_RETURN_ON_ERROR(gpio_set_level(EXAMPLE_PIN_NUM_TOUCH_IRQ, int_level), TAG, "set GT911 address level failed"); ESP_RETURN_ON_ERROR(gpio_set_level(EXAMPLE_PIN_NUM_TOUCH_IRQ, int_level), TAG, "set GT911 address level failed");
vTaskDelay(pdMS_TO_TICKS(2)); vTaskDelay(pdMS_TO_TICKS(1));
ESP_RETURN_ON_ERROR(gpio_set_level(EXAMPLE_PIN_NUM_TOUCH_RST, 1), TAG, "release GT911 reset failed"); ESP_RETURN_ON_ERROR(gpio_set_level(EXAMPLE_PIN_NUM_TOUCH_RST, 1), TAG, "release GT911 reset failed");
vTaskDelay(pdMS_TO_TICKS(80)); vTaskDelay(pdMS_TO_TICKS(10));
ESP_RETURN_ON_ERROR(gpio_set_direction(EXAMPLE_PIN_NUM_TOUCH_IRQ, GPIO_MODE_INPUT), TAG,
"release GT911 INT failed");
ESP_RETURN_ON_ERROR(gpio_set_pull_mode(EXAMPLE_PIN_NUM_TOUCH_IRQ, GPIO_PULLUP_ONLY), TAG,
"enable GT911 INT pull-up failed");
vTaskDelay(pdMS_TO_TICKS(50));
return ESP_OK; return ESP_OK;
} }
static esp_err_t try_init_gt911_touch(uint8_t dev_addr) static esp_err_t try_init_gt911_touch(uint8_t dev_addr)
{ {
ESP_LOGI(TAG, "Initialize GT911 touch at I2C address 0x%02x", dev_addr); ESP_LOGI(TAG, "Initialize GT911 at 0x%02x with RST=IO%d INT=IO%d",
dev_addr, EXAMPLE_PIN_NUM_TOUCH_RST, EXAMPLE_PIN_NUM_TOUCH_IRQ);
ESP_RETURN_ON_ERROR(select_gt911_address(dev_addr), TAG, "select GT911 address failed"); ESP_RETURN_ON_ERROR(select_gt911_address(dev_addr), TAG, "select GT911 address failed");
log_gt911_i2c_idle_levels();
esp_err_t ret = i2c_master_probe(s_i2c_bus, dev_addr, EXAMPLE_TOUCH_PROBE_TIMEOUT_MS); esp_err_t ret = i2c_master_probe(s_i2c_bus, dev_addr, EXAMPLE_TOUCH_PROBE_TIMEOUT_MS);
if (ret != ESP_OK) { if (ret != ESP_OK) {
@@ -540,11 +504,13 @@ static esp_err_t init_gt911_touch(void)
static void init_touch_optional(void) static void init_touch_optional(void)
{ {
esp_err_t ret = release_touch_reset_before_i2c(); esp_err_t ret = init_i2c_bus();
if (ret == ESP_OK) {
ret = init_i2c_bus();
}
if (ret == ESP_OK) { if (ret == ESP_OK) {
esp_err_t reset_ret = i2c_master_bus_reset(s_i2c_bus);
if (reset_ret != ESP_OK) {
ESP_LOGW(TAG, "GT911 I2C bus recovery failed: %s", esp_err_to_name(reset_ret));
log_gt911_i2c_idle_levels();
}
ret = init_gt911_touch(); ret = init_gt911_touch();
} }
@@ -556,7 +522,8 @@ static void init_touch_optional(void)
ESP_LOGE(TAG, "GT911 is unavailable: %s. Continue with LCD only", esp_err_to_name(ret)); ESP_LOGE(TAG, "GT911 is unavailable: %s. Continue with LCD only", esp_err_to_name(ret));
s_touch = NULL; s_touch = NULL;
if (s_i2c_bus != NULL) { if (s_i2c_bus != NULL) {
scan_i2c_bus(); log_gt911_i2c_idle_levels();
ESP_LOGW(TAG, "Check T_SCL/T_SDA wiring, touch power, common GND, and I2C pull-ups");
} }
} }
@@ -613,6 +580,6 @@ void app_main(void)
ESP_ERROR_CHECK(init_spi_bus()); ESP_ERROR_CHECK(init_spi_bus());
ESP_ERROR_CHECK(init_st7789_panel(&panel_io)); ESP_ERROR_CHECK(init_st7789_panel(&panel_io));
ESP_ERROR_CHECK(init_display_buffer()); init_touch_optional();
ESP_ERROR_CHECK(display_standard_diagnostic()); ESP_ERROR_CHECK(init_lvgl(panel_io));
} }

View File

@@ -8,6 +8,8 @@ CONFIG_LV_FONT_MONTSERRAT_18=y
CONFIG_ESP_LCD_TOUCH_MAX_POINTS=5 CONFIG_ESP_LCD_TOUCH_MAX_POINTS=5
CONFIG_ESP_LCD_TOUCH_MAX_BUTTONS=0 CONFIG_ESP_LCD_TOUCH_MAX_BUTTONS=0
CONFIG_FREERTOS_HZ=1000 CONFIG_FREERTOS_HZ=1000
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
CONFIG_COMPILER_OPTIMIZATION_PERF=y
CONFIG_IDF_TARGET="esp32s3" CONFIG_IDF_TARGET="esp32s3"
CONFIG_EXAMPLE_LCD_CONTROLLER_ST7789=y CONFIG_EXAMPLE_LCD_CONTROLLER_ST7789=y
CONFIG_EXAMPLE_LCD_ST7735_H_RES=240 CONFIG_EXAMPLE_LCD_ST7735_H_RES=240