diff --git a/.gitmodules b/.gitmodules index da779449f51..e4844a6aeb8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -14,4 +14,4 @@ [submodule "radio/src/thirdparty/libopenui/thirdparty/lvgl"] path = radio/src/thirdparty/libopenui/thirdparty/lvgl url = https://github.com/EdgeTX/lvgl.git - branch = release/v8.2 + branch = v8.3-patched diff --git a/radio/src/MultiProtoDefs.h b/radio/src/MultiProtoDefs.h index 934b96b85ca..1b824bc7ed3 100644 --- a/radio/src/MultiProtoDefs.h +++ b/radio/src/MultiProtoDefs.h @@ -20,7 +20,7 @@ */ // -// Data based on MPM firmware version 1.3.3.20 +// Data based on MPM firmware version 1.3.3.33 multi.txt // #if defined(MULTIMODULE) or defined(SIMU) @@ -125,6 +125,7 @@ enum ModuleSubtypeMulti { MODULE_SUBTYPE_MULTI_XERALL, //90 MODULE_SUBTYPE_MULTI_MT99XX2, MODULE_SUBTYPE_MULTI_KYOSHO2, + MODULE_SUBTYPE_MULTI_SCORPIO, // // spare entries - don't touch, // just add to known protocols @@ -163,7 +164,7 @@ enum ModuleSubtypeMulti { "Tiger", "XK","XN297DU","FrSkyX2","FrSkyR9","Propel","FrSky L","Skyartc","ESkyV2","DSM_RX",\ "JJRC345","Q90C","Kyosho","RadLink","ExpLRS","Realacc","OMP","M-Link","WFLY2","E016Hv2",\ "E010r5","LOLI","E129","JOYSWAY","E016H","Config","IKEA","WILLIFM","Losi","MouldKg",\ - "Xerall","MT99XX2", "Kyosho2" + "Xerall","MT99XX2", "Kyosho2", "Scorpio" #define SPARE_PROTO_NAMES \ "NN 1","NN 2","NN 3","NN 4","NN 5","NN 6","NN 7","NN 8","NN 9","NN 10" #define SPARE_SUBTYPE_NAMES \ diff --git a/radio/src/MultiSubtypeDefs.h b/radio/src/MultiSubtypeDefs.h index be7228b4eb9..ad9a9e42fa6 100644 --- a/radio/src/MultiSubtypeDefs.h +++ b/radio/src/MultiSubtypeDefs.h @@ -20,7 +20,7 @@ */ // -// Data based on MPM firmware version 1.3.3.20 +// Data based on MPM firmware version 1.3.3.33 multi.txt // #if defined(MULTIMODULE) or defined(SIMU) @@ -123,7 +123,7 @@ STRLIST(STR_SUBTYPE_E01X, {"E012","E015"}) STRLIST(STR_SUBTYPE_V911S, {"Std","E119"}) STRLIST(STR_SUBTYPE_GD00X, {"GD_V1","GD_V2"}) STRLIST(STR_SUBTYPE_V761, {"3ch","4ch","TOPRC"}) -STRLIST(STR_SUBTYPE_KF606, {"KF606","MIG320"}) +STRLIST(STR_SUBTYPE_KF606, {"KF606","MIG320","ZCZ50"}) STRLIST(STR_SUBTYPE_REDPINE, {"Fast","Slow"}) STRLIST(STR_SUBTYPE_POTENSIC, {"A20"}) STRLIST(STR_SUBTYPE_ZSX, {"280JJRC"}) @@ -148,6 +148,7 @@ STRLIST(STR_SUBTYPE_WFLY2, {"RF20x"}) STRLIST(STR_SUBTYPE_MOULDKG, {"Analog","Digital"}) STRLIST(STR_SUBTYPE_MT992, {"PA18"}) STRLIST(STR_SUBTYPE_RX, {"Multi","CPPM"}) +STRLIST(STR_SUBTYPE_DSM_RX, {"Multi","CloneTX","EraseTX","CPPM"}) STRLIST(STR_SUBTYPE_E129, {"STD","C186"}) // @@ -209,7 +210,7 @@ PROTODEF { {MODULE_SUBTYPE_MULTI_V911S, 1, false, false, STR_SUBTYPE_V911S, STR_MULTI_RFTUNE}, {MODULE_SUBTYPE_MULTI_GD00X, 1, false, false, STR_SUBTYPE_GD00X, STR_MULTI_RFTUNE}, {MODULE_SUBTYPE_MULTI_V761, 2, false, false, STR_SUBTYPE_V761, nullptr}, - {MODULE_SUBTYPE_MULTI_KF606, 1, false, false, STR_SUBTYPE_KF606, STR_MULTI_RFTUNE}, + {MODULE_SUBTYPE_MULTI_KF606, 2, false, false, STR_SUBTYPE_KF606, STR_MULTI_RFTUNE}, {MODULE_SUBTYPE_MULTI_REDPINE, 1, false, false, STR_SUBTYPE_REDPINE, STR_MULTI_RFTUNE}, {MODULE_SUBTYPE_MULTI_POTENSIC, 0, false, false, STR_SUBTYPE_POTENSIC, nullptr}, {MODULE_SUBTYPE_MULTI_ZSX, 0, false, false, STR_SUBTYPE_ZSX, nullptr}, @@ -230,7 +231,7 @@ PROTODEF { {MODULE_SUBTYPE_MULTI_FRSKYL, 1, false, false, STR_SUBTYPE_FRSKYL, STR_MULTI_RFTUNE}, {MODULE_SUBTYPE_MULTI_SKYARTEC, 0, false, true, NO_SUBTYPE, STR_MULTI_RFTUNE}, {MODULE_SUBTYPE_MULTI_ESKY150V2, 0, false, true, STR_SUBTYPE_ESKY150V2, STR_MULTI_RFTUNE}, - {MODULE_SUBTYPE_MULTI_DSM_RX, 1, false, true, STR_SUBTYPE_RX, nullptr}, //new + {MODULE_SUBTYPE_MULTI_DSM_RX, 3, false, true, STR_SUBTYPE_DSM_RX, nullptr}, //new {MODULE_SUBTYPE_MULTI_JJRC345, 1, false, false, STR_SUBTYPE_JJRC345, nullptr}, {MODULE_SUBTYPE_MULTI_Q90C, 0, false, false, NO_SUBTYPE, STR_MULTI_RFTUNE}, {MODULE_SUBTYPE_MULTI_KYOSHO, 1, false, true, STR_SUBTYPE_KYOSHO, nullptr}, @@ -254,6 +255,7 @@ PROTODEF { {MODULE_SUBTYPE_MULTI_XERALL, 0, false, false, NO_SUBTYPE, nullptr}, //new {MODULE_SUBTYPE_MULTI_MT99XX2, 0, false, false, STR_SUBTYPE_MT992, nullptr}, {MODULE_SUBTYPE_MULTI_KYOSHO2, 0, false, false, STR_SUBTYPE_KYOSHO2, nullptr}, + {MODULE_SUBTYPE_MULTI_SCORPIO, 0, false, true, NO_SUBTYPE, nullptr}, {MODULE_SUBTYPE_MULTI_NN1, 7, true, true, STR_SUBTYPE_NN, STR_MULTI_OPTION}, {MODULE_SUBTYPE_MULTI_NN2, 7, true, true, STR_SUBTYPE_NN, STR_MULTI_OPTION}, {MODULE_SUBTYPE_MULTI_NN3, 7, true, true, STR_SUBTYPE_NN, STR_MULTI_OPTION}, diff --git a/radio/src/gui/colorlcd/standalone_lua.cpp b/radio/src/gui/colorlcd/standalone_lua.cpp index 5d54816a782..2be86944bcb 100644 --- a/radio/src/gui/colorlcd/standalone_lua.cpp +++ b/radio/src/gui/colorlcd/standalone_lua.cpp @@ -126,7 +126,7 @@ void StandaloneLuaWindow::checkEvents() if (luaState != INTERPRETER_RELOAD_PERMANENT_SCRIPTS) { // if LUA finished a full cycle, // invalidate to display the screen buffer - if (luaTask(0, true)) { invalidate(); } + if (luaTask(true)) { invalidate(); } } if (luaState == INTERPRETER_RELOAD_PERMANENT_SCRIPTS) { diff --git a/radio/src/gui/colorlcd/themes/etx_lv_theme.cpp b/radio/src/gui/colorlcd/themes/etx_lv_theme.cpp index daa0d75d435..1b251e7c25d 100644 --- a/radio/src/gui/colorlcd/themes/etx_lv_theme.cpp +++ b/radio/src/gui/colorlcd/themes/etx_lv_theme.cpp @@ -52,7 +52,6 @@ static lv_theme_t theme; #define LV_STYLE_CONST_SINGLE_INIT(var_name, prop, value) \ const lv_style_t var_name = {.v_p = {.value1 = {.num = value}}, \ .prop1 = prop, \ - .is_const = 0, \ .has_group = 1 << ((prop & 0x1FF) >> 4), \ .prop_cnt = 1} @@ -60,10 +59,9 @@ static lv_theme_t theme; // Copied from lv_style.h and modified to compile with ARM GCC C++ #define LV_STYLE_CONST_MULTI_INIT(var_name, prop_array) \ const lv_style_t var_name = {.v_p = {.const_props = prop_array}, \ - .prop1 = 0, \ - .is_const = 1, \ + .prop1 = LV_STYLE_PROP_ANY, \ .has_group = 0xFF, \ - .prop_cnt = 0} + .prop_cnt = (sizeof(prop_array) / sizeof((prop_array)[0]))} // Opacity LV_STYLE_CONST_SINGLE_INIT(bg_opacity_transparent, LV_STYLE_BG_OPA, @@ -286,33 +284,41 @@ class EdgeTxStyles lv_style_t font_std; lv_style_t font_bold; - EdgeTxStyles() + EdgeTxStyles() {} + + void init() { - // Colors - for (int i = DEFAULT_COLOR_INDEX; i < LCD_COLOR_COUNT; i += 1) { - lv_style_init(&bg_color[i]); - lv_style_init(&txt_color[i]); + if (!initDone) { + initDone = true; + + // Colors + for (int i = DEFAULT_COLOR_INDEX; i < LCD_COLOR_COUNT; i += 1) { + lv_style_init(&bg_color[i]); + lv_style_init(&txt_color[i]); + } + lv_style_init(&border_color_secondary1); + lv_style_init(&border_color_secondary2); + lv_style_init(&border_color_focus); + + lv_style_init(&bg_color_grey); + lv_style_set_bg_color(&bg_color_grey, lv_palette_main(LV_PALETTE_GREY)); + lv_style_init(&bg_color_white); + lv_style_set_bg_color(&bg_color_white, lv_color_white()); + lv_style_init(&bg_color_black); + lv_style_set_bg_color(&bg_color_black, lv_color_black()); + lv_style_init(&fg_color_black); + lv_style_set_text_color(&fg_color_black, lv_color_black()); + lv_style_init(&border_color_black); + lv_style_set_border_color(&border_color_black, lv_color_black()); + + // Fonts + lv_style_init(&font_std); + lv_style_set_text_font(&font_std, getFont(FONT(STD))); + lv_style_init(&font_bold); + lv_style_set_text_font(&font_bold, getFont(FONT(BOLD))); + + applyColors(); } - lv_style_init(&border_color_secondary1); - lv_style_init(&border_color_secondary2); - lv_style_init(&border_color_focus); - - lv_style_init(&bg_color_grey); - lv_style_set_bg_color(&bg_color_grey, lv_palette_main(LV_PALETTE_GREY)); - lv_style_init(&bg_color_white); - lv_style_set_bg_color(&bg_color_white, lv_color_white()); - lv_style_init(&bg_color_black); - lv_style_set_bg_color(&bg_color_black, lv_color_black()); - lv_style_init(&fg_color_black); - lv_style_set_text_color(&fg_color_black, lv_color_black()); - lv_style_init(&border_color_black); - lv_style_set_border_color(&border_color_black, lv_color_black()); - - // Fonts - lv_style_init(&font_std); - lv_style_set_text_font(&font_std, getFont(FONT(STD))); - lv_style_init(&font_bold); - lv_style_set_text_font(&font_bold, getFont(FONT(BOLD))); } void applyColors() @@ -334,11 +340,12 @@ class EdgeTxStyles } protected: + bool initDone = false; }; -static EdgeTxStyles* styles; +static EdgeTxStyles mainStyles; static EdgeTxStyles* previewStyles; -static EdgeTxStyles* mainStyles; +static EdgeTxStyles* styles = &mainStyles; /********************** * GLOBAL FUNCTIONS @@ -355,11 +362,7 @@ lv_theme_t* etx_lv_theme_init(lv_disp_t* disp, lv_color_t color_primary, theme.font_large = font; theme.flags = 0; - if (!styles) { - styles = new EdgeTxStyles(); - mainStyles = styles; - } - styles->applyColors(); + styles->init(); if (disp == NULL || lv_disp_get_theme(disp) == &theme) lv_obj_report_style_change(NULL); @@ -374,7 +377,7 @@ void usePreviewStyle() styles->applyColors(); } -void useMainStyle() { styles = mainStyles; } +void useMainStyle() { styles = &mainStyles; } /********************** * Custom object creation @@ -569,8 +572,7 @@ void etx_switch_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj) void etx_slider_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj) { - etx_add_colors_and_opacity(obj, LV_PART_MAIN, - COLOR_THEME_SECONDARY1_INDEX, + etx_add_colors_and_opacity(obj, LV_PART_MAIN, COLOR_THEME_SECONDARY1_INDEX, COLOR_THEME_PRIMARY2_INDEX); lv_obj_add_style(obj, (lv_style_t*)&circle, LV_PART_MAIN); lv_obj_add_style(obj, &styles->bg_color[COLOR_THEME_FOCUS_INDEX], @@ -586,7 +588,8 @@ void etx_slider_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj) lv_obj_add_style(obj, (lv_style_t*)&bg_opacity_cover, LV_PART_KNOB); lv_obj_add_style(obj, (lv_style_t*)&slider_knob, LV_PART_KNOB); lv_obj_add_style(obj, &styles->border_color_secondary1, LV_PART_KNOB); - lv_obj_add_style(obj, &styles->border_color_focus, LV_PART_KNOB | LV_STATE_FOCUSED); + lv_obj_add_style(obj, &styles->border_color_focus, + LV_PART_KNOB | LV_STATE_FOCUSED); } void etx_btnmatrix_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj) diff --git a/radio/src/lua/interface.cpp b/radio/src/lua/interface.cpp index b6073d970d4..7fa68db68d0 100644 --- a/radio/src/lua/interface.cpp +++ b/radio/src/lua/interface.cpp @@ -1255,14 +1255,11 @@ static bool resumeLua(bool init, bool allowLcdUsage) } //resumeLua(...) -bool luaTask(event_t evt, bool allowLcdUsage) +bool luaTask(bool allowLcdUsage) { bool init = false; bool scriptWasRun = false; - // Add event to buffer - if (evt != 0) { luaPushEvent(evt); } - // For preemption luaCycleStart = get_tmr10ms(); diff --git a/radio/src/lua/lua_api.h b/radio/src/lua/lua_api.h index a80afede465..6cc3a21e404 100644 --- a/radio/src/lua/lua_api.h +++ b/radio/src/lua/lua_api.h @@ -189,7 +189,7 @@ extern ScriptInternalData scriptInternalData[MAX_SCRIPTS]; extern ScriptInputsOutputs scriptInputsOutputs[MAX_SCRIPTS]; void luaClose(lua_State ** L); -bool luaTask(event_t evt, bool allowLcdUsage); +bool luaTask(bool allowLcdUsage); void checkLuaMemoryUsage(); void luaExec(const char * filename); void luaDoGc(lua_State * L, bool full); diff --git a/radio/src/lv_conf.h b/radio/src/lv_conf.h index 549ec06bf80..57d1fa4ba28 100644 --- a/radio/src/lv_conf.h +++ b/radio/src/lv_conf.h @@ -29,9 +29,9 @@ /*Swap the 2 bytes of RGB565 color. Useful if the display has an 8-bit interface (e.g. SPI)*/ #define LV_COLOR_16_SWAP 0 -/*Enable more complex drawing routines to manage screens transparency. - *Can be used if the UI is above another layer, e.g. an OSD menu or video player. - *Requires `LV_COLOR_DEPTH = 32` colors and the screen's `bg_opa` should be set to non LV_OPA_COVER value*/ +/*Enable features to draw on transparent background. + *It's required if opa, and transform_* style properties are used. + *Can be also used if the UI is above another layer, e.g. an OSD menu or video player.*/ #define LV_COLOR_SCREEN_TRANSP 0 /* Adjust color mix functions rounding. GPUs might calculate color mix (blending) differently. @@ -49,14 +49,14 @@ #define LV_MEM_CUSTOM 1 #if LV_MEM_CUSTOM == 0 /*Size of the memory available for `lv_mem_alloc()` in bytes (>= 2kB)*/ - #define LV_MEM_SIZE (8U * 1024U) /*[bytes]*/ + #define LV_MEM_SIZE (48U * 1024U) /*[bytes]*/ /*Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too.*/ #define LV_MEM_ADR 0 /*0: unused*/ /*Instead of an address give a memory allocator that will be called to get a memory pool for LVGL. E.g. my_malloc*/ #if LV_MEM_ADR == 0 - //#define LV_MEM_POOL_INCLUDE your_alloc_library /* Uncomment if using an external allocator*/ - //#define LV_MEM_POOL_ALLOC your_alloc /* Uncomment if using an external allocator*/ + #undef LV_MEM_POOL_INCLUDE + #undef LV_MEM_POOL_ALLOC #endif #else /*LV_MEM_CUSTOM*/ @@ -89,6 +89,9 @@ #if LV_TICK_CUSTOM #define LV_TICK_CUSTOM_INCLUDE "Arduino.h" /*Header for the system time function*/ #define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current system time in ms*/ + /*If using lvgl as ESP32 component*/ + // #define LV_TICK_CUSTOM_INCLUDE "esp_timer.h" + // #define LV_TICK_CUSTOM_SYS_TIME_EXPR ((esp_timer_get_time() / 1000LL)) #endif /*LV_TICK_CUSTOM*/ /*Default Dot Per Inch. Used to initialize default sizes such as widgets sized, style paddings. @@ -126,33 +129,49 @@ #define LV_CIRCLE_CACHE_SIZE 4 #endif /*LV_DRAW_COMPLEX*/ +/** + * "Simple layers" are used when a widget has `style_opa < 255` to buffer the widget into a layer + * and blend it as an image with the given opacity. + * Note that `bg_opa`, `text_opa` etc don't require buffering into layer) + * The widget can be buffered in smaller chunks to avoid using large buffers. + * + * - LV_LAYER_SIMPLE_BUF_SIZE: [bytes] the optimal target buffer size. LVGL will try to allocate it + * - LV_LAYER_SIMPLE_FALLBACK_BUF_SIZE: [bytes] used if `LV_LAYER_SIMPLE_BUF_SIZE` couldn't be allocated. + * + * Both buffer sizes are in bytes. + * "Transformed layers" (where transform_angle/zoom properties are used) use larger buffers + * and can't be drawn in chunks. So these settings affects only widgets with opacity. + */ +#define LV_LAYER_SIMPLE_BUF_SIZE (24 * 1024) +#define LV_LAYER_SIMPLE_FALLBACK_BUF_SIZE (3 * 1024) + /*Default image cache size. Image caching keeps the images opened. *If only the built-in image formats are used there is no real advantage of caching. (I.e. if no new image decoder is added) *With complex image decoders (e.g. PNG or JPG) caching can save the continuous open/decode of images. *However the opened images might consume additional RAM. *0: to disable caching*/ -#define LV_IMG_CACHE_DEF_SIZE 0 +#define LV_IMG_CACHE_DEF_SIZE 0 /*Number of stops allowed per gradient. Increase this to allow more stops. *This adds (sizeof(lv_color_t) + 1) bytes per additional stop*/ -#define LV_GRADIENT_MAX_STOPS 2 +#define LV_GRADIENT_MAX_STOPS 2 /*Default gradient buffer size. *When LVGL calculates the gradient "maps" it can save them into a cache to avoid calculating them again. *LV_GRAD_CACHE_DEF_SIZE sets the size of this cache in bytes. *If the cache is too small the map will be allocated only while it's required for the drawing. *0 mean no caching.*/ -#define LV_GRAD_CACHE_DEF_SIZE 0 +#define LV_GRAD_CACHE_DEF_SIZE 0 /*Allow dithering the gradients (to achieve visual smooth color gradients on limited color depth display) *LV_DITHER_GRADIENT implies allocating one or two more lines of the object's rendering surface *The increase in memory consumption is (32 bits * object width) plus 24 bits * object width if using error diffusion */ -#define LV_DITHER_GRADIENT 0 +#define LV_DITHER_GRADIENT 0 #if LV_DITHER_GRADIENT /*Add support for error diffusion dithering. *Error diffusion dithering gets a much better visual result, but implies more CPU consumption and memory when drawing. *The increase in memory consumption is (24 bits * object's width)*/ - #define LV_DITHER_ERROR_DIFFUSION 0 + #define LV_DITHER_ERROR_DIFFUSION 0 #endif /*Maximum buffer size to allocate for rotation. @@ -163,6 +182,9 @@ * GPU *-----------*/ +/*Use Arm's 2D acceleration library Arm-2D */ +#define LV_USE_GPU_ARM2D 0 + /*Use STM32's DMA2D (aka Chrom Art) GPU*/ #if defined(SIMU) #define LV_USE_GPU_STM32_DMA2D 0 @@ -172,7 +194,7 @@ #if LV_USE_GPU_STM32_DMA2D /*Must be defined to include path of CMSIS header of target processor e.g. "stm32f769xx.h" or "stm32f429xx.h"*/ - #define LV_GPU_DMA2D_CMSIS_INCLUDE "stm32f4xx.h" + #define LV_GPU_DMA2D_CMSIS_INCLUDE "thirdparty/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h" #if !defined(DMA2D_NLR_PL_Pos) #define DMA2D_NLR_PL_Pos 16 #endif @@ -190,6 +212,11 @@ #endif #endif +/*Use SWM341's DMA2D GPU*/ +#define LV_USE_GPU_SWM341_DMA2D 0 +#if LV_USE_GPU_SWM341_DMA2D + #define LV_GPU_SWM341_DMA2D_INCLUDE "SWM341.h" +#endif /*Use NXP's PXP GPU iMX RTxxx platforms*/ #define LV_USE_GPU_NXP_PXP 0 #if LV_USE_GPU_NXP_PXP @@ -492,6 +519,9 @@ #define LV_FONT_SUBPX_BGR 0 /*0: RGB; 1:BGR order*/ #endif +/*Enable drawing placeholders when glyph dsc is not found*/ +#define LV_USE_FONT_PLACEHOLDER 1 + /*================= * TEXT SETTINGS *=================*/ @@ -726,7 +756,7 @@ #if LV_USE_FS_STDIO #define LV_FS_STDIO_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ #define LV_FS_STDIO_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/ - #define LV_FS_STDIO_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ + #define LV_FS_STDIO_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ #endif /*API for open, read, etc*/ @@ -734,13 +764,13 @@ #if LV_USE_FS_POSIX #define LV_FS_POSIX_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ #define LV_FS_POSIX_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/ - #define LV_FS_POSIX_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ + #define LV_FS_POSIX_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ #endif /*API for CreateFile, ReadFile, etc*/ #define LV_USE_FS_WIN32 0 #if LV_USE_FS_WIN32 - #define LV_FS_WIN32_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ + #define LV_FS_WIN32_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ #define LV_FS_WIN32_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/ #define LV_FS_WIN32_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ #endif @@ -802,10 +832,10 @@ /*FFmpeg library for image decoding and playing videos *Supports all major image formats so do not enable other image decoder with it*/ -#define LV_USE_FFMPEG 0 +#define LV_USE_FFMPEG 0 #if LV_USE_FFMPEG /*Dump input information to stderr*/ - #define LV_FFMPEG_AV_DUMP_FORMAT 0 + #define LV_FFMPEG_DUMP_FORMAT 0 #endif /*----------- @@ -821,6 +851,33 @@ /*1: Enable grid navigation*/ #define LV_USE_GRIDNAV 0 +/*1: Enable lv_obj fragment*/ +#define LV_USE_FRAGMENT 0 + +/*1: Support using images as font in label or span widgets */ +#define LV_USE_IMGFONT 0 + +/*1: Enable a published subscriber based messaging system */ +#define LV_USE_MSG 0 + +/*1: Enable Pinyin input method*/ +/*Requires: lv_keyboard*/ +#define LV_USE_IME_PINYIN 0 +#if LV_USE_IME_PINYIN + /*1: Use default thesaurus*/ + /*If you do not use the default thesaurus, be sure to use `lv_ime_pinyin` after setting the thesauruss*/ + #define LV_IME_PINYIN_USE_DEFAULT_DICT 1 + /*Set the maximum number of candidate panels that can be displayed*/ + /*This needs to be adjusted according to the size of the screen*/ + #define LV_IME_PINYIN_CAND_TEXT_NUM 6 + + /*Use 9 key input(k9)*/ + #define LV_IME_PINYIN_USE_K9_MODE 1 + #if LV_IME_PINYIN_USE_K9_MODE == 1 + #define LV_IME_PINYIN_K9_CAND_TEXT_NUM 3 + #endif // LV_IME_PINYIN_USE_K9_MODE +#endif + /*================== * EXAMPLES *==================*/ @@ -833,28 +890,32 @@ ====================*/ /*Show some widget. It might be required to increase `LV_MEM_SIZE` */ -#define LV_USE_DEMO_WIDGETS 0 +#define LV_USE_DEMO_WIDGETS 0 #if LV_USE_DEMO_WIDGETS -#define LV_DEMO_WIDGETS_SLIDESHOW 0 +#define LV_DEMO_WIDGETS_SLIDESHOW 0 #endif /*Demonstrate the usage of encoder and keyboard*/ -#define LV_USE_DEMO_KEYPAD_AND_ENCODER 0 +#define LV_USE_DEMO_KEYPAD_AND_ENCODER 0 /*Benchmark your system*/ -#define LV_USE_DEMO_BENCHMARK 0 +#define LV_USE_DEMO_BENCHMARK 0 +#if LV_USE_DEMO_BENCHMARK +/*Use RGB565A8 images with 16 bit color depth instead of ARGB8565*/ +#define LV_DEMO_BENCHMARK_RGB565A8 0 +#endif /*Stress test for LVGL*/ -#define LV_USE_DEMO_STRESS 0 +#define LV_USE_DEMO_STRESS 0 /*Music player demo*/ -#define LV_USE_DEMO_MUSIC 0 +#define LV_USE_DEMO_MUSIC 0 #if LV_USE_DEMO_MUSIC -# define LV_DEMO_MUSIC_SQUARE 0 -# define LV_DEMO_MUSIC_LANDSCAPE 0 -# define LV_DEMO_MUSIC_ROUND 0 -# define LV_DEMO_MUSIC_LARGE 0 -# define LV_DEMO_MUSIC_AUTO_PLAY 0 + #define LV_DEMO_MUSIC_SQUARE 0 + #define LV_DEMO_MUSIC_LANDSCAPE 0 + #define LV_DEMO_MUSIC_ROUND 0 + #define LV_DEMO_MUSIC_LARGE 0 + #define LV_DEMO_MUSIC_AUTO_PLAY 0 #endif /*--END OF LV_CONF_H--*/ diff --git a/radio/src/main.cpp b/radio/src/main.cpp index 42c4f16e4c6..4c61303689e 100644 --- a/radio/src/main.cpp +++ b/radio/src/main.cpp @@ -34,6 +34,10 @@ #include "cli.h" #endif +#if defined(LUA) + #include "lua/lua_event.h" +#endif + uint8_t currentSpeakerVolume = 255; uint8_t requiredSpeakerVolume = 255; uint8_t currentBacklightBright = 0; @@ -394,7 +398,7 @@ void guiMain(event_t evt) } DEBUG_TIMER_START(debugTimerLua); - luaTask(0, false); + luaTask(false); DEBUG_TIMER_STOP(debugTimerLua); t0 = get_tmr10ms() - t0; @@ -429,14 +433,17 @@ void guiMain(event_t evt) bool handleGui(event_t event) { bool refreshNeeded; #if defined(LUA) - refreshNeeded = luaTask(event, true); - if (menuHandlers[menuLevel] == menuViewTelemetry && - TELEMETRY_SCREEN_TYPE(s_frsky_view) == TELEMETRY_SCREEN_TYPE_SCRIPT) { - menuHandlers[menuLevel](event); - } + bool isTelemView = + menuHandlers[menuLevel] == menuViewTelemetry && + TELEMETRY_SCREEN_TYPE(s_frsky_view) == TELEMETRY_SCREEN_TYPE_SCRIPT; + bool isStandalone = scriptInternalData[0].reference == SCRIPT_STANDALONE; + if (isTelemView || isStandalone) luaPushEvent(event); + refreshNeeded = luaTask(true); + if (isTelemView) + menuHandlers[menuLevel](event); else if (scriptInternalData[0].reference != SCRIPT_STANDALONE) #endif -// No foreground Lua script is running - clear the screen show normal menu + // No foreground Lua script is running - clear the screen show normal menu { lcdClear(); menuHandlers[menuLevel](event); @@ -460,7 +467,7 @@ void guiMain(event_t evt) } // run Lua scripts that don't use LCD (to use CPU time while LCD DMA is running) - luaTask(0, false); + luaTask(false); t0 = get_tmr10ms() - t0; if (t0 > maxLuaDuration) { diff --git a/radio/src/mixer.cpp b/radio/src/mixer.cpp index 6e7f0e6b19a..39bcc4b6662 100644 --- a/radio/src/mixer.cpp +++ b/radio/src/mixer.cpp @@ -20,6 +20,7 @@ */ #include "opentx.h" +#include "opentx_types.h" #include "timers.h" #include "switches.h" #include "input_mapping.h" @@ -634,6 +635,31 @@ int getSourceTrimValue(int source, int stickValue=0) } } +constexpr bitfield_channels_t all_channels_dirty = (bitfield_channels_t)-1; + +static inline bitfield_channels_t channel_bit(uint16_t ch) +{ + return (bitfield_channels_t)1 << ch; +} + +static inline bitfield_channels_t channel_dirty(bitfield_channels_t mask, uint16_t ch) +{ + return mask & channel_bit(ch); +} + +static inline bitfield_channels_t upper_channels_mask(uint16_t ch) +{ + // take the 2's complement to generate a bit pattern + // that has all bits of 'ch' order and above set + // + // Examples (mask for max 8 channels): + // - channel 0: 0b11111111 + // - channel 1: 0b11111110 + // - channel 2: 0b11111100 + + return ~(channel_bit(ch)) + 1; +} + uint8_t mixerCurrentFlightMode; void evalFlightModeMixes(uint8_t mode, uint8_t tick10ms) @@ -714,11 +740,10 @@ void evalFlightModeMixes(uint8_t mode, uint8_t tick10ms) memclear(chans, sizeof(chans)); // all outputs to 0 //========== MIXER LOOP =============== - uint8_t lv_mixWarning = 0; uint8_t pass = 0; - - bitfield_channels_t dirtyChannels = (bitfield_channels_t)-1; // all dirty when mixer starts + uint8_t lv_mixWarning = 0; + bitfield_channels_t dirtyChannels = all_channels_dirty; do { bitfield_channels_t passDirtyChannels = 0; @@ -729,62 +754,76 @@ void evalFlightModeMixes(uint8_t mode, uint8_t tick10ms) MixData * md = mixAddress(i); - if (md->srcRaw == 0) + if (md->srcRaw == 0) { #if defined(COLORLCD) continue; #else break; #endif + } - mixsrc_t stickIndex = md->srcRaw - MIXSRC_FIRST_STICK; - - if (!(dirtyChannels & ((bitfield_channels_t)1 << md->destCh))) + if (!channel_dirty(dirtyChannels, md->destCh)) continue; - // if this is the first calculation for the destination channel, initialize it with 0 (otherwise would be random) - if (i == 0 || md->destCh != (md-1)->destCh) + // if this is the first calculation for the destination channel, + // initialize it with 0 (otherwise would be random) + if (i == 0 || md->destCh != (md - 1)->destCh) chans[md->destCh] = 0; //========== FLIGHT MODE && SWITCH ===== - bool mixCondition = (md->flightModes != 0 || md->swtch); - delayval_t mixEnabled = (!(md->flightModes & (1 << mixerCurrentFlightMode)) && getSwitch(md->swtch)) ? DELAY_POS_MARGIN+1 : 0; - -#define MIXER_LINE_DISABLE() (mixCondition = true, mixEnabled = 0) - - if (mixEnabled && md->srcRaw >= MIXSRC_FIRST_TRAINER && md->srcRaw <= MIXSRC_LAST_TRAINER && !is_trainer_connected()) { - MIXER_LINE_DISABLE(); - } + bool fmEnabled = (md->flightModes & (1 << mixerCurrentFlightMode)) == 0; + bool mixLineActive = fmEnabled && getSwitch(md->swtch); + + if (mixLineActive) { + // disable mixer using trainer channels if not connected + if (md->srcRaw >= MIXSRC_FIRST_TRAINER && + md->srcRaw <= MIXSRC_LAST_TRAINER && !is_trainer_connected()) { + mixLineActive = false; + } #if defined(LUA_MODEL_SCRIPTS) - // disable mixer if Lua script is used as source and script was killed - if (mixEnabled && md->srcRaw >= MIXSRC_FIRST_LUA && md->srcRaw <= MIXSRC_LAST_LUA) { - div_t qr = div(md->srcRaw-MIXSRC_FIRST_LUA, MAX_SCRIPT_OUTPUTS); - if (scriptInternalData[qr.quot].state != SCRIPT_OK) { - MIXER_LINE_DISABLE(); + // disable mixer if Lua script is used as source and script was killed + if (md->srcRaw >= MIXSRC_FIRST_LUA && md->srcRaw <= MIXSRC_LAST_LUA) { + div_t qr = div(md->srcRaw - MIXSRC_FIRST_LUA, MAX_SCRIPT_OUTPUTS); + if (scriptInternalData[qr.quot].state != SCRIPT_OK) { + mixLineActive = false; + } } - } #endif + } //========== VALUE =============== getvalue_t v = 0; + if (mode > e_perout_mode_inactive_flight_mode) { - if (mixEnabled) - v = getValue(md->srcRaw); - else - continue; - } - else { - mixsrc_t srcRaw = MIXSRC_FIRST_STICK + stickIndex; + if (!mixLineActive) continue; + v = getValue(md->srcRaw); + } else { + mixsrc_t srcRaw = md->srcRaw; v = getValue(srcRaw); - srcRaw -= MIXSRC_FIRST_CH; - if (srcRaw <= MIXSRC_LAST_CH-MIXSRC_FIRST_CH && md->destCh != srcRaw) { - if (dirtyChannels & ((bitfield_channels_t)1 << srcRaw) & (passDirtyChannels|~(((bitfield_channels_t) 1 << md->destCh)-1))) - passDirtyChannels |= (bitfield_channels_t) 1 << md->destCh; - if (srcRaw < md->destCh || pass > 0) - v = chans[srcRaw] >> 8; - } - if (!mixCondition) { - mixEnabled = v; + + if (srcRaw >= MIXSRC_FIRST_CH) { + + auto srcChan = srcRaw - MIXSRC_FIRST_CH; + if (srcChan <= MAX_OUTPUT_CHANNELS && md->destCh != srcChan) { + + // check whether we need to recompute the current channel later + bitfield_channels_t upperChansMask = upper_channels_mask(md->destCh); + bitfield_channels_t srcChanDirtyMask = channel_dirty(dirtyChannels, srcChan); + + // if the source is any of the channels marked as dirty + // or contained in [ destCh, MAX_OUTPUT_CHANNELS [ + if (srcChanDirtyMask & (passDirtyChannels | upperChansMask)) { + passDirtyChannels |= channel_bit(md->destCh); + } + + // if the source has already be computed, + // then use it! + if (srcChan < md->destCh || pass > 0) { + // channels are in [ -1024 * 256, 1024 * 256 ] + v = chans[srcChan] >> 8; + } + } } } @@ -793,41 +832,35 @@ void evalFlightModeMixes(uint8_t mode, uint8_t tick10ms) //========== DELAYS =============== delayval_t _swOn = swOn[i].now; delayval_t _swPrev = swOn[i].prev; - bool swTog = (mixEnabled > _swOn+DELAY_POS_MARGIN || mixEnabled < _swOn-DELAY_POS_MARGIN); + + delayval_t v_active = mixLineActive ? v : 0; + + bool swTog = (v_active > _swOn + DELAY_POS_MARGIN || v_active < _swOn - DELAY_POS_MARGIN); if (mode == e_perout_mode_normal && swTog) { - if (!swOn[i].delay) - _swPrev = _swOn; - swOn[i].delay = (mixEnabled > _swOn ? md->delayUp : md->delayDown) * 10; - swOn[i].now = mixEnabled; - swOn[i].prev = _swPrev; + if (!swOn[i].delay) { swOn[i].prev = _swOn; } + swOn[i].now = v_active; + swOn[i].delay = (v_active > _swOn ? md->delayUp : md->delayDown) * 10; } if (mode == e_perout_mode_normal && swOn[i].delay > 0) { swOn[i].delay = max(0, (int16_t)swOn[i].delay - tick10ms); - if (!mixCondition) - v = _swPrev; - else if (mixEnabled) - continue; + v = _swPrev; } else { - if (mode==e_perout_mode_normal) { - swOn[i].now = swOn[i].prev = mixEnabled; + if (mode == e_perout_mode_normal) { + swOn[i].now = swOn[i].prev = v_active; } - if (!mixEnabled) { - if ((md->speedDown || md->speedUp) && md->mltpx!=MLTPX_REPL) { - if (mixCondition) { - v = (md->mltpx == MLTPX_ADD ? 0 : RESX); - applyOffsetAndCurve = false; - } - } - else if (mixCondition) { + if (!mixLineActive) { + if ((md->speedDown || md->speedUp) && md->mltpx != MLTPX_REPL) { + v = (md->mltpx == MLTPX_ADD ? 0 : RESX); + applyOffsetAndCurve = false; + } else { continue; } } } - if (mode==e_perout_mode_normal && (!mixCondition || mixEnabled || swOn[i].delay)) { - if (md->mixWarn) - lv_mixWarning |= 1 << (md->mixWarn - 1); + if (mode == e_perout_mode_normal && (mixLineActive || swOn[i].delay)) { + if (md->mixWarn) lv_mixWarning |= 1 << (md->mixWarn - 1); swOn[i].activeMix = true; } diff --git a/radio/src/storage/yaml/yaml_datastructs_funcs.cpp b/radio/src/storage/yaml/yaml_datastructs_funcs.cpp index 351f31ab282..2c2e94afdbd 100644 --- a/radio/src/storage/yaml/yaml_datastructs_funcs.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_funcs.cpp @@ -129,6 +129,27 @@ static int _legacy_mix_src(const char* val, uint8_t val_len) extern const struct YamlIdStr enum_MixSources[]; +// Find next ',' separator, return length up to; but not inclding separator. +uint8_t find_sep(const char* val, uint8_t val_len) +{ + // find "," + const char* sep = (const char *)memchr(val, ',', val_len); + if (sep) { + // Special case - check for '(x,y)' in string. If found skip past closing bracket + const char* bkt = (const char *)memchr(val, '(', val_len); + if (bkt && bkt < sep) { + // Found '(' before ',' + bkt = (const char *)memchr(val, ')', val_len); + if (bkt && bkt > sep) { + // Found ')' after ',' + sep = (const char *)memchr(bkt, ',', val_len-(bkt-val)); + } + } + } + // Return length up to ',' (or full length if not found) + return sep ? sep - val : val_len; +} + // sources: parse/output // - lua(script#,n): LUA mix outputs // - ls(n): logical switches @@ -1405,8 +1426,7 @@ static void r_customFn(void* user, uint8_t* data, uint32_t bitoffs, } // find "," and cut val_len - const char* sep = (const char *)memchr(val, ',', val_len); - uint8_t l_sep = sep ? sep - val : val_len; + uint8_t l_sep = find_sep(val, val_len); bool eat_comma = true; // read values... @@ -1543,8 +1563,7 @@ static void r_customFn(void* user, uint8_t* data, uint32_t bitoffs, val++; val_len--; // find "," and cut val_len - sep = (const char *)memchr(val, ',', val_len); - l_sep = sep ? sep - val : val_len; + l_sep = find_sep(val, val_len); // parse CFN_GVAR_MODE for (unsigned i=0; i < DIM(_adjust_gvar_mode_lookup); i++) { @@ -1558,8 +1577,7 @@ static void r_customFn(void* user, uint8_t* data, uint32_t bitoffs, if (val_len == 0 || val[0] != ',') return; val++; val_len--; // find "," and cut val_len - sep = (const char *)memchr(val, ',', val_len); - l_sep = sep ? sep - val : val_len; + l_sep = find_sep(val, val_len); // output param switch(CFN_GVAR_MODE(cfn)) { @@ -1801,8 +1819,7 @@ static void r_logicSw(void* user, uint8_t* data, uint32_t bitoffs, data -= sizeof(LogicalSwitchData::func); // find "," and cut val_len - const char* sep = (const char *)memchr(val, ',', val_len); - uint8_t l_sep = sep ? sep - val : val_len; + uint8_t l_sep = find_sep(val, val_len); auto ls = reinterpret_cast(data); switch(lswFamily(ls->func)) { @@ -2033,8 +2050,7 @@ static void r_modSubtype(void* user, uint8_t* data, uint32_t bitoffs, #if defined(MULTIMODULE) // Read type/subType by the book (see MPM documentation) // read "[type],[subtype]" - const char* sep = (const char *)memchr(val, ',', val_len); - uint8_t l_sep = sep ? sep - val : val_len; + uint8_t l_sep = find_sep(val, val_len); int type = yaml_str2uint(val, l_sep); val += l_sep; val_len -= l_sep; diff --git a/radio/src/targets/horus/lcd_driver.cpp b/radio/src/targets/horus/lcd_driver.cpp index 0d9949a06c2..6ffa7b16142 100644 --- a/radio/src/targets/horus/lcd_driver.cpp +++ b/radio/src/targets/horus/lcd_driver.cpp @@ -68,11 +68,9 @@ static void _copy_rotate_180(uint16_t* dst, uint16_t* src, const rect_t& copy_ar coord_t x1 = LCD_W - copy_area.w - copy_area.x; coord_t y1 = LCD_H - copy_area.h - copy_area.y; - auto total = copy_area.w * copy_area.h; - uint16_t* px_src = src + total - 2; + src += copy_area.w - 2; + dst += (y1 + copy_area.h - 1) * LCD_W + x1; - dst += y1 * LCD_W + x1; - for (auto line = 0; line < copy_area.h; line++) { // invert line into _line_buffer first (SRAM) @@ -80,27 +78,26 @@ static void _copy_rotate_180(uint16_t* dst, uint16_t* src, const rect_t& copy_ar auto line_end = px_dst + (copy_area.w & ~1); while (px_dst != line_end) { - uint32_t* px2_src = (uint32_t*)px_src; - uint32_t* px2_dst = (uint32_t*)px_dst; + uint32_t* px2_src = (uint32_t*)src; - uint32_t px = ((*px2_src & 0xFFFF0000) >> 16) | ((*px2_src & 0xFFFF) << 16); - *px2_dst = px; + *((uint32_t*)px_dst) = ((*px2_src & 0xFFFF0000) >> 16) | ((*px2_src & 0xFFFF) << 16); - px_src -= 2; + src -= 2; px_dst += 2; } if (copy_area.w & 1) { - *px_dst = *(px_src+1); - px_src--; + *px_dst = *(src+1); + src--; } // ... and DMA back into SDRAM DMACopyBitmap(dst, copy_area.w, 1, 0, 0, _line_buffer, copy_area.w, 1, 0, 0, copy_area.w, 1); - - dst += LCD_W; + + src += copy_area.w * 2; + dst -= LCD_W; } } diff --git a/radio/src/tests/mixer.cpp b/radio/src/tests/mixer.cpp index 14ad80e9984..f2b4441965e 100644 --- a/radio/src/tests/mixer.cpp +++ b/radio/src/tests/mixer.cpp @@ -662,10 +662,43 @@ TEST_F(MixerTest, DelayOnSwitch) g_model.mixData[0].srcRaw = MIXSRC_MAX; g_model.mixData[0].weight = 100; g_model.mixData[0].swtch = SWSRC_FIRST_SWITCH + 2; + g_model.mixData[0].delayUp = 50; + g_model.mixData[0].delayDown = 50; + int switch_index = 0; + simuSetSwitch(switch_index, -1); + + evalFlightModeMixes(e_perout_mode_normal, 0); + EXPECT_EQ(chans[0], 0); + + simuSetSwitch(switch_index, 1); + CHECK_DELAY(0, 500); + + evalFlightModeMixes(e_perout_mode_normal, 1); + EXPECT_EQ(chans[0], CHANNEL_MAX); + + simuSetSwitch(switch_index, 0); + CHECK_DELAY(0, 500); + + evalFlightModeMixes(e_perout_mode_normal, 1); + EXPECT_EQ(chans[0], 0); +} + +TEST_F(MixerTest, DelayOnSwitch2) +{ + g_eeGeneral.switchConfig = SWITCH_3POS; + + g_model.mixData[0].destCh = 0; + g_model.mixData[0].mltpx = MLTPX_ADD; + g_model.mixData[0].srcRaw = MIXSRC_FIRST_SWITCH; + g_model.mixData[0].weight = 100; + g_model.mixData[0].swtch = SWSRC_ON; g_model.mixData[0].delayUp = 50; g_model.mixData[0].delayDown = 50; + int switch_index = 0; + simuSetSwitch(switch_index, -1); + evalFlightModeMixes(e_perout_mode_normal, 0); EXPECT_EQ(chans[0], 0); diff --git a/radio/src/tests/primitives_CN_480x272.png b/radio/src/tests/primitives_CN_480x272.png deleted file mode 100644 index 6e203fd9849..00000000000 Binary files a/radio/src/tests/primitives_CN_480x272.png and /dev/null differ diff --git a/radio/src/tests/primitives_EN_320x480.png b/radio/src/tests/primitives_EN_320x480.png index 982541571dc..2ef25205ae4 100644 Binary files a/radio/src/tests/primitives_EN_320x480.png and b/radio/src/tests/primitives_EN_320x480.png differ diff --git a/radio/src/tests/primitives_EN_480x272.png b/radio/src/tests/primitives_EN_480x272.png index e8ce337140e..3a278a7b2d7 100644 Binary files a/radio/src/tests/primitives_EN_480x272.png and b/radio/src/tests/primitives_EN_480x272.png differ diff --git a/radio/src/tests/transparency_CN_480x272.png b/radio/src/tests/transparency_CN_480x272.png deleted file mode 100644 index 8f792854acd..00000000000 Binary files a/radio/src/tests/transparency_CN_480x272.png and /dev/null differ diff --git a/radio/src/tests/transparency_EN_320x480.png b/radio/src/tests/transparency_EN_320x480.png index 520f04dee6c..1fcce4de4b0 100644 Binary files a/radio/src/tests/transparency_EN_320x480.png and b/radio/src/tests/transparency_EN_320x480.png differ diff --git a/radio/src/tests/transparency_EN_480x272.png b/radio/src/tests/transparency_EN_480x272.png index 8c78e936e67..11f389fc56d 100644 Binary files a/radio/src/tests/transparency_EN_480x272.png and b/radio/src/tests/transparency_EN_480x272.png differ diff --git a/radio/src/thirdparty/libopenui/thirdparty/CMakeLists.txt b/radio/src/thirdparty/libopenui/thirdparty/CMakeLists.txt index 303deb2c809..df5a7d727ec 100644 --- a/radio/src/thirdparty/libopenui/thirdparty/CMakeLists.txt +++ b/radio/src/thirdparty/libopenui/thirdparty/CMakeLists.txt @@ -20,6 +20,7 @@ set(LVGL_SOURCES_MINIMAL draw/sw/lv_draw_sw_gradient.c draw/sw/lv_draw_sw.c draw/sw/lv_draw_sw_blend.c + draw/sw/lv_draw_sw_layer.c draw/sw/lv_draw_sw_letter.c draw/sw/lv_draw_sw_arc.c draw/sw/lv_draw_sw_polygon.c @@ -27,7 +28,10 @@ set(LVGL_SOURCES_MINIMAL draw/sw/lv_draw_sw_line.c draw/sw/lv_draw_sw_dither.c draw/sw/lv_draw_sw_rect.c + draw/sw/lv_draw_sw_transform.c + draw/lv_draw_layer.c draw/lv_draw_line.c + draw/lv_draw_transform.c draw/lv_draw.c draw/lv_img_buf.c draw/lv_draw_rect.c diff --git a/radio/src/thirdparty/libopenui/thirdparty/lvgl b/radio/src/thirdparty/libopenui/thirdparty/lvgl index 9a414b1d48d..48cf9ec1406 160000 --- a/radio/src/thirdparty/libopenui/thirdparty/lvgl +++ b/radio/src/thirdparty/libopenui/thirdparty/lvgl @@ -1 +1 @@ -Subproject commit 9a414b1d48d2893133b6038ec80d59fb157aade4 +Subproject commit 48cf9ec1406ed3bce8a2a4bdbd84678df3503988