✅ 验证完成: - 音频卡顿明显改善(用户实测) - 数字人 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>
39 lines
1.3 KiB
C
39 lines
1.3 KiB
C
#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 建议 17000(1帧)
|
||
// 返回 true=成功等到 VBLANK,false=超时或读取失败
|
||
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_
|