Rdzleo 31982ba7b9 feat(ui): Phase 10 - 数字人模式 LVGL → esp_emote_gfx 完整切换
 验证完成:
- 音频卡顿明显改善(用户实测)
- 数字人 hiyori 动画正常显示
- nm 验证:固件中 0 个 lv_*/lvgl_* 函数符号
- kapi.bin: 4.7MB → 2.75MB(-42%)

关键改动:
- main/dzbj/ai_chat_ui_eaf.c (404 行新增):
  完全替代 LVGL 版 ai_chat_ui.c,提供同名 C API(ai_chat_screen_init
  / set_status / set_emotion / set_chat_message / resume_animation)。
  AiChatDisplay C++ 桥接层无需改动。
  内部用 gfx_emote_init + gfx_disp_add + gfx_anim + mmap_assets。
- main/CMakeLists.txt:双轨编译
  CONFIG_BAJI_BADGE_MODE=y → ai_chat_ui.c (LVGL) + bg_gif_demo.c
  CONFIG_BAJI_BADGE_MODE=n → ai_chat_ui_eaf.c (esp_emote_gfx)
- main/dzbj/dzbj_init.c:EAF 模式跳过 lvgl_lcd_init() 调用
- main/dzbj/lcd.c/h:暴露 lcd_io_handle 给 EAF 注册 IO 完成回调

踩坑修复(commit message 留档供后续参考):
1. esp_mmap_assets v2.0.0 在 use_fs=true 模式下 mmap_assets_get_mem()
   返回的是文件内偏移量而非 RAM 指针(fseek bug + offset 没加
   data_section_start),导致 LoadProhibited panic。
   解决:完全绕过 mmap_assets,自己 fopen + 解析 MMAP bin 头
   (layout: 头 16B + 每 entry 28B + data 段每文件 2B magic + 数据)。
2. esp_emote_gfx 期望 esp_lcd_touch v2.x 新 API,项目用 v1.1.2 旧 API。
   在 managed_components 内 gfx_touch.c 加 shim 桥接(local patch,
   reconfigure 后需 reapply)。
3. EAF format magic 是 0x89 'EAF'(gfx_eaf_dec.h),不是 0x5A5A
   (那是 esp_mmap_assets 内部文件分隔符)。
4. SPIFFS 需要在 ai_chat_screen_init 入口自动挂载(不能依赖
   bg_gif_demo 的惰性挂载,那个已被 CONFIG 排除)。

依赖增量:
- espressif2022/esp_emote_gfx: ~3.0.5
- espressif/esp_mmap_assets: * (仅用于声明依赖,运行时被绕过)

数字人模式核心 UI 范围:
- 显示数字人动画  (hiyori_m06/m07, 居中循环)
- 情绪 → GIF 映射  (23 情绪 → 2 EAF,sad/angry 暂用 m07,m03 待补)
- 字幕/状态文字: stub (字体接驳留待后续,需打包 .bin 字体到资源)
- 触摸: 不支持(PoC 阶段不需要)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 15:53:21 +08:00

39 lines
1.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef _DZBJ_LCD_H_
#define _DZBJ_LCD_H_
#include "dzbj_gpio.h"
#include "esp_lvgl_port.h"
#include "esp_lcd_st77916.h"
#include <driver/i2c_master.h>
// 全局 LCD 句柄lcd_init 后可用)
extern esp_lcd_panel_handle_t panel_handle;
extern esp_lcd_panel_io_handle_t lcd_io_handle; // Phase 10: 给 EAF 注册 IO 完成回调
void lcd_init(void);
void lvgl_lcd_init(void);
void lcd_clear_screen_black(void);
// 直接 DMA 填充全屏纯色(绕过 LVGL约 26ms
// buf: 调用者预分配的 DMA 缓冲区,大小 >= LCD_WID * strip_h * 2 字节
// buf 中的数据必须已填充好目标颜色的 RGB565 值
// strip_h: 每条带高度(推荐 40
void lcd_fill_color_with_buf(uint16_t *buf, int strip_h);
// VSYNC 同步(防撕裂)
// 读取当前 LCD 扫描行号,成功返回 ESP_OK
esp_err_t lcd_read_scanline(uint16_t *scanline);
// 等待进入 VBLANK 消隐期timeout_us 建议 170001帧
// 返回 true=成功等到 VBLANKfalse=超时或读取失败
bool lcd_wait_vsync_timeout(uint32_t timeout_us);
// I2C 总线共享:传入主项目的 I2C 总线句柄,供触摸控制器使用
void lcd_set_i2c_bus(i2c_master_bus_handle_t bus);
#if DZBJ_ENABLE_TOUCH
void touch_init(void);
void get_touch(uint16_t* touchx, uint16_t* touchy);
#endif
#endif // _DZBJ_LCD_H_