Skip to content

Commit

Permalink
feat(LVGL port): Generate C arrays for images during build process
Browse files Browse the repository at this point in the history
  • Loading branch information
espzav committed May 9, 2024
1 parent c1692db commit d100e9d
Show file tree
Hide file tree
Showing 33 changed files with 470 additions and 671 deletions.
15 changes: 14 additions & 1 deletion bsp/esp32_p4_function_ev_board/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,20 @@
ESP32-P4 Function EV Board is internal Espressif board for testing features on ESP32P4 chip.

<!-- Autogenerated start: Dependencies -->

### Capabilities and dependencies
| Capability | Available | Component |Version|
|-------------|------------------|----------------------------------------------------------------------------------------------------------|-------|
| DISPLAY |:heavy_check_mark:| [espressif/esp_lcd_ili9881c](https://components.espressif.com/components/espressif/esp_lcd_ili9881c) |>=0.2.0|
| LVGL_PORT |:heavy_check_mark:| [espressif/esp_lvgl_port](https://components.espressif.com/components/espressif/esp_lvgl_port) | ^2 |
| TOUCH |:heavy_check_mark:|[espressif/esp_lcd_touch_gt911](https://components.espressif.com/components/espressif/esp_lcd_touch_gt911)| ^1 |
| BUTTONS | :x: | | |
| AUDIO | :x: | | |
|AUDIO_SPEAKER| :x: | | |
| AUDIO_MIC | :x: | | |
| SDCARD |:heavy_check_mark:| idf | >=5.3 |
| IMU | :x: | | |
<!-- Autogenerated end: Dependencies -->
<!-- Autogenerated start: Dependencies -->
### Capabilities and dependencies
| Capability | Available | Component |Version|
|-------------|------------------|----------------------------------------------------------------------------------------------------------|-------|
Expand Down
3 changes: 0 additions & 3 deletions bsp/esp32_p4_function_ev_board/esp32_p4_function_ev_board.c
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,6 @@ static lv_display_t *bsp_display_lcd_init(const bsp_display_cfg_t *cfg)
.control_handle = lcd_panels.control,
.buffer_size = cfg->buffer_size,
.double_buffer = cfg->double_buffer,
.trans_size = (cfg->flags.sw_rotate ? BSP_LCD_H_RES * 50 : 0),
.hres = BSP_LCD_V_RES,
.vres = BSP_LCD_H_RES,
.monochrome = false,
Expand All @@ -363,7 +362,6 @@ static lv_display_t *bsp_display_lcd_init(const bsp_display_cfg_t *cfg)
.buff_dma = cfg->flags.buff_dma,
.buff_spiram = cfg->flags.buff_spiram,
.swap_bytes = (BSP_LCD_BIGENDIAN ? true : false),
.sw_rotate = cfg->flags.sw_rotate, /* Only SW rotation is supported for 90° and 270° */
}
};

Expand Down Expand Up @@ -393,7 +391,6 @@ lv_display_t *bsp_display_start(void)
.flags = {
.buff_dma = true,
.buff_spiram = false,
.sw_rotate = false, /* When SPIRAM used for buffer, only SW rotation is supported; For 90° and 270° is not supported HW rotation in this driver. */
}
};
return bsp_display_start_with_config(&cfg);
Expand Down
2 changes: 1 addition & 1 deletion bsp/esp32_p4_function_ev_board/idf_component.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: "1.1.0"
version: "1.1.1"
description: Board Support Package (BSP) for ESP32-P4 Function EV Board (preview)
url: https://github.com/espressif/esp-bsp/tree/master/bsp/esp32_p4_function_ev_board

