add some code

This commit is contained in:
2025-09-05 13:25:11 +08:00
parent 9ff0a99e7a
commit 3cf1229a85
8911 changed files with 2535396 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(i2c_oled)

View File

@@ -0,0 +1,73 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
# I2C OLED example
[esp_lcd](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/lcd.html) supports I2C interfaced OLED LCD, whose color depth is usually 1bpp.
This example shows how to make use of the SSD1306 panel driver from `esp_lcd` component to facilitate the porting of LVGL library. In the end, example will display a scrolling text on the OLED screen.
## LVGL Version
This example is using the **LVGL8** version. For use it with LVGL9 version, please delete file [sdkconfig.defaults](sdkconfig.defaults) and change version to `"^9"` on this line in [idf_component.yml](main/idf_component.yml) file:
```
lvgl/lvgl: "^8"
```
NOTE: When you are changing LVGL versions, please remove these files and folders before new build:
- build/
- managed_components/
- dependencies.lock
- sdkconfig
## How to use the example
### Hardware Required
* An ESP development board
* An SSD1306 OLED LCD, with I2C interface
* An USB cable for power supply and programming
### Hardware Connection
The connection between ESP Board and the LCD is as follows:
```
ESP Board OLED LCD (I2C)
+------------------+ +-------------------+
| GND+--------------+GND |
| | | |
| 3V3+--------------+VCC |
| | | |
| SDA+--------------+SDA |
| | | |
| SCL+--------------+SCL |
+------------------+ +-------------------+
```
The GPIO number used by this example can be changed in [lvgl_example_main.c](main/i2c_oled_example_main.c). Please pay attention to the I2C hardware device address as well, you should refer to your module's spec and schematic to determine that address.
### Build and Flash
Run `idf.py -p PORT build flash monitor` to build, flash and monitor the project. A scrolling text will show up on the LCD as expected.
The first time you run `idf.py` for the example will cost extra time as the build system needs to address the component dependencies and downloads the missing components from registry into `managed_components` folder.
(To exit the serial monitor, type ``Ctrl-]``.)
See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.
### Example Output
```bash
...
I (0) cpu_start: Starting scheduler on APP CPU.
I (345) example: Initialize I2C bus
I (345) example: Install panel IO
I (345) example: Install SSD1306 panel driver
I (455) example: Initialize LVGL library
I (455) example: Register display driver to LVGL
I (455) example: Install LVGL tick timer
I (455) example: Display LVGL Scroll Text
...
```

View File

@@ -0,0 +1,5 @@
idf_component_register(
SRCS "i2c_oled_example_main.c" "lvgl_demo_ui.c"
INCLUDE_DIRS "."
REQUIRES driver
)

View File

@@ -0,0 +1,35 @@
menu "Example Configuration"
choice EXAMPLE_LCD_CONTROLLER
prompt "LCD controller model"
default EXAMPLE_LCD_CONTROLLER_SSD1306
help
Select LCD controller model
config EXAMPLE_LCD_CONTROLLER_SSD1306
bool "SSD1306"
config EXAMPLE_LCD_CONTROLLER_SH1107
bool "SH1107"
endchoice
if EXAMPLE_LCD_CONTROLLER_SSD1306
choice EXAMPLE_SSD1306_HEIGHT
prompt "SSD1306 Height in pixels"
default EXAMPLE_SSD1306_HEIGHT_64
help
Height of the display in pixels. a.k.a vertical resolution
config EXAMPLE_SSD1306_HEIGHT_64
bool "64"
config EXAMPLE_SSD1306_HEIGHT_32
bool "32"
endchoice
config EXAMPLE_SSD1306_HEIGHT
int
default 64 if EXAMPLE_SSD1306_HEIGHT_64
default 32 if EXAMPLE_SSD1306_HEIGHT_32
endif
endmenu

View File

