删除LVGL,屏幕驱动测试完成
This commit is contained in:
@@ -21,8 +21,8 @@ copying cross-layer contracts or coupling orchestration code to asset paths.
|
||||
`platform_lcd_presentation_*` in `components/platform/include/platform.h`.
|
||||
- Domain runtime adapters map semantic expressions to platform presentation
|
||||
requests.
|
||||
- Platform LCD internals serialize presentation requests and perform all LVGL
|
||||
object mutation inside the LCD render task.
|
||||
- Platform LCD internals serialize presentation requests and perform all panel
|
||||
drawing inside the LCD render task.
|
||||
|
||||
## Consequences
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ power hold
|
||||
| 2 | Audio init | Wait with bounded timeout | Log and skip boot sound | Initializes the codec path needed for playback: I2C, I2S, codec, PA control, codec buffers, and decoder resources. |
|
||||
| 3 | Boot sound playback | Wait for completion or timeout | Stop playback and continue boot | The sound must not block startup indefinitely. Use a short product-defined timeout. |
|
||||
| 4 | Audio release | Wait for synchronous release | Continue if release reports a recoverable error | If Wi-Fi/TLS starts soon after, deinit or release idle audio resources to reduce DMA/internal heap pressure. |
|
||||
| 5 | LCD device init | Wait | Continue with display disabled if init fails | Initializes SPI, panel, LVGL, draw buffers, tick timer, and backlight. |
|
||||
| 5 | LCD device init | Wait | Continue with display disabled if init fails | Initializes SPI, ST7789 panel, direct draw buffers, render state, and backlight. |
|
||||
| 6 | LCD render loop | Start and continue | Continue with display disabled if task creation fails | Needed for the default boot image or animation to appear. |
|
||||
| 7 | Boot/default expression | Do not wait for animation completion | Ignore request failure when LCD is unavailable | This is the first visible boot state. |
|
||||
| 8 | Platform/domain init | Wait | Stop boot on unrecoverable error | Performs stepper electrical initialization and domain direction state setup. |
|
||||
@@ -91,7 +91,7 @@ storage/filesystem prerequisite must be moved before audio playback.
|
||||
TLS handshake, HTTPS requests, or fortune refresh.
|
||||
- Prefer releasing idle audio resources before Wi-Fi bootstrap to reduce
|
||||
internal heap and DMA-capable memory pressure.
|
||||
- Do not initialize LCD/LVGL draw buffers concurrently with audio init unless
|
||||
- Do not initialize LCD draw buffers concurrently with audio init unless
|
||||
memory measurements prove it is stable.
|
||||
- Boot sound playback must have bounded completion semantics.
|
||||
- Audio startup failure must not prevent display, calibration, or Wi-Fi startup.
|
||||
@@ -133,4 +133,3 @@ The boot sound API should define:
|
||||
- what happens after timeout,
|
||||
- whether audio resources remain initialized after playback,
|
||||
- idempotent behavior for repeated boot calls.
|
||||
|
||||
|
||||
+37
-121
@@ -9,7 +9,7 @@ LCD expressions are split into semantic intent and low-level playback:
|
||||
|
||||
- `control_plane` decides when an expression should be requested.
|
||||
- `domain` owns semantic expression IDs and maps them to playback requests.
|
||||
- `platform` owns LCD presentation primitives and LVGL playback.
|
||||
- `platform` owns LCD presentation primitives and direct ST7789 drawing.
|
||||
|
||||
Do not bypass this path from upper layers. The expected flow is:
|
||||
|
||||
@@ -17,22 +17,34 @@ Do not bypass this path from upper layers. The expected flow is:
|
||||
control_plane condition
|
||||
-> domain_runtime_request_expression()
|
||||
-> platform_lcd_request_presentation()
|
||||
-> LCD render task / LVGL
|
||||
-> LCD direct render task
|
||||
```
|
||||
|
||||
`control_plane` must not call `platform_lcd_*` APIs directly. `platform` must
|
||||
not expose domain expression IDs.
|
||||
|
||||
## Current Backend State
|
||||
|
||||
The current LCD backend is `components/platform/src/lcd_direct.c`. It initializes
|
||||
the ST7789 panel directly through SPI using the `CONFIG_TQ_SCREEN_*` pin and
|
||||
orientation settings, starts one render task, and accepts the existing platform
|
||||
presentation requests.
|
||||
|
||||
The direct backend currently draws deterministic full-screen test patterns for
|
||||
presentation requests. Real image/resource playback is the next migration step.
|
||||
The previous widget-based display source files, display middleware dependency,
|
||||
and legacy animation assets have been removed from the build.
|
||||
|
||||
## Current Expressions
|
||||
|
||||
| Domain expression | Trigger owner | Playback kind | Behavior |
|
||||
| Domain expression | Trigger owner | Playback kind | Current behavior |
|
||||
| --- | --- | --- | --- |
|
||||
| `DOMAIN_EXPRESSION_IDLE` | LCD startup / restore path | `PLATFORM_LCD_PRESENTATION_IDLE` | Shows the default cat idle screen. |
|
||||
| `DOMAIN_EXPRESSION_SERVER_ERROR` | Multimodal server failure events | `PLATFORM_LCD_PRESENTATION_ASSET_SEQUENCE` | Plays `server_error` for 5 cycles, then returns to idle. |
|
||||
| `DOMAIN_EXPRESSION_SLOT_REELS` | Slot feature switch worker | `PLATFORM_LCD_PRESENTATION_SLOT_REELS` | Plays the procedural slot reels presentation. |
|
||||
| `DOMAIN_EXPRESSION_WIFI_DISCONNECTED` | Wi-Fi state monitor worker | `PLATFORM_LCD_PRESENTATION_ASSET_SEQUENCE` | Loops `wifi_disconnected` while STA is unavailable; saved credentials are retried with backoff, then idle is restored after reconnect. |
|
||||
| `DOMAIN_EXPRESSION_WEALTH_SPIN` | Model-command direction worker | `PLATFORM_LCD_PRESENTATION_ASSET_SEQUENCE` | Plays `spin` exactly twice as a fixed intro while the cat stays still; the worker blocks until it completes, then the reveal and motor rotation start together. |
|
||||
| `DOMAIN_EXPRESSION_WEALTH_DIRECTION` | Model-command direction worker | `PLATFORM_LCD_PRESENTATION_ASSET_SEQUENCE` | Plays the matched direction's reveal once, then returns to idle. Parametric on `direction_index`; the asset directory is resolved from the domain direction catalog order. |
|
||||
| `DOMAIN_EXPRESSION_IDLE` | LCD startup / restore path | `PLATFORM_LCD_PRESENTATION_IDLE` | Draws the direct backend idle test pattern. |
|
||||
| `DOMAIN_EXPRESSION_SERVER_ERROR` | Multimodal server failure events | `PLATFORM_LCD_PRESENTATION_ASSET_SEQUENCE` | Draws a direct backend pattern selected from the mapped asset name. |
|
||||
| `DOMAIN_EXPRESSION_SLOT_REELS` | Slot feature switch worker | `PLATFORM_LCD_PRESENTATION_SLOT_REELS` | Draws a direct backend slot-pattern placeholder. |
|
||||
| `DOMAIN_EXPRESSION_WIFI_DISCONNECTED` | Wi-Fi state monitor worker | `PLATFORM_LCD_PRESENTATION_ASSET_SEQUENCE` | Draws a direct backend pattern selected from the mapped asset name. |
|
||||
| `DOMAIN_EXPRESSION_WEALTH_SPIN` | Model-command direction worker | `PLATFORM_LCD_PRESENTATION_ASSET_SEQUENCE` | Draws a direct backend pattern selected from `spin`. |
|
||||
| `DOMAIN_EXPRESSION_WEALTH_DIRECTION` | Model-command direction worker | `PLATFORM_LCD_PRESENTATION_ASSET_SEQUENCE` | Draws a direct backend pattern selected from the mapped direction asset name. |
|
||||
|
||||
Server error currently triggers only from:
|
||||
|
||||
@@ -45,92 +57,18 @@ not meaningful without Wi-Fi connectivity.
|
||||
|
||||
Transport disconnect/error events are not server error expressions.
|
||||
|
||||
## Asset Management
|
||||
## Asset Migration Direction
|
||||
|
||||
Expression assets live under:
|
||||
The target image playback path is a platform-owned direct LCD asset pipeline.
|
||||
The reference project at `D:\Code\chaowan\lcd(1)\lcd` uses compiled RLE image
|
||||
arrays plus a small decoder/write path. When this is ported:
|
||||
|
||||
```text
|
||||
components/platform/assets/lvgl_animations/<asset_dir>/
|
||||
```
|
||||
|
||||
The platform build copies all `.bin` files under this tree into the `gifpack`
|
||||
LittleFS partition while preserving relative directories. Runtime LVGL paths are
|
||||
resolved as:
|
||||
|
||||
```text
|
||||
A:/littlefs/<asset_dir>/<file>.bin
|
||||
```
|
||||
|
||||
Asset rules:
|
||||
|
||||
- Use LVGL `.bin` images compatible with the active LCD color configuration.
|
||||
- RGB565 LZ4 compressed assets are supported by the existing decoder path when
|
||||
`LV_BIN_DECODER_RAM_LOAD` and `LV_USE_LZ4` are enabled.
|
||||
- File discovery is lexicographic. Name files with zero-padded numeric suffixes.
|
||||
- If an expression needs a non-linear playback sequence, define `frame_order` in
|
||||
the domain catalog instead of duplicating files.
|
||||
- Keep `asset_dir` names short enough for `PLATFORM_LCD_PRESENTATION_ASSET_DIR_MAX`.
|
||||
|
||||
The current server error expression uses:
|
||||
|
||||
```text
|
||||
components/platform/assets/lvgl_animations/server_error/
|
||||
```
|
||||
|
||||
Sorted source frames:
|
||||
|
||||
```text
|
||||
TQ_Cat_Server_Error_0000.bin
|
||||
TQ_Cat_Server_Error_0001.bin
|
||||
TQ_Cat_Server_Error_0002.bin
|
||||
```
|
||||
|
||||
Playback order is declared in the domain catalog as:
|
||||
|
||||
```c
|
||||
{0, 1, 2, 1, 0}
|
||||
```
|
||||
|
||||
The Wi-Fi disconnected expression uses:
|
||||
|
||||
```text
|
||||
components/platform/assets/lvgl_animations/wifi_disconnected/
|
||||
```
|
||||
|
||||
Sorted source frames:
|
||||
|
||||
```text
|
||||
TQ_Cat_wifi_disconnected_0000.bin
|
||||
TQ_Cat_wifi_disconnected_0001.bin
|
||||
TQ_Cat_wifi_disconnected_0002.bin
|
||||
TQ_Cat_wifi_disconnected_0003.bin
|
||||
```
|
||||
|
||||
Playback order is declared in the domain catalog as:
|
||||
|
||||
```c
|
||||
{0, 1, 2, 3, 2, 1, 0}
|
||||
```
|
||||
|
||||
The wealth-direction reveal uses one shared spin intro plus one body per
|
||||
direction:
|
||||
|
||||
```text
|
||||
components/platform/assets/lvgl_animations/spin/ (fixed two-cycle spin intro)
|
||||
components/platform/assets/lvgl_animations/south/
|
||||
components/platform/assets/lvgl_animations/southwest/
|
||||
components/platform/assets/lvgl_animations/west/
|
||||
components/platform/assets/lvgl_animations/northwest/
|
||||
components/platform/assets/lvgl_animations/north/
|
||||
components/platform/assets/lvgl_animations/northeast/
|
||||
components/platform/assets/lvgl_animations/east/
|
||||
components/platform/assets/lvgl_animations/southeast/
|
||||
```
|
||||
|
||||
These play all frames in sorted order (`frame_order = NULL`). The direction body
|
||||
asset is resolved from `direction_index` via `s_wealth_direction_asset_dirs[]` in
|
||||
`components/domain/src/runtime/domain_runtime_adapters.c`, whose order must match
|
||||
the direction catalog (`components/domain/src/direction/domain_direction_catalog.c`).
|
||||
- RLE decode and ST7789 writes stay inside `platform`.
|
||||
- Domain continues to map semantic expressions to short asset IDs or names.
|
||||
- Upper layers continue to use `domain_runtime_request_expression()`.
|
||||
- Large image data should not be blindly compiled into the app if it risks
|
||||
exceeding the OTA partition; prefer partition-backed resources for large
|
||||
frame sets.
|
||||
|
||||
## Requesting Expressions
|
||||
|
||||
@@ -149,42 +87,26 @@ Trigger IDs should describe why the expression was requested. They are useful
|
||||
for logs and future policy decisions, but the playback mapping is still owned by
|
||||
the domain catalog.
|
||||
|
||||
Slot reel playback uses the same expression path:
|
||||
`domain_runtime_request_expression()` with `DOMAIN_EXPRESSION_SLOT_REELS`.
|
||||
|
||||
## Playback Scheduling
|
||||
|
||||
The platform LCD presentation scheduler is non-blocking:
|
||||
|
||||
- Requests are copied at API entry.
|
||||
- LVGL objects are created, deleted, and mutated only inside the LCD render task.
|
||||
- Panel drawing is serialized by the LCD render task.
|
||||
- Same active or pending requests are coalesced.
|
||||
- Higher-priority interrupting requests replace the active presentation.
|
||||
- Lower-priority requests are ignored while a higher-priority presentation is
|
||||
active or pending.
|
||||
- Asset-backed expressions are cached after their frames are decoded. The LCD
|
||||
task preheats the `spin` asset after startup and preheats the selected wealth
|
||||
direction reveal while the fixed spin intro is playing.
|
||||
- Preheat requests do not change the active display. They decode incrementally
|
||||
during the render loop, and playback finishes any remaining decode work
|
||||
synchronously if a reveal is requested before preheat completes.
|
||||
|
||||
Current priorities:
|
||||
|
||||
| Presentation | Priority | Interrupts current |
|
||||
| --- | --- | --- |
|
||||
| Wi-Fi disconnected / idle restore | `120` | Idle restore interrupts Wi-Fi disconnected. |
|
||||
| Wealth spin / wealth-direction reveal | `110` | Yes (spin interrupts current; the reveal follows after the spin completes). |
|
||||
| Wealth spin / wealth-direction reveal | `110` | Yes |
|
||||
| Server error | `100` | Yes |
|
||||
| Slot reels | `20` | No |
|
||||
|
||||
The wealth spin/reveal pair is requested by the model-command direction worker
|
||||
(`control_plane_model_command_task`): the spin plays exactly twice as a blocking
|
||||
intro while the selected reveal is preheated, then the reveal is requested and
|
||||
the motor rotation starts together. At priority `110` a Wi-Fi-disconnected
|
||||
screen (`120`) still wins, so the reveal is suppressed while STA is down —
|
||||
consistent with the server-error suppression rule above.
|
||||
|
||||
## Adding a New Expression
|
||||
|
||||
Follow this checklist for every new expression:
|
||||
@@ -194,14 +116,11 @@ Follow this checklist for every new expression:
|
||||
2. Add a trigger reason to `domain_expression_trigger_t` if the new expression
|
||||
needs a new trigger source.
|
||||
3. Add a catalog entry in `components/domain/src/runtime/domain_runtime_adapters.c`.
|
||||
4. For asset-backed expressions, place `.bin` frames under
|
||||
`components/platform/assets/lvgl_animations/<asset_dir>/`.
|
||||
5. If the expression needs a custom frame order, define a static `uint8_t`
|
||||
frame-order array in the domain adapter and reference it from the catalog.
|
||||
6. Add or update the `control_plane` rule that creates
|
||||
4. Add or map the platform direct LCD asset in the platform LCD backend.
|
||||
5. Add or update the `control_plane` rule that creates
|
||||
`domain_expression_request_t`.
|
||||
7. Build with ESP-IDF v5.5.3 and confirm the LittleFS image includes the asset
|
||||
directory.
|
||||
6. Build with the repository-approved ESP-IDF path and verify LCD logs on
|
||||
hardware.
|
||||
|
||||
Do not add one-off APIs such as `domain_runtime_show_happy()` or
|
||||
`platform_lcd_show_error()`. Keep extension through the expression catalog and
|
||||
@@ -212,12 +131,9 @@ the unified presentation request path.
|
||||
Before merging expression changes:
|
||||
|
||||
- Run `idf.py build` through the repository-approved ESP-IDF activation path.
|
||||
- Confirm new asset files appear in the `gifpack` build output.
|
||||
- Verify `control_plane` does not include `platform.h` or call `platform_lcd_*`.
|
||||
- Verify platform code does not refer to `DOMAIN_EXPRESSION_*`.
|
||||
- For finite asset sequences, verify completion returns to idle when
|
||||
`return_to_idle` is set.
|
||||
- For interrupting expressions, verify the active lower-priority presentation is
|
||||
cancelled cleanly.
|
||||
- For wealth-direction playback, verify default -> spin and spin -> reveal
|
||||
transitions use cached/preheated assets without visible transition stalls.
|
||||
|
||||
@@ -1,221 +0,0 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user