Update LVGL (master 9.2+) and related libraries (#130)

- LVGL 9.2+ (master commit)
- esp_lvgl_port (master with my PR hotfix changes)
- espressif/esp_lcd_touch_gt911 1.1.1~2
This commit is contained in:
Ken Van Hoeylandt
2024-12-16 23:30:57 +01:00
committed by GitHub
parent e4b8519f67
commit 80b69b7f45
90 changed files with 7328 additions and 469 deletions
@@ -0,0 +1,4 @@
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(i2c_oled)
@@ -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
...
```
@@ -0,0 +1,2 @@
idf_component_register(SRCS "i2c_oled_example_main.c" "lvgl_demo_ui.c"
INCLUDE_DIRS ".")
@@ -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
@@ -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();
}
}
@@ -0,0 +1,7 @@
dependencies:
idf: ">=4.4"
lvgl/lvgl: "^8"
esp_lcd_sh1107: "^1"
esp_lvgl_port:
version: "*"
override_path: "../../../"
@@ -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);
}
@@ -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