Description
I tried switching between screens with lv_scr_load_anim()
, but it loads with low rendering speed. I have tried optimizing SPI Frequency and prj.conf, still no difference.
What MCU/Processor/Board and compiler are you using?
MCU: nRF52832
Display: 240x240 ST7789 and CST816S
Platform: Zephyr with nRF Connect
What LVGL version are you using?
8.4.0
What do you want to achieve?
Smooth screen transition animations
What have you tried so far?
Optimized SPI speed frequency and LV memory size
Code to reproduce
main code:
void switch_to_screen(int screen_index, lv_scr_load_anim_t anim)
{
uint64_t screen_count = sizeof(create_screens) / sizeof(create_screens[0]);
if (screen_index < 0 || screen_index >= screen_count)
{
LOG_ERR("Invalid screen number: %d", screen_index);
return;
}
lv_obj_t *screen = create_screens[screen_index]();
if (screen == NULL)
{
LOG_ERR("Failed to create screen %d", screen_index);
return;
}
lv_scr_load_anim(screen, anim, DISPLAY_ANIMATION_TIME, DISPLAY_ANIMATION_DELAY, true);
current_screen = screen;
}
static void handle_screen_gesture(lv_dir_t dir)
{
lv_scr_load_anim_t anim = LV_SCR_LOAD_ANIM_NONE;
uint64_t screen_count = sizeof(create_screens) / sizeof(create_screens[0]);
if (dir == LV_DIR_TOP)
{
current_screen_index++;
if (current_screen_index > screen_count - 1)
{
current_screen_index = 0;
}
anim = LV_SCR_LOAD_ANIM_MOVE_TOP;
}
else if (dir == LV_DIR_BOTTOM)
{
current_screen_index--;
if (current_screen_index < 0)
{
current_screen_index = screen_count - 1;
}
anim = LV_SCR_LOAD_ANIM_MOVE_BOTTOM;
}
else if (dir == LV_DIR_RIGHT && current_screen_index != 0)
{
current_screen_index = 0;
switch_to_screen(current_screen_index, anim);
return;
}
else
{
LOG_WRN("Unknown gesture direction: %d", dir);
return;
}
switch_to_screen(current_screen_index, anim);
last_screen_index = current_screen_index;
}
static void on_lvgl_screen_gesture_event_callback(lv_event_t *e)
{
lv_dir_t dir;
lv_event_code_t code = lv_event_get_code(e);
if (code == LV_EVENT_GESTURE)
{
dir = lv_indev_get_gesture_dir(lv_indev_get_act());
if (dir == LV_DIR_TOP || dir == LV_DIR_BOTTOM || dir == LV_DIR_RIGHT)
{
if (change_to_others_screen)
{
handle_others_screen_gesture(dir);
}
else
{
handle_screen_gesture(dir);
}
}
}
else if (code == LV_EVENT_CLICKED)
{
uint32_t screen_count = sizeof(create_screens) / sizeof(create_screens[0]);
if (last_screen_index == screen_count - 1)
{
if (!change_to_others_screen)
{
change_to_others_screen = true;
current_others_screen_index = 0;
k_msleep(DISPLAY_ANIMATION_DELAY);
switch_to_others_screen(current_others_screen_index, LV_SCR_LOAD_ANIM_NONE);
}
}
}
else
{
LOG_WRN("Unknown event code: %d", code);
}
lv_indev_wait_release(lv_indev_get_act());
}
lv_obj_t *create_screen0()
{
lv_obj_t *screen = lv_obj_create(NULL);
lv_obj_set_style_bg_color(screen, lv_color_hex(0x000033), LV_PART_MAIN);
lv_obj_t *label = lv_label_create(screen);
lv_label_set_text(label, "Screen 0: Welcome!");
lv_obj_set_style_text_color(label, lv_color_white(), LV_PART_MAIN);
lv_obj_set_style_text_font(label, &lv_font_montserrat_22, LV_PART_MAIN);
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
lv_obj_add_event_cb(screen, on_lvgl_screen_gesture_event_callback, LV_EVENT_GESTURE, NULL);
return screen;
}
lv_obj_t *create_screen1()
{
lv_obj_t *screen = lv_obj_create(NULL);
lv_obj_set_style_bg_color(screen, lv_color_hex(0x003366), LV_PART_MAIN);
lv_obj_t *label = lv_label_create(screen);
lv_label_set_text(label, "Screen 1: Hello!");
lv_obj_set_style_text_color(label, lv_color_white(), LV_PART_MAIN);
lv_obj_set_style_text_font(label, &lv_font_montserrat_22, LV_PART_MAIN);
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
lv_obj_add_event_cb(screen, on_lvgl_screen_gesture_event_callback, LV_EVENT_GESTURE, NULL);
return screen;
}
Board overlay:
/ {
chosen {
zephyr,display = &display;
};
aliases {
input = &touch_screen;
};
leds {
compatible = "gpio-leds";
lcd_backlight: lcd_backlight {
gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
label = "LCD Backlight";
};
};
lvgl_pointer_input:lvgl_pointer {
compatible = "zephyr,lvgl-pointer-input";
input = <&touch_screen>;
};
};
&spi0 {
compatible = "nordic,nrf-spim";
display: st7789v@0 {
label = "ST7789 Display";
compatible = "sitronix,st7789v";
spi-max-frequency = <DT_FREQ_M(32)>;
reg = <0>;
cmd-data-gpios = < &gpio0 27 GPIO_ACTIVE_LOW>;
reset-gpios = < &gpio0 31 GPIO_ACTIVE_LOW>;
width = <240>;
height = <240>;
x-offset = <0>;
y-offset = <0>;
vcom = <0x19>;
gctrl = <0x35>;
vrhs = <0x12>;
vdvs = <0x20>;
mdac = <0x00>;
gamma = <0x01>;
colmod = <0x05>;
lcm = <0x2c>;
porch-param = [0c 0c 00 33 33];
cmd2en-param = [5a 69 02 01];
pwctrl1-param = [a4 a1];
pvgam-param = [D0 04 0D 11 13 2B 3F 54 4C 18 0D 0B 1F 23];
nvgam-param = [D0 04 0C 11 13 2C 3F 44 51 2F 1F 1F 20 23];
ram-param = [00 F0];
rgb-param = [CD 08 14];
};
};
&i2c1 {
touch_screen: cst186s@15 {
label = "CST816S";
compatible = "hynitron,cst816s";
reg = <0x15>;
irq-gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
rst-gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
};
};
prj.conf
CONFIG_LOG=y
CONFIG_SHELL=y
CONFIG_THREAD_STACK_INFO=y
CONFIG_MAIN_STACK_SIZE=2048
CONFIG_DISPLAY=y
CONFIG_DISPLAY_LOG_LEVEL_ERR=y
CONFIG_LVGL=y
CONFIG_LV_Z_MEM_POOL_SIZE=8192
CONFIG_LV_Z_SHELL=y
CONFIG_LV_MEM_CUSTOM=y
CONFIG_LV_USE_LOG=y
CONFIG_LV_USE_LABEL=y
CONFIG_LV_FONT_MONTSERRAT_22=y
CONFIG_LV_Z_POINTER_INPUT=y
CONFIG_INPUT=y
CONFIG_INPUT_CST816S=y
CONFIG_INPUT_CST816S_INTERRUPT=y
CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58=y