@@ -0,0 +1,155 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_timer.h"
#include "esp_lcd_panel_io.h"
#include "esp_lcd_panel_ops.h"
#include "driver/i2c_master.h"
#include "esp_err.h"
#include "esp_log.h"
#include "lvgl.h"
#include "esp_lvgl_port.h"
#if CONFIG_EXAMPLE_LCD_CONTROLLER_SH1107
#include "esp_lcd_sh1107.h"
#else
#include "esp_lcd_panel_vendor.h"
#endif
static const char *TAG = "example";
#define I2C_HOST 0
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////// Please update the following configuration according to your LCD spec //////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define EXAMPLE_LCD_PIXEL_CLOCK_HZ (400 * 1000)
#define EXAMPLE_PIN_NUM_SDA 18
#define EXAMPLE_PIN_NUM_SCL 23
#define EXAMPLE_PIN_NUM_RST -1
#define EXAMPLE_I2C_HW_ADDR 0x3C
// The pixel number in horizontal and vertical
#if CONFIG_EXAMPLE_LCD_CONTROLLER_SSD1306
#define EXAMPLE_LCD_H_RES 128
#define EXAMPLE_LCD_V_RES CONFIG_EXAMPLE_SSD1306_HEIGHT
#elif CONFIG_EXAMPLE_LCD_CONTROLLER_SH1107
#define EXAMPLE_LCD_H_RES 64
#define EXAMPLE_LCD_V_RES 128
#endif
// Bit number used to represent command and parameter
#define EXAMPLE_LCD_CMD_BITS 8
#define EXAMPLE_LCD_PARAM_BITS 8
extern void example_lvgl_demo_ui(lv_disp_t *disp);
void app_main(void)
{
ESP_LOGI(TAG, "Initialize I2C bus");
i2c_master_bus_handle_t i2c_bus = NULL;
i2c_master_bus_config_t bus_config = {
.clk_source = I2C_CLK_SRC_DEFAULT,
.glitch_ignore_cnt = 7,
.i2c_port = I2C_HOST,
.sda_io_num = EXAMPLE_PIN_NUM_SDA,
.scl_io_num = EXAMPLE_PIN_NUM_SCL,
.flags.enable_internal_pullup = true,
};
ESP_ERROR_CHECK(i2c_new_master_bus(&bus_config, &i2c_bus));
ESP_LOGI(TAG, "Install panel IO");
esp_lcd_panel_io_handle_t io_handle = NULL;
esp_lcd_panel_io_i2c_config_t io_config = {
.dev_addr = EXAMPLE_I2C_HW_ADDR,
.scl_speed_hz = EXAMPLE_LCD_PIXEL_CLOCK_HZ,
.control_phase_bytes = 1, // According to SSD1306 datasheet
.lcd_cmd_bits = EXAMPLE_LCD_CMD_BITS, // According to SSD1306 datasheet
.lcd_param_bits = EXAMPLE_LCD_PARAM_BITS, // According to SSD1306 datasheet
#if CONFIG_EXAMPLE_LCD_CONTROLLER_SSD1306
.dc_bit_offset = 6, // According to SSD1306 datasheet
#elif CONFIG_EXAMPLE_LCD_CONTROLLER_SH1107
.dc_bit_offset = 0, // According to SH1107 datasheet
.flags =
{
.disable_control_phase = 1,
}
#endif
};
ESP_ERROR_CHECK(esp_lcd_new_panel_io_i2c(i2c_bus, &io_config, &io_handle));
esp_lcd_panel_handle_t panel_handle = NULL;
esp_lcd_panel_dev_config_t panel_config = {
.bits_per_pixel = 1,
.reset_gpio_num = EXAMPLE_PIN_NUM_RST,
#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5,0,0))
.color_space = ESP_LCD_COLOR_SPACE_MONOCHROME,
#endif
};
#if CONFIG_EXAMPLE_LCD_CONTROLLER_SSD1306
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,3,0))
esp_lcd_panel_ssd1306_config_t ssd1306_config = {
.height = EXAMPLE_LCD_V_RES,
};
panel_config.vendor_config = &ssd1306_config;
#endif
ESP_LOGI(TAG, "Install SSD1306 panel driver");
ESP_ERROR_CHECK(esp_lcd_new_panel_ssd1306(io_handle, &panel_config, &panel_handle));
#elif CONFIG_EXAMPLE_LCD_CONTROLLER_SH1107
ESP_LOGI(TAG, "Install SH1107 panel driver");
ESP_ERROR_CHECK(esp_lcd_new_panel_sh1107(io_handle, &panel_config, &panel_handle));
#endif
ESP_ERROR_CHECK(esp_lcd_panel_reset(panel_handle));
ESP_ERROR_CHECK(esp_lcd_panel_init(panel_handle));
ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_handle, true));
#if CONFIG_EXAMPLE_LCD_CONTROLLER_SH1107
ESP_ERROR_CHECK(esp_lcd_panel_invert_color(panel_handle, true));
#endif
ESP_LOGI(TAG, "Initialize LVGL");
const lvgl_port_cfg_t lvgl_cfg = ESP_LVGL_PORT_INIT_CONFIG();
lvgl_port_init(&lvgl_cfg);
const lvgl_port_display_cfg_t disp_cfg = {
.io_handle = io_handle,
.panel_handle = panel_handle,
.buffer_size = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES,
.double_buffer = true,
.hres = EXAMPLE_LCD_H_RES,
.vres = EXAMPLE_LCD_V_RES,
.monochrome = true,
#if LVGL_VERSION_MAJOR >= 9
.color_format = LV_COLOR_FORMAT_RGB565,
#endif
.rotation = {
.swap_xy = false,
.mirror_x = false,
.mirror_y = false,
},
.flags = {
#if LVGL_VERSION_MAJOR >= 9
.swap_bytes = false,
#endif
.sw_rotate = false,
}
};
lv_disp_t *disp = lvgl_port_add_disp(&disp_cfg);
ESP_LOGI(TAG, "Display LVGL Scroll Text");
// Lock the mutex due to the LVGL APIs are not thread-safe
if (lvgl_port_lock(0)) {
/* Rotation of the screen */
lv_disp_set_rotation(disp, LV_DISPLAY_ROTATION_0);
example_lvgl_demo_ui(disp);
// Release the mutex
lvgl_port_unlock();
}
}

View File

@@ -0,0 +1,7 @@
dependencies:
idf: ">=4.4"
lvgl/lvgl: "^8"
esp_lcd_sh1107: "^1"
esp_lvgl_port:
version: "*"
override_path: "../../../"

View File

@@ -0,0 +1,22 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/
#include "lvgl.h"
void example_lvgl_demo_ui(lv_disp_t *disp)
{
lv_obj_t *scr = lv_disp_get_scr_act(disp);
lv_obj_t *label = lv_label_create(scr);
lv_label_set_long_mode(label, LV_LABEL_LONG_SCROLL_CIRCULAR); /* Circular scroll */
lv_label_set_text(label, "Hello Espressif, Hello LVGL.");
/* Size of the screen (if you use rotation 90 or 270, please set disp->driver->ver_res) */
#if LVGL_VERSION_MAJOR >= 9
lv_obj_set_width(label, lv_display_get_physical_horizontal_resolution(disp));
#else
lv_obj_set_width(label, disp->driver->hor_res);
#endif
lv_obj_align(label, LV_ALIGN_TOP_MID, 0, 0);
}

