From e4582561937fc7a0608921aa0bf6ecdddad271a1 Mon Sep 17 00:00:00 2001 From: GW_MC <72297530+GWMCwing@users.noreply.github.com> Date: Sat, 17 Jan 2026 20:09:33 +0800 Subject: [PATCH] Add main application logic and touch handling functionality - Implemented main application entry point in main.cpp, initializing queues and event groups. - Created TouchHandler and EInkTouchHandler classes for handling touch events. - Added a minimal event loop for touch processing in touch.cpp. - Introduced unit tests for the hello world application in pytest_hello_world.py. - Added configuration files for CI and Wokwi support. - Created empty header files for network and UI modules. --- .clang-tidy | 1 + .clangd | 2 + .devcontainer/Dockerfile | 13 + .devcontainer/devcontainer.json | 30 + .gitignore | 84 ++ CMakeLists.txt | 9 + dependencies.lock | 58 ++ diagram.json | 29 + main/CMakeLists.txt | 5 + main/Kconfig.projbuild | 9 + main/common/constants.h | 14 + main/common/queue_defs.h | 30 + main/display/display.cpp | 62 ++ main/display/display.h | 42 + main/idf_component.yml | 19 + main/info/info.cpp | 30 + main/info/info.h | 10 + main/io/io.h | 0 main/lv_conf.h | 1513 +++++++++++++++++++++++++++++++ main/main.cpp | 175 ++++ main/network/network.h | 0 main/touch/touch.cpp | 53 ++ main/touch/touch.h | 32 + main/ui/ui.h | 0 pytest_hello_world.py | 55 ++ sdkconfig.ci | 0 wokwi.toml | 4 + 27 files changed, 2279 insertions(+) create mode 100644 .clang-tidy create mode 100644 .clangd create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/devcontainer.json create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 dependencies.lock create mode 100644 diagram.json create mode 100644 main/CMakeLists.txt create mode 100644 main/Kconfig.projbuild create mode 100644 main/common/constants.h create mode 100644 main/common/queue_defs.h create mode 100644 main/display/display.cpp create mode 100644 main/display/display.h create mode 100644 main/idf_component.yml create mode 100644 main/info/info.cpp create mode 100644 main/info/info.h create mode 100644 main/io/io.h create mode 100644 main/lv_conf.h create mode 100644 main/main.cpp create mode 100644 main/network/network.h create mode 100644 main/touch/touch.cpp create mode 100644 main/touch/touch.h create mode 100644 main/ui/ui.h create mode 100644 pytest_hello_world.py create mode 100644 sdkconfig.ci create mode 100644 wokwi.toml diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..907ab0c --- /dev/null +++ b/.clang-tidy @@ -0,0 +1 @@ +Checks: '-clang-diagnostic-builtin-macro-redefined' diff --git a/.clangd b/.clangd new file mode 100644 index 0000000..437f255 --- /dev/null +++ b/.clangd @@ -0,0 +1,2 @@ +CompileFlags: + Remove: [-f*, -m*] diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..dafb8ad --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,13 @@ +ARG DOCKER_TAG=latest +FROM espressif/idf:${DOCKER_TAG} + +ENV LC_ALL=C.UTF-8 +ENV LANG=C.UTF-8 + +RUN apt-get update -y && apt-get install udev -y + +RUN echo "source /opt/esp/idf/export.sh > /dev/null 2>&1" >> ~/.bashrc + +ENTRYPOINT [ "/opt/esp/entrypoint.sh" ] + +CMD ["/bin/bash", "-c"] \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..478f2d2 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,30 @@ +{ + "name": "ESP-IDF QEMU", + "build": { + "dockerfile": "Dockerfile" + }, + "customizations": { + "vscode": { + "settings": { + "terminal.integrated.defaultProfile.linux": "bash", + "idf.espIdfPath": "/opt/esp/idf", + "idf.toolsPath": "/opt/esp", + "idf.gitPath": "/usr/bin/git" + }, + "extensions": [ + "espressif.esp-idf-extension", + "espressif.esp-idf-web", + "ms-vscode.cpptools", + "streetsidesoftware.code-spell-checker", + "mhutchie.git-graph", + "oderwat.indent-rainbow", + "SirTori.indenticator", + "christian-kohler.path-intellisense", + "esbenp.prettier-vscode", + "redhat.vscode-yaml" + + ] + } + }, + "runArgs": ["--privileged"] +} \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a93d5f0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,84 @@ +# macOS +.DS_Store +.AppleDouble +.LSOverride + +# Directory metadata +.directory + +# Temporary files +*~ +*.swp +*.swo +*.bak +*.tmp + +# Log files +*.log + +# Build artifacts and directories +**/build/ +build/ +*.o +*.a +*.out +*.exe # For any host-side utilities compiled on Windows + +# ESP-IDF specific build outputs +*.bin +*.elf +*.map +flasher_args.json # Generated in build directory +sdkconfig.old +sdkconfig + +# ESP-IDF dependencies +# For older versions or manual component management +/components/.idf/ +**/components/.idf/ +# For modern ESP-IDF component manager +managed_components/ +# If ESP-IDF tools are installed/referenced locally to the project +.espressif/ + +# CMake generated files +CMakeCache.txt +CMakeFiles/ +cmake_install.cmake +install_manifest.txt +CTestTestfile.cmake + +# Python environment files +*.pyc +*.pyo +*.pyd +__pycache__/ +*.egg-info/ +dist/ + +# Virtual environment folders +venv/ +.venv/ +env/ + +# Language Servers +.clangd/ +.ccls-cache/ +compile_commands.json + +# Windows specific +Thumbs.db +ehthumbs.db +Desktop.ini + +# User-specific configuration files +*.user +*.workspace # General workspace files, can be from various tools +*.suo # Visual Studio Solution User Options +*.sln.docstates # Visual Studio + +# cache files +.cache/ + +# vscode settings +.vscode/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..26eef5b --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,9 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) +# target_compile_options(${COMPONENT_LIB} PRIVATE -std=c++23) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +# "Trim" the build. Include the minimal set of components, main, and anything it depends on. +idf_build_set_property(MINIMAL_BUILD ON) +project(ink-board) diff --git a/dependencies.lock b/dependencies.lock new file mode 100644 index 0000000..7077b96 --- /dev/null +++ b/dependencies.lock @@ -0,0 +1,58 @@ +dependencies: + espressif/esp_lcd_touch: + component_hash: 3f85a7d95af876f1a6ecca8eb90a81614890d0f03a038390804e5a77e2caf862 + dependencies: + - name: idf + require: private + version: '>=4.4.2' + source: + registry_url: https://components.espressif.com + type: service + version: 1.2.1 + espressif/esp_lcd_touch_gt911: + component_hash: be02e243d18b9a661bc13b0d22c0a5cfa3f708cf04d6eb059772276c8c8a4d76 + dependencies: + - name: espressif/esp_lcd_touch + registry_url: https://components.espressif.com + require: public + version: ^1.2.0 + - name: idf + require: private + version: '>=4.4.2' + source: + registry_url: https://components.espressif.com/ + type: service + version: 1.2.0~1 + espressif/esp_lvgl_port: + component_hash: f872401524cb645ee6ff1c9242d44fb4ddcfd4d37d7be8b9ed3f4e85a404efcd + dependencies: + - name: idf + require: private + version: '>=5.1' + - name: lvgl/lvgl + registry_url: https://components.espressif.com + require: public + version: '>=8,<10' + source: + registry_url: https://components.espressif.com/ + type: service + version: 2.7.0 + idf: + source: + type: idf + version: 5.5.2 + lvgl/lvgl: + component_hash: 17e68bfd21f0edf4c3ee838e2273da840bf3930e5dbc3bfa6c1190c3aed41f9f + dependencies: [] + source: + registry_url: https://components.espressif.com/ + type: service + version: 9.4.0 +direct_dependencies: +- espressif/esp_lcd_touch_gt911 +- espressif/esp_lvgl_port +- idf +- lvgl/lvgl +manifest_hash: fef450d0c399587685f90aba8ae661965ef507d04a5fcf17633db86d5d0fbcff +target: esp32 +version: 2.0.0 diff --git a/diagram.json b/diagram.json new file mode 100644 index 0000000..30b0c62 --- /dev/null +++ b/diagram.json @@ -0,0 +1,29 @@ +{ + "version": 1, + "author": "GW_ MC", + "editor": "wokwi", + "parts": [ + { + "type": "board-esp32-devkit-c-v4", + "id": "esp", + "top": 0, + "left": 0, + "attrs": {} + } + ], + "connections": [ + [ + "esp:TX", + "$serialMonitor:RX", + "", + [] + ], + [ + "esp:RX", + "$serialMonitor:TX", + "", + [] + ] + ], + "dependencies": {} +} \ No newline at end of file diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt new file mode 100644 index 0000000..3b65896 --- /dev/null +++ b/main/CMakeLists.txt @@ -0,0 +1,5 @@ +file(GLOB SRCS "main.cpp" "*.cpp" "*.c" "**/*.cpp" "**/*.c") +idf_component_register(SRCS ${SRCS} + PRIV_REQUIRES + spi_flash + INCLUDE_DIRS "." "display" "touch" "network" "ui" "io" "common") diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild new file mode 100644 index 0000000..8d0286e --- /dev/null +++ b/main/Kconfig.projbuild @@ -0,0 +1,9 @@ +menu "ink-board Configuration" + + config PARTIAL_REFRESH_LIMIT + int "Partial Refresh Limit" + default 20 + range 5 100 + help "Number of partial updates before full refresh" + +endmenu \ No newline at end of file diff --git a/main/common/constants.h b/main/common/constants.h new file mode 100644 index 0000000..c6db730 --- /dev/null +++ b/main/common/constants.h @@ -0,0 +1,14 @@ +// 800x480 = 384,000 pixels + +#define EINK_WIDTH 800 +#define EINK_HEIGHT 480 + +#define CORE_0 0 +#define CORE_1 1 + +#define SYSTEM_SHUTDOWN_BIT (1 << 0) +#define SYSTEM_RESTART_BIT (1 << 1) +#define SYSTEM_START_BIT (1 << 2) +// +#define DISPLAY_READY_BIT (1 << 1) +#define TOUCH_CALIBRATED_BIT (1 << 2) \ No newline at end of file diff --git a/main/common/queue_defs.h b/main/common/queue_defs.h new file mode 100644 index 0000000..64faede --- /dev/null +++ b/main/common/queue_defs.h @@ -0,0 +1,30 @@ +#include + +typedef enum { + CMD_DISPLAY_UPDATE, + CMD_SAVE_DATA, + CMD_LOAD_DATA, + CMD_REFRESH_DISPLAY, + CMD_SYSTEM_STATUS, +} cmd_type_t; + +typedef struct { + cmd_type_t type; + uint32_t id; + void* data; + size_t len; + QueueHandle_t reply_to; // NULL if one-way +} async_cmd_t; + +extern QueueHandle_t command_queue; + +typedef struct { + uint16_t x, y; + lv_indev_state_t state; // LV_INDEV_STATE_PR/REL + uint32_t timestamp; + uint8_t gesture; // TAP, SWIPE, LONG_PRESS +} touch_event_t; + +extern QueueHandle_t touch_queue; + +extern EventGroupHandle_t system_event_group; \ No newline at end of file diff --git a/main/display/display.cpp b/main/display/display.cpp new file mode 100644 index 0000000..738eefe --- /dev/null +++ b/main/display/display.cpp @@ -0,0 +1,62 @@ +#include "display.h" +#include "common/constants.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/event_groups.h" +// TODO: implement actual display functionality + +DisplayHandler::DisplayHandler(QueueHandle_t touch_queue, SemaphoreHandle_t lvgl_mutex) { + (void)touch_queue; + (void)lvgl_mutex; +} + +DisplayHandler::~DisplayHandler() { } + +EInkDisplayHandler::EInkDisplayHandler(QueueHandle_t touch_queue, SemaphoreHandle_t lvgl_mutex) + : DisplayHandler(touch_queue, lvgl_mutex) { } + +EInkDisplayHandler::~EInkDisplayHandler() { } + +void EInkDisplayHandler::init(EventGroupHandle_t system_event_group) { + if (system_event_group != NULL) { + xEventGroupSetBits(system_event_group, DISPLAY_READY_BIT); + } +} +void EInkDisplayHandler::start_event_loop() { + // Minimal background task to represent display processing + xTaskCreate( + // use the static adapter and pass `this` as the task parameter + EInkDisplayHandler::task_adapter, + "display_task", + 2048, + this, + tskIDLE_PRIORITY + 1, + nullptr + ); +} + +// static +void EInkDisplayHandler::task_adapter(void* arg) { + EInkDisplayHandler* self = static_cast(arg); + if (self) { + self->run_event_loop(); + } else { + printf("EInkDisplayHandler::task_adapter received null pointer\n"); + } + // If run_event_loop ever returns, delete the task. + vTaskDelete(NULL); +} + +void EInkDisplayHandler::run_event_loop() { + for (;;) { + vTaskDelay(pdMS_TO_TICKS(1000)); + } +} + +shutdown_display_handlerFunc EInkDisplayHandler::get_shutdown_display_handler() { + return nullptr; +} + +restart_display_handlerFunc EInkDisplayHandler::get_restart_display_handler() { + return nullptr; +} diff --git a/main/display/display.h b/main/display/display.h new file mode 100644 index 0000000..7f3921f --- /dev/null +++ b/main/display/display.h @@ -0,0 +1,42 @@ +#include "info/info.h" + +typedef void (*shutdown_display_handlerFunc)(void); +typedef void (*restart_display_handlerFunc)(void); + +class DisplayHandler { +public: + DisplayHandler(QueueHandle_t touch_queue, SemaphoreHandle_t lvgl_mutex); + // the system_event_group is used to set display-ready bit + virtual void init(EventGroupHandle_t system_event_group) = 0; + virtual void start_event_loop() = 0; + // get a handler to perform display shutdown cleanup, this is called after event loop ends and DisplayHandler is deleted + virtual shutdown_display_handlerFunc get_shutdown_display_handler() = 0; + virtual restart_display_handlerFunc get_restart_display_handler() = 0; + virtual ~DisplayHandler() = 0; + +private: + DisplayHandler(const DisplayHandler&) = delete; + DisplayHandler& operator=(const DisplayHandler&) = delete; +}; + +class EInkDisplayHandler : public DisplayHandler { +public: + EInkDisplayHandler(QueueHandle_t touch_queue, SemaphoreHandle_t lvgl_mutex); + void init(EventGroupHandle_t system_event_group) override; + void start_event_loop() override; + shutdown_display_handlerFunc get_shutdown_display_handler() override; + restart_display_handlerFunc get_restart_display_handler() override; + ~EInkDisplayHandler() override; + +private: + // Task adapter used for FreeRTOS task creation. It forwards to the + // instance `run_event_loop()` method using the `this` pointer passed + // as the task parameter. + static void task_adapter(void* arg); + + // Instance method that implements the display task loop. + void run_event_loop(); + // prevent copying + EInkDisplayHandler(const EInkDisplayHandler&) = delete; + EInkDisplayHandler& operator=(const EInkDisplayHandler&) = delete; +}; diff --git a/main/idf_component.yml b/main/idf_component.yml new file mode 100644 index 0000000..a967005 --- /dev/null +++ b/main/idf_component.yml @@ -0,0 +1,19 @@ +## IDF Component Manager Manifest File +dependencies: + ## Required IDF version + idf: + version: '>=4.1.0' + # # Put list of dependencies here + # # For components maintained by Espressif: + # component: "~1.0.0" + # # For 3rd party components: + # username/component: ">=1.0.0,<2.0.0" + # username2/component2: + # version: "~1.0.0" + # # For transient dependencies `public` flag can be set. + # # `public` flag doesn't have an effect dependencies of the `main` component. + # # All dependencies of `main` are public by default. + # public: true + lvgl/lvgl: ^9.4.0 + espressif/esp_lcd_touch_gt911: ^1.2.0~1 + espressif/esp_lvgl_port: ^2.7.0 diff --git a/main/info/info.cpp b/main/info/info.cpp new file mode 100644 index 0000000..9e52d13 --- /dev/null +++ b/main/info/info.cpp @@ -0,0 +1,30 @@ +#include "info.h" + +void display_chip_info() { + + /* Print chip information */ + esp_chip_info_t chip_info; + uint32_t flash_size; + esp_chip_info(&chip_info); + printf("This is %s chip with %d CPU core(s), %s%s%s%s, ", + CONFIG_IDF_TARGET, + chip_info.cores, + (chip_info.features & CHIP_FEATURE_WIFI_BGN) ? "WiFi/" : "", + (chip_info.features & CHIP_FEATURE_BT) ? "BT" : "", + (chip_info.features & CHIP_FEATURE_BLE) ? "BLE" : "", + (chip_info.features & CHIP_FEATURE_IEEE802154) ? ", 802.15.4 (Zigbee/Thread)" : ""); + + unsigned major_rev = chip_info.revision / 100; + unsigned minor_rev = chip_info.revision % 100; + printf("silicon revision v%d.%d, ", major_rev, minor_rev); + if (esp_flash_get_size(NULL, &flash_size) != ESP_OK) { + printf("Get flash size failed"); + return; + } + + printf("%" PRIu32 "MB %s flash\n", flash_size / (uint32_t)(1024 * 1024), + (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external"); + + printf("Minimum free heap size: %" PRIu32 " bytes\n", esp_get_minimum_free_heap_size()); + +} \ No newline at end of file diff --git a/main/info/info.h b/main/info/info.h new file mode 100644 index 0000000..286bd9d --- /dev/null +++ b/main/info/info.h @@ -0,0 +1,10 @@ +#include +#include +#include "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_chip_info.h" +#include "esp_flash.h" +#include "esp_system.h" + +void display_chip_info(); diff --git a/main/io/io.h b/main/io/io.h new file mode 100644 index 0000000..e69de29 diff --git a/main/lv_conf.h b/main/lv_conf.h new file mode 100644 index 0000000..c500dd0 --- /dev/null +++ b/main/lv_conf.h @@ -0,0 +1,1513 @@ +/** + * @file lv_conf.h + * Configuration file for v9.5.0-dev + */ + + /* + * Copy this file as `lv_conf.h` + * 1. simply next to `lvgl` folder + * 2. or to any other place and + * - define `LV_CONF_INCLUDE_SIMPLE`; + * - add the path as an include path. + */ + + /* clang-format off */ +#if 1 /* Set this to "1" to enable content */ + +#ifndef LV_CONF_H +#define LV_CONF_H + +/* If you need to include anything here, do it inside the `__ASSEMBLY__` guard */ +#if 0 && defined(__ASSEMBLY__) +#include "my_include.h" +#endif + +/*==================== + COLOR SETTINGS + *====================*/ + + /** Color depth: 1 (I1), 8 (L8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888) */ +#define LV_COLOR_DEPTH 1 + +/*========================= + STDLIB WRAPPER SETTINGS + *=========================*/ + + /** Possible values + * - LV_STDLIB_BUILTIN: LVGL's built in implementation + * - LV_STDLIB_CLIB: Standard C functions, like malloc, strlen, etc + * - LV_STDLIB_MICROPYTHON: MicroPython implementation + * - LV_STDLIB_RTTHREAD: RT-Thread implementation + * - LV_STDLIB_CUSTOM: Implement the functions externally + */ +#define LV_USE_STDLIB_MALLOC LV_STDLIB_BUILTIN + + /** Possible values + * - LV_STDLIB_BUILTIN: LVGL's built in implementation + * - LV_STDLIB_CLIB: Standard C functions, like malloc, strlen, etc + * - LV_STDLIB_MICROPYTHON: MicroPython implementation + * - LV_STDLIB_RTTHREAD: RT-Thread implementation + * - LV_STDLIB_CUSTOM: Implement the functions externally + */ +#define LV_USE_STDLIB_STRING LV_STDLIB_BUILTIN + + /** Possible values + * - LV_STDLIB_BUILTIN: LVGL's built in implementation + * - LV_STDLIB_CLIB: Standard C functions, like malloc, strlen, etc + * - LV_STDLIB_MICROPYTHON: MicroPython implementation + * - LV_STDLIB_RTTHREAD: RT-Thread implementation + * - LV_STDLIB_CUSTOM: Implement the functions externally + */ +#define LV_USE_STDLIB_SPRINTF LV_STDLIB_BUILTIN + +#define LV_STDINT_INCLUDE +#define LV_STDDEF_INCLUDE +#define LV_STDBOOL_INCLUDE +#define LV_INTTYPES_INCLUDE +#define LV_LIMITS_INCLUDE +#define LV_STDARG_INCLUDE + +#if LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN + /** Size of memory available for `lv_malloc()` in bytes (>= 2kB) */ +#define LV_MEM_SIZE (64 * 1024U) /**< [bytes] */ + +/** Size of the memory expand for `lv_malloc()` in bytes */ +#define LV_MEM_POOL_EXPAND_SIZE 0 + +/** Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too. */ +#define LV_MEM_ADR 0 /**< 0: unused*/ +/* Instead of an address give a memory allocator that will be called to get a memory pool for LVGL. E.g. my_malloc */ +#if LV_MEM_ADR == 0 +#undef LV_MEM_POOL_INCLUDE +#undef LV_MEM_POOL_ALLOC +#endif +#endif /*LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN*/ + +/*==================== + HAL SETTINGS + *====================*/ + + /** Default display refresh, input device read and animation step period. */ +#define LV_DEF_REFR_PERIOD 33 /**< [ms] */ + +/** Default Dots Per Inch. Used to initialize default sizes such as widgets sized, style paddings. + * (Not so important, you can adjust it to modify default sizes and spaces.) */ + // #define LV_DPI_DEF 130 /**< [px/inch] */ +#define LV_DPI_DEF 124 /**< [px/inch] */ + + + /*================= + * OPERATING SYSTEM + *=================*/ + /** Select operating system to use. Possible options: + * - LV_OS_NONE + * - LV_OS_PTHREAD + * - LV_OS_FREERTOS + * - LV_OS_CMSIS_RTOS2 + * - LV_OS_RTTHREAD + * - LV_OS_WINDOWS + * - LV_OS_MQX + * - LV_OS_SDL2 + * - LV_OS_CUSTOM */ +#define LV_USE_OS LV_OS_NONE + +#if LV_USE_OS == LV_OS_CUSTOM +#define LV_OS_CUSTOM_INCLUDE +#endif +#if LV_USE_OS == LV_OS_FREERTOS + /* + * Unblocking an RTOS task with a direct notification is 45% faster and uses less RAM + * than unblocking a task using an intermediary object such as a binary semaphore. + * RTOS task notifications can only be used when there is only one task that can be the recipient of the event. + */ +#define LV_USE_FREERTOS_TASK_NOTIFY 1 +#endif + + /*======================== + * RENDERING CONFIGURATION + *========================*/ + + /** Align stride of all layers and images to this bytes */ +#define LV_DRAW_BUF_STRIDE_ALIGN 1 + +/** Align start address of draw_buf addresses to this bytes*/ +#define LV_DRAW_BUF_ALIGN 4 + +/** Using matrix for transformations. + * Requirements: + * - `LV_USE_MATRIX = 1`. + * - Rendering engine needs to support 3x3 matrix transformations. */ +#define LV_DRAW_TRANSFORM_USE_MATRIX 0 + + /* If a widget has `style_opa < 255` (not `bg_opa`, `text_opa` etc) or not NORMAL blend mode + * it is buffered into a "simple" layer before rendering. The widget can be buffered in smaller chunks. + * "Transformed layers" (if `transform_angle/zoom` are set) use larger buffers + * and can't be drawn in chunks. */ + + /** The target buffer size for simple layer chunks. */ +#define LV_DRAW_LAYER_SIMPLE_BUF_SIZE (24 * 1024) /**< [bytes]*/ + +/* Limit the max allocated memory for simple and transformed layers. + * It should be at least `LV_DRAW_LAYER_SIMPLE_BUF_SIZE` sized but if transformed layers are also used + * it should be enough to store the largest widget too (width x height x 4 area). + * Set it to 0 to have no limit. */ +#define LV_DRAW_LAYER_MAX_MEMORY 0 /**< No limit by default [bytes]*/ + + /** Stack size of drawing thread. + * NOTE: If FreeType or ThorVG is enabled, it is recommended to set it to 32KB or more. + */ +#define LV_DRAW_THREAD_STACK_SIZE (8 * 1024) /**< [bytes]*/ + + /** Thread priority of the drawing task. + * Higher values mean higher priority. + * Can use values from lv_thread_prio_t enum in lv_os.h: LV_THREAD_PRIO_LOWEST, + * LV_THREAD_PRIO_LOW, LV_THREAD_PRIO_MID, LV_THREAD_PRIO_HIGH, LV_THREAD_PRIO_HIGHEST + * Make sure the priority value aligns with the OS-specific priority levels. + * On systems with limited priority levels (e.g., FreeRTOS), a higher value can improve + * rendering performance but might cause other tasks to starve. */ +#define LV_DRAW_THREAD_PRIO LV_THREAD_PRIO_HIGH + +#define LV_USE_DRAW_SW 1 +#if LV_USE_DRAW_SW == 1 + /* + * Selectively disable color format support in order to reduce code size. + * NOTE: some features use certain color formats internally, e.g. + * - gradients use RGB888 + * - bitmaps with transparency may use ARGB8888 + */ +#define LV_DRAW_SW_SUPPORT_RGB565 1 +#define LV_DRAW_SW_SUPPORT_RGB565_SWAPPED 1 +#define LV_DRAW_SW_SUPPORT_RGB565A8 1 +#define LV_DRAW_SW_SUPPORT_RGB888 1 +#define LV_DRAW_SW_SUPPORT_XRGB8888 1 +#define LV_DRAW_SW_SUPPORT_ARGB8888 1 +#define LV_DRAW_SW_SUPPORT_ARGB8888_PREMULTIPLIED 1 +#define LV_DRAW_SW_SUPPORT_L8 1 +#define LV_DRAW_SW_SUPPORT_AL88 1 +#define LV_DRAW_SW_SUPPORT_A8 1 +#define LV_DRAW_SW_SUPPORT_I1 1 + + /* The threshold of the luminance to consider a pixel as + * active in indexed color format */ +#define LV_DRAW_SW_I1_LUM_THRESHOLD 127 + + /** Set number of draw units. + * - > 1 requires operating system to be enabled in `LV_USE_OS`. + * - > 1 means multiple threads will render the screen in parallel. */ +#define LV_DRAW_SW_DRAW_UNIT_CNT 1 + + /** Use Arm-2D to accelerate software (sw) rendering. */ +#define LV_USE_DRAW_ARM2D_SYNC 0 + +/** Enable native helium assembly to be compiled. */ +#define LV_USE_NATIVE_HELIUM_ASM 0 + +/** + * - 0: Use a simple renderer capable of drawing only simple rectangles with gradient, images, text, and straight lines only. + * - 1: Use a complex renderer capable of drawing rounded corners, shadow, skew lines, and arcs too. */ +#define LV_DRAW_SW_COMPLEX 1 + +#if LV_DRAW_SW_COMPLEX == 1 + /** Allow buffering some shadow calculation. + * LV_DRAW_SW_SHADOW_CACHE_SIZE is the maximum shadow size to buffer, where shadow size is + * `shadow_width + radius`. Caching has LV_DRAW_SW_SHADOW_CACHE_SIZE^2 RAM cost. */ +#define LV_DRAW_SW_SHADOW_CACHE_SIZE 0 + + /** Set number of maximally-cached circle data. + * The circumference of 1/4 circle are saved for anti-aliasing. + * `radius * 4` bytes are used per circle (the most often used radiuses are saved). + * - 0: disables caching */ +#define LV_DRAW_SW_CIRCLE_CACHE_SIZE 4 +#endif + +#define LV_USE_DRAW_SW_ASM LV_DRAW_SW_ASM_NONE + +#if LV_USE_DRAW_SW_ASM == LV_DRAW_SW_ASM_CUSTOM +#define LV_DRAW_SW_ASM_CUSTOM_INCLUDE "" +#endif + + /** Enable drawing complex gradients in software: linear at an angle, radial or conical */ +#define LV_USE_DRAW_SW_COMPLEX_GRADIENTS 0 + +#endif + +/*Use TSi's aka (Think Silicon) NemaGFX */ +#define LV_USE_NEMA_GFX 0 + +#if LV_USE_NEMA_GFX + /** Select which NemaGFX HAL to use. Possible options: + * - LV_NEMA_HAL_CUSTOM + * - LV_NEMA_HAL_STM32 */ +#define LV_USE_NEMA_HAL LV_NEMA_HAL_CUSTOM +#if LV_USE_NEMA_HAL == LV_NEMA_HAL_STM32 +#define LV_NEMA_STM32_HAL_INCLUDE +#endif + + /*Enable Vector Graphics Operations. Available only if NemaVG library is present*/ +#define LV_USE_NEMA_VG 0 +#if LV_USE_NEMA_VG + /*Define application's resolution used for VG related buffer allocation */ +#define LV_NEMA_GFX_MAX_RESX 800 +#define LV_NEMA_GFX_MAX_RESY 600 +#endif +#endif + +/** Use NXP's PXP on iMX RTxxx platforms. */ +#define LV_USE_PXP 0 + +#if LV_USE_PXP + /** Use PXP for drawing.*/ +#define LV_USE_DRAW_PXP 1 + +/** Use PXP to rotate display.*/ +#define LV_USE_ROTATE_PXP 0 + +#if LV_USE_DRAW_PXP && LV_USE_OS + /** Use additional draw thread for PXP processing.*/ +#define LV_USE_PXP_DRAW_THREAD 1 +#endif + +/** Enable PXP asserts. */ +#define LV_USE_PXP_ASSERT 0 +#endif + +/** Use NXP's G2D on MPU platforms. */ +#define LV_USE_G2D 0 + +#if LV_USE_G2D + /** Use G2D for drawing. **/ +#define LV_USE_DRAW_G2D 1 + +/** Use G2D to rotate display. **/ +#define LV_USE_ROTATE_G2D 0 + +/** Maximum number of buffers that can be stored for G2D draw unit. + * Includes the frame buffers and assets. */ +#define LV_G2D_HASH_TABLE_SIZE 50 + +#if LV_USE_DRAW_G2D && LV_USE_OS + /** Use additional draw thread for G2D processing.*/ +#define LV_USE_G2D_DRAW_THREAD 1 +#endif + +/** Enable G2D asserts. */ +#define LV_USE_G2D_ASSERT 0 +#endif + +/** Use Renesas Dave2D on RA platforms. */ +#define LV_USE_DRAW_DAVE2D 0 + +/** Draw using cached SDL textures*/ +#define LV_USE_DRAW_SDL 0 + +/** Use VG-Lite GPU. */ +#define LV_USE_DRAW_VG_LITE 0 +#if LV_USE_DRAW_VG_LITE + /** Enable VG-Lite custom external 'gpu_init()' function */ +#define LV_VG_LITE_USE_GPU_INIT 0 + +/** Enable VG-Lite assert. */ +#define LV_VG_LITE_USE_ASSERT 0 + +/** VG-Lite flush commit trigger threshold. GPU will try to batch these many draw tasks. */ +#define LV_VG_LITE_FLUSH_MAX_COUNT 8 + +/** Enable border to simulate shadow. + * NOTE: which usually improves performance, + * but does not guarantee the same rendering quality as the software. */ +#define LV_VG_LITE_USE_BOX_SHADOW 1 + + /** VG-Lite gradient maximum cache number. + * @note The memory usage of a single gradient image is 4K bytes. */ +#define LV_VG_LITE_GRAD_CACHE_CNT 32 + + /** VG-Lite stroke maximum cache number. */ +#define LV_VG_LITE_STROKE_CACHE_CNT 32 + +/** VG-Lite unaligned bitmap font maximum cache number. */ +#define LV_VG_LITE_BITMAP_FONT_CACHE_CNT 256 + +/** Remove VLC_OP_CLOSE path instruction (Workaround for NXP) **/ +#define LV_VG_LITE_DISABLE_VLC_OP_CLOSE 0 + +/** Disable blit rectangular offset to resolve certain hardware errors. */ +#define LV_VG_LITE_DISABLE_BLIT_RECT_OFFSET 0 + +/** Disable linear gradient extension for some older versions of drivers. */ +#define LV_VG_LITE_DISABLE_LINEAR_GRADIENT_EXT 0 + +/** Maximum path dump print length (in points) */ +#define LV_VG_LITE_PATH_DUMP_MAX_LEN 1000 + +/** Enable usage of the LVGL's built-in vg_lite driver */ +#define LV_USE_VG_LITE_DRIVER 0 +#if LV_USE_VG_LITE_DRIVER + /** Used to pick the correct GPU series folder valid options are gc255, gc355 and gc555*/ +#define LV_VG_LITE_HAL_GPU_SERIES gc255 + +/** Used to pick the correct GPU revision header it depends on the vendor */ +#define LV_VG_LITE_HAL_GPU_REVISION 0x40 + +/** Base memory address of the GPU IP it depends on SoC, + * default value is for NXP based devices */ +#define LV_VG_LITE_HAL_GPU_BASE_ADDRESS 0x40240000 +#endif /*LV_USE_VG_LITE_DRIVER*/ + + /** Use ThorVG (a software vector library) as VG-Lite driver to allow testing VGLite on PC + * Requires: LV_USE_THORVG_INTERNAL or LV_USE_THORVG_EXTERNAL */ +#define LV_USE_VG_LITE_THORVG 0 +#if LV_USE_VG_LITE_THORVG + /** Enable LVGL's blend mode support */ +#define LV_VG_LITE_THORVG_LVGL_BLEND_SUPPORT 0 + +/** Enable YUV color format support */ +#define LV_VG_LITE_THORVG_YUV_SUPPORT 0 + +/** Enable Linear gradient extension support */ +#define LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT 0 + +/** Enable alignment on 16 pixels */ +#define LV_VG_LITE_THORVG_16PIXELS_ALIGN 1 + +/** Buffer address alignment */ +#define LV_VG_LITE_THORVG_BUF_ADDR_ALIGN 64 + +/** Enable multi-thread render */ +#define LV_VG_LITE_THORVG_THREAD_RENDER 0 +#endif /*LV_USE_VG_LITE_THORVG*/ +#endif + +/** Accelerate blends, fills, etc. with STM32 DMA2D */ +#define LV_USE_DRAW_DMA2D 0 +#if LV_USE_DRAW_DMA2D +#define LV_DRAW_DMA2D_HAL_INCLUDE "stm32h7xx_hal.h" + +/* if enabled, the user is required to call `lv_draw_dma2d_transfer_complete_interrupt_handler` + * upon receiving the DMA2D global interrupt + */ +#define LV_USE_DRAW_DMA2D_INTERRUPT 0 +#endif + + /** Draw using cached OpenGLES textures. Requires LV_USE_OPENGLES */ +#define LV_USE_DRAW_OPENGLES 0 +#if LV_USE_DRAW_OPENGLES +#define LV_DRAW_OPENGLES_TEXTURE_CACHE_COUNT 64 +#endif + +/** Draw using espressif PPA accelerator */ +#define LV_USE_PPA 0 +#if LV_USE_PPA +#define LV_USE_PPA_IMG 0 +#endif + +/* Use EVE FT81X GPU. */ +#define LV_USE_DRAW_EVE 0 +#if LV_USE_DRAW_EVE + /* EVE_GEN value: 2, 3, or 4 */ +#define LV_DRAW_EVE_EVE_GENERATION 4 + +/* The maximum number of bytes to buffer before a single SPI transmission. + * Set it to 0 to disable write buffering. + */ +#define LV_DRAW_EVE_WRITE_BUFFER_SIZE 2048 +#endif + + /** Use NanoVG Renderer + * - Requires LV_USE_NANOVG, LV_USE_MATRIX. + */ +#define LV_USE_DRAW_NANOVG 0 +#if LV_USE_DRAW_NANOVG + /** Select OpenGL backend for NanoVG: + * - LV_NANOVG_BACKEND_GL2: OpenGL 2.0 + * - LV_NANOVG_BACKEND_GL3: OpenGL 3.0+ + * - LV_NANOVG_BACKEND_GLES2: OpenGL ES 2.0 + * - LV_NANOVG_BACKEND_GLES3: OpenGL ES 3.0+ + */ +#define LV_NANOVG_BACKEND LV_NANOVG_BACKEND_GLES2 + + /** Draw image texture cache count. */ +#define LV_NANOVG_IMAGE_CACHE_CNT 128 + +/** Draw letter texture cache count. */ +#define LV_NANOVG_LETTER_CACHE_CNT 512 +#endif + +/*======================= + * FEATURE CONFIGURATION + *=======================*/ + + /*------------- + * Logging + *-----------*/ + + /** Enable log module */ +#define LV_USE_LOG 0 +#if LV_USE_LOG + /** Set value to one of the following levels of logging detail: + * - LV_LOG_LEVEL_TRACE Log detailed information. + * - LV_LOG_LEVEL_INFO Log important events. + * - LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem. + * - LV_LOG_LEVEL_ERROR Log only critical issues, when system may fail. + * - LV_LOG_LEVEL_USER Log only custom log messages added by the user. + * - LV_LOG_LEVEL_NONE Do not log anything. */ +#define LV_LOG_LEVEL LV_LOG_LEVEL_WARN + + /** - 1: Print log with 'printf'; + * - 0: User needs to register a callback with `lv_log_register_print_cb()`. */ +#define LV_LOG_PRINTF 0 + + /** Set callback to print logs. + * E.g `my_print`. The prototype should be `void my_print(lv_log_level_t level, const char * buf)`. + * Can be overwritten by `lv_log_register_print_cb`. */ + //#define LV_LOG_PRINT_CB + + /** - 1: Enable printing timestamp; + * - 0: Disable printing timestamp. */ +#define LV_LOG_USE_TIMESTAMP 1 + + /** - 1: Print file and line number of the log; + * - 0: Do not print file and line number of the log. */ +#define LV_LOG_USE_FILE_LINE 1 + + /* Enable/disable LV_LOG_TRACE in modules that produces a huge number of logs. */ +#define LV_LOG_TRACE_MEM 1 /**< Enable/disable trace logs in memory operations. */ +#define LV_LOG_TRACE_TIMER 1 /**< Enable/disable trace logs in timer operations. */ +#define LV_LOG_TRACE_INDEV 1 /**< Enable/disable trace logs in input device operations. */ +#define LV_LOG_TRACE_DISP_REFR 1 /**< Enable/disable trace logs in display re-draw operations. */ +#define LV_LOG_TRACE_EVENT 1 /**< Enable/disable trace logs in event dispatch logic. */ +#define LV_LOG_TRACE_OBJ_CREATE 1 /**< Enable/disable trace logs in object creation (core `obj` creation plus every widget). */ +#define LV_LOG_TRACE_LAYOUT 1 /**< Enable/disable trace logs in flex- and grid-layout operations. */ +#define LV_LOG_TRACE_ANIM 1 /**< Enable/disable trace logs in animation logic. */ +#define LV_LOG_TRACE_CACHE 1 /**< Enable/disable trace logs in cache operations. */ +#endif /*LV_USE_LOG*/ + +/*------------- + * Asserts + *-----------*/ + + /* Enable assertion failures if an operation fails or invalid data is found. + * If LV_USE_LOG is enabled, an error message will be printed on failure. */ +#define LV_USE_ASSERT_NULL 1 /**< Check if the parameter is NULL. (Very fast, recommended) */ +#define LV_USE_ASSERT_MALLOC 1 /**< Checks is the memory is successfully allocated or no. (Very fast, recommended) */ +#define LV_USE_ASSERT_STYLE 0 /**< Check if the styles are properly initialized. (Very fast, recommended) */ +#define LV_USE_ASSERT_MEM_INTEGRITY 0 /**< Check the integrity of `lv_mem` after critical operations. (Slow) */ +#define LV_USE_ASSERT_OBJ 0 /**< Check the object's type and existence (e.g. not deleted). (Slow) */ + + /** Add a custom handler when assert happens e.g. to restart MCU. */ +#define LV_ASSERT_HANDLER_INCLUDE +#define LV_ASSERT_HANDLER while(1); /**< Halt by default */ + +/*------------- + * Debug + *-----------*/ + + /** 1: Draw random colored rectangles over the redrawn areas. */ +#define LV_USE_REFR_DEBUG 0 + +/** 1: Draw a red overlay for ARGB layers and a green overlay for RGB layers*/ +#define LV_USE_LAYER_DEBUG 0 + +/** 1: Adds the following behaviors for debugging: + * - Draw overlays with different colors for each draw_unit's tasks. + * - Draw index number of draw unit on white background. + * - For layers, draws index number of draw unit on black background. */ +#define LV_USE_PARALLEL_DRAW_DEBUG 0 + + /*------------- + * Others + *-----------*/ + +#define LV_ENABLE_GLOBAL_CUSTOM 0 +#if LV_ENABLE_GLOBAL_CUSTOM + /** Header to include for custom 'lv_global' function" */ +#define LV_GLOBAL_CUSTOM_INCLUDE +#endif + +/** Default cache size in bytes. + * Used by image decoders such as `lv_lodepng` to keep the decoded image in memory. + * If size is not set to 0, the decoder will fail to decode when the cache is full. + * If size is 0, the cache function is not enabled and the decoded memory will be + * released immediately after use. */ +#define LV_CACHE_DEF_SIZE 0 + + /** Default number of image header cache entries. The cache is used to store the headers of images + * The main logic is like `LV_CACHE_DEF_SIZE` but for image headers. */ +#define LV_IMAGE_HEADER_CACHE_DEF_CNT 0 + + /** Number of stops allowed per gradient. Increase this to allow more stops. + * This adds (sizeof(lv_color_t) + 1) bytes per additional stop. */ +#define LV_GRADIENT_MAX_STOPS 2 + + /** Adjust color mix functions rounding. GPUs might calculate color mix (blending) differently. + * - 0: round down, + * - 64: round up from x.75, + * - 128: round up from half, + * - 192: round up from x.25, + * - 254: round up */ +#define LV_COLOR_MIX_ROUND_OFS 0 + + /** Add 2 x 32-bit variables to each `lv_obj_t` to speed up getting style properties */ +#define LV_OBJ_STYLE_CACHE 0 + +/** Add `id` field to `lv_obj_t` */ +#define LV_USE_OBJ_ID 0 + +/** Enable support widget names*/ +#define LV_USE_OBJ_NAME 0 + +/** Automatically assign an ID when obj is created */ +#define LV_OBJ_ID_AUTO_ASSIGN LV_USE_OBJ_ID + +/** Use builtin obj ID handler functions: +* - lv_obj_assign_id: Called when a widget is created. Use a separate counter for each widget class as an ID. +* - lv_obj_id_compare: Compare the ID to decide if it matches with a requested value. +* - lv_obj_stringify_id: Return string-ified identifier, e.g. "button3". +* - lv_obj_free_id: Does nothing, as there is no memory allocation for the ID. +* When disabled these functions needs to be implemented by the user.*/ +#define LV_USE_OBJ_ID_BUILTIN 1 + +/** Use obj property set/get API. */ +#define LV_USE_OBJ_PROPERTY 0 + +/** Enable property name support. */ +#define LV_USE_OBJ_PROPERTY_NAME 1 + +/* Enable the multi-touch gesture recognition feature */ +/* Gesture recognition requires the use of floats */ +#define LV_USE_GESTURE_RECOGNITION 0 + +/*===================== + * COMPILER SETTINGS + *====================*/ + + /** For big endian systems set to 1 */ +#define LV_BIG_ENDIAN_SYSTEM 0 + +/** Define a custom attribute for `lv_tick_inc` function */ +#define LV_ATTRIBUTE_TICK_INC + +/** Define a custom attribute for `lv_timer_handler` function */ +#define LV_ATTRIBUTE_TIMER_HANDLER + +/** Define a custom attribute for `lv_display_flush_ready` function */ +#define LV_ATTRIBUTE_FLUSH_READY + +/** Align VG_LITE buffers on this number of bytes. + * @note vglite_src_buf_aligned() uses this value to validate alignment of passed buffer pointers. */ +#define LV_ATTRIBUTE_MEM_ALIGN_SIZE 1 + + /** Will be added where memory needs to be aligned (with -Os data might not be aligned to boundary by default). + * E.g. __attribute__((aligned(4)))*/ +#define LV_ATTRIBUTE_MEM_ALIGN + + /** Attribute to mark large constant arrays, for example for font bitmaps */ +#define LV_ATTRIBUTE_LARGE_CONST + +/** Compiler prefix for a large array declaration in RAM */ +#define LV_ATTRIBUTE_LARGE_RAM_ARRAY + +/** Place performance critical functions into a faster memory (e.g RAM) */ +#define LV_ATTRIBUTE_FAST_MEM + +/** Export integer constant to binding. This macro is used with constants in the form of LV_ that + * should also appear on LVGL binding API such as MicroPython. */ +#define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning /**< The default value just prevents GCC warning */ + + /** Prefix all global extern data with this */ +#define LV_ATTRIBUTE_EXTERN_DATA + +/** Use `float` as `lv_value_precise_t` */ +#define LV_USE_FLOAT 0 + +/** Enable matrix support + * - Requires `LV_USE_FLOAT = 1` */ +#define LV_USE_MATRIX 0 + + /** Include `lvgl_private.h` in `lvgl.h` to access internal data and functions by default */ +#ifndef LV_USE_PRIVATE_API +#define LV_USE_PRIVATE_API 0 +#endif + +/*================== + * FONT USAGE + *===================*/ + + /* Montserrat fonts with ASCII range and some symbols using bpp = 4 + * https://fonts.google.com/specimen/Montserrat */ +#define LV_FONT_MONTSERRAT_8 0 +#define LV_FONT_MONTSERRAT_10 0 +#define LV_FONT_MONTSERRAT_12 0 +#define LV_FONT_MONTSERRAT_14 1 +#define LV_FONT_MONTSERRAT_16 0 +#define LV_FONT_MONTSERRAT_18 0 +#define LV_FONT_MONTSERRAT_20 0 +#define LV_FONT_MONTSERRAT_22 0 +#define LV_FONT_MONTSERRAT_24 0 +#define LV_FONT_MONTSERRAT_26 0 +#define LV_FONT_MONTSERRAT_28 0 +#define LV_FONT_MONTSERRAT_30 0 +#define LV_FONT_MONTSERRAT_32 0 +#define LV_FONT_MONTSERRAT_34 0 +#define LV_FONT_MONTSERRAT_36 0 +#define LV_FONT_MONTSERRAT_38 0 +#define LV_FONT_MONTSERRAT_40 0 +#define LV_FONT_MONTSERRAT_42 0 +#define LV_FONT_MONTSERRAT_44 0 +#define LV_FONT_MONTSERRAT_46 0 +#define LV_FONT_MONTSERRAT_48 0 + + /* Demonstrate special features */ +#define LV_FONT_MONTSERRAT_28_COMPRESSED 0 /**< bpp = 3 */ +#define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 0 /**< Hebrew, Arabic, Persian letters and all their forms */ +#define LV_FONT_SOURCE_HAN_SANS_SC_14_CJK 0 /**< 1338 most common CJK radicals */ +#define LV_FONT_SOURCE_HAN_SANS_SC_16_CJK 0 /**< 1338 most common CJK radicals */ + +/** Pixel perfect monospaced fonts */ +#define LV_FONT_UNSCII_8 0 +#define LV_FONT_UNSCII_16 0 + +/** Optionally declare custom fonts here. + * + * You can use any of these fonts as the default font too and they will be available + * globally. Example: + * + * @code + * #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) LV_FONT_DECLARE(my_font_2) + * @endcode + */ +#define LV_FONT_CUSTOM_DECLARE + + /** Always set a default font */ +#define LV_FONT_DEFAULT &lv_font_montserrat_14 + +/** Enable handling large font and/or fonts with a lot of characters. + * The limit depends on the font size, font face and bpp. + * A compiler error will be triggered if a font needs it. */ +#define LV_FONT_FMT_TXT_LARGE 0 + + /** Enables/disables support for compressed fonts. */ +#define LV_USE_FONT_COMPRESSED 0 + +/** Enable drawing placeholders when glyph dsc is not found. */ +#define LV_USE_FONT_PLACEHOLDER 1 + +/*================= + * TEXT SETTINGS + *=================*/ + + /** + * Select a character encoding for strings. + * Your IDE or editor should have the same character encoding. + * - LV_TXT_ENC_UTF8 + * - LV_TXT_ENC_ASCII + */ +#define LV_TXT_ENC LV_TXT_ENC_UTF8 + + /** While rendering text strings, break (wrap) text on these chars. */ +#define LV_TXT_BREAK_CHARS " ,.;:-_)]}" + +/** If a word is at least this long, will break wherever "prettiest". + * To disable, set to a value <= 0. */ +#define LV_TXT_LINE_BREAK_LONG_LEN 0 + + /** Minimum number of characters in a long word to put on a line before a break. + * Depends on LV_TXT_LINE_BREAK_LONG_LEN. */ +#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3 + + /** Minimum number of characters in a long word to put on a line after a break. + * Depends on LV_TXT_LINE_BREAK_LONG_LEN. */ +#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3 + + /** Support bidirectional text. Allows mixing Left-to-Right and Right-to-Left text. + * The direction will be processed according to the Unicode Bidirectional Algorithm: + * https://www.w3.org/International/articles/inline-bidi-markup/uba-basics */ +#define LV_USE_BIDI 0 +#if LV_USE_BIDI + /*Set the default direction. Supported values: + *`LV_BASE_DIR_LTR` Left-to-Right + *`LV_BASE_DIR_RTL` Right-to-Left + *`LV_BASE_DIR_AUTO` detect text base direction*/ +#define LV_BIDI_BASE_DIR_DEF LV_BASE_DIR_AUTO +#endif + + /** Enable Arabic/Persian processing + * In these languages characters should be replaced with another form based on their position in the text */ +#define LV_USE_ARABIC_PERSIAN_CHARS 0 + + /*The control character to use for signaling text recoloring*/ +#define LV_TXT_COLOR_CMD "#" + +/*================== + * WIDGETS + *================*/ + /* Documentation for widgets can be found here: https://docs.lvgl.io/master/widgets/index.html . */ + + /** 1: Causes these widgets to be given default values at creation time. + * - lv_buttonmatrix_t: Get default maps: {"Btn1", "Btn2", "Btn3", "\n", "Btn4", "Btn5", ""}, else map not set. + * - lv_checkbox_t : String label set to "Check box", else set to empty string. + * - lv_dropdown_t : Options set to "Option 1", "Option 2", "Option 3", else no values are set. + * - lv_roller_t : Options set to "Option 1", "Option 2", "Option 3", "Option 4", "Option 5", else no values are set. + * - lv_label_t : Text set to "Text", else empty string. + * - lv_arclabel_t : Text set to "Arced Text", else empty string. + * */ +#define LV_WIDGETS_HAS_DEFAULT_VALUE 1 + +#define LV_USE_ANIMIMG 1 + +#define LV_USE_ARC 1 + +#define LV_USE_ARCLABEL 1 + +#define LV_USE_BAR 1 + +#define LV_USE_BUTTON 1 + +#define LV_USE_BUTTONMATRIX 1 + +#define LV_USE_CALENDAR 1 +#if LV_USE_CALENDAR +#define LV_CALENDAR_WEEK_STARTS_MONDAY 0 +#if LV_CALENDAR_WEEK_STARTS_MONDAY +#define LV_CALENDAR_DEFAULT_DAY_NAMES {"Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"} +#else +#define LV_CALENDAR_DEFAULT_DAY_NAMES {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"} +#endif + +#define LV_CALENDAR_DEFAULT_MONTH_NAMES {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"} +#define LV_USE_CALENDAR_HEADER_ARROW 1 +#define LV_USE_CALENDAR_HEADER_DROPDOWN 1 +#define LV_USE_CALENDAR_CHINESE 0 +#endif /*LV_USE_CALENDAR*/ + +#define LV_USE_CANVAS 1 + +#define LV_USE_CHART 1 + +#define LV_USE_CHECKBOX 1 + +#define LV_USE_DROPDOWN 1 /**< Requires: lv_label */ + +#define LV_USE_IMAGE 1 /**< Requires: lv_label */ + +#define LV_USE_IMAGEBUTTON 1 + +#define LV_USE_KEYBOARD 1 + +#define LV_USE_LABEL 1 +#if LV_USE_LABEL +#define LV_LABEL_TEXT_SELECTION 1 /**< Enable selecting text of the label */ +#define LV_LABEL_LONG_TXT_HINT 1 /**< Store some extra info in labels to speed up drawing of very long text */ +#define LV_LABEL_WAIT_CHAR_COUNT 3 /**< The count of wait chart */ +#endif + +#define LV_USE_LED 1 + +#define LV_USE_LINE 1 + +#define LV_USE_LIST 1 + +#define LV_USE_LOTTIE 0 /**< Requires: lv_canvas, thorvg */ + +#define LV_USE_MENU 1 + +#define LV_USE_MSGBOX 1 + +#define LV_USE_ROLLER 1 /**< Requires: lv_label */ + +#define LV_USE_SCALE 1 + +#define LV_USE_SLIDER 1 /**< Requires: lv_bar */ + +#define LV_USE_SPAN 1 +#if LV_USE_SPAN + /** A line of text can contain this maximum number of span descriptors. */ +#define LV_SPAN_SNIPPET_STACK_SIZE 64 +#endif + +#define LV_USE_SPINBOX 1 + +#define LV_USE_SPINNER 1 + +#define LV_USE_SWITCH 1 + +#define LV_USE_TABLE 1 + +#define LV_USE_TABVIEW 1 + +#define LV_USE_TEXTAREA 1 /**< Requires: lv_label */ +#if LV_USE_TEXTAREA != 0 +#define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500 /**< [ms] */ +#endif + +#define LV_USE_TILEVIEW 1 + +#define LV_USE_WIN 1 + +#define LV_USE_3DTEXTURE 0 + +/*================== + * THEMES + *==================*/ + /* Documentation for themes can be found here: https://docs.lvgl.io/master/common-widget-features/styles/styles.html#themes . */ + + /** A simple, impressive and very complete theme */ +#define LV_USE_THEME_DEFAULT 1 +#if LV_USE_THEME_DEFAULT + /** 0: Light mode; 1: Dark mode */ +#define LV_THEME_DEFAULT_DARK 0 + +/** 1: Enable grow on press */ +#define LV_THEME_DEFAULT_GROW 1 + +/** Default transition time in ms. */ +#define LV_THEME_DEFAULT_TRANSITION_TIME 80 +#endif /*LV_USE_THEME_DEFAULT*/ + +/** A very simple theme that is a good starting point for a custom theme */ +#define LV_USE_THEME_SIMPLE 1 + +/** A theme designed for monochrome displays */ +#define LV_USE_THEME_MONO 1 + +/*================== + * LAYOUTS + *==================*/ + /* Documentation for layouts can be found here: https://docs.lvgl.io/master/common-widget-features/layouts/index.html . */ + + /** A layout similar to Flexbox in CSS. */ +#define LV_USE_FLEX 1 + +/** A layout similar to Grid in CSS. */ +#define LV_USE_GRID 1 + +/*==================== + * 3RD PARTS LIBRARIES + *====================*/ + /* Documentation for libraries can be found here: https://docs.lvgl.io/master/libs/index.html . */ + + /* File system interfaces for common APIs */ + + /** Setting a default driver letter allows skipping the driver prefix in filepaths. + * Documentation about how to use the below driver-identifier letters can be found at + * https://docs.lvgl.io/master/main-modules/fs.html#lv-fs-identifier-letters . */ +#define LV_FS_DEFAULT_DRIVER_LETTER '\0' + + /** API for fopen, fread, etc. */ +#define LV_USE_FS_STDIO 0 +#if LV_USE_FS_STDIO +#define LV_FS_STDIO_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ +#define LV_FS_STDIO_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ +#define LV_FS_STDIO_CACHE_SIZE 0 /**< >0 to cache this number of bytes in lv_fs_read() */ +#endif + +/** API for open, read, etc. */ +#define LV_USE_FS_POSIX 0 +#if LV_USE_FS_POSIX +#define LV_FS_POSIX_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ +#define LV_FS_POSIX_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ +#define LV_FS_POSIX_CACHE_SIZE 0 /**< >0 to cache this number of bytes in lv_fs_read() */ +#endif + +/** API for CreateFile, ReadFile, etc. */ +#define LV_USE_FS_WIN32 0 +#if LV_USE_FS_WIN32 +#define LV_FS_WIN32_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ +#define LV_FS_WIN32_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ +#define LV_FS_WIN32_CACHE_SIZE 0 /**< >0 to cache this number of bytes in lv_fs_read() */ +#endif + +/** API for FATFS (needs to be added separately). Uses f_open, f_read, etc. */ +#define LV_USE_FS_FATFS 0 +#if LV_USE_FS_FATFS +#define LV_FS_FATFS_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ +#define LV_FS_FATFS_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ +#define LV_FS_FATFS_CACHE_SIZE 0 /**< >0 to cache this number of bytes in lv_fs_read() */ +#endif + +/** API for memory-mapped file access. */ +#define LV_USE_FS_MEMFS 0 +#if LV_USE_FS_MEMFS +#define LV_FS_MEMFS_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ +#endif + +/** API for LittleFs. */ +#define LV_USE_FS_LITTLEFS 0 +#if LV_USE_FS_LITTLEFS +#define LV_FS_LITTLEFS_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ +#define LV_FS_LITTLEFS_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ +#endif + +/** API for Arduino LittleFs. */ +#define LV_USE_FS_ARDUINO_ESP_LITTLEFS 0 +#if LV_USE_FS_ARDUINO_ESP_LITTLEFS +#define LV_FS_ARDUINO_ESP_LITTLEFS_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ +#define LV_FS_ARDUINO_ESP_LITTLEFS_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ +#endif + +/** API for Arduino Sd. */ +#define LV_USE_FS_ARDUINO_SD 0 +#if LV_USE_FS_ARDUINO_SD +#define LV_FS_ARDUINO_SD_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ +#define LV_FS_ARDUINO_SD_PATH "" /**< Set the working directory. File/directory paths will be appended to it. */ +#endif + +/** API for UEFI */ +#define LV_USE_FS_UEFI 0 +#if LV_USE_FS_UEFI +#define LV_FS_UEFI_LETTER '\0' /**< Set an upper-case driver-identifier letter for this driver (e.g. 'A'). */ +#endif + +#define LV_USE_FS_FROGFS 0 +#if LV_USE_FS_FROGFS +#define LV_FS_FROGFS_LETTER '\0' +#endif + +/** LODEPNG decoder library */ +#define LV_USE_LODEPNG 0 + +/** PNG decoder(libpng) library */ +#define LV_USE_LIBPNG 0 + +/** BMP decoder library */ +#define LV_USE_BMP 0 + +/** JPG + split JPG decoder library. + * Split JPG is a custom format optimized for embedded systems. */ +#define LV_USE_TJPGD 0 + + /** libjpeg-turbo decoder library. + * - Supports complete JPEG specifications and high-performance JPEG decoding. */ +#define LV_USE_LIBJPEG_TURBO 0 + + /** WebP decoder library */ +#define LV_USE_LIBWEBP 0 + +/** GIF decoder library */ +#define LV_USE_GIF 0 +#if LV_USE_GIF + /** GIF decoder accelerate */ +#define LV_GIF_CACHE_DECODE_DATA 0 +#endif + +/** GStreamer library */ +#define LV_USE_GSTREAMER 0 + +/** Decode bin images to RAM */ +#define LV_BIN_DECODER_RAM_LOAD 0 + +/** RLE decompress library */ +#define LV_USE_RLE 0 + +/** QR code library */ +#define LV_USE_QRCODE 0 + +/** Barcode code library */ +#define LV_USE_BARCODE 0 + +/** FreeType library */ +#define LV_USE_FREETYPE 0 +#if LV_USE_FREETYPE + /** Let FreeType use LVGL memory and file porting */ +#define LV_FREETYPE_USE_LVGL_PORT 0 + +/** Cache count of glyphs in FreeType, i.e. number of glyphs that can be cached. + * The higher the value, the more memory will be used. */ +#define LV_FREETYPE_CACHE_FT_GLYPH_CNT 256 +#endif + + /** Built-in TTF decoder */ +#define LV_USE_TINY_TTF 0 +#if LV_USE_TINY_TTF + /* Enable loading TTF data from files */ +#define LV_TINY_TTF_FILE_SUPPORT 0 +#define LV_TINY_TTF_CACHE_GLYPH_CNT 128 +#define LV_TINY_TTF_CACHE_KERNING_CNT 256 +#endif + +/** Rlottie library */ +#define LV_USE_RLOTTIE 0 + +/** Requires `LV_USE_3DTEXTURE = 1` */ +#define LV_USE_GLTF 0 + +/** Enable Vector Graphic APIs + * Requires `LV_USE_MATRIX = 1` + * and a rendering engine supporting vector graphics, e.g. + * (LV_USE_DRAW_SW and LV_USE_THORVG) or LV_USE_DRAW_VG_LITE or LV_USE_NEMA_VG. */ +#define LV_USE_VECTOR_GRAPHIC 0 + + /** Enable ThorVG (vector graphics library) from the src/libs folder. + * Requires LV_USE_VECTOR_GRAPHIC */ +#define LV_USE_THORVG_INTERNAL 0 + + /** Enable ThorVG by assuming that its installed and linked to the project + * Requires LV_USE_VECTOR_GRAPHIC */ +#define LV_USE_THORVG_EXTERNAL 0 + + /** Enable NanoVG (vector graphics library) */ +#define LV_USE_NANOVG 0 + +/** Use lvgl built-in LZ4 lib */ +#define LV_USE_LZ4_INTERNAL 0 + +/** Use external LZ4 library */ +#define LV_USE_LZ4_EXTERNAL 0 + +/*SVG library + * - Requires `LV_USE_VECTOR_GRAPHIC = 1` */ +#define LV_USE_SVG 0 +#define LV_USE_SVG_ANIMATION 0 +#define LV_USE_SVG_DEBUG 0 + + /** FFmpeg library for image decoding and playing videos. + * Supports all major image formats so do not enable other image decoder with it. */ +#define LV_USE_FFMPEG 0 +#if LV_USE_FFMPEG + /** Dump input information to stderr */ +#define LV_FFMPEG_DUMP_FORMAT 0 +/** Use lvgl file path in FFmpeg Player widget + * You won't be able to open URLs after enabling this feature. + * Note that FFmpeg image decoder will always use lvgl file system. */ +#define LV_FFMPEG_PLAYER_USE_LV_FS 0 +#endif + + /*================== + * OTHERS + *==================*/ + /* Documentation for several of the below items can be found here: https://docs.lvgl.io/master/auxiliary-modules/index.html . */ + + /** 1: Enable API to take snapshot for object */ +#define LV_USE_SNAPSHOT 0 + +/** 1: Enable system monitor component */ +#define LV_USE_SYSMON 0 +#if LV_USE_SYSMON + /** Get the idle percentage. E.g. uint32_t my_get_idle(void); */ +#define LV_SYSMON_GET_IDLE lv_os_get_idle_percent +/** 1: Enable usage of lv_os_get_proc_idle_percent.*/ +#define LV_SYSMON_PROC_IDLE_AVAILABLE 0 +#if LV_SYSMON_PROC_IDLE_AVAILABLE + /** Get the applications idle percentage. + * - Requires `LV_USE_OS == LV_OS_PTHREAD` */ +#define LV_SYSMON_GET_PROC_IDLE lv_os_get_proc_idle_percent +#endif + + /** 1: Show CPU usage and FPS count. + * - Requires `LV_USE_SYSMON = 1` */ +#define LV_USE_PERF_MONITOR 0 +#if LV_USE_PERF_MONITOR +#define LV_USE_PERF_MONITOR_POS LV_ALIGN_BOTTOM_RIGHT + + /** 0: Displays performance data on the screen; 1: Prints performance data using log. */ +#define LV_USE_PERF_MONITOR_LOG_MODE 0 +#endif + +/** 1: Show used memory and memory fragmentation. + * - Requires `LV_USE_STDLIB_MALLOC = LV_STDLIB_BUILTIN` + * - Requires `LV_USE_SYSMON = 1`*/ +#define LV_USE_MEM_MONITOR 0 +#if LV_USE_MEM_MONITOR +#define LV_USE_MEM_MONITOR_POS LV_ALIGN_BOTTOM_LEFT +#endif +#endif /*LV_USE_SYSMON*/ + + /** 1: Enable runtime performance profiler */ +#define LV_USE_PROFILER 0 +#if LV_USE_PROFILER + /** 1: Enable the built-in profiler */ +#define LV_USE_PROFILER_BUILTIN 1 +#if LV_USE_PROFILER_BUILTIN + /** Default profiler trace buffer size */ +#define LV_PROFILER_BUILTIN_BUF_SIZE (16 * 1024) /**< [bytes] */ +#define LV_PROFILER_BUILTIN_DEFAULT_ENABLE 1 +#define LV_USE_PROFILER_BUILTIN_POSIX 0 /**< Enable POSIX profiler port */ +#endif + +/** Header to include for profiler */ +#define LV_PROFILER_INCLUDE "lvgl/src/misc/lv_profiler_builtin.h" + +/** Profiler start point function */ +#define LV_PROFILER_BEGIN LV_PROFILER_BUILTIN_BEGIN + +/** Profiler end point function */ +#define LV_PROFILER_END LV_PROFILER_BUILTIN_END + +/** Profiler start point function with custom tag */ +#define LV_PROFILER_BEGIN_TAG LV_PROFILER_BUILTIN_BEGIN_TAG + +/** Profiler end point function with custom tag */ +#define LV_PROFILER_END_TAG LV_PROFILER_BUILTIN_END_TAG + +/*Enable layout profiler*/ +#define LV_PROFILER_LAYOUT 1 + +/*Enable disp refr profiler*/ +#define LV_PROFILER_REFR 1 + +/*Enable draw profiler*/ +#define LV_PROFILER_DRAW 1 + +/*Enable indev profiler*/ +#define LV_PROFILER_INDEV 1 + +/*Enable decoder profiler*/ +#define LV_PROFILER_DECODER 1 + +/*Enable font profiler*/ +#define LV_PROFILER_FONT 1 + +/*Enable fs profiler*/ +#define LV_PROFILER_FS 1 + +/*Enable style profiler*/ +#define LV_PROFILER_STYLE 0 + +/*Enable timer profiler*/ +#define LV_PROFILER_TIMER 1 + +/*Enable cache profiler*/ +#define LV_PROFILER_CACHE 1 + +/*Enable event profiler*/ +#define LV_PROFILER_EVENT 1 +#endif + +/** 1: Enable Monkey test */ +#define LV_USE_MONKEY 0 + +/** 1: Enable grid navigation */ +#define LV_USE_GRIDNAV 0 + +/** 1: Enable `lv_obj` fragment logic */ +#define LV_USE_FRAGMENT 0 + +/** 1: Support using images as font in label or span widgets */ +#define LV_USE_IMGFONT 0 + +/** 1: Enable an observer pattern implementation */ +#define LV_USE_OBSERVER 1 + +/** 1: Enable Pinyin input method + * - Requires: lv_keyboard */ +#define LV_USE_IME_PINYIN 0 +#if LV_USE_IME_PINYIN + /** 1: Use default thesaurus. + * @note If you do not use the default thesaurus, be sure to use `lv_ime_pinyin` after setting the thesaurus. */ +#define LV_IME_PINYIN_USE_DEFAULT_DICT 1 + /** Set maximum number of candidate panels that can be displayed. + * @note This needs to be adjusted according to size of screen. */ +#define LV_IME_PINYIN_CAND_TEXT_NUM 6 + + /** Use 9-key input (k9). */ +#define LV_IME_PINYIN_USE_K9_MODE 1 +#if LV_IME_PINYIN_USE_K9_MODE == 1 +#define LV_IME_PINYIN_K9_CAND_TEXT_NUM 3 +#endif /*LV_IME_PINYIN_USE_K9_MODE*/ +#endif + +/** 1: Enable file explorer. + * - Requires: lv_table */ +#define LV_USE_FILE_EXPLORER 0 +#if LV_USE_FILE_EXPLORER + /** Maximum length of path */ +#define LV_FILE_EXPLORER_PATH_MAX_LEN (128) +/** Quick access bar, 1:use, 0:do not use. + * - Requires: lv_list */ +#define LV_FILE_EXPLORER_QUICK_ACCESS 1 +#endif + + /** 1: Enable Font manager */ +#define LV_USE_FONT_MANAGER 0 +#if LV_USE_FONT_MANAGER + +/**Font manager name max length*/ +#define LV_FONT_MANAGER_NAME_MAX_LEN 32 + +#endif + +/** Enable emulated input devices, time emulation, and screenshot compares. */ +#define LV_USE_TEST 0 +#if LV_USE_TEST + +/** Enable `lv_test_screenshot_compare`. + * Requires lodepng and a few MB of extra RAM. */ +#define LV_USE_TEST_SCREENSHOT_COMPARE 0 + +#if LV_USE_TEST_SCREENSHOT_COMPARE + /** 1: Automatically create missing reference images*/ +#define LV_TEST_SCREENSHOT_CREATE_REFERENCE_IMAGE 1 +#endif /*LV_USE_TEST_SCREENSHOT_COMPARE*/ + +#endif /*LV_USE_TEST*/ + +/** Enable loading XML UIs runtime */ +#define LV_USE_XML 0 + +/** 1: Enable text translation support */ +#define LV_USE_TRANSLATION 0 + +/*1: Enable color filter style*/ +#define LV_USE_COLOR_FILTER 0 + +/*================== + * DEVICES + *==================*/ + + /** Use SDL to open window on PC and handle mouse and keyboard. */ +#define LV_USE_SDL 0 +#if LV_USE_SDL +#define LV_SDL_INCLUDE_PATH +#define LV_SDL_RENDER_MODE LV_DISPLAY_RENDER_MODE_DIRECT /**< LV_DISPLAY_RENDER_MODE_DIRECT is recommended for best performance */ +#define LV_SDL_BUF_COUNT 1 /**< 1 or 2 */ +#define LV_SDL_ACCELERATED 1 /**< 1: Use hardware acceleration*/ +#define LV_SDL_FULLSCREEN 0 /**< 1: Make the window full screen by default */ +#define LV_SDL_DIRECT_EXIT 1 /**< 1: Exit the application when all SDL windows are closed */ +#define LV_SDL_MOUSEWHEEL_MODE LV_SDL_MOUSEWHEEL_MODE_ENCODER /*LV_SDL_MOUSEWHEEL_MODE_ENCODER/CROWN*/ +#endif + +/** Use X11 to open window on Linux desktop and handle mouse and keyboard */ +#define LV_USE_X11 0 +#if LV_USE_X11 +#define LV_X11_DIRECT_EXIT 1 /**< Exit application when all X11 windows have been closed */ +#define LV_X11_DOUBLE_BUFFER 1 /**< Use double buffers for rendering */ +/* Select only 1 of the following render modes (LV_X11_RENDER_MODE_PARTIAL preferred!). */ +#define LV_X11_RENDER_MODE_PARTIAL 1 /**< Partial render mode (preferred) */ +#define LV_X11_RENDER_MODE_DIRECT 0 /**< Direct render mode */ +#define LV_X11_RENDER_MODE_FULL 0 /**< Full render mode */ +#endif + +/** Use Wayland to open a window and handle input on Linux or BSD desktops */ +#define LV_USE_WAYLAND 0 +#if LV_USE_WAYLAND +#define LV_WAYLAND_DIRECT_EXIT 1 /**< 1: Exit the application when all Wayland windows are closed */ +#endif + +/** Driver for /dev/fb */ +#define LV_USE_LINUX_FBDEV 0 +#if LV_USE_LINUX_FBDEV +#define LV_LINUX_FBDEV_BSD 0 +#define LV_LINUX_FBDEV_RENDER_MODE LV_DISPLAY_RENDER_MODE_PARTIAL +#define LV_LINUX_FBDEV_BUFFER_COUNT 0 +#define LV_LINUX_FBDEV_BUFFER_SIZE 60 +#define LV_LINUX_FBDEV_MMAP 1 +#endif + +/** Use Nuttx to open window and handle touchscreen */ +#define LV_USE_NUTTX 0 + +#if LV_USE_NUTTX +#define LV_USE_NUTTX_INDEPENDENT_IMAGE_HEAP 0 + +/** Use independent image heap for default draw buffer */ +#define LV_NUTTX_DEFAULT_DRAW_BUF_USE_INDEPENDENT_IMAGE_HEAP 0 + +#define LV_USE_NUTTX_LIBUV 0 + +/** Use Nuttx custom init API to open window and handle touchscreen */ +#define LV_USE_NUTTX_CUSTOM_INIT 0 + +/** Driver for /dev/lcd */ +#define LV_USE_NUTTX_LCD 0 +#if LV_USE_NUTTX_LCD +#define LV_NUTTX_LCD_BUFFER_COUNT 0 +#define LV_NUTTX_LCD_BUFFER_SIZE 60 +#endif + +/** Driver for /dev/input */ +#define LV_USE_NUTTX_TOUCHSCREEN 0 + +/** Touchscreen cursor size in pixels(<=0: disable cursor) */ +#define LV_NUTTX_TOUCHSCREEN_CURSOR_SIZE 0 + +/** Driver for /dev/mouse */ +#define LV_USE_NUTTX_MOUSE 0 + +/** Mouse movement step (pixels) */ +#define LV_USE_NUTTX_MOUSE_MOVE_STEP 1 + +/*NuttX trace file and its path*/ +#define LV_USE_NUTTX_TRACE_FILE 0 +#if LV_USE_NUTTX_TRACE_FILE +#define LV_NUTTX_TRACE_FILE_PATH "/data/lvgl-trace.log" +#endif + +#endif + +/** Driver for /dev/dri/card */ +#define LV_USE_LINUX_DRM 0 + +#if LV_USE_LINUX_DRM + + /* Use the MESA GBM library to allocate DMA buffers that can be + * shared across sub-systems and libraries using the Linux DMA-BUF API. + * The GBM library aims to provide a platform independent memory management system + * it supports the major GPU vendors - This option requires linking with libgbm */ +#define LV_USE_LINUX_DRM_GBM_BUFFERS 0 + +#define LV_LINUX_DRM_USE_EGL 0 +#endif + + /** Interface for TFT_eSPI */ +#define LV_USE_TFT_ESPI 0 + +/** Interface for Lovyan_GFX */ +#define LV_USE_LOVYAN_GFX 0 + +#if LV_USE_LOVYAN_GFX +#define LV_LGFX_USER_INCLUDE "lv_lgfx_user.hpp" + +#endif /*LV_USE_LOVYAN_GFX*/ + +/** Driver for evdev input devices */ +#define LV_USE_EVDEV 0 + +/** Driver for libinput input devices */ +#define LV_USE_LIBINPUT 0 + +#if LV_USE_LIBINPUT +#define LV_LIBINPUT_BSD 0 + +/** Full keyboard support */ +#define LV_LIBINPUT_XKB 0 +#if LV_LIBINPUT_XKB + /** "setxkbmap -query" can help find the right values for your keyboard */ +#define LV_LIBINPUT_XKB_KEY_MAP { .rules = NULL, .model = "pc101", .layout = "us", .variant = NULL, .options = NULL } +#endif +#endif + +/* Drivers for LCD devices connected via SPI/parallel port */ +#define LV_USE_ST7735 0 +#define LV_USE_ST7789 0 +#define LV_USE_ST7796 0 +#define LV_USE_ILI9341 0 +#define LV_USE_FT81X 0 +#define LV_USE_NV3007 0 + +#if (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341 | LV_USE_NV3007) +#define LV_USE_GENERIC_MIPI 1 +#else +#define LV_USE_GENERIC_MIPI 0 +#endif + +/** Driver for Renesas GLCD */ +#define LV_USE_RENESAS_GLCDC 0 + +/** Driver for ST LTDC */ +#define LV_USE_ST_LTDC 0 +#if LV_USE_ST_LTDC + /* Only used for partial. */ +#define LV_ST_LTDC_USE_DMA2D_FLUSH 0 +#endif + +/** Driver for NXP ELCDIF */ +#define LV_USE_NXP_ELCDIF 0 + +/** LVGL Windows backend */ +#define LV_USE_WINDOWS 0 + +/** LVGL UEFI backend */ +#define LV_USE_UEFI 0 +#if LV_USE_UEFI +#define LV_USE_UEFI_INCLUDE "myefi.h" /**< Header that hides the actual framework (EDK2, gnu-efi, ...) */ +#define LV_UEFI_USE_MEMORY_SERVICES 0 /**< Use the memory functions from the boot services table */ +#endif + +/** Use a generic OpenGL driver that can be used to embed in other applications or used with GLFW/EGL */ +#define LV_USE_OPENGLES 0 +#if LV_USE_OPENGLES +#define LV_USE_OPENGLES_DEBUG 1 /**< Enable or disable debug for opengles */ +#endif + +/** Use GLFW to open window on PC and handle mouse and keyboard. Requires*/ +#define LV_USE_GLFW 0 + + +/** QNX Screen display and input drivers */ +#define LV_USE_QNX 0 +#if LV_USE_QNX +#define LV_QNX_BUF_COUNT 1 /**< 1 or 2 */ +#endif + +/** Enable or disable for external data and destructor function */ +#define LV_USE_EXT_DATA 0 + +/*===================== +* BUILD OPTIONS +*======================*/ + +/** Enable examples to be built with the library. */ +#define LV_BUILD_EXAMPLES 1 + +/** Build the demos */ +#define LV_BUILD_DEMOS 1 + +/*=================== + * DEMO USAGE + ====================*/ + +#if LV_BUILD_DEMOS + /** Show some widgets. This might be required to increase `LV_MEM_SIZE`. */ +#define LV_USE_DEMO_WIDGETS 0 + +/** Demonstrate usage of encoder and keyboard. */ +#define LV_USE_DEMO_KEYPAD_AND_ENCODER 0 + +/** Benchmark your system */ +#define LV_USE_DEMO_BENCHMARK 0 + +#if LV_USE_DEMO_BENCHMARK + /** Use fonts where bitmaps are aligned 16 byte and has Nx16 byte stride */ +#define LV_DEMO_BENCHMARK_ALIGNED_FONTS 0 +#endif + +/** Render test for each primitive. + * - Requires at least 480x272 display. */ +#define LV_USE_DEMO_RENDER 0 + + /** Stress test for LVGL */ +#define LV_USE_DEMO_STRESS 0 + +/** Music player demo */ +#define LV_USE_DEMO_MUSIC 0 +#if LV_USE_DEMO_MUSIC +#define LV_DEMO_MUSIC_SQUARE 0 +#define LV_DEMO_MUSIC_LANDSCAPE 0 +#define LV_DEMO_MUSIC_ROUND 0 +#define LV_DEMO_MUSIC_LARGE 0 +#define LV_DEMO_MUSIC_AUTO_PLAY 0 +#endif + +/** Vector graphic demo */ +#define LV_USE_DEMO_VECTOR_GRAPHIC 0 + +/** GLTF demo */ +#define LV_USE_DEMO_GLTF 0 + +/*--------------------------- + * Demos from lvgl/lv_demos + ---------------------------*/ + + /** Flex layout demo */ +#define LV_USE_DEMO_FLEX_LAYOUT 0 + +/** Smart-phone like multi-language demo */ +#define LV_USE_DEMO_MULTILANG 0 + +/*E-bike demo with Lottie animations (if LV_USE_LOTTIE is enabled)*/ +#define LV_USE_DEMO_EBIKE 0 +#if LV_USE_DEMO_EBIKE +#define LV_DEMO_EBIKE_PORTRAIT 0 /*0: for 480x270..480x320, 1: for 480x800..720x1280*/ +#endif + +/** High-resolution demo */ +#define LV_USE_DEMO_HIGH_RES 0 + +/* Smart watch demo */ +#define LV_USE_DEMO_SMARTWATCH 0 +#endif /* LV_BUILD_DEMOS */ + +/*--END OF LV_CONF_H--*/ + +#endif /*LV_CONF_H*/ + +#endif /*End of "Content enable"*/ \ No newline at end of file diff --git a/main/main.cpp b/main/main.cpp new file mode 100644 index 0000000..545bc5c --- /dev/null +++ b/main/main.cpp @@ -0,0 +1,175 @@ +/* + * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + + +#include +#include +#include +#include "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_chip_info.h" +#include "esp_flash.h" +#include "esp_system.h" + + // +#include "common/constants.h" +#include "common/queue_defs.h" +#include "info/info.h" +#include "display/display.h" +#include "touch/touch.h" +#include + +extern "C" void app_main(void); + +void init_queues( + QueueHandle_t& touch_queue, + EventGroupHandle_t& system_event_group, + EventGroupHandle_t& system_lifecycle_event_group +); + + +void app_main(void) { + display_chip_info(); + + try { + QueueHandle_t touch_event_queue = NULL; + EventGroupHandle_t system_event_group = NULL, system_lifecycle_event_group = NULL; + + init_queues(touch_event_queue, system_event_group, system_lifecycle_event_group); + if (touch_event_queue == NULL || system_event_group == NULL || system_lifecycle_event_group == NULL) { + throw std::runtime_error("Failed to create one or more queues/event groups"); + } + printf("Queues initialized.\n"); + SemaphoreHandle_t lvgl_mutex = xSemaphoreCreateMutex(); + if (lvgl_mutex == NULL) { + throw std::runtime_error("Failed to create LVGL mutex"); + } + // + DisplayHandler* display_handler = new EInkDisplayHandler(touch_event_queue, lvgl_mutex); + TouchHandler* touch_handler = new EInkTouchHandler(touch_event_queue); + // + display_handler->init(system_event_group); + touch_handler->init(system_event_group); + // + // LVGL tick timer + auto lvgl_tick_timer_callback = [](TimerHandle_t xTimer) { + lv_tick_inc(5); + }; + TimerHandle_t lvgl_tick_timer = xTimerCreate( + "lvgl_tick_timer", + pdMS_TO_TICKS(5), + pdTRUE, + NULL, + lvgl_tick_timer_callback + ); + if (lvgl_tick_timer == NULL) { + throw std::runtime_error("Failed to create LVGL tick timer"); + } + xTimerStart(lvgl_tick_timer, 0); + + // + printf("Waiting for system to be ready...\n"); + xEventGroupWaitBits( + system_event_group, + DISPLAY_READY_BIT | TOUCH_CALIBRATED_BIT, + pdFALSE, + pdTRUE, + portMAX_DELAY + ); + printf("System is ready. Starting main application...\n"); + // starting event loops + display_handler->start_event_loop(); + touch_handler->start_event_loop(); + // wait for shutdown signal + EventBits_t bits = xEventGroupWaitBits( + system_event_group, + SYSTEM_SHUTDOWN_BIT | SYSTEM_RESTART_BIT, + // do not clear on exit, require explicit reset + pdFALSE, + pdFALSE, + portMAX_DELAY + ); + printf("Shutdown signal received. Cleaning up...\n"); + + // cleanup + shutdown_display_handlerFunc shutdown_display_handler = display_handler->get_shutdown_display_handler(); + restart_display_handlerFunc restart_display_handler = display_handler->get_restart_display_handler(); + delete display_handler; + delete touch_handler; + vSemaphoreDelete(lvgl_mutex); + vEventGroupDelete(system_event_group); + vQueueDelete(touch_event_queue); + + printf("Cleanup complete.\n"); + + // handle shutdown or restart + if (bits & SYSTEM_SHUTDOWN_BIT) { + if (shutdown_display_handler != nullptr) { + printf("Calling display shutdown handler...\n"); + shutdown_display_handler(); + } else { + printf("No display shutdown handler to call.\n"); + } + printf("System is shutting down.\n"); + fflush(stdout); + // wait for start bit to be set again if future restart is desired, else expect manual power cycle + EventBits_t bits = xEventGroupWaitBits( + system_lifecycle_event_group, + SYSTEM_START_BIT, + pdFALSE, + pdFALSE, + portMAX_DELAY + ); + } else if (bits & SYSTEM_RESTART_BIT) { + if (restart_display_handler != nullptr) { + printf("Calling display restart handler...\n"); + restart_display_handler(); + } else { + printf("No display restart handler to call.\n"); + } + printf("System is restarting.\n"); + fflush(stdout); + } else { + printf("Unknown shutdown signal received. Restarting by default.\n"); + fflush(stdout); + } + + return esp_restart(); + } + catch (const std::exception& e) { + printf("Exception occurred during initialization: %s\n", e.what()); + printf("System will restart due to the error.\n"); + for (int i = 5; i >= 0; --i) { + printf("Restarting in %d seconds...\n", i); + vTaskDelay(1000 / portTICK_PERIOD_MS); + } + printf("Restarting now.\n"); + fflush(stdout); + return esp_restart(); + } + + printf("Reached end of app_main unexpectedly.\n"); + printf("System will restart in 10 seconds...\n"); + for (int i = 10; i >= 0; --i) { + printf("Restarting in %d seconds...\n", i); + vTaskDelay(1000 / portTICK_PERIOD_MS); + } + printf("Restarting now.\n"); + fflush(stdout); + return esp_restart(); +} + +void init_queues( + QueueHandle_t& touch_queue, + EventGroupHandle_t& system_event_group, + EventGroupHandle_t& system_lifecycle_event_group +) { + // Implementation of queue initialization + touch_queue = xQueueCreate(10, sizeof(touch_event_t)); + system_event_group = xEventGroupCreate(); + system_lifecycle_event_group = xEventGroupCreate(); +} diff --git a/main/network/network.h b/main/network/network.h new file mode 100644 index 0000000..e69de29 diff --git a/main/touch/touch.cpp b/main/touch/touch.cpp new file mode 100644 index 0000000..e82a7b4 --- /dev/null +++ b/main/touch/touch.cpp @@ -0,0 +1,53 @@ +#include "touch.h" +#include "common/constants.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/event_groups.h" +// TODO: implement actual touch functionality + +TouchHandler::TouchHandler(QueueHandle_t touch_queue) { + (void)touch_queue; +} + +TouchHandler::~TouchHandler() { } + +EInkTouchHandler::EInkTouchHandler(QueueHandle_t touch_queue) + : TouchHandler(touch_queue) { } + +EInkTouchHandler::~EInkTouchHandler() { } + +void EInkTouchHandler::init(EventGroupHandle_t system_event_group) { + if (system_event_group != NULL) { + xEventGroupSetBits(system_event_group, TOUCH_CALIBRATED_BIT); + } +} + +void EInkTouchHandler::start_event_loop() { + // Minimal background task to represent touch processing + xTaskCreate( + // use static adapter and pass `this` as task parameter + EInkTouchHandler::task_adapter, + "touch_task", + 2048, + this, + tskIDLE_PRIORITY + 1, + nullptr + ); +} + +// static +void EInkTouchHandler::task_adapter(void* arg) { + EInkTouchHandler* self = static_cast(arg); + if (self) { + self->run_event_loop(); + } else { + printf("EInkTouchHandler::task_adapter received null pointer\n"); + } + vTaskDelete(NULL); +} + +void EInkTouchHandler::run_event_loop() { + for (;;) { + vTaskDelay(pdMS_TO_TICKS(1000)); + } +} diff --git a/main/touch/touch.h b/main/touch/touch.h new file mode 100644 index 0000000..899c050 --- /dev/null +++ b/main/touch/touch.h @@ -0,0 +1,32 @@ +#include "info/info.h" + +class TouchHandler { +public: + TouchHandler(QueueHandle_t touch_queue); + // the system_event_group is used to set touch-calibrated bit + virtual void init(EventGroupHandle_t system_event_group) = 0; + virtual void start_event_loop() = 0; + virtual ~TouchHandler() = 0; +private: + TouchHandler(const TouchHandler&) = delete; + TouchHandler& operator=(const TouchHandler&) = delete; +}; + +class EInkTouchHandler : public TouchHandler { +public: + EInkTouchHandler(QueueHandle_t touch_queue); + void init(EventGroupHandle_t system_event_group) override; + void start_event_loop() override; + ~EInkTouchHandler() override; + +private: + // Task adapter used for FreeRTOS task creation. Forwards to + // `run_event_loop()` using the `this` pointer passed as the task param. + static void task_adapter(void* arg); + + // Instance method implementing the touch event loop. + void run_event_loop(); + // prevent copying + EInkTouchHandler(const EInkTouchHandler&) = delete; + EInkTouchHandler& operator=(const EInkTouchHandler&) = delete; +}; diff --git a/main/ui/ui.h b/main/ui/ui.h new file mode 100644 index 0000000..e69de29 diff --git a/pytest_hello_world.py b/pytest_hello_world.py new file mode 100644 index 0000000..eb02bd7 --- /dev/null +++ b/pytest_hello_world.py @@ -0,0 +1,55 @@ +# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +import hashlib +import logging +from typing import Callable + +import pytest +from pytest_embedded_idf.dut import IdfDut +from pytest_embedded_idf.utils import idf_parametrize +from pytest_embedded_qemu.app import QemuApp +from pytest_embedded_qemu.dut import QemuDut + + +@pytest.mark.generic +@idf_parametrize('target', ['supported_targets', 'preview_targets'], indirect=['target']) +def test_hello_world(dut: IdfDut, log_minimum_free_heap_size: Callable[..., None]) -> None: + dut.expect('Hello world!') + log_minimum_free_heap_size() + + +@pytest.mark.host_test +@idf_parametrize('target', ['linux'], indirect=['target']) +def test_hello_world_linux(dut: IdfDut) -> None: + dut.expect('Hello world!') + + +@pytest.mark.host_test +@pytest.mark.macos_shell +@idf_parametrize('target', ['linux'], indirect=['target']) +def test_hello_world_macos(dut: IdfDut) -> None: + dut.expect('Hello world!') + + +def verify_elf_sha256_embedding(app: QemuApp, sha256_reported: str) -> None: + sha256 = hashlib.sha256() + with open(app.elf_file, 'rb') as f: + sha256.update(f.read()) + sha256_expected = sha256.hexdigest() + + logging.info(f'ELF file SHA256: {sha256_expected}') + logging.info(f'ELF file SHA256 (reported by the app): {sha256_reported}') + + # the app reports only the first several hex characters of the SHA256, check that they match + if not sha256_expected.startswith(sha256_reported): + raise ValueError('ELF file SHA256 mismatch') + + +@pytest.mark.host_test +@pytest.mark.qemu +@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target']) +def test_hello_world_host(app: QemuApp, dut: QemuDut) -> None: + sha256_reported = dut.expect(r'ELF file SHA256:\s+([a-f0-9]+)').group(1).decode('utf-8') + verify_elf_sha256_embedding(app, sha256_reported) + + dut.expect('Hello world!') diff --git a/sdkconfig.ci b/sdkconfig.ci new file mode 100644 index 0000000..e69de29 diff --git a/wokwi.toml b/wokwi.toml new file mode 100644 index 0000000..2ef6510 --- /dev/null +++ b/wokwi.toml @@ -0,0 +1,4 @@ +[wokwi] +version = 1 +firmware = 'build/flasher_args.json' +elf = "build/ink-board.elf" \ No newline at end of file