7 Commits

Author SHA1 Message Date
6b166f4463 feat: add EAF RTC and badge dual mode
1. 固定 RTC 数字人链路使用 ai_chat_ui_eaf,双模式开启后不再回退 LVGL/GIF 旧 RTC UI。

2. 保留电子吧唧 LVGL/SquareLine UI,只在电子吧唧运行模式启动 LVGL,避免与 EAF 抢同一 LCD flush。

3. 拆分 dzbj_hw_display_init 与 dzbj_display_init,AI/配网只初始化 LCD Touch 硬件,电子吧唧再启动 LVGL UI。

4. 配网模式使用 EAF 最小显示栈显示中文提示,请使用APP 蓝牙配网,不加载数字人资源和动画。

5. 开启 CONFIG_BAJI_BADGE_MODE,形成 RTC 数字人对话与电子吧唧图片显示双模式固件。

6. 电子吧唧图片扫描跳过 Background_360x360.jpg,避免 RTC 数字人背景进入吧唧图片列表。

7. BLE 图传在 BLE 5.0 关闭时跳过 2M PHY API,保持 legacy 1M PHY 兼容配网和图传。

8. sdkconfig.defaults 同步 BLE 内存优化,限制连接数和缓存,保留 GATT 与扫描能力。

9. 移除 ota.cc 编译和 app_update 直接依赖,双模式固件不创建 OTA 检查任务。

10. Ota 接口改为禁用 stub,保留接口兼容但不执行升级和版本检查。

11. Board 上报 JSON 的 OTA label 改为 disabled,避免依赖 OTA 运行分区。

12. partitions.csv 改为 factory 单 app 分区,扩大 app 到 0x900000,并扩大 storage 到 0x6F0000。

13. application 去除 OTA 任务句柄和服务器时间依赖,减少运行时资源占用。

14. system_info 去除 esp_ota_ops 依赖,配合无 OTA 分区配置。

15. 同步最新烧录运行日志,记录本轮双模式与配网测试结果。
2026-06-02 13:16:39 +08:00
bffd31645e feat(provisioning): BLE 配网完整修复 (跳过 EAF 资源 + EAF 最小化 + 音效播放)
修复 4 个配网模式核心问题, 让 Rtc_AIavatar 分支 (含火山 RTC SDK + 软件 AEC + 完整业务)
能像 adaptation_dzbjImg_shar 一样正常配网, 同时显示居中提示文字.

============ 问题与修复 ============

### 问题 1: 配网模式 BLE 广播 ADV_DATA malloc 失败 (手机搜不到设备)

  日志:
    E (3731) BLE_INIT: Malloc failed
    E (3731) BT_HCI: CC evt: op=0x2008 (HCI_BLE_WRITE_ADV_DATA), status=0x7
    I (3731) BluetoothProvisioning:  广播启动成功  (假成功, 广播数据空)

  根因:
    Rtc_AIavatar 比 adaptation_dzbjImg_shar 多 ~50-80 KB DRAM 业务 .bss
      (软件 AEC + HTTPS 完整状态机 + dialog watchdog + 完整 RTC 状态),
    + 火山 RTC SDK 静态库 .bss ~30-50 KB (g_cnxMgr 14.6KB, ack$14 12.6KB 等),
    配网模式时 BLE Bluedroid stack 抢不到广播数据 malloc 所需的 ~10KB DRAM.

  修复 (前次 commit 已做): sdkconfig 关闭 BLE 5.0 6 个特性 (项目实际只用 4.2 legacy),
    省 ~15 KB controller DRAM, 广播数据 malloc 成功.