View File

@@ -0,0 +1,5 @@
# This file was generated using idf.py save-defconfig. It can be edited manually.
# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration
#
CONFIG_LV_USE_USER_DATA=y
CONFIG_LV_COLOR_DEPTH_1=y

View File

@@ -0,0 +1,9 @@
# The following lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
# "Trim" the build. Include the minimal set of components, main and anything it depends on.
set(COMPONENTS main)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(rgb_lcd)

View File

@@ -0,0 +1,19 @@
# ESP LVGL RGB Screen Example
Very simple example for demonstration of initialization and usage of the `esp_lvgl_port` component with RGB LCD. This example contains four main parts:
## 1. LCD HW initialization - `app_lcd_init()`
Standard HW initialization of the LCD using [`esp_lcd`](https://github.com/espressif/esp-idf/tree/master/components/esp_lcd) component. Settings of this example are fully compatible with [ESP32-S3-LCD-EV-Board-2](https://github.com/espressif/esp-bsp/tree/master/bsp/esp32_s3_lcd_ev_board) board.
## 2. Touch HW initialization - `app_touch_init()`
Standard HW initialization of the LCD touch using [`esp_lcd_touch`](https://github.com/espressif/esp-bsp/tree/master/components/lcd_touch/esp_lcd_touch) component. Settings of this example are fully compatible with [ESP32-S3-LCD-EV-Board-2](https://github.com/espressif/esp-bsp/tree/master/bsp/esp32_s3_lcd_ev_board) board.
## 3. LVGL port initialization - `app_lvgl_init()`
Initialization of the LVGL port.
## 4. LVGL objects example usage - `app_main_display()`
Very simple demonstration code of using LVGL objects after LVGL port initialization.

View File

@@ -0,0 +1,10 @@
idf_component_register(SRCS "main.c"
INCLUDE_DIRS "." ${LV_DEMO_DIR})
lvgl_port_create_c_image("images/esp_logo.png" "images/" "ARGB8888" "NONE")
lvgl_port_add_images(${COMPONENT_LIB} "images/")
set_source_files_properties(
PROPERTIES COMPILE_OPTIONS
"-DLV_LVGL_H_INCLUDE_SIMPLE;-Wno-format;"
)

View File

@@ -0,0 +1,8 @@
dependencies:
idf: ">=5.0"
esp_lcd_touch_gt1151:
version: "^1"
override_path: "../../../../lcd_touch/esp_lcd_touch_gt1151/"
esp_lvgl_port:
version: "*"
override_path: "../../../"

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

@@ -0,0 +1,312 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_err.h"
#include "esp_log.h"
#include "esp_check.h"
#include "driver/i2c.h"
#include "esp_lcd_panel_io.h"
#include "esp_lcd_panel_ops.h"
#include "esp_lcd_panel_rgb.h"
#include "esp_lvgl_port.h"
#include "lv_demos.h"
#include "esp_lcd_touch_gt1151.h"
/* LCD size */
#define EXAMPLE_LCD_H_RES (800)
#define EXAMPLE_LCD_V_RES (480)
/* LCD settings */
#define EXAMPLE_LCD_LVGL_FULL_REFRESH (0)
#define EXAMPLE_LCD_LVGL_DIRECT_MODE (1)
#define EXAMPLE_LCD_LVGL_AVOID_TEAR (1)
#define EXAMPLE_LCD_RGB_BOUNCE_BUFFER_MODE (1)
#define EXAMPLE_LCD_DRAW_BUFF_DOUBLE (0)
#define EXAMPLE_LCD_DRAW_BUFF_HEIGHT (100)
#define EXAMPLE_LCD_RGB_BUFFER_NUMS (2)
#define EXAMPLE_LCD_RGB_BOUNCE_BUFFER_HEIGHT (10)
/* LCD pins */
#define EXAMPLE_LCD_GPIO_VSYNC (GPIO_NUM_3)
#define EXAMPLE_LCD_GPIO_HSYNC (GPIO_NUM_46)
#define EXAMPLE_LCD_GPIO_DE (GPIO_NUM_17)
#define EXAMPLE_LCD_GPIO_PCLK (GPIO_NUM_9)
#define EXAMPLE_LCD_GPIO_DISP (GPIO_NUM_NC)
#define EXAMPLE_LCD_GPIO_DATA0 (GPIO_NUM_10)
#define EXAMPLE_LCD_GPIO_DATA1 (GPIO_NUM_11)
#define EXAMPLE_LCD_GPIO_DATA2 (GPIO_NUM_12)
#define EXAMPLE_LCD_GPIO_DATA3 (GPIO_NUM_13)
#define EXAMPLE_LCD_GPIO_DATA4 (GPIO_NUM_14)
#define EXAMPLE_LCD_GPIO_DATA5 (GPIO_NUM_21)
#define EXAMPLE_LCD_GPIO_DATA6 (GPIO_NUM_47)
#define EXAMPLE_LCD_GPIO_DATA7 (GPIO_NUM_48)
#define EXAMPLE_LCD_GPIO_DATA8 (GPIO_NUM_45)
#define EXAMPLE_LCD_GPIO_DATA9 (GPIO_NUM_38)
#define EXAMPLE_LCD_GPIO_DATA10 (GPIO_NUM_39)
#define EXAMPLE_LCD_GPIO_DATA11 (GPIO_NUM_40)
#define EXAMPLE_LCD_GPIO_DATA12 (GPIO_NUM_41)
#define EXAMPLE_LCD_GPIO_DATA13 (GPIO_NUM_42)
#define EXAMPLE_LCD_GPIO_DATA14 (GPIO_NUM_2)
#define EXAMPLE_LCD_GPIO_DATA15 (GPIO_NUM_1)
/* Touch settings */
#define EXAMPLE_TOUCH_I2C_NUM (0)
#define EXAMPLE_TOUCH_I2C_CLK_HZ (400000)
/* LCD touch pins */
#define EXAMPLE_TOUCH_I2C_SCL (GPIO_NUM_18)
#define EXAMPLE_TOUCH_I2C_SDA (GPIO_NUM_8)
#define EXAMPLE_LCD_PANEL_35HZ_RGB_TIMING() \
{ \
.pclk_hz = 18 * 1000 * 1000, \
.h_res = EXAMPLE_LCD_H_RES, \
.v_res = EXAMPLE_LCD_V_RES, \
.hsync_pulse_width = 40, \
.hsync_back_porch = 40, \
.hsync_front_porch = 48, \
.vsync_pulse_width = 23, \
.vsync_back_porch = 32, \
.vsync_front_porch = 13, \
.flags.pclk_active_neg = true, \
}
static const char *TAG = "EXAMPLE";
// LVGL image declare
LV_IMG_DECLARE(esp_logo)
/* LCD IO and panel */
static esp_lcd_panel_handle_t lcd_panel = NULL;
static esp_lcd_touch_handle_t touch_handle = NULL;
/* LVGL display and touch */
static lv_display_t *lvgl_disp = NULL;
static lv_indev_t *lvgl_touch_indev = NULL;
static esp_err_t app_lcd_init(void)
{
esp_err_t ret = ESP_OK;
/* LCD initialization */
ESP_LOGI(TAG, "Initialize RGB panel");
esp_lcd_rgb_panel_config_t panel_conf = {
.clk_src = LCD_CLK_SRC_PLL160M,
.psram_trans_align = 64,
.data_width = 16,
.bits_per_pixel = 16,
.de_gpio_num = EXAMPLE_LCD_GPIO_DE,
.pclk_gpio_num = EXAMPLE_LCD_GPIO_PCLK,
.vsync_gpio_num = EXAMPLE_LCD_GPIO_VSYNC,
.hsync_gpio_num = EXAMPLE_LCD_GPIO_HSYNC,
.disp_gpio_num = EXAMPLE_LCD_GPIO_DISP,
.data_gpio_nums = {
EXAMPLE_LCD_GPIO_DATA0,
EXAMPLE_LCD_GPIO_DATA1,
EXAMPLE_LCD_GPIO_DATA2,
EXAMPLE_LCD_GPIO_DATA3,
EXAMPLE_LCD_GPIO_DATA4,
EXAMPLE_LCD_GPIO_DATA5,
EXAMPLE_LCD_GPIO_DATA6,
EXAMPLE_LCD_GPIO_DATA7,
EXAMPLE_LCD_GPIO_DATA8,
EXAMPLE_LCD_GPIO_DATA9,
EXAMPLE_LCD_GPIO_DATA10,
EXAMPLE_LCD_GPIO_DATA11,
EXAMPLE_LCD_GPIO_DATA12,
EXAMPLE_LCD_GPIO_DATA13,
EXAMPLE_LCD_GPIO_DATA14,
EXAMPLE_LCD_GPIO_DATA15,
},
.timings = EXAMPLE_LCD_PANEL_35HZ_RGB_TIMING(),
.flags.fb_in_psram = 1,
.num_fbs = EXAMPLE_LCD_RGB_BUFFER_NUMS,
#if EXAMPLE_LCD_RGB_BOUNCE_BUFFER_MODE
.bounce_buffer_size_px = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_RGB_BOUNCE_BUFFER_HEIGHT,
#endif
};
ESP_GOTO_ON_ERROR(esp_lcd_new_rgb_panel(&panel_conf, &lcd_panel), err, TAG, "RGB init failed");
ESP_GOTO_ON_ERROR(esp_lcd_panel_init(lcd_panel), err, TAG, "LCD init failed");
return ret;
err:
if (lcd_panel) {
esp_lcd_panel_del(lcd_panel);
}
return ret;
}
static esp_err_t app_touch_init(void)
{
/* Initilize I2C */
const i2c_config_t i2c_conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = EXAMPLE_TOUCH_I2C_SDA,
.sda_pullup_en = GPIO_PULLUP_DISABLE,
.scl_io_num = EXAMPLE_TOUCH_I2C_SCL,
.scl_pullup_en = GPIO_PULLUP_DISABLE,
.master.clk_speed = EXAMPLE_TOUCH_I2C_CLK_HZ
};
ESP_RETURN_ON_ERROR(i2c_param_config(EXAMPLE_TOUCH_I2C_NUM, &i2c_conf), TAG, "I2C configuration failed");
ESP_RETURN_ON_ERROR(i2c_driver_install(EXAMPLE_TOUCH_I2C_NUM, i2c_conf.mode, 0, 0, 0), TAG, "I2C initialization failed");
/* Initialize touch HW */
const esp_lcd_touch_config_t tp_cfg = {
.x_max = EXAMPLE_LCD_H_RES,
.y_max = EXAMPLE_LCD_V_RES,
.rst_gpio_num = GPIO_NUM_NC,
.int_gpio_num = GPIO_NUM_NC,
.levels = {
.reset = 0,
.interrupt = 0,
},
.flags = {
.swap_xy = 0,
.mirror_x = 0,
.mirror_y = 0,
},
};
esp_lcd_panel_io_handle_t tp_io_handle = NULL;
const esp_lcd_panel_io_i2c_config_t tp_io_config = ESP_LCD_TOUCH_IO_I2C_GT1151_CONFIG();
ESP_RETURN_ON_ERROR(esp_lcd_new_panel_io_i2c((esp_lcd_i2c_bus_handle_t)EXAMPLE_TOUCH_I2C_NUM, &tp_io_config, &tp_io_handle), TAG, "");
return esp_lcd_touch_new_i2c_gt1151(tp_io_handle, &tp_cfg, &touch_handle);
}
static esp_err_t app_lvgl_init(void)
{
/* Initialize LVGL */
const lvgl_port_cfg_t lvgl_cfg = {
.task_priority = 4, /* LVGL task priority */
.task_stack = 6144, /* LVGL task stack size */
.task_affinity = -1, /* LVGL task pinned to core (-1 is no affinity) */
.task_max_sleep_ms = 500, /* Maximum sleep in LVGL task */
.timer_period_ms = 5 /* LVGL timer tick period in ms */
};
ESP_RETURN_ON_ERROR(lvgl_port_init(&lvgl_cfg), TAG, "LVGL port initialization failed");
uint32_t buff_size = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_DRAW_BUFF_HEIGHT;
#if EXAMPLE_LCD_LVGL_FULL_REFRESH || EXAMPLE_LCD_LVGL_DIRECT_MODE
buff_size = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES;
#endif
/* Add LCD screen */
ESP_LOGD(TAG, "Add LCD screen");
const lvgl_port_display_cfg_t disp_cfg = {
.panel_handle = lcd_panel,
.buffer_size = buff_size,
.double_buffer = EXAMPLE_LCD_DRAW_BUFF_DOUBLE,
.hres = EXAMPLE_LCD_H_RES,
.vres = EXAMPLE_LCD_V_RES,
.monochrome = false,
#if LVGL_VERSION_MAJOR >= 9
.color_format = LV_COLOR_FORMAT_RGB565,
#endif
.rotation = {
.swap_xy = false,
.mirror_x = false,
.mirror_y = false,
},
.flags = {
.buff_dma = false,
.buff_spiram = false,
#if EXAMPLE_LCD_LVGL_FULL_REFRESH
.full_refresh = true,
#elif EXAMPLE_LCD_LVGL_DIRECT_MODE
.direct_mode = true,
#endif
#if LVGL_VERSION_MAJOR >= 9
.swap_bytes = false,
#endif
}
};
const lvgl_port_display_rgb_cfg_t rgb_cfg = {
.flags = {
#if EXAMPLE_LCD_RGB_BOUNCE_BUFFER_MODE
.bb_mode = true,
#else
.bb_mode = false,
#endif
#if EXAMPLE_LCD_LVGL_AVOID_TEAR
.avoid_tearing = true,
#else
.avoid_tearing = false,
#endif
}
};
lvgl_disp = lvgl_port_add_disp_rgb(&disp_cfg, &rgb_cfg);
/* Add touch input (for selected screen) */
const lvgl_port_touch_cfg_t touch_cfg = {
.disp = lvgl_disp,
.handle = touch_handle,
};
lvgl_touch_indev = lvgl_port_add_touch(&touch_cfg);
return ESP_OK;
}
static void _app_button_cb(lv_event_t *e)
{
lv_disp_rotation_t rotation = lv_disp_get_rotation(lvgl_disp);
rotation++;
if (rotation > LV_DISPLAY_ROTATION_270) {
rotation = LV_DISPLAY_ROTATION_0;
}
/* LCD HW rotation */
lv_disp_set_rotation(lvgl_disp, rotation);
}
static void app_main_display(void)
{
lv_obj_t *scr = lv_scr_act();
/* Your LVGL objects code here .... */
/* Create image */
lv_obj_t *img_logo = lv_img_create(scr);
lv_img_set_src(img_logo, &esp_logo);
lv_obj_align(img_logo, LV_ALIGN_TOP_MID, 0, 20);
/* Label */
lv_obj_t *label = lv_label_create(scr);
lv_obj_set_width(label, EXAMPLE_LCD_H_RES);
lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0);
#if LVGL_VERSION_MAJOR == 8
lv_label_set_recolor(label, true);
lv_label_set_text(label, "#FF0000 "LV_SYMBOL_BELL" Hello world Espressif and LVGL "LV_SYMBOL_BELL"#\n#FF9400 "LV_SYMBOL_WARNING" For simplier initialization, use BSP "LV_SYMBOL_WARNING" #");
#else
lv_label_set_text(label, LV_SYMBOL_BELL" Hello world Espressif and LVGL "LV_SYMBOL_BELL"\n "LV_SYMBOL_WARNING" For simplier initialization, use BSP "LV_SYMBOL_WARNING);
#endif
lv_obj_align(label, LV_ALIGN_CENTER, 0, 20);
/* Button */
lv_obj_t *btn = lv_btn_create(scr);
label = lv_label_create(btn);
lv_label_set_text_static(label, "Rotate screen");
lv_obj_align(btn, LV_ALIGN_BOTTOM_MID, 0, -30);
lv_obj_add_event_cb(btn, _app_button_cb, LV_EVENT_CLICKED, NULL);
}
void app_main(void)
{
/* LCD HW initialization */
ESP_ERROR_CHECK(app_lcd_init());
/* Touch initialization */
ESP_ERROR_CHECK(app_touch_init());
/* LVGL initialization */
ESP_ERROR_CHECK(app_lvgl_init());
/* Show LVGL objects */
lvgl_port_lock(0);
//app_main_display();
lv_demo_music();
lvgl_port_unlock();
}

