perf: optimize ST7789 LVGL touch responsiveness
This commit is contained in:
@@ -30,13 +30,13 @@
|
||||
static const char *TAG = "lvgl_touch";
|
||||
|
||||
#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_PARAM_BITS 8
|
||||
#define EXAMPLE_LVGL_TICK_PERIOD_MS 2
|
||||
#define EXAMPLE_LVGL_BUFFER_LINES 80
|
||||
#define EXAMPLE_TOUCH_I2C_FREQ_HZ (100 * 1000)
|
||||
#define EXAMPLE_TOUCH_LOG_PERIOD_MS 120
|
||||
#define EXAMPLE_LVGL_BUFFER_LINES 120
|
||||
#define EXAMPLE_TOUCH_I2C_FREQ_HZ (400 * 1000)
|
||||
#define EXAMPLE_TOUCH_LOG_PERIOD_MS 500
|
||||
#define EXAMPLE_TOUCH_PROBE_TIMEOUT_MS 30
|
||||
|
||||
// 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)
|
||||
{
|
||||
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);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "LCD flush failed: %s", esp_err_to_name(ret));
|
||||
@@ -159,10 +165,10 @@ static void lvgl_task(void *arg)
|
||||
(void)arg;
|
||||
while (1) {
|
||||
uint32_t delay_ms = lv_timer_handler();
|
||||
if (delay_ms < 2) {
|
||||
delay_ms = 2;
|
||||
} else if (delay_ms > 8) {
|
||||
delay_ms = 8;
|
||||
if (delay_ms < 1) {
|
||||
delay_ms = 1;
|
||||
} else if (delay_ms > 5) {
|
||||
delay_ms = 5;
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(delay_ms));
|
||||
}
|
||||
@@ -396,60 +402,11 @@ static esp_err_t init_i2c_bus(void)
|
||||
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 = {
|
||||
.mode = GPIO_MODE_OUTPUT,
|
||||
.pin_bit_mask = 1ULL << EXAMPLE_PIN_NUM_TOUCH_RST,
|
||||
};
|
||||
|
||||
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;
|
||||
ESP_LOGI(TAG, "GT911 I2C idle levels: SCL(IO%d)=%d SDA(IO%d)=%d",
|
||||
EXAMPLE_PIN_NUM_TOUCH_SCL, gpio_get_level(EXAMPLE_PIN_NUM_TOUCH_SCL),
|
||||
EXAMPLE_PIN_NUM_TOUCH_SDA, gpio_get_level(EXAMPLE_PIN_NUM_TOUCH_SDA));
|
||||
}
|
||||
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
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;
|
||||
}
|
||||
|
||||
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");
|
||||
log_gt911_i2c_idle_levels();
|
||||
|
||||
esp_err_t ret = i2c_master_probe(s_i2c_bus, dev_addr, EXAMPLE_TOUCH_PROBE_TIMEOUT_MS);
|
||||
if (ret != ESP_OK) {
|
||||
@@ -540,11 +504,13 @@ static esp_err_t init_gt911_touch(void)
|
||||
|
||||
static void init_touch_optional(void)
|
||||
{
|
||||
esp_err_t ret = release_touch_reset_before_i2c();
|
||||
if (ret == ESP_OK) {
|
||||
ret = init_i2c_bus();
|
||||
}
|
||||
esp_err_t ret = init_i2c_bus();
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
s_touch = 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_st7789_panel(&panel_io));
|
||||
ESP_ERROR_CHECK(init_display_buffer());
|
||||
ESP_ERROR_CHECK(display_standard_diagnostic());
|
||||
init_touch_optional();
|
||||
ESP_ERROR_CHECK(init_lvgl(panel_io));
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ CONFIG_LV_FONT_MONTSERRAT_18=y
|
||||
CONFIG_ESP_LCD_TOUCH_MAX_POINTS=5
|
||||
CONFIG_ESP_LCD_TOUCH_MAX_BUTTONS=0
|
||||
CONFIG_FREERTOS_HZ=1000
|
||||
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_PERF=y
|
||||
CONFIG_IDF_TARGET="esp32s3"
|
||||
CONFIG_EXAMPLE_LCD_CONTROLLER_ST7789=y
|
||||
CONFIG_EXAMPLE_LCD_ST7735_H_RES=240
|
||||
|
||||
Reference in New Issue
Block a user