diff --git a/main/spi_lcd_touch_example_main.c b/main/spi_lcd_touch_example_main.c index cfea175..5ddca8f 100644 --- a/main/spi_lcd_touch_example_main.c +++ b/main/spi_lcd_touch_example_main.c @@ -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)); } diff --git a/sdkconfig.defaults b/sdkconfig.defaults index 78a142e..100a594 100644 --- a/sdkconfig.defaults +++ b/sdkconfig.defaults @@ -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