## 核心变更 ### 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>
112 lines
3.2 KiB
C++
112 lines
3.2 KiB
C++
#include "button.h"
|
||
|
||
#include <esp_log.h>
|
||
|
||
static const char* TAG = "Button";
|
||
#if CONFIG_SOC_ADC_SUPPORTED
|
||
Button::Button(const button_adc_config_t& adc_cfg) {
|
||
button_config_t button_config = {
|
||
.type = BUTTON_TYPE_ADC,
|
||
.long_press_time = 3000, // 长按3秒触发(模式切换)
|
||
.short_press_time = 50,
|
||
.adc_button_config = adc_cfg
|
||
};
|
||
button_handle_ = iot_button_create(&button_config);
|
||
if (button_handle_ == NULL) {
|
||
ESP_LOGE(TAG, "Failed to create button handle");
|
||
return;
|
||
}
|
||
}
|
||
#endif
|
||
|
||
Button::Button(gpio_num_t gpio_num, bool active_high) : gpio_num_(gpio_num) {
|
||
if (gpio_num == GPIO_NUM_NC) {
|
||
return;
|
||
}
|
||
button_config_t button_config = {
|
||
.type = BUTTON_TYPE_GPIO,
|
||
.long_press_time = 3000, // 长按3秒触发(模式切换)
|
||
.short_press_time = 50,
|
||
.gpio_button_config = {
|
||
.gpio_num = gpio_num,
|
||
.active_level = static_cast<uint8_t>(active_high ? 1 : 0)
|
||
}
|
||
};
|
||
button_handle_ = iot_button_create(&button_config);
|
||
if (button_handle_ == NULL) {
|
||
ESP_LOGE(TAG, "Failed to create button handle");
|
||
return;
|
||
}
|
||
}
|
||
|
||
Button::~Button() {
|
||
if (button_handle_ != NULL) {
|
||
iot_button_delete(button_handle_);
|
||
}
|
||
}
|
||
|
||
void Button::OnPressDown(std::function<void()> callback) {
|
||
if (button_handle_ == nullptr) {
|
||
return;
|
||
}
|
||
on_press_down_ = callback;
|
||
iot_button_register_cb(button_handle_, BUTTON_PRESS_DOWN, [](void* handle, void* usr_data) {
|
||
Button* button = static_cast<Button*>(usr_data);
|
||
if (button->on_press_down_) {
|
||
button->on_press_down_();
|
||
}
|
||
}, this);
|
||
}
|
||
|
||
void Button::OnPressUp(std::function<void()> callback) {
|
||
if (button_handle_ == nullptr) {
|
||
return;
|
||
}
|
||
on_press_up_ = callback;
|
||
iot_button_register_cb(button_handle_, BUTTON_PRESS_UP, [](void* handle, void* usr_data) {
|
||
Button* button = static_cast<Button*>(usr_data);
|
||
if (button->on_press_up_) {
|
||
button->on_press_up_();
|
||
}
|
||
}, this);
|
||
}
|
||
|
||
void Button::OnLongPress(std::function<void()> callback) {
|
||
if (button_handle_ == nullptr) {
|
||
return;
|
||
}
|
||
on_long_press_ = callback;
|
||
iot_button_register_cb(button_handle_, BUTTON_LONG_PRESS_START, [](void* handle, void* usr_data) {
|
||
Button* button = static_cast<Button*>(usr_data);
|
||
if (button->on_long_press_) {
|
||
button->on_long_press_();
|
||
}
|
||
}, this);
|
||
}
|
||
|
||
void Button::OnClick(std::function<void()> callback) {
|
||
if (button_handle_ == nullptr) {
|
||
return;
|
||
}
|
||
on_click_ = callback;
|
||
iot_button_register_cb(button_handle_, BUTTON_SINGLE_CLICK, [](void* handle, void* usr_data) {
|
||
Button* button = static_cast<Button*>(usr_data);
|
||
if (button->on_click_) {
|
||
button->on_click_();
|
||
}
|
||
}, this);
|
||
}
|
||
|
||
void Button::OnDoubleClick(std::function<void()> callback) {
|
||
if (button_handle_ == nullptr) {
|
||
return;
|
||
}
|
||
on_double_click_ = callback;
|
||
iot_button_register_cb(button_handle_, BUTTON_DOUBLE_CLICK, [](void* handle, void* usr_data) {
|
||
Button* button = static_cast<Button*>(usr_data);
|
||
if (button->on_double_click_) {
|
||
button->on_double_click_();
|
||
}
|
||
}, this);
|
||
}
|