From bcfd8a96c744b2b1e595aa1ab8d9c1995c158c64 Mon Sep 17 00:00:00 2001 From: Thomas Farstrike Date: Sun, 12 Oct 2025 11:37:26 +0200 Subject: [PATCH 1/9] Customize lv_conf.h --- lib/lv_conf.h | 65 ++++++++++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/lib/lv_conf.h b/lib/lv_conf.h index 4f97f728..122290ad 100644 --- a/lib/lv_conf.h +++ b/lib/lv_conf.h @@ -14,7 +14,7 @@ #define MICROPY_SDL 0 #endif #ifndef MICROPY_FFMPEG - #define MICROPY_FFMPEG 0 + #define MICROPY_FFMPEG 0 // works on unix/desktop but not on esp32 (conflicting time.h time_t in /home/user/sources/lvgl_micropython/lib/esp-idf/components/mbedtls/mbedtls/include/mbedtls/platform_time.h) #endif #ifndef MICROPY_RLOTTIE #define MICROPY_RLOTTIE 0 @@ -23,10 +23,12 @@ #define MICROPY_TINY_TTF 0 #endif #ifndef MICROPY_CACHE_SIZE - #define MICROPY_CACHE_SIZE 0 + //#define MICROPY_CACHE_SIZE 50 * 64 * 64 * 2 // 50 images of 64x64 pixels at 2 bytes per pixel + //#define MICROPY_CACHE_SIZE 1320000 // one image of 1100x600 pixels at 2 bytes per pixel + #define MICROPY_CACHE_SIZE 2518040 // one image of 1058x595 pixels at 4 bytes per pixel #endif #ifndef MICROPY_COLOR_DEPTH - #define MICROPY_COLOR_DEPTH 32 + #define MICROPY_COLOR_DEPTH 16 #endif #ifndef MICROPY_FLOAT #define MICROPY_FLOAT 0 @@ -216,7 +218,7 @@ extern void *mp_lv_roots; * 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: to disable caching */ - #define LV_DRAW_SW_CIRCLE_CACHE_SIZE 4 + #define LV_DRAW_SW_CIRCLE_CACHE_SIZE 40 #endif #define LV_USE_DRAW_SW_ASM LV_DRAW_SW_ASM_NONE @@ -293,7 +295,7 @@ extern void *mp_lv_roots; *-----------*/ /*Enable the log module*/ -#define LV_USE_LOG 0 +#define LV_USE_LOG 1 #if LV_USE_LOG /*How important log should be added: @@ -303,11 +305,14 @@ extern void *mp_lv_roots; *LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail *LV_LOG_LEVEL_USER Only logs added by the user *LV_LOG_LEVEL_NONE Do not log anything*/ - #define LV_LOG_LEVEL LV_LOG_LEVEL_WARN + // // 0 is trace, 1 is info, 2 is warn, 3 is error, 4 is user (FPS is here as 'sysmon' user) + // trace is useful but logs a LOT for every screen draw... + //#define LV_LOG_LEVEL LV_LOG_LEVEL_WARN + #define LV_LOG_LEVEL LV_LOG_LEVEL_INFO /*1: Print the log with 'printf'; *0: User need to register a callback with `lv_log_register_print_cb()`*/ - #define LV_LOG_PRINTF 0 + #define LV_LOG_PRINTF 0 // this doesn't seem to print anything to the serial port, so don't use it /*Set callback to print the logs. *E.g `my_print`. The prototype should be `void my_print(lv_log_level_t level, const char * buf)` @@ -344,12 +349,14 @@ extern void *mp_lv_roots; *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_STYLE 1 /*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 the MCU*/ #define LV_ASSERT_HANDLER_INCLUDE +///home/user/sources/lvgl_micropython/lib/lv_conf.h:353:27: error: implicit declaration of function 'printf' [-Werror=implicit-function-declaration] +//#define LV_ASSERT_HANDLER printf("custom handler when assert happens e.g. to restart the MCU"); while(1); /*Halt by default*/ #define LV_ASSERT_HANDLER while(1); /*Halt by default*/ /*------------- @@ -385,7 +392,7 @@ extern void *mp_lv_roots; /*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 +#define LV_IMAGE_HEADER_CACHE_DEF_CNT 24 /*Number of stops allowed per gradient. Increase this to allow more stops. *This adds (sizeof(lv_color_t) + 1) bytes per additional stop*/ @@ -492,18 +499,18 @@ extern void *mp_lv_roots; /*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_8 1 +#define LV_FONT_MONTSERRAT_10 1 #define LV_FONT_MONTSERRAT_12 1 #define LV_FONT_MONTSERRAT_14 1 #define LV_FONT_MONTSERRAT_16 1 -#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_18 1 +#define LV_FONT_MONTSERRAT_20 1 +#define LV_FONT_MONTSERRAT_22 1 +#define LV_FONT_MONTSERRAT_24 1 +#define LV_FONT_MONTSERRAT_26 1 +#define LV_FONT_MONTSERRAT_28 1 +#define LV_FONT_MONTSERRAT_30 1 #define LV_FONT_MONTSERRAT_32 0 #define LV_FONT_MONTSERRAT_34 0 #define LV_FONT_MONTSERRAT_36 0 @@ -516,13 +523,13 @@ extern void *mp_lv_roots; /*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_DEJAVU_16_PERSIAN_HEBREW 1 /*Hebrew, Arabic, Persian letters and all their forms*/ #define LV_FONT_SIMSUN_14_CJK 0 /*1000 most common CJK radicals*/ #define LV_FONT_SIMSUN_16_CJK 0 /*1000 most common CJK radicals*/ /*Pixel perfect monospace fonts*/ -#define LV_FONT_UNSCII_8 0 -#define LV_FONT_UNSCII_16 0 +#define LV_FONT_UNSCII_8 1 +#define LV_FONT_UNSCII_16 1 /*Optionally declare custom fonts here. *You can use these fonts as default font too and they will be available globally. @@ -606,7 +613,7 @@ extern void *mp_lv_roots; #define LV_USE_CALENDAR 1 #if LV_USE_CALENDAR - #define LV_CALENDAR_WEEK_STARTS_MONDAY 0 + #define LV_CALENDAR_WEEK_STARTS_MONDAY 1 #if LV_CALENDAR_WEEK_STARTS_MONDAY #define LV_CALENDAR_DEFAULT_DAY_NAMES {"Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"} #else @@ -795,13 +802,13 @@ extern void *mp_lv_roots; /* libjpeg-turbo decoder library. * Supports complete JPEG specifications and high-performance JPEG decoding. */ -#define LV_USE_LIBJPEG_TURBO 0 +#define LV_USE_LIBJPEG_TURBO 0 // needs LDFLAGS += -ljpeg in MicroPython's Makefile for this port. Only got it working on unix, not esp32 yet, needs libjpeg probably. /*GIF decoder library*/ #define LV_USE_GIF 1 #if LV_USE_GIF /*GIF decoder accelerate*/ -#define LV_GIF_CACHE_DECODE_DATA 0 +#define LV_GIF_CACHE_DECODE_DATA 1 #endif @@ -869,19 +876,19 @@ extern void *mp_lv_roots; #define LV_USE_SNAPSHOT 1 /*1: Enable system monitor component*/ -#define LV_USE_SYSMON 0 +#define LV_USE_SYSMON 1 #if LV_USE_SYSMON /*Get the idle percentage. E.g. uint32_t my_get_idle(void);*/ #define LV_SYSMON_GET_IDLE lv_timer_get_idle /*1: Show CPU usage and FPS count * Requires `LV_USE_SYSMON = 1`*/ - #define LV_USE_PERF_MONITOR 0 + #define LV_USE_PERF_MONITOR 1 #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 + #define LV_USE_PERF_MONITOR_LOG_MODE 1 #endif /*1: Show the used memory and the memory fragmentation @@ -936,7 +943,7 @@ extern void *mp_lv_roots; #define LV_IMGFONT_PATH_MAX_LEN 64 /*1: Use img cache to buffer header information*/ - #define LV_IMGFONT_USE_IMAGE_CACHE_HEADER 0 + #define LV_IMGFONT_USE_IMAGE_CACHE_HEADER 1 #endif /*1: Enable an observer pattern implementation*/ @@ -962,7 +969,7 @@ extern void *mp_lv_roots; /*1: Enable file explorer*/ /*Requires: lv_table*/ -#define LV_USE_FILE_EXPLORER 0 +#define LV_USE_FILE_EXPLORER 1 #if LV_USE_FILE_EXPLORER /*Maximum length of path*/ #define LV_FILE_EXPLORER_PATH_MAX_LEN (128) From ab8b4656598a7982cc3ff03fd7c18cd4e5b03758 Mon Sep 17 00:00:00 2001 From: Thomas Farstrike Date: Sat, 25 Oct 2025 22:03:34 +0200 Subject: [PATCH 2/9] add debug --- builder/esp32.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/builder/esp32.py b/builder/esp32.py index cfa00aaf..d5eabc0f 100644 --- a/builder/esp32.py +++ b/builder/esp32.py @@ -1570,11 +1570,19 @@ def compile(*args): # NOQA espressif_path = os.path.expanduser('~/.espressif') + import sys + print(f"version: {sys.version}") + import os + os.listdir(f"~") + os.listdir(f"{espressif_path}/") + os.listdir(f"{espressif_path}/python_env") + for ver in ('3.8', '3.9', '3.10', '3.11', '3.12', '3.13'): python_path = ( f'{espressif_path}/python_env/' f'idf{IDF_VER[:-2]}_py{ver}_env/bin' ) + print(f"checking path {python_path}") if os.path.exists(python_path): break else: From bc5232d86c66cf2f9d097d4cee3c153e88cfe43a Mon Sep 17 00:00:00 2001 From: Thomas Farstrike Date: Sat, 25 Oct 2025 22:31:49 +0200 Subject: [PATCH 3/9] maybe fix it --- builder/esp32.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/builder/esp32.py b/builder/esp32.py index d5eabc0f..3e5cdad1 100644 --- a/builder/esp32.py +++ b/builder/esp32.py @@ -1568,14 +1568,19 @@ def compile(*args): # NOQA if 'Project build complete.' in output: output = output.rsplit('To flash, run:')[-1].strip() + import os espressif_path = os.path.expanduser('~/.espressif') - import sys - print(f"version: {sys.version}") - import os - os.listdir(f"~") - os.listdir(f"{espressif_path}/") - os.listdir(f"{espressif_path}/python_env") + try: + print(f"espressif_path: {espressif_path}") + import sys + print(f"version: {sys.version}") + import os + os.listdir(f"~") + os.listdir(f"{espressif_path}/") + os.listdir(f"{espressif_path}/python_env/") + except Exception as e: + print(f"got exception {e}") for ver in ('3.8', '3.9', '3.10', '3.11', '3.12', '3.13'): python_path = ( From 66128c7ef53b8c4123b982827f2609850e75c8bb Mon Sep 17 00:00:00 2001 From: Thomas Farstrike Date: Sat, 25 Oct 2025 22:59:50 +0200 Subject: [PATCH 4/9] fix build on esp32.py with python 3.14 --- builder/esp32.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/builder/esp32.py b/builder/esp32.py index 3e5cdad1..1da8f6d0 100644 --- a/builder/esp32.py +++ b/builder/esp32.py @@ -1576,26 +1576,27 @@ def compile(*args): # NOQA import sys print(f"version: {sys.version}") import os - os.listdir(f"~") + #os.listdir(f"~") os.listdir(f"{espressif_path}/") os.listdir(f"{espressif_path}/python_env/") except Exception as e: print(f"got exception {e}") - for ver in ('3.8', '3.9', '3.10', '3.11', '3.12', '3.13'): + for ver in ('3.8', '3.9', '3.10', '3.11', '3.12', '3.13', '3.14', '3.15', '3.16'): python_path = ( f'{espressif_path}/python_env/' f'idf{IDF_VER[:-2]}_py{ver}_env/bin' ) print(f"checking path {python_path}") if os.path.exists(python_path): + python_path += '/python' break else: - raise RuntimeError( - 'unable to locate python version used in the ESP-IDF' - ) + #raise RuntimeError( + # 'unable to locate python version used in the ESP-IDF' + #) + python_path = "python" - python_path += '/python' output = output.split('python ', 1)[-1] output = output.split('\n', 1)[0] From 24a1c2de2e51387ce92b80dc2e890ef8368fda80 Mon Sep 17 00:00:00 2001 From: Thomas Farstrike Date: Sun, 26 Oct 2025 06:32:16 +0100 Subject: [PATCH 5/9] Adding just the new python version worked --- builder/esp32.py | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/builder/esp32.py b/builder/esp32.py index 1da8f6d0..800bddaf 100644 --- a/builder/esp32.py +++ b/builder/esp32.py @@ -1568,35 +1568,21 @@ def compile(*args): # NOQA if 'Project build complete.' in output: output = output.rsplit('To flash, run:')[-1].strip() - import os espressif_path = os.path.expanduser('~/.espressif') - try: - print(f"espressif_path: {espressif_path}") - import sys - print(f"version: {sys.version}") - import os - #os.listdir(f"~") - os.listdir(f"{espressif_path}/") - os.listdir(f"{espressif_path}/python_env/") - except Exception as e: - print(f"got exception {e}") - for ver in ('3.8', '3.9', '3.10', '3.11', '3.12', '3.13', '3.14', '3.15', '3.16'): python_path = ( f'{espressif_path}/python_env/' f'idf{IDF_VER[:-2]}_py{ver}_env/bin' ) - print(f"checking path {python_path}") if os.path.exists(python_path): - python_path += '/python' break else: - #raise RuntimeError( - # 'unable to locate python version used in the ESP-IDF' - #) - python_path = "python" + raise RuntimeError( + 'unable to locate python version used in the ESP-IDF' + ) + python_path += '/python' output = output.split('python ', 1)[-1] output = output.split('\n', 1)[0] From effa90082ca3058c35f9e916f97973d9902cc00a Mon Sep 17 00:00:00 2001 From: Thomas Farstrike Date: Sun, 26 Oct 2025 11:48:25 +0100 Subject: [PATCH 6/9] Add bigger font sizes --- lib/lv_conf.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/lv_conf.h b/lib/lv_conf.h index 122290ad..363f5eea 100644 --- a/lib/lv_conf.h +++ b/lib/lv_conf.h @@ -511,15 +511,15 @@ extern void *mp_lv_roots; #define LV_FONT_MONTSERRAT_26 1 #define LV_FONT_MONTSERRAT_28 1 #define LV_FONT_MONTSERRAT_30 1 -#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 +#define LV_FONT_MONTSERRAT_32 1 +#define LV_FONT_MONTSERRAT_34 1 +#define LV_FONT_MONTSERRAT_36 1 +#define LV_FONT_MONTSERRAT_38 1 +#define LV_FONT_MONTSERRAT_40 1 +#define LV_FONT_MONTSERRAT_42 1 +#define LV_FONT_MONTSERRAT_44 1 +#define LV_FONT_MONTSERRAT_46 1 +#define LV_FONT_MONTSERRAT_48 1 /*Demonstrate special features*/ #define LV_FONT_MONTSERRAT_28_COMPRESSED 0 /*bpp = 3*/ From 678e52468fc6da80ba1e387b0672c4ecbe08a85e Mon Sep 17 00:00:00 2001 From: Kili <60932529+QuasiKili@users.noreply.github.com> Date: Wed, 5 Nov 2025 16:04:22 +0100 Subject: [PATCH 7/9] Update print statements for compiled binary path so copying and running always works without navigating --- builder/unix.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/builder/unix.py b/builder/unix.py index 1316298c..9062146d 100644 --- a/builder/unix.py +++ b/builder/unix.py @@ -453,9 +453,10 @@ def compile(*args): # NOQA dst = f'build/lvgl_micropy_{REAL_PORT}' shutil.copyfile(src, dst) - print(f'compiled binary is {os.path.abspath(os.path.split(dst)[0])}') + buildpath = f"{os.path.abspath(os.path.split(dst)[0])}/lvgl_micropy_{REAL_PORT}" + print(f'compiled binary is {buildpath}') print('You need to make the binary executable by running') - print(f'"sudo chmod +x lvgl_micropy_{REAL_PORT}"') + print(f'"sudo chmod +x {buildpath}"') def mpy_cross(): From aff733ec6f38ec83310c8086c3baa643ed54f88e Mon Sep 17 00:00:00 2001 From: Thomas Farstrike Date: Fri, 7 Nov 2025 10:42:27 +0100 Subject: [PATCH 8/9] Update task_handler.py Fix upstream lvgl_micropython issue #351 --- api_drivers/common_api_drivers/frozen/other/task_handler.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api_drivers/common_api_drivers/frozen/other/task_handler.py b/api_drivers/common_api_drivers/frozen/other/task_handler.py index 67c85fa3..99e9f4a1 100644 --- a/api_drivers/common_api_drivers/frozen/other/task_handler.py +++ b/api_drivers/common_api_drivers/frozen/other/task_handler.py @@ -82,9 +82,9 @@ def add_event_cb(self, callback, event, user_data=_DefaultUserData): self._callbacks.append((callback, event, user_data)) def remove_event_cb(self, callback): - for i, obj in self._callbacks: - if obj[0] == callback: - self._callbacks.remove(obj) + for (cb, evt, data) in self._callbacks: + if cb == callback: + self._callbacks.remove((cb,evt,data)) break def deinit(self): From ae26761ef34ecfec4e92664dceabf94ff61d4693 Mon Sep 17 00:00:00 2001 From: Thomas Farstrike Date: Fri, 14 Nov 2025 17:56:14 +0100 Subject: [PATCH 9/9] Add CLAUDE.md --- CLAUDE.md | 285 +++++++++++++++++++++++++ ext_mod/esp32_components.cmake | 4 + lib/SDL | 2 +- micropy_updates/esp32/machine_sdcard.c | 2 +- 4 files changed, 291 insertions(+), 2 deletions(-) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..59a0e252 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,285 @@ +# CLAUDE.md - lvgl_micropython + +This file provides guidance for working with the lvgl_micropython build system and repository structure. + +## Project Overview + +**lvgl_micropython** is a binding project that brings LVGL (Light and Versatile Graphics Library) to MicroPython. It's a fork/spinoff of the official lv_micropython and lv_binding_micropython projects, designed to: +- Simplify compilation +- Provide a common API for adding drivers +- Support more display and input device connection topologies +- Improve build system flexibility + +This is a **composite repository** containing multiple large subprojects as git submodules. + +## Critical Build Rules + +⚠️ **IMPORTANT - READ FIRST**: + +1. **DO NOT initialize submodules manually** - The build system handles this automatically +2. **DO NOT use** information from official LVGL bindings - this is a custom fork +3. **Clone and build process**: + ```bash + git clone https://github.com/lvgl-micropython/lvgl_micropython + cd lvgl_micropython + python3 make.py esp32 ... + ``` +4. **To update to latest**: Delete local copy and re-clone from scratch (don't use git pull) +5. **Windows is NOT supported** - Build on Linux/macOS only + +## Repository Structure + +### Top-Level Directories + +- **`lib/`**: Git submodules for major dependencies + - `micropython/`: MicroPython interpreter (the Python runtime) + - `lvgl/`: LVGL graphics library (C99 framework) + - `esp-idf/`: Espressif IoT Development Framework (ESP32 SDK) + - `SDL/`: Simple DirectMedia Layer (for desktop builds) + - `pycparser/`: Python C parser (used by code generator) + +- **`builder/`**: Build system scripts (per-platform build logic) + - `__init__.py`: Core build orchestration + - `esp32.py`: ESP32-specific build configuration + - `unix.py`: Unix/Linux build configuration + - `macOS.py`: macOS build configuration + - `stm32.py`, `rp2.py`, `nrf.py`, etc.: Other platform configs + - `toml_reader.py`: TOML configuration file parser + +- **`api_drivers/`**: Display and touch controller drivers + - `common_api_drivers/`: C-based drivers (display ICs, touch ICs) + - `py_api_drivers/`: Python-based driver wrappers + +- **`ext_mod/`**: LVGL MicroPython binding code (the glue between Python and C) + +- **`gen/`**: Generated binding code (auto-generated from LVGL headers) + +- **`micropy_updates/`**: Patches and updates to MicroPython core + +- **`build/`**: Build output directory (created during compilation) + - Contains compiled binaries + - Contains intermediate build artifacts + - `display.py`: Generated display driver configuration (from TOML) + +- **`custom_board_and_toml_examples/`**: Example configurations for custom boards + +- **`display_configs/`**: Predefined display configuration files + +## Build System - make.py + +The primary entry point is **`make.py`**, a Python script that orchestrates the entire build process. + +### Basic Usage + +```bash +python3 make.py [options] +``` + +**Supported targets**: +- `esp32`: ESP32 microcontrollers +- `unix`: Linux desktop +- `macOS`: macOS desktop +- `stm32`: STM32 microcontrollers +- `rp2`: Raspberry Pi Pico (RP2040) +- `nrf`: Nordic nRF series +- `renesas-ra`: Renesas RA series +- `mimxrt`: NXP i.MX RT series +- `samd`: Microchip SAMD series +- `raspberry_pi`: Raspberry Pi (full Linux) + +### Command-Line Arguments + +**Custom board support**: +```bash +--custom-board-path # Path to custom board definition directory +``` + +**TOML configuration**: +```bash +--toml # Path to TOML configuration file for build customization +``` + +**Build control**: +```bash +-clean # Clean build artifacts before building +``` + +**LVGL compiler flags**: +```bash +-LV_CFLAGS # Additional compiler flags for LVGL +``` + +### Build Flow + +1. **Parse arguments**: Process target, custom board path, TOML config +2. **Load TOML** (if provided): Parse board configuration, generate display.py +3. **Select builder**: Import appropriate platform builder (esp32.py, unix.py, etc.) +4. **Setup environment**: Configure paths, dependencies, compiler flags +5. **Fetch submodules**: Automatically clone/update required submodules (LVGL, MicroPython, etc.) +6. **Apply patches**: Apply MicroPython updates from `micropy_updates/` +7. **Generate bindings**: Run code generator to create Python↔C glue code +8. **Compile**: Build MicroPython with LVGL binding and drivers +9. **Output**: Place binaries in `build/` directory + +### TOML Configuration System + +TOML files provide declarative board configuration instead of command-line flags. + +**Example TOML structure**: +```toml +[board] +name = "Custom ESP32 Board" +mcu = "esp32s3" + +[display] +driver = "st7789" +width = 320 +height = 240 +bus = "spi" + +[touch] +driver = "cst816s" +bus = "i2c" +``` + +The `toml_reader.py` module: +- Parses TOML configuration +- Generates `build/display.py` driver initialization code +- Converts TOML settings into make.py command-line arguments +- Simplifies custom board definitions + +## How MicroPythonOS Uses This + +MicroPythonOS uses **`scripts/build_mpos.sh`** which wraps `make.py`: + +```bash +# From MicroPythonOS root: +./scripts/build_mpos.sh unix dev +./scripts/build_mpos.sh esp32 prod waveshare-esp32-s3-touch-lcd-2 +``` + +The build script: +1. Calls `lvgl_micropython/make.py` with appropriate flags +2. Passes display driver configuration (e.g., st7789, cst816s) +3. Adds MicroPythonOS-specific C modules (camera, secp256k1, quirc) +4. Creates symlinks to MicroPythonOS manifests +5. Handles ESP32 board variants (waveshare, fri3d-2024, etc.) + +## Display and Touch Drivers + +### Supported Display ICs (common_api_drivers/display/) +- **st7789**: 240x320 TFT LCD (used by MicroPythonOS) +- **ili9341**: 240x320 TFT LCD +- **gc9a01**: 240x240 round TFT LCD +- **ssd1306**: OLED displays +- And many more... + +### Supported Touch ICs (common_api_drivers/indev/) +- **cst816s**: Capacitive touch controller (used by MicroPythonOS) +- **ft6x36**: Capacitive touch controller +- **xpt2046**: Resistive touch controller +- And more... + +### Driver API + +Drivers expose a Python API through `py_api_drivers/` wrappers: +```python +import lvgl as lv +from display_driver import DisplayDriver + +# Initialize display +display = DisplayDriver() + +# Use LVGL +screen = lv.obj() +label = lv.label(screen) +label.set_text("Hello LVGL!") +``` + +## Special Features + +### RGB Bus Driver Optimization + +The RGB bus driver uses a special dual-core optimization: +- Two **full frame buffers** hidden in C code (in SPIRAM) +- User allocates smaller **partial buffers** (e.g., 1/10 display size) +- Second ESP32 core handles buffer copying in background +- LVGL renders to partial buffer while copying happens on other core +- Screen rotation handled in C for better performance +- Reduces memory pressure while maintaining smooth rendering + +### Code Generation (gen/) + +The binding between Python and LVGL C API is **auto-generated**: +- Parses LVGL headers using pycparser +- Generates Python wrapper functions +- Creates type conversions between Python objects and C structs +- Handles memory management and garbage collection + +## Common Tasks + +### Adding a New Display Driver + +1. Create driver in `api_drivers/common_api_drivers/display//` +2. Implement standard driver API (init, flush, etc.) +3. Create Python wrapper in `api_drivers/py_api_drivers/` +4. Add to build system in appropriate `builder/.py` +5. Test with: `python3 make.py unix --display ` + +### Custom Board Definition + +1. Create directory: `custom_board_and_toml_examples/my_board/` +2. Create TOML: `my_board/board_config.toml` +3. Build: `python3 make.py esp32 --custom-board-path custom_board_and_toml_examples/my_board/` + +### Debugging Build Issues + +- **Clean build**: `python3 make.py -clean` +- **Verbose output**: Check builder script output for errors +- **Check submodules**: Ensure `lib/micropython/`, `lib/lvgl/` exist +- **Build directory**: Inspect `build/` for generated files and logs +- **Environment**: Verify CMake, Ninja, compilers are installed + +## Integration with MicroPythonOS + +When building MicroPythonOS, the integration works as follows: + +1. **MicroPythonOS manifests** are symlinked into `lib/micropython/ports//boards/` +2. **C modules** (camera, secp256k1, c_mpos) are symlinked as user modules +3. **Display config** is passed via command-line flags or TOML +4. **Frozen filesystem** (if prod build) is included via manifest.py +5. **Output binary** goes to `lvgl_micropython/build/lvgl_micropy_` +6. **MicroPythonOS** then uses this binary via `scripts/run_desktop.sh` + +## Key Files to Understand + +- **`make.py`**: Main build orchestrator (start here) +- **`builder/__init__.py`**: Core build logic +- **`builder/esp32.py`**: ESP32 platform specifics (board config, IDF integration) +- **`builder/unix.py`**: Desktop platform specifics (SDL integration) +- **`lib/lv_conf.h`**: LVGL configuration (features, memory, rendering) +- **`ext_mod/`**: Python binding implementation + +## Version Information + +The binding tracks three separate version streams: +- **LVGL version**: Currently 9.3.0 (in lib/lvgl/) +- **MicroPython version**: Tracks upstream (in lib/micropython/) +- **Binding version**: Independent versioning for the glue code + +Updates to any component require careful synchronization and testing. + +## Important Notes + +- **Submodules**: Never manually run `git submodule update` - let make.py handle it +- **Platform limitations**: Not all displays/touch drivers work on all platforms +- **Memory**: ESP32 builds require SPIRAM for LVGL framebuffers +- **Threading**: MicroPython uses single core; second core used for display DMA +- **Build time**: First build downloads submodules and compiles everything (~10-30 minutes) +- **Incremental builds**: Subsequent builds are faster (use -clean to force full rebuild) + +## Getting Help + +- **README.md**: Detailed driver lists and build instructions +- **GitHub Issues**: https://github.com/lvgl-micropython/lvgl_micropython/issues +- **MicroPythonOS docs**: https://docs.micropythonos.com for integration specifics diff --git a/ext_mod/esp32_components.cmake b/ext_mod/esp32_components.cmake index 8b137891..3ff66ec4 100644 --- a/ext_mod/esp32_components.cmake +++ b/ext_mod/esp32_components.cmake @@ -1 +1,5 @@ + +include(/home/user/projects/MicroPythonOS/MicroPythonOS/micropython-camera-API/src/micropython.cmake) +include(/home/user/projects/MicroPythonOS/MicroPythonOS/secp256k1-embedded-ecdh/micropython.cmake) +include(/home/user/projects/MicroPythonOS/MicroPythonOS/c_mpos/micropython.cmake) \ No newline at end of file diff --git a/lib/SDL b/lib/SDL index 6ad390fc..f461d91c 160000 --- a/lib/SDL +++ b/lib/SDL @@ -1 +1 @@ -Subproject commit 6ad390fc5093bcbf785b7ad103484501d11d8c2a +Subproject commit f461d91cd265d7b9a44b4d472b1df0c0ad2855a0 diff --git a/micropy_updates/esp32/machine_sdcard.c b/micropy_updates/esp32/machine_sdcard.c index 0ecde718..a524ece7 100644 --- a/micropy_updates/esp32/machine_sdcard.c +++ b/micropy_updates/esp32/machine_sdcard.c @@ -41,7 +41,7 @@ #include "sdmmc_cmd.h" #include "esp_log.h" -#define DEBUG 0 +#define DEBUG 1 #if DEBUG #define DEBUG_printf(...) ESP_LOGI("modsdcard", __VA_ARGS__) #else