View File

@@ -0,0 +1,5 @@
# Name, Type, SubType, Offset, Size, Flags
# Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild
nvs, data, nvs, 0x9000, 0x6000,
phy_init, data, phy, 0xf000, 0x1000,
factory, app, factory, 0x10000, 2M,
1 # Name, Type, SubType, Offset, Size, Flags
2 # Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild
3 nvs, data, nvs, 0x9000, 0x6000,
4 phy_init, data, phy, 0xf000, 0x1000,
5 factory, app, factory, 0x10000, 2M,

View File

@@ -0,0 +1,40 @@
CONFIG_IDF_TARGET="esp32s3"
CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_COMPILER_OPTIMIZATION_PERF=y
CONFIG_SPIRAM=y
CONFIG_SPIRAM_MODE_OCT=y
CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y
CONFIG_SPIRAM_RODATA=y
CONFIG_SPIRAM_SPEED_80M=y
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
CONFIG_ESP32S3_DATA_CACHE_LINE_64B=y
CONFIG_FREERTOS_HZ=1000
CONFIG_LV_MEM_CUSTOM=y
CONFIG_LV_MEMCPY_MEMSET_STD=y
CONFIG_LV_ATTRIBUTE_FAST_MEM_USE_IRAM=y
CONFIG_LV_FONT_MONTSERRAT_12=y
CONFIG_LV_FONT_MONTSERRAT_16=y
CONFIG_LV_USE_DEMO_WIDGETS=y
CONFIG_LV_USE_DEMO_BENCHMARK=y
CONFIG_LV_USE_DEMO_STRESS=y
CONFIG_LV_USE_DEMO_MUSIC=y
CONFIG_LV_DEMO_MUSIC_AUTO_PLAY=y
## LVGL8 ##
CONFIG_LV_MEM_SIZE_KILOBYTES=48
CONFIG_LV_USE_PERF_MONITOR=y
## LVGL9 ##
CONFIG_LV_CONF_SKIP=y
#CLIB default
CONFIG_LV_USE_CLIB_MALLOC=y
CONFIG_LV_USE_CLIB_SPRINTF=y
CONFIG_LV_USE_CLIB_STRING=y
# Performance monitor
CONFIG_LV_USE_OBSERVER=y
CONFIG_LV_USE_SYSMON=y
CONFIG_LV_USE_PERF_MONITOR=y

