From cf48cae20ea12e78a96bbe0aae925bae1c249582 Mon Sep 17 00:00:00 2001 From: Niklas Hauser Date: Sun, 6 Oct 2024 15:26:28 +0200 Subject: [PATCH] [ext] Update LVGL to v9.2.0 --- examples/nucleo_l452re/lvgl/main.cpp | 57 +++++++--------- examples/stm32f469_discovery/lvgl/main.cpp | 76 +++++++++------------- ext/lvgl/lv_conf.h.in | 39 ++--------- ext/lvgl/lv_modm_clock.cpp | 17 ----- ext/lvgl/lv_modm_clock.h | 20 ------ ext/lvgl/lv_modm_logging.cpp | 21 ------ ext/lvgl/lv_modm_port.cpp.in | 32 +++++++++ ext/lvgl/lvgl | 2 +- ext/lvgl/lvgl.lb | 20 +++--- 9 files changed, 100 insertions(+), 184 deletions(-) delete mode 100644 ext/lvgl/lv_modm_clock.cpp delete mode 100644 ext/lvgl/lv_modm_clock.h delete mode 100644 ext/lvgl/lv_modm_logging.cpp create mode 100644 ext/lvgl/lv_modm_port.cpp.in diff --git a/examples/nucleo_l452re/lvgl/main.cpp b/examples/nucleo_l452re/lvgl/main.cpp index 84e430b86b..86bda2ac0e 100644 --- a/examples/nucleo_l452re/lvgl/main.cpp +++ b/examples/nucleo_l452re/lvgl/main.cpp @@ -62,28 +62,27 @@ namespace touch modm::Touch2046 touchController; -static lv_disp_draw_buf_t disp_buf; static constexpr size_t buf_size = LV_HOR_RES_MAX * LV_VER_RES_MAX / 8; static lv_color_t buf[buf_size]; -void my_touchpad_read(lv_indev_drv_t*, lv_indev_data_t* data) +void my_touchpad_read(lv_indev_t*, lv_indev_data_t* data) { - data->state = RF_CALL_BLOCKING(touchController.isTouched()) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; - if(data->state == LV_INDEV_STATE_PR) { + data->state = RF_CALL_BLOCKING(touchController.isTouched()) ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED; + if(data->state == LV_INDEV_STATE_PRESSED) { auto xy = RF_CALL_BLOCKING(touchController.getTouchPosition()); data->point.x = std::get<0>(xy); data->point.y = std::get<1>(xy); } } -void my_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p) +void disp_flush(lv_display_t* disp, const lv_area_t* area, uint8_t* px_map) { tftController.drawRaw( {area->x1, area->y1}, (area->x2 - area->x1 +1), (area->y2 - area->y1 + 1), - (modm::color::Rgb565*)color_p); - lv_disp_flush_ready(disp_drv); + (modm::color::Rgb565*)px_map); + lv_display_flush_ready(disp); } int @@ -118,45 +117,35 @@ main() MODM_LOG_INFO << "modm LVGL example on Nucleo-L452RE board!\n\n"; - lv_init(); - - // Initialize the display buffer - lv_disp_draw_buf_init(&disp_buf, buf, NULL, buf_size); - - // Initialize the display: - lv_disp_drv_t disp_drv; - lv_disp_drv_init(&disp_drv); - disp_drv.draw_buf = &disp_buf; - disp_drv.flush_cb = my_flush_cb; - disp_drv.hor_res = LV_HOR_RES_MAX; - disp_drv.ver_res = LV_VER_RES_MAX; - lv_disp_t *disp = lv_disp_drv_register(&disp_drv); + lv_display_t *disp = lv_display_create(LV_HOR_RES_MAX, LV_VER_RES_MAX); + lv_display_set_flush_cb(disp, disp_flush); + lv_display_set_buffers(disp, buf, NULL, sizeof(buf), LV_DISPLAY_RENDER_MODE_DIRECT); // Initialize touchscreen driver: - lv_indev_drv_t indev_drv; - lv_indev_drv_init(&indev_drv); - indev_drv.type = LV_INDEV_TYPE_POINTER; - indev_drv.read_cb = my_touchpad_read; - lv_indev_drv_register(&indev_drv); - - lv_obj_t* scr = lv_disp_get_scr_act(disp); // Get the current screen + lv_indev_t* indev = lv_indev_create(); + lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); + lv_indev_set_read_cb(indev, my_touchpad_read); - lv_obj_t* labelA = lv_label_create(scr); + lv_obj_t* labelA = lv_label_create(lv_screen_active()); lv_label_set_text(labelA, "Hello world!"); lv_obj_set_pos(labelA, 60, 10); lv_obj_set_size(labelA, 120, 50); - lv_obj_t* btn = lv_btn_create(lv_scr_act()); + lv_obj_t* btn = lv_button_create(lv_screen_active()); lv_obj_set_pos(btn, 60, 135); lv_obj_set_size(btn, 120, 50); + lv_obj_t* btnLabel = lv_label_create(btn); lv_label_set_text(btnLabel, "Button"); - lv_obj_add_event_cb(btn, [](lv_event_t *event) { + + lv_obj_add_event_cb(btn, [](lv_event_t *event) + { static uint16_t btnCounter = 0; - lv_label_set_text_fmt(lv_obj_get_child(event->target, 0), "Button: %d", ++btnCounter); - }, LV_EVENT_PRESSED, NULL); + lv_label_set_text_fmt((lv_obj_t*) lv_event_get_user_data(event), + "Button: %d", ++btnCounter); + }, LV_EVENT_PRESSED, btnLabel); - lv_obj_t* labelB = lv_label_create(scr); + lv_obj_t* labelB = lv_label_create(lv_screen_active()); lv_label_set_text(labelB, "Big Font"); lv_obj_set_pos(labelB, 40, 260); lv_obj_set_style_text_font(labelB, &lv_font_montserrat_36, LV_PART_MAIN); @@ -167,7 +156,7 @@ main() while (true) { - lv_task_handler(); + lv_timer_handler(); if (tmr.execute()) { diff --git a/examples/stm32f469_discovery/lvgl/main.cpp b/examples/stm32f469_discovery/lvgl/main.cpp index 87c9ce96d8..9a365cecb3 100644 --- a/examples/stm32f469_discovery/lvgl/main.cpp +++ b/examples/stm32f469_discovery/lvgl/main.cpp @@ -26,38 +26,30 @@ using namespace Board::ft6; using namespace modm::literals; -static uint16_t* displayBuffer; -static lv_disp_draw_buf_t disp_buf; -static lv_color_t* buf; -static constexpr size_t buf_size = LV_HOR_RES_MAX * LV_VER_RES_MAX; - Touch::Data touchData; Touch touch{touchData, TouchAddress}; -void my_touchpad_read(lv_indev_drv_t*, lv_indev_data_t* data) +void my_touchpad_read(lv_indev_t*, lv_indev_data_t* data) { RF_CALL_BLOCKING(touch.readTouches()); Touch::touch_t tp; touch.getData().getTouch(&tp, 0); // mirror and rotate correctly uint16_t x{tp.y}, y{uint16_t(480 - tp.x)}; - data->state = (tp.event == Touch::Event::Contact) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; - if(data->state == LV_INDEV_STATE_PR) { + if (tp.event == Touch::Event::Contact) + { + data->state = LV_INDEV_STATE_PRESSED; data->point.x = x; data->point.y = y; } + else data->state = LV_INDEV_STATE_RELEASED; } -void my_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p) +uint8_t *buf_1, *buf_2; +void disp_flush(lv_display_t* disp, const lv_area_t*, uint8_t* px_map) { - for(lv_coord_t y = area->y1; y <= area->y2; y++) { - std::memcpy( - &displayBuffer[(800*y) + area->x1], - &color_p[(y - area->y1) * (area->x2 - area->x1 + 1)], - (area->x2 - area->x1 + 1) * sizeof(lv_color_t) - ); - } - lv_disp_flush_ready(disp_drv); + setDisplayBuffer((uint16_t*) px_map); + lv_display_flush_ready(disp); } @@ -72,55 +64,45 @@ main() RF_CALL_BLOCKING(touch.configure(Touch::InterruptMode::Trigger, 60, 60)); - lv_init(); - - buf = new(modm::MemoryExternal) lv_color_t[buf_size]; - displayBuffer = new(modm::MemoryExternal) uint16_t[buf_size]; - - setDisplayBuffer(displayBuffer); - - // Initialize the display buffer - lv_disp_draw_buf_init(&disp_buf, buf, NULL, buf_size); - // Initialize the display: - lv_disp_drv_t disp_drv; - lv_disp_drv_init(&disp_drv); - disp_drv.draw_buf = &disp_buf; - disp_drv.flush_cb = my_flush_cb; - disp_drv.hor_res = LV_HOR_RES_MAX; - disp_drv.ver_res = LV_VER_RES_MAX; - lv_disp_t *disp = lv_disp_drv_register(&disp_drv); + lv_display_t *disp = lv_display_create(LV_HOR_RES_MAX, LV_VER_RES_MAX); + lv_display_set_flush_cb(disp, disp_flush); - // Initialize touchscreen driver: - lv_indev_drv_t indev_drv; - lv_indev_drv_init(&indev_drv); - indev_drv.type = LV_INDEV_TYPE_POINTER; - indev_drv.read_cb = my_touchpad_read; - lv_indev_drv_register(&indev_drv); + static constexpr size_t BufSize = LV_HOR_RES_MAX * LV_VER_RES_MAX * sizeof(lv_color_t); + buf_1 = new(modm::MemoryExternal) uint8_t[BufSize]; + buf_2 = new(modm::MemoryExternal) uint8_t[BufSize]; + lv_display_set_buffers(disp, buf_1, buf_2, BufSize, LV_DISPLAY_RENDER_MODE_DIRECT); - lv_obj_t* scr = lv_disp_get_scr_act(disp); // Get the current screen + // Initialize touchscreen driver: + lv_indev_t* indev = lv_indev_create(); + lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); + lv_indev_set_read_cb(indev, my_touchpad_read); - lv_obj_t* labelA = lv_label_create(scr); + lv_obj_t *labelA = lv_label_create(lv_screen_active()); lv_label_set_text(labelA, "Hello world!"); lv_obj_set_pos(labelA, 10, 10); lv_obj_set_size(labelA, 120, 50); - lv_obj_t* btn2 = lv_btn_create(lv_scr_act()); + lv_obj_t* btn2 = lv_button_create(lv_screen_active()); lv_obj_set_pos(btn2, 140, 10); lv_obj_set_size(btn2, 120, 50); + lv_obj_t* label2 = lv_label_create(btn2); lv_label_set_text(label2, "Button2"); - lv_obj_add_event_cb(btn2, [](lv_event_t *event) { + + lv_obj_add_event_cb(btn2, [](lv_event_t *event) + { static uint16_t btn2Counter = 0; - lv_label_set_text_fmt(lv_obj_get_child(event->target, 0), "Button 2: %d", ++btn2Counter); - }, LV_EVENT_PRESSED, NULL); + lv_label_set_text_fmt((lv_obj_t*) lv_event_get_user_data(event), + "Button 2: %d", ++btn2Counter); + }, LV_EVENT_PRESSED, label2); uint16_t counter = 0; modm::ShortPeriodicTimer tmr{20ms}; while (true) { - lv_task_handler(); + lv_timer_handler(); if (tmr.execute()) { diff --git a/ext/lvgl/lv_conf.h.in b/ext/lvgl/lv_conf.h.in index 55aaec0a3a..4000d53f57 100644 --- a/ext/lvgl/lv_conf.h.in +++ b/ext/lvgl/lv_conf.h.in @@ -6,48 +6,17 @@ #ifndef LV_CONF_H #define LV_CONF_H -#include - /* A header file that overwrites with local project settings. */ #if __has_include() # include #endif -/*==================== - Graphical settings - *====================*/ - -/* Type of coordinates. Should be `int16_t` (or `int32_t` for extreme cases) */ -typedef int16_t lv_coord_t; - /*========================= - Memory manager settings + STDLIB WRAPPER SETTINGS *=========================*/ -/* 1: use custom malloc/free, 0: use the built-in `lv_mem_alloc` and `lv_mem_free` */ -#define LV_MEM_CUSTOM 1 - -/*Use the standard `memcpy` and `memset` instead of LVGL's own functions. (Might or might not be faster).*/ -#define LV_MEMCPY_MEMSET_STD 1 - -/*=================== - * HAL settings - *==================*/ - -/* 1: use a custom tick source. - * It removes the need to manually update the tick with `lv_tick_inc`) */ -#define LV_TICK_CUSTOM 1 - /*Header for the system time function*/ -#define LV_TICK_CUSTOM_INCLUDE -/*Expression evaluating to current system time in ms*/ -#define LV_TICK_CUSTOM_SYS_TIME_EXPR (lv_modm_clock_now()) - -/*================ - * Log settings - *===============*/ - -/* 1: Print the log with 'printf'; - * 0: user need to register a callback with `lv_log_register_print_cb`*/ -#define LV_LOG_PRINTF 0 +#define LV_USE_STDLIB_MALLOC LV_STDLIB_CLIB +#define LV_USE_STDLIB_STRING LV_STDLIB_CLIB +#define LV_USE_STDLIB_SPRINTF LV_STDLIB_CLIB #endif /*LV_CONF_H*/ diff --git a/ext/lvgl/lv_modm_clock.cpp b/ext/lvgl/lv_modm_clock.cpp deleted file mode 100644 index 4807970b39..0000000000 --- a/ext/lvgl/lv_modm_clock.cpp +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2021 Niklas Hauser - * - * This file is part of the modm project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#include "lv_modm_clock.h" -#include - -uint32_t lv_modm_clock_now() -{ - return modm::Clock::now().time_since_epoch().count(); -} diff --git a/ext/lvgl/lv_modm_clock.h b/ext/lvgl/lv_modm_clock.h deleted file mode 100644 index 677529247e..0000000000 --- a/ext/lvgl/lv_modm_clock.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2021 Niklas Hauser - * - * This file is part of the modm project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#ifndef LV_MODM_CLOCK_HPP -#define LV_MODM_CLOCK_HPP - -#include -#include - -modm_extern_c uint32_t -lv_modm_clock_now(void); - -#endif diff --git a/ext/lvgl/lv_modm_logging.cpp b/ext/lvgl/lv_modm_logging.cpp deleted file mode 100644 index 61ebc1bc30..0000000000 --- a/ext/lvgl/lv_modm_logging.cpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2021 Raphael Lehmann - * - * This file is part of the modm project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#include -#include - -#if LV_USE_LOG -__attribute__((constructor)) -static void lv_register_modm_logging() -{ - // register modm logging callback with LVGL - lv_log_register_print_cb([](const char *buffer) { MODM_LOG_INFO << buffer; }); -} -#endif diff --git a/ext/lvgl/lv_modm_port.cpp.in b/ext/lvgl/lv_modm_port.cpp.in new file mode 100644 index 0000000000..e272349c91 --- /dev/null +++ b/ext/lvgl/lv_modm_port.cpp.in @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021, 2024 Niklas Hauser + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include +#include +%% if has_debug +#if LV_USE_LOG +# include +#endif +%% endif + +__attribute__((constructor(1000))) +static void modm_lv_init() +{ + lv_init(); + lv_tick_set_cb([]{ return modm::Clock::now().time_since_epoch().count(); }); +%% if has_debug +#if LV_USE_LOG + lv_log_register_print_cb([](lv_log_level_t, const char *buffer) + { + MODM_LOG_INFO << buffer; + }); +#endif +%% endif +} diff --git a/ext/lvgl/lvgl b/ext/lvgl/lvgl index 22f131620a..7c510899d4 160000 --- a/ext/lvgl/lvgl +++ b/ext/lvgl/lvgl @@ -1 +1 @@ -Subproject commit 22f131620a144d0aa813f024322b940d806def64 +Subproject commit 7c510899d4f9911057c3295d6e508fc65d79da6a diff --git a/ext/lvgl/lvgl.lb b/ext/lvgl/lvgl.lb index 5a89f24d8b..21388e1e36 100644 --- a/ext/lvgl/lvgl.lb +++ b/ext/lvgl/lvgl.lb @@ -22,7 +22,6 @@ and low memory footprint. - https://lvgl.io/ - https://github.com/lvgl/lvgl - ## Configuration LVGL defines defaults for all it's configuration settings, which you can find in @@ -31,11 +30,10 @@ the [configuration template][conf_template]. This module generates a `lv_conf.h` file to define the options necessary for integration with modm which are: -- `LV_MEM_CUSTOM = 1`: Heap is provided by the `modm:platform:heap` module. -- `LV_TICK_CUSTOM = 1`: Tick is implemented via the `modm:platform:clock` module. +- Heap is provided by the `modm:platform:heap` module. +- Tick is implemented via the `modm:platform:clock` module. - `LV_LOG_PRINTF = 0`: logging is redirected to `MODM_LOG_*` if the `modm:debug` module is included and `LV_USE_LOG = 1`. -- `typedef int16_t lv_coord_t;`: Hardcoded choice for now. To add your own configuration you can create a `` file which will automatically be included at the *beginning* of our `lv_conf.h`. @@ -64,6 +62,12 @@ Example `` configuration: #define LV_ANTIALIAS 0 ``` +## Initialization + +modm will call `lv_init()` as a constructor with priority 1000 and then set the +required callbacks for the modm port to work. Static constructors are called +afterwards therefore can already use the LVGL functions. + [conf_template]: https://github.com/lvgl/lvgl/blob/master/lv_conf_template.h """ @@ -79,10 +83,8 @@ def build(env): env.outbasepath = "modm/ext/lvgl" env.copy("lvgl/lvgl.h") + env.copy("lvgl/lv_version.h") env.template("lv_conf.h.in") env.copy("lvgl/src") - env.copy("lv_modm_clock.h") - env.copy("lv_modm_clock.cpp") - - if env.has_module(":debug"): - env.copy("lv_modm_logging.cpp") + env.substitutions = {"has_debug": env.has_module(":debug")} + env.template("lv_modm_port.cpp.in")