222 lines
11 KiB
Markdown
222 lines
11 KiB
Markdown
# 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`.
|
|
|
|
<!-- ### B.4 GPIO mapping
|
|
|
|
Configured pins in code:
|
|
- `MOSI=17`, `SCLK=18`, `CS=16`, `DC=7`, `RST=3`, `BL=9`.
|
|
Evidence: `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`.
|
|
|
|
Reference mapping document:
|
|
- `LCD_CS=IO6`, `LCD_DC=IO7`, `LCD_SPI_MOSI=IO17`, `LCD_SPI_SCLK=IO18`, `LCD_RST=IO3`, `LCD_BACKLIGHT_EN=IO9`.
|
|
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`. -->
|
|
|
|
## 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 <PORT> 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
|