View File

@@ -0,0 +1,9 @@
# The following lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
# "Trim" the build. Include the minimal set of components, main and anything it depends on.
set(COMPONENTS main)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(touchscreen)

View File

@@ -0,0 +1,19 @@
# ESP LVGL Touch Screen Example
Very simple example for demonstration of initialization and usage of the `esp_lvgl_port` component. This example contains four main parts:
## 1. LCD HW initialization - `app_lcd_init()`
Standard HW initialization of the LCD using [`esp_lcd`](https://github.com/espressif/esp-idf/tree/master/components/esp_lcd) component. Settings of this example are fully compatible with [ESP-BOX](https://github.com/espressif/esp-bsp/tree/master/esp-box) board.
## 2. Touch HW initialization - `app_touch_init()`
Standard HW initialization of the LCD touch using [`esp_lcd_touch`](https://github.com/espressif/esp-bsp/tree/master/components/lcd_touch/esp_lcd_touch) component. Settings of this example are fully compatible with [ESP-BOX](https://github.com/espressif/esp-bsp/tree/master/esp-box) board.
## 3. LVGL port initialization - `app_lvgl_init()`
Initialization of the LVGL port.
## 4. LVGL objects example usage - `app_main_display()`
Very simple demonstration code of using LVGL objects after LVGL port initialization.

View File

@@ -0,0 +1,5 @@
idf_component_register(SRCS "main.c"
INCLUDE_DIRS ".")
lvgl_port_create_c_image("images/esp_logo.png" "images/" "ARGB8888" "NONE")
lvgl_port_add_images(${COMPONENT_LIB} "images/")

View File

@@ -0,0 +1,8 @@
dependencies:
idf: ">=4.4"
esp_lcd_touch_tt21100:
version: "^1"
override_path: "../../../../lcd_touch/esp_lcd_touch_tt21100/"
esp_lvgl_port:
version: "*"
override_path: "../../../"

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

@@ -0,0 +1,277 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_err.h"
#include "esp_log.h"
#include "esp_check.h"
#include "driver/i2c.h"
#include "driver/gpio.h"
#include "driver/spi_master.h"
#include "esp_lcd_panel_io.h"
#include "esp_lcd_panel_vendor.h"
#include "esp_lcd_panel_ops.h"
#include "esp_lvgl_port.h"
#include "esp_lcd_touch_tt21100.h"
/* LCD size */
#define EXAMPLE_LCD_H_RES (320)
#define EXAMPLE_LCD_V_RES (240)
/* LCD settings */
#define EXAMPLE_LCD_SPI_NUM (SPI3_HOST)
#define EXAMPLE_LCD_PIXEL_CLK_HZ (40 * 1000 * 1000)
#define EXAMPLE_LCD_CMD_BITS (8)
#define EXAMPLE_LCD_PARAM_BITS (8)
#define EXAMPLE_LCD_COLOR_SPACE (ESP_LCD_COLOR_SPACE_BGR)
#define EXAMPLE_LCD_BITS_PER_PIXEL (16)
#define EXAMPLE_LCD_DRAW_BUFF_DOUBLE (1)
#define EXAMPLE_LCD_DRAW_BUFF_HEIGHT (50)
#define EXAMPLE_LCD_BL_ON_LEVEL (1)
/* LCD pins */
#define EXAMPLE_LCD_GPIO_SCLK (GPIO_NUM_7)
#define EXAMPLE_LCD_GPIO_MOSI (GPIO_NUM_6)
#define EXAMPLE_LCD_GPIO_RST (GPIO_NUM_48)
#define EXAMPLE_LCD_GPIO_DC (GPIO_NUM_4)
#define EXAMPLE_LCD_GPIO_CS (GPIO_NUM_5)
#define EXAMPLE_LCD_GPIO_BL (GPIO_NUM_45)
/* Touch settings */
#define EXAMPLE_TOUCH_I2C_NUM (0)
#define EXAMPLE_TOUCH_I2C_CLK_HZ (400000)
/* LCD touch pins */
#define EXAMPLE_TOUCH_I2C_SCL (GPIO_NUM_18)
#define EXAMPLE_TOUCH_I2C_SDA (GPIO_NUM_8)
#define EXAMPLE_TOUCH_GPIO_INT (GPIO_NUM_3)
static const char *TAG = "EXAMPLE";
// LVGL image declare
LV_IMG_DECLARE(esp_logo)
/* LCD IO and panel */
static esp_lcd_panel_io_handle_t lcd_io = NULL;
static esp_lcd_panel_handle_t lcd_panel = NULL;
static esp_lcd_touch_handle_t touch_handle = NULL;
/* LVGL display and touch */
static lv_display_t *lvgl_disp = NULL;
static lv_indev_t *lvgl_touch_indev = NULL;
static esp_err_t app_lcd_init(void)
{
esp_err_t ret = ESP_OK;
/* LCD backlight */
gpio_config_t bk_gpio_config = {
.mode = GPIO_MODE_OUTPUT,
.pin_bit_mask = 1ULL << EXAMPLE_LCD_GPIO_BL
};
ESP_ERROR_CHECK(gpio_config(&bk_gpio_config));
/* LCD initialization */
ESP_LOGD(TAG, "Initialize SPI bus");
const spi_bus_config_t buscfg = {
.sclk_io_num = EXAMPLE_LCD_GPIO_SCLK,
.mosi_io_num = EXAMPLE_LCD_GPIO_MOSI,
.miso_io_num = GPIO_NUM_NC,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.max_transfer_sz = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_DRAW_BUFF_HEIGHT * sizeof(uint16_t),
};
ESP_RETURN_ON_ERROR(spi_bus_initialize(EXAMPLE_LCD_SPI_NUM, &buscfg, SPI_DMA_CH_AUTO), TAG, "SPI init failed");
ESP_LOGD(TAG, "Install panel IO");
const esp_lcd_panel_io_spi_config_t io_config = {
.dc_gpio_num = EXAMPLE_LCD_GPIO_DC,
.cs_gpio_num = EXAMPLE_LCD_GPIO_CS,
.pclk_hz = EXAMPLE_LCD_PIXEL_CLK_HZ,
.lcd_cmd_bits = EXAMPLE_LCD_CMD_BITS,
.lcd_param_bits = EXAMPLE_LCD_PARAM_BITS,
.spi_mode = 0,
.trans_queue_depth = 10,
};
ESP_GOTO_ON_ERROR(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)EXAMPLE_LCD_SPI_NUM, &io_config, &lcd_io), err, TAG, "New panel IO failed");
ESP_LOGD(TAG, "Install LCD driver");
const esp_lcd_panel_dev_config_t panel_config = {
.reset_gpio_num = EXAMPLE_LCD_GPIO_RST,
.color_space = EXAMPLE_LCD_COLOR_SPACE,
.bits_per_pixel = EXAMPLE_LCD_BITS_PER_PIXEL,
};
ESP_GOTO_ON_ERROR(esp_lcd_new_panel_st7789(lcd_io, &panel_config, &lcd_panel), err, TAG, "New panel failed");
esp_lcd_panel_reset(lcd_panel);
esp_lcd_panel_init(lcd_panel);
esp_lcd_panel_mirror(lcd_panel, true, true);
esp_lcd_panel_disp_on_off(lcd_panel, true);
/* LCD backlight on */
ESP_ERROR_CHECK(gpio_set_level(EXAMPLE_LCD_GPIO_BL, EXAMPLE_LCD_BL_ON_LEVEL));
return ret;
err:
if (lcd_panel) {
esp_lcd_panel_del(lcd_panel);
}
if (lcd_io) {
esp_lcd_panel_io_del(lcd_io);
}
spi_bus_free(EXAMPLE_LCD_SPI_NUM);
return ret;
}
static esp_err_t app_touch_init(void)
{
/* Initilize I2C */
const i2c_config_t i2c_conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = EXAMPLE_TOUCH_I2C_SDA,
.sda_pullup_en = GPIO_PULLUP_DISABLE,
.scl_io_num = EXAMPLE_TOUCH_I2C_SCL,
.scl_pullup_en = GPIO_PULLUP_DISABLE,
.master.clk_speed = EXAMPLE_TOUCH_I2C_CLK_HZ
};
ESP_RETURN_ON_ERROR(i2c_param_config(EXAMPLE_TOUCH_I2C_NUM, &i2c_conf), TAG, "I2C configuration failed");
ESP_RETURN_ON_ERROR(i2c_driver_install(EXAMPLE_TOUCH_I2C_NUM, i2c_conf.mode, 0, 0, 0), TAG, "I2C initialization failed");
/* Initialize touch HW */
const esp_lcd_touch_config_t tp_cfg = {
.x_max = EXAMPLE_LCD_H_RES,
.y_max = EXAMPLE_LCD_V_RES,
.rst_gpio_num = GPIO_NUM_NC, // Shared with LCD reset
.int_gpio_num = EXAMPLE_TOUCH_GPIO_INT,
.levels = {
.reset = 0,
.interrupt = 0,
},
.flags = {
.swap_xy = 0,
.mirror_x = 1,
.mirror_y = 0,
},
};
esp_lcd_panel_io_handle_t tp_io_handle = NULL;
const esp_lcd_panel_io_i2c_config_t tp_io_config = ESP_LCD_TOUCH_IO_I2C_TT21100_CONFIG();
ESP_RETURN_ON_ERROR(esp_lcd_new_panel_io_i2c((esp_lcd_i2c_bus_handle_t)EXAMPLE_TOUCH_I2C_NUM, &tp_io_config, &tp_io_handle), TAG, "");
return esp_lcd_touch_new_i2c_tt21100(tp_io_handle, &tp_cfg, &touch_handle);
}
static esp_err_t app_lvgl_init(void)
{
/* Initialize LVGL */
const lvgl_port_cfg_t lvgl_cfg = {
.task_priority = 4, /* LVGL task priority */
.task_stack = 4096, /* LVGL task stack size */
.task_affinity = -1, /* LVGL task pinned to core (-1 is no affinity) */
.task_max_sleep_ms = 500, /* Maximum sleep in LVGL task */
.timer_period_ms = 5 /* LVGL timer tick period in ms */
};
ESP_RETURN_ON_ERROR(lvgl_port_init(&lvgl_cfg), TAG, "LVGL port initialization failed");
/* Add LCD screen */
ESP_LOGD(TAG, "Add LCD screen");
const lvgl_port_display_cfg_t disp_cfg = {
.io_handle = lcd_io,
.panel_handle = lcd_panel,
.buffer_size = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_DRAW_BUFF_HEIGHT,
.double_buffer = EXAMPLE_LCD_DRAW_BUFF_DOUBLE,
.hres = EXAMPLE_LCD_H_RES,
.vres = EXAMPLE_LCD_V_RES,
.monochrome = false,
#if LVGL_VERSION_MAJOR >= 9
.color_format = LV_COLOR_FORMAT_RGB565,
#endif
.rotation = {
.swap_xy = false,
.mirror_x = true,
.mirror_y = true,
},
.flags = {
.buff_dma = true,
#if LVGL_VERSION_MAJOR >= 9
.swap_bytes = true,
#endif
}
};
lvgl_disp = lvgl_port_add_disp(&disp_cfg);
/* Add touch input (for selected screen) */
const lvgl_port_touch_cfg_t touch_cfg = {
.disp = lvgl_disp,
.handle = touch_handle,
};
lvgl_touch_indev = lvgl_port_add_touch(&touch_cfg);
return ESP_OK;
}
static void _app_button_cb(lv_event_t *e)
{
lv_disp_rotation_t rotation = lv_disp_get_rotation(lvgl_disp);
rotation++;
if (rotation > LV_DISPLAY_ROTATION_270) {
rotation = LV_DISPLAY_ROTATION_0;
}
/* LCD HW rotation */
lv_disp_set_rotation(lvgl_disp, rotation);
}
static void app_main_display(void)
{
lv_obj_t *scr = lv_scr_act();
/* Task lock */
lvgl_port_lock(0);
/* Your LVGL objects code here .... */
/* Create image */
lv_obj_t *img_logo = lv_img_create(scr);
lv_img_set_src(img_logo, &esp_logo);
lv_obj_align(img_logo, LV_ALIGN_TOP_MID, 0, 20);
/* Label */
lv_obj_t *label = lv_label_create(scr);
lv_obj_set_width(label, EXAMPLE_LCD_H_RES);
lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0);
#if LVGL_VERSION_MAJOR == 8
lv_label_set_recolor(label, true);
lv_label_set_text(label, "#FF0000 "LV_SYMBOL_BELL" Hello world Espressif and LVGL "LV_SYMBOL_BELL"#\n#FF9400 "LV_SYMBOL_WARNING" For simplier initialization, use BSP "LV_SYMBOL_WARNING" #");
#else
lv_label_set_text(label, LV_SYMBOL_BELL" Hello world Espressif and LVGL "LV_SYMBOL_BELL"\n "LV_SYMBOL_WARNING" For simplier initialization, use BSP "LV_SYMBOL_WARNING);
#endif
lv_obj_align(label, LV_ALIGN_CENTER, 0, 20);
/* Button */
lv_obj_t *btn = lv_btn_create(scr);
label = lv_label_create(btn);
lv_label_set_text_static(label, "Rotate screen");
lv_obj_align(btn, LV_ALIGN_BOTTOM_MID, 0, -30);
lv_obj_add_event_cb(btn, _app_button_cb, LV_EVENT_CLICKED, NULL);
/* Task unlock */
lvgl_port_unlock();
}
void app_main(void)
{
/* LCD HW initialization */
ESP_ERROR_CHECK(app_lcd_init());
/* Touch initialization */
ESP_ERROR_CHECK(app_touch_init());
/* LVGL initialization */
ESP_ERROR_CHECK(app_lvgl_init());
/* Show LVGL objects */
app_main_display();
}

View File

@@ -0,0 +1,4 @@
CONFIG_IDF_TARGET="esp32s3"
CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
CONFIG_LV_COLOR_16_SWAP=y