diff --git a/samples/subsys/display/gui_guider/CMakeLists.txt b/samples/subsys/display/gui_guider/CMakeLists.txt new file mode 100644 index 0000000000000..436ecd50cb327 --- /dev/null +++ b/samples/subsys/display/gui_guider/CMakeLists.txt @@ -0,0 +1,13 @@ +# Copyright 2025 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(gui_guider) + +FILE(GLOB_RECURSE app_sources src/*.c) +target_include_directories(app PRIVATE src/generated src/custom src/generated/guider_customer_fonts src/generated/guider_fonts src/generated/images) +target_sources(app PRIVATE ${app_sources}) diff --git a/samples/subsys/display/gui_guider/README.rst b/samples/subsys/display/gui_guider/README.rst new file mode 100644 index 0000000000000..a27bfbcc7da2f --- /dev/null +++ b/samples/subsys/display/gui_guider/README.rst @@ -0,0 +1,61 @@ +.. zephyr:code-sample:: gui_guider + :name: GUI Guider basic sample + :relevant-api: display_interface input_interface + + Display a slider widget. + +Overview +******** + +This sample application displays a slider in the top left corner of the screen. + +Requirements +************ + +Display shield and a board which provides a configuration +for corresponding connectors, for example: + +a simulated display environment in a :zephyr:board:`native_sim ` application: + +- :zephyr:board:`native_sim` +- `SDL2`_ + +or + +- :zephyr:board:`mimxrt1050_evk` +- `RK043FN02H-CT`_ + +or + +- :zephyr:board:`mimxrt1064_evk` +- `RK043FN02H-CT`_ + +Building and Running +******************** + +Example building for :zephyr:board:`mimxrt1064_evk`: + +.. zephyr-app-commands:: + :zephyr-app: samples/subsys/display/gui_guider + :board: mimxrt1064_evk + :shield: rk043fn02h_ct + :goals: build flash + +Example building for :zephyr:board:`native_sim `: + +.. zephyr-app-commands:: + :zephyr-app: samples/subsys/display/gui_guider + :board: native_sim + :goals: build run + +Alternatively, if building from a 64-bit host machine, the previous target +board argument may also be replaced by ``native_sim/native/64``. + +References +********** + +.. target-notes:: + +.. _LVGL Web Page: https://lvgl.io/ +.. _SDL2: https://www.libsdl.org +.. _RK043FN02H-CT: https://www.nxp.com/products/processors-and-microcontrollers/arm-based-processors-and-mcus/i.mx-applications-processors/i.mx-rt-series/4.3-lcd-panel:RK043FN02H-CT diff --git a/samples/subsys/display/gui_guider/prj.conf b/samples/subsys/display/gui_guider/prj.conf new file mode 100644 index 0000000000000..3d2bba0ca2535 --- /dev/null +++ b/samples/subsys/display/gui_guider/prj.conf @@ -0,0 +1,9 @@ +CONFIG_LV_Z_MEM_POOL_SIZE=65536 +CONFIG_MAIN_STACK_SIZE=4096 + +CONFIG_DISPLAY=y + +CONFIG_LOG=y + +CONFIG_LVGL=y +CONFIG_LV_USE_LOG=y diff --git a/samples/subsys/display/gui_guider/sample.yaml b/samples/subsys/display/gui_guider/sample.yaml new file mode 100644 index 0000000000000..91237b58c0e6c --- /dev/null +++ b/samples/subsys/display/gui_guider/sample.yaml @@ -0,0 +1,66 @@ +sample: + description: GUI Guider sample application + name: gui guider sample +common: + tags: + - display + - gui + - gui_guider + - samples + modules: + - lvgl +tests: + sample.display.gui_guider.gui: + filter: dt_chosen_enabled("zephyr,display") + # flash usage varies depending on the platform, but ~200K are the bare + # minimum, give some room by adding 50K more. RAM usage depends largerly on + # the display buffer, but a minimum is also required for the system itself. + # ~25K seem to be sufficient for most cases, rounded to 32K. + min_flash: 250 + min_ram: 32 + harness: none + integration_platforms: + - native_sim/native/64 + sample.display.gui_guider.rk055hdmipi4m: + tags: shield + # This sample is intended to test the RT1170 and RT595, which require + # a display shield to work with LVGL + min_flash: 250 + # The minimum RAM needed for this display is actually around 8MB, + # but the RT595 uses external PSRAM for the display buffer + min_ram: 32 + harness: none + extra_args: SHIELD="rk055hdmipi4ma0" + platform_allow: + - mimxrt1170_evk/mimxrt1176/cm7 + - mimxrt595_evk/mimxrt595s/cm33 + integration_platforms: + - mimxrt1170_evk/mimxrt1176/cm7 + harness_config: + fixture: fixture_display_rk055hdmipi4m + sample.subsys.display.gui_guider.rk043fn66hs_ctg: + tags: shield + platform_allow: + - mimxrt1064_evk + - mimxrt1060_evk/mimxrt1062/qspi + - mimxrt1050_evk/mimxrt1052/hyperflash + - mimxrt1040_evk + integration_platforms: + - mimxrt1040_evk + harness: console + extra_args: SHIELD=rk043fn66hs_ctg + harness_config: + fixture: fixture_display_rk043fn66hs_ctg + sample.subsys.display.gui_guider.rk043fn02h_ct: + tags: shield + platform_allow: + - mimxrt1064_evk + - mimxrt1060_evk@C/mimxrt1062/qspi + - mimxrt1050_evk/mimxrt1052/hyperflash + - mimxrt1040_evk + integration_platforms: + - mimxrt1040_evk + harness: console + extra_args: SHIELD=rk043fn02h_ct + harness_config: + fixture: fixture_display_rk043fn02h_ct diff --git a/samples/subsys/display/gui_guider/src/custom/custom.c b/samples/subsys/display/gui_guider/src/custom/custom.c new file mode 100644 index 0000000000000..18d2966546afc --- /dev/null +++ b/samples/subsys/display/gui_guider/src/custom/custom.c @@ -0,0 +1,37 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/********************* + * INCLUDES + *********************/ +#include +#include "lvgl.h" +#include "custom.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/** + * Create a demo application + */ + +void custom_init(lv_ui *ui) +{ + /* Add your codes here */ +} diff --git a/samples/subsys/display/gui_guider/src/custom/custom.h b/samples/subsys/display/gui_guider/src/custom/custom.h new file mode 100644 index 0000000000000..e6bf4d3cee5e5 --- /dev/null +++ b/samples/subsys/display/gui_guider/src/custom/custom.h @@ -0,0 +1,20 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef CUSTOM_H +#define CUSTOM_H +#ifdef __cplusplus +extern "C" { +#endif + +#include "gui_guider.h" + +void custom_init(lv_ui *ui); + +#ifdef __cplusplus +} +#endif +#endif /* CUSTOM_H */ diff --git a/samples/subsys/display/gui_guider/src/generated/events_init.c b/samples/subsys/display/gui_guider/src/generated/events_init.c new file mode 100644 index 0000000000000..ac07f5262e3dc --- /dev/null +++ b/samples/subsys/display/gui_guider/src/generated/events_init.c @@ -0,0 +1,13 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "events_init.h" +#include +#include "lvgl.h" + +void events_init(lv_ui *ui) +{ +} diff --git a/samples/subsys/display/gui_guider/src/generated/events_init.h b/samples/subsys/display/gui_guider/src/generated/events_init.h new file mode 100644 index 0000000000000..36dc128e50d75 --- /dev/null +++ b/samples/subsys/display/gui_guider/src/generated/events_init.h @@ -0,0 +1,20 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef EVENTS_INIT_H +#define EVENTS_INIT_H +#ifdef __cplusplus +extern "C" { +#endif + +#include "gui_guider.h" + +void events_init(lv_ui *ui); + +#ifdef __cplusplus +} +#endif +#endif /* EVENTS_INIT_H */ diff --git a/samples/subsys/display/gui_guider/src/generated/gui_guider.c b/samples/subsys/display/gui_guider/src/generated/gui_guider.c new file mode 100644 index 0000000000000..78c8150320fb7 --- /dev/null +++ b/samples/subsys/display/gui_guider/src/generated/gui_guider.c @@ -0,0 +1,84 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "lvgl.h" +#include +#include "gui_guider.h" + +void ui_init_style(lv_style_t *style) +{ + if (style->prop_cnt > 1) { + lv_style_reset(style); + } else { + lv_style_init(style); + } +} + +void ui_load_scr_animation(lv_ui *ui, lv_obj_t **new_scr, bool new_scr_del, bool *old_scr_del, + ui_setup_scr_t setup_scr, lv_screen_load_anim_t anim_type, uint32_t time, + uint32_t delay, bool is_clean, bool auto_del) +{ + lv_obj_t *act_scr = lv_screen_active(); + + if (auto_del && is_clean) { + lv_obj_clean(act_scr); + } + if (new_scr_del) { + setup_scr(ui); + } + lv_screen_load_anim(*new_scr, anim_type, time, delay, auto_del); + *old_scr_del = auto_del; +} + +void ui_animation(void *var, uint32_t duration, int32_t delay, int32_t start_value, + int32_t end_value, lv_anim_path_cb_t path_cb, uint32_t repeat_cnt, + uint32_t repeat_delay, uint32_t playback_time, uint32_t playback_delay, + lv_anim_exec_xcb_t exec_cb, lv_anim_start_cb_t start_cb, + lv_anim_completed_cb_t ready_cb, lv_anim_deleted_cb_t deleted_cb) +{ + lv_anim_t anim; + lv_anim_init(&anim); + + lv_anim_set_var(&anim, var); + lv_anim_set_exec_cb(&anim, exec_cb); + lv_anim_set_values(&anim, start_value, end_value); + lv_anim_set_time(&anim, duration); + lv_anim_set_delay(&anim, delay); + lv_anim_set_path_cb(&anim, path_cb); + lv_anim_set_repeat_count(&anim, repeat_cnt); + lv_anim_set_repeat_delay(&anim, repeat_delay); + lv_anim_set_playback_time(&anim, playback_time); + lv_anim_set_playback_delay(&anim, playback_delay); + if (start_cb) { + lv_anim_set_start_cb(&anim, start_cb); + } + if (ready_cb) { + lv_anim_set_completed_cb(&anim, ready_cb); + } + if (deleted_cb) { + lv_anim_set_deleted_cb(&anim, deleted_cb); + } + lv_anim_start(&anim); +} + +void init_scr_del_flag(lv_ui *ui) +{ + + ui->screen_del = true; +} + +void setup_bottom_layer(void) +{ + lv_theme_apply(lv_layer_bottom()); +} + +void setup_ui(lv_ui *ui) +{ + setup_bottom_layer(); + init_scr_del_flag(ui); + setup_scr_screen(ui); + lv_screen_load(ui->screen); +} diff --git a/samples/subsys/display/gui_guider/src/generated/gui_guider.h b/samples/subsys/display/gui_guider/src/generated/gui_guider.h new file mode 100644 index 0000000000000..000e7c200fa76 --- /dev/null +++ b/samples/subsys/display/gui_guider/src/generated/gui_guider.h @@ -0,0 +1,49 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef GUI_GUIDER_H +#define GUI_GUIDER_H +#ifdef __cplusplus +extern "C" { +#endif + +#include "lvgl.h" + +typedef struct { + + lv_obj_t *screen; + bool screen_del; + lv_obj_t *screen_slider_1; +} lv_ui; + +typedef void (*ui_setup_scr_t)(lv_ui *ui); + +void ui_init_style(lv_style_t *style); + +void ui_load_scr_animation(lv_ui *ui, lv_obj_t **new_scr, bool new_scr_del, bool *old_scr_del, + ui_setup_scr_t setup_scr, lv_screen_load_anim_t anim_type, uint32_t time, + uint32_t delay, bool is_clean, bool auto_del); + +void ui_animation(void *var, uint32_t duration, int32_t delay, int32_t start_value, + int32_t end_value, lv_anim_path_cb_t path_cb, uint32_t repeat_cnt, + uint32_t repeat_delay, uint32_t playback_time, uint32_t playback_delay, + lv_anim_exec_xcb_t exec_cb, lv_anim_start_cb_t start_cb, + lv_anim_completed_cb_t ready_cb, lv_anim_deleted_cb_t deleted_cb); + +void init_scr_del_flag(lv_ui *ui); + +void setup_bottom_layer(void); + +void setup_ui(lv_ui *ui); + +extern lv_ui guider_ui; + +void setup_scr_screen(lv_ui *ui); + +#ifdef __cplusplus +} +#endif +#endif /* GUI_GUIDER_H */ diff --git a/samples/subsys/display/gui_guider/src/generated/setup_scr_screen.c b/samples/subsys/display/gui_guider/src/generated/setup_scr_screen.c new file mode 100644 index 0000000000000..703f6014b06a9 --- /dev/null +++ b/samples/subsys/display/gui_guider/src/generated/setup_scr_screen.c @@ -0,0 +1,60 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "lvgl.h" +#include +#include "gui_guider.h" +#include "events_init.h" +#include "custom.h" + +void setup_scr_screen(lv_ui *ui) +{ + /* Write codes screen */ + ui->screen = lv_screen_active(); + lv_obj_set_scrollbar_mode(ui->screen, LV_SCROLLBAR_MODE_OFF); + + /* Write style for screen, Part: LV_PART_MAIN, State: LV_STATE_DEFAULT. */ + lv_obj_set_style_bg_opa(ui->screen, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + /* Write codes screen_slider_1 */ + ui->screen_slider_1 = lv_slider_create(ui->screen); + lv_obj_set_pos(ui->screen_slider_1, 10, 30); + lv_obj_set_size(ui->screen_slider_1, 160, 8); + lv_slider_set_range(ui->screen_slider_1, 0, 100); + lv_slider_set_mode(ui->screen_slider_1, LV_SLIDER_MODE_NORMAL); + lv_slider_set_value(ui->screen_slider_1, 50, LV_ANIM_OFF); + + /* Write style for screen_slider_1, Part: LV_PART_MAIN, State: LV_STATE_DEFAULT. */ + lv_obj_set_style_bg_opa(ui->screen_slider_1, 60, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_color(ui->screen_slider_1, lv_color_hex(0x2195f6), + LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_bg_grad_dir(ui->screen_slider_1, LV_GRAD_DIR_NONE, + LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_radius(ui->screen_slider_1, 8, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_outline_width(ui->screen_slider_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + lv_obj_set_style_shadow_width(ui->screen_slider_1, 0, LV_PART_MAIN | LV_STATE_DEFAULT); + + /* Write style for screen_slider_1, Part: LV_PART_INDICATOR, State: LV_STATE_DEFAULT. */ + lv_obj_set_style_bg_opa(ui->screen_slider_1, 255, LV_PART_INDICATOR | LV_STATE_DEFAULT); + lv_obj_set_style_bg_color(ui->screen_slider_1, lv_color_hex(0x2195f6), + LV_PART_INDICATOR | LV_STATE_DEFAULT); + lv_obj_set_style_bg_grad_dir(ui->screen_slider_1, LV_GRAD_DIR_NONE, + LV_PART_INDICATOR | LV_STATE_DEFAULT); + lv_obj_set_style_radius(ui->screen_slider_1, 8, LV_PART_INDICATOR | LV_STATE_DEFAULT); + + /* Write style for screen_slider_1, Part: LV_PART_KNOB, State: LV_STATE_DEFAULT. */ + lv_obj_set_style_bg_opa(ui->screen_slider_1, 255, LV_PART_KNOB | LV_STATE_DEFAULT); + lv_obj_set_style_bg_color(ui->screen_slider_1, lv_color_hex(0x2195f6), + LV_PART_KNOB | LV_STATE_DEFAULT); + lv_obj_set_style_bg_grad_dir(ui->screen_slider_1, LV_GRAD_DIR_NONE, + LV_PART_KNOB | LV_STATE_DEFAULT); + lv_obj_set_style_radius(ui->screen_slider_1, 8, LV_PART_KNOB | LV_STATE_DEFAULT); + + /* The custom code of screen. */ + + /* Update current screen layout. */ + lv_obj_update_layout(ui->screen); +} diff --git a/samples/subsys/display/gui_guider/src/main.c b/samples/subsys/display/gui_guider/src/main.c new file mode 100644 index 0000000000000..84ced24ae9747 --- /dev/null +++ b/samples/subsys/display/gui_guider/src/main.c @@ -0,0 +1,46 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#include "../generated/gui_guider.h" +#include "../generated/events_init.h" + +#define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL +#include +LOG_MODULE_REGISTER(app); + +lv_ui guider_ui; + +int main(void) +{ + const struct device *display_dev; + + display_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display)); + if (!device_is_ready(display_dev)) { + LOG_ERR("Device not ready, aborting test"); + return 0; + } + + setup_ui(&guider_ui); + events_init(&guider_ui); + + lv_timer_handler(); + display_blanking_off(display_dev); + + while (1) { + uint32_t sleep_ms = lv_timer_handler(); + + k_msleep(MIN(sleep_ms, INT32_MAX)); + } + + return 0; +}