From c593bef24ef6044ab15f42982e1e16c6f04197a1 Mon Sep 17 00:00:00 2001 From: morris Date: Wed, 24 Jul 2024 18:52:02 +0800 Subject: [PATCH] change(lcd): simplify the i80 lcd example removed the lcd touch panel initialization code. For those touch panel driver usage, please check the esp_bsp repo. --- .../peripherals/lcd/i80_controller/README.md | 68 ++++------ .../lcd/i80_controller/main/Kconfig.projbuild | 35 ++--- .../main/i80_controller_example_main.c | 123 +----------------- .../lcd/i80_controller/main/idf_component.yml | 6 +- .../lcd/i80_controller/main/lvgl_demo_ui.c | 22 +--- .../lcd/i80_controller/sdkconfig.defaults | 1 + .../i80_controller/sdkconfig.defaults.esp32p4 | 3 + .../i80_controller/sdkconfig.defaults.esp32s3 | 3 +- 8 files changed, 43 insertions(+), 218 deletions(-) create mode 100644 examples/peripherals/lcd/i80_controller/sdkconfig.defaults.esp32p4 diff --git a/examples/peripherals/lcd/i80_controller/README.md b/examples/peripherals/lcd/i80_controller/README.md index 81f68ae419..f125c9f5c9 100644 --- a/examples/peripherals/lcd/i80_controller/README.md +++ b/examples/peripherals/lcd/i80_controller/README.md @@ -1,7 +1,7 @@ -| Supported Targets | ESP32 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -# LVGL porting example (based on i80 interfaced LCD controller) +# i80 LCD LVGL porting example LVGL is an open-source graphics library for creating modern GUIs. It has plenty of built-in graphical elements with low memory footprint, which is friendly for embedded GUI applications. @@ -29,34 +29,25 @@ The connection between ESP Board and the LCD is as follows: ```text ESP Board LCD Screen -┌─────────────┐ ┌────────────────┐ -│ │ │ │ -│ 3V3 ├─────────────►│ VCC │ -│ │ │ │ -│ GND ├──────────────┤ GND │ -│ │ │ │ -│ DATA[0..7] │◄────────────►│ DATA[0..7] │ -│ │ │ │ -│ PCLK ├─────────────►│ PCLK │ -│ │ │ │ -│ CS ├─────────────►│ CS │ -│ │ │ │ -│ D/C ├─────────────►│ D/C │ -│ │ │ │ -│ RST ├─────────────►│ RST │ -│ │ │ │ -│ BK_LIGHT ├─────────────►│ BCKL │ -│ │ │ │ -│ │ └────────────────┘ -│ │ LCD TOUCH -│ │ ┌────────────────┐ -│ │ │ │ -│ I2C SCL ├─────────────►│ I2C SCL │ -│ │ │ │ -│ I2C SDA │◄────────────►│ I2C SDA │ -│ │ │ │ -└─────────────┘ └────────────────┘ - ++-------------+ +----------------+ +| | | | +| 3V3 +------------->| VCC | +| | | | +| GND +--------------+ GND | +| | | | +| DATA[0..7] |<------------>| DATA[0..7] | +| | | | +| PCLK +------------->| PCLK | +| | | | +| CS +------------->| CS | +| | | | +| D/C +------------->| D/C | +| | | | +| RST +------------->| RST | +| | | | +| BK_LIGHT +------------->| BCKL | +| | | | ++-------------+ +----------------+ ``` The GPIO number used by this example can be changed in [i80_controller_example_main.c](main/i80_controller_example_main.c). @@ -69,9 +60,8 @@ Run `idf.py set-target ` to select one supported target that can ru Run `idf.py menuconfig` to open a terminal UI where you can tune specific configuration for this example in the `Example Configuration` menu. * `i80 LCD controller model`: Choose the LCD model to use by the example. If you choose `NT35510`, there will be another relevant configuration `NT35510 Data Width`, to choose the data line width for your NT35510 LCD module. - * `Allocate color data from PSRAM`: Select this option if you want to allocate the LVGL draw buffers from PSRAM. - +* `Pixel clock frequency (Hz)`: Set the pixel clock frequency for the LCD controller. * `LCD image source from`: Select where to load the image resource. See [Image Resource](#image-resource) for more details. Run `idf.py -p PORT build flash monitor` to build, flash and monitor the project. A fancy animation will show up on the LCD as expected. @@ -99,16 +89,6 @@ I (558) example: Starting LVGL task I (638) example: Display LVGL animation ``` -## Touch Screen Support - -This example supports touch screen connected via I2C. You can enable it by running `idf.py menuconfig` and navigating to `Example Configuration -> Enable LCD touch`. When touch is enabled, there will be a new button in the GUI that can restart the animation. - -These touch controllers are supported: - -* [GT911](https://github.com/espressif/esp-bsp/tree/master/components/lcd_touch/esp_lcd_touch_gt911) -* [TT21100](https://github.com/espressif/esp-bsp/tree/master/components/lcd_touch/esp_lcd_touch_tt21100) -* [FT5X06](https://github.com/espressif/esp-bsp/tree/master/components/lcd_touch/esp_lcd_touch_ft5x06) - ## Image Resource This example supports two ways of reading images @@ -120,6 +100,6 @@ This example supports two ways of reading images * Can't get a stable UI when `EXAMPLE_LCD_I80_COLOR_IN_PSRAM` is enabled. - This is because of the limited PSRAM bandwidth, compared to the internal SRAM. You can either decrease the PCLK clock `EXAMPLE_LCD_PIXEL_CLOCK_HZ` in [i80_controller_example_main.c](main/i80_controller_example_main.c) or increase the PSRAM working frequency `SPIRAM_SPEED` from the KConfig (e.g. **ESP32S3-Specific** -> **Set RAM clock speed**) or decrease the FPS in LVGL configuration. For illustration, this example has set the refresh period to 100ms in the default sdkconfig file. + This is because of the limited PSRAM bandwidth, compared to the internal SRAM. You can either decrease the PCLK clock `EXAMPLE_LCD_PIXEL_CLOCK_HZ` from the menuconfig or increase the PSRAM working frequency `SPIRAM_SPEED` from the KConfig (e.g. **ESP32S3-Specific** -> **Set RAM clock speed**) or decrease the FPS in LVGL configuration. For illustration, this example has set the refresh period to 100ms in the default sdkconfig file. For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. diff --git a/examples/peripherals/lcd/i80_controller/main/Kconfig.projbuild b/examples/peripherals/lcd/i80_controller/main/Kconfig.projbuild index cf4a5e392a..c88cc25017 100644 --- a/examples/peripherals/lcd/i80_controller/main/Kconfig.projbuild +++ b/examples/peripherals/lcd/i80_controller/main/Kconfig.projbuild @@ -2,11 +2,17 @@ menu "Example Configuration" config EXAMPLE_LCD_I80_COLOR_IN_PSRAM bool "Allocate color data from PSRAM" - depends on IDF_TARGET_ESP32S3 + depends on SOC_PSRAM_DMA_CAPABLE default y help - Enable this option if you wish to allocate the color buffer used by LVGL from PSRAM. - Unmatched PSRAM band width with LCD requirement can lead to blurred image display. + Enable this option if you want to allocate the LVGL draw buffer from PSRAM. + + config EXAMPLE_LCD_PIXEL_CLOCK_HZ + int "Pixel clock frequency (Hz)" + default 2000000 if EXAMPLE_LCD_I80_COLOR_IN_PSRAM && IDF_TARGET_ESP32S3 + default 10000000 + help + Set the pixel clock frequency in Hz. choice EXAMPLE_LCD_I80_CONTROLLER_MODEL prompt "i80 LCD controller model" @@ -45,29 +51,6 @@ menu "Example Configuration" default 16 if EXAMPLE_LCD_NT35510_DATA_WIDTH_16 default 8 - config EXAMPLE_LCD_TOUCH_ENABLED - bool "Enable LCD touch" - default n - help - Enable this option if you wish to use display touch. You can select from three touch controllers. - - choice EXAMPLE_LCD_TOUCH_CONTROLLER - prompt "LCD touch controller model" - depends on EXAMPLE_LCD_TOUCH_ENABLED - default EXAMPLE_LCD_TOUCH_CONTROLLER_FT5X06 - help - Select LCD touch controller model - - config EXAMPLE_LCD_TOUCH_CONTROLLER_GT911 - bool "GT911" - - config EXAMPLE_LCD_TOUCH_CONTROLLER_TT21100 - bool "TT21100" - - config EXAMPLE_LCD_TOUCH_CONTROLLER_FT5X06 - bool "FT5X06" - endchoice - choice EXAMPLE_LCD_IMAGE_SOURCE prompt "LCD image source from" default EXAMPLE_LCD_IMAGE_FROM_EMBEDDED_BINARY diff --git a/examples/peripherals/lcd/i80_controller/main/i80_controller_example_main.c b/examples/peripherals/lcd/i80_controller/main/i80_controller_example_main.c index 259dd4bcb5..84fa07c9e1 100644 --- a/examples/peripherals/lcd/i80_controller/main/i80_controller_example_main.c +++ b/examples/peripherals/lcd/i80_controller/main/i80_controller_example_main.c @@ -9,36 +9,21 @@ #include "freertos/task.h" #include "freertos/semphr.h" #include "esp_timer.h" -#include "esp_heap_caps.h" +#include "esp_err.h" +#include "esp_log.h" #include "esp_lcd_panel_io.h" #include "esp_lcd_panel_vendor.h" #include "esp_lcd_panel_ops.h" -#include "esp_lcd_touch.h" #include "esp_spiffs.h" #include "driver/gpio.h" -#include "driver/i2c.h" -#include "esp_err.h" -#include "esp_log.h" #include "lvgl.h" -#if CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_GT911 -#include "esp_lcd_touch_gt911.h" -#elif CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_TT21100 -#include "esp_lcd_touch_tt21100.h" -#elif CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_FT5X06 -#include "esp_lcd_touch_ft5x06.h" -#endif static const char *TAG = "example"; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////// Please update the following configuration according to your LCD spec ////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#if CONFIG_EXAMPLE_LCD_I80_COLOR_IN_PSRAM -// PCLK frequency can't go too high as the limitation of PSRAM bandwidth -#define EXAMPLE_LCD_PIXEL_CLOCK_HZ (2 * 1000 * 1000) -#else -#define EXAMPLE_LCD_PIXEL_CLOCK_HZ (10 * 1000 * 1000) -#endif // CONFIG_EXAMPLE_LCD_I80_COLOR_IN_PSRAM +#define EXAMPLE_LCD_PIXEL_CLOCK_HZ CONFIG_EXAMPLE_LCD_PIXEL_CLOCK_HZ #define EXAMPLE_LCD_BK_LIGHT_ON_LEVEL 1 #define EXAMPLE_LCD_BK_LIGHT_OFF_LEVEL !EXAMPLE_LCD_BK_LIGHT_ON_LEVEL @@ -81,12 +66,6 @@ static const char *TAG = "example"; #define EXAMPLE_LCD_PARAM_BITS 8 #endif -#if CONFIG_EXAMPLE_LCD_TOUCH_ENABLED -#define EXAMPLE_I2C_NUM 0 // I2C number -#define EXAMPLE_I2C_SCL 39 -#define EXAMPLE_I2C_SDA 40 -#endif - #define EXAMPLE_LVGL_TICK_PERIOD_MS 2 #define EXAMPLE_LVGL_TASK_MAX_DELAY_MS 500 #define EXAMPLE_LVGL_TASK_MIN_DELAY_MS 1 @@ -117,29 +96,6 @@ static void example_lvgl_flush_cb(lv_disp_drv_t *drv, const lv_area_t *area, lv_ esp_lcd_panel_draw_bitmap(panel_handle, offsetx1, offsety1, offsetx2 + 1, offsety2 + 1, color_map); } -#if CONFIG_EXAMPLE_LCD_TOUCH_ENABLED -static void example_lvgl_touch_cb(lv_indev_drv_t *drv, lv_indev_data_t *data) -{ - uint16_t touchpad_x[1] = {0}; - uint16_t touchpad_y[1] = {0}; - uint8_t touchpad_cnt = 0; - - /* Read touch controller data */ - esp_lcd_touch_read_data(drv->user_data); - - /* Get coordinates */ - bool touchpad_pressed = esp_lcd_touch_get_coordinates(drv->user_data, touchpad_x, touchpad_y, NULL, &touchpad_cnt, 1); - - if (touchpad_pressed && touchpad_cnt > 0) { - data->point.x = touchpad_x[0]; - data->point.y = touchpad_y[0]; - data->state = LV_INDEV_STATE_PRESSED; - } else { - data->state = LV_INDEV_STATE_RELEASED; - } -} -#endif - static void example_increase_lvgl_tick(void *arg) { /* Tell LVGL how many milliseconds has elapsed */ @@ -342,64 +298,6 @@ void example_init_lcd_panel(esp_lcd_panel_io_handle_t io_handle, esp_lcd_panel_h *panel = panel_handle; } -#if CONFIG_EXAMPLE_LCD_TOUCH_ENABLED -void example_init_lcd_touch(esp_lcd_touch_handle_t *tp_handle) -{ - esp_lcd_touch_handle_t tp = NULL; - esp_lcd_panel_io_handle_t tp_io_handle = NULL; - - const i2c_config_t i2c_conf = { - .mode = I2C_MODE_MASTER, - .sda_io_num = EXAMPLE_I2C_SDA, - .scl_io_num = EXAMPLE_I2C_SCL, - .sda_pullup_en = GPIO_PULLUP_ENABLE, - .scl_pullup_en = GPIO_PULLUP_ENABLE, - .master.clk_speed = 400000, - }; - /* Initialize I2C */ - ESP_ERROR_CHECK(i2c_param_config(EXAMPLE_I2C_NUM, &i2c_conf)); - ESP_ERROR_CHECK(i2c_driver_install(EXAMPLE_I2C_NUM, i2c_conf.mode, 0, 0, 0)); - -#if CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_GT911 - esp_lcd_panel_io_i2c_config_t tp_io_config = ESP_LCD_TOUCH_IO_I2C_GT911_CONFIG(); -#elif CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_TT21100 - esp_lcd_panel_io_i2c_config_t tp_io_config = ESP_LCD_TOUCH_IO_I2C_TT21100_CONFIG(); -#elif CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_FT5X06 - esp_lcd_panel_io_i2c_config_t tp_io_config = ESP_LCD_TOUCH_IO_I2C_FT5x06_CONFIG(); -#endif - - ESP_LOGI(TAG, "Initialize touch IO (I2C)"); - - /* Touch IO handle */ - ESP_ERROR_CHECK(esp_lcd_new_panel_io_i2c((esp_lcd_i2c_bus_handle_t)EXAMPLE_I2C_NUM, &tp_io_config, &tp_io_handle)); - - esp_lcd_touch_config_t tp_cfg = { - .x_max = EXAMPLE_LCD_V_RES, - .y_max = EXAMPLE_LCD_H_RES, - .rst_gpio_num = -1, - .int_gpio_num = -1, - .flags = { - .swap_xy = 1, - .mirror_x = 1, - .mirror_y = 0, - }, - }; - - /* Initialize touch */ -#if CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_GT911 - ESP_LOGI(TAG, "Initialize touch controller GT911"); - ESP_ERROR_CHECK(esp_lcd_touch_new_i2c_gt911(tp_io_handle, &tp_cfg, &tp)); -#elif CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_TT21100 - ESP_LOGI(TAG, "Initialize touch controller TT21100"); - ESP_ERROR_CHECK(esp_lcd_touch_new_i2c_tt21100(tp_io_handle, &tp_cfg, &tp)); -#elif CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_FT5X06 - ESP_LOGI(TAG, "Initialize touch controller FT5X06"); - ESP_ERROR_CHECK(esp_lcd_touch_new_i2c_ft5x06(tp_io_handle, &tp_cfg, &tp)); -#endif - *tp_handle = tp; -} -#endif // CONFIG_EXAMPLE_LCD_TOUCH_ENABLED - void app_main(void) { static lv_disp_draw_buf_t disp_buf; // contains internal graphic buffer(s) called draw buffer(s) @@ -425,11 +323,6 @@ void app_main(void) esp_lcd_panel_handle_t panel_handle = NULL; example_init_lcd_panel(io_handle, &panel_handle); -#if CONFIG_EXAMPLE_LCD_TOUCH_ENABLED - esp_lcd_touch_handle_t tp_handle = NULL; - example_init_lcd_touch(&tp_handle); -#endif // CONFIG_EXAMPLE_LCD_TOUCH_ENABLED - // Stub: user can flush pre-defined pattern to the screen before we turn on the screen or backlight ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_handle, true)); @@ -474,16 +367,6 @@ void app_main(void) ESP_ERROR_CHECK(esp_timer_create(&lvgl_tick_timer_args, &lvgl_tick_timer)); ESP_ERROR_CHECK(esp_timer_start_periodic(lvgl_tick_timer, EXAMPLE_LVGL_TICK_PERIOD_MS * 1000)); -#if CONFIG_EXAMPLE_LCD_TOUCH_ENABLED - static lv_indev_drv_t indev_drv; // Input device driver (Touch) - lv_indev_drv_init(&indev_drv); - indev_drv.type = LV_INDEV_TYPE_POINTER; - indev_drv.disp = disp; - indev_drv.read_cb = example_lvgl_touch_cb; - indev_drv.user_data = tp_handle; - lv_indev_drv_register(&indev_drv); -#endif // CONFIG_EXAMPLE_LCD_TOUCH_ENABLED - lvgl_mux = xSemaphoreCreateRecursiveMutex(); assert(lvgl_mux); ESP_LOGI(TAG, "Create LVGL task"); diff --git a/examples/peripherals/lcd/i80_controller/main/idf_component.yml b/examples/peripherals/lcd/i80_controller/main/idf_component.yml index feb5edc9c7..982d037d37 100644 --- a/examples/peripherals/lcd/i80_controller/main/idf_component.yml +++ b/examples/peripherals/lcd/i80_controller/main/idf_component.yml @@ -1,6 +1,2 @@ dependencies: - idf: ">=4.4" - lvgl/lvgl: "~8.3.0" - esp_lcd_touch_gt911: "^1.0" - esp_lcd_touch_tt21100: "^1.0" - esp_lcd_touch_ft5x06: "^1.0" + lvgl/lvgl: "~8.4.0" diff --git a/examples/peripherals/lcd/i80_controller/main/lvgl_demo_ui.c b/examples/peripherals/lcd/i80_controller/main/lvgl_demo_ui.c index ab5d9a57f3..8459e366d5 100644 --- a/examples/peripherals/lcd/i80_controller/main/lvgl_demo_ui.c +++ b/examples/peripherals/lcd/i80_controller/main/lvgl_demo_ui.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: CC0-1.0 */ @@ -24,7 +24,6 @@ typedef struct { } my_timer_context_t; static my_timer_context_t my_tim_ctx; -static lv_obj_t *btn; static lv_obj_t *arc[3]; static lv_obj_t *img_logo = NULL; static lv_obj_t *img_text = NULL; @@ -78,9 +77,6 @@ static void anim_timer_cb(lv_timer_t *timer) // Delete timer when all animation finished if ((count += 5) == 220) { lv_timer_del(timer); - - // Enable button - lv_obj_clear_state(btn, LV_STATE_DISABLED); } else { timer_ctx->count_val = count; } @@ -118,15 +114,6 @@ static void start_animation(lv_obj_t *scr) my_tim_ctx.count_val = -90; my_tim_ctx.scr = scr; lv_timer_create(anim_timer_cb, 20, &my_tim_ctx); - - // Disable button - lv_obj_add_state(btn, LV_STATE_DISABLED); -} - -static void btn_cb(lv_event_t *e) -{ - lv_obj_t *scr = lv_event_get_user_data(e); - start_animation(scr); } void example_lvgl_demo_ui(lv_disp_t *disp) @@ -140,13 +127,6 @@ void example_lvgl_demo_ui(lv_disp_t *disp) #elif CONFIG_EXAMPLE_LCD_IMAGE_FROM_EMBEDDED_BINARY lv_img_set_src(img_logo, &esp_logo); #endif - btn = lv_btn_create(scr); - lv_obj_t *lbl = lv_label_create(btn); - lv_label_set_text_static(lbl, LV_SYMBOL_REFRESH" SHOW AGAIN"); - lv_obj_set_style_text_font(lbl, &lv_font_montserrat_20, 0); - lv_obj_align(btn, LV_ALIGN_BOTTOM_LEFT, 30, -30); - // Button event - lv_obj_add_event_cb(btn, btn_cb, LV_EVENT_CLICKED, scr); start_animation(scr); } diff --git a/examples/peripherals/lcd/i80_controller/sdkconfig.defaults b/examples/peripherals/lcd/i80_controller/sdkconfig.defaults index 931fa4c551..f6df29ce55 100644 --- a/examples/peripherals/lcd/i80_controller/sdkconfig.defaults +++ b/examples/peripherals/lcd/i80_controller/sdkconfig.defaults @@ -5,3 +5,4 @@ CONFIG_LV_USE_USER_DATA=y CONFIG_LV_COLOR_16_SWAP=y CONFIG_LV_COLOR_DEPTH_16=y CONFIG_LV_FONT_MONTSERRAT_20=y +CONFIG_IDF_EXPERIMENTAL_FEATURES=y diff --git a/examples/peripherals/lcd/i80_controller/sdkconfig.defaults.esp32p4 b/examples/peripherals/lcd/i80_controller/sdkconfig.defaults.esp32p4 new file mode 100644 index 0000000000..702fac3342 --- /dev/null +++ b/examples/peripherals/lcd/i80_controller/sdkconfig.defaults.esp32p4 @@ -0,0 +1,3 @@ +CONFIG_SPIRAM=y +CONFIG_SPIRAM_MODE_HEX=y +CONFIG_SPIRAM_SPEED_200M=y diff --git a/examples/peripherals/lcd/i80_controller/sdkconfig.defaults.esp32s3 b/examples/peripherals/lcd/i80_controller/sdkconfig.defaults.esp32s3 index 2cfad7e522..41d6ae4a71 100644 --- a/examples/peripherals/lcd/i80_controller/sdkconfig.defaults.esp32s3 +++ b/examples/peripherals/lcd/i80_controller/sdkconfig.defaults.esp32s3 @@ -3,5 +3,4 @@ CONFIG_SPIRAM_SPEED_80M=y # Enabling the following configurations can help increase the PCLK frequency in the case when # the Frame Buffer is allocated from the PSRAM and fetched by EDMA -CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y -CONFIG_SPIRAM_RODATA=y +CONFIG_SPIRAM_XIP_FROM_PSRAM=y