├── .clang-format ├── .gitignore ├── LICENSE ├── README.md ├── images ├── lv_m5stack_core2.gif ├── lv_m5stack_cores3.gif ├── lv_m5stack_dial.gif └── lv_m5stack_fire.gif ├── include ├── README ├── lv_conf.h ├── lv_conf_v8.h └── lv_conf_v9.h ├── lib └── README ├── platformio.ini ├── src ├── main.cpp ├── user_app.cpp └── utility │ ├── lvgl_port_m5stack.cpp │ ├── lvgl_port_m5stack.hpp │ └── sdl_main.cpp ├── support ├── pio_explorer.png └── sdl2_build_extra.py └── test └── README /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | BasedOnStyle: Google 4 | AccessModifierOffset: -1 5 | AlignAfterOpenBracket: Align 6 | AlignConsecutiveMacros: true 7 | AlignConsecutiveAssignments: true 8 | AlignConsecutiveDeclarations: false 9 | AlignEscapedNewlines: Left 10 | AlignOperands: true 11 | AlignTrailingComments: true 12 | AllowAllArgumentsOnNextLine: true 13 | AllowAllConstructorInitializersOnNextLine: true 14 | AllowAllParametersOfDeclarationOnNextLine: true 15 | AllowShortBlocksOnASingleLine: Never 16 | AllowShortCaseLabelsOnASingleLine: false 17 | AllowShortFunctionsOnASingleLine: false 18 | AllowShortLambdasOnASingleLine: All 19 | AllowShortIfStatementsOnASingleLine: WithoutElse 20 | AllowShortLoopsOnASingleLine: true 21 | AlwaysBreakAfterDefinitionReturnType: None 22 | AlwaysBreakAfterReturnType: None 23 | AlwaysBreakBeforeMultilineStrings: true 24 | AlwaysBreakTemplateDeclarations: Yes 25 | BinPackArguments: true 26 | BinPackParameters: true 27 | BraceWrapping: 28 | AfterCaseLabel: false 29 | AfterClass: false 30 | AfterControlStatement: false 31 | AfterEnum: false 32 | AfterFunction: false 33 | AfterNamespace: false 34 | AfterObjCDeclaration: false 35 | AfterStruct: false 36 | AfterUnion: false 37 | AfterExternBlock: false 38 | BeforeCatch: false 39 | BeforeElse: false 40 | IndentBraces: false 41 | SplitEmptyFunction: true 42 | SplitEmptyRecord: true 43 | SplitEmptyNamespace: true 44 | BreakBeforeBinaryOperators: None 45 | BreakBeforeBraces: Attach 46 | BreakBeforeInheritanceComma: false 47 | BreakInheritanceList: BeforeColon 48 | BreakBeforeTernaryOperators: true 49 | BreakConstructorInitializersBeforeComma: false 50 | BreakConstructorInitializers: BeforeColon 51 | BreakAfterJavaFieldAnnotations: false 52 | BreakStringLiterals: true 53 | ColumnLimit: 120 54 | CommentPragmas: '^ IWYU pragma:' 55 | CompactNamespaces: false 56 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 57 | ConstructorInitializerIndentWidth: 4 58 | ContinuationIndentWidth: 4 59 | Cpp11BracedListStyle: true 60 | DeriveLineEnding: true 61 | DerivePointerAlignment: true 62 | DisableFormat: false 63 | ExperimentalAutoDetectBinPacking: false 64 | FixNamespaceComments: true 65 | ForEachMacros: 66 | - foreach 67 | - Q_FOREACH 68 | - BOOST_FOREACH 69 | IncludeBlocks: Regroup 70 | IncludeCategories: 71 | - Regex: '^' 72 | Priority: 2 73 | SortPriority: 0 74 | - Regex: '^<.*\.h>' 75 | Priority: 1 76 | SortPriority: 0 77 | - Regex: '^<.*' 78 | Priority: 2 79 | SortPriority: 0 80 | - Regex: '.*' 81 | Priority: 3 82 | SortPriority: 0 83 | IncludeIsMainRegex: '([-_](test|unittest))?$' 84 | IncludeIsMainSourceRegex: '' 85 | IndentCaseLabels: true 86 | IndentGotoLabels: true 87 | IndentPPDirectives: None 88 | IndentWidth: 4 89 | IndentWrappedFunctionNames: false 90 | JavaScriptQuotes: Leave 91 | JavaScriptWrapImports: true 92 | KeepEmptyLinesAtTheStartOfBlocks: false 93 | MacroBlockBegin: '' 94 | MacroBlockEnd: '' 95 | MaxEmptyLinesToKeep: 1 96 | NamespaceIndentation: None 97 | ObjCBinPackProtocolList: Never 98 | ObjCBlockIndentWidth: 2 99 | ObjCSpaceAfterProperty: false 100 | ObjCSpaceBeforeProtocolList: true 101 | PenaltyBreakAssignment: 2 102 | PenaltyBreakBeforeFirstCallParameter: 1 103 | PenaltyBreakComment: 300 104 | PenaltyBreakFirstLessLess: 120 105 | PenaltyBreakString: 1000 106 | PenaltyBreakTemplateDeclaration: 10 107 | PenaltyExcessCharacter: 1000000 108 | PenaltyReturnTypeOnItsOwnLine: 200 109 | PointerAlignment: Left 110 | RawStringFormats: 111 | - Language: Cpp 112 | Delimiters: 113 | - cc 114 | - CC 115 | - cpp 116 | - Cpp 117 | - CPP 118 | - 'c++' 119 | - 'C++' 120 | CanonicalDelimiter: '' 121 | BasedOnStyle: google 122 | - Language: TextProto 123 | Delimiters: 124 | - pb 125 | - PB 126 | - proto 127 | - PROTO 128 | EnclosingFunctions: 129 | - EqualsProto 130 | - EquivToProto 131 | - PARSE_PARTIAL_TEXT_PROTO 132 | - PARSE_TEST_PROTO 133 | - PARSE_TEXT_PROTO 134 | - ParseTextOrDie 135 | - ParseTextProtoOrDie 136 | CanonicalDelimiter: '' 137 | BasedOnStyle: google 138 | ReflowComments: true 139 | SortIncludes: false 140 | SortUsingDeclarations: true 141 | SpaceAfterCStyleCast: false 142 | SpaceAfterLogicalNot: false 143 | SpaceAfterTemplateKeyword: true 144 | SpaceBeforeAssignmentOperators: true 145 | SpaceBeforeCpp11BracedList: false 146 | SpaceBeforeCtorInitializerColon: true 147 | SpaceBeforeInheritanceColon: true 148 | SpaceBeforeParens: ControlStatements 149 | SpaceBeforeRangeBasedForLoopColon: true 150 | SpaceInEmptyBlock: false 151 | SpaceInEmptyParentheses: false 152 | SpacesBeforeTrailingComments: 2 153 | SpacesInAngles: false 154 | SpacesInConditionalStatement: false 155 | SpacesInContainerLiterals: true 156 | SpacesInCStyleCastParentheses: false 157 | SpacesInParentheses: false 158 | SpacesInSquareBrackets: false 159 | SpaceBeforeSquareBrackets: false 160 | Standard: Auto 161 | StatementMacros: 162 | - Q_UNUSED 163 | - QT_REQUIRE_VERSION 164 | TabWidth: 4 165 | UseCRLF: false 166 | UseTab: Never 167 | ... 168 | 169 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode 3 | 4 | .DS_Store 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 M5Stack 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Running the M5Stack LVGL device emulator via PlatformIO 2 | 3 | Now it is more convenient to design [LVGL](https://github.com/lvgl/lvgl) UI on PC, 4 | which can reduce the time wasted in flash the firmware. 5 | Using [M5GFX](https://github.com/m5stack/M5GFX), we can ensure that the display 6 | effect on the PC side is consistent with that of the device. 7 | Now we have also added a picture of the device shell as the border background, 8 | which can better simulate the display effect on the device side. 9 | 10 |
11 | 12 |
13 | 14 | ## How to install & use demo 15 | 16 | ### Install Visual Studio Code 17 | 18 | https://code.visualstudio.com/ - follow instructions there, if you don't have 19 | vscode yet. 20 | 21 | 22 | ### Install SDL drivers 23 | 24 | **Linux (Ubuntu, Debian, ...)** 25 | 26 | Use one of options below: 27 | 28 | ```sh 29 | # 64 bits 30 | sudo apt-get install libsdl2-dev 31 | ``` 32 | 33 | ```sh 34 | # 32 bits 35 | sudo apt-get install gcc-multilib g++-multilib libsdl2-dev:i386 36 | ``` 37 | 38 | Note: 39 | 40 | - Use 32-bits build for more correct memory stat info. 41 | - If you have conflicts on `libsdl2-dev:i386` install, remove 64-bits version 42 | and dependencies first. 43 | 44 | **MacOS** 45 | 46 | Use [Homebrew](https://brew.sh/): 47 | 48 | ```sh 49 | brew install sdl2 pkg-config 50 | ``` 51 | Note: 52 | On MacOS you need to include (uncomment in provided example [platformio.ini](./platformio.ini) file) these lines in your platformio.ini file to import the drivers: 53 | ``` 54 | ; SDL2 includes 55 | !pkg-config --cflags SDL2 56 | !pkg-config --libs SDL2 57 | ``` 58 | 59 | **Windows** 60 | 61 | Use [MSYS2](https://www.msys2.org/) 62 | 63 | ```sh 64 | pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-SDL2 65 | ``` 66 | 67 | Add the path to your Mingw-w64 `bin` folder to the Windows PATH environment 68 | variable (usually `C:\msys64\mingw64\bin`). See [instruction, 4](https://code.visualstudio.com/docs/cpp/config-mingw#_prerequisites). 69 | 70 | 71 | ### Install flasher drivers (optional) 72 | 73 | If you plan to upload firmware & debug hardware, read notes in PlatformIO 74 | [install docs](http://docs.platformio.org/en/latest/installation.html#troubleshooting). 75 | 76 | 77 | ### Choose LVGL version(V8 or V9) 78 | 79 | If you want build with lvgl v8, this was default option, you don't need change any files! 80 | But if you want try the lvgl latest version v9, you need to modify the version control macro definition in [platformio.ini](./platformio.ini) file as: 81 | ``` 82 | -D LVGL_USE_V8=0 ; lvgl v8 83 | -D LVGL_USE_V9=1 ; lvgl v9 84 | ``` 85 | And don't forget to modify the links of the dependent libs to this: 86 | ``` 87 | ; lvgl=https://github.com/lvgl/lvgl/archive/refs/tags/v8.3.0.zip ; lvgl v8 88 | lvgl=https://github.com/lvgl/lvgl#master ; lvgl v9 89 | ``` 90 | 91 | ### Build/Run 92 | 93 | 1. Clone this repository or download as zip. 94 | 2. In vscode, open folder via `File` -> `Open Folder...` menu. 95 | - If you do it first time - agree, when it suggests to install PlatformIO 96 | plugin, and wait when PlatformIO then install build tools and package 97 | dependencies. 98 | 99 | To build/execute, on PlafomIO tab expand desired env and click target: 100 | 101 | 102 | 103 | Note, for emulator env `upload` also executes compiled binary. 104 | 105 | ### Zoom and rotate the window at runtime 106 | 107 | The emulator support zoom and rotate the window at runtime. So you can easily zoom and rotate the window to view UI details. 108 | 109 | 1. Zoom 110 | 111 | Press :keyboard: **1 ~ 6** number key to zoom the window size. 112 | 113 | 1. Rotate 114 | 115 | Press :keyboard: **"L"** **"R"** letter key to rotate the window. 116 | -------------------------------------------------------------------------------- /images/lv_m5stack_core2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m5stack/lv_m5_emulator/f7cc52e18c275c14773fc902c452187f6841f7b5/images/lv_m5stack_core2.gif -------------------------------------------------------------------------------- /images/lv_m5stack_cores3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m5stack/lv_m5_emulator/f7cc52e18c275c14773fc902c452187f6841f7b5/images/lv_m5stack_cores3.gif -------------------------------------------------------------------------------- /images/lv_m5stack_dial.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m5stack/lv_m5_emulator/f7cc52e18c275c14773fc902c452187f6841f7b5/images/lv_m5stack_dial.gif -------------------------------------------------------------------------------- /images/lv_m5stack_fire.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m5stack/lv_m5_emulator/f7cc52e18c275c14773fc902c452187f6841f7b5/images/lv_m5stack_fire.gif -------------------------------------------------------------------------------- /include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /include/lv_conf.h: -------------------------------------------------------------------------------- 1 | 2 | #if LVGL_USE_V8 == 1 3 | #include "lv_conf_v8.h" 4 | #elif LVGL_USE_V9 == 1 5 | #include "lv_conf_v9.h" 6 | #endif 7 | -------------------------------------------------------------------------------- /include/lv_conf_v8.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file lv_conf.h 3 | * Configuration file for v8.3.0 4 | */ 5 | 6 | /* 7 | * Copy this file as `lv_conf.h` 8 | * 1. simply next to the `lvgl` folder 9 | * 2. or any other places and 10 | * - define `LV_CONF_INCLUDE_SIMPLE` 11 | * - add the path as include path 12 | */ 13 | 14 | /* clang-format off */ 15 | #if 1 /*Set it to "1" to enable content*/ 16 | 17 | #ifndef LV_CONF_H 18 | #define LV_CONF_H 19 | 20 | #include 21 | 22 | /*==================== 23 | COLOR SETTINGS 24 | *====================*/ 25 | 26 | /*Color depth: 1 (1 byte per pixel), 8 (RGB332), 16 (RGB565), 32 (ARGB8888)*/ 27 | #define LV_COLOR_DEPTH 16 28 | 29 | /*Swap the 2 bytes of RGB565 color. Useful if the display has an 8-bit interface (e.g. SPI)*/ 30 | #define LV_COLOR_16_SWAP 0 31 | 32 | /*Enable features to draw on transparent background. 33 | *It's required if opa, and transform_* style properties are used. 34 | *Can be also used if the UI is above another layer, e.g. an OSD menu or video player.*/ 35 | #define LV_COLOR_SCREEN_TRANSP 1 36 | 37 | /* Adjust color mix functions rounding. GPUs might calculate color mix (blending) differently. 38 | * 0: round down, 64: round up from x.75, 128: round up from half, 192: round up from x.25, 254: round up */ 39 | #define LV_COLOR_MIX_ROUND_OFS 0 40 | 41 | /*Images pixels with this color will not be drawn if they are chroma keyed)*/ 42 | #define LV_COLOR_CHROMA_KEY lv_color_hex(0x00ff00) /*pure green*/ 43 | 44 | /*========================= 45 | MEMORY SETTINGS 46 | *=========================*/ 47 | 48 | /*1: use custom malloc/free, 0: use the built-in `lv_mem_alloc()` and `lv_mem_free()`*/ 49 | #define LV_MEM_CUSTOM 0 50 | #if LV_MEM_CUSTOM == 0 51 | /*Size of the memory available for `lv_mem_alloc()` in bytes (>= 2kB)*/ 52 | #define LV_MEM_SIZE (64U * 1024U) /*[bytes]*/ 53 | 54 | /*Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too.*/ 55 | #define LV_MEM_ADR 0 /*0: unused*/ 56 | /*Instead of an address give a memory allocator that will be called to get a memory pool for LVGL. E.g. my_malloc*/ 57 | #if LV_MEM_ADR == 0 58 | #undef LV_MEM_POOL_INCLUDE 59 | #undef LV_MEM_POOL_ALLOC 60 | #endif 61 | 62 | #else /*LV_MEM_CUSTOM*/ 63 | #define LV_MEM_CUSTOM_INCLUDE /*Header for the dynamic memory function*/ 64 | #define LV_MEM_CUSTOM_ALLOC malloc 65 | #define LV_MEM_CUSTOM_FREE free 66 | #define LV_MEM_CUSTOM_REALLOC realloc 67 | #endif /*LV_MEM_CUSTOM*/ 68 | 69 | /*Number of the intermediate memory buffer used during rendering and other internal processing mechanisms. 70 | *You will see an error log message if there wasn't enough buffers. */ 71 | #define LV_MEM_BUF_MAX_NUM 16 72 | 73 | /*Use the standard `memcpy` and `memset` instead of LVGL's own functions. (Might or might not be faster).*/ 74 | #define LV_MEMCPY_MEMSET_STD 0 75 | 76 | /*==================== 77 | HAL SETTINGS 78 | *====================*/ 79 | 80 | /*Default display refresh period. LVG will redraw changed areas with this period time*/ 81 | #define LV_DISP_DEF_REFR_PERIOD 30 /*[ms]*/ 82 | 83 | /*Input device read period in milliseconds*/ 84 | #define LV_INDEV_DEF_READ_PERIOD 30 /*[ms]*/ 85 | 86 | /*Use a custom tick source that tells the elapsed time in milliseconds. 87 | *It removes the need to manually update the tick with `lv_tick_inc()`)*/ 88 | #define LV_TICK_CUSTOM 0 89 | #if LV_TICK_CUSTOM 90 | #define LV_TICK_CUSTOM_INCLUDE "Arduino.h" /*Header for the system time function*/ 91 | #define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current system time in ms*/ 92 | #endif /*LV_TICK_CUSTOM*/ 93 | 94 | /*Default Dot Per Inch. Used to initialize default sizes such as widgets sized, style paddings. 95 | *(Not so important, you can adjust it to modify default sizes and spaces)*/ 96 | #define LV_DPI_DEF 130 /*[px/inch]*/ 97 | 98 | /*======================= 99 | * FEATURE CONFIGURATION 100 | *=======================*/ 101 | 102 | /*------------- 103 | * Drawing 104 | *-----------*/ 105 | 106 | /*Enable complex draw engine. 107 | *Required to draw shadow, gradient, rounded corners, circles, arc, skew lines, image transformations or any masks*/ 108 | #define LV_DRAW_COMPLEX 1 109 | #if LV_DRAW_COMPLEX != 0 110 | 111 | /*Allow buffering some shadow calculation. 112 | *LV_SHADOW_CACHE_SIZE is the max. shadow size to buffer, where shadow size is `shadow_width + radius` 113 | *Caching has LV_SHADOW_CACHE_SIZE^2 RAM cost*/ 114 | #define LV_SHADOW_CACHE_SIZE 0 115 | 116 | /* Set number of maximally cached circle data. 117 | * The circumference of 1/4 circle are saved for anti-aliasing 118 | * radius * 4 bytes are used per circle (the most often used radiuses are saved) 119 | * 0: to disable caching */ 120 | #define LV_CIRCLE_CACHE_SIZE 4 121 | #endif /*LV_DRAW_COMPLEX*/ 122 | 123 | /** 124 | * "Simple layers" are used when a widget has `style_opa < 255` to buffer the widget into a layer 125 | * and blend it as an image with the given opacity. 126 | * Note that `bg_opa`, `text_opa` etc don't require buffering into layer) 127 | * The widget can be buffered in smaller chunks to avoid using large buffers. 128 | * 129 | * - LV_LAYER_SIMPLE_BUF_SIZE: [bytes] the optimal target buffer size. LVGL will try to allocate it 130 | * - LV_LAYER_SIMPLE_FALLBACK_BUF_SIZE: [bytes] used if `LV_LAYER_SIMPLE_BUF_SIZE` couldn't be allocated. 131 | * 132 | * Both buffer sizes are in bytes. 133 | * "Transformed layers" (where transform_angle/zoom properties are used) use larger buffers 134 | * and can't be drawn in chunks. So these settings affects only widgets with opacity. 135 | */ 136 | #define LV_LAYER_SIMPLE_BUF_SIZE (24 * 1024) 137 | #define LV_LAYER_SIMPLE_FALLBACK_BUF_SIZE (3 * 1024) 138 | 139 | /*Default image cache size. Image caching keeps the images opened. 140 | *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) 141 | *With complex image decoders (e.g. PNG or JPG) caching can save the continuous open/decode of images. 142 | *However the opened images might consume additional RAM. 143 | *0: to disable caching*/ 144 | #define LV_IMG_CACHE_DEF_SIZE 0 145 | 146 | /*Number of stops allowed per gradient. Increase this to allow more stops. 147 | *This adds (sizeof(lv_color_t) + 1) bytes per additional stop*/ 148 | #define LV_GRADIENT_MAX_STOPS 2 149 | 150 | /*Default gradient buffer size. 151 | *When LVGL calculates the gradient "maps" it can save them into a cache to avoid calculating them again. 152 | *LV_GRAD_CACHE_DEF_SIZE sets the size of this cache in bytes. 153 | *If the cache is too small the map will be allocated only while it's required for the drawing. 154 | *0 mean no caching.*/ 155 | #define LV_GRAD_CACHE_DEF_SIZE 0 156 | 157 | /*Allow dithering the gradients (to achieve visual smooth color gradients on limited color depth display) 158 | *LV_DITHER_GRADIENT implies allocating one or two more lines of the object's rendering surface 159 | *The increase in memory consumption is (32 bits * object width) plus 24 bits * object width if using error diffusion */ 160 | #define LV_DITHER_GRADIENT 0 161 | #if LV_DITHER_GRADIENT 162 | /*Add support for error diffusion dithering. 163 | *Error diffusion dithering gets a much better visual result, but implies more CPU consumption and memory when drawing. 164 | *The increase in memory consumption is (24 bits * object's width)*/ 165 | #define LV_DITHER_ERROR_DIFFUSION 0 166 | #endif 167 | 168 | /*Maximum buffer size to allocate for rotation. 169 | *Only used if software rotation is enabled in the display driver.*/ 170 | #define LV_DISP_ROT_MAX_BUF (10*1024) 171 | 172 | /*------------- 173 | * GPU 174 | *-----------*/ 175 | 176 | /*Use Arm's 2D acceleration library Arm-2D */ 177 | #define LV_USE_GPU_ARM2D 0 178 | 179 | /*Use STM32's DMA2D (aka Chrom Art) GPU*/ 180 | #define LV_USE_GPU_STM32_DMA2D 0 181 | #if LV_USE_GPU_STM32_DMA2D 182 | /*Must be defined to include path of CMSIS header of target processor 183 | e.g. "stm32f769xx.h" or "stm32f429xx.h"*/ 184 | #define LV_GPU_DMA2D_CMSIS_INCLUDE 185 | #endif 186 | 187 | /*Use SWM341's DMA2D GPU*/ 188 | #define LV_USE_GPU_SWM341_DMA2D 0 189 | #if LV_USE_GPU_SWM341_DMA2D 190 | #define LV_GPU_SWM341_DMA2D_INCLUDE "SWM341.h" 191 | #endif 192 | 193 | /*Use NXP's PXP GPU iMX RTxxx platforms*/ 194 | #define LV_USE_GPU_NXP_PXP 0 195 | #if LV_USE_GPU_NXP_PXP 196 | /*1: Add default bare metal and FreeRTOS interrupt handling routines for PXP (lv_gpu_nxp_pxp_osa.c) 197 | * and call lv_gpu_nxp_pxp_init() automatically during lv_init(). Note that symbol SDK_OS_FREE_RTOS 198 | * has to be defined in order to use FreeRTOS OSA, otherwise bare-metal implementation is selected. 199 | *0: lv_gpu_nxp_pxp_init() has to be called manually before lv_init() 200 | */ 201 | #define LV_USE_GPU_NXP_PXP_AUTO_INIT 0 202 | #endif 203 | 204 | /*Use NXP's VG-Lite GPU iMX RTxxx platforms*/ 205 | #define LV_USE_GPU_NXP_VG_LITE 0 206 | 207 | /*Use SDL renderer API*/ 208 | #define LV_USE_GPU_SDL 0 209 | #if LV_USE_GPU_SDL 210 | #define LV_GPU_SDL_INCLUDE_PATH 211 | /*Texture cache size, 8MB by default*/ 212 | #define LV_GPU_SDL_LRU_SIZE (1024 * 1024 * 8) 213 | /*Custom blend mode for mask drawing, disable if you need to link with older SDL2 lib*/ 214 | #define LV_GPU_SDL_CUSTOM_BLEND_MODE (SDL_VERSION_ATLEAST(2, 0, 6)) 215 | #endif 216 | 217 | /*------------- 218 | * Logging 219 | *-----------*/ 220 | 221 | /*Enable the log module*/ 222 | #define LV_USE_LOG 0 223 | #if LV_USE_LOG 224 | 225 | /*How important log should be added: 226 | *LV_LOG_LEVEL_TRACE A lot of logs to give detailed information 227 | *LV_LOG_LEVEL_INFO Log important events 228 | *LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem 229 | *LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail 230 | *LV_LOG_LEVEL_USER Only logs added by the user 231 | *LV_LOG_LEVEL_NONE Do not log anything*/ 232 | #define LV_LOG_LEVEL LV_LOG_LEVEL_WARN 233 | 234 | /*1: Print the log with 'printf'; 235 | *0: User need to register a callback with `lv_log_register_print_cb()`*/ 236 | #define LV_LOG_PRINTF 1 237 | 238 | /*Enable/disable LV_LOG_TRACE in modules that produces a huge number of logs*/ 239 | #define LV_LOG_TRACE_MEM 1 240 | #define LV_LOG_TRACE_TIMER 1 241 | #define LV_LOG_TRACE_INDEV 1 242 | #define LV_LOG_TRACE_DISP_REFR 1 243 | #define LV_LOG_TRACE_EVENT 1 244 | #define LV_LOG_TRACE_OBJ_CREATE 1 245 | #define LV_LOG_TRACE_LAYOUT 1 246 | #define LV_LOG_TRACE_ANIM 1 247 | 248 | #endif /*LV_USE_LOG*/ 249 | 250 | /*------------- 251 | * Asserts 252 | *-----------*/ 253 | 254 | /*Enable asserts if an operation is failed or an invalid data is found. 255 | *If LV_USE_LOG is enabled an error message will be printed on failure*/ 256 | #define LV_USE_ASSERT_NULL 1 /*Check if the parameter is NULL. (Very fast, recommended)*/ 257 | #define LV_USE_ASSERT_MALLOC 1 /*Checks is the memory is successfully allocated or no. (Very fast, recommended)*/ 258 | #define LV_USE_ASSERT_STYLE 0 /*Check if the styles are properly initialized. (Very fast, recommended)*/ 259 | #define LV_USE_ASSERT_MEM_INTEGRITY 0 /*Check the integrity of `lv_mem` after critical operations. (Slow)*/ 260 | #define LV_USE_ASSERT_OBJ 0 /*Check the object's type and existence (e.g. not deleted). (Slow)*/ 261 | 262 | /*Add a custom handler when assert happens e.g. to restart the MCU*/ 263 | #define LV_ASSERT_HANDLER_INCLUDE 264 | #define LV_ASSERT_HANDLER while(1); /*Halt by default*/ 265 | 266 | /*------------- 267 | * Others 268 | *-----------*/ 269 | 270 | /*1: Show CPU usage and FPS count*/ 271 | #define LV_USE_PERF_MONITOR 0 272 | #if LV_USE_PERF_MONITOR 273 | #define LV_USE_PERF_MONITOR_POS LV_ALIGN_BOTTOM_RIGHT 274 | #endif 275 | 276 | /*1: Show the used memory and the memory fragmentation 277 | * Requires LV_MEM_CUSTOM = 0*/ 278 | #define LV_USE_MEM_MONITOR 0 279 | #if LV_USE_MEM_MONITOR 280 | #define LV_USE_MEM_MONITOR_POS LV_ALIGN_BOTTOM_LEFT 281 | #endif 282 | 283 | /*1: Draw random colored rectangles over the redrawn areas*/ 284 | #define LV_USE_REFR_DEBUG 0 285 | 286 | /*Change the built in (v)snprintf functions*/ 287 | #define LV_SPRINTF_CUSTOM 0 288 | #if LV_SPRINTF_CUSTOM 289 | #define LV_SPRINTF_INCLUDE 290 | #define lv_snprintf snprintf 291 | #define lv_vsnprintf vsnprintf 292 | #else /*LV_SPRINTF_CUSTOM*/ 293 | #define LV_SPRINTF_USE_FLOAT 0 294 | #endif /*LV_SPRINTF_CUSTOM*/ 295 | 296 | #define LV_USE_USER_DATA 1 297 | 298 | /*Garbage Collector settings 299 | *Used if lvgl is bound to higher level language and the memory is managed by that language*/ 300 | #define LV_ENABLE_GC 0 301 | #if LV_ENABLE_GC != 0 302 | #define LV_GC_INCLUDE "gc.h" /*Include Garbage Collector related things*/ 303 | #endif /*LV_ENABLE_GC*/ 304 | 305 | /*===================== 306 | * COMPILER SETTINGS 307 | *====================*/ 308 | 309 | /*For big endian systems set to 1*/ 310 | #define LV_BIG_ENDIAN_SYSTEM 0 311 | 312 | /*Define a custom attribute to `lv_tick_inc` function*/ 313 | #define LV_ATTRIBUTE_TICK_INC 314 | 315 | /*Define a custom attribute to `lv_timer_handler` function*/ 316 | #define LV_ATTRIBUTE_TIMER_HANDLER 317 | 318 | /*Define a custom attribute to `lv_disp_flush_ready` function*/ 319 | #define LV_ATTRIBUTE_FLUSH_READY 320 | 321 | /*Required alignment size for buffers*/ 322 | #define LV_ATTRIBUTE_MEM_ALIGN_SIZE 1 323 | 324 | /*Will be added where memories needs to be aligned (with -Os data might not be aligned to boundary by default). 325 | * E.g. __attribute__((aligned(4)))*/ 326 | #define LV_ATTRIBUTE_MEM_ALIGN 327 | 328 | /*Attribute to mark large constant arrays for example font's bitmaps*/ 329 | #define LV_ATTRIBUTE_LARGE_CONST 330 | 331 | /*Compiler prefix for a big array declaration in RAM*/ 332 | #define LV_ATTRIBUTE_LARGE_RAM_ARRAY 333 | 334 | /*Place performance critical functions into a faster memory (e.g RAM)*/ 335 | #define LV_ATTRIBUTE_FAST_MEM 336 | 337 | /*Prefix variables that are used in GPU accelerated operations, often these need to be placed in RAM sections that are DMA accessible*/ 338 | #define LV_ATTRIBUTE_DMA 339 | 340 | /*Export integer constant to binding. This macro is used with constants in the form of LV_ that 341 | *should also appear on LVGL binding API such as Micropython.*/ 342 | #define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning /*The default value just prevents GCC warning*/ 343 | 344 | /*Extend the default -32k..32k coordinate range to -4M..4M by using int32_t for coordinates instead of int16_t*/ 345 | #define LV_USE_LARGE_COORD 0 346 | 347 | /*================== 348 | * FONT USAGE 349 | *===================*/ 350 | 351 | /*Montserrat fonts with ASCII range and some symbols using bpp = 4 352 | *https://fonts.google.com/specimen/Montserrat*/ 353 | #define LV_FONT_MONTSERRAT_8 0 354 | #define LV_FONT_MONTSERRAT_10 0 355 | #define LV_FONT_MONTSERRAT_12 1 356 | #define LV_FONT_MONTSERRAT_14 1 357 | #define LV_FONT_MONTSERRAT_16 1 358 | #define LV_FONT_MONTSERRAT_18 0 359 | #define LV_FONT_MONTSERRAT_20 0 360 | #define LV_FONT_MONTSERRAT_22 0 361 | #define LV_FONT_MONTSERRAT_24 0 362 | #define LV_FONT_MONTSERRAT_26 0 363 | #define LV_FONT_MONTSERRAT_28 0 364 | #define LV_FONT_MONTSERRAT_30 0 365 | #define LV_FONT_MONTSERRAT_32 0 366 | #define LV_FONT_MONTSERRAT_34 0 367 | #define LV_FONT_MONTSERRAT_36 0 368 | #define LV_FONT_MONTSERRAT_38 0 369 | #define LV_FONT_MONTSERRAT_40 0 370 | #define LV_FONT_MONTSERRAT_42 0 371 | #define LV_FONT_MONTSERRAT_44 0 372 | #define LV_FONT_MONTSERRAT_46 0 373 | #define LV_FONT_MONTSERRAT_48 0 374 | 375 | /*Demonstrate special features*/ 376 | #define LV_FONT_MONTSERRAT_12_SUBPX 0 377 | #define LV_FONT_MONTSERRAT_28_COMPRESSED 0 /*bpp = 3*/ 378 | #define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 0 /*Hebrew, Arabic, Persian letters and all their forms*/ 379 | #define LV_FONT_SIMSUN_16_CJK 0 /*1000 most common CJK radicals*/ 380 | 381 | /*Pixel perfect monospace fonts*/ 382 | #define LV_FONT_UNSCII_8 1 383 | #define LV_FONT_UNSCII_16 1 384 | 385 | /*Optionally declare custom fonts here. 386 | *You can use these fonts as default font too and they will be available globally. 387 | *E.g. #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) LV_FONT_DECLARE(my_font_2)*/ 388 | 389 | /*Always set a default font*/ 390 | #define LV_FONT_DEFAULT &lv_font_montserrat_14 391 | 392 | /*Enable handling large font and/or fonts with a lot of characters. 393 | *The limit depends on the font size, font face and bpp. 394 | *Compiler error will be triggered if a font needs it.*/ 395 | #define LV_FONT_FMT_TXT_LARGE 1 396 | 397 | /*Enables/disables support for compressed fonts.*/ 398 | #define LV_USE_FONT_COMPRESSED 0 399 | 400 | /*Enable subpixel rendering*/ 401 | #define LV_USE_FONT_SUBPX 0 402 | #if LV_USE_FONT_SUBPX 403 | /*Set the pixel order of the display. Physical order of RGB channels. Doesn't matter with "normal" fonts.*/ 404 | #define LV_FONT_SUBPX_BGR 0 /*0: RGB; 1:BGR order*/ 405 | #endif 406 | 407 | /*Enable drawing placeholders when glyph dsc is not found*/ 408 | #define LV_USE_FONT_PLACEHOLDER 1 409 | 410 | /*================= 411 | * TEXT SETTINGS 412 | *=================*/ 413 | 414 | /** 415 | * Select a character encoding for strings. 416 | * Your IDE or editor should have the same character encoding 417 | * - LV_TXT_ENC_UTF8 418 | * - LV_TXT_ENC_ASCII 419 | */ 420 | #define LV_TXT_ENC LV_TXT_ENC_UTF8 421 | 422 | /*Can break (wrap) texts on these chars*/ 423 | #define LV_TXT_BREAK_CHARS " ,.;:-_" 424 | 425 | /*If a word is at least this long, will break wherever "prettiest" 426 | *To disable, set to a value <= 0*/ 427 | #define LV_TXT_LINE_BREAK_LONG_LEN 0 428 | 429 | /*Minimum number of characters in a long word to put on a line before a break. 430 | *Depends on LV_TXT_LINE_BREAK_LONG_LEN.*/ 431 | #define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3 432 | 433 | /*Minimum number of characters in a long word to put on a line after a break. 434 | *Depends on LV_TXT_LINE_BREAK_LONG_LEN.*/ 435 | #define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3 436 | 437 | /*The control character to use for signalling text recoloring.*/ 438 | #define LV_TXT_COLOR_CMD "#" 439 | 440 | /*Support bidirectional texts. Allows mixing Left-to-Right and Right-to-Left texts. 441 | *The direction will be processed according to the Unicode Bidirectional Algorithm: 442 | *https://www.w3.org/International/articles/inline-bidi-markup/uba-basics*/ 443 | #define LV_USE_BIDI 0 444 | #if LV_USE_BIDI 445 | /*Set the default direction. Supported values: 446 | *`LV_BASE_DIR_LTR` Left-to-Right 447 | *`LV_BASE_DIR_RTL` Right-to-Left 448 | *`LV_BASE_DIR_AUTO` detect texts base direction*/ 449 | #define LV_BIDI_BASE_DIR_DEF LV_BASE_DIR_AUTO 450 | #endif 451 | 452 | /*Enable Arabic/Persian processing 453 | *In these languages characters should be replaced with an other form based on their position in the text*/ 454 | #define LV_USE_ARABIC_PERSIAN_CHARS 0 455 | 456 | /*================== 457 | * WIDGET USAGE 458 | *================*/ 459 | 460 | /*Documentation of the widgets: https://docs.lvgl.io/latest/en/html/widgets/index.html*/ 461 | 462 | #define LV_USE_ARC 1 463 | 464 | #define LV_USE_BAR 1 465 | 466 | #define LV_USE_BTN 1 467 | 468 | #define LV_USE_BTNMATRIX 1 469 | 470 | #define LV_USE_CANVAS 1 471 | 472 | #define LV_USE_CHECKBOX 1 473 | 474 | #define LV_USE_DROPDOWN 1 /*Requires: lv_label*/ 475 | 476 | #define LV_USE_IMG 1 /*Requires: lv_label*/ 477 | 478 | #define LV_USE_LABEL 1 479 | #if LV_USE_LABEL 480 | #define LV_LABEL_TEXT_SELECTION 1 /*Enable selecting text of the label*/ 481 | #define LV_LABEL_LONG_TXT_HINT 1 /*Store some extra info in labels to speed up drawing of very long texts*/ 482 | #endif 483 | 484 | #define LV_USE_LINE 1 485 | 486 | #define LV_USE_ROLLER 1 /*Requires: lv_label*/ 487 | #if LV_USE_ROLLER 488 | #define LV_ROLLER_INF_PAGES 7 /*Number of extra "pages" when the roller is infinite*/ 489 | #endif 490 | 491 | #define LV_USE_SLIDER 1 /*Requires: lv_bar*/ 492 | 493 | #define LV_USE_SWITCH 1 494 | 495 | #define LV_USE_TEXTAREA 1 /*Requires: lv_label*/ 496 | #if LV_USE_TEXTAREA != 0 497 | #define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500 /*ms*/ 498 | #endif 499 | 500 | #define LV_USE_TABLE 1 501 | 502 | /*================== 503 | * EXTRA COMPONENTS 504 | *==================*/ 505 | 506 | /*----------- 507 | * Widgets 508 | *----------*/ 509 | #define LV_USE_ANIMIMG 1 510 | 511 | #define LV_USE_CALENDAR 1 512 | #if LV_USE_CALENDAR 513 | #define LV_CALENDAR_WEEK_STARTS_MONDAY 0 514 | #if LV_CALENDAR_WEEK_STARTS_MONDAY 515 | #define LV_CALENDAR_DEFAULT_DAY_NAMES {"Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"} 516 | #else 517 | #define LV_CALENDAR_DEFAULT_DAY_NAMES {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"} 518 | #endif 519 | 520 | #define LV_CALENDAR_DEFAULT_MONTH_NAMES {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"} 521 | #define LV_USE_CALENDAR_HEADER_ARROW 1 522 | #define LV_USE_CALENDAR_HEADER_DROPDOWN 1 523 | #endif /*LV_USE_CALENDAR*/ 524 | 525 | #define LV_USE_CHART 1 526 | 527 | #define LV_USE_COLORWHEEL 1 528 | 529 | #define LV_USE_IMGBTN 1 530 | 531 | #define LV_USE_KEYBOARD 1 532 | 533 | #define LV_USE_LED 1 534 | 535 | #define LV_USE_LIST 1 536 | 537 | #define LV_USE_MENU 1 538 | 539 | #define LV_USE_METER 1 540 | 541 | #define LV_USE_MSGBOX 1 542 | 543 | #define LV_USE_SPAN 1 544 | #if LV_USE_SPAN 545 | /*A line text can contain maximum num of span descriptor */ 546 | #define LV_SPAN_SNIPPET_STACK_SIZE 64 547 | #endif 548 | 549 | #define LV_USE_SPINBOX 1 550 | 551 | #define LV_USE_SPINNER 1 552 | 553 | #define LV_USE_TABVIEW 1 554 | 555 | #define LV_USE_TILEVIEW 1 556 | 557 | #define LV_USE_WIN 1 558 | 559 | /*----------- 560 | * Themes 561 | *----------*/ 562 | 563 | /*A simple, impressive and very complete theme*/ 564 | #define LV_USE_THEME_DEFAULT 1 565 | #if LV_USE_THEME_DEFAULT 566 | 567 | /*0: Light mode; 1: Dark mode*/ 568 | #define LV_THEME_DEFAULT_DARK 0 569 | 570 | /*1: Enable grow on press*/ 571 | #define LV_THEME_DEFAULT_GROW 1 572 | 573 | /*Default transition time in [ms]*/ 574 | #define LV_THEME_DEFAULT_TRANSITION_TIME 80 575 | #endif /*LV_USE_THEME_DEFAULT*/ 576 | 577 | /*A very simple theme that is a good starting point for a custom theme*/ 578 | #define LV_USE_THEME_BASIC 1 579 | 580 | /*A theme designed for monochrome displays*/ 581 | #define LV_USE_THEME_MONO 1 582 | 583 | /*----------- 584 | * Layouts 585 | *----------*/ 586 | 587 | /*A layout similar to Flexbox in CSS.*/ 588 | #define LV_USE_FLEX 1 589 | 590 | /*A layout similar to Grid in CSS.*/ 591 | #define LV_USE_GRID 1 592 | 593 | /*--------------------- 594 | * 3rd party libraries 595 | *--------------------*/ 596 | 597 | /*File system interfaces for common APIs */ 598 | 599 | /*API for fopen, fread, etc*/ 600 | #define LV_USE_FS_STDIO 0 601 | #if LV_USE_FS_STDIO 602 | #define LV_FS_STDIO_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ 603 | #define LV_FS_STDIO_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/ 604 | #define LV_FS_STDIO_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ 605 | #endif 606 | 607 | /*API for open, read, etc*/ 608 | #define LV_USE_FS_POSIX 0 609 | #if LV_USE_FS_POSIX 610 | #define LV_FS_POSIX_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ 611 | #define LV_FS_POSIX_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/ 612 | #define LV_FS_POSIX_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ 613 | #endif 614 | 615 | /*API for CreateFile, ReadFile, etc*/ 616 | #define LV_USE_FS_WIN32 0 617 | #if LV_USE_FS_WIN32 618 | #define LV_FS_WIN32_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ 619 | #define LV_FS_WIN32_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/ 620 | #define LV_FS_WIN32_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ 621 | #endif 622 | 623 | /*API for FATFS (needs to be added separately). Uses f_open, f_read, etc*/ 624 | #define LV_USE_FS_FATFS 0 625 | #if LV_USE_FS_FATFS 626 | #define LV_FS_FATFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ 627 | #define LV_FS_FATFS_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ 628 | #endif 629 | 630 | /*PNG decoder library*/ 631 | #define LV_USE_PNG 1 632 | 633 | /*BMP decoder library*/ 634 | #define LV_USE_BMP 1 635 | 636 | /* JPG + split JPG decoder library. 637 | * Split JPG is a custom format optimized for embedded systems. */ 638 | #define LV_USE_SJPG 1 639 | 640 | /*GIF decoder library*/ 641 | #define LV_USE_GIF 1 642 | 643 | /*QR code library*/ 644 | #define LV_USE_QRCODE 1 645 | 646 | /*FreeType library*/ 647 | #define LV_USE_FREETYPE 0 648 | #if LV_USE_FREETYPE 649 | /*Memory used by FreeType to cache characters [bytes] (-1: no caching)*/ 650 | #define LV_FREETYPE_CACHE_SIZE (16 * 1024) 651 | #if LV_FREETYPE_CACHE_SIZE >= 0 652 | /* 1: bitmap cache use the sbit cache, 0:bitmap cache use the image cache. */ 653 | /* sbit cache:it is much more memory efficient for small bitmaps(font size < 256) */ 654 | /* if font size >= 256, must be configured as image cache */ 655 | #define LV_FREETYPE_SBIT_CACHE 0 656 | /* Maximum number of opened FT_Face/FT_Size objects managed by this cache instance. */ 657 | /* (0:use system defaults) */ 658 | #define LV_FREETYPE_CACHE_FT_FACES 0 659 | #define LV_FREETYPE_CACHE_FT_SIZES 0 660 | #endif 661 | #endif 662 | 663 | /*Rlottie library*/ 664 | #define LV_USE_RLOTTIE 0 665 | 666 | /*FFmpeg library for image decoding and playing videos 667 | *Supports all major image formats so do not enable other image decoder with it*/ 668 | #define LV_USE_FFMPEG 0 669 | #if LV_USE_FFMPEG 670 | /*Dump input information to stderr*/ 671 | #define LV_FFMPEG_DUMP_FORMAT 0 672 | #endif 673 | 674 | /*----------- 675 | * Others 676 | *----------*/ 677 | 678 | /*1: Enable API to take snapshot for object*/ 679 | #define LV_USE_SNAPSHOT 1 680 | 681 | /*1: Enable Monkey test*/ 682 | #define LV_USE_MONKEY 0 683 | 684 | /*1: Enable grid navigation*/ 685 | #define LV_USE_GRIDNAV 0 686 | 687 | /*1: Enable lv_obj fragment*/ 688 | #define LV_USE_FRAGMENT 0 689 | 690 | /*1: Support using images as font in label or span widgets */ 691 | #define LV_USE_IMGFONT 0 692 | 693 | /*1: Enable a published subscriber based messaging system */ 694 | #define LV_USE_MSG 0 695 | 696 | /*1: Enable Pinyin input method*/ 697 | /*Requires: lv_keyboard*/ 698 | #define LV_USE_IME_PINYIN 0 699 | #if LV_USE_IME_PINYIN 700 | /*1: Use default thesaurus*/ 701 | /*If you do not use the default thesaurus, be sure to use `lv_ime_pinyin` after setting the thesauruss*/ 702 | #define LV_IME_PINYIN_USE_DEFAULT_DICT 1 703 | /*Set the maximum number of candidate panels that can be displayed*/ 704 | /*This needs to be adjusted according to the size of the screen*/ 705 | #define LV_IME_PINYIN_CAND_TEXT_NUM 6 706 | 707 | /*Use 9 key input(k9)*/ 708 | #define LV_IME_PINYIN_USE_K9_MODE 1 709 | #if LV_IME_PINYIN_USE_K9_MODE == 1 710 | #define LV_IME_PINYIN_K9_CAND_TEXT_NUM 3 711 | #endif // LV_IME_PINYIN_USE_K9_MODE 712 | #endif 713 | 714 | /*================== 715 | * EXAMPLES 716 | *==================*/ 717 | 718 | /*Enable the examples to be built with the library*/ 719 | #define LV_BUILD_EXAMPLES 1 720 | 721 | /*=================== 722 | * DEMO USAGE 723 | ====================*/ 724 | 725 | /*Show some widget. It might be required to increase `LV_MEM_SIZE` */ 726 | #define LV_USE_DEMO_WIDGETS 1 727 | #if LV_USE_DEMO_WIDGETS 728 | #define LV_DEMO_WIDGETS_SLIDESHOW 0 729 | #endif 730 | 731 | /*Demonstrate the usage of encoder and keyboard*/ 732 | #define LV_USE_DEMO_KEYPAD_AND_ENCODER 1 733 | 734 | /*Benchmark your system*/ 735 | #define LV_USE_DEMO_BENCHMARK 1 736 | #if LV_USE_DEMO_BENCHMARK 737 | /*Use RGB565A8 images with 16 bit color depth instead of ARGB8565*/ 738 | #define LV_DEMO_BENCHMARK_RGB565A8 0 739 | #endif 740 | 741 | /*Stress test for LVGL*/ 742 | #define LV_USE_DEMO_STRESS 1 743 | 744 | /*Music player demo*/ 745 | #define LV_USE_DEMO_MUSIC 1 746 | #if LV_USE_DEMO_MUSIC 747 | #define LV_DEMO_MUSIC_SQUARE 0 748 | #define LV_DEMO_MUSIC_LANDSCAPE 0 749 | #define LV_DEMO_MUSIC_ROUND 0 750 | #define LV_DEMO_MUSIC_LARGE 0 751 | #define LV_DEMO_MUSIC_AUTO_PLAY 0 752 | #endif 753 | 754 | /*--END OF LV_CONF_H--*/ 755 | 756 | #endif /*LV_CONF_H*/ 757 | 758 | #endif /*End of "Content enable"*/ 759 | -------------------------------------------------------------------------------- /include/lv_conf_v9.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file lv_conf.h 3 | * Configuration file for v9.0.0 4 | */ 5 | 6 | /* 7 | * Copy this file as `lv_conf.h` 8 | * 1. simply next to the `lvgl` folder 9 | * 2. or any other places and 10 | * - define `LV_CONF_INCLUDE_SIMPLE` 11 | * - add the path as include path 12 | */ 13 | 14 | /* clang-format off */ 15 | #if 1 /*Set it to "1" to enable content*/ 16 | 17 | #ifndef LV_CONF_H 18 | #define LV_CONF_H 19 | 20 | /*==================== 21 | COLOR SETTINGS 22 | *====================*/ 23 | 24 | /*Color depth: 8 (A8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888)*/ 25 | #define LV_COLOR_DEPTH 16 26 | 27 | /*========================= 28 | STDLIB WRAPPER SETTINGS 29 | *=========================*/ 30 | 31 | /* Possible values 32 | * - LV_STDLIB_BUILTIN: LVGL's built in implementation 33 | * - LV_STDLIB_CLIB: Standard C functions, like malloc, strlen, etc 34 | * - LV_STDLIB_MICROPYTHON: MicroPython implementation 35 | * - LV_STDLIB_RTTHREAD: RT-Thread implementation 36 | * - LV_STDLIB_CUSTOM: Implement the functions externally 37 | */ 38 | #define LV_USE_STDLIB_MALLOC LV_STDLIB_BUILTIN 39 | #define LV_USE_STDLIB_STRING LV_STDLIB_BUILTIN 40 | #define LV_USE_STDLIB_SPRINTF LV_STDLIB_BUILTIN 41 | 42 | 43 | #if LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN 44 | /*Size of the memory available for `lv_malloc()` in bytes (>= 2kB)*/ 45 | #define LV_MEM_SIZE (64U * 1024U) /*[bytes]*/ 46 | 47 | /*Size of the memory expand for `lv_malloc()` in bytes*/ 48 | #define LV_MEM_POOL_EXPAND_SIZE 0 49 | 50 | /*Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too.*/ 51 | #define LV_MEM_ADR 0 /*0: unused*/ 52 | /*Instead of an address give a memory allocator that will be called to get a memory pool for LVGL. E.g. my_malloc*/ 53 | #if LV_MEM_ADR == 0 54 | #undef LV_MEM_POOL_INCLUDE 55 | #undef LV_MEM_POOL_ALLOC 56 | #endif 57 | #endif /*LV_USE_MALLOC == LV_STDLIB_BUILTIN*/ 58 | 59 | /*==================== 60 | HAL SETTINGS 61 | *====================*/ 62 | 63 | /*Default display refresh, input device read and animation step period.*/ 64 | #define LV_DEF_REFR_PERIOD 33 /*[ms]*/ 65 | 66 | /*Default Dot Per Inch. Used to initialize default sizes such as widgets sized, style paddings. 67 | *(Not so important, you can adjust it to modify default sizes and spaces)*/ 68 | #define LV_DPI_DEF 130 /*[px/inch]*/ 69 | 70 | /*================= 71 | * OPERATING SYSTEM 72 | *=================*/ 73 | /*Select an operating system to use. Possible options: 74 | * - LV_OS_NONE 75 | * - LV_OS_PTHREAD 76 | * - LV_OS_FREERTOS 77 | * - LV_OS_CMSIS_RTOS2 78 | * - LV_OS_RTTHREAD 79 | * - LV_OS_WINDOWS 80 | * - LV_OS_CUSTOM */ 81 | #define LV_USE_OS LV_OS_NONE 82 | 83 | #if LV_USE_OS == LV_OS_CUSTOM 84 | #define LV_OS_CUSTOM_INCLUDE 85 | #endif 86 | 87 | /*======================== 88 | * RENDERING CONFIGURATION 89 | *========================*/ 90 | 91 | /*Align the stride of all layers and images to this bytes*/ 92 | #define LV_DRAW_BUF_STRIDE_ALIGN 1 93 | 94 | /*Align the start address of draw_buf addresses to this bytes*/ 95 | #define LV_DRAW_BUF_ALIGN 4 96 | 97 | #define LV_USE_DRAW_SW 1 98 | #if LV_USE_DRAW_SW == 1 99 | /* Set the number of draw unit. 100 | * > 1 requires an operating system enabled in `LV_USE_OS` 101 | * > 1 means multiply threads will render the screen in parallel */ 102 | #define LV_DRAW_SW_DRAW_UNIT_CNT 1 103 | 104 | /* Use Arm-2D to accelerate the sw render */ 105 | #define LV_USE_DRAW_ARM2D_SYNC 0 106 | 107 | /* If a widget has `style_opa < 255` (not `bg_opa`, `text_opa` etc) or not NORMAL blend mode 108 | * it is buffered into a "simple" layer before rendering. The widget can be buffered in smaller chunks. 109 | * "Transformed layers" (if `transform_angle/zoom` are set) use larger buffers 110 | * and can't be drawn in chunks. */ 111 | 112 | /*The target buffer size for simple layer chunks.*/ 113 | #define LV_DRAW_SW_LAYER_SIMPLE_BUF_SIZE (24 * 1024) /*[bytes]*/ 114 | 115 | /* 0: use a simple renderer capable of drawing only simple rectangles with gradient, images, texts, and straight lines only 116 | * 1: use a complex renderer capable of drawing rounded corners, shadow, skew lines, and arcs too */ 117 | #define LV_DRAW_SW_COMPLEX 1 118 | 119 | #if LV_DRAW_SW_COMPLEX == 1 120 | /*Allow buffering some shadow calculation. 121 | *LV_DRAW_SW_SHADOW_CACHE_SIZE is the max. shadow size to buffer, where shadow size is `shadow_width + radius` 122 | *Caching has LV_DRAW_SW_SHADOW_CACHE_SIZE^2 RAM cost*/ 123 | #define LV_DRAW_SW_SHADOW_CACHE_SIZE 0 124 | 125 | /* Set number of maximally cached circle data. 126 | * The circumference of 1/4 circle are saved for anti-aliasing 127 | * radius * 4 bytes are used per circle (the most often used radiuses are saved) 128 | * 0: to disable caching */ 129 | #define LV_DRAW_SW_CIRCLE_CACHE_SIZE 4 130 | #endif 131 | 132 | #define LV_USE_DRAW_SW_ASM LV_DRAW_SW_ASM_NONE 133 | 134 | #if LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_CUSTOM 135 | #define LV_DRAW_SW_ASM_CUSTOM_INCLUDE "" 136 | #endif 137 | #endif 138 | 139 | /* Use NXP's VG-Lite GPU on iMX RTxxx platforms. */ 140 | #define LV_USE_DRAW_VGLITE 0 141 | 142 | #if LV_USE_DRAW_VGLITE 143 | /* Enable blit quality degradation workaround recommended for screen's dimension > 352 pixels. */ 144 | #define LV_USE_VGLITE_BLIT_SPLIT 0 145 | 146 | #if LV_USE_OS 147 | /* Enable VGLite draw async. Queue multiple tasks and flash them once to the GPU. */ 148 | #define LV_USE_VGLITE_DRAW_ASYNC 1 149 | #endif 150 | 151 | /* Enable VGLite asserts. */ 152 | #define LV_USE_VGLITE_ASSERT 0 153 | #endif 154 | 155 | /* Use NXP's PXP on iMX RTxxx platforms. */ 156 | #define LV_USE_DRAW_PXP 0 157 | 158 | #if LV_USE_DRAW_PXP 159 | /* Enable PXP asserts. */ 160 | #define LV_USE_PXP_ASSERT 0 161 | #endif 162 | 163 | /* Use Renesas Dave2D on RA platforms. */ 164 | #define LV_USE_DRAW_DAVE2D 0 165 | 166 | /* Draw using cached SDL textures*/ 167 | #define LV_USE_DRAW_SDL 0 168 | 169 | /* Use VG-Lite GPU. */ 170 | #define LV_USE_DRAW_VG_LITE 0 171 | 172 | #if LV_USE_DRAW_VG_LITE 173 | /* Enable VG-Lite custom external 'gpu_init()' function */ 174 | #define LV_VG_LITE_USE_GPU_INIT 0 175 | 176 | /* Enable VG-Lite assert. */ 177 | #define LV_VG_LITE_USE_ASSERT 0 178 | 179 | #endif 180 | 181 | /*======================= 182 | * FEATURE CONFIGURATION 183 | *=======================*/ 184 | 185 | /*------------- 186 | * Logging 187 | *-----------*/ 188 | 189 | /*Enable the log module*/ 190 | #define LV_USE_LOG 0 191 | #if LV_USE_LOG 192 | 193 | /*How important log should be added: 194 | *LV_LOG_LEVEL_TRACE A lot of logs to give detailed information 195 | *LV_LOG_LEVEL_INFO Log important events 196 | *LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem 197 | *LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail 198 | *LV_LOG_LEVEL_USER Only logs added by the user 199 | *LV_LOG_LEVEL_NONE Do not log anything*/ 200 | #define LV_LOG_LEVEL LV_LOG_LEVEL_WARN 201 | 202 | /*1: Print the log with 'printf'; 203 | *0: User need to register a callback with `lv_log_register_print_cb()`*/ 204 | #define LV_LOG_PRINTF 1 205 | 206 | /*1: Enable print timestamp; 207 | *0: Disable print timestamp*/ 208 | #define LV_LOG_USE_TIMESTAMP 1 209 | 210 | /*1: Print file and line number of the log; 211 | *0: Do not print file and line number of the log*/ 212 | #define LV_LOG_USE_FILE_LINE 1 213 | 214 | /*Enable/disable LV_LOG_TRACE in modules that produces a huge number of logs*/ 215 | #define LV_LOG_TRACE_MEM 1 216 | #define LV_LOG_TRACE_TIMER 1 217 | #define LV_LOG_TRACE_INDEV 1 218 | #define LV_LOG_TRACE_DISP_REFR 1 219 | #define LV_LOG_TRACE_EVENT 1 220 | #define LV_LOG_TRACE_OBJ_CREATE 1 221 | #define LV_LOG_TRACE_LAYOUT 1 222 | #define LV_LOG_TRACE_ANIM 1 223 | #define LV_LOG_TRACE_CACHE 1 224 | 225 | #endif /*LV_USE_LOG*/ 226 | 227 | /*------------- 228 | * Asserts 229 | *-----------*/ 230 | 231 | /*Enable asserts if an operation is failed or an invalid data is found. 232 | *If LV_USE_LOG is enabled an error message will be printed on failure*/ 233 | #define LV_USE_ASSERT_NULL 1 /*Check if the parameter is NULL. (Very fast, recommended)*/ 234 | #define LV_USE_ASSERT_MALLOC 1 /*Checks is the memory is successfully allocated or no. (Very fast, recommended)*/ 235 | #define LV_USE_ASSERT_STYLE 0 /*Check if the styles are properly initialized. (Very fast, recommended)*/ 236 | #define LV_USE_ASSERT_MEM_INTEGRITY 0 /*Check the integrity of `lv_mem` after critical operations. (Slow)*/ 237 | #define LV_USE_ASSERT_OBJ 0 /*Check the object's type and existence (e.g. not deleted). (Slow)*/ 238 | 239 | /*Add a custom handler when assert happens e.g. to restart the MCU*/ 240 | #define LV_ASSERT_HANDLER_INCLUDE 241 | #define LV_ASSERT_HANDLER while(1); /*Halt by default*/ 242 | 243 | /*------------- 244 | * Debug 245 | *-----------*/ 246 | 247 | /*1: Draw random colored rectangles over the redrawn areas*/ 248 | #define LV_USE_REFR_DEBUG 0 249 | 250 | /*1: Draw a red overlay for ARGB layers and a green overlay for RGB layers*/ 251 | #define LV_USE_LAYER_DEBUG 0 252 | 253 | /*1: Draw overlays with different colors for each draw_unit's tasks. 254 | *Also add the index number of the draw unit on white background. 255 | *For layers add the index number of the draw unit on black background.*/ 256 | #define LV_USE_PARALLEL_DRAW_DEBUG 0 257 | 258 | /*------------- 259 | * Others 260 | *-----------*/ 261 | 262 | #define LV_ENABLE_GLOBAL_CUSTOM 0 263 | #if LV_ENABLE_GLOBAL_CUSTOM 264 | /*Header to include for the custom 'lv_global' function"*/ 265 | #define LV_GLOBAL_CUSTOM_INCLUDE 266 | #endif 267 | 268 | /*Default cache size in bytes. 269 | *Used by image decoders such as `lv_lodepng` to keep the decoded image in the memory. 270 | *If size is not set to 0, the decoder will fail to decode when the cache is full. 271 | *If size is 0, the cache function is not enabled and the decoded mem will be released immediately after use.*/ 272 | #define LV_CACHE_DEF_SIZE 0 273 | 274 | /*Default number of image header cache entries. The cache is used to store the headers of images 275 | *The main logic is like `LV_CACHE_DEF_SIZE` but for image headers.*/ 276 | #define LV_IMAGE_HEADER_CACHE_DEF_CNT 0 277 | 278 | /*Number of stops allowed per gradient. Increase this to allow more stops. 279 | *This adds (sizeof(lv_color_t) + 1) bytes per additional stop*/ 280 | #define LV_GRADIENT_MAX_STOPS 2 281 | 282 | /* Adjust color mix functions rounding. GPUs might calculate color mix (blending) differently. 283 | * 0: round down, 64: round up from x.75, 128: round up from half, 192: round up from x.25, 254: round up */ 284 | #define LV_COLOR_MIX_ROUND_OFS 0 285 | 286 | /* Add 2 x 32 bit variables to each lv_obj_t to speed up getting style properties */ 287 | #define LV_OBJ_STYLE_CACHE 0 288 | 289 | /* Add `id` field to `lv_obj_t` */ 290 | #define LV_USE_OBJ_ID 0 291 | 292 | /* Use lvgl builtin method for obj ID */ 293 | #define LV_USE_OBJ_ID_BUILTIN 0 294 | 295 | /*Use obj property set/get API*/ 296 | #define LV_USE_OBJ_PROPERTY 0 297 | 298 | /* VG-Lite Simulator */ 299 | /*Requires: LV_USE_THORVG_INTERNAL or LV_USE_THORVG_EXTERNAL */ 300 | #define LV_USE_VG_LITE_THORVG 1 301 | 302 | #if LV_USE_VG_LITE_THORVG 303 | 304 | /*Enable LVGL's blend mode support*/ 305 | #define LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT 0 306 | 307 | /*Enable YUV color format support*/ 308 | #define LV_VG_LITE_THORVG_YUV_SUPPORT 0 309 | 310 | /*Enable 16 pixels alignment*/ 311 | #define LV_VG_LITE_THORVG_16PIXELS_ALIGN 1 312 | 313 | /*Enable multi-thread render*/ 314 | #define LV_VG_LITE_THORVG_THREAD_RENDER 0 315 | 316 | #endif 317 | 318 | /*===================== 319 | * COMPILER SETTINGS 320 | *====================*/ 321 | 322 | /*For big endian systems set to 1*/ 323 | #define LV_BIG_ENDIAN_SYSTEM 0 324 | 325 | /*Define a custom attribute to `lv_tick_inc` function*/ 326 | #define LV_ATTRIBUTE_TICK_INC 327 | 328 | /*Define a custom attribute to `lv_timer_handler` function*/ 329 | #define LV_ATTRIBUTE_TIMER_HANDLER 330 | 331 | /*Define a custom attribute to `lv_display_flush_ready` function*/ 332 | #define LV_ATTRIBUTE_FLUSH_READY 333 | 334 | /*Required alignment size for buffers*/ 335 | #define LV_ATTRIBUTE_MEM_ALIGN_SIZE 1 336 | 337 | /*Will be added where memories needs to be aligned (with -Os data might not be aligned to boundary by default). 338 | * E.g. __attribute__((aligned(4)))*/ 339 | #define LV_ATTRIBUTE_MEM_ALIGN 340 | 341 | /*Attribute to mark large constant arrays for example font's bitmaps*/ 342 | #define LV_ATTRIBUTE_LARGE_CONST 343 | 344 | /*Compiler prefix for a big array declaration in RAM*/ 345 | #define LV_ATTRIBUTE_LARGE_RAM_ARRAY 346 | 347 | /*Place performance critical functions into a faster memory (e.g RAM)*/ 348 | #define LV_ATTRIBUTE_FAST_MEM 349 | 350 | /*Export integer constant to binding. This macro is used with constants in the form of LV_ that 351 | *should also appear on LVGL binding API such as Micropython.*/ 352 | #define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning /*The default value just prevents GCC warning*/ 353 | 354 | /*Prefix all global extern data with this*/ 355 | #define LV_ATTRIBUTE_EXTERN_DATA 356 | 357 | /* Use `float` as `lv_value_precise_t` */ 358 | #define LV_USE_FLOAT 0 359 | 360 | /*================== 361 | * FONT USAGE 362 | *===================*/ 363 | 364 | /*Montserrat fonts with ASCII range and some symbols using bpp = 4 365 | *https://fonts.google.com/specimen/Montserrat*/ 366 | #define LV_FONT_MONTSERRAT_8 0 367 | #define LV_FONT_MONTSERRAT_10 0 368 | #define LV_FONT_MONTSERRAT_12 1 369 | #define LV_FONT_MONTSERRAT_14 1 370 | #define LV_FONT_MONTSERRAT_16 1 371 | #define LV_FONT_MONTSERRAT_18 1 372 | #define LV_FONT_MONTSERRAT_20 0 373 | #define LV_FONT_MONTSERRAT_22 0 374 | #define LV_FONT_MONTSERRAT_24 1 375 | #define LV_FONT_MONTSERRAT_26 0 376 | #define LV_FONT_MONTSERRAT_28 0 377 | #define LV_FONT_MONTSERRAT_30 0 378 | #define LV_FONT_MONTSERRAT_32 0 379 | #define LV_FONT_MONTSERRAT_34 0 380 | #define LV_FONT_MONTSERRAT_36 0 381 | #define LV_FONT_MONTSERRAT_38 0 382 | #define LV_FONT_MONTSERRAT_40 0 383 | #define LV_FONT_MONTSERRAT_42 0 384 | #define LV_FONT_MONTSERRAT_44 0 385 | #define LV_FONT_MONTSERRAT_46 0 386 | #define LV_FONT_MONTSERRAT_48 0 387 | 388 | /*Demonstrate special features*/ 389 | #define LV_FONT_MONTSERRAT_28_COMPRESSED 0 /*bpp = 3*/ 390 | #define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 0 /*Hebrew, Arabic, Persian letters and all their forms*/ 391 | #define LV_FONT_SIMSUN_16_CJK 0 /*1000 most common CJK radicals*/ 392 | 393 | /*Pixel perfect monospace fonts*/ 394 | #define LV_FONT_UNSCII_8 0 395 | #define LV_FONT_UNSCII_16 0 396 | 397 | /*Optionally declare custom fonts here. 398 | *You can use these fonts as default font too and they will be available globally. 399 | *E.g. #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) LV_FONT_DECLARE(my_font_2)*/ 400 | #define LV_FONT_CUSTOM_DECLARE 401 | 402 | /*Always set a default font*/ 403 | #define LV_FONT_DEFAULT &lv_font_montserrat_14 404 | 405 | /*Enable handling large font and/or fonts with a lot of characters. 406 | *The limit depends on the font size, font face and bpp. 407 | *Compiler error will be triggered if a font needs it.*/ 408 | #define LV_FONT_FMT_TXT_LARGE 0 409 | 410 | /*Enables/disables support for compressed fonts.*/ 411 | #define LV_USE_FONT_COMPRESSED 0 412 | 413 | /*Enable drawing placeholders when glyph dsc is not found*/ 414 | #define LV_USE_FONT_PLACEHOLDER 1 415 | 416 | /*================= 417 | * TEXT SETTINGS 418 | *=================*/ 419 | 420 | /** 421 | * Select a character encoding for strings. 422 | * Your IDE or editor should have the same character encoding 423 | * - LV_TXT_ENC_UTF8 424 | * - LV_TXT_ENC_ASCII 425 | */ 426 | #define LV_TXT_ENC LV_TXT_ENC_UTF8 427 | 428 | /*Can break (wrap) texts on these chars*/ 429 | #define LV_TXT_BREAK_CHARS " ,.;:-_)]}" 430 | 431 | /*If a word is at least this long, will break wherever "prettiest" 432 | *To disable, set to a value <= 0*/ 433 | #define LV_TXT_LINE_BREAK_LONG_LEN 0 434 | 435 | /*Minimum number of characters in a long word to put on a line before a break. 436 | *Depends on LV_TXT_LINE_BREAK_LONG_LEN.*/ 437 | #define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3 438 | 439 | /*Minimum number of characters in a long word to put on a line after a break. 440 | *Depends on LV_TXT_LINE_BREAK_LONG_LEN.*/ 441 | #define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3 442 | 443 | /*Support bidirectional texts. Allows mixing Left-to-Right and Right-to-Left texts. 444 | *The direction will be processed according to the Unicode Bidirectional Algorithm: 445 | *https://www.w3.org/International/articles/inline-bidi-markup/uba-basics*/ 446 | #define LV_USE_BIDI 0 447 | #if LV_USE_BIDI 448 | /*Set the default direction. Supported values: 449 | *`LV_BASE_DIR_LTR` Left-to-Right 450 | *`LV_BASE_DIR_RTL` Right-to-Left 451 | *`LV_BASE_DIR_AUTO` detect texts base direction*/ 452 | #define LV_BIDI_BASE_DIR_DEF LV_BASE_DIR_AUTO 453 | #endif 454 | 455 | /*Enable Arabic/Persian processing 456 | *In these languages characters should be replaced with an other form based on their position in the text*/ 457 | #define LV_USE_ARABIC_PERSIAN_CHARS 0 458 | 459 | /*================== 460 | * WIDGETS 461 | *================*/ 462 | 463 | /*Documentation of the widgets: https://docs.lvgl.io/latest/en/html/widgets/index.html*/ 464 | 465 | #define LV_WIDGETS_HAS_DEFAULT_VALUE 1 466 | 467 | #define LV_USE_ANIMIMG 1 468 | 469 | #define LV_USE_ARC 1 470 | 471 | #define LV_USE_BAR 1 472 | 473 | #define LV_USE_BUTTON 1 474 | 475 | #define LV_USE_BUTTONMATRIX 1 476 | 477 | #define LV_USE_CALENDAR 1 478 | #if LV_USE_CALENDAR 479 | #define LV_CALENDAR_WEEK_STARTS_MONDAY 0 480 | #if LV_CALENDAR_WEEK_STARTS_MONDAY 481 | #define LV_CALENDAR_DEFAULT_DAY_NAMES {"Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"} 482 | #else 483 | #define LV_CALENDAR_DEFAULT_DAY_NAMES {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"} 484 | #endif 485 | 486 | #define LV_CALENDAR_DEFAULT_MONTH_NAMES {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"} 487 | #define LV_USE_CALENDAR_HEADER_ARROW 1 488 | #define LV_USE_CALENDAR_HEADER_DROPDOWN 1 489 | #endif /*LV_USE_CALENDAR*/ 490 | 491 | #define LV_USE_CANVAS 1 492 | 493 | #define LV_USE_CHART 1 494 | 495 | #define LV_USE_CHECKBOX 1 496 | 497 | #define LV_USE_DROPDOWN 1 /*Requires: lv_label*/ 498 | 499 | #define LV_USE_IMAGE 1 /*Requires: lv_label*/ 500 | 501 | #define LV_USE_IMAGEBUTTON 1 502 | 503 | #define LV_USE_KEYBOARD 1 504 | 505 | #define LV_USE_LABEL 1 506 | #if LV_USE_LABEL 507 | #define LV_LABEL_TEXT_SELECTION 1 /*Enable selecting text of the label*/ 508 | #define LV_LABEL_LONG_TXT_HINT 1 /*Store some extra info in labels to speed up drawing of very long texts*/ 509 | #define LV_LABEL_WAIT_CHAR_COUNT 3 /*The count of wait chart*/ 510 | #endif 511 | 512 | #define LV_USE_LED 1 513 | 514 | #define LV_USE_LINE 1 515 | 516 | #define LV_USE_LIST 1 517 | 518 | #define LV_USE_MENU 1 519 | 520 | #define LV_USE_MSGBOX 1 521 | 522 | #define LV_USE_ROLLER 1 /*Requires: lv_label*/ 523 | 524 | #define LV_USE_SCALE 1 525 | 526 | #define LV_USE_SLIDER 1 /*Requires: lv_bar*/ 527 | 528 | #define LV_USE_SPAN 1 529 | #if LV_USE_SPAN 530 | /*A line text can contain maximum num of span descriptor */ 531 | #define LV_SPAN_SNIPPET_STACK_SIZE 64 532 | #endif 533 | 534 | #define LV_USE_SPINBOX 1 535 | 536 | #define LV_USE_SPINNER 1 537 | 538 | #define LV_USE_SWITCH 1 539 | 540 | #define LV_USE_TEXTAREA 1 /*Requires: lv_label*/ 541 | #if LV_USE_TEXTAREA != 0 542 | #define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500 /*ms*/ 543 | #endif 544 | 545 | #define LV_USE_TABLE 1 546 | 547 | #define LV_USE_TABVIEW 1 548 | 549 | #define LV_USE_TILEVIEW 1 550 | 551 | #define LV_USE_WIN 1 552 | 553 | /*================== 554 | * THEMES 555 | *==================*/ 556 | 557 | /*A simple, impressive and very complete theme*/ 558 | #define LV_USE_THEME_DEFAULT 1 559 | #if LV_USE_THEME_DEFAULT 560 | 561 | /*0: Light mode; 1: Dark mode*/ 562 | #define LV_THEME_DEFAULT_DARK 0 563 | 564 | /*1: Enable grow on press*/ 565 | #define LV_THEME_DEFAULT_GROW 1 566 | 567 | /*Default transition time in [ms]*/ 568 | #define LV_THEME_DEFAULT_TRANSITION_TIME 80 569 | #endif /*LV_USE_THEME_DEFAULT*/ 570 | 571 | /*A very simple theme that is a good starting point for a custom theme*/ 572 | #define LV_USE_THEME_SIMPLE 1 573 | 574 | /*A theme designed for monochrome displays*/ 575 | #define LV_USE_THEME_MONO 1 576 | 577 | /*================== 578 | * LAYOUTS 579 | *==================*/ 580 | 581 | /*A layout similar to Flexbox in CSS.*/ 582 | #define LV_USE_FLEX 1 583 | 584 | /*A layout similar to Grid in CSS.*/ 585 | #define LV_USE_GRID 1 586 | 587 | /*==================== 588 | * 3RD PARTS LIBRARIES 589 | *====================*/ 590 | 591 | /*File system interfaces for common APIs */ 592 | 593 | /*API for fopen, fread, etc*/ 594 | #define LV_USE_FS_STDIO 0 595 | #if LV_USE_FS_STDIO 596 | #define LV_FS_STDIO_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ 597 | #define LV_FS_STDIO_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/ 598 | #define LV_FS_STDIO_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ 599 | #endif 600 | 601 | /*API for open, read, etc*/ 602 | #define LV_USE_FS_POSIX 0 603 | #if LV_USE_FS_POSIX 604 | #define LV_FS_POSIX_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ 605 | #define LV_FS_POSIX_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/ 606 | #define LV_FS_POSIX_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ 607 | #endif 608 | 609 | /*API for CreateFile, ReadFile, etc*/ 610 | #define LV_USE_FS_WIN32 0 611 | #if LV_USE_FS_WIN32 612 | #define LV_FS_WIN32_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ 613 | #define LV_FS_WIN32_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/ 614 | #define LV_FS_WIN32_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ 615 | #endif 616 | 617 | /*API for FATFS (needs to be added separately). Uses f_open, f_read, etc*/ 618 | #define LV_USE_FS_FATFS 0 619 | #if LV_USE_FS_FATFS 620 | #define LV_FS_FATFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ 621 | #define LV_FS_FATFS_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ 622 | #endif 623 | 624 | /*API for memory-mapped file access. */ 625 | #define LV_USE_FS_MEMFS 0 626 | #if LV_USE_FS_MEMFS 627 | #define LV_FS_MEMFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ 628 | #endif 629 | 630 | /*LODEPNG decoder library*/ 631 | #define LV_USE_LODEPNG 0 632 | 633 | /*PNG decoder(libpng) library*/ 634 | #define LV_USE_LIBPNG 0 635 | 636 | /*BMP decoder library*/ 637 | #define LV_USE_BMP 0 638 | 639 | /* JPG + split JPG decoder library. 640 | * Split JPG is a custom format optimized for embedded systems. */ 641 | #define LV_USE_TJPGD 0 642 | 643 | /* libjpeg-turbo decoder library. 644 | * Supports complete JPEG specifications and high-performance JPEG decoding. */ 645 | #define LV_USE_LIBJPEG_TURBO 0 646 | 647 | /*GIF decoder library*/ 648 | #define LV_USE_GIF 0 649 | #if LV_USE_GIF 650 | /*GIF decoder accelerate*/ 651 | #define LV_GIF_CACHE_DECODE_DATA 0 652 | #endif 653 | 654 | 655 | /*Decode bin images to RAM*/ 656 | #define LV_BIN_DECODER_RAM_LOAD 0 657 | 658 | /*RLE decompress library*/ 659 | #define LV_USE_RLE 0 660 | 661 | /*QR code library*/ 662 | #define LV_USE_QRCODE 0 663 | 664 | /*Barcode code library*/ 665 | #define LV_USE_BARCODE 0 666 | 667 | /*FreeType library*/ 668 | #define LV_USE_FREETYPE 0 669 | #if LV_USE_FREETYPE 670 | /*Memory used by FreeType to cache characters in kilobytes*/ 671 | #define LV_FREETYPE_CACHE_SIZE 768 672 | 673 | /*Let FreeType to use LVGL memory and file porting*/ 674 | #define LV_FREETYPE_USE_LVGL_PORT 0 675 | 676 | /* Maximum number of opened FT_Face/FT_Size objects managed by this cache instance. */ 677 | /* (0:use system defaults) */ 678 | #define LV_FREETYPE_CACHE_FT_FACES 8 679 | #define LV_FREETYPE_CACHE_FT_SIZES 8 680 | #define LV_FREETYPE_CACHE_FT_GLYPH_CNT 256 681 | #endif 682 | 683 | /* Built-in TTF decoder */ 684 | #define LV_USE_TINY_TTF 0 685 | #if LV_USE_TINY_TTF 686 | /* Enable loading TTF data from files */ 687 | #define LV_TINY_TTF_FILE_SUPPORT 0 688 | #endif 689 | 690 | /*Rlottie library*/ 691 | #define LV_USE_RLOTTIE 0 692 | 693 | /*Enable Vector Graphic APIs*/ 694 | #define LV_USE_VECTOR_GRAPHIC 0 695 | 696 | /* Enable ThorVG (vector graphics library) from the src/libs folder */ 697 | #define LV_USE_THORVG_INTERNAL 0 698 | 699 | /* Enable ThorVG by assuming that its installed and linked to the project */ 700 | #define LV_USE_THORVG_EXTERNAL 0 701 | 702 | /*Enable LZ4 compress/decompress lib*/ 703 | #define LV_USE_LZ4 0 704 | 705 | /*Use lvgl built-in LZ4 lib*/ 706 | #define LV_USE_LZ4_INTERNAL 0 707 | 708 | /*Use external LZ4 library*/ 709 | #define LV_USE_LZ4_EXTERNAL 0 710 | 711 | /*FFmpeg library for image decoding and playing videos 712 | *Supports all major image formats so do not enable other image decoder with it*/ 713 | #define LV_USE_FFMPEG 0 714 | #if LV_USE_FFMPEG 715 | /*Dump input information to stderr*/ 716 | #define LV_FFMPEG_DUMP_FORMAT 0 717 | #endif 718 | 719 | /*================== 720 | * OTHERS 721 | *==================*/ 722 | 723 | /*1: Enable API to take snapshot for object*/ 724 | #define LV_USE_SNAPSHOT 0 725 | 726 | /*1: Enable system monitor component*/ 727 | #define LV_USE_SYSMON 0 728 | #if LV_USE_SYSMON 729 | /*Get the idle percentage. E.g. uint32_t my_get_idle(void);*/ 730 | #define LV_SYSMON_GET_IDLE lv_timer_get_idle 731 | 732 | /*1: Show CPU usage and FPS count 733 | * Requires `LV_USE_SYSMON = 1`*/ 734 | #define LV_USE_PERF_MONITOR 1 735 | #if LV_USE_PERF_MONITOR 736 | #define LV_USE_PERF_MONITOR_POS LV_ALIGN_BOTTOM_RIGHT 737 | 738 | /*0: Displays performance data on the screen, 1: Prints performance data using log.*/ 739 | #define LV_USE_PERF_MONITOR_LOG_MODE 0 740 | #endif 741 | 742 | /*1: Show the used memory and the memory fragmentation 743 | * Requires `LV_USE_BUILTIN_MALLOC = 1` 744 | * Requires `LV_USE_SYSMON = 1`*/ 745 | #define LV_USE_MEM_MONITOR 1 746 | #if LV_USE_MEM_MONITOR 747 | #define LV_USE_MEM_MONITOR_POS LV_ALIGN_BOTTOM_LEFT 748 | #endif 749 | 750 | #endif /*LV_USE_SYSMON*/ 751 | 752 | /*1: Enable the runtime performance profiler*/ 753 | #define LV_USE_PROFILER 0 754 | #if LV_USE_PROFILER 755 | /*1: Enable the built-in profiler*/ 756 | #define LV_USE_PROFILER_BUILTIN 1 757 | #if LV_USE_PROFILER_BUILTIN 758 | /*Default profiler trace buffer size*/ 759 | #define LV_PROFILER_BUILTIN_BUF_SIZE (16 * 1024) /*[bytes]*/ 760 | #endif 761 | 762 | /*Header to include for the profiler*/ 763 | #define LV_PROFILER_INCLUDE "lvgl/src/misc/lv_profiler_builtin.h" 764 | 765 | /*Profiler start point function*/ 766 | #define LV_PROFILER_BEGIN LV_PROFILER_BUILTIN_BEGIN 767 | 768 | /*Profiler end point function*/ 769 | #define LV_PROFILER_END LV_PROFILER_BUILTIN_END 770 | 771 | /*Profiler start point function with custom tag*/ 772 | #define LV_PROFILER_BEGIN_TAG LV_PROFILER_BUILTIN_BEGIN_TAG 773 | 774 | /*Profiler end point function with custom tag*/ 775 | #define LV_PROFILER_END_TAG LV_PROFILER_BUILTIN_END_TAG 776 | #endif 777 | 778 | /*1: Enable Monkey test*/ 779 | #define LV_USE_MONKEY 0 780 | 781 | /*1: Enable grid navigation*/ 782 | #define LV_USE_GRIDNAV 0 783 | 784 | /*1: Enable lv_obj fragment*/ 785 | #define LV_USE_FRAGMENT 0 786 | 787 | /*1: Support using images as font in label or span widgets */ 788 | #define LV_USE_IMGFONT 0 789 | 790 | /*1: Enable an observer pattern implementation*/ 791 | #define LV_USE_OBSERVER 1 792 | 793 | /*1: Enable Pinyin input method*/ 794 | /*Requires: lv_keyboard*/ 795 | #define LV_USE_IME_PINYIN 0 796 | #if LV_USE_IME_PINYIN 797 | /*1: Use default thesaurus*/ 798 | /*If you do not use the default thesaurus, be sure to use `lv_ime_pinyin` after setting the thesauruss*/ 799 | #define LV_IME_PINYIN_USE_DEFAULT_DICT 1 800 | /*Set the maximum number of candidate panels that can be displayed*/ 801 | /*This needs to be adjusted according to the size of the screen*/ 802 | #define LV_IME_PINYIN_CAND_TEXT_NUM 6 803 | 804 | /*Use 9 key input(k9)*/ 805 | #define LV_IME_PINYIN_USE_K9_MODE 1 806 | #if LV_IME_PINYIN_USE_K9_MODE == 1 807 | #define LV_IME_PINYIN_K9_CAND_TEXT_NUM 3 808 | #endif /*LV_IME_PINYIN_USE_K9_MODE*/ 809 | #endif 810 | 811 | /*1: Enable file explorer*/ 812 | /*Requires: lv_table*/ 813 | #define LV_USE_FILE_EXPLORER 0 814 | #if LV_USE_FILE_EXPLORER 815 | /*Maximum length of path*/ 816 | #define LV_FILE_EXPLORER_PATH_MAX_LEN (128) 817 | /*Quick access bar, 1:use, 0:not use*/ 818 | /*Requires: lv_list*/ 819 | #define LV_FILE_EXPLORER_QUICK_ACCESS 1 820 | #endif 821 | 822 | /*================== 823 | * DEVICES 824 | *==================*/ 825 | 826 | /*Use SDL to open window on PC and handle mouse and keyboard*/ 827 | #define LV_USE_SDL 0 828 | #if LV_USE_SDL 829 | #define LV_SDL_INCLUDE_PATH 830 | #define LV_SDL_RENDER_MODE LV_DISPLAY_RENDER_MODE_DIRECT /*LV_DISPLAY_RENDER_MODE_DIRECT is recommended for best performance*/ 831 | #define LV_SDL_BUF_COUNT 1 /*1 or 2*/ 832 | #define LV_SDL_FULLSCREEN 0 /*1: Make the window full screen by default*/ 833 | #define LV_SDL_DIRECT_EXIT 1 /*1: Exit the application when all SDL windows are closed*/ 834 | #endif 835 | 836 | /*Use X11 to open window on Linux desktop and handle mouse and keyboard*/ 837 | #define LV_USE_X11 0 838 | #if LV_USE_X11 839 | #define LV_X11_DIRECT_EXIT 1 /*Exit the application when all X11 windows have been closed*/ 840 | #define LV_X11_DOUBLE_BUFFER 1 /*Use double buffers for endering*/ 841 | /*select only 1 of the following render modes (LV_X11_RENDER_MODE_PARTIAL preferred!)*/ 842 | #define LV_X11_RENDER_MODE_PARTIAL 1 /*Partial render mode (preferred)*/ 843 | #define LV_X11_RENDER_MODE_DIRECT 0 /*direct render mode*/ 844 | #define LV_X11_RENDER_MODE_FULL 0 /*Full render mode*/ 845 | #endif 846 | 847 | /*Driver for /dev/fb*/ 848 | #define LV_USE_LINUX_FBDEV 0 849 | #if LV_USE_LINUX_FBDEV 850 | #define LV_LINUX_FBDEV_BSD 0 851 | #define LV_LINUX_FBDEV_RENDER_MODE LV_DISPLAY_RENDER_MODE_PARTIAL 852 | #define LV_LINUX_FBDEV_BUFFER_COUNT 0 853 | #define LV_LINUX_FBDEV_BUFFER_SIZE 60 854 | #endif 855 | 856 | /*Use Nuttx to open window and handle touchscreen*/ 857 | #define LV_USE_NUTTX 0 858 | 859 | #if LV_USE_NUTTX 860 | #define LV_USE_NUTTX_LIBUV 0 861 | 862 | /*Use Nuttx custom init API to open window and handle touchscreen*/ 863 | #define LV_USE_NUTTX_CUSTOM_INIT 0 864 | 865 | /*Driver for /dev/lcd*/ 866 | #define LV_USE_NUTTX_LCD 0 867 | #if LV_USE_NUTTX_LCD 868 | #define LV_NUTTX_LCD_BUFFER_COUNT 0 869 | #define LV_NUTTX_LCD_BUFFER_SIZE 60 870 | #endif 871 | 872 | /*Driver for /dev/input*/ 873 | #define LV_USE_NUTTX_TOUCHSCREEN 0 874 | 875 | #endif 876 | 877 | /*Driver for /dev/dri/card*/ 878 | #define LV_USE_LINUX_DRM 0 879 | 880 | /*Interface for TFT_eSPI*/ 881 | #define LV_USE_TFT_ESPI 0 882 | 883 | /*Driver for evdev input devices*/ 884 | #define LV_USE_EVDEV 0 885 | 886 | /*Drivers for LCD devices connected via SPI/parallel port*/ 887 | #define LV_USE_ST7735 0 888 | #define LV_USE_ST7789 0 889 | #define LV_USE_ST7796 0 890 | #define LV_USE_ILI9341 0 891 | 892 | #define LV_USE_GENERIC_MIPI (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341) 893 | 894 | /* LVGL Windows backend */ 895 | #define LV_USE_WINDOWS 0 896 | 897 | /*================== 898 | * EXAMPLES 899 | *==================*/ 900 | 901 | /*Enable the examples to be built with the library*/ 902 | #define LV_BUILD_EXAMPLES 1 903 | 904 | /*=================== 905 | * DEMO USAGE 906 | ====================*/ 907 | 908 | /*Show some widget. It might be required to increase `LV_MEM_SIZE` */ 909 | #define LV_USE_DEMO_WIDGETS 1 910 | #if LV_USE_DEMO_WIDGETS 911 | #define LV_DEMO_WIDGETS_SLIDESHOW 0 912 | #endif 913 | 914 | /*Demonstrate the usage of encoder and keyboard*/ 915 | #define LV_USE_DEMO_KEYPAD_AND_ENCODER 0 916 | 917 | /*Benchmark your system*/ 918 | #define LV_USE_DEMO_BENCHMARK 1 919 | 920 | /*Render test for each primitives. Requires at least 480x272 display*/ 921 | #define LV_USE_DEMO_RENDER 0 922 | 923 | /*Stress test for LVGL*/ 924 | #define LV_USE_DEMO_STRESS 1 925 | 926 | /*Music player demo*/ 927 | #define LV_USE_DEMO_MUSIC 0 928 | #if LV_USE_DEMO_MUSIC 929 | #define LV_DEMO_MUSIC_SQUARE 0 930 | #define LV_DEMO_MUSIC_LANDSCAPE 0 931 | #define LV_DEMO_MUSIC_ROUND 0 932 | #define LV_DEMO_MUSIC_LARGE 0 933 | #define LV_DEMO_MUSIC_AUTO_PLAY 0 934 | #endif 935 | 936 | /*Flex layout demo*/ 937 | #define LV_USE_DEMO_FLEX_LAYOUT 0 938 | 939 | /*Smart-phone like multi-language demo*/ 940 | #define LV_USE_DEMO_MULTILANG 0 941 | 942 | /*Widget transformation demo*/ 943 | #define LV_USE_DEMO_TRANSFORM 0 944 | 945 | /*Demonstrate scroll settings*/ 946 | #define LV_USE_DEMO_SCROLL 0 947 | 948 | /*Vector graphic demo*/ 949 | #define LV_USE_DEMO_VECTOR_GRAPHIC 0 950 | /*--END OF LV_CONF_H--*/ 951 | 952 | #endif /*LV_CONF_H*/ 953 | 954 | #endif /*End of "Content enable"*/ 955 | -------------------------------------------------------------------------------- /lib/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project specific (private) libraries. 3 | PlatformIO will compile them to static libraries and link into executable file. 4 | 5 | The source code of each library should be placed in a an own separate directory 6 | ("lib/your_library_name/[here are source files]"). 7 | 8 | For example, see a structure of the following two libraries `Foo` and `Bar`: 9 | 10 | |--lib 11 | | | 12 | | |--Bar 13 | | | |--docs 14 | | | |--examples 15 | | | |--src 16 | | | |- Bar.c 17 | | | |- Bar.h 18 | | | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html 19 | | | 20 | | |--Foo 21 | | | |- Foo.c 22 | | | |- Foo.h 23 | | | 24 | | |- README --> THIS FILE 25 | | 26 | |- platformio.ini 27 | |--src 28 | |- main.c 29 | 30 | and a contents of `src/main.c`: 31 | ``` 32 | #include 33 | #include 34 | 35 | int main (void) 36 | { 37 | ... 38 | } 39 | 40 | ``` 41 | 42 | PlatformIO Library Dependency Finder will find automatically dependent 43 | libraries scanning project source files. 44 | 45 | More information about PlatformIO Library Dependency Finder 46 | - https://docs.platformio.org/page/librarymanager/ldf.html 47 | -------------------------------------------------------------------------------- /platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | default_envs = emulator_Core 13 | 14 | [env] 15 | build_flags = 16 | -std=c++17 17 | -I include 18 | -I src/utility 19 | 20 | ; LVGL 21 | -D LV_CONF_INCLUDE_SIMPLE 22 | -D LV_LVGL_H_INCLUDE_SIMPLE 23 | -D LVGL_USE_V8=1 ; lvgl v8 24 | -D LVGL_USE_V9=0 ; lvgl v9 25 | 26 | ; SDL2 includes, uncomment the next two lines on MAC OS if you intalled sdl via homebrew 27 | ; !pkg-config --cflags SDL2 28 | ; !pkg-config --libs SDL2 29 | lib_deps = 30 | https://github.com/m5stack/M5GFX#develop 31 | lvgl=https://github.com/lvgl/lvgl/archive/refs/tags/v8.3.0.zip ; lvgl v8 32 | ; lvgl=https://github.com/lvgl/lvgl#master ; lvgl v9 33 | lib_archive = false 34 | 35 | 36 | [env:emulator_common] 37 | build_flags = 38 | ; uncomment the next line if running on MacOS Mx (arm64 architecture) 39 | ; -arch arm64 40 | -l SDL2 41 | ${env.build_flags} 42 | -D M5GFX_SHOW_FRAME 43 | -D M5GFX_BACK_COLOR=0xFFFFFFU ; background color 44 | -D M5GFX_SCALE=2 45 | -D M5GFX_ROTATION=0 46 | 47 | 48 | [env:emulator_Core] 49 | platform = native@^1.2.1 50 | extra_scripts = support/sdl2_build_extra.py 51 | build_type = debug 52 | build_flags = 53 | ${env:emulator_common.build_flags} 54 | -D M5GFX_BOARD=board_M5Stack 55 | build_src_filter = 56 | +<*> 57 | +<../.pio/libdeps/emulator_Core/lvgl/demos> 58 | 59 | 60 | [env:board_M5Core] 61 | platform = espressif32 62 | board = m5stack-fire 63 | framework = arduino 64 | build_flags = 65 | ${env.build_flags} 66 | -D M5GFX_BOARD=board_M5Stack 67 | -D BOARD_HAS_PSRAM 68 | build_src_filter = 69 | +<*> 70 | +<../.pio/libdeps/board_M5Core/lvgl/demos> 71 | 72 | 73 | [env:emulator_Core2] 74 | platform = native@^1.2.1 75 | extra_scripts = support/sdl2_build_extra.py 76 | build_type = debug 77 | build_flags = 78 | ${env:emulator_common.build_flags} 79 | -D M5GFX_BOARD=board_M5StackCore2 80 | build_src_filter = 81 | +<*> 82 | +<../.pio/libdeps/emulator_Core2/lvgl/demos> 83 | 84 | 85 | [env:board_M5Core2] 86 | platform = espressif32 87 | board = m5stack-core2 88 | framework = arduino 89 | build_flags = 90 | ${env.build_flags} 91 | -D M5GFX_BOARD=board_M5StackCore2 92 | -D BOARD_HAS_PSRAM 93 | build_src_filter = 94 | +<*> 95 | +<../.pio/libdeps/board_M5Core2/lvgl/demos> 96 | 97 | 98 | [env:emulator_CoreS3] 99 | platform = native@^1.2.1 100 | extra_scripts = support/sdl2_build_extra.py 101 | build_type = debug 102 | build_flags = 103 | ${env:emulator_common.build_flags} 104 | -D M5GFX_BOARD=board_M5StackCoreS3 105 | build_src_filter = 106 | +<*> 107 | +<../.pio/libdeps/emulator_CoreS3/lvgl/demos> 108 | 109 | 110 | [env:board_M5CoreS3] 111 | platform = espressif32 112 | board = esp32-s3-devkitc-1 113 | framework = arduino 114 | build_flags = 115 | ${env.build_flags} 116 | -D M5GFX_BOARD=board_M5StackCoreS3 117 | -D BOARD_HAS_PSRAM 118 | build_src_filter = 119 | +<*> 120 | +<../.pio/libdeps/board_M5CoreS3/lvgl/demos> 121 | 122 | 123 | [env:emulator_StickCPlus] 124 | platform = native@^1.2.1 125 | extra_scripts = support/sdl2_build_extra.py 126 | build_type = debug 127 | build_flags = 128 | ${env:emulator_common.build_flags} 129 | -D M5GFX_BOARD=board_M5StickCPlus 130 | build_src_filter = 131 | +<*> 132 | +<../.pio/libdeps/emulator_StickCPlus/lvgl/demos> 133 | 134 | 135 | [env:emulator_StickCPlus2] 136 | platform = native@^1.2.1 137 | extra_scripts = support/sdl2_build_extra.py 138 | build_type = debug 139 | build_flags = 140 | ${env:emulator_common.build_flags} 141 | -D M5GFX_BOARD=board_M5StickCPlus2 142 | build_src_filter = 143 | +<*> 144 | +<../.pio/libdeps/emulator_StickCPlus2/lvgl/demos> 145 | 146 | 147 | [env:emulator_Dial] 148 | platform = native@^1.2.1 149 | extra_scripts = support/sdl2_build_extra.py 150 | build_type = debug 151 | build_flags = 152 | ${env:emulator_common.build_flags} 153 | -D M5GFX_BOARD=board_M5Dial 154 | build_src_filter = 155 | +<*> 156 | +<../.pio/libdeps/emulator_Dial/lvgl/demos> 157 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "lvgl_port_m5stack.hpp" 5 | 6 | extern void user_app(void); 7 | 8 | M5GFX gfx; 9 | 10 | void setup(void) { 11 | gfx.init(); 12 | 13 | lvgl_port_init(gfx); 14 | 15 | user_app(); 16 | } 17 | 18 | void loop(void) { 19 | #if defined(ARDUINO) && defined(ESP_PLATFORM) 20 | delay(10); 21 | #elif !defined(ARDUINO) && (__has_include() || __has_include()) 22 | usleep(10 * 000); 23 | #endif 24 | } 25 | -------------------------------------------------------------------------------- /src/user_app.cpp: -------------------------------------------------------------------------------- 1 | #include "lvgl.h" 2 | #include "lvgl_port_m5stack.hpp" 3 | #include "demos/lv_demos.h" 4 | 5 | void user_app(void) { 6 | // You can test the lvgl default demo 7 | //* 8 | if (lvgl_port_lock()) { 9 | #if LVGL_USE_V8 == 1 10 | lv_demo_widgets(); 11 | #elif LVGL_USE_V9 == 1 12 | // lv_demo_widgets not work proerly with v9 for now :( 13 | #if defined(ARDUINO) && defined(ESP_PLATFORM) 14 | lv_demo_benchmark(); 15 | #else 16 | // lv_demo_stress not work properly with actual devices for now :( 17 | lv_demo_stress(); 18 | #endif 19 | #endif 20 | lvgl_port_unlock(); 21 | } 22 | //*/ 23 | 24 | // Or you can create your own lvgl app here 25 | /* 26 | if (lvgl_port_lock()) { 27 | static lv_obj_t* label; 28 | 29 | static lv_obj_t* btn1 = lv_btn_create(lv_scr_act()); 30 | lv_obj_align(btn1, LV_ALIGN_CENTER, 0, 0); 31 | 32 | label = lv_label_create(btn1); 33 | lv_label_set_text(label, "Button"); 34 | lv_obj_center(label); 35 | 36 | lvgl_port_unlock(); 37 | } 38 | //*/ 39 | } 40 | -------------------------------------------------------------------------------- /src/utility/lvgl_port_m5stack.cpp: -------------------------------------------------------------------------------- 1 | #include "lvgl_port_m5stack.hpp" 2 | 3 | #if defined(ARDUINO) && defined(ESP_PLATFORM) 4 | static SemaphoreHandle_t xGuiSemaphore; 5 | #elif !defined(ARDUINO) && (__has_include() || __has_include()) 6 | static SDL_mutex *xGuiMutex; 7 | #endif 8 | 9 | #ifndef LV_BUFFER_LINE 10 | #define LV_BUFFER_LINE 120 11 | #endif 12 | 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif 16 | 17 | #if defined(ARDUINO) && defined(ESP_PLATFORM) 18 | static void lvgl_tick_timer(void *arg) { 19 | (void)arg; 20 | lv_tick_inc(10); 21 | } 22 | static void lvgl_rtos_task(void *pvParameter) { 23 | (void)pvParameter; 24 | while (1) { 25 | if (pdTRUE == xSemaphoreTake(xGuiSemaphore, portMAX_DELAY)) { 26 | lv_timer_handler(); 27 | xSemaphoreGive(xGuiSemaphore); 28 | } 29 | vTaskDelay(pdMS_TO_TICKS(10)); 30 | } 31 | } 32 | #elif !defined(ARDUINO) && (__has_include() || __has_include()) 33 | static uint32_t lvgl_tick_timer(uint32_t interval, void *param) { 34 | (void)interval; 35 | (void)param; 36 | lv_tick_inc(10); 37 | return 10; 38 | } 39 | 40 | static int lvgl_sdl_thread(void *data) { 41 | (void)data; 42 | while (1) { 43 | if (SDL_LockMutex(xGuiMutex) == 0) { 44 | lv_timer_handler(); 45 | SDL_UnlockMutex(xGuiMutex); 46 | } 47 | SDL_Delay(10); 48 | } 49 | return 0; 50 | } 51 | #endif 52 | 53 | #if LVGL_USE_V8 == 1 54 | static lv_disp_draw_buf_t draw_buf; 55 | static void lvgl_flush_cb(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) { 56 | M5GFX &gfx = *(M5GFX *)disp->user_data; 57 | int w = (area->x2 - area->x1 + 1); 58 | int h = (area->y2 - area->y1 + 1); 59 | 60 | gfx.startWrite(); 61 | gfx.setAddrWindow(area->x1, area->y1, w, h); 62 | gfx.writePixels((lgfx::rgb565_t *)&color_p->full, w * h); 63 | // gfx.writePixels((lgfx::swap565_t *)&color_p->full, w * h); // swap red and blue 64 | gfx.endWrite(); 65 | 66 | lv_disp_flush_ready(disp); 67 | } 68 | 69 | static void lvgl_read_cb(lv_indev_drv_t *indev_driver, lv_indev_data_t *data) { 70 | M5GFX &gfx = *(M5GFX *)indev_driver->user_data; 71 | uint16_t touchX, touchY; 72 | 73 | bool touched = gfx.getTouch(&touchX, &touchY); 74 | if (!touched) { 75 | data->state = LV_INDEV_STATE_REL; 76 | } else { 77 | data->state = LV_INDEV_STATE_PR; 78 | data->point.x = touchX; 79 | data->point.y = touchY; 80 | } 81 | } 82 | 83 | void lvgl_port_init(M5GFX &gfx) { 84 | lv_init(); 85 | 86 | #if defined(ARDUINO) && defined(ESP_PLATFORM) 87 | #if defined(BOARD_HAS_PSRAM) 88 | static lv_color_t *buf1 = 89 | (lv_color_t *)heap_caps_malloc(gfx.width() * LV_BUFFER_LINE * sizeof(lv_color_t), MALLOC_CAP_SPIRAM); 90 | static lv_color_t *buf2 = 91 | (lv_color_t *)heap_caps_malloc(gfx.width() * LV_BUFFER_LINE * sizeof(lv_color_t), MALLOC_CAP_SPIRAM); 92 | lv_disp_draw_buf_init(&draw_buf, buf1, buf2, gfx.width() * LV_BUFFER_LINE); 93 | #else 94 | static lv_color_t *buf1 = (lv_color_t *)malloc(gfx.width() * LV_BUFFER_LINE * sizeof(lv_color_t)); 95 | lv_disp_draw_buf_init(&draw_buf, buf1, NULL, gfx.width() * LV_BUFFER_LINE); 96 | #endif 97 | #elif !defined(ARDUINO) && (__has_include() || __has_include()) 98 | static lv_color_t *buf1 = (lv_color_t *)malloc(gfx.width() * LV_BUFFER_LINE * sizeof(lv_color_t)); 99 | static lv_color_t *buf2 = (lv_color_t *)malloc(gfx.width() * LV_BUFFER_LINE * sizeof(lv_color_t)); 100 | lv_disp_draw_buf_init(&draw_buf, buf1, buf2, gfx.width() * LV_BUFFER_LINE); 101 | #endif 102 | 103 | static lv_disp_drv_t disp_drv; 104 | lv_disp_drv_init(&disp_drv); 105 | disp_drv.hor_res = gfx.width(); 106 | disp_drv.ver_res = gfx.height(); 107 | disp_drv.flush_cb = lvgl_flush_cb; 108 | disp_drv.draw_buf = &draw_buf; 109 | disp_drv.user_data = &gfx; 110 | lv_disp_drv_register(&disp_drv); 111 | 112 | static lv_indev_drv_t indev_drv; 113 | lv_indev_drv_init(&indev_drv); 114 | indev_drv.type = LV_INDEV_TYPE_POINTER; 115 | indev_drv.read_cb = lvgl_read_cb; 116 | indev_drv.user_data = &gfx; 117 | lv_indev_t *indev = lv_indev_drv_register(&indev_drv); 118 | 119 | #if defined(ARDUINO) && defined(ESP_PLATFORM) 120 | xGuiSemaphore = xSemaphoreCreateMutex(); 121 | const esp_timer_create_args_t periodic_timer_args = {.callback = &lvgl_tick_timer, .name = "lvgl_tick_timer"}; 122 | esp_timer_handle_t periodic_timer; 123 | ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer)); 124 | ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, 10 * 1000)); 125 | xTaskCreate(lvgl_rtos_task, "lvgl_rtos_task", 4096, NULL, 1, NULL); 126 | #elif !defined(ARDUINO) && (__has_include() || __has_include()) 127 | xGuiMutex = SDL_CreateMutex(); 128 | SDL_AddTimer(10, lvgl_tick_timer, NULL); 129 | SDL_CreateThread(lvgl_sdl_thread, "lvgl_sdl_thread", NULL); 130 | #endif 131 | } 132 | #elif LVGL_USE_V9 == 1 133 | static void lvgl_flush_cb(lv_display_t *disp, const lv_area_t *area, uint8_t *px_map) { 134 | M5GFX &gfx = *(M5GFX *)lv_display_get_driver_data(disp); 135 | 136 | uint32_t w = (area->x2 - area->x1 + 1); 137 | uint32_t h = (area->y2 - area->y1 + 1); 138 | 139 | gfx.startWrite(); 140 | gfx.setAddrWindow(area->x1, area->y1, w, h); 141 | gfx.writePixels((lgfx::rgb565_t *)px_map, w * h); 142 | gfx.endWrite(); 143 | 144 | lv_display_flush_ready(disp); 145 | } 146 | 147 | static void lvgl_read_cb(lv_indev_t *indev, lv_indev_data_t *data) { 148 | M5GFX &gfx = *(M5GFX *)lv_indev_get_driver_data(indev); 149 | uint16_t touchX, touchY; 150 | 151 | bool touched = gfx.getTouch(&touchX, &touchY); 152 | if (!touched) { 153 | data->state = LV_INDEV_STATE_REL; 154 | } else { 155 | data->state = LV_INDEV_STATE_PR; 156 | data->point.x = touchX; 157 | data->point.y = touchY; 158 | } 159 | } 160 | 161 | void lvgl_port_init(M5GFX &gfx) { 162 | lv_init(); 163 | 164 | static lv_display_t *disp = lv_display_create(gfx.width(), gfx.height()); 165 | if (disp == NULL) { 166 | LV_LOG_ERROR("lv_display_create failed"); 167 | return; 168 | } 169 | 170 | lv_display_set_driver_data(disp, &gfx); 171 | lv_display_set_flush_cb(disp, lvgl_flush_cb); 172 | #if defined(ARDUINO) && defined(ESP_PLATFORM) 173 | #if defined(BOARD_HAS_PSRAM) 174 | static uint8_t *buf1 = (uint8_t *)heap_caps_malloc(gfx.width() * LV_BUFFER_LINE, MALLOC_CAP_SPIRAM); 175 | static uint8_t *buf2 = (uint8_t *)heap_caps_malloc(gfx.width() * LV_BUFFER_LINE, MALLOC_CAP_SPIRAM); 176 | lv_display_set_buffers(disp, (void *)buf1, (void *)buf2, gfx.width() * LV_BUFFER_LINE, 177 | LV_DISPLAY_RENDER_MODE_PARTIAL); 178 | #else 179 | static uint8_t *buf1 = (uint8_t *)malloc(gfx.width() * LV_BUFFER_LINE); 180 | lv_display_set_buffers(disp, (void *)buf1, NULL, gfx.width() * LV_BUFFER_LINE, LV_DISPLAY_RENDER_MODE_PARTIAL); 181 | #endif 182 | #elif !defined(ARDUINO) && (__has_include() || __has_include()) 183 | static uint8_t *buf1 = (uint8_t *)malloc(gfx.width() * LV_BUFFER_LINE * 2); 184 | static uint8_t *buf2 = (uint8_t *)malloc(gfx.width() * LV_BUFFER_LINE * 2); 185 | lv_display_set_buffers(disp, (void *)buf1, (void *)buf2, gfx.width() * LV_BUFFER_LINE * 2, 186 | LV_DISPLAY_RENDER_MODE_PARTIAL); 187 | #endif 188 | 189 | static lv_indev_t *indev = lv_indev_create(); 190 | LV_ASSERT_MALLOC(indev); 191 | if (indev == NULL) { 192 | LV_LOG_ERROR("lv_indev_create failed"); 193 | return; 194 | } 195 | lv_indev_set_driver_data(indev, &gfx); 196 | lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); 197 | lv_indev_set_read_cb(indev, lvgl_read_cb); 198 | lv_indev_set_display(indev, disp); 199 | 200 | #if defined(ARDUINO) && defined(ESP_PLATFORM) 201 | xGuiSemaphore = xSemaphoreCreateMutex(); 202 | const esp_timer_create_args_t periodic_timer_args = {.callback = &lvgl_tick_timer, .name = "lvgl_tick_timer"}; 203 | esp_timer_handle_t periodic_timer; 204 | ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer)); 205 | ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, 10 * 1000)); 206 | xTaskCreate(lvgl_rtos_task, "lvgl_rtos_task", 4096, NULL, 1, NULL); 207 | #elif !defined(ARDUINO) && (__has_include() || __has_include()) 208 | xGuiMutex = SDL_CreateMutex(); 209 | SDL_AddTimer(10, lvgl_tick_timer, NULL); 210 | SDL_CreateThread(lvgl_sdl_thread, "lvgl_sdl_thread", NULL); 211 | #endif 212 | } 213 | #endif 214 | 215 | bool lvgl_port_lock(void) { 216 | #if defined(ARDUINO) && defined(ESP_PLATFORM) 217 | return xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE ? true : false; 218 | #elif !defined(ARDUINO) && (__has_include() || __has_include()) 219 | return SDL_LockMutex(xGuiMutex) == 0 ? true : false; 220 | #endif 221 | } 222 | 223 | void lvgl_port_unlock(void) { 224 | #if defined(ARDUINO) && defined(ESP_PLATFORM) 225 | xSemaphoreGive(xGuiSemaphore); 226 | #elif !defined(ARDUINO) && (__has_include() || __has_include()) 227 | SDL_UnlockMutex(xGuiMutex); 228 | #endif 229 | } 230 | 231 | #ifdef __cplusplus 232 | } 233 | #endif 234 | -------------------------------------------------------------------------------- /src/utility/lvgl_port_m5stack.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __LVGL_PORT_M5STACK_HPP__ 2 | #define __LVGL_PORT_M5STACK_HPP__ 3 | 4 | #if defined(ARDUINO) 5 | #include 6 | #endif 7 | #include 8 | #include "lvgl.h" 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | void lvgl_port_init(M5GFX &gfx); 15 | bool lvgl_port_lock(void); 16 | void lvgl_port_unlock(void); 17 | 18 | #ifdef __cplusplus 19 | } 20 | #endif 21 | 22 | #endif // __LVGL_PORT_M5STACK_HPP__ -------------------------------------------------------------------------------- /src/utility/sdl_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #if defined(SDL_h_) 3 | 4 | void setup(void); 5 | void loop(void); 6 | 7 | __attribute__((weak)) int user_func(bool *running) { 8 | setup(); 9 | do { 10 | loop(); 11 | } while (*running); 12 | return 0; 13 | } 14 | 15 | int main(int, char **) { 16 | // The second argument is effective for step execution with breakpoints. 17 | // You can specify the time in milliseconds to perform slow execution that ensures screen updates. 18 | return lgfx::Panel_sdl::main(user_func, 128); 19 | } 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /support/pio_explorer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m5stack/lv_m5_emulator/f7cc52e18c275c14773fc902c452187f6841f7b5/support/pio_explorer.png -------------------------------------------------------------------------------- /support/sdl2_build_extra.py: -------------------------------------------------------------------------------- 1 | Import("env", "projenv") 2 | 3 | for e in [ env, projenv ]: 4 | # If compiler uses `-m32`, propagate it to linker. 5 | # Add via script, because `-Wl,-m32` does not work. 6 | if "-m32" in e['CCFLAGS']: 7 | e.Append(LINKFLAGS = ["-m32"]) 8 | 9 | exec_name = "${BUILD_DIR}/${PROGNAME}${PROGSUFFIX}" 10 | 11 | # Override unused "upload" to execute compiled binary 12 | from SCons.Script import AlwaysBuild 13 | AlwaysBuild(env.Alias("upload", exec_name, exec_name)) 14 | 15 | # Add custom target to explorer 16 | env.AddTarget( 17 | name = "execute", 18 | dependencies = exec_name, 19 | actions = exec_name, 20 | title = "Execute", 21 | description = "Build and execute", 22 | group="General" 23 | ) 24 | 25 | #print('=====================================') 26 | #print(env.Dump()) 27 | -------------------------------------------------------------------------------- /test/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for PlatformIO Test Runner and project tests. 3 | 4 | Unit Testing is a software testing method by which individual units of 5 | source code, sets of one or more MCU program modules together with associated 6 | control data, usage procedures, and operating procedures, are tested to 7 | determine whether they are fit for use. Unit testing finds problems early 8 | in the development cycle. 9 | 10 | More information about PlatformIO Unit Testing: 11 | - https://docs.platformio.org/en/latest/advanced/unit-testing/index.html 12 | --------------------------------------------------------------------------------