Expand Down
14 changes: 14 additions & 0 deletions bsp/m5stack_core_s3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,17 @@ Sound output on CoreS3 is optimized with the high-fidelity 16-bit I2S power ampl
| SDCARD |:heavy_check_mark:| idf | >=5.0 |
| IMU | :x: | | |
<!-- Autogenerated end: Dependencies -->
<!-- Autogenerated start: Dependencies -->
### Capabilities and dependencies
| Capability | Available | Component |Version|
|-------------|------------------|------------------------------------------------------------------------------------------------------------|-------|
| DISPLAY |:heavy_check_mark:| [espressif/esp_lcd_ili9341](https://components.espressif.com/components/espressif/esp_lcd_ili9341) | ^1 |
| LVGL_PORT |:heavy_check_mark:| [espressif/esp_lvgl_port](https://components.espressif.com/components/espressif/esp_lvgl_port) | ^1.3 |
| TOUCH |:heavy_check_mark:|[espressif/esp_lcd_touch_ft5x06](https://components.espressif.com/components/espressif/esp_lcd_touch_ft5x06)| ^1 |
| BUTTONS | :x: | | |
| AUDIO |:heavy_check_mark:| [espressif/esp_codec_dev](https://components.espressif.com/components/espressif/esp_codec_dev) | ^1.1 |
|AUDIO_SPEAKER|:heavy_check_mark:| | |
| AUDIO_MIC |:heavy_check_mark:| | |
| SDCARD |:heavy_check_mark:| idf | >=5.0 |
| IMU | :x: | | |
<!-- Autogenerated end: Dependencies -->
2 changes: 1 addition & 1 deletion bsp/m5stack_core_s3/idf_component.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: "1.0.0"
version: "1.0.1"
description: Board Support Package (BSP) for M5Stack CoreS3
url: https://github.com/espressif/esp-bsp/tree/master/bsp/m5stack_core_s3

Expand Down
9 changes: 4 additions & 5 deletions bsp/m5stack_core_s3/m5stack_core_s3.c
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,6 @@ esp_err_t bsp_display_new(const bsp_display_config_t *config, esp_lcd_panel_hand

esp_lcd_panel_reset(*ret_panel);
esp_lcd_panel_init(*ret_panel);
esp_lcd_panel_mirror(*ret_panel, true, true);
esp_lcd_panel_invert_color(*ret_panel, true);
return ret;

Expand Down Expand Up @@ -409,8 +408,8 @@ esp_err_t bsp_touch_new(const bsp_touch_config_t *config, esp_lcd_touch_handle_t
},
.flags = {
.swap_xy = 0,
.mirror_x = 1,
.mirror_y = 1,
.mirror_x = 0,
.mirror_y = 0,
},
};
esp_lcd_panel_io_handle_t tp_io_handle = NULL;
Expand Down Expand Up @@ -445,8 +444,8 @@ static lv_disp_t *bsp_display_lcd_init(const bsp_display_cfg_t *cfg)
/* Rotation values must be same as used in esp_lcd for initial settings of the screen */
.rotation = {
.swap_xy = false,
.mirror_x = true,
.mirror_y = true,
.mirror_x = false,
.mirror_y = false,
},
.flags = {
.buff_dma = cfg->flags.buff_dma,
Expand Down
15 changes: 7 additions & 8 deletions components/esp_lvgl_port/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
# Changelog

## 2.0.1
## 2.1.0

### Features
- Added unit test
- Allow to sleep main LVGL task
- Wake LVGL task from touch and display, when set big maximum sleep
- Allow to select display color mode (only with LVGL9)
- Added LVGL sleep feature: The esp_lvgl_port handling can sleep if the display and touch are inactive (only with LVGL9)
- Added support for different display color modes (only with LVGL9)
- Added script for generating C array images during build (depends on LVGL version)

### Fixes
- Apply display rotation from configuration
- Wait for stop task when deinit
- Added esp_idf_version.h
- Applied initial display rotation from configuration https://github.com/espressif/esp-bsp/pull/278
- Added blocking wait for LVGL task stop during esp_lvgl_port de-initialization https://github.com/espressif/esp-bsp/issues/277
- Added missing esp_idf_version.h include

## 2.0.0

Expand Down
34 changes: 32 additions & 2 deletions components/esp_lvgl_port/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,30 +280,60 @@ If the SRAM is insufficient, you can use the PSRAM as a canvas and use a small t
}
```
### Generating images (C Array)
Images can be generated during build by adding these lines to end of the main CMakeLists.txt:
```
# Generate C array for each image
lvgl_port_create_c_image("images/logo.png" "images/" "ARGB8888" "NONE")
lvgl_port_create_c_image("images/image.png" "images/" "ARGB8888" "NONE")
# Add generated images to build
lvgl_port_add_images(${COMPONENT_LIB} "images/")
```
Usage of create C image function:
```
lvgl_port_create_c_image(input_image output_folder color_format compression)
```
Available color formats:
L8,I1,I2,I4,I8,A1,A2,A4,A8,ARGB8888,XRGB8888,RGB565,RGB565A8,RGB888,TRUECOLOR,TRUECOLOR_ALPHA,AUTO
Available compression:
NONE,RLE,LZ4
**Note:** Parameters `color_format` and `compression` are used only in LVGL 9.
## Power Saving
The LVGL port can be optimized for power saving mode. There are two main features.
### LVGL task sleep
For optimization power saving, the LVGL task should sleep, when it does nothing. Set `task_max_sleep_ms` to big value, the LVGL task will wait for events only.
The LVGL task can sleep till these situations:
* LVGL display invalidate
* LVGL animation in process
* Touch interrupt
* Button interrupt
* Knob interrupt
* USB mouse/keyboard interrupt
* Timeout (`task_max_sleep_ms` in configuration structure)
* User wake (by function `lvgl_port_task_wake`)
**Warning:** This feature is available from LVGL 9.
**Note:** Don't forget to set the interrupt pin in LCD touch when you set a big time for sleep in `task_max_sleep_ms`.
### Stopping the timer
For sleep, you can stop LVGL timer by function:
Timers can still work during light-sleep mode. You can stop LVGL timer before use light-sleep by function:
```
lvgl_port_stop();
```
and resume LVGL timer by function:
and resume LVGL timer after wake by function:
```
lvgl_port_resume();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +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/")
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.c
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 14 additions & 2 deletions components/esp_lvgl_port/examples/touchscreen/main/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@

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;
Expand Down Expand Up @@ -177,20 +180,24 @@ static esp_err_t app_lvgl_init(void)
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 * sizeof(uint16_t),
.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);
Expand Down Expand Up @@ -226,6 +233,11 @@ static void app_main_display(void)

/* 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);
Expand All @@ -236,7 +248,7 @@ static void app_main_display(void)
#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, -30);
lv_obj_align(label, LV_ALIGN_CENTER, 0, 20);

/* Button */
lv_obj_t *btn = lv_btn_create(scr);
Expand Down
2 changes: 1 addition & 1 deletion components/esp_lvgl_port/idf_component.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: "2.0.0"
version: "2.1.0"
description: ESP LVGL port
url: https://github.com/espressif/esp-bsp/tree/master/components/esp_lvgl_port
dependencies:
Expand Down
15 changes: 12 additions & 3 deletions components/esp_lvgl_port/include/esp_lvgl_port.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,20 @@ extern "C" {
#endif

/**
* @brief LVGL Port task events
* @brief LVGL Port task event type
*/
typedef enum {
LVGL_PORT_EVENT_DISPLAY = 1,
LVGL_PORT_EVENT_TOUCH = 2,
LVGL_PORT_EVENT_USER = 99,
} lvgl_port_event_type_t;

/**
* @brief LVGL Port task events
*/
typedef struct {
lvgl_port_event_type_t type;
void *param;
} lvgl_port_event_t;

/**
Expand Down Expand Up @@ -135,13 +143,14 @@ esp_err_t lvgl_port_resume(void);
*
* @note It is called from LVGL events and touch interrupts
*
* @param isr true, when called from interrupt
* @param event event type
* @param param user param
* @return
* - ESP_OK on success
* - ESP_ERR_NOT_SUPPORTED if it is not implemented
* - ESP_ERR_INVALID_STATE if queue is not initialized (can be returned after LVGL deinit)
*/
esp_err_t lvgl_port_task_wake(lvgl_port_event_t event, bool isr);
esp_err_t lvgl_port_task_wake(lvgl_port_event_type_t event, void *param);

#ifdef __cplusplus
}
Expand Down
2 changes: 2 additions & 0 deletions components/esp_lvgl_port/include/esp_lvgl_port_disp.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ typedef struct {
struct {
unsigned int buff_dma: 1; /*!< Allocated LVGL buffer will be DMA capable */
unsigned int buff_spiram: 1; /*!< Allocated LVGL buffer will be in PSRAM */
#if LVGL_VERSION_MAJOR == 8
unsigned int sw_rotate: 1; /*!< Use software rotation (slower) */
#endif
#if LVGL_VERSION_MAJOR >= 9
unsigned int swap_bytes: 1; /*!< Swap bytes in RGB656 (16-bit) color format before send to LCD driver */
#endif
Expand Down
65 changes: 65 additions & 0 deletions components/esp_lvgl_port/project_include.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# lvgl_port_create_c_image
#
# Create a C array of image for using with LVGL
function(lvgl_port_create_c_image image_path output_path color_format compression)

#Get LVGL version
idf_component_get_property(lvgl_ver lvgl__lvgl COMPONENT_VERSION)
set(LVGL_NAME "lvgl__lvgl")
if(lvgl_ver EQUAL "")
idf_component_get_property(lvgl_ver lvgl COMPONENT_VERSION)
set(LVGL_NAME "lvgl")
endif()

get_filename_component(image_full_path ${image_path} ABSOLUTE)
get_filename_component(output_full_path ${output_path} ABSOLUTE)
if(NOT EXISTS ${image_full_path})
message(FATAL_ERROR "Input image (${image_full_path}) not exists!")
endif()

message(STATUS "Generating C array image: ${image_path}")

#Create C array image by LVGL version
if(lvgl_ver VERSION_LESS "9.0.0")
if(CONFIG_LV_COLOR_16_SWAP)
set(color_format "RGB565SWAP")
else()
set(color_format "RGB565")
endif()

execute_process(COMMAND git clone https://github.com/W-Mai/lvgl_image_converter.git "${CMAKE_BINARY_DIR}/lvgl_image_converter")
execute_process(COMMAND git checkout 9174634e9dcc1b21a63668969406897aad650f35 WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/lvgl_image_converter" OUTPUT_QUIET)
execute_process(COMMAND python -m pip install -r "${CMAKE_BINARY_DIR}/lvgl_image_converter/requirements.txt")
execute_process(COMMAND ${PYTHON} "${CMAKE_BINARY_DIR}/lvgl_image_converter/lv_img_conv.py"
-ff C
-f true_color_alpha
-cf ${color_format}
-o ${output_full_path}
${image_full_path})
else()
idf_component_get_property(lvgl_dir ${LVGL_NAME} COMPONENT_DIR)
get_filename_component(script_path ${lvgl_dir}/scripts/LVGLImage.py ABSOLUTE)
set(lvglimage_py ${PYTHON} ${script_path})

#Install dependencies
execute_process(COMMAND python -m pip install pypng lz4)

execute_process(COMMAND ${lvglimage_py}
--ofmt=C
--cf=${color_format}
--compress=${compression}
-o ${output_full_path}
${image_full_path})
endif()

endfunction()

# lvgl_port_add_images
#
# Add all images to build
function(lvgl_port_add_images component output_path)
#Add images to sources
file(GLOB_RECURSE IMAGE_SOURCES ${output_path}*.c)
target_sources(${component} PRIVATE ${IMAGE_SOURCES})
idf_build_set_property(COMPILE_OPTIONS "-DLV_LVGL_H_INCLUDE_SIMPLE=1" APPEND)
endfunction()
2 changes: 1 addition & 1 deletion components/esp_lvgl_port/src/lvgl8/esp_lvgl_port.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ void lvgl_port_unlock(void)
xSemaphoreGiveRecursive(lvgl_port_ctx.lvgl_mux);
}

esp_err_t lvgl_port_task_wake(lvgl_port_event_t event, bool isr)
esp_err_t lvgl_port_task_wake(lvgl_port_event_type_t event, void *param)
{
ESP_LOGE(TAG, "Task wake is not supported, when used LVGL8!");
return ESP_ERR_NOT_SUPPORTED;
Expand Down
Loading

0 comments on commit d100e9d

Please sign in to comment.