### 问题 2: 配网模式下 LCD 绘制跟 WiFi/BLE 初始化抢 DRAM 导致 reboot

  日志:
    E (1200) wifi:Expected to init 10 rx buffer, actual is 1
    E (1220) BluetoothProvisioning: WiFi初始化失败: ESP_ERR_NO_MEM
    assert failed: vQueueDelete queue.c:2355 (pxQueue) ← BLE GATT fixed_queue_new 失败 → 反向清理 NULL 队列

  排查路径 (失败方案记录):
    - esp_lcd_panel_draw_bitmap 一次画 360x360 (253KB): SPI queue 满, 下半屏未画 + DRAM 抢 WiFi
    - 分块画 (60 行/块) + vTaskDelay 块间: SPI driver 内部 queue 持续保留 DRAM, 仍然抢
    - 强制 codec output_only=false 完整 duplex: 多 15KB DRAM, BLE BTU_StartUp malloc 失败 reboot
    - CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY=y: 引入 BTU bt_workqueue 分配失败 → vQueueDelete NULL → assert

  修复 (本次 commit): EAF 最小化初始化
    movecall_moji_esp32s3.cc 配网模式调用新增的 ai_chat_screen_init_provisioning(),
    跳过 8 张 EAF 资源加载 (省 4.32 MB PSRAM + ~10KB DRAM), 跳过数字人 anim,
    只启用 gfx_emote renderer + 单个 gfx_label, flush buffer 启动时预分配 (~30KB DRAM 一次到位),
    跟 BLE 初始化不再有动态分配冲突. 跟 adaptation_dzbjImg_shar 用 LVGL 显示 GIF 同思路,
    用 EAF 替代 LVGL 避免引入 50-80KB LVGL .bss.

### 问题 3: 配网模式音效不播放

  根因:
    ResetWifiConfiguration 由 BOOT 按键 OnClick 调用, 跑在 esp_timer task 上下文,
    vTaskDelay(4000ms) 实测只等了 1.1 秒就被唤醒, 音效没播完就 esp_restart.

  修复 (前次 commit 已做): 派发到独立 task 跑 PlaySound + vTaskDelay + esp_restart,
    独立 task 中 vTaskDelay 正常工作, 等 4 秒确保 解码 + DMA + 功放尾音完整.

### 问题 4: 配网时屏幕黑屏 (UX 不友好)

  实施: ai_chat_screen_init_provisioning("请使用APP\n蓝牙配网~")
    LCD 黑底白字居中显示提示文字, 用户感知"配网中".
    label height=64 (恰好包 2 行 + 余白), GFX_ALIGN_CENTER 上下左右居中.

============ 文件改动 ============

  main/application.cc:
    Application 构造时显式注释: 不能在配网模式置 background_task_=nullptr
    (OnAudioOutput 无判空, 会 std::mutex::lock 异常 abort).

  main/boards/common/wifi_board.cc:
    ResetWifiConfiguration 派发独立 task 跑 PlaySound + 4s delay + esp_restart,
    EnterWifiConfigMode BLE 启动后早 return (StartBleProvisioning 内部已 Alert 音效).

  main/boards/movecall-moji-esp32s3/movecall_moji_esp32s3.cc:
    AI 对话模式分支: 配网时调 ai_chat_screen_init_provisioning() 显示文字,
    正常模式调 ai_chat_screen_init() 显示数字人.

  main/dzbj/ai_chat_ui.h:
    新增 ai_chat_screen_init_provisioning(const char* hint_text) 声明.

  main/dzbj/ai_chat_ui_eaf.c:
    新增 ai_chat_screen_init_provisioning() 实现, EAF 最小化路径:
      gfx_emote_init + gfx_disp_add + 单 label 显示文字, 跳过 EAF 资源/anim/背景图.

============ 测试结果 (设备实测) ============
  - 按 BOOT 触发配网: 听到完整配网音效 (P3_LALA_WIFICONFIG 约 1 秒)
  - 设备重启 → 配网模式启动 → LCD 显示"请使用APP\n蓝牙配网~" 居中
  - 手机能搜到 Airhub_d0:cf:13:03:bb:f2 → 能连接 → 配网完成
  - 配网完成重启 → 正常模式数字人 + RTC 对话功能正常

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 14:42:13 +08:00
2458c4e8bc fix(ble): 关闭 BLE 5.0 特性释放 controller DRAM, 修复配网广播数据 malloc 失败
问题:
  日志:
    E (3731) BLE_INIT: Malloc failed
    E (3731) BT_HCI: CC evt: op=0x2008 (HCI_BLE_WRITE_ADV_DATA), status=0x7
    E (3731) BLE_INIT: Malloc failed
    E (3731) BT_HCI: CC evt: op=0x2009 (HCI_BLE_WRITE_SCAN_RSP), status=0x7
    I (3731) BluetoothProvisioning:  广播启动成功
  代码层"广播启动成功", 但 HCI 层 ADV_DATA + SCAN_RSP_DATA 都没写入 → 广播空数据 → 手机搜不到设备.

根因:
  sdkconfig 同时启用了 BLE 5.0 + 4.2 全套特性, 但项目代码实际只用 4.2 legacy advertising
  (esp_ble_adv_params_t / esp_ble_gap_start_advertising). BLE 5.0 6 个特性总和占用 controller DRAM,
  让 HCI ADV_DATA / SCAN_RSP_DATA 内存池耗尽.

修复:
  sdkconfig 关闭所有 BLE 5.0 特性 (项目实际不用):
    # CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set
    # CONFIG_BT_BLE_50_EXTEND_ADV_EN is not set
    # CONFIG_BT_BLE_50_PERIODIC_ADV_EN is not set
    # CONFIG_BT_BLE_50_EXTEND_SCAN_EN is not set
    # CONFIG_BT_BLE_50_EXTEND_SYNC_EN is not set
    # CONFIG_BT_BLE_50_DTM_TEST_EN is not set
  保留 CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y (legacy advertising 必需).
  dzbj_ble.c:458 用了 esp_ble_gap_set_preferred_phy (BLE 5.0 API), 但有
  #if (BLE_50_FEATURE_SUPPORT == TRUE) 保护, 关闭后编译自动跳过, 不影响其他功能.

附加: 修复 BOOT 触发配网时音效不响

  wifi_board.cc::ResetWifiConfiguration():
    - 移除直接 vTaskDelay (iot_button 回调跑在 esp_timer task, 实测 vTaskDelay 4000ms 只等了 1.1s)
    - 改用 xTaskCreate("wifi_reset") 独立 task 跑: PlaySound + vTaskDelay(4000) + esp_restart
    - 在重启前播完配网音效

  wifi_board.cc::EnterWifiConfigMode():
    - 移除之前在 BLE 配网成功后重复 PlaySound 的代码 (StartBleProvisioning 内部 Alert 已经调用过)

注: codec output_only 仍保持 NeedsProvisioning() (TX-only + ES8311-only).
  强制 duplex 会让 BLE Bluedroid gatt_init malloc failed → assert reboot loop, 已验证.

待解决 (留待 adaptation_dzbjImg_shar 分支对比):
  - 关闭 BLE 5.0 后手机可搜到设备, 但点击连接失败
  - 配网模式下 P3_LALA_WIFICONFIG 音效仍不响 (StartBleProvisioning 内 Alert 调用但 audio_loop 似乎没消费)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 12:02:44 +08:00
58c33e3cb4 feat: AI对话模式emoji表情系统 + 中文字体 + 分区优化
1. 新增AI对话LVGL界面(ai_chat_ui),支持emoji图片 + 状态文本 + 聊天消息
2. 新增7个emoji表情资源(64×64 PNG C数组):neutral/happy/sad/angry/crying/funny/laughing
3. 新增阿里巴巴普惠体20px 4bpp中文字体(GB2312字符集)
4. 利用火山RTC会话状态(VOLC_MSG_CONV_STATUS)驱动emoji切换:
   - LISTENING→happy, THINKING→neutral, ANSWERING→laughing
   - INTERRUPTED→funny, ANSWER_FINISH→happy
5. 设备状态emoji映射:Listening→happy, Speaking→laughing, Dialog→happy
6. 配网模式显示happy emoji
7. 分区优化:model 3MB→64KB,OTA 5MB→6.5MB
8. 编译优化:-Og→-Os,移除SimSun CJK字体

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 18:14:19 +08:00
14776acb0a feat: 完成 AI/吧唧双模式完全隔离重构 + 触摸坐标日志 + SPIFFS 预烧录
## 核心变更

### 1. 双模式完全隔离 (Phase 2+4)
- 拆分 InitializeButtons() 为 InitializeBadgeModeButtons() + InitializeAiModeButtons()
- 构造函数按 device_mode 分支:吧唧模式不创建 PowerSaveTimer/BackgroundTask
- 吧唧模式不注册音量/故事按键回调,避免调用 GetAudioCodec() 崩溃
- GPIO0 由 iot_button 统一处理,dzbj_button 仅注册 KEY2(GPIO4)
- SetDeviceState() 中 background_task_ 空指针保护

### 2. 吧唧模式 BOOT 按键崩溃修复
- 新增 dzbj_boot_click_handler()(C 函数,避免 lvgl.h 与 display.h 冲突)
- 移植 dzbj 的唤醒屏幕/退出手电筒/返回Home 完整逻辑

### 3. esp_timer 阻塞 LVGL 渲染修复
- iot_button 回调在 esp_timer 任务中执行,vTaskDelay 会阻塞 lv_tick_inc
- 改为 xTaskCreate 派发到独立 FreeRTOS 任务,避免冻结 LVGL 渲染

### 4. 触摸坐标日志 + SPIFFS 预烧录
- esp_lvgl_port_touch.c 添加触摸坐标打印
- CMakeLists.txt 添加 spiffs_create_partition_image 自动打包 spiffs_image/

### 5. dzbj 模块文件新增
- device_mode: NVS 设备模式管理 (AI=0/吧唧=1)
- dzbj_button: GPIO4 KEY2 中断 + BOOT 点击处理
- dzbj_ble: BLE GATT 图传服务 (0x0B00)
- dzbj_battery: ADC 电池电压监测
- sleep_mgr: 10s 超时熄屏低功耗管理
- pages: 图片浏览/GIF播放/PWM亮度
- fatfs: SPIFFS 文件管理

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 10:23:04 +08:00
c24a9bc162 feat: 集成 dzbj LVGL 显示模块 + 配网模式内存优化
阶段1: 将 dzbj 项目的 LVGL 8.3.11 LCD 显示集成到 AI小智 主项目,
开机显示 ScreenHome 界面,同时优化配网模式下的内存使用,
确保 WiFi+BLE+LVGL 三者共存运行。

## 新增功能

### dzbj 显示模块集成
- 新增 main/dzbj/ 目录,移植 LCD 驱动(ST77916 QSPI)、触摸驱动(CST816S)、
  LVGL 初始化和 SquareLine Studio UI 界面
- I2C 总线共享:dzbj 触摸控制器复用主项目的 I2C_NUM_1 总线
- GPIO 冲突解决:LED(GPIO21)、Touch1(GPIO1)、Touch4(GPIO7) 改为 NC,
  电池 ADC 从 GPIO6 改为 GPIO3
- 添加 LVGL、esp_lcd_st77916、esp_lcd_touch_cst816s 等组件依赖
- managed_components 纳入版本管理

### 配网模式轻量化启动
- BoxAudioCodec: 新增 output_only 模式,仅创建 I2S TX 通道(省 ~13KB DMA)
  跳过 ES7210 ADC 初始化(省 ~2-4KB)
- AudioCodec: 新增 StartOutputOnly() 方法,仅启用扬声器输出
- Application: 配网模式跳过 Opus 编码器、输入重采样器、协议初始化、
  天气位置检测等网络业务
- 板级构造函数: 配网模式跳过电池检测、IMU传感器、PowerSaveTimer

### WifiBoard 配网流程修复
- NeedsProvisioning() 静态方法: 读取 NVS force_ap 和 SSID 列表,
  用于提前判断配网模式
- force_ap 竞态修复: 构造函数不再清零 force_ap,改在 StartNetwork() 清零,
  确保 NeedsProvisioning() 能正确读到 force_ap=1
- Application 缓存 provisioning_mode_ 成员变量,避免重复读 NVS

### BLE 配网重启修复
- 配网成功后用 esp_timer 延迟重启替代 xTaskCreate,
  避免内存紧张时任务创建失败导致设备不重启
- 注释掉 WiFi 连接成功后的 MAC 地址发送步骤

### sdkconfig 内存优化
- BT_ALLOCATION_FROM_SPIRAM_FIRST=y (BLE 动态分配优先 PSRAM)
- SPIRAM_MALLOC_RESERVE_INTERNAL=32768
- NVS_ALLOCATE_CACHE_IN_SPIRAM=y
- WiFi 静态缓冲区数量优化 (RX=10, TX=8)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 17:07:51 +08:00
03496efecb 1、初始化代码,待适配中.... 2026-02-24 15:28:34 +08:00