# LVGL + GIF Reproduction Guide (ESP-IDF Project 1:1 Porting) This document tracks how to reproduce the `LVGL + ST7789V + GIF` runtime path in this repository, and records what is already implemented versus what is still missing. All claims should be traceable to file:line evidence. If evidence is not available in the repository, mark it as `UNKNOWN`. ## Section 0: Current Implementation Status (2026-03-12) This section reflects the actual state of the repository and takes precedence over older assumptions. ### 0.1 Scope approved in this round - Introduce LVGL using `lvgl/lvgl = 9.2.0`. - Use a single ST7789V panel. - Do not use shared SPI for multiple LCD panels. - Follow LCD GPIO mapping from `docs/gpio-map.md`. - Keep layered architecture unchanged: `app_composition -> control_plane -> domain -> platform`. ### 0.2 Completed progress 1. LVGL dependency was added and locked to `9.2.0`. Evidence: `main/idf_component.yml:3`, `dependencies.lock:64`, `dependencies.lock:70`. 2. LCD runtime was migrated from JPEG demo rendering to `esp_lcd + lvgl`. Evidence: `components/platform/CMakeLists.txt:13`, `components/platform/CMakeLists.txt:49`, `components/platform/CMakeLists.txt:58`, `components/platform/src/lcd.c:367`, `components/platform/src/lcd.c:401`, `components/platform/src/lcd.c:429`, `components/platform/src/lcd.c:543`. 3. Single ST7789V panel path is active. Evidence: `components/platform/src/lcd.c:2`, `components/platform/src/lcd.c:401`, `components/platform/src/lcd.c:496`. 4. LCD pin mapping matches the GPIO map document. Evidence: `docs/gpio-map.md:16`, `docs/gpio-map.md:18`, `docs/gpio-map.md:19`, `docs/gpio-map.md:20`, `docs/gpio-map.md:24`, `docs/gpio-map.md:26`, `components/platform/src/lcd.c:35`, `components/platform/src/lcd.c:36`, `components/platform/src/lcd.c:37`, `components/platform/src/lcd.c:38`, `components/platform/src/lcd.c:39`, `components/platform/src/lcd.c:40`, `sdkconfig.defaults:81`. 5. Build passed after integration. Evidence: local run `idf.py fullclean && idf.py build` completed successfully. 6. No runtime `gc9a01` dependency remains under `components` and `main`. Evidence: `rg -n "gc9a01|GC9A01" components main` returned no matches. ### 0.3 Still missing 1. GIF business pipeline is not implemented yet in the current codebase. Missing modules include `components/gifdisplay/*`, GIF package loading, preload, and runtime switching. 2. Emotion-driven GIF switching path is not implemented (`components/emotion/*` is absent). 3. The current LVGL UI is a baseline default screen, not GIF playback UI. 4. Device-side GIF runtime logs are not available yet (`Switching gifs...` class logs are not present in runtime code). ### 0.4 Differences vs the original baseline description 1. Panel topology: Original baseline: dual GC9A01. Current implementation: single ST7789V. 2. LVGL version: Original baseline: `9.4.0`. Current implementation: `9.2.0` (explicitly requested in this round). 3. Display stack: Original baseline references an older code layout and line map. Current repository uses the layered runtime path and a rewritten `components/platform/src/lcd.c` implementation. 4. GIF status: Original baseline assumes full GIF chain exists. Current repository does not yet include GIF runtime components. ### 0.5 Environment note - `AGENTS.md` requires ESP-IDF `5.5.2` setup instructions. Evidence: `AGENTS.md:31`. - The actual local verification in this round used ESP-IDF `5.5.1` because that environment path exists locally. Evidence: `dependencies.lock:63`. ## Section A: Reality Check + Runtime Call Graph (Current Repository) ### A.1 Reality Check 1. LVGL runtime path is now present in production LCD code (not only a test utility). Evidence: `components/platform/src/lcd.c:415`, `components/platform/src/lcd.c:429`, `components/platform/src/lcd.c:479`, `components/platform/src/lcd.c:543`. 2. GIF playback path is not present in runtime code. Evidence: `rg -n "gifdisplay|lv_gif|gifpack" components main` has no runtime hits. 3. `app_main` still starts LCD through layered interfaces. Evidence: `main/main.c:285`, `components/app_composition/src/app_composition_runtime_support.c:65`, `components/control_plane/src/control_plane_runtime_support.c:39`, `components/domain/src/domain_runtime_support.c:39`, `components/platform/src/platform_runtime_support.c:176`. ### A.2 Runtime Call Graph (`app_main` to panel flush) Current startup chain: `app_main` -> `app_composition_init_lcd_device` -> `control_plane_init_lcd_device` -> `domain_init_lcd_device` -> `platform_init_lcd_device` -> `platform_runtime_init_lcd_device` -> `lcd_init_device` -> `lcd_panel_init` -> `esp_lcd_new_panel_st7789` -> LVGL display setup -> `lv_timer_handler` loop -> `lvgl_flush_cb` -> `esp_lcd_panel_draw_bitmap` Evidence: - `main/main.c:285` - `components/app_composition/src/app_composition_runtime_support.c:65` - `components/control_plane/src/control_plane_runtime_support.c:39` - `components/domain/src/domain_runtime_support.c:39` - `components/platform/src/platform_runtime_support.c:176` - `components/platform/src/lcd.c:479` - `components/platform/src/lcd.c:367` - `components/platform/src/lcd.c:401` - `components/platform/src/lcd.c:415` - `components/platform/src/lcd.c:543` - `components/platform/src/lcd.c:340` - `components/platform/src/lcd.c:343` ## Section B: LVGL Stack Details (Current) ### B.1 Versions and dependencies - IDF in lock file: `5.5.1`. Evidence: `dependencies.lock:63`. - LVGL dependency: `lvgl/lvgl 9.2.0`. Evidence: `main/idf_component.yml:3`, `dependencies.lock:64`, `dependencies.lock:70`. - Platform component dependencies include `esp_lcd`, `esp_timer`, `lvgl`. Evidence: `components/platform/CMakeLists.txt:49`, `components/platform/CMakeLists.txt:52`, `components/platform/CMakeLists.txt:58`. ### B.2 Display driver stack (single ST7789V) - SPI host: `SPI2_HOST`. Evidence: `components/platform/src/lcd.c:30`. - Panel create API: `esp_lcd_new_panel_st7789`. Evidence: `components/platform/src/lcd.c:401`. - Flush callback: `lvgl_flush_cb` -> `esp_lcd_panel_draw_bitmap`. Evidence: `components/platform/src/lcd.c:340`, `components/platform/src/lcd.c:343`. - Flush done callback: `on_color_trans_done` -> `lv_display_flush_ready`. Evidence: `components/platform/src/lcd.c:327`, `components/platform/src/lcd.c:335`, `components/platform/src/lcd.c:434`, `components/platform/src/lcd.c:437`. - Tick source: `esp_timer` calling `lv_tick_inc` every 2 ms. Evidence: `components/platform/src/lcd.c:89`, `components/platform/src/lcd.c:174`, `components/platform/src/lcd.c:177`, `components/platform/src/lcd.c:449`. - LVGL loop: `lv_timer_handler` in blocking task loop. Evidence: `components/platform/src/lcd.c:540`, `components/platform/src/lcd.c:543`. - Locking: recursive mutex around LVGL operations. Evidence: `components/platform/src/lcd.c:159`, `components/platform/src/lcd.c:164`, `components/platform/src/lcd.c:167`, `components/platform/src/lcd.c:170`, `components/platform/src/lcd.c:485`. ### B.3 Key LCD/LVGL parameters - Resolution: `320x240`. Evidence: `components/platform/src/lcd.c:86`, `components/platform/src/lcd.c:87`. - Draw buffer lines: `20`. Evidence: `components/platform/src/lcd.c:88`. - Color format: `RGB565`. Evidence: `components/platform/src/lcd.c:429`. - SPI clock: `10 MHz`. Evidence: `components/platform/src/lcd.c:31`. ## Section C: GIF Pipeline Status ### C.1 Current status - `UNKNOWN` as implemented feature in this repository branch: full GIF runtime pipeline. - No `gifdisplay` component exists in current source tree. - No `emotion` component exists in current source tree. ### C.2 Required future implementation (not done yet) 1. Add GIF runtime owner component (recommended: `components/gifdisplay`). 2. Add GIF asset packaging and partition-read path. 3. Add GIF widget playback path in LVGL (`lv_gif_set_src` or equivalent strategy). 4. Add business trigger path from runtime state to GIF switching. 5. Add startup preload / timeout / rollback strategy consistent with target behavior. ## Section D: Layering and Dependency Compliance Current layered dependency chain remains valid: - `app_composition` depends on `control_plane`. Evidence: `components/app_composition/CMakeLists.txt:11`. - `control_plane` depends on `domain`. Evidence: `components/control_plane/CMakeLists.txt:13`. - `domain` depends on `platform`. Evidence: `components/domain/CMakeLists.txt:13`. - `platform` owns runtime LCD integration directly (no separate `lcd` component dependency). Evidence: `components/platform/CMakeLists.txt:13`, `components/platform/src/platform_runtime_support.c:11`, `components/platform/src/platform_runtime_support.c:176`. ## Section E: Verification Matrix ### E.1 Completed in this round | Check | Command | Result | |---|---|---| | Build | `idf.py fullclean && idf.py build` | Passed | | LVGL dependency | lockfile inspection | `lvgl/lvgl = 9.2.0` | | GC9A01 runtime residue | `rg -n "gc9a01|GC9A01" components main` | No matches | ### E.2 Pending for next round | Check | Command | Expected | |---|---|---| | Device runtime LVGL stability | `idf.py -p flash monitor` | No frequent flush/panel failures | | GIF startup and switching | Same monitor run with GIF triggers | GIF load and switching logs present | | Long-run behavior | Continuous run test | Stable memory and frame updates | ## Section F: Risks and Open Items 1. The guide originally describes a complete GIF stack, but the current repository does not include those modules yet. 2. The current implementation is LVGL-base-only; GIF behavior parity is still pending. 3. Environment parity risk exists if strict ESP-IDF `5.5.2` compliance is mandatory. 4. Performance targets (FPS/CPU/memory thresholds) are not yet defined in code-level acceptance criteria. ## Section G: Minimal File Set (Current State) Implemented in this round: - `main/idf_component.yml` - `dependencies.lock` - `components/platform/CMakeLists.txt` - `components/platform/internal/lcd.h` - `components/platform/src/lcd.c` Not yet implemented but required for full GIF parity: - `components/gifdisplay/*` - `components/emotion/*` - GIF assets and packaging scripts