这是一次长久的提交:
1. 应用界面增加了返回主页的按钮 2. 修复了gif渲染内存泄漏的严重bug 3. 将PetDao当中的cJSON API替换为cpp_json,完美通过测试 4. 整合已经实现的各种上层建筑,实现了一个宠物对话基本业务应用,用于样品测试展示用 5. 重构了音频播放类,使其更modern,更加便于移植和拓展
This commit is contained in:
@@ -303,7 +303,7 @@ void WebSocketManager::heartbeatThread() {
|
|||||||
if (connected && config.heartbeat_interval > 0) { // 如果处于连接状态且心跳间隔大于0
|
if (connected && config.heartbeat_interval > 0) { // 如果处于连接状态且心跳间隔大于0
|
||||||
// 发送心跳消息
|
// 发送心跳消息
|
||||||
cppjson::Json hb = cppjson::Json::object();
|
cppjson::Json hb = cppjson::Json::object();
|
||||||
hb.set("type", cppjson::Json("heartbeat"))
|
hb.set("type", cppjson::Json("ping"))
|
||||||
.set("timestamp", cppjson::Json(esp_log_timestamp()));
|
.set("timestamp", cppjson::Json(esp_log_timestamp()));
|
||||||
sendJson(hb); // 已经重载好了,直接塞
|
sendJson(hb); // 已经重载好了,直接塞
|
||||||
|
|
||||||
|
|||||||
+174
-438
@@ -4,217 +4,20 @@
|
|||||||
#include "CppHandle.h"
|
#include "CppHandle.h"
|
||||||
|
|
||||||
#include "OTAClass.h"
|
#include "OTAClass.h"
|
||||||
#include "PetBaseClass.h"
|
|
||||||
#include "PetDao.h"
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <mbedtls/base64.h>
|
||||||
void testPetSystem() {
|
|
||||||
std::cout << "Test point1" << std::endl;
|
|
||||||
// 创建阶段策略
|
|
||||||
auto stageStrategy = std::make_unique<PetStageStrategy>();
|
|
||||||
stageStrategy->addStage(PetStageType::PET_STAGE_YOUNG, "models/young.obj");
|
|
||||||
stageStrategy->addStage(PetStageType::PET_STAGE_ADULT, "models/adult.obj");
|
|
||||||
stageStrategy->addStage(PetStageType::PET_STAGE_OLD, "models/old.obj");
|
|
||||||
stageStrategy->addStageAudio(PetStageType::PET_STAGE_YOUNG, "audio/young.mp3");
|
|
||||||
stageStrategy->addStageAudio(PetStageType::PET_STAGE_ADULT, "audio/adult.mp3");
|
|
||||||
stageStrategy->addStageAudio(PetStageType::PET_STAGE_OLD, "audio/old.mp3");
|
|
||||||
|
|
||||||
// 创建动作策略
|
|
||||||
auto actionStrategy = std::make_unique<PetActionStrategy>();
|
|
||||||
actionStrategy->addAction(PetActionType::PET_ACTION_EAT, "models/eat.obj");
|
|
||||||
actionStrategy->addAction(PetActionType::PET_ACTION_HAPPY, "models/happy.obj");
|
|
||||||
actionStrategy->addAction(PetActionType::PET_ACTION_SLEEP, "models/sleep.obj");
|
|
||||||
actionStrategy->addAction(PetActionType::PET_ACTION_ANGRY, "models/angry.obj");
|
|
||||||
actionStrategy->addAction(PetActionType::PET_ACTION_SAD, "models/sad.obj");
|
|
||||||
actionStrategy->addAction(PetActionType::PET_ACTION_EVOLVE, "models/evolve.obj");
|
|
||||||
actionStrategy->addAction(PetActionType::PET_ACTION_TOUCH, "models/touch.obj");
|
|
||||||
|
|
||||||
actionStrategy->addActionAudio(PetActionType::PET_ACTION_EAT, "audio/eat.mp3");
|
|
||||||
actionStrategy->addActionAudio(PetActionType::PET_ACTION_HAPPY, "audio/happy.mp3");
|
|
||||||
actionStrategy->addActionAudio(PetActionType::PET_ACTION_SLEEP, "audio/sleep.mp3");
|
|
||||||
std::cout << "Test point2" << std::endl;
|
|
||||||
|
|
||||||
// 创建宠物信息
|
|
||||||
PetBaseInfo info;
|
|
||||||
info.pet_name = "芝士雪豹";
|
|
||||||
info.pet_hp = 100;
|
|
||||||
info.pet_density = 50;
|
|
||||||
info.pet_identity = "我是顶真";
|
|
||||||
|
|
||||||
// 创建宠物
|
|
||||||
auto pet = std::make_shared<PetBase>(info, std::move(stageStrategy), std::move(actionStrategy));
|
|
||||||
std::cout << "Test point3" << std::endl;
|
|
||||||
|
|
||||||
// 创建音频观察者
|
|
||||||
auto audioStrategy = std::make_shared<PetAudioStrategy>();
|
|
||||||
audioStrategy->setAudioCallback([](const std::string& audioPath) {
|
|
||||||
std::cout << "Playing audio: " << audioPath << std::endl;
|
|
||||||
});
|
|
||||||
audioStrategy->subscribe(pet);
|
|
||||||
std::cout << "Test point4" << std::endl;
|
|
||||||
|
|
||||||
// 创建渲染器观察者
|
|
||||||
auto rendererStrategy = std::make_shared<PetRendererStrategy>(
|
|
||||||
pet->getStageStrategy(),
|
|
||||||
pet->getActionStrategy()
|
|
||||||
);
|
|
||||||
rendererStrategy->setRenderCallback([](const std::string& modelPath) {
|
|
||||||
std::cout << "Rendering model: " << modelPath << std::endl;
|
|
||||||
});
|
|
||||||
rendererStrategy->subscribe(pet);
|
|
||||||
std::cout << "Test point5" << std::endl;
|
|
||||||
|
|
||||||
// 执行一些动作
|
|
||||||
std::cout << "=== Testing basic actions ===" << std::endl;
|
|
||||||
pet->feed();
|
|
||||||
pet->play();
|
|
||||||
pet->touch();
|
|
||||||
std::cout << "Test point6" << std::endl;
|
|
||||||
|
|
||||||
// 检查当前状态
|
|
||||||
std::cout << "Current HP: " << pet->getPetInfo().pet_hp << std::endl;
|
|
||||||
std::cout << "Current density: " << pet->getPetInfo().pet_density << std::endl;
|
|
||||||
std::cout << "Current stage: " << static_cast<int>(pet->getCurrentStage()) << std::endl;
|
|
||||||
std::cout << "Current action: " << static_cast<int>(pet->getCurrentAction()) << std::endl;
|
|
||||||
std::cout << "Test point7" << std::endl;
|
|
||||||
|
|
||||||
// 测试进化
|
|
||||||
std::cout << "\n=== Testing evolution ===" << std::endl;
|
|
||||||
// 直接修改亲密度来测试进化
|
|
||||||
PetBaseInfo newInfo = pet->getPetInfo();
|
|
||||||
newInfo.pet_density = 100; // 达到进化条件
|
|
||||||
pet->setPetInfo(newInfo);
|
|
||||||
std::cout << "Test point8" << std::endl;
|
|
||||||
|
|
||||||
if (pet->checkEvolution()) {
|
|
||||||
std::cout << "Evolution successful!" << std::endl;
|
|
||||||
} else {
|
|
||||||
std::cout << "Evolution failed!" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 进一步增加亲密度到150,尝试再次进化
|
|
||||||
newInfo.pet_density = 150;
|
|
||||||
pet->setPetInfo(newInfo);
|
|
||||||
if (pet->checkEvolution()) {
|
|
||||||
std::cout << "Second evolution successful!" << std::endl;
|
|
||||||
} else {
|
|
||||||
std::cout << "Second evolution failed!" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "Final stage: " << static_cast<int>(pet->getCurrentStage()) << std::endl;
|
|
||||||
|
|
||||||
PetDAO petDAO(SDFileManager::getInstance());
|
|
||||||
petDAO.savePet(pet, "my_pet.json");
|
|
||||||
// 列出所有宠物文件
|
|
||||||
auto petFiles = petDAO.listPetFiles();
|
|
||||||
for (const auto& file : petFiles) {
|
|
||||||
std::cout << "Pet file: " << file << std::endl;
|
|
||||||
}
|
|
||||||
std::cout << SDFileManager::getInstance()->catCommand("/sdcard/pet_data/my_pet.json") << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#include "SpeechRecognizer.h"
|
|
||||||
#include <nvs.h>
|
|
||||||
#include <nvs_flash.h>
|
|
||||||
// 命令回调函数
|
|
||||||
void commandCallback(int command_id, const std::string& phrase, float probability) {
|
|
||||||
ESP_LOGI("Example", "Received command: ID=%d, Phrase='%s', Probability=%.2f",
|
|
||||||
command_id, phrase.c_str(), probability);
|
|
||||||
|
|
||||||
// 根据命令执行相应操作
|
|
||||||
switch (command_id) {
|
|
||||||
case 0:
|
|
||||||
ESP_LOGI("Example", "执行命令0");
|
|
||||||
// 执行命令0的操作
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
ESP_LOGI("Example", "执行命令1");
|
|
||||||
// 执行命令1的操作
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
ESP_LOGI("Example", "执行命令2");
|
|
||||||
// 执行命令2的操作
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ESP_LOGI("Example", "未知的命令ID: %d", command_id);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 状态回调函数
|
|
||||||
void stateCallback(const std::string& state) {
|
|
||||||
ESP_LOGI("Example", "状态改变到: %s", state.c_str());
|
|
||||||
}
|
|
||||||
#include "SDFileManager.h"
|
|
||||||
void testMIC() {
|
|
||||||
// 初始化NVS
|
|
||||||
esp_err_t ret = nvs_flash_init();
|
|
||||||
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
|
||||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
|
||||||
ret = nvs_flash_init();
|
|
||||||
}
|
|
||||||
ESP_ERROR_CHECK(ret);
|
|
||||||
|
|
||||||
// 初始化SD卡管理器
|
|
||||||
SDFileManager::getInstance()->tryInitSDCard();
|
|
||||||
|
|
||||||
// 获取SpeechRecognizer实例
|
|
||||||
SpeechRecognizer* recognizer = SpeechRecognizer::getInstance();
|
|
||||||
|
|
||||||
// 配置识别器
|
|
||||||
SpeechRecognizerConfig config;
|
|
||||||
config.enable_vad = true;
|
|
||||||
config.vad_mode = VAD_MODE_3; // 更高的VAD灵敏度
|
|
||||||
config.model_path = "/sdcard/srmodels";
|
|
||||||
|
|
||||||
// 初始化
|
|
||||||
if (!recognizer->init(config)) {
|
|
||||||
ESP_LOGE("main", "Failed to initialize speech recognizer");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加自定义命令
|
|
||||||
std::vector<std::pair<int, std::string>> commands = {
|
|
||||||
{0, "kai deng"}, // 开灯
|
|
||||||
{1, "guan deng"}, // 关灯
|
|
||||||
{2, "ti gao liang du"}, // 提高亮度
|
|
||||||
{3, "jiang di liang du"}, // 降低亮度
|
|
||||||
{4, "bo fang yin yue"}, // 播放音乐
|
|
||||||
{5, "ting zhi bo fang"} // 停止播放
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!recognizer->addCommands(commands)) {
|
|
||||||
ESP_LOGE("main", "Failed to add some commands");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 注册回调函数
|
|
||||||
recognizer->registerCommandCallback(commandCallback);
|
|
||||||
recognizer->registerStateCallback(stateCallback);
|
|
||||||
|
|
||||||
// 开始识别
|
|
||||||
if (!recognizer->start()) {
|
|
||||||
ESP_LOGE("main", "Failed to start speech recognition");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ESP_LOGI("main", "Speech recognition system started successfully");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#include "ToolsClass.h"
|
#include "ToolsClass.h"
|
||||||
#include "WifiConnectors.h"
|
#include "WifiConnectors.h"
|
||||||
#include "CommClass.h"
|
#include "CommClass.h"
|
||||||
#include "sys_conf_singleton.h"
|
#include "sys_conf_singleton.h"
|
||||||
#include "HttpOtaUpdater.h"
|
#include "HttpOtaUpdater.h"
|
||||||
using namespace std::chrono;
|
#include "AudioOutput.h"
|
||||||
const auto sleep_time = seconds{
|
|
||||||
5
|
|
||||||
};
|
|
||||||
// OTA相关
|
// OTA相关
|
||||||
HttpOtaUpdater otaUpdater;
|
HttpOtaUpdater otaUpdater;
|
||||||
|
|
||||||
void setupOtaCallbacks() {
|
void setupOtaCallbacks() {
|
||||||
// 设置进度回调
|
// 设置进度回调
|
||||||
otaUpdater.setProgressCallback([](int progress, int total) {
|
otaUpdater.setProgressCallback([](int progress, int total) {
|
||||||
@@ -222,15 +25,15 @@ void setupOtaCallbacks() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 设置状态回调
|
// 设置状态回调
|
||||||
otaUpdater.setStateCallback([](HttpOtaUpdater::OtaState state, const std::string& message) {
|
otaUpdater.setStateCallback([](HttpOtaUpdater::OtaState state, const std::string &message) {
|
||||||
const char* stateNames[] = {
|
const char *stateNames[] = {
|
||||||
"IDLE", "CONNECTING", "DOWNLOADING", "VERIFYING", "SUCCESS", "FAILED"
|
"IDLE", "CONNECTING", "DOWNLOADING", "VERIFYING", "SUCCESS", "FAILED"
|
||||||
};
|
};
|
||||||
ESP_LOGI("OTA", "State: %s - %s", stateNames[static_cast<int>(state)], message.c_str());
|
ESP_LOGI("OTA", "State: %s - %s", stateNames[static_cast<int>(state)], message.c_str());
|
||||||
});
|
});
|
||||||
|
|
||||||
// 设置完成回调
|
// 设置完成回调
|
||||||
otaUpdater.setFinishCallback([](bool success, const std::string& message) {
|
otaUpdater.setFinishCallback([](bool success, const std::string &message) {
|
||||||
if (success) {
|
if (success) {
|
||||||
ESP_LOGI("OTA", "Completed successfully: %s", message.c_str());
|
ESP_LOGI("OTA", "Completed successfully: %s", message.c_str());
|
||||||
} else {
|
} else {
|
||||||
@@ -243,6 +46,55 @@ void setupOtaCallbacks() {
|
|||||||
// otaUpdater.skipCertCommonNameCheck(true); // 仅用于测试
|
// otaUpdater.skipCertCommonNameCheck(true); // 仅用于测试
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 把 HTTP 文件完整下载到 PSRAM,返回首地址和长度
|
||||||
|
uint8_t *download_to_psram(const char *url, size_t *out_len)
|
||||||
|
{
|
||||||
|
uint8_t *buf = nullptr;
|
||||||
|
size_t total = 0;
|
||||||
|
|
||||||
|
esp_http_client_config_t cfg = {
|
||||||
|
.url = url,
|
||||||
|
.timeout_ms = 10000,
|
||||||
|
.keep_alive_enable = true,
|
||||||
|
};
|
||||||
|
esp_http_client_handle_t client = esp_http_client_init(&cfg);
|
||||||
|
|
||||||
|
if (esp_http_client_open(client, 0) != ESP_OK) {
|
||||||
|
ESP_LOGE("HTTP", "Failed to open HTTP connection");
|
||||||
|
}
|
||||||
|
int content_len = esp_http_client_fetch_headers(client);
|
||||||
|
if (content_len <= 0) {
|
||||||
|
ESP_LOGE("HTTP", "Content-Length invalid");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
buf = (uint8_t *)heap_caps_malloc(content_len, MALLOC_CAP_SPIRAM);
|
||||||
|
if (!buf) {
|
||||||
|
ESP_LOGE("HTTP", "PSRAM malloc %d bytes failed", content_len);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int read;
|
||||||
|
do {
|
||||||
|
read = esp_http_client_read(client, (char *)buf + total, content_len - total);
|
||||||
|
if (read > 0) total += read;
|
||||||
|
} while (read > 0 && total < content_len);
|
||||||
|
|
||||||
|
if (total != content_len) {
|
||||||
|
ESP_LOGE("HTTP", "Download incomplete %d/%d", total, content_len);
|
||||||
|
heap_caps_free(buf);
|
||||||
|
buf = nullptr;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
*out_len = total;
|
||||||
|
ESP_LOGI("HTTP", "Download done, %d bytes in PSRAM", total);
|
||||||
|
|
||||||
|
err:
|
||||||
|
esp_http_client_close(client);
|
||||||
|
esp_http_client_cleanup(client);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
// JSON 数据回调函数
|
// JSON 数据回调函数
|
||||||
/** 交互所使用的json内容
|
/** 交互所使用的json内容
|
||||||
{
|
{
|
||||||
@@ -250,14 +102,14 @@ void setupOtaCallbacks() {
|
|||||||
"xxx":"xxx", // 其他数据
|
"xxx":"xxx", // 其他数据
|
||||||
......
|
......
|
||||||
}
|
}
|
||||||
|
此回调函数为核心业务处理函数!!!
|
||||||
*/
|
*/
|
||||||
void onJsonData(const cppjson::Json& json)
|
void onJsonData(const cppjson::Json &json) {
|
||||||
{
|
|
||||||
// 打印收到的 JSON
|
// 打印收到的 JSON
|
||||||
ESP_LOGI("JSON_CALLBACK", "收到JSON数据: %s", json.dump().c_str());
|
ESP_LOGI("JSON_CALLBACK", "收到JSON数据: %s", json.dump().c_str());
|
||||||
|
|
||||||
// 解析消息类型
|
// 解析消息类型
|
||||||
const cppjson::Json& type = json["type"];
|
const cppjson::Json &type = json["type"];
|
||||||
if (!type.isString()) return;
|
if (!type.isString()) return;
|
||||||
|
|
||||||
std::string typeStr = type.asString();
|
std::string typeStr = type.asString();
|
||||||
@@ -276,11 +128,11 @@ void onJsonData(const cppjson::Json& json)
|
|||||||
ESP_LOGI("JSON_CALLBACK", "收到OTA消息");
|
ESP_LOGI("JSON_CALLBACK", "收到OTA消息");
|
||||||
// 进一步处理OTA消息
|
// 进一步处理OTA消息
|
||||||
// 获取OTA中的版本信息
|
// 获取OTA中的版本信息
|
||||||
const cppjson::Json& version = json["version"];
|
const cppjson::Json &version = json["version"];
|
||||||
if (!version.isString()) return;
|
if (!version.isString()) return;
|
||||||
std::string versionStr = version.asString();
|
std::string versionStr = version.asString();
|
||||||
// 获取OTA中的HTTP URL
|
// 获取OTA中的HTTP URL
|
||||||
const cppjson::Json& url = json["url"];
|
const cppjson::Json &url = json["url"];
|
||||||
if (!url.isString()) return;
|
if (!url.isString()) return;
|
||||||
std::string urlStr = url.asString();
|
std::string urlStr = url.asString();
|
||||||
// 告诉服务端,升级开始
|
// 告诉服务端,升级开始
|
||||||
@@ -288,12 +140,25 @@ void onJsonData(const cppjson::Json& json)
|
|||||||
response.set("type", cppjson::Json("ota_start"));
|
response.set("type", cppjson::Json("ota_start"));
|
||||||
WebSocketManager::getInstance()->sendJson(response);
|
WebSocketManager::getInstance()->sendJson(response);
|
||||||
otaUpdater.start(urlStr);
|
otaUpdater.start(urlStr);
|
||||||
|
} else if (typeStr == "audio") {
|
||||||
|
ESP_LOGI("JSON_CALLBACK", "收到音频消息");
|
||||||
|
// 进一步解析音频消息内容
|
||||||
|
// 获取音频信息
|
||||||
|
cppjson::Json audio_url = json["audio_url"]; // 音频信息
|
||||||
|
cppjson::Json audio_size = json["audio_size"]; // 音频信息
|
||||||
|
if (!audio_url.isObject()) return;
|
||||||
|
if (!audio_size.isObject()) return;
|
||||||
|
std::cout << "base64: " << audio_url.asString() << std::endl;
|
||||||
|
std::cout << "size: " << audio_size.asInt() << std::endl;
|
||||||
|
size_t size;
|
||||||
|
const uint8_t *pcm_buf = download_to_psram(audio_url.asString().c_str(), &size);
|
||||||
|
// 播放音频
|
||||||
|
AudioOutput::getInstance()->playPcmStream(pcm_buf, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// WebSocket事件回调函数
|
// WebSocket事件回调函数
|
||||||
void onWebSocketEvent(WebSocketEvent event, const std::string& message) {
|
void onWebSocketEvent(WebSocketEvent event, const std::string &message) {
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case WebSocketEvent::CONNECTED:
|
case WebSocketEvent::CONNECTED:
|
||||||
ESP_LOGI("EVENT_CALLBACK", "WebSocket已连接: %s", message.c_str());
|
ESP_LOGI("EVENT_CALLBACK", "WebSocket已连接: %s", message.c_str());
|
||||||
@@ -311,8 +176,7 @@ void onWebSocketEvent(WebSocketEvent event, const std::string& message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 发送状态信息函数
|
// 发送状态信息函数
|
||||||
void sendStatus()
|
void sendStatus() {
|
||||||
{
|
|
||||||
cppjson::Json status = cppjson::Json::object();
|
cppjson::Json status = cppjson::Json::object();
|
||||||
status.set("type", cppjson::Json("status"));
|
status.set("type", cppjson::Json("status"));
|
||||||
|
|
||||||
@@ -330,8 +194,7 @@ void sendStatus()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 发送问候消息函数
|
// 发送问候消息函数
|
||||||
void sendGreeting()
|
void sendGreeting() {
|
||||||
{
|
|
||||||
cppjson::Json greeting = cppjson::Json::object();
|
cppjson::Json greeting = cppjson::Json::object();
|
||||||
greeting.set("type", cppjson::Json("greeting"))
|
greeting.set("type", cppjson::Json("greeting"))
|
||||||
.set("message", cppjson::Json("Hello from ESP32-S3"))
|
.set("message", cppjson::Json("Hello from ESP32-S3"))
|
||||||
@@ -343,6 +206,7 @@ void sendGreeting()
|
|||||||
ESP_LOGE("SEND", "发送问候消息失败");
|
ESP_LOGE("SEND", "发送问候消息失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void websocket_task() {
|
void websocket_task() {
|
||||||
TickType_t lastStatusTime = 0;
|
TickType_t lastStatusTime = 0;
|
||||||
TickType_t lastHeartbeatTime = 0;
|
TickType_t lastHeartbeatTime = 0;
|
||||||
@@ -392,7 +256,8 @@ void createWebSocket() {
|
|||||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||||
}
|
}
|
||||||
// 保存SN
|
// 保存SN
|
||||||
SysConfJson::getInstance()->saveSN(ToolsClass::GenerateSN(ToolsClass::getChipMAC(), ToolsClass::getChipSerialNumber()));
|
SysConfJson::getInstance()->saveSN(
|
||||||
|
ToolsClass::GenerateSN(ToolsClass::getChipMAC(), ToolsClass::getChipSerialNumber()));
|
||||||
// 读取SN
|
// 读取SN
|
||||||
std::string sn = SysConfJson::getInstance()->loadSN();
|
std::string sn = SysConfJson::getInstance()->loadSN();
|
||||||
ESP_LOGI("conf", "loaded sn = %s", sn.c_str());
|
ESP_LOGI("conf", "loaded sn = %s", sn.c_str());
|
||||||
@@ -408,7 +273,7 @@ void createWebSocket() {
|
|||||||
// 初始化WebSocket管理器
|
// 初始化WebSocket管理器
|
||||||
if (!WebSocketManager::getInstance()->initialize(config)) {
|
if (!WebSocketManager::getInstance()->initialize(config)) {
|
||||||
ESP_LOGE("APP_TASK", "WebSocket管理器初始化失败");
|
ESP_LOGE("APP_TASK", "WebSocket管理器初始化失败");
|
||||||
vTaskDelete(NULL);
|
vTaskDelete(nullptr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -432,248 +297,120 @@ void createWebSocket() {
|
|||||||
std::thread websocket_thread = ThreadManager::createThread(websocket_config, websocket_task);
|
std::thread websocket_thread = ThreadManager::createThread(websocket_config, websocket_task);
|
||||||
websocket_thread.detach();
|
websocket_thread.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "LVGLRender.h"
|
#include "LVGLRender.h"
|
||||||
#include <lvgl.h>
|
#include "SimpleI2SForwarder.h"
|
||||||
#define TAG "BIN_TEST"
|
|
||||||
|
|
||||||
/* 从 SD 卡读任意 .bin 到堆 → 直接显示 */
|
|
||||||
void test_show_bin(const char* fileName)
|
|
||||||
{
|
|
||||||
ESP_LOGI(TAG, "=== fast bin test: %s ===", fileName);
|
|
||||||
|
|
||||||
/* 1. 读文件 */
|
|
||||||
std::string path = "/sdcard/" + std::string(fileName);
|
|
||||||
std::string data = SDFileManager::getInstance()->readFileSync(path.c_str());
|
|
||||||
if (data.empty()) {
|
|
||||||
ESP_LOGE(TAG, "read fail");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
size_t sz = data.size();
|
|
||||||
ESP_LOGI(TAG, "file size = %zu", sz);
|
|
||||||
ESP_LOG_BUFFER_HEX(TAG, data.data(), 16); // 头 16 字节
|
|
||||||
|
|
||||||
/* 2. 拷到堆(LVGL 长期持有)*/
|
|
||||||
void* buf = heap_caps_malloc(sz, MALLOC_CAP_8BIT);
|
|
||||||
memcpy(buf, data.data(), sz);
|
|
||||||
|
|
||||||
/* 3. 离线量好的尺寸(先填 320×240 测试,不对再改)*/
|
|
||||||
uint32_t w = 720;
|
|
||||||
uint32_t h = 720;
|
|
||||||
if (sz != w * h * 2) { // RGB565 每像素 2 字节
|
|
||||||
ESP_LOGW(TAG, "size mismatch, expect %ld, got %zu", w * h * 2, sz);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 4. 一次性描述符 */
|
|
||||||
static lv_img_dsc_t dsc;
|
|
||||||
dsc.data = static_cast<const uint8_t *>(buf);
|
|
||||||
dsc.header.cf = LV_IMG_CF_TRUE_COLOR;
|
|
||||||
dsc.header.w = w;
|
|
||||||
dsc.header.h = h;
|
|
||||||
dsc.data_size = sz;
|
|
||||||
|
|
||||||
/* 5. 直接显示(不经过 PNG 解码器)*/
|
|
||||||
lv_obj_t* img = lv_img_create(lv_scr_act());
|
|
||||||
lv_img_set_src(img, &dsc);
|
|
||||||
lv_obj_center(img);
|
|
||||||
|
|
||||||
ESP_LOGI(TAG, "bin displayed, w=%ld h=%ld", w, h);
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "lvpp.h"
|
#include "lvpp.h"
|
||||||
|
#include "BaseApp.h"
|
||||||
LV_FONT_DECLARE(SiYuanHeiTiGoogleBan);
|
LV_FONT_DECLARE(SiYuanHeiTiGoogleBan);
|
||||||
// 使用全局智能指针管理主要对象
|
// 使用全局智能指针管理主要对象
|
||||||
static std::shared_ptr<lvgl_cpp::Screen> g_screen;
|
static std::shared_ptr<lvgl_cpp::Screen> g_screen;
|
||||||
using namespace lvgl_cpp;
|
static std::shared_ptr<lvgl_cpp::HomePage> g_home;
|
||||||
struct AppCalc : BaseApp {
|
static std::shared_ptr<lvgl_cpp::AppMenu> g_menu;
|
||||||
using BaseApp::BaseApp;
|
|
||||||
void onShow() override {
|
int pet_Test() {
|
||||||
Label(*this).text("Calculator").center();
|
/*
|
||||||
|
// 存档
|
||||||
|
PetDAO dao(SDFileManager::getInstance());
|
||||||
|
const string filename = "cheese_snow_leopard.json";
|
||||||
|
cout << "\n===== 存档 =====" << endl;
|
||||||
|
if (dao.savePet(pet, filename))
|
||||||
|
cout << "✅ 已保存到 " << filename << endl;
|
||||||
|
else
|
||||||
|
cout << "❌ 保存失败" << endl;
|
||||||
|
|
||||||
|
// 5. 读档
|
||||||
|
cout << "\n===== 读档 =====" << endl;
|
||||||
|
auto loaded = dao.loadPet(filename);
|
||||||
|
if (!loaded) {
|
||||||
|
cout << "❌ 读档失败" << endl;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
cout << "✅ 读档成功,继续互动:" << endl;
|
||||||
struct AppMusic : BaseApp {
|
printPet(*loaded);
|
||||||
using BaseApp::BaseApp;
|
|
||||||
void onShow() override {
|
|
||||||
btn_.emplace(*this);
|
|
||||||
gif.emplace(*this);
|
|
||||||
btn_->size(180, 60)
|
|
||||||
.align(LV_ALIGN_CENTER, nullptr, 0, 80)
|
|
||||||
.on(LV_EVENT_CLICKED, [&](lv_event_t*) {
|
|
||||||
/* 居中 GIF,背景黑 */
|
|
||||||
lv_obj_set_style_bg_color(this->raw(), lv_color_black(), 0);
|
|
||||||
lv_obj_set_style_bg_opa(this->raw(), LV_OPA_COVER, 0);
|
|
||||||
gif->src("small_-min.gif")
|
|
||||||
.center();
|
|
||||||
});
|
|
||||||
|
|
||||||
/* 按钮文字 */
|
// 6. 对新对象继续互动
|
||||||
lv_obj_t* label = lv_label_create(btn_->raw());
|
loaded->neglect(); printPet(*loaded);
|
||||||
lv_obj_set_style_text_font(label, &SiYuanHeiTiGoogleBan, LV_PART_MAIN);
|
loaded->feed(); printPet(*loaded);
|
||||||
lv_label_set_text(label, "Gif测试");
|
*/
|
||||||
lv_obj_center(label);
|
return 1;
|
||||||
}
|
}
|
||||||
private:
|
|
||||||
std::optional<lvgl_cpp::Button> btn_; // c++17 轻量 RAII
|
|
||||||
std::optional<lvgl_cpp::Gif> gif;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ButtonApp : public BaseApp {
|
|
||||||
public:
|
|
||||||
using BaseApp::BaseApp; // 继承 exit 按钮机制
|
|
||||||
|
|
||||||
void onShow() override {
|
|
||||||
/* 居中按钮:180×60 px,圆角,现代蓝 */
|
|
||||||
btn_.emplace(*this);
|
|
||||||
btn_->size(180, 60)
|
|
||||||
.align(LV_ALIGN_CENTER, nullptr, 0, 80)
|
|
||||||
.on(LV_EVENT_CLICKED, [](lv_event_t*) {
|
|
||||||
lvgl_cpp::Toast::show("咕咕嘎嘎!",
|
|
||||||
lvgl_cpp::Toast::Type::INFO,
|
|
||||||
1000);
|
|
||||||
});
|
|
||||||
LV_FONT_DECLARE(SiYuanHeiTiGoogleBan);
|
|
||||||
/* 按钮文字 */
|
|
||||||
lv_obj_t* label = lv_label_create(btn_->raw());
|
|
||||||
lv_obj_set_style_text_font(label, &SiYuanHeiTiGoogleBan, LV_PART_MAIN);
|
|
||||||
lv_label_set_text(label, "按我");
|
|
||||||
lv_obj_center(label);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::optional<lvgl_cpp::Button> btn_; // c++17 轻量 RAII
|
|
||||||
};
|
|
||||||
static std::shared_ptr<HomePage> g_home;
|
|
||||||
static std::shared_ptr<AppMenu> g_menu;
|
|
||||||
void Cpp_Hand() {
|
void Cpp_Hand() {
|
||||||
// testMIC();
|
// 打印设备信息
|
||||||
// testPetSystem();
|
ESP_LOGI("CppHandle::Cpp_Hand", "当前固件版本 %s:", ToolsClass::getDeviceVersion().c_str());
|
||||||
SDFileManager::getInstance()->tryInitSDCard();
|
ESP_LOGI("CppHandle::Cpp_Hand", "当前设备MAC地址 %s:", ToolsClass::getChipMAC().c_str());
|
||||||
|
ESP_LOGI("CppHandle::Cpp_Hand", "当前设备固件序列号 %s:", ToolsClass::getChipSerialNumber().c_str());
|
||||||
|
|
||||||
|
SDFileManager::getInstance()->tryInitSDCard(); // 初始化SD卡
|
||||||
LVGLRender::getInstance()->tryToInitRenderGif(); // 初始化lvgl驱动(包括任务循环)
|
LVGLRender::getInstance()->tryToInitRenderGif(); // 初始化lvgl驱动(包括任务循环)
|
||||||
LVGLRender::setFps(60); // 设置lvgl刷新频率
|
LVGLRender::setFps(60); // 设置lvgl刷新频率
|
||||||
|
|
||||||
/* LVGL 已经初始化,屏幕驱动已注册 */
|
// 创建屏幕
|
||||||
// auto scr = lvgl_cpp::Screen{}; // RAII,离开作用域自动 del
|
|
||||||
// lv_scr_load(scr.raw()); // 让 LVGL 把它当活动屏幕
|
|
||||||
|
|
||||||
// lvgl_cpp::Image img(scr);
|
|
||||||
// img.bin("pic_no_alp_swap.bin", 720, 720)
|
|
||||||
// .center();
|
|
||||||
//
|
|
||||||
// /* 1. 创建按钮 */
|
|
||||||
// /* 1. 黑色文字样式 */
|
|
||||||
// static lvgl_cpp::Style txt_style;
|
|
||||||
// txt_style.text_color(lv_color_black());
|
|
||||||
//
|
|
||||||
// /* 2. 按钮 */
|
|
||||||
// lvgl_cpp::Button btn{scr};
|
|
||||||
// btn.size(150, 60).pos(40, 40);
|
|
||||||
// /* 3. 先创建 Label 对象并保存,再链式调 */
|
|
||||||
// lvgl_cpp::Label lbl{btn}; // 一定要存实例
|
|
||||||
// lbl.text("Click Me")
|
|
||||||
// .add_style(&txt_style.s, LV_PART_MAIN); // 样式作用到文字本身
|
|
||||||
// /* 3. 注册点击事件 */
|
|
||||||
// btn.on(LV_EVENT_CLICKED, [](lv_event_t*){
|
|
||||||
// lvgl_cpp::Toast::show("Saved successfully !");
|
|
||||||
// /* 2. 警告,3 s,顶部 */
|
|
||||||
// lvgl_cpp::Toast::show("SD card missing", lvgl_cpp::Toast::Type::WARN, 3000, LV_ALIGN_TOP_MID, 20);
|
|
||||||
//
|
|
||||||
// /* 3. 错误,1.5 s,底部右侧 */
|
|
||||||
// lvgl_cpp::Toast::show("Network error", lvgl_cpp::Toast::Type::ERROR, 1500, LV_ALIGN_BOTTOM_RIGHT, -30);
|
|
||||||
// ESP_LOGI("BTN", "pressed");
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// /* 1. 消息框 */
|
|
||||||
// // const char* btns[] = {"Yes", "No", ""};
|
|
||||||
// // auto mbox = lvgl_cpp::MsgBox::create("Hint", "Delete file ?", btns);
|
|
||||||
//
|
|
||||||
// /* 3. 进度条(双向 + 动画) */
|
|
||||||
// lvgl_cpp::Bar bar(scr);
|
|
||||||
// bar.range(0, 100)
|
|
||||||
// .start_value(20) // 左端
|
|
||||||
// .value(80, LV_ANIM_ON) // 右端带动画
|
|
||||||
// .anim_time(500)
|
|
||||||
// .size(200, 15)
|
|
||||||
// .align(LV_ALIGN_CENTER, nullptr, 0, 40);
|
|
||||||
//
|
|
||||||
// /* 4. 折线:画一个 △ */
|
|
||||||
// std::vector<lv_point_t> triangle = {{0,0}, {40,0}, {20,40}, {0,0}};
|
|
||||||
// lvgl_cpp::Line line(scr);
|
|
||||||
// line.points(triangle)
|
|
||||||
// .y_invert(false)
|
|
||||||
// .align(LV_ALIGN_CENTER, nullptr, 0, 100);
|
|
||||||
//
|
|
||||||
// lvgl_cpp::Battery bat(scr);
|
|
||||||
// bat.size(60, 30) // 手机经典尺寸
|
|
||||||
// .percent(true) // 显示 50%
|
|
||||||
// .onRead([]() -> uint8_t { // 替换成你的 ADC/INA219 回调
|
|
||||||
// static uint8_t v = 100;
|
|
||||||
// if (v) --v;
|
|
||||||
// return v;
|
|
||||||
// })
|
|
||||||
// .align(LV_ALIGN_TOP_RIGHT, -10, 10); // 九宫格对齐
|
|
||||||
//
|
|
||||||
// /* 3. 日期时间 */
|
|
||||||
// lvgl_cpp::DateTime dt(scr);
|
|
||||||
// dt.format("%m/%d %a %H:%M")
|
|
||||||
// .onRead([](char* buf, size_t len){
|
|
||||||
// /* 这里用 SNTP / RTC 填充,示例直接给假时间 */
|
|
||||||
// snprintf(buf, len, "06/25 Tue 14:30");
|
|
||||||
// })
|
|
||||||
// .align(LV_ALIGN_BOTTOM_MID, nullptr, 0, -10);
|
|
||||||
|
|
||||||
|
|
||||||
// lvgl_cpp::ColorPicker cp(scr);
|
|
||||||
// cp.size(120, 120)
|
|
||||||
// .align(LV_ALIGN_BOTTOM_MID, nullptr, 0, -20)
|
|
||||||
// .on(LV_EVENT_VALUE_CHANGED, [&](lv_event_t*){
|
|
||||||
// lv_color_t c = cp.color();
|
|
||||||
// ESP_LOGI("CP", "rgb=%d,%d,%d", c.ch.red, c.ch.green_h, c.ch.blue);
|
|
||||||
// });
|
|
||||||
|
|
||||||
// 1. 创建屏幕
|
|
||||||
g_screen = std::make_shared<lvgl_cpp::Screen>();
|
g_screen = std::make_shared<lvgl_cpp::Screen>();
|
||||||
lv_scr_load(g_screen->raw());
|
lv_scr_load(g_screen->raw());
|
||||||
|
|
||||||
// 2. 延迟创建界面组件
|
// 延迟创建界面组件
|
||||||
auto init_timer = std::make_unique<lvgl_cpp::Timer>([&]() {
|
auto init_timer = std::make_unique<lvgl_cpp::Timer>([&]() {
|
||||||
ESP_LOGI("MAIN", "Initializing UI components...");
|
ESP_LOGI("MAIN", "Initializing UI components...");
|
||||||
|
|
||||||
// 创建主页
|
// 创建主页
|
||||||
g_home = std::make_shared<HomePage>(*g_screen);
|
g_home = std::make_shared<lvgl_cpp::HomePage>(*g_screen);
|
||||||
g_home->bg("pic360.bin", 360, 360)
|
g_home->bg("pic360.bin", 360, 360)
|
||||||
.onBattery([]() -> uint8_t {
|
.onBattery([]() -> uint8_t {
|
||||||
static uint8_t v = 100;
|
return static_cast<uint8_t>(ToolsClass::getInstance()->getBatteryPer());
|
||||||
if (v) --v;
|
|
||||||
return 88;
|
|
||||||
})
|
})
|
||||||
.onDateTime([](char* buf, size_t len) {
|
.onDateTime([](char *buf, const size_t len) {
|
||||||
snprintf(buf, len, "06/25 Tue 14:30");
|
snprintf(buf, len, "06/25 Tue 14:30");
|
||||||
});
|
});
|
||||||
|
|
||||||
// 创建菜单
|
// 创建菜单
|
||||||
g_menu = std::make_shared<AppMenu>(*g_screen);
|
g_menu = std::make_shared<lvgl_cpp::AppMenu>(*g_screen);
|
||||||
g_menu->addItem("Calcu", 100, 50)
|
g_menu->addItem("Calcu", 100, 50)
|
||||||
.addItem("Gif测试", 100, 50)
|
.addItem("Gif测试", 100, 50)
|
||||||
.addItem("Button", 100, 50)
|
.addItem("Button", 100, 50)
|
||||||
.onClick([](const char* name) {
|
.addItem("AI测试", 100, 50)
|
||||||
|
.addItem("长按录音", 100, 50)
|
||||||
|
.addItem("宠物样例", 100, 50)
|
||||||
|
.onClick([](const char *name) {
|
||||||
ESP_LOGI("APP", "Launching: %s", name);
|
ESP_LOGI("APP", "Launching: %s", name);
|
||||||
|
// 让工厂创建子应用
|
||||||
/* 1. 让工厂创建子应用 */
|
auto app = lvgl_cpp::AppFactory::create(name, *g_screen);
|
||||||
auto app = AppFactory::create(name, *g_screen);
|
|
||||||
if (!app) return;
|
if (!app) return;
|
||||||
|
|
||||||
/* 2. 隐藏菜单,显示应用 */
|
// 隐藏菜单,显示应用
|
||||||
lv_obj_add_flag(g_menu->raw(), LV_OBJ_FLAG_HIDDEN);
|
lv_obj_add_flag(g_menu->raw(), LV_OBJ_FLAG_HIDDEN);
|
||||||
app->onShow();
|
app->onShow();
|
||||||
|
|
||||||
/* 3. 应用退出时回到菜单 */
|
// 应用退出时回到菜单
|
||||||
app->onExit([app_ptr = app.release()]() { // 转移所有权到 lambda
|
app->onExit([app_ptr = app.release()]() {
|
||||||
|
// 转移所有权到 lambda
|
||||||
lv_obj_clear_flag(g_menu->raw(), LV_OBJ_FLAG_HIDDEN);
|
lv_obj_clear_flag(g_menu->raw(), LV_OBJ_FLAG_HIDDEN);
|
||||||
lv_obj_del(app_ptr->raw()); // 自毁
|
lv_obj_del(app_ptr->raw()); // 自毁
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
g_menu->onBack([]() {
|
||||||
|
ESP_LOGI("AppMenu", "返回主页回调执行");
|
||||||
|
|
||||||
|
// 添加调试信息
|
||||||
|
if (g_menu && g_menu->raw()) {
|
||||||
|
ESP_LOGI("AppMenu", "隐藏菜单");
|
||||||
lv_obj_add_flag(g_menu->raw(), LV_OBJ_FLAG_HIDDEN);
|
lv_obj_add_flag(g_menu->raw(), LV_OBJ_FLAG_HIDDEN);
|
||||||
|
} else {
|
||||||
|
ESP_LOGE("AppMenu", "菜单对象无效");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_home && g_home->raw()) {
|
||||||
|
ESP_LOGI("AppMenu", "显示主页");
|
||||||
|
lv_obj_clear_flag(g_home->raw(), LV_OBJ_FLAG_HIDDEN);
|
||||||
|
} else {
|
||||||
|
ESP_LOGE("AppMenu", "主页对象无效");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 强制刷新显示
|
||||||
|
lv_refr_now(nullptr);
|
||||||
|
});
|
||||||
|
lv_obj_add_flag(g_menu->raw(), LV_OBJ_FLAG_HIDDEN);
|
||||||
// 安全的事件连接
|
// 安全的事件连接
|
||||||
g_home->onOpenMenu([]() {
|
g_home->onOpenMenu([]() {
|
||||||
if (g_home && g_menu) {
|
if (g_home && g_menu) {
|
||||||
@@ -681,44 +418,43 @@ void Cpp_Hand() {
|
|||||||
lv_obj_clear_flag(g_menu->raw(), LV_OBJ_FLAG_HIDDEN);
|
lv_obj_clear_flag(g_menu->raw(), LV_OBJ_FLAG_HIDDEN);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ESP_LOGI("MAIN", "UI initialization complete");
|
ESP_LOGI("MAIN", "UI initialization complete");
|
||||||
}, 1000, true); // 1秒后执行一次
|
}, 1000, true); // 1秒后执行一次
|
||||||
|
|
||||||
// 注册应用
|
// 注册应用
|
||||||
AppFactory::registerApp("Calcu", [](Obj& p) {
|
lvgl_cpp::AppFactory::registerApp("Calcu", [](lvgl_cpp::Obj &p) {
|
||||||
return std::make_unique<AppCalc>(p);
|
return std::make_unique<AppCalc>(p);
|
||||||
});
|
});
|
||||||
AppFactory::registerApp("Gif测试", [](Obj& p) {
|
lvgl_cpp::AppFactory::registerApp("Gif测试", [](lvgl_cpp::Obj &p) {
|
||||||
return std::make_unique<AppMusic>(p);
|
return std::make_unique<AppMusic>(p);
|
||||||
});
|
});
|
||||||
AppFactory::registerApp("Button", [](lvgl_cpp::Obj& p) {
|
lvgl_cpp::AppFactory::registerApp("Button", [](lvgl_cpp::Obj &p) {
|
||||||
return std::make_unique<ButtonApp>(p);
|
return std::make_unique<ButtonApp>(p);
|
||||||
});
|
});
|
||||||
|
lvgl_cpp::AppFactory::registerApp("AI测试", [](lvgl_cpp::Obj &p) {
|
||||||
// test_show_bin("pic_no_alp_swap.bin");
|
return std::make_unique<WebSocketVoice>(p);
|
||||||
|
});
|
||||||
// LVGLRender::getInstance()->RenderGif("sequence02mmm.gif");
|
lvgl_cpp::AppFactory::registerApp("长按录音", [](lvgl_cpp::Obj &p) {
|
||||||
|
return std::make_unique<LongPressButtonAnim>(p);
|
||||||
ESP_LOGI("CppHandle::Cpp_Hand", "当前固件版本 %s:", ToolsClass::getDeviceVersion().c_str());
|
});
|
||||||
|
lvgl_cpp::AppFactory::registerApp("宠物样例", [](lvgl_cpp::Obj &p) {
|
||||||
ESP_LOGI("CppHandle::Cpp_Hand", "当前设备MAC地址 %s:", ToolsClass::getChipMAC().c_str());
|
return std::make_unique<PetApp>(p);
|
||||||
ESP_LOGI("CppHandle::Cpp_Hand", "当前设备固件序列号 %s:", ToolsClass::getChipSerialNumber().c_str());
|
});
|
||||||
|
|
||||||
// 连接wifi
|
// 连接wifi
|
||||||
// WifiConnectors::getInstance()->connectWifi("Misaki-2.4G", "88888888", 5);
|
WifiConnectors::getInstance()->connectWifi("Misaki-2.4G", "88888888", 5);
|
||||||
|
|
||||||
// 创建WebSocket
|
// 创建WebSocket
|
||||||
// createWebSocket();
|
createWebSocket();
|
||||||
|
|
||||||
// 设置OTA回调
|
// 设置OTA回调
|
||||||
// setupOtaCallbacks();
|
// setupOtaCallbacks();
|
||||||
|
while (true) {
|
||||||
while (true) { // 主线程线程循环
|
// 主线程线程循环
|
||||||
// ThreadManager::print_sys_memory(); // 打印系统内存使用情况
|
ThreadManager::print_sys_memory(); // 打印系统内存使用情况
|
||||||
// ThreadManager::stats_task(); // 打印任务统计信息
|
// ThreadManager::stats_task(); // 打印任务统计信息
|
||||||
ESP_LOGI("APP_TASK", "Battery is:%ld", ToolsClass::getInstance()->getBatteryPer());
|
// ESP_LOGI("APP_TASK", "Battery is:%ld", ToolsClass::getInstance()->getBatteryPer());
|
||||||
ESP_LOGI("APP_TASK", "Battery is:%f", ToolsClass::getInstance()->getBatteryVolts());
|
// ESP_LOGI("APP_TASK", "Battery is:%f", ToolsClass::getInstance()->getBatteryVolts());
|
||||||
std::this_thread::sleep_for(sleep_time); // 休眠5秒
|
std::this_thread::sleep_for(std::chrono::seconds(1)); // 休眠 1 秒
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,27 +47,26 @@ PetDAO::PetDAO(SDFileManager* fileManager) : fileManager(fileManager) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool PetDAO::savePet(const std::shared_ptr<PetBase>& pet, const std::string& filename) {
|
bool PetDAO::savePet(const std::shared_ptr<PetBase>& pet, const std::string& filename) {
|
||||||
|
try {
|
||||||
// 转换为JSON
|
// 转换为JSON
|
||||||
cJSON* json = petToJson(pet);
|
cppjson::Json json = petToJson(pet);
|
||||||
if (!json) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 转换为字符串
|
// 序列化为字符串
|
||||||
char* jsonStr = cJSON_PrintUnformatted(json);
|
std::string jsonStr = json.dump();
|
||||||
std::string fullPath = std::string(PET_DATA_DIR) + "/" + filename;
|
std::string fullPath = std::string(PET_DATA_DIR) + "/" + filename;
|
||||||
|
|
||||||
// 保存到文件
|
// 保存到文件
|
||||||
bool success = fileManager->writeFileSync(fullPath.c_str(), jsonStr);
|
const bool success = fileManager->writeFileSync(fullPath.c_str(), jsonStr.c_str(), jsonStr.size(), "w");
|
||||||
|
|
||||||
// 清理资源
|
|
||||||
free(jsonStr);
|
|
||||||
cJSON_Delete(json);
|
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
std::cerr << "Save pet failed: " << e.what() << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<PetBase> PetDAO::loadPet(const std::string& filename) {
|
std::shared_ptr<PetBase> PetDAO::loadPet(const std::string& filename) {
|
||||||
|
try {
|
||||||
std::string fullPath = std::string(PET_DATA_DIR) + "/" + filename;
|
std::string fullPath = std::string(PET_DATA_DIR) + "/" + filename;
|
||||||
|
|
||||||
// 读取文件内容
|
// 读取文件内容
|
||||||
@@ -77,18 +76,14 @@ std::shared_ptr<PetBase> PetDAO::loadPet(const std::string& filename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 解析JSON
|
// 解析JSON
|
||||||
cJSON* json = cJSON_Parse(content.c_str());
|
cppjson::Json json = cppjson::Json::parse(content);
|
||||||
if (!json) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建宠物对象
|
// 创建宠物对象
|
||||||
auto pet = petFromJson(json);
|
return petFromJson(json);
|
||||||
|
} catch (const std::exception& e) {
|
||||||
// 清理资源
|
std::cerr << "Load pet failed: " << e.what() << std::endl;
|
||||||
cJSON_Delete(json);
|
return nullptr;
|
||||||
|
}
|
||||||
return pet;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> PetDAO::listPetFiles() {
|
std::vector<std::string> PetDAO::listPetFiles() {
|
||||||
@@ -100,204 +95,178 @@ bool PetDAO::deletePetFile(const std::string& filename) {
|
|||||||
return fileManager->rmCommand(fullPath.c_str(), false);
|
return fileManager->rmCommand(fullPath.c_str(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
cJSON* PetDAO::petToJson(const std::shared_ptr<PetBase>& pet) {
|
cppjson::Json PetDAO::petToJson(const std::shared_ptr<PetBase>& pet) {
|
||||||
cJSON* json = cJSON_CreateObject();
|
auto json = cppjson::Json::object();
|
||||||
if (!json) return nullptr;
|
|
||||||
|
|
||||||
// 添加基本信息
|
// 添加基本信息
|
||||||
cJSON_AddStringToObject(json, "name", pet->pet_info.pet_name.c_str());
|
json.set("name", cppjson::Json(pet->pet_info.pet_name))
|
||||||
cJSON_AddNumberToObject(json, "hp", pet->pet_info.pet_hp);
|
.set("hp", cppjson::Json(pet->pet_info.pet_hp))
|
||||||
cJSON_AddNumberToObject(json, "density", pet->pet_info.pet_density);
|
.set("density", cppjson::Json(pet->pet_info.pet_density))
|
||||||
cJSON_AddStringToObject(json, "identity", pet->pet_info.pet_identity.c_str());
|
.set("identity", cppjson::Json(pet->pet_info.pet_identity));
|
||||||
|
|
||||||
// 添加阶段策略
|
// 添加阶段策略
|
||||||
cJSON* stageJson = stageStrategyToJson(pet->pet_stage_strategy);
|
auto stageJson = stageStrategyToJson(pet->pet_stage_strategy);
|
||||||
if (stageJson) {
|
if (!stageJson.isNull()) {
|
||||||
cJSON_AddItemToObject(json, "stage_strategy", stageJson);
|
json.set("stage_strategy", stageJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加动作策略
|
// 添加动作策略
|
||||||
cJSON* actionJson = actionStrategyToJson(pet->pet_action_strategy);
|
auto actionJson = actionStrategyToJson(pet->pet_action_strategy);
|
||||||
if (actionJson) {
|
if (!actionJson.isNull()) {
|
||||||
cJSON_AddItemToObject(json, "action_strategy", actionJson);
|
json.set("action_strategy", actionJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<PetBase> PetDAO::petFromJson(cJSON* json) {
|
std::shared_ptr<PetBase> PetDAO::petFromJson(const cppjson::Json& json) {
|
||||||
if (!json) return nullptr;
|
if (json.isNull()) return nullptr;
|
||||||
|
|
||||||
// 创建宠物基本信息
|
// 创建宠物基本信息
|
||||||
PetBaseInfo info;
|
PetBaseInfo info;
|
||||||
cJSON* nameItem = cJSON_GetObjectItemCaseSensitive(json, "name");
|
|
||||||
if (cJSON_IsString(nameItem)) {
|
if (json["name"].isString()) {
|
||||||
info.pet_name = nameItem->valuestring;
|
info.pet_name = json["name"].asString();
|
||||||
}
|
}
|
||||||
|
|
||||||
cJSON* hpItem = cJSON_GetObjectItemCaseSensitive(json, "hp");
|
if (json["hp"].isNumber()) {
|
||||||
if (cJSON_IsNumber(hpItem)) {
|
info.pet_hp = json["hp"].asInt();
|
||||||
info.pet_hp = hpItem->valueint;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cJSON* densityItem = cJSON_GetObjectItemCaseSensitive(json, "density");
|
if (json["density"].isNumber()) {
|
||||||
if (cJSON_IsNumber(densityItem)) {
|
info.pet_density = json["density"].asInt();
|
||||||
info.pet_density = densityItem->valueint;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cJSON* identityItem = cJSON_GetObjectItemCaseSensitive(json, "identity");
|
if (json["identity"].isString()) {
|
||||||
if (cJSON_IsString(identityItem)) {
|
info.pet_identity = json["identity"].asString();
|
||||||
info.pet_identity = identityItem->valuestring;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建阶段策略
|
// 创建阶段策略
|
||||||
cJSON* stageJson = cJSON_GetObjectItemCaseSensitive(json, "stage_strategy");
|
auto stageStrategy = stageStrategyFromJson(json["stage_strategy"]);
|
||||||
auto stageStrategy = stageStrategyFromJson(stageJson);
|
|
||||||
|
|
||||||
// 创建动作策略
|
// 创建动作策略
|
||||||
cJSON* actionJson = cJSON_GetObjectItemCaseSensitive(json, "action_strategy");
|
auto actionStrategy = actionStrategyFromJson(json["action_strategy"]);
|
||||||
auto actionStrategy = actionStrategyFromJson(actionJson);
|
|
||||||
|
|
||||||
// 创建宠物对象
|
// 创建宠物对象
|
||||||
return std::make_shared<PetBase>(info, stageStrategy, actionStrategy);
|
return std::make_shared<PetBase>(info, stageStrategy, actionStrategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
cJSON* PetDAO::stageStrategyToJson(const std::shared_ptr<PetStageStrategy>& strategy) {
|
|
||||||
if (!strategy) return nullptr;
|
|
||||||
|
|
||||||
cJSON* json = cJSON_CreateObject();
|
cppjson::Json PetDAO::stageStrategyToJson(const std::shared_ptr<PetStageStrategy>& strategy) {
|
||||||
if (!json) return nullptr;
|
if (!strategy) return {};
|
||||||
|
|
||||||
|
auto json = cppjson::Json::object();
|
||||||
|
|
||||||
// 添加当前阶段
|
// 添加当前阶段
|
||||||
cJSON_AddStringToObject(json, "current_stage",
|
json.set("current_stage", cppjson::Json(stageTypeToString(strategy->getCurrentStageType())));
|
||||||
stageTypeToString(strategy->getCurrentStageType()).c_str());
|
|
||||||
|
|
||||||
// 添加阶段模型映射
|
// 添加阶段模型映射
|
||||||
cJSON* modelMap = cJSON_CreateObject();
|
auto modelMap = cppjson::Json::object();
|
||||||
for (const auto& pair : strategy->getStageModelMap()) {
|
for (const auto& pair : strategy->getStageModelMap()) {
|
||||||
cJSON_AddStringToObject(modelMap,
|
modelMap.set(stageTypeToString(pair.first), cppjson::Json(pair.second));
|
||||||
stageTypeToString(pair.first).c_str(),
|
|
||||||
pair.second.c_str());
|
|
||||||
}
|
}
|
||||||
cJSON_AddItemToObject(json, "stage_model_map", modelMap);
|
json.set("stage_model_map", modelMap);
|
||||||
|
|
||||||
// 添加阶段音频映射
|
// 添加阶段音频映射
|
||||||
cJSON* audioMap = cJSON_CreateObject();
|
auto audioMap = cppjson::Json::object();
|
||||||
for (const auto& pair : strategy->getStageAudioMap()) {
|
for (const auto& pair : strategy->getStageAudioMap()) {
|
||||||
cJSON_AddStringToObject(audioMap,
|
audioMap.set(stageTypeToString(pair.first), cppjson::Json(pair.second));
|
||||||
stageTypeToString(pair.first).c_str(),
|
|
||||||
pair.second.c_str());
|
|
||||||
}
|
}
|
||||||
cJSON_AddItemToObject(json, "stage_audio_map", audioMap);
|
json.set("stage_audio_map", audioMap);
|
||||||
|
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<PetStageStrategy> PetDAO::stageStrategyFromJson(cJSON* json) {
|
std::shared_ptr<PetStageStrategy> PetDAO::stageStrategyFromJson(const cppjson::Json& json) {
|
||||||
if (!json) return nullptr;
|
if (json.isNull()) return nullptr;
|
||||||
|
|
||||||
auto strategy = std::make_shared<PetStageStrategy>();
|
auto strategy = std::make_shared<PetStageStrategy>();
|
||||||
|
|
||||||
// 获取当前阶段
|
// 获取当前阶段
|
||||||
cJSON* currentStageItem = cJSON_GetObjectItemCaseSensitive(json, "current_stage");
|
if (json["current_stage"].isString()) {
|
||||||
if (cJSON_IsString(currentStageItem)) {
|
strategy->current_stage = stringToStageType(json["current_stage"].asString());
|
||||||
strategy->current_stage = stringToStageType(currentStageItem->valuestring);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取阶段模型映射
|
// 获取阶段模型映射
|
||||||
cJSON* modelMapItem = cJSON_GetObjectItemCaseSensitive(json, "stage_model_map");
|
auto modelMapJson = json["stage_model_map"];
|
||||||
if (cJSON_IsObject(modelMapItem)) {
|
if (modelMapJson.isObject()) {
|
||||||
cJSON* child = modelMapItem->child;
|
for (const auto& item : modelMapJson.items()) {
|
||||||
while (child) {
|
if (item.second.isString()) {
|
||||||
if (cJSON_IsString(child)) {
|
PetStageType stage = stringToStageType(item.first);
|
||||||
PetStageType stage = stringToStageType(child->string);
|
strategy->stage_model_map[stage] = item.second.asString();
|
||||||
strategy->stage_model_map[stage] = child->valuestring;
|
|
||||||
}
|
}
|
||||||
child = child->next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取阶段音频映射
|
// 获取阶段音频映射
|
||||||
cJSON* audioMapItem = cJSON_GetObjectItemCaseSensitive(json, "stage_audio_map");
|
auto audioMapJson = json["stage_audio_map"];
|
||||||
if (cJSON_IsObject(audioMapItem)) {
|
if (audioMapJson.isObject()) {
|
||||||
cJSON* child = audioMapItem->child;
|
for (const auto& item : audioMapJson.items()) {
|
||||||
while (child) {
|
if (item.second.isString()) {
|
||||||
if (cJSON_IsString(child)) {
|
PetStageType stage = stringToStageType(item.first);
|
||||||
PetStageType stage = stringToStageType(child->string);
|
strategy->stage_audio_map[stage] = item.second.asString();
|
||||||
strategy->stage_audio_map[stage] = child->valuestring;
|
|
||||||
}
|
}
|
||||||
child = child->next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return strategy;
|
return strategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
cJSON* PetDAO::actionStrategyToJson(const std::shared_ptr<PetActionStrategy>& strategy) {
|
cppjson::Json PetDAO::actionStrategyToJson(const std::shared_ptr<PetActionStrategy>& strategy) {
|
||||||
if (!strategy) return nullptr;
|
if (!strategy) return {};
|
||||||
|
|
||||||
cJSON* json = cJSON_CreateObject();
|
auto json = cppjson::Json::object();
|
||||||
if (!json) return nullptr;
|
|
||||||
|
|
||||||
// 添加当前动作
|
// 添加当前动作
|
||||||
cJSON_AddStringToObject(json, "current_action",
|
json.set("current_action", cppjson::Json(actionTypeToString(strategy->getCurrentActionType())));
|
||||||
actionTypeToString(strategy->getCurrentActionType()).c_str());
|
|
||||||
|
|
||||||
// 添加动作模型映射
|
// 添加动作模型映射
|
||||||
cJSON* modelMap = cJSON_CreateObject();
|
auto modelMap = cppjson::Json::object();
|
||||||
for (const auto& pair : strategy->getActionModelMap()) {
|
for (const auto& pair : strategy->getActionModelMap()) {
|
||||||
cJSON_AddStringToObject(modelMap,
|
modelMap.set(actionTypeToString(pair.first), cppjson::Json(pair.second));
|
||||||
actionTypeToString(pair.first).c_str(),
|
|
||||||
pair.second.c_str());
|
|
||||||
}
|
}
|
||||||
cJSON_AddItemToObject(json, "action_model_map", modelMap);
|
json.set("action_model_map", modelMap);
|
||||||
|
|
||||||
// 添加动作音频映射
|
// 添加动作音频映射
|
||||||
cJSON* audioMap = cJSON_CreateObject();
|
auto audioMap = cppjson::Json::object();
|
||||||
for (const auto& pair : strategy->getActionAudioMap()) {
|
for (const auto& pair : strategy->getActionAudioMap()) {
|
||||||
cJSON_AddStringToObject(audioMap,
|
audioMap.set(actionTypeToString(pair.first), cppjson::Json(pair.second));
|
||||||
actionTypeToString(pair.first).c_str(),
|
|
||||||
pair.second.c_str());
|
|
||||||
}
|
}
|
||||||
cJSON_AddItemToObject(json, "action_audio_map", audioMap);
|
json.set("action_audio_map", audioMap);
|
||||||
|
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<PetActionStrategy> PetDAO::actionStrategyFromJson(cJSON* json) {
|
|
||||||
if (!json) return nullptr;
|
std::shared_ptr<PetActionStrategy> PetDAO::actionStrategyFromJson(const cppjson::Json& json) {
|
||||||
|
if (json.isNull()) return nullptr;
|
||||||
|
|
||||||
auto strategy = std::make_shared<PetActionStrategy>();
|
auto strategy = std::make_shared<PetActionStrategy>();
|
||||||
|
|
||||||
// 获取当前动作
|
// 获取当前动作
|
||||||
cJSON* currentActionItem = cJSON_GetObjectItemCaseSensitive(json, "current_action");
|
if (json["current_action"].isString()) {
|
||||||
if (cJSON_IsString(currentActionItem)) {
|
strategy->current_action = stringToActionType(json["current_action"].asString());
|
||||||
strategy->current_action = stringToActionType(currentActionItem->valuestring);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取动作模型映射
|
// 获取动作模型映射
|
||||||
cJSON* modelMapItem = cJSON_GetObjectItemCaseSensitive(json, "action_model_map");
|
auto modelMapJson = json["action_model_map"];
|
||||||
if (cJSON_IsObject(modelMapItem)) {
|
if (modelMapJson.isObject()) {
|
||||||
cJSON* child = modelMapItem->child;
|
for (const auto& item : modelMapJson.items()) {
|
||||||
while (child) {
|
if (item.second.isString()) {
|
||||||
if (cJSON_IsString(child)) {
|
PetActionType action = stringToActionType(item.first);
|
||||||
PetActionType action = stringToActionType(child->string);
|
strategy->action_model_map[action] = item.second.asString();
|
||||||
strategy->action_model_map[action] = child->valuestring;
|
|
||||||
}
|
}
|
||||||
child = child->next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取动作音频映射
|
// 获取动作音频映射
|
||||||
cJSON* audioMapItem = cJSON_GetObjectItemCaseSensitive(json, "action_audio_map");
|
auto audioMapJson = json["action_audio_map"];
|
||||||
if (cJSON_IsObject(audioMapItem)) {
|
if (audioMapJson.isObject()) {
|
||||||
cJSON* child = audioMapItem->child;
|
for (const auto& item : audioMapJson.items()) {
|
||||||
while (child) {
|
if (item.second.isString()) {
|
||||||
if (cJSON_IsString(child)) {
|
PetActionType action = stringToActionType(item.first);
|
||||||
PetActionType action = stringToActionType(child->string);
|
strategy->action_audio_map[action] = item.second.asString();
|
||||||
strategy->action_audio_map[action] = child->valuestring;
|
|
||||||
}
|
}
|
||||||
child = child->next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,62 +5,61 @@
|
|||||||
|
|
||||||
#include "PetBaseClass.h"
|
#include "PetBaseClass.h"
|
||||||
#include "SDFileManager.h"
|
#include "SDFileManager.h"
|
||||||
#include "cJSON.h"
|
#include "cpp_json.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
// 辅助函数:枚举类型与字符串的转换
|
// 辅助函数:枚举类型与字符串的转换
|
||||||
namespace PetEnumConverter {
|
namespace PetEnumConverter {
|
||||||
// PetStageType 转换
|
// PetStageType 转换
|
||||||
std::string stageTypeToString(PetStageType stage);
|
std::string stageTypeToString(PetStageType stage);
|
||||||
PetStageType stringToStageType(const std::string& str);
|
PetStageType stringToStageType(const std::string &str);
|
||||||
|
|
||||||
// PetActionType 转换
|
// PetActionType 转换
|
||||||
std::string actionTypeToString(PetActionType action);
|
std::string actionTypeToString(PetActionType action);
|
||||||
PetActionType stringToActionType(const std::string& str);
|
PetActionType stringToActionType(const std::string &str);
|
||||||
}
|
}
|
||||||
|
|
||||||
// PetDAO 类 - 负责宠物的数据持久化
|
// PetDAO 类 - 负责宠物的数据持久化
|
||||||
class PetDAO {
|
class PetDAO {
|
||||||
public:
|
public:
|
||||||
// 构造函数,需要SDFileManager实例
|
// 构造函数,需要SDFileManager实例
|
||||||
explicit PetDAO(SDFileManager* fileManager);
|
explicit PetDAO(SDFileManager *fileManager);
|
||||||
|
|
||||||
// 保存宠物数据到文件
|
// 保存宠物数据到文件
|
||||||
bool savePet(const std::shared_ptr<PetBase>& pet, const std::string& filename);
|
bool savePet(const std::shared_ptr<PetBase> &pet, const std::string &filename);
|
||||||
|
|
||||||
// 从文件加载宠物数据
|
// 从文件加载宠物数据
|
||||||
std::shared_ptr<PetBase> loadPet(const std::string& filename);
|
std::shared_ptr<PetBase> loadPet(const std::string &filename);
|
||||||
|
|
||||||
// 获取所有保存的宠物文件列表
|
// 获取所有保存的宠物文件列表
|
||||||
std::vector<std::string> listPetFiles();
|
std::vector<std::string> listPetFiles();
|
||||||
|
|
||||||
// 删除宠物文件
|
// 删除宠物文件
|
||||||
bool deletePetFile(const std::string& filename);
|
bool deletePetFile(const std::string &filename);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// 将宠物数据转换为JSON对象
|
// 将宠物数据转换为JSON对象
|
||||||
cJSON* petToJson(const std::shared_ptr<PetBase>& pet);
|
cppjson::Json petToJson(const std::shared_ptr<PetBase> &pet); // 返回 cppjson::Json
|
||||||
|
|
||||||
// 从JSON对象创建宠物
|
// 从JSON对象创建宠物
|
||||||
std::shared_ptr<PetBase> petFromJson(cJSON* json);
|
std::shared_ptr<PetBase> petFromJson(const cppjson::Json &json); // 参数改为 cppjson::Json
|
||||||
|
|
||||||
// 将阶段策略转换为JSON对象
|
// 将阶段策略转换为JSON对象
|
||||||
cJSON* stageStrategyToJson(const std::shared_ptr<PetStageStrategy>& strategy);
|
cppjson::Json stageStrategyToJson(const std::shared_ptr<PetStageStrategy> &strategy);
|
||||||
|
|
||||||
// 从JSON对象创建阶段策略
|
// 从JSON对象创建阶段策略
|
||||||
std::shared_ptr<PetStageStrategy> stageStrategyFromJson(cJSON* json);
|
std::shared_ptr<PetStageStrategy> stageStrategyFromJson(const cppjson::Json &json);
|
||||||
|
|
||||||
// 将动作策略转换为JSON对象
|
// 将动作策略转换为JSON对象
|
||||||
cJSON* actionStrategyToJson(const std::shared_ptr<PetActionStrategy>& strategy);
|
cppjson::Json actionStrategyToJson(const std::shared_ptr<PetActionStrategy> &strategy);
|
||||||
|
|
||||||
// 从JSON对象创建动作策略
|
// 从JSON对象创建动作策略
|
||||||
std::shared_ptr<PetActionStrategy> actionStrategyFromJson(cJSON* json);
|
std::shared_ptr<PetActionStrategy> actionStrategyFromJson(const cppjson::Json &json);
|
||||||
|
|
||||||
// 文件管理器实例
|
// 文件管理器实例
|
||||||
SDFileManager* fileManager;
|
SDFileManager *fileManager;
|
||||||
|
|
||||||
// 宠物数据存储目录
|
// 宠物数据存储目录
|
||||||
static constexpr const char* PET_DATA_DIR = "/sdcard/pet_data";
|
static constexpr const char *PET_DATA_DIR = "/sdcard/pet_data";
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -3,10 +3,13 @@
|
|||||||
//
|
//
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "PetInterface.h"
|
#include "PetInterface.h"
|
||||||
|
// 用于回调函数传递回调类型,以区分回调的是宠物动作还是宠物阶段
|
||||||
|
enum class PetType : uint8_t {Action, Stage};
|
||||||
|
|
||||||
// 宠物音频播放观察者类,继承自宠物观察者
|
// 宠物音频播放观察者类,继承自宠物观察者
|
||||||
class PetAudioStrategy : public PetObserver, public std::enable_shared_from_this<PetAudioStrategy> {
|
class PetAudioStrategy : public PetObserver, public std::enable_shared_from_this<PetAudioStrategy> {
|
||||||
public:
|
public:
|
||||||
using AudioCallback = std::function<void(const std::string&)>;
|
using AudioCallback = std::function<void(PetType petType, const std::string&)>;
|
||||||
/**
|
/**
|
||||||
* 构造时候就将“事件→音频”两张表填好
|
* 构造时候就将“事件→音频”两张表填好
|
||||||
* @param actionAudios 动作→音频
|
* @param actionAudios 动作→音频
|
||||||
@@ -66,7 +69,7 @@ public:
|
|||||||
if (!audio_callback) return;
|
if (!audio_callback) return;
|
||||||
auto it = action_audio.find(action);
|
auto it = action_audio.find(action);
|
||||||
if (it != action_audio.end()) {
|
if (it != action_audio.end()) {
|
||||||
audio_callback(it->second); // 播放对应音频
|
audio_callback(PetType::Action, it->second); // 播放对应音频
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -79,7 +82,7 @@ public:
|
|||||||
if (!audio_callback) return;
|
if (!audio_callback) return;
|
||||||
auto it = stage_audio.find(newStage); // 注意:播“新阶段”的音频
|
auto it = stage_audio.find(newStage); // 注意:播“新阶段”的音频
|
||||||
if (it != stage_audio.end()) {
|
if (it != stage_audio.end()) {
|
||||||
audio_callback(it->second);
|
audio_callback(PetType::Stage, it->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
@@ -95,7 +98,7 @@ private:
|
|||||||
// 渲染器观察者类,继承自PetObserver
|
// 渲染器观察者类,继承自PetObserver
|
||||||
class PetRendererStrategy : public PetObserver, public std::enable_shared_from_this<PetRendererStrategy> {
|
class PetRendererStrategy : public PetObserver, public std::enable_shared_from_this<PetRendererStrategy> {
|
||||||
public:
|
public:
|
||||||
using RenderCallback = std::function<void(const std::string&)>;
|
using RenderCallback = std::function<void(PetType petType, const std::string&)>;
|
||||||
/**
|
/**
|
||||||
* 构造函数,可以传入动作到模型路径和阶段到模型路径的映射表
|
* 构造函数,可以传入动作到模型路径和阶段到模型路径的映射表
|
||||||
* @param actionModels 动作→模型路径映射
|
* @param actionModels 动作→模型路径映射
|
||||||
@@ -120,7 +123,7 @@ public:
|
|||||||
}
|
}
|
||||||
~PetRendererStrategy() override {
|
~PetRendererStrategy() override {
|
||||||
// 自动取消注册
|
// 自动取消注册
|
||||||
if (auto subject = pet_subject.lock()) {
|
if (const auto subject = pet_subject.lock()) {
|
||||||
subject->removeObserver(shared_from_this());
|
subject->removeObserver(shared_from_this());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -148,11 +151,11 @@ public:
|
|||||||
* 宠物动作时触发[Observer接口实现]
|
* 宠物动作时触发[Observer接口实现]
|
||||||
* @param action 动作类型
|
* @param action 动作类型
|
||||||
*/
|
*/
|
||||||
void onPetAction(PetActionType action) override {
|
void onPetAction(const PetActionType action) override {
|
||||||
if (!render_callback) return;
|
if (!render_callback) return;
|
||||||
auto it = action_models.find(action);
|
const auto it = action_models.find(action);
|
||||||
if (it != action_models.end()) {
|
if (it != action_models.end()) {
|
||||||
render_callback(it->second); // 渲染对应动作模型
|
render_callback(PetType::Action, it->second); // 渲染对应动作模型
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -160,11 +163,11 @@ public:
|
|||||||
* @param oldStage 旧阶段
|
* @param oldStage 旧阶段
|
||||||
* @param newStage 新阶段
|
* @param newStage 新阶段
|
||||||
*/
|
*/
|
||||||
void onPetStageChange(PetStageType oldStage, PetStageType newStage) override {
|
void onPetStageChange(PetStageType oldStage, const PetStageType newStage) override {
|
||||||
if (!render_callback) return;
|
if (!render_callback) return;
|
||||||
auto it = stage_models.find(newStage); // 注意:渲染"新阶段"的模型
|
const auto it = stage_models.find(newStage); // 注意:渲染"新阶段"的模型,实际上并没有使用到旧阶段,但还是保留,留一手
|
||||||
if (it != stage_models.end()) {
|
if (it != stage_models.end()) {
|
||||||
render_callback(it->second);
|
render_callback(PetType::Stage, it->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
//
|
//
|
||||||
// Created by misaki on 2025/9/9.
|
// Created by misaki on 2025/9/9.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "AudioOutput.h"
|
#include "AudioOutput.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@@ -81,8 +80,8 @@ bool AudioOutput::playSync(const char* directory, const char* fileName) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioOutput::playAsync(const char* directory, const char* fileName, AudioCallback callback) {
|
void AudioOutput::playAsync(const char* directory, const char* fileName, const AudioCallback& callback) {
|
||||||
ThreadConfig config = getThreadConfig("play_async");
|
const ThreadConfig config = getThreadConfig("play_async");
|
||||||
|
|
||||||
ThreadManager::createThread(config, [this, directory = std::string(directory),
|
ThreadManager::createThread(config, [this, directory = std::string(directory),
|
||||||
fileName = std::string(fileName), callback]() {
|
fileName = std::string(fileName), callback]() {
|
||||||
@@ -90,9 +89,9 @@ void AudioOutput::playAsync(const char* directory, const char* fileName, AudioCa
|
|||||||
}).detach();
|
}).detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioOutput::playInternal(const char* directory, const char* fileName, AudioCallback callback) {
|
void AudioOutput::playInternal(const char* directory, const char* fileName, const AudioCallback& callback) {
|
||||||
bool success = false;
|
bool success = false;
|
||||||
AudioState finalState = AudioState::ERROR;
|
auto finalState = AudioState::ERROR;
|
||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(stateMutex);
|
std::lock_guard<std::mutex> lock(stateMutex);
|
||||||
@@ -246,3 +245,121 @@ void AudioOutput::setState(AudioState newState) {
|
|||||||
std::lock_guard<std::mutex> lock(stateMutex);
|
std::lock_guard<std::mutex> lock(stateMutex);
|
||||||
currentState = newState;
|
currentState = newState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AudioOutput::playPcmFile(const char* filePath,
|
||||||
|
uint32_t sampleRate,
|
||||||
|
i2s_data_bit_width_t bits,
|
||||||
|
i2s_slot_mode_t ch)
|
||||||
|
{
|
||||||
|
// 简单文件尺寸获取
|
||||||
|
FILE* f = fopen(filePath, "rb");
|
||||||
|
if (!f) return false;
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
const size_t bytes = ftell(f);
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
playPcmCommon(filePath, bytes, true, sampleRate, bits, ch, nullptr);
|
||||||
|
return getState() == AudioState::PLAYING;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AudioOutput::playPcmStream(const uint8_t* pcmData,
|
||||||
|
size_t dataBytes,
|
||||||
|
uint32_t sampleRate,
|
||||||
|
i2s_data_bit_width_t bits,
|
||||||
|
i2s_slot_mode_t ch)
|
||||||
|
{
|
||||||
|
playPcmCommon(pcmData, dataBytes, false, sampleRate, bits, ch, nullptr);
|
||||||
|
return getState() == AudioState::PLAYING;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioOutput::playPcmFileAsync(const char* filePath,
|
||||||
|
uint32_t sampleRate,
|
||||||
|
i2s_data_bit_width_t bits,
|
||||||
|
i2s_slot_mode_t ch,
|
||||||
|
const AudioCallback& cb)
|
||||||
|
{
|
||||||
|
ThreadConfig cfg = getThreadConfig("pcm_file");
|
||||||
|
std::thread([=](){
|
||||||
|
playPcmCommon(filePath, 0, true, sampleRate, bits, ch, cb);
|
||||||
|
}).detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioOutput::playPcmStreamAsync(const uint8_t* pcmData,
|
||||||
|
size_t dataBytes,
|
||||||
|
uint32_t sampleRate,
|
||||||
|
i2s_data_bit_width_t bits,
|
||||||
|
i2s_slot_mode_t ch,
|
||||||
|
const AudioCallback& cb)
|
||||||
|
{
|
||||||
|
ThreadConfig cfg = getThreadConfig("pcm_stream");
|
||||||
|
std::thread([=](){
|
||||||
|
playPcmCommon(pcmData, dataBytes, false, sampleRate, bits, ch, cb);
|
||||||
|
}).detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioOutput::playPcmCommon(const void* source,
|
||||||
|
size_t bytes,
|
||||||
|
bool isFile,
|
||||||
|
uint32_t sampleRate,
|
||||||
|
i2s_data_bit_width_t bits,
|
||||||
|
i2s_slot_mode_t ch,
|
||||||
|
const AudioCallback& cb)
|
||||||
|
{
|
||||||
|
// 停止旧播放
|
||||||
|
stop();
|
||||||
|
// 重新配置 I2S 时钟/位宽/声道
|
||||||
|
bsp_i2s_reconfig_clk(sampleRate, bits, ch);
|
||||||
|
// 打开“文件”或“内存”数据源
|
||||||
|
FILE* f = nullptr;
|
||||||
|
const uint8_t* mem = nullptr;
|
||||||
|
size_t memLeft = 0;
|
||||||
|
if (isFile) {
|
||||||
|
f = fopen(static_cast<const char *>(source), "rb");
|
||||||
|
if (!f) {
|
||||||
|
if (cb) cb(AudioState::ERROR, static_cast<const char *>(source));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mem = static_cast<const uint8_t *>(source);
|
||||||
|
memLeft = bytes;
|
||||||
|
}
|
||||||
|
// 状态置为 PLAYING
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lk(stateMutex);
|
||||||
|
currentState = AudioState::PLAYING;
|
||||||
|
currentFilePath = isFile ? static_cast<const char *>(source) : "<stream>";
|
||||||
|
}
|
||||||
|
if (cb) cb(AudioState::PLAYING, currentFilePath.c_str());
|
||||||
|
|
||||||
|
// 循环送 PCM 数据到 I2S
|
||||||
|
constexpr size_t CHUNK = 512; // 任意 2 的幂
|
||||||
|
int16_t buf[CHUNK];
|
||||||
|
size_t bw;
|
||||||
|
while (true) {
|
||||||
|
size_t rd = 0;
|
||||||
|
if (isFile) {
|
||||||
|
rd = fread(buf, 1, sizeof(buf), f);
|
||||||
|
} else {
|
||||||
|
rd = memLeft > sizeof(buf) ? sizeof(buf) : memLeft;
|
||||||
|
memcpy(buf, mem, rd);
|
||||||
|
mem += rd;
|
||||||
|
memLeft -= rd;
|
||||||
|
}
|
||||||
|
if (rd == 0) break;
|
||||||
|
|
||||||
|
// 音量实时缩放(复用已有逻辑)
|
||||||
|
const float vf = currentVolume / 100.0f;
|
||||||
|
for (size_t i = 0; i < rd / 2; ++i) buf[i] = static_cast<int16_t>(buf[i] * vf);
|
||||||
|
|
||||||
|
// 写 I2S
|
||||||
|
i2s_channel_write(i2s_tx_chan, buf, rd, &bw, portMAX_DELAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 播放结束
|
||||||
|
if (f) fclose(f);
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lk(stateMutex);
|
||||||
|
currentState = AudioState::STOPPED;
|
||||||
|
}
|
||||||
|
if (cb) cb(AudioState::STOPPED, currentFilePath.c_str());
|
||||||
|
}
|
||||||
@@ -1,14 +1,12 @@
|
|||||||
//
|
//
|
||||||
// Created by misaki on 2025/9/9.
|
// Created by misaki on 2025/9/9.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <hal/i2s_types.h>
|
||||||
|
|
||||||
#include "ThreadManager.h"
|
#include "ThreadManager.h"
|
||||||
#include "SDFileManager.h"
|
#include "SDFileManager.h"
|
||||||
|
|
||||||
@@ -88,7 +86,7 @@ public:
|
|||||||
* @param fileName 文件名
|
* @param fileName 文件名
|
||||||
* @param callback 回调函数
|
* @param callback 回调函数
|
||||||
*/
|
*/
|
||||||
void playAsync(const char* directory, const char* fileName, AudioCallback callback = nullptr);
|
void playAsync(const char* directory, const char* fileName, const AudioCallback& callback = nullptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 暂停播放
|
* 暂停播放
|
||||||
@@ -175,6 +173,58 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool isFinished() const;
|
bool isFinished() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 播放 PCM 文件(阻塞)
|
||||||
|
* @param filePath PCM 文件路径
|
||||||
|
* @param sampleRate 采样率
|
||||||
|
* @param bits 数据位宽
|
||||||
|
* @param ch 插槽模式
|
||||||
|
* @return 是否成功
|
||||||
|
*/
|
||||||
|
bool playPcmFile(const char* filePath,
|
||||||
|
uint32_t sampleRate = 16000,
|
||||||
|
i2s_data_bit_width_t bits = I2S_DATA_BIT_WIDTH_16BIT,
|
||||||
|
i2s_slot_mode_t ch = I2S_SLOT_MODE_MONO);
|
||||||
|
|
||||||
|
// 异步播放 PCM 文件
|
||||||
|
void playPcmFileAsync(const char* filePath,
|
||||||
|
uint32_t sampleRate = 16000,
|
||||||
|
i2s_data_bit_width_t bits = I2S_DATA_BIT_WIDTH_16BIT,
|
||||||
|
i2s_slot_mode_t ch = I2S_SLOT_MODE_MONO,
|
||||||
|
const AudioCallback& cb = nullptr);
|
||||||
|
/**
|
||||||
|
* 播放内存 PCM 流(阻塞)
|
||||||
|
* @param pcmData PCM 数据
|
||||||
|
* @param dataBytes 数据字节数
|
||||||
|
* @param sampleRate 采样率
|
||||||
|
* @param bits 数据位宽
|
||||||
|
* @param ch 插槽模式
|
||||||
|
* @return 是否成功
|
||||||
|
*/
|
||||||
|
bool playPcmStream(const uint8_t* pcmData,
|
||||||
|
size_t dataBytes,
|
||||||
|
uint32_t sampleRate = 16000,
|
||||||
|
i2s_data_bit_width_t bits = I2S_DATA_BIT_WIDTH_16BIT,
|
||||||
|
i2s_slot_mode_t ch = I2S_SLOT_MODE_MONO);
|
||||||
|
|
||||||
|
// 异步播放 PCM 流
|
||||||
|
void playPcmStreamAsync(const uint8_t* pcmData,
|
||||||
|
size_t dataBytes,
|
||||||
|
uint32_t sampleRate = 16000,
|
||||||
|
i2s_data_bit_width_t bits = I2S_DATA_BIT_WIDTH_16BIT,
|
||||||
|
i2s_slot_mode_t ch = I2S_SLOT_MODE_MONO,
|
||||||
|
const AudioCallback& cb = nullptr);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 通用 PCM 播放实现
|
||||||
|
void playPcmCommon(const void* source,
|
||||||
|
size_t bytes,
|
||||||
|
bool isFile,
|
||||||
|
uint32_t sampleRate,
|
||||||
|
i2s_data_bit_width_t bits,
|
||||||
|
i2s_slot_mode_t ch,
|
||||||
|
const AudioCallback& cb);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// 私有构造函数
|
// 私有构造函数
|
||||||
AudioOutput();
|
AudioOutput();
|
||||||
@@ -184,7 +234,7 @@ private:
|
|||||||
ThreadConfig getThreadConfig(const char* operation);
|
ThreadConfig getThreadConfig(const char* operation);
|
||||||
|
|
||||||
// 内部播放实现
|
// 内部播放实现
|
||||||
void playInternal(const char* directory, const char* fileName, AudioCallback callback);
|
void playInternal(const char* directory, const char* fileName, const AudioCallback& callback);
|
||||||
|
|
||||||
// 状态转换辅助方法
|
// 状态转换辅助方法
|
||||||
void setState(AudioState newState);
|
void setState(AudioState newState);
|
||||||
|
|||||||
@@ -32,14 +32,15 @@
|
|||||||
std::cout << "\n";\n
|
std::cout << "\n";\n
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// cpp_json.hpp
|
// cpp_json.h
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <cJSON.h>
|
#include <cJSON.h>
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
namespace cppjson {
|
namespace cppjson {
|
||||||
|
|
||||||
@@ -152,42 +153,176 @@ public:
|
|||||||
cJSON_AddItemToArray(ptr_, cJSON_Duplicate(v.ptr_, 1));
|
cJSON_AddItemToArray(ptr_, cJSON_Duplicate(v.ptr_, 1));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
// 便捷的 append 方法重载
|
||||||
|
Json& append(int value) {
|
||||||
|
return append(Json(value));
|
||||||
|
}
|
||||||
|
Json& append(double value) {
|
||||||
|
return append(Json(value));
|
||||||
|
}
|
||||||
|
Json& append(bool value) {
|
||||||
|
return append(Json(value));
|
||||||
|
}
|
||||||
|
Json& append(const char* value) {
|
||||||
|
return append(Json(value));
|
||||||
|
}
|
||||||
|
Json& append(const std::string& value) {
|
||||||
|
return append(Json(value));
|
||||||
|
}
|
||||||
|
|
||||||
Json& set(const std::string& key, const Json& v) {
|
Json& set(const std::string& key, const Json& v) {
|
||||||
if (!isObject()) throw std::runtime_error("not object");
|
if (!isObject()) throw std::runtime_error("not object");
|
||||||
cJSON_AddItemToObject(ptr_, key.c_str(), cJSON_Duplicate(v.ptr_, 1));
|
cJSON_AddItemToObject(ptr_, key.c_str(), cJSON_Duplicate(v.ptr_, 1));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
// 便捷的 set 方法重载
|
||||||
|
Json& set(const std::string& key, int value) {
|
||||||
|
return set(key, Json(value));
|
||||||
|
}
|
||||||
|
Json& set(const std::string& key, double value) {
|
||||||
|
return set(key, Json(value));
|
||||||
|
}
|
||||||
|
Json& set(const std::string& key, bool value) {
|
||||||
|
return set(key, Json(value));
|
||||||
|
}
|
||||||
|
Json& set(const std::string& key, const char* value) {
|
||||||
|
return set(key, Json(value));
|
||||||
|
}
|
||||||
|
Json& set(const std::string& key, const std::string& value) {
|
||||||
|
return set(key, Json(value));
|
||||||
|
}
|
||||||
|
|
||||||
// 迭代器(只读)
|
// 获取对象的所有键
|
||||||
|
[[nodiscard]] std::vector<std::string> keys() const {
|
||||||
|
if (!isObject()) throw std::runtime_error("not object");
|
||||||
|
std::vector<std::string> result;
|
||||||
|
cJSON* child = ptr_->child;
|
||||||
|
while (child) {
|
||||||
|
if (child->string) {
|
||||||
|
result.emplace_back(child->string);
|
||||||
|
}
|
||||||
|
child = child->next;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 数组迭代器(只读)
|
||||||
template <bool IsConst>
|
template <bool IsConst>
|
||||||
struct iterator_impl {
|
struct array_iterator_impl {
|
||||||
using iterator_category = std::forward_iterator_tag;
|
using iterator_category = std::forward_iterator_tag;
|
||||||
using value_type = Json;
|
using value_type = Json;
|
||||||
using difference_type = std::ptrdiff_t;
|
using difference_type = std::ptrdiff_t;
|
||||||
using pointer = typename std::conditional<IsConst, const Json, Json>::type*;
|
using pointer = typename std::conditional<IsConst, const Json, Json>::type*;
|
||||||
using reference = typename std::conditional<IsConst, const Json, Json>::type&;
|
using reference = typename std::conditional<IsConst, const Json, Json>::type&;
|
||||||
|
|
||||||
iterator_impl(cJSON* h, cJSON* c) : head_(h), cur_(c) {}
|
array_iterator_impl(cJSON* head, cJSON* c) : head_(head), cur_(c) {}
|
||||||
reference operator*() {
|
reference operator*() {
|
||||||
tmp = std::make_unique<Json>(cur_, false);
|
tmp = std::make_unique<Json>(cur_, false);
|
||||||
return *tmp;
|
return *tmp;
|
||||||
}
|
}
|
||||||
pointer operator->() { return &(operator*()); }
|
pointer operator->() { return &(operator*()); }
|
||||||
iterator_impl& operator++() { cur_ = cur_ ? cur_->next : nullptr; return *this; }
|
array_iterator_impl& operator++() { cur_ = cur_ ? cur_->next : nullptr; return *this; }
|
||||||
friend bool operator==(const iterator_impl& a, const iterator_impl& b) { return a.cur_ == b.cur_; }
|
friend bool operator==(const array_iterator_impl& a, const array_iterator_impl& b) { return a.cur_ == b.cur_; }
|
||||||
friend bool operator!=(const iterator_impl& a, const iterator_impl& b) { return !(a == b); }
|
friend bool operator!=(const array_iterator_impl& a, const array_iterator_impl& b) { return !(a == b); }
|
||||||
private:
|
private:
|
||||||
cJSON *head_, *cur_;
|
cJSON *head_, *cur_;
|
||||||
std::unique_ptr<Json> tmp; // 改为智能指针
|
std::unique_ptr<Json> tmp;
|
||||||
};
|
};
|
||||||
using iterator = iterator_impl<false>;
|
using array_iterator = array_iterator_impl<false>;
|
||||||
using const_iterator = iterator_impl<true>;
|
using const_array_iterator = array_iterator_impl<true>;
|
||||||
iterator begin() { return iterator(ptr_, ptr_ ? ptr_->child : nullptr); }
|
|
||||||
iterator end() { return iterator(ptr_, nullptr); }
|
// 对象键值对迭代器
|
||||||
[[nodiscard]] const_iterator begin() const { return cbegin(); }
|
template <bool IsConst>
|
||||||
[[nodiscard]] const_iterator end() const { return cend(); }
|
struct object_iterator_impl {
|
||||||
[[nodiscard]] const_iterator cbegin() const { return const_iterator(ptr_, ptr_ ? ptr_->child : nullptr); }
|
using iterator_category = std::forward_iterator_tag;
|
||||||
[[nodiscard]] const_iterator cend() const { return const_iterator(ptr_, nullptr); }
|
using value_type = std::pair<std::string, Json>;
|
||||||
|
using difference_type = std::ptrdiff_t;
|
||||||
|
using pointer = typename std::conditional<IsConst, const value_type, value_type>::type*;
|
||||||
|
using reference = typename std::conditional<IsConst, const value_type, value_type>::type&;
|
||||||
|
object_iterator_impl(cJSON* c) : cur_(c) {
|
||||||
|
if (cur_ && cur_->string) {
|
||||||
|
updateValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reference operator*() {
|
||||||
|
tmp = std::make_unique<value_type>(cur_->string ? cur_->string : "", Json(cur_, false));
|
||||||
|
return *tmp;
|
||||||
|
}
|
||||||
|
pointer operator->() { return &(operator*()); }
|
||||||
|
object_iterator_impl& operator++() {
|
||||||
|
cur_ = cur_ ? cur_->next : nullptr;
|
||||||
|
if (cur_) {
|
||||||
|
updateValue();
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
friend bool operator==(const object_iterator_impl& a, const object_iterator_impl& b) { return a.cur_ == b.cur_; }
|
||||||
|
friend bool operator!=(const object_iterator_impl& a, const object_iterator_impl& b) { return !(a == b); }
|
||||||
|
private:
|
||||||
|
void updateValue() {
|
||||||
|
if (cur_ && cur_->string) {
|
||||||
|
current_key = cur_->string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cJSON* cur_ = nullptr;
|
||||||
|
std::string current_key;
|
||||||
|
std::unique_ptr<value_type> tmp;
|
||||||
|
};
|
||||||
|
using object_iterator = object_iterator_impl<false>;
|
||||||
|
using const_object_iterator = object_iterator_impl<true>;
|
||||||
|
// 统一的迭代器接口(用于数组)
|
||||||
|
array_iterator begin() {
|
||||||
|
if (!isArray()) throw std::runtime_error("not array");
|
||||||
|
return {ptr_, ptr_ ? ptr_->child : nullptr};
|
||||||
|
}
|
||||||
|
array_iterator end() {
|
||||||
|
if (!isArray()) throw std::runtime_error("not array");
|
||||||
|
return {ptr_, nullptr};
|
||||||
|
}
|
||||||
|
[[nodiscard]] const_array_iterator begin() const { return cbegin(); }
|
||||||
|
[[nodiscard]] const_array_iterator end() const { return cend(); }
|
||||||
|
[[nodiscard]] const_array_iterator cbegin() const {
|
||||||
|
if (!isArray()) throw std::runtime_error("not array");
|
||||||
|
return {ptr_, ptr_ ? ptr_->child : nullptr};
|
||||||
|
}
|
||||||
|
[[nodiscard]] const_array_iterator cend() const {
|
||||||
|
if (!isArray()) throw std::runtime_error("not array");
|
||||||
|
return {ptr_, nullptr};
|
||||||
|
}
|
||||||
|
// 对象项迭代器
|
||||||
|
object_iterator begin_object() {
|
||||||
|
if (!isObject()) throw std::runtime_error("not object");
|
||||||
|
return {ptr_ ? ptr_->child : nullptr};
|
||||||
|
}
|
||||||
|
object_iterator end_object() {
|
||||||
|
if (!isObject()) throw std::runtime_error("not object");
|
||||||
|
return {nullptr};
|
||||||
|
}
|
||||||
|
[[nodiscard]] const_object_iterator begin_object() const { return cbegin_object(); }
|
||||||
|
[[nodiscard]] const_object_iterator end_object() const { return cend_object(); }
|
||||||
|
[[nodiscard]] const_object_iterator cbegin_object() const {
|
||||||
|
if (!isObject()) throw std::runtime_error("not object");
|
||||||
|
return {ptr_ ? ptr_->child : nullptr};
|
||||||
|
}
|
||||||
|
[[nodiscard]] const_object_iterator cend_object() const {
|
||||||
|
if (!isObject()) throw std::runtime_error("not object");
|
||||||
|
return {nullptr};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 便利的 items() 方法,用于结构化绑定
|
||||||
|
class ItemsProxy {
|
||||||
|
public:
|
||||||
|
explicit ItemsProxy(Json* json) : json_(json) {}
|
||||||
|
object_iterator begin() { return json_->begin_object(); }
|
||||||
|
object_iterator end() { return json_->end_object(); }
|
||||||
|
[[nodiscard]] const_object_iterator begin() const { return json_->cbegin_object(); }
|
||||||
|
[[nodiscard]] const_object_iterator end() const { return json_->cend_object(); }
|
||||||
|
private:
|
||||||
|
Json* json_;
|
||||||
|
};
|
||||||
|
|
||||||
|
ItemsProxy items() { return ItemsProxy(this); }
|
||||||
|
[[nodiscard]] ItemsProxy items() const { return ItemsProxy(const_cast<Json*>(this)); }
|
||||||
|
|
||||||
/*-------- 工具 ------------------------------------------------*/
|
/*-------- 工具 ------------------------------------------------*/
|
||||||
void swap(Json& rhs) noexcept { std::swap(ptr_, rhs.ptr_); std::swap(owner_, rhs.owner_); }
|
void swap(Json& rhs) noexcept { std::swap(ptr_, rhs.ptr_); std::swap(owner_, rhs.owner_); }
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ LVGLRender::LVGLRender() {
|
|||||||
I2C_Init();
|
I2C_Init();
|
||||||
LCD_Init();
|
LCD_Init();
|
||||||
LVGL_Init();
|
LVGL_Init();
|
||||||
|
|
||||||
|
// std::this_thread::sleep_for(std::chrono::milliseconds(2000)); // 延时2秒 确保所有 LVGL 对象已创建完成
|
||||||
ESP_LOGI("LVGL_Render", "LVGL_Render构造函数...初始化媒体驱动成功...");
|
ESP_LOGI("LVGL_Render", "LVGL_Render构造函数...初始化媒体驱动成功...");
|
||||||
|
|
||||||
ESP_LOGI("LVGL_Render", "LVGL_Render构造函数...创建LVGL心跳...");
|
ESP_LOGI("LVGL_Render", "LVGL_Render构造函数...创建LVGL心跳...");
|
||||||
@@ -53,7 +55,7 @@ LVGLRender::LVGLRender() {
|
|||||||
trickConfig.core_id = 1; // 渲染分配给核0
|
trickConfig.core_id = 1; // 渲染分配给核0
|
||||||
trickConfig.name = "LVGL_Render";
|
trickConfig.name = "LVGL_Render";
|
||||||
trickConfig.priority = 5; //
|
trickConfig.priority = 5; //
|
||||||
trickConfig.stack_size = 4096; // 给LVGL一个较大的堆栈,避免栈溢出
|
trickConfig.stack_size = 8192; // 给LVGL一个较大的堆栈,避免栈溢出
|
||||||
|
|
||||||
std::thread tick_thread = ThreadManager::createMemberThread(trickConfig, this, &LVGLRender::LVGL_Update);
|
std::thread tick_thread = ThreadManager::createMemberThread(trickConfig, this, &LVGLRender::LVGL_Update);
|
||||||
|
|
||||||
@@ -74,96 +76,7 @@ uint16_t LVGLRender::getFps() {
|
|||||||
return fps;
|
return fps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void LVGLRender::tryToInitRenderGif() {
|
void LVGLRender::tryToInitRenderGif() {
|
||||||
ESP_LOGI("LVGL_Render", "尝试初始化 LVGL 底层驱动...");
|
ESP_LOGI("LVGL_Render", "尝试初始化 LVGL 底层驱动...");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LVGLRender::log() {
|
|
||||||
ESP_LOGI("LVGL_Render", "LVGL_Render log...");
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "SDFileManager.h"
|
|
||||||
std::vector<uint8_t> LVGLRender::readWholeFile(const std::string& path)
|
|
||||||
{
|
|
||||||
ESP_LOGI("LVGLRender", "开始读取文件: %s", path.c_str());
|
|
||||||
|
|
||||||
// 直接用 SDFileManager 同步读整个文件 TODO: 考虑修改为异步读
|
|
||||||
std::string content = SDFileManager::getInstance()->readFileSync(path.c_str());
|
|
||||||
if (content.empty()) {
|
|
||||||
ESP_LOGE("LVGLRender", "readFileSync 失败或文件为空");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
// string -> vector,零拷贝 move
|
|
||||||
return {content.begin(), content.end()};
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LVGLRender::getGifWH(const uint8_t* raw, uint32_t& w, uint32_t& h)
|
|
||||||
{
|
|
||||||
if (!raw || memcmp(raw, "GIF", 3) != 0) {
|
|
||||||
ESP_LOGE("LVGLRender", "不是合法 GIF 文件头");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// GIF87a/89a 宽高偏移 6~9 字节,小端
|
|
||||||
w = raw[6] | (raw[7] << 8);
|
|
||||||
h = raw[8] | (raw[9] << 8);
|
|
||||||
ESP_LOGI("LVGLRender", "GIF 尺寸: %lu x %lu", w, h);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
void LVGLRender::renderGifInternal(const std::vector<uint8_t>& data,
|
|
||||||
uint32_t w, uint32_t h)
|
|
||||||
{
|
|
||||||
// 删除旧对象
|
|
||||||
if (current_gif_obj != nullptr) {
|
|
||||||
lv_obj_del(current_gif_obj);
|
|
||||||
current_gif_obj = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 保存数据,防止被释放
|
|
||||||
current_gif_data = data;
|
|
||||||
|
|
||||||
// 构造新的描述符(不要 static)
|
|
||||||
lv_img_dsc_t gif_desc = {};
|
|
||||||
gif_desc.header.cf = LV_IMG_CF_RAW_CHROMA_KEYED;
|
|
||||||
gif_desc.header.always_zero = 0;
|
|
||||||
gif_desc.header.reserved = 0;
|
|
||||||
gif_desc.header.w = static_cast<lv_coord_t>(w);
|
|
||||||
gif_desc.header.h = static_cast<lv_coord_t>(h);
|
|
||||||
gif_desc.data_size = current_gif_data.size();
|
|
||||||
gif_desc.data = current_gif_data.data();
|
|
||||||
|
|
||||||
// 创建新的 GIF 对象
|
|
||||||
current_gif_obj = lv_gif_create(lv_scr_act()); // copy到当前gif对象
|
|
||||||
lv_gif_set_src(current_gif_obj, &gif_desc); // 设置源
|
|
||||||
lv_obj_center(current_gif_obj); // 居中
|
|
||||||
|
|
||||||
ESP_LOGI("LVGLRender", "GIF 已渲染并循环播放");
|
|
||||||
}
|
|
||||||
|
|
||||||
void LVGLRender::RenderGif(const std::string &filename) {
|
|
||||||
if (filename == last_gif_filename) {
|
|
||||||
ESP_LOGW("LVGLRender", "重复加载同一 GIF,忽略");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
last_gif_filename = filename;
|
|
||||||
|
|
||||||
lv_obj_set_style_bg_color(lv_scr_act(), lv_color_black(), 0); // 背景黑色
|
|
||||||
lv_obj_set_style_bg_opa(lv_scr_act(), LV_OPA_COVER, 0); // 透明度
|
|
||||||
|
|
||||||
std::string fullPath = ToolsClass::makeFullPath(filename);
|
|
||||||
std::vector<uint8_t> gifBin = readWholeFile(fullPath);
|
|
||||||
if (gifBin.empty()) return;
|
|
||||||
|
|
||||||
uint32_t w = 0, h = 0;
|
|
||||||
if (!getGifWH(gifBin.data(), w, h)) return;
|
|
||||||
|
|
||||||
renderGifInternal(gifBin, w, h);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
/**
|
/**
|
||||||
* 本类为单例类,用于实现LVGL的渲染
|
* 本类为单例类,用于实现LVGL的渲染
|
||||||
* 封装了一整套的LVGL渲染流
|
* 封装了一整套的LVGL渲染流
|
||||||
* 同时兼顾了底层的显示驱动
|
* 同时兼顾了底层的显示驱动初始化
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
@@ -23,33 +23,12 @@ public:
|
|||||||
public:
|
public:
|
||||||
static LVGLRender* getInstance();
|
static LVGLRender* getInstance();
|
||||||
|
|
||||||
/**
|
|
||||||
* 全屏渲染gif动画
|
|
||||||
* @brief 渲染GIF文件
|
|
||||||
* @param filename GIF文件路径
|
|
||||||
*/
|
|
||||||
void RenderGif(const std::string &filename);
|
|
||||||
|
|
||||||
static void setFps(uint16_t fps_);
|
static void setFps(uint16_t fps_);
|
||||||
|
|
||||||
static uint16_t getFps();
|
static uint16_t getFps();
|
||||||
|
|
||||||
void tryToInitRenderGif();
|
void tryToInitRenderGif();
|
||||||
|
|
||||||
void log();
|
|
||||||
|
|
||||||
// gif渲染
|
|
||||||
private:
|
|
||||||
/* 同步读整个文件到 vector */
|
|
||||||
std::vector<uint8_t> readWholeFile(const std::string& path);
|
|
||||||
|
|
||||||
/* 从原始数据解析 GIF 宽高 */
|
|
||||||
bool getGifWH(const uint8_t* raw, uint32_t& w, uint32_t& h);
|
|
||||||
|
|
||||||
/* 真正的渲染实现(空壳,先打印日志) */
|
|
||||||
void renderGifInternal(const std::vector<uint8_t>& data,
|
|
||||||
uint32_t w, uint32_t h);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit LVGLRender(); // 构造函数私有化
|
explicit LVGLRender(); // 构造函数私有化
|
||||||
~LVGLRender();
|
~LVGLRender();
|
||||||
@@ -60,10 +39,6 @@ private:
|
|||||||
static std::mutex instance_mutex; /// 单例锁
|
static std::mutex instance_mutex; /// 单例锁
|
||||||
static uint16_t fps; /// 帧率
|
static uint16_t fps; /// 帧率
|
||||||
|
|
||||||
lv_obj_t* current_gif_obj = nullptr; /// 当前GIF对象
|
|
||||||
std::vector<uint8_t> current_gif_data; /// 当前GIF数据
|
|
||||||
std::string last_gif_filename; /// 最后一次渲染的GIF文件名
|
|
||||||
|
|
||||||
std::mutex mtx;
|
std::mutex mtx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,18 +2,17 @@
|
|||||||
// Created by misaki on 2025/9/26.
|
// Created by misaki on 2025/9/26.
|
||||||
//
|
//
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <atomic>
|
||||||
#include <esp_heap_caps.h>
|
#include <esp_heap_caps.h>
|
||||||
#include <esp_log.h>
|
#include <esp_log.h>
|
||||||
#include <lvgl.h>
|
#include <lvgl.h>
|
||||||
#include <font/lv_font.h>
|
#include <font/lv_font.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <optional>
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include "SDFileManager.h"
|
#include "SDFileManager.h"
|
||||||
#include "ToolsClass.h"
|
#include "ToolsClass.h"
|
||||||
LV_FONT_DECLARE(SiYuanHeiTiGoogleBan); // 思源黑体 Google版
|
LV_FONT_DECLARE(SiYuanHeiTiGoogleBan); // 思源黑体 Google版
|
||||||
namespace lvgl_cpp {
|
namespace lvgl_cpp {
|
||||||
|
|
||||||
// 前向声明
|
// 前向声明
|
||||||
class Obj;
|
class Obj;
|
||||||
class Screen;
|
class Screen;
|
||||||
@@ -28,13 +27,18 @@ class List;
|
|||||||
class TextArea;
|
class TextArea;
|
||||||
class Image;
|
class Image;
|
||||||
class IconButton;
|
class IconButton;
|
||||||
|
|
||||||
// 基础封装
|
// 基础封装
|
||||||
class Obj {
|
class Obj {
|
||||||
public:
|
public:
|
||||||
Obj() = default;
|
Obj() = default;
|
||||||
explicit Obj(lv_obj_t* raw) : ptr_(raw) {}
|
explicit Obj(lv_obj_t* raw) : ptr_(raw) {}
|
||||||
virtual ~Obj() { if (ptr_) lv_obj_del(ptr_); }
|
virtual ~Obj() {
|
||||||
|
if (ptr_ && lv_obj_is_valid(ptr_)) {
|
||||||
|
// 先移除所有事件回调
|
||||||
|
lv_obj_remove_event_cb_with_user_data(ptr_, event_trampoline, nullptr);
|
||||||
|
lv_obj_del(ptr_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Obj(Obj&& o) noexcept : ptr_(std::exchange(o.ptr_, nullptr)) {}
|
Obj(Obj&& o) noexcept : ptr_(std::exchange(o.ptr_, nullptr)) {}
|
||||||
Obj& operator=(Obj&& o) noexcept {
|
Obj& operator=(Obj&& o) noexcept {
|
||||||
@@ -48,9 +52,9 @@ public:
|
|||||||
void reset() { if (ptr_) { lv_obj_del(ptr_); ptr_ = nullptr; } }
|
void reset() { if (ptr_) { lv_obj_del(ptr_); ptr_ = nullptr; } }
|
||||||
|
|
||||||
// 通用链式
|
// 通用链式
|
||||||
Obj& size(const lv_coord_t w, const lv_coord_t h) { lv_obj_set_size(ptr_, w, h); return *this; }
|
virtual Obj& size(const lv_coord_t w, const lv_coord_t h) { lv_obj_set_size(ptr_, w, h); return *this; }
|
||||||
Obj& pos(const lv_coord_t x, const lv_coord_t y) { lv_obj_set_pos(ptr_, x, y); return *this; }
|
virtual Obj& pos(const lv_coord_t x, const lv_coord_t y) { lv_obj_set_pos(ptr_, x, y); return *this; }
|
||||||
Obj& center() { lv_obj_center(ptr_); return *this; }
|
virtual Obj& center() { lv_obj_center(ptr_); return *this; }
|
||||||
Obj& align(const lv_align_t align, const lv_obj_t* base = nullptr, const lv_coord_t x = 0, const lv_coord_t y = 0) {
|
Obj& align(const lv_align_t align, const lv_obj_t* base = nullptr, const lv_coord_t x = 0, const lv_coord_t y = 0) {
|
||||||
if (base) { // 如果有 base
|
if (base) { // 如果有 base
|
||||||
lv_obj_align_to(ptr_, base, align, x, y);
|
lv_obj_align_to(ptr_, base, align, x, y);
|
||||||
@@ -70,6 +74,10 @@ public:
|
|||||||
Obj& on(const lv_event_code_t code, EventCb cb) {
|
Obj& on(const lv_event_code_t code, EventCb cb) {
|
||||||
auto* ctx = new EventCb(std::move(cb));
|
auto* ctx = new EventCb(std::move(cb));
|
||||||
lv_obj_add_event_cb(ptr_, event_trampoline, code, ctx);
|
lv_obj_add_event_cb(ptr_, event_trampoline, code, ctx);
|
||||||
|
|
||||||
|
// 保存回调上下文以便后续清理
|
||||||
|
std::lock_guard<std::mutex> lock(event_mutex_);
|
||||||
|
event_contexts_.push_back(ctx);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
protected: // 改为 protected 以允许派生类访问
|
protected: // 改为 protected 以允许派生类访问
|
||||||
@@ -77,8 +85,16 @@ protected: // 改为 protected 以允许派生类访问
|
|||||||
private:
|
private:
|
||||||
static void event_trampoline(lv_event_t* e) {
|
static void event_trampoline(lv_event_t* e) {
|
||||||
const auto* ctx = static_cast<EventCb*>(lv_event_get_user_data(e));
|
const auto* ctx = static_cast<EventCb*>(lv_event_get_user_data(e));
|
||||||
|
lv_obj_t* obj = lv_event_get_target(e); // 获取事件对象
|
||||||
|
// 安全检查:确保对象仍然有效
|
||||||
|
if (!obj || !lv_obj_is_valid(obj) || !ctx) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
(*ctx)(e);
|
(*ctx)(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<EventCb*> event_contexts_;
|
||||||
|
std::mutex event_mutex_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 样式构造器
|
// 样式构造器
|
||||||
@@ -333,7 +349,7 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Toast 消息泡泡
|
// Toast 消息泡泡 TODO: 有严重空指针异常问题,需要fix
|
||||||
class Toast {
|
class Toast {
|
||||||
public:
|
public:
|
||||||
enum class Type : uint8_t { INFO, WARN, ERROR };
|
enum class Type : uint8_t { INFO, WARN, ERROR };
|
||||||
@@ -539,8 +555,8 @@ private:
|
|||||||
grad.stops[0].frac = 0;
|
grad.stops[0].frac = 0;
|
||||||
grad.stops[1].color = mainColor_;
|
grad.stops[1].color = mainColor_;
|
||||||
grad.stops[1].frac = 128;
|
grad.stops[1].frac = 128;
|
||||||
grad.stops[2].color = lv_color_darken(mainColor_, LV_OPA_30);
|
// grad.stops[2].color = lv_color_darken(mainColor_, LV_OPA_30);
|
||||||
grad.stops[2].frac = 255;
|
// grad.stops[2].frac = 255;
|
||||||
lv_obj_set_style_bg_grad(fill_, &grad, 0);
|
lv_obj_set_style_bg_grad(fill_, &grad, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -587,11 +603,154 @@ private:
|
|||||||
char buf_[64] = {0};
|
char buf_[64] = {0};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class LongPressButton : public Obj {
|
||||||
|
public:
|
||||||
|
explicit LongPressButton(const Obj& parent)
|
||||||
|
: Obj(lv_btn_create(parent.raw()))
|
||||||
|
{
|
||||||
|
// 基础事件
|
||||||
|
on(LV_EVENT_PRESSED, [this](lv_event_t*){ onPress(); });
|
||||||
|
on(LV_EVENT_RELEASED, [this](lv_event_t*){ onRelease(); });
|
||||||
|
on(LV_EVENT_PRESS_LOST,[this](lv_event_t*){ onRelease(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 链式外观
|
||||||
|
LongPressButton& size(const lv_coord_t w, const lv_coord_t h)
|
||||||
|
{ lv_obj_set_size(raw(), w, h); return *this; }
|
||||||
|
// 短按回调(主线程)
|
||||||
|
LongPressButton& onShort(std::function<void()> cb)
|
||||||
|
{ short_cb_ = std::move(cb); return *this; }
|
||||||
|
// 长按回调(工作线程循环,参数为停止标志)
|
||||||
|
LongPressButton& onLong(std::function<void(std::atomic<bool>&)> cb)
|
||||||
|
{ long_cb_ = std::move(cb); return *this; }
|
||||||
|
// 设置判定长按的超时时间,默认 400 ms
|
||||||
|
LongPressButton& longPressTimeout(const uint32_t ms)
|
||||||
|
{ long_timeout_ms_ = ms; return *this; }
|
||||||
|
|
||||||
|
~LongPressButton() override
|
||||||
|
{
|
||||||
|
stopThread();
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
// 按下
|
||||||
|
void onPress()
|
||||||
|
{
|
||||||
|
pressed_ = true;
|
||||||
|
stop_flag_ = false;
|
||||||
|
// 启动“长按判定定时器”
|
||||||
|
long_timer_ = lv_timer_create([](lv_timer_t* t){
|
||||||
|
auto* self = static_cast<LongPressButton*>(t->user_data);
|
||||||
|
self->onLongTimeout();
|
||||||
|
}, long_timeout_ms_, this);
|
||||||
|
lv_timer_set_repeat_count(long_timer_, 1); // 一次性
|
||||||
|
}
|
||||||
|
|
||||||
|
// 释放
|
||||||
|
void onRelease()
|
||||||
|
{
|
||||||
|
if (!pressed_) return;
|
||||||
|
pressed_ = false;
|
||||||
|
if (long_timer_) { // 还在跑 → 短按
|
||||||
|
lv_timer_del(long_timer_);
|
||||||
|
long_timer_ = nullptr;
|
||||||
|
if (short_cb_) short_cb_();
|
||||||
|
}
|
||||||
|
else { // 已进入长按模式
|
||||||
|
stopThread(); // 请求停止 + join
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 长按超时 → 启动工作线程
|
||||||
|
void onLongTimeout()
|
||||||
|
{
|
||||||
|
long_timer_ = nullptr; // 定时器自毁
|
||||||
|
if (!long_cb_) return;
|
||||||
|
// 启动工作线程
|
||||||
|
stop_flag_ = false;
|
||||||
|
thread_ = ThreadManager::createThread(
|
||||||
|
ThreadConfig{
|
||||||
|
.name = "lpbtn_worker",
|
||||||
|
.core_id = 1, // 可改
|
||||||
|
.stack_size = 4096,
|
||||||
|
.priority = 5
|
||||||
|
},
|
||||||
|
&LongPressButton::workerEntry, this);
|
||||||
|
}
|
||||||
|
// 工作线程入口
|
||||||
|
static void workerEntry(LongPressButton* self)
|
||||||
|
{
|
||||||
|
self->long_cb_(self->stop_flag_);
|
||||||
|
}
|
||||||
|
// 请求停止并等待线程结束
|
||||||
|
void stopThread()
|
||||||
|
{
|
||||||
|
if (thread_.joinable()) {
|
||||||
|
stop_flag_ = true;
|
||||||
|
thread_.join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::function<void()> short_cb_;
|
||||||
|
std::function<void(std::atomic<bool>&)> long_cb_;
|
||||||
|
uint32_t long_timeout_ms_ = 300; /// 默认 300 ms
|
||||||
|
|
||||||
|
lv_timer_t* long_timer_ = nullptr;
|
||||||
|
std::atomic<bool> pressed_{false};
|
||||||
|
std::atomic<bool> stop_flag_{false};
|
||||||
|
std::thread thread_;
|
||||||
|
};
|
||||||
|
|
||||||
// GIF 显示控件
|
// GIF 显示控件
|
||||||
class Gif final : public Obj {
|
class Gif final : public Obj {
|
||||||
public:
|
public:
|
||||||
explicit Gif(const Obj& parent) : Obj(lv_gif_create(parent.raw())) {}
|
explicit Gif(const Obj& parent) : Obj(lv_gif_create(parent.raw())) {}
|
||||||
|
~Gif() override {
|
||||||
|
// drop();
|
||||||
|
if (raw() && lv_obj_is_valid(raw()))
|
||||||
|
lv_gif_set_src(raw(), nullptr);
|
||||||
|
}
|
||||||
|
// 仅把 lv_obj 从树上摘下来,但不 delete 任何数据
|
||||||
|
void detach() {
|
||||||
|
if (raw() && lv_obj_is_valid(raw())) {
|
||||||
|
lv_obj_remove_style_all(raw()); // 清掉所有样式,防止刷新
|
||||||
|
lv_obj_clear_flag(raw(), LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_PRESS_LOCK);
|
||||||
|
lv_obj_move_foreground(raw()); // 移到最前,避免树遍历卡住
|
||||||
|
lv_obj_del_async(raw()); // 让 LVGL 在下一轮把 obj 删掉
|
||||||
|
ptr_ = nullptr; // 把基类保存的指针清零,防止再访问
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void stopTimer() {
|
||||||
|
if (raw() && lv_obj_is_valid(raw())) {
|
||||||
|
lv_gif_set_src(raw(), nullptr); // 再清解码器
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 异步释放 GIF 资源
|
||||||
|
void drop_async() {
|
||||||
|
if (!dsc_) return;
|
||||||
|
// 先让 LVGL 关闭解码器(需要 dsc_ 有效)
|
||||||
|
if (raw() && lv_obj_is_valid(raw()))
|
||||||
|
lv_gif_set_src(raw(), nullptr);
|
||||||
|
// 把 dsc_ 移出来(裸指针)
|
||||||
|
auto* keep = dsc_.release();
|
||||||
|
// 脱钩 obj
|
||||||
|
detach();
|
||||||
|
// 异步释放“纯数据”
|
||||||
|
lv_async_call([](void* p) {
|
||||||
|
auto* raw_dsc = static_cast<lv_img_dsc_t*>(p);
|
||||||
|
if (raw_dsc) {
|
||||||
|
if (raw_dsc->data) heap_caps_free(const_cast<uint8_t*>(raw_dsc->data));
|
||||||
|
delete raw_dsc;
|
||||||
|
}
|
||||||
|
}, keep);
|
||||||
|
}
|
||||||
|
// 主动释放解码缓冲区(必须在对象还活着时调用)
|
||||||
|
void drop() {
|
||||||
|
if (raw() && lv_obj_is_valid(raw())) {
|
||||||
|
lv_gif_set_src(raw(), nullptr); // 停定时器 gd_close_gif()
|
||||||
|
}
|
||||||
|
// 把内部指针清零,防止重复关闭
|
||||||
|
if (dsc_) {
|
||||||
|
dsc_.reset(); // 释放 dsc_ + PSRAM
|
||||||
|
}
|
||||||
|
}
|
||||||
bool getGifWH(const uint8_t* raw, uint32_t& w, uint32_t& h)
|
bool getGifWH(const uint8_t* raw, uint32_t& w, uint32_t& h)
|
||||||
{
|
{
|
||||||
if (!raw || memcmp(raw, "GIF", 3) != 0) {
|
if (!raw || memcmp(raw, "GIF", 3) != 0) {
|
||||||
@@ -607,8 +766,12 @@ public:
|
|||||||
|
|
||||||
// 从 SD 卡加载 GIF 文件(完整路径)
|
// 从 SD 卡加载 GIF 文件(完整路径)
|
||||||
Gif& src(const char* full_path) {
|
Gif& src(const char* full_path) {
|
||||||
|
if (raw() && lv_obj_is_valid(raw())) {
|
||||||
|
lv_gif_set_src(raw(), nullptr); // 停止旧解码器
|
||||||
|
}
|
||||||
|
|
||||||
// 读整个文件到 PSRAM
|
// 读整个文件到 PSRAM
|
||||||
std::string content = SDFileManager::getInstance()->readFileSync(ToolsClass::makeFullPath(full_path));
|
const std::string content = SDFileManager::getInstance()->readFileSync(ToolsClass::makeFullPath(full_path));
|
||||||
if (content.empty()) {
|
if (content.empty()) {
|
||||||
ESP_LOGE("Gif", "read %s fail", full_path);
|
ESP_LOGE("Gif", "read %s fail", full_path);
|
||||||
return *this;
|
return *this;
|
||||||
@@ -631,7 +794,7 @@ public:
|
|||||||
|
|
||||||
// 构造一次性描述符(跟随 Gif 对象生命周期)
|
// 构造一次性描述符(跟随 Gif 对象生命周期)
|
||||||
dsc_ = std::unique_ptr<lv_img_dsc_t, DscDeleter>(new lv_img_dsc_t{});
|
dsc_ = std::unique_ptr<lv_img_dsc_t, DscDeleter>(new lv_img_dsc_t{});
|
||||||
dsc_->header.cf = LV_IMG_CF_RAW_CHROMA_KEYED;
|
dsc_->header.cf = LV_IMG_CF_RAW_CHROMA_KEYED/*LV_IMG_CF_TRUE_COLOR_ALPHA*/;
|
||||||
dsc_->header.always_zero = 0;
|
dsc_->header.always_zero = 0;
|
||||||
dsc_->header.reserved = 0;
|
dsc_->header.reserved = 0;
|
||||||
dsc_->header.w = static_cast<lv_coord_t>(w);
|
dsc_->header.w = static_cast<lv_coord_t>(w);
|
||||||
@@ -641,6 +804,9 @@ public:
|
|||||||
|
|
||||||
// 交给 LVGL
|
// 交给 LVGL
|
||||||
lv_gif_set_src(raw(), dsc_.get());
|
lv_gif_set_src(raw(), dsc_.get());
|
||||||
|
lv_obj_clear_flag(raw(), LV_OBJ_FLAG_SCROLLABLE); // 禁止滚动
|
||||||
|
lv_obj_set_scroll_dir(raw(), LV_DIR_NONE);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -659,47 +825,275 @@ private:
|
|||||||
std::unique_ptr<lv_img_dsc_t, DscDeleter> dsc_;
|
std::unique_ptr<lv_img_dsc_t, DscDeleter> dsc_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// GIF 播放控件
|
||||||
|
class GifPlayer : public Obj {
|
||||||
|
public:
|
||||||
|
explicit GifPlayer(const Obj& parent) : Obj(lv_obj_create(parent.raw())) {
|
||||||
|
lv_obj_set_size(raw(), LV_SIZE_CONTENT, LV_SIZE_CONTENT);
|
||||||
|
lv_obj_clear_flag(raw(), LV_OBJ_FLAG_SCROLLABLE);
|
||||||
|
lv_obj_center(raw());
|
||||||
|
}
|
||||||
|
|
||||||
|
~GifPlayer() override { stop(); }
|
||||||
|
|
||||||
|
// 设置/切换轮播图 TODO: 切换轮播图的时候存在定时器空指针重复释放问题
|
||||||
|
GifPlayer& loop(const char* path, const uint32_t duration = 5000) {
|
||||||
|
loop_path_ = path ? path : "";
|
||||||
|
loop_duration_ = duration;
|
||||||
|
if (!in_burst_) show_loop();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 插播一张图;播完自动回到轮播
|
||||||
|
GifPlayer& burst(const char* path, const uint32_t duration = 5000) {
|
||||||
|
if (!path || !*path) return *this;
|
||||||
|
in_burst_ = true;
|
||||||
|
show_burst(path); // 创建并显示突发图
|
||||||
|
burst_timer_ = lv_timer_create(
|
||||||
|
[](lv_timer_t* t){
|
||||||
|
auto* self = static_cast<GifPlayer*>(t->user_data);
|
||||||
|
self->in_burst_ = false;
|
||||||
|
if (self->burst_gif_) self->burst_gif_->drop_async();
|
||||||
|
self->burst_gif_->drop_async(); // 内部已把 obj 和数据都处理完
|
||||||
|
self->burst_gif_.reset(); // 只把 unique_ptr 置空,不再访问 obj
|
||||||
|
if (!self->loop_path_.empty()) self->show_loop();
|
||||||
|
lv_timer_del(t);
|
||||||
|
self->burst_timer_ = nullptr;
|
||||||
|
}, duration, this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 停止并释放所有资源
|
||||||
|
void stop() {
|
||||||
|
if (burst_timer_) {
|
||||||
|
lv_timer_del(burst_timer_);
|
||||||
|
burst_timer_ = nullptr;
|
||||||
|
}
|
||||||
|
burst_gif_.reset();
|
||||||
|
loop_gif_.reset();
|
||||||
|
in_burst_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void show_loop() {
|
||||||
|
if (burst_gif_) lv_obj_add_flag(burst_gif_->raw(), LV_OBJ_FLAG_HIDDEN);
|
||||||
|
if (!loop_gif_) {
|
||||||
|
loop_gif_ = std::make_unique<Gif>(*this);
|
||||||
|
(void)loop_gif_->raw();
|
||||||
|
}
|
||||||
|
lv_obj_clear_flag(loop_gif_->raw(), LV_OBJ_FLAG_HIDDEN);
|
||||||
|
loop_gif_->src(loop_path_.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void show_burst(const char* path) {
|
||||||
|
if (!burst_gif_) {
|
||||||
|
burst_gif_ = std::make_unique<Gif>(*this);
|
||||||
|
(void)burst_gif_->raw();
|
||||||
|
}
|
||||||
|
lv_obj_clear_flag(burst_gif_->raw(), LV_OBJ_FLAG_HIDDEN);
|
||||||
|
if (loop_gif_) lv_obj_add_flag(loop_gif_->raw(), LV_OBJ_FLAG_HIDDEN);
|
||||||
|
burst_gif_->src(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool in_burst_ = false;
|
||||||
|
std::string loop_path_;
|
||||||
|
uint32_t loop_duration_ = 5000;
|
||||||
|
lv_timer_t* burst_timer_ = nullptr;
|
||||||
|
std::unique_ptr<Gif> loop_gif_;
|
||||||
|
std::unique_ptr<Gif> burst_gif_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 纯文字透明浮层
|
||||||
|
class TextOverlay : public Obj {
|
||||||
|
public:
|
||||||
|
explicit TextOverlay(const Obj& parent)
|
||||||
|
: Obj(lv_label_create(parent.raw()))
|
||||||
|
{
|
||||||
|
// 初始化为透明背景
|
||||||
|
lv_obj_set_style_bg_opa(raw(), LV_OPA_TRANSP, 0);
|
||||||
|
lv_obj_set_style_pad_all(raw(), 0, 0); // 去掉内边距,真正的“裸文字”
|
||||||
|
lv_obj_clear_flag(raw(), LV_OBJ_FLAG_SCROLLABLE); // 不需要滚动
|
||||||
|
lv_label_set_long_mode(raw(), LV_LABEL_LONG_WRAP); // 自动换行
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文字内容
|
||||||
|
TextOverlay& text(const char* txt) {
|
||||||
|
lv_label_set_text(raw(), txt);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
TextOverlay& text_fmt(const char* fmt, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
// 先用栈缓冲格式化,再交给 LVGL
|
||||||
|
char buf[128];
|
||||||
|
vsnprintf(buf, sizeof(buf), fmt, args);
|
||||||
|
lv_label_set_text(raw(), buf);
|
||||||
|
va_end(args);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文字颜色,默认白色
|
||||||
|
TextOverlay& textColor(const lv_color_t c) {
|
||||||
|
lv_obj_set_style_text_color(raw(), c, 0);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 字体,默认 &SiYuanHeiTiGoogleBan
|
||||||
|
TextOverlay& font(const lv_font_t* fnt) {
|
||||||
|
lv_obj_set_style_text_font(raw(), fnt, 0);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对齐方式:LEFT / CENTER / RIGHT
|
||||||
|
TextOverlay& alignText(const lv_text_align_t align) {
|
||||||
|
lv_obj_set_style_text_align(raw(), align, 0);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 快速定位(沿用 Obj 的 align 链式)
|
||||||
|
TextOverlay& place(const lv_align_t align,
|
||||||
|
const lv_obj_t* base = nullptr,
|
||||||
|
const lv_coord_t x = 0,
|
||||||
|
const lv_coord_t y = 0)
|
||||||
|
{
|
||||||
|
this->align(align, base, x, y);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 是否让文字区域可点击(默认不可点击)
|
||||||
|
TextOverlay& clickable(const bool en = true) {
|
||||||
|
if (en) lv_obj_add_flag(raw(), LV_OBJ_FLAG_CLICKABLE);
|
||||||
|
else lv_obj_clear_flag(raw(), LV_OBJ_FLAG_CLICKABLE);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 子应用抽象
|
// 子应用抽象
|
||||||
class BaseApp : public Obj {
|
class BaseApp : public Obj {
|
||||||
public:
|
public:
|
||||||
explicit BaseApp(const Obj& parent) : Obj(lv_obj_create(parent.raw())), btn_exit_(parent) {
|
explicit BaseApp(const Obj& parent) : Obj(lv_obj_create(parent.raw())) {
|
||||||
lv_obj_set_size(raw(), 360, 360);
|
lv_obj_set_size(raw(), 360, 360);
|
||||||
// 退出按钮
|
|
||||||
btn_exit_.size(40, 40)
|
// 创建退出按钮
|
||||||
.align(LV_ALIGN_CENTER, nullptr, 0, -130) // 居中
|
btn_exit_ = std::make_unique<Button>(*this);
|
||||||
.on(LV_EVENT_CLICKED, [this](lv_event_t *) { this->exit(); });
|
label_ = std::make_unique<Label>(*btn_exit_);
|
||||||
label_.align(LV_ALIGN_CENTER, nullptr, 0, 0);
|
|
||||||
label_.text(LV_SYMBOL_CLOSE);
|
// 设置按钮位置和样式
|
||||||
|
btn_exit_->size(40, 40)
|
||||||
|
.align(LV_ALIGN_CENTER, nullptr, 0, -100)
|
||||||
|
.add_style(&getExitButtonStyle());
|
||||||
|
|
||||||
|
label_->text(LV_SYMBOL_CLOSE);
|
||||||
|
label_->center();
|
||||||
|
lv_obj_set_style_text_color(label_->raw(), lv_color_white(), 0);
|
||||||
|
lv_obj_set_style_text_font(label_->raw(), &lv_font_montserrat_16, 0);
|
||||||
|
|
||||||
|
// 使用更安全的事件绑定方式
|
||||||
|
setupExitButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 子类重写:界面内容
|
~BaseApp() override {
|
||||||
virtual void onShow() {} // 进入时调用
|
// 标记为正在销毁
|
||||||
virtual void onHide() {} // 退出时调用
|
is_destroying_ = true;
|
||||||
|
|
||||||
|
// 先清理子对象
|
||||||
|
label_.reset();
|
||||||
|
btn_exit_.reset();
|
||||||
|
|
||||||
|
// 如果ptr_仍然有效,安全删除
|
||||||
|
if (ptr_ && lv_obj_is_valid(ptr_)) {
|
||||||
|
// 先隐藏对象,停止所有交互
|
||||||
|
lv_obj_add_flag(ptr_, LV_OBJ_FLAG_HIDDEN);
|
||||||
|
|
||||||
|
// 延迟删除,确保所有事件处理完成
|
||||||
|
lv_timer_create([](lv_timer_t* timer) {
|
||||||
|
lv_obj_t* obj = static_cast<lv_obj_t*>(timer->user_data);
|
||||||
|
if (obj && lv_obj_is_valid(obj)) {
|
||||||
|
lv_obj_del(obj);
|
||||||
|
}
|
||||||
|
lv_timer_del(timer);
|
||||||
|
}, 100, ptr_); // 延迟100ms删除
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 主动退出
|
|
||||||
void exit() {
|
void exit() {
|
||||||
|
if (is_exiting_) return;
|
||||||
|
is_exiting_ = true;
|
||||||
|
onCleanup();
|
||||||
onHide();
|
onHide();
|
||||||
// 禁止自己再被点击
|
|
||||||
lv_obj_clear_flag(raw(), LV_OBJ_FLAG_CLICKABLE);
|
|
||||||
|
|
||||||
// 异步自毁:让 LVGL 在下一轮循环再删我们
|
// 立即隐藏并禁用
|
||||||
lv_async_call([](void* self) {
|
if (ptr_ && lv_obj_is_valid(ptr_)) {
|
||||||
lv_obj_del(static_cast<lv_obj_t*>(self));
|
lv_obj_add_flag(ptr_, LV_OBJ_FLAG_HIDDEN);
|
||||||
}, raw());
|
lv_obj_clear_flag(ptr_, LV_OBJ_FLAG_CLICKABLE);
|
||||||
// 通知工厂回到主页 → 由工厂/菜单负责
|
|
||||||
if (exit_cb_) exit_cb_();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 注册退出通知回调(由 AppFactory 设置)
|
// 通知退出回调
|
||||||
void onExit(std::function<void()> cb) { exit_cb_ = std::move(cb); }
|
if (exit_cb_) {
|
||||||
|
exit_cb_();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 延迟自毁
|
||||||
|
auto self = this;
|
||||||
|
lv_timer_create([](lv_timer_t* timer) {
|
||||||
|
const auto* app = static_cast<BaseApp*>(timer->user_data);
|
||||||
|
if (app && app->ptr_ && lv_obj_is_valid(app->ptr_)) {
|
||||||
|
lv_obj_del(app->ptr_);
|
||||||
|
}
|
||||||
|
lv_timer_del(timer);
|
||||||
|
}, 50, this); // 50ms后删除
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void onShow() {}
|
||||||
|
virtual void onHide() {}
|
||||||
|
|
||||||
|
void onExit(std::function<void()> cb) { exit_cb_ = std::move(cb); }
|
||||||
protected:
|
protected:
|
||||||
Button btn_exit_{*this}; // 退出按钮
|
// 子类有需要就重写, 用于释放资源
|
||||||
Label label_{btn_exit_}; // 退出图标
|
virtual void onCleanup() {}
|
||||||
|
protected:
|
||||||
|
std::unique_ptr<Button> btn_exit_;
|
||||||
|
std::unique_ptr<Label> label_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::function<void()> exit_cb_;
|
std::function<void()> exit_cb_;
|
||||||
|
std::atomic<bool> is_exiting_{false};
|
||||||
|
std::atomic<bool> is_destroying_{false};
|
||||||
|
|
||||||
|
void setupExitButton() {
|
||||||
|
// 使用原始LVGL事件,避免C++回调问题
|
||||||
|
lv_obj_add_event_cb(btn_exit_->raw(), [](lv_event_t* e) {
|
||||||
|
lv_obj_t* btn = lv_event_get_target(e);
|
||||||
|
if (!btn || !lv_obj_is_valid(btn)) return;
|
||||||
|
|
||||||
|
lv_obj_t* parent = lv_obj_get_parent(btn);
|
||||||
|
if (!parent || !lv_obj_is_valid(parent)) return;
|
||||||
|
|
||||||
|
// 通过用户数据找到BaseApp实例
|
||||||
|
auto* app = static_cast<BaseApp*>(lv_obj_get_user_data(parent));
|
||||||
|
if (app && !app->is_exiting_ && !app->is_destroying_) {
|
||||||
|
app->exit();
|
||||||
|
}
|
||||||
|
}, LV_EVENT_CLICKED, this);
|
||||||
|
|
||||||
|
// 保存this指针到用户数据
|
||||||
|
lv_obj_set_user_data(raw(), this);
|
||||||
|
}
|
||||||
|
|
||||||
|
static lv_style_t& getExitButtonStyle() {
|
||||||
|
static lv_style_t style;
|
||||||
|
static bool style_initialized = false;
|
||||||
|
|
||||||
|
if (!style_initialized) {
|
||||||
|
lv_style_init(&style);
|
||||||
|
lv_style_set_bg_color(&style, lv_color_hex(0xFF3B30));
|
||||||
|
lv_style_set_bg_opa(&style, LV_OPA_COVER);
|
||||||
|
lv_style_set_radius(&style, 20);
|
||||||
|
lv_style_set_border_width(&style, 0);
|
||||||
|
style_initialized = true;
|
||||||
|
}
|
||||||
|
return style;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 子应用工厂
|
// 子应用工厂
|
||||||
@@ -731,11 +1125,12 @@ public:
|
|||||||
lv_obj_set_style_bg_opa(raw(), LV_OPA_TRANSP, 0);
|
lv_obj_set_style_bg_opa(raw(), LV_OPA_TRANSP, 0);
|
||||||
lv_obj_set_style_border_width(raw(), 0, 0);
|
lv_obj_set_style_border_width(raw(), 0, 0);
|
||||||
lv_obj_clear_flag(raw(), LV_OBJ_FLAG_SCROLLABLE); // 圆形屏建议不要滚动
|
lv_obj_clear_flag(raw(), LV_OBJ_FLAG_SCROLLABLE); // 圆形屏建议不要滚动
|
||||||
lv_obj_set_style_pad_top(raw(), 60, 0); // ← 新增
|
lv_obj_set_style_pad_top(raw(), 100, 0); // 增加顶部内边距为返回按钮留空间
|
||||||
lv_obj_set_style_pad_bottom(raw(),60, 0); // ← 新增
|
lv_obj_set_style_pad_bottom(raw(),60, 0); // ← 新增
|
||||||
lv_obj_set_style_pad_left(raw(), 20, 0);
|
lv_obj_set_style_pad_left(raw(), 20, 0);
|
||||||
lv_obj_set_style_pad_right(raw(), 20, 0);
|
lv_obj_set_style_pad_right(raw(), 20, 0);
|
||||||
|
// 创建返回主页按钮(放在顶部)
|
||||||
|
createBackButton();
|
||||||
// 横向 2 列,居中排列
|
// 横向 2 列,居中排列
|
||||||
lv_obj_set_flex_flow(raw(), LV_FLEX_FLOW_ROW_WRAP);
|
lv_obj_set_flex_flow(raw(), LV_FLEX_FLOW_ROW_WRAP);
|
||||||
lv_obj_set_flex_align(raw(), LV_FLEX_ALIGN_SPACE_EVENLY,
|
lv_obj_set_flex_align(raw(), LV_FLEX_ALIGN_SPACE_EVENLY,
|
||||||
@@ -775,9 +1170,81 @@ public:
|
|||||||
click_cb_ = std::move(cb);
|
click_cb_ = std::move(cb);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
// 注册返回主页回调
|
||||||
|
AppMenu& onBack(std::function<void()> cb) {
|
||||||
|
back_cb_ = std::move(cb);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
void createBackButton() {
|
||||||
|
// 创建返回按钮容器(固定在顶部)
|
||||||
|
back_btn_ = std::make_unique<Button>(*this);
|
||||||
|
back_label_ = std::make_unique<Label>(*back_btn_);
|
||||||
|
|
||||||
|
// 设置返回按钮样式
|
||||||
|
back_btn_->size(120, 40)
|
||||||
|
.align(LV_ALIGN_TOP_MID, nullptr, 0, 20) // 顶部中间,向下偏移20px
|
||||||
|
.add_style(&getBackButtonStyle());
|
||||||
|
|
||||||
|
back_label_->text("返回主页");
|
||||||
|
back_label_->center();
|
||||||
|
lv_obj_set_style_text_color(back_label_->raw(), lv_color_white(), 0);
|
||||||
|
lv_obj_set_style_text_font(back_label_->raw(), &SiYuanHeiTiGoogleBan, LV_PART_MAIN);
|
||||||
|
|
||||||
|
// 返回按钮点击事件
|
||||||
|
lv_obj_add_event_cb(back_btn_->raw(), [](lv_event_t* e) {
|
||||||
|
// lv_obj_t* target = lv_event_get_target(e);
|
||||||
|
// ESP_LOGI("BackButton", "收到事件: %d, 对象: %p", code, target);
|
||||||
|
switch(lv_event_get_code(e)) {
|
||||||
|
case LV_EVENT_PRESSED: {
|
||||||
|
ESP_LOGI("BackButton", "按钮按下");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LV_EVENT_RELEASED: {
|
||||||
|
ESP_LOGI("BackButton", "按钮释放");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LV_EVENT_CLICKED: {
|
||||||
|
ESP_LOGI("BackButton", "按钮点击!!!");
|
||||||
|
// 处理点击事件
|
||||||
|
lv_obj_t* btn = lv_event_get_target(e);
|
||||||
|
lv_obj_t* menu_obj = lv_obj_get_parent(btn);
|
||||||
|
auto* menu = static_cast<AppMenu*>(lv_obj_get_user_data(menu_obj));
|
||||||
|
if (menu && menu->back_cb_) {
|
||||||
|
ESP_LOGI("BackButton", "执行返回回调");
|
||||||
|
menu->back_cb_();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, LV_EVENT_CLICKED, nullptr);
|
||||||
|
// 确保设置用户数据
|
||||||
|
lv_obj_set_user_data(raw(), this);
|
||||||
|
// ESP_LOGI("AppMenu", "返回按钮创建完成, 按钮地址: %p", back_btn_->raw());
|
||||||
|
}
|
||||||
|
|
||||||
|
static lv_style_t& getBackButtonStyle() {
|
||||||
|
static lv_style_t style;
|
||||||
|
static bool style_initialized = false;
|
||||||
|
|
||||||
|
if (!style_initialized) {
|
||||||
|
lv_style_init(&style);
|
||||||
|
lv_style_set_bg_color(&style, lv_color_hex(0x4CAF50)); // 绿色背景
|
||||||
|
lv_style_set_bg_opa(&style, LV_OPA_COVER);
|
||||||
|
lv_style_set_radius(&style, 20);
|
||||||
|
lv_style_set_border_width(&style, 0);
|
||||||
|
style_initialized = true;
|
||||||
|
}
|
||||||
|
return style;
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
std::function<void(const char*)> click_cb_;
|
std::function<void(const char*)> click_cb_;
|
||||||
|
std::function<void()> back_cb_;
|
||||||
|
std::unique_ptr<Button> back_btn_;
|
||||||
|
std::unique_ptr<Label> back_label_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 主页
|
// 主页
|
||||||
@@ -794,44 +1261,37 @@ public:
|
|||||||
|
|
||||||
// 背景图片(默认空,可热切换)
|
// 背景图片(默认空,可热切换)
|
||||||
bg_img_ = std::make_unique<Image>(*this);
|
bg_img_ = std::make_unique<Image>(*this);
|
||||||
|
|
||||||
// 顶栏电池
|
// 顶栏电池
|
||||||
battery_ = std::make_unique<Battery>(*this);
|
battery_ = std::make_unique<Battery>(*this);
|
||||||
battery_->size(60, 30)
|
battery_->size(60, 30)
|
||||||
.percent(true)
|
.percent(true)
|
||||||
.align(LV_ALIGN_CENTER, -10, -150);
|
.align(LV_ALIGN_CENTER, -10, -150);
|
||||||
|
|
||||||
// 底栏时间
|
// 底栏时间
|
||||||
datetime_ = std::make_unique<DateTime>(*this);
|
datetime_ = std::make_unique<DateTime>(*this);
|
||||||
datetime_->format("%m/%d %a %H:%M")
|
datetime_->format("%m/%d %a %H:%M")
|
||||||
.align(LV_ALIGN_BOTTOM_MID, nullptr, 0, -10);
|
.align(LV_ALIGN_BOTTOM_MID, nullptr, 0, -10);
|
||||||
|
|
||||||
// 长按识别:按住 500 ms 即进入应用菜单
|
// 长按识别:按住 500 ms 即进入应用菜单
|
||||||
lv_obj_add_flag(raw(), LV_OBJ_FLAG_CLICKABLE); // 必须置位,否则收不到输入事件
|
lv_obj_add_flag(raw(), LV_OBJ_FLAG_CLICKABLE); // 必须置位,否则收不到输入事件
|
||||||
on(LV_EVENT_LONG_PRESSED, [this](lv_event_t*) {
|
on(LV_EVENT_LONG_PRESSED, [this](lv_event_t*) {
|
||||||
if (menu_open_cb_) menu_open_cb_();
|
if (menu_open_cb_) menu_open_cb_();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 热切换背景
|
// 热切换背景
|
||||||
HomePage& bg(const char* bin_path, const uint32_t w, const uint32_t h) {
|
HomePage& bg(const char* bin_path, const uint32_t w, const uint32_t h) {
|
||||||
bg_img_->bin(bin_path, w, h);
|
bg_img_->bin(bin_path, w, h);
|
||||||
bg_img_->center();
|
bg_img_->center();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 注册电量回调
|
// 注册电量回调
|
||||||
HomePage& onBattery(std::function<uint8_t()> cb) {
|
HomePage& onBattery(std::function<uint8_t()> cb) {
|
||||||
battery_->onRead(std::move(cb));
|
battery_->onRead(std::move(cb));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 注册时间回调
|
// 注册时间回调
|
||||||
HomePage& onDateTime(std::function<void(char*, size_t)> cb) {
|
HomePage& onDateTime(std::function<void(char*, size_t)> cb) {
|
||||||
datetime_->onRead(std::move(cb));
|
datetime_->onRead(std::move(cb));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 注册右滑 → 打开菜单的回调
|
// 注册右滑 → 打开菜单的回调
|
||||||
HomePage& onOpenMenu(std::function<void()> cb) {
|
HomePage& onOpenMenu(std::function<void()> cb) {
|
||||||
menu_open_cb_ = std::move(cb);
|
menu_open_cb_ = std::move(cb);
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
//
|
||||||
|
// Created by misaki on 2025/9/28.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "BaseApp.h"
|
||||||
@@ -0,0 +1,415 @@
|
|||||||
|
//
|
||||||
|
// Created by misaki on 2025/9/28.
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
#include <optional>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "lvpp.h"
|
||||||
|
#include "cpp_json.h"
|
||||||
|
#include "CommClass.h"
|
||||||
|
LV_FONT_DECLARE(SiYuanHeiTiGoogleBan); // 引入字体
|
||||||
|
struct AppCalc : lvgl_cpp::BaseApp {
|
||||||
|
using BaseApp::BaseApp;
|
||||||
|
void onShow() override {
|
||||||
|
lvgl_cpp::Label(*this).text("Calculator").center();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct AppMusic : lvgl_cpp::BaseApp {
|
||||||
|
using BaseApp::BaseApp;
|
||||||
|
void onShow() override {
|
||||||
|
btn_.emplace(*this);
|
||||||
|
gif.emplace(*this);
|
||||||
|
btn_->size(180, 60)
|
||||||
|
.align(LV_ALIGN_CENTER, nullptr, 0, 80)
|
||||||
|
.on(LV_EVENT_CLICKED, [&](lv_event_t*) {
|
||||||
|
// 居中 GIF,背景黑
|
||||||
|
lv_obj_set_style_bg_color(this->raw(), lv_color_black(), 0);
|
||||||
|
lv_obj_clear_flag(this->raw(), LV_OBJ_FLAG_SCROLLABLE); // 禁止滚动
|
||||||
|
lv_obj_set_scroll_dir(this->raw(), LV_DIR_NONE);
|
||||||
|
|
||||||
|
lv_obj_set_style_bg_opa(this->raw(), LV_OPA_COVER, 0);
|
||||||
|
gif->src("sequence02mmm.gif")
|
||||||
|
.center();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 按钮文字
|
||||||
|
lv_obj_t* label = lv_label_create(btn_->raw());
|
||||||
|
lv_obj_set_style_text_font(label, &SiYuanHeiTiGoogleBan, LV_PART_MAIN);
|
||||||
|
lv_label_set_text(label, "Gif测试");
|
||||||
|
lv_obj_center(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onCleanup() override {
|
||||||
|
if (gif) gif->drop(); // 对象还活着,立即释放
|
||||||
|
}
|
||||||
|
|
||||||
|
~AppMusic() override{
|
||||||
|
gif.reset();
|
||||||
|
btn_.reset();
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::optional<lvgl_cpp::Button> btn_; // c++17 轻量 RAII
|
||||||
|
std::optional<lvgl_cpp::Gif> gif;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ButtonApp : public lvgl_cpp::BaseApp {
|
||||||
|
public:
|
||||||
|
using BaseApp::BaseApp; // 继承 exit 按钮机制
|
||||||
|
|
||||||
|
void onShow() override {
|
||||||
|
/* 居中按钮:180×60 px,圆角,现代蓝 */
|
||||||
|
btn_.emplace(*this);
|
||||||
|
btn_->size(180, 60)
|
||||||
|
.align(LV_ALIGN_CENTER, nullptr, 0, 80)
|
||||||
|
.on(LV_EVENT_CLICKED, [](lv_event_t*) {
|
||||||
|
lvgl_cpp::Toast::show("咕咕嘎嘎!",
|
||||||
|
lvgl_cpp::Toast::Type::INFO,
|
||||||
|
1000);
|
||||||
|
});
|
||||||
|
/* 按钮文字 */
|
||||||
|
lv_obj_t* label = lv_label_create(btn_->raw());
|
||||||
|
lv_obj_set_style_text_font(label, &SiYuanHeiTiGoogleBan, LV_PART_MAIN);
|
||||||
|
lv_label_set_text(label, "按我");
|
||||||
|
lv_obj_center(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::optional<lvgl_cpp::Button> btn_; // c++17 轻量 RAII
|
||||||
|
};
|
||||||
|
|
||||||
|
class WebSocketVoice : public lvgl_cpp::BaseApp {
|
||||||
|
public:
|
||||||
|
using BaseApp::BaseApp; // 继承 exit 按钮机制
|
||||||
|
|
||||||
|
void onShow() override {
|
||||||
|
/* 居中按钮:180×60 px,圆角,现代蓝 */
|
||||||
|
btn_.emplace(*this);
|
||||||
|
btn_->size(180, 60)
|
||||||
|
.align(LV_ALIGN_CENTER, nullptr, 0, 80)
|
||||||
|
.on(LV_EVENT_CLICKED, [](lv_event_t*) {
|
||||||
|
lvgl_cpp::Toast::show("测试!",
|
||||||
|
lvgl_cpp::Toast::Type::ERROR,
|
||||||
|
1000);
|
||||||
|
});
|
||||||
|
/* 按钮文字 */
|
||||||
|
lv_obj_t* label = lv_label_create(btn_->raw());
|
||||||
|
lv_obj_set_style_text_font(label, &SiYuanHeiTiGoogleBan, LV_PART_MAIN);
|
||||||
|
lv_label_set_text(label, "按我");
|
||||||
|
lv_obj_center(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::optional<lvgl_cpp::Button> btn_; // c++17 轻量 RAII
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "SDFileManager.h"
|
||||||
|
#include "SimpleI2SForwarder.h"
|
||||||
|
#include <mbedtls/base64.h> // base64 编解码
|
||||||
|
class LongPressButtonAnim : public lvgl_cpp::BaseApp {
|
||||||
|
public:
|
||||||
|
using BaseApp::BaseApp; // 继承 exit 按钮机制
|
||||||
|
|
||||||
|
void onShow() override {
|
||||||
|
/* 居中按钮:180×60 px,圆角,现代蓝 */
|
||||||
|
btn_.emplace(*this);
|
||||||
|
btn_->size(180, 60)
|
||||||
|
.align(LV_ALIGN_CENTER, nullptr, 0, 80);
|
||||||
|
btn_->onLong([](const std::atomic<bool>& stop) { // 长按循环按钮
|
||||||
|
std::vector<int16_t> audio_data;
|
||||||
|
std::vector<int16_t> audio_data_sum;
|
||||||
|
constexpr int SHIFT_AVE = 14; // 你喂 AFE 时右移的位数
|
||||||
|
constexpr int GAIN_SHIFT = 14 - 9; // 想拉回 0 dB 需要左移多少
|
||||||
|
ESP_LOGI("LP","开始录音");
|
||||||
|
while(!stop){
|
||||||
|
// 获取所有可用的最新数据,并累加到 audio_data_sum 当中
|
||||||
|
if (LatestDataForwarder::getInstance()->retrieveLatestData(audio_data, 100)) {
|
||||||
|
// 放大到正常幅度再累加(放大声音)
|
||||||
|
for (auto &s : audio_data) {
|
||||||
|
int32_t tmp = static_cast<int32_t>(s) << GAIN_SHIFT; // 能量拉回 0 dB
|
||||||
|
if (tmp > 32767) tmp = 32767;
|
||||||
|
if (tmp < -32768) tmp = -32768;
|
||||||
|
audio_data_sum.push_back(static_cast<int16_t>(tmp));
|
||||||
|
}
|
||||||
|
// ESP_LOGI("LP", "got %zu samples, total now %zu",
|
||||||
|
// audio_data.size(), audio_data_sum.size());
|
||||||
|
} else {
|
||||||
|
ESP_LOGW("LP", "no data within 100 ms");
|
||||||
|
}
|
||||||
|
// vTaskDelay(pdMS_TO_TICKS(5));
|
||||||
|
}
|
||||||
|
ESP_LOGI("LP","结束录音");
|
||||||
|
// 在SD卡根目录创建一个pcm文件,向其中写入数据
|
||||||
|
// ESP_LOGI("LP","开始写入文件");
|
||||||
|
// SDFileManager::getInstance()->writeFileSync(
|
||||||
|
// ToolsClass::makeFullPath("temp_little_endian_16bit_16khz.pcm").c_str(),
|
||||||
|
// reinterpret_cast<const char *>(audio_data_sum.data()),
|
||||||
|
// audio_data_sum.size() * sizeof(int16_t),
|
||||||
|
// "wb");
|
||||||
|
// ESP_LOGI("LP","写入文件成功");
|
||||||
|
// 将数据封装成 json 后通过 websocket 发送给服务器
|
||||||
|
ESP_LOGI("LP","开始发送数据");
|
||||||
|
size_t pcm_bytes = audio_data_sum.size() * sizeof(int16_t);
|
||||||
|
size_t b64_len = 0;
|
||||||
|
mbedtls_base64_encode(nullptr, 0, &b64_len,
|
||||||
|
reinterpret_cast<const unsigned char*>(audio_data_sum.data()),
|
||||||
|
pcm_bytes);
|
||||||
|
/* 再真正编码 */
|
||||||
|
std::vector<unsigned char> b64_buf(b64_len);
|
||||||
|
mbedtls_base64_encode(b64_buf.data(), b64_len, &b64_len,
|
||||||
|
reinterpret_cast<const unsigned char*>(audio_data_sum.data()),
|
||||||
|
pcm_bytes);
|
||||||
|
/* 转成 std::string(不含 \0) */
|
||||||
|
std::string b64_str(reinterpret_cast<char*>(b64_buf.data()), b64_len);
|
||||||
|
cppjson::Json audio_json = cppjson::Json::object(); // 创建 json 对象
|
||||||
|
cppjson::Json audio_json_body = cppjson::Json::object();
|
||||||
|
audio_json.set("type", cppjson::Json("audio"));
|
||||||
|
audio_json_body
|
||||||
|
.set("data", cppjson::Json(b64_str))
|
||||||
|
.set("size", cppjson::Json(audio_data_sum.size()));
|
||||||
|
audio_json.set("body", audio_json_body);
|
||||||
|
WebSocketManager::getInstance()->sendJson(audio_json);
|
||||||
|
ESP_LOGI("LP","发送数据 OVER!");
|
||||||
|
ESP_LOGI("LP","long exit");
|
||||||
|
});
|
||||||
|
btn_->onShort([]() { // 短按(点一下)
|
||||||
|
ESP_LOGI("Btn", "short click");
|
||||||
|
});
|
||||||
|
|
||||||
|
/* 按钮文字 */
|
||||||
|
lv_obj_t* label = lv_label_create(btn_->raw());
|
||||||
|
lv_obj_set_style_text_font(label, &SiYuanHeiTiGoogleBan, LV_PART_MAIN);
|
||||||
|
lv_label_set_text(label, "长按录音");
|
||||||
|
lv_obj_center(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::optional<lvgl_cpp::LongPressButton> btn_; // c++17 轻量 RAII
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#include "SpeechRecognizer.h"
|
||||||
|
#include "AudioOutput.h"
|
||||||
|
#include "PetBaseClass.h"
|
||||||
|
#include "PetDao.h"
|
||||||
|
class PetApp : public lvgl_cpp::BaseApp {
|
||||||
|
public:
|
||||||
|
using BaseApp::BaseApp; // 继承 exit 按钮机制
|
||||||
|
|
||||||
|
// 打印宠物当前状态
|
||||||
|
static void printPet(const PetBase& pet)
|
||||||
|
{
|
||||||
|
const auto& info = pet.getPetInfo();
|
||||||
|
std::cout << "【状态】"
|
||||||
|
<< " 名称:" << info.pet_name
|
||||||
|
<< " HP:" << info.pet_hp
|
||||||
|
<< " 亲密度:" << info.pet_density
|
||||||
|
<< " 身份:" << info.pet_identity
|
||||||
|
<< " 阶段:" << static_cast<int>(pet.getCurrentStage())
|
||||||
|
<< " 动作:" << static_cast<int>(pet.getCurrentAction())
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化测试宠物信息
|
||||||
|
void initPet() {
|
||||||
|
// 创建雪豹
|
||||||
|
PetBaseInfo info{
|
||||||
|
.pet_name = "芝士雪豹",
|
||||||
|
.pet_hp = 100,
|
||||||
|
.pet_density = 45, // 故意设低,方便看进化
|
||||||
|
.pet_identity = "我是顶真,来自妈妈省"
|
||||||
|
};
|
||||||
|
const auto stageStrategy = std::make_shared<PetStageStrategy>();
|
||||||
|
const auto actionStrategy = std::make_shared<PetActionStrategy>();
|
||||||
|
|
||||||
|
// 填阶段资源(模型/音频)
|
||||||
|
stageStrategy->addStage(PetStageType::PET_STAGE_YOUNG, "pet_data/cheese_snow_leopard/models/setdown30.gif");
|
||||||
|
stageStrategy->addStage(PetStageType::PET_STAGE_ADULT, "pet_data/cheese_snow_leopard/models/setdown10.gif");
|
||||||
|
stageStrategy->addStage(PetStageType::PET_STAGE_OLD, "pet_data/cheese_snow_leopard/models/setdown20.gif");
|
||||||
|
stageStrategy->addStageAudio(PetStageType::PET_STAGE_YOUNG, "pet_data/cheese_snow_leopard/audio/dog.pcm");
|
||||||
|
stageStrategy->addStageAudio(PetStageType::PET_STAGE_ADULT, "/audio/snow_adult.mp3");
|
||||||
|
stageStrategy->addStageAudio(PetStageType::PET_STAGE_OLD, "/audio/snow_old.mp3");
|
||||||
|
|
||||||
|
// 填动作资源
|
||||||
|
actionStrategy->addAction(PetActionType::PET_ACTION_EAT, "pet_data/cheese_snow_leopard/models/eat1.gif");
|
||||||
|
actionStrategy->addActionAudio(PetActionType::PET_ACTION_EAT, "pet_data/cheese_snow_leopard/audio/cat.pcm");
|
||||||
|
// 创建宠物
|
||||||
|
pet = std::make_shared<PetBase>(info, stageStrategy, actionStrategy);
|
||||||
|
// 4. 构造观察者
|
||||||
|
audioObserver = std::make_shared<PetAudioStrategy>(stageStrategy, actionStrategy);
|
||||||
|
audioObserver->setAudioCallback([&](PetType petType, const std::string& path){
|
||||||
|
std::cout << "🔊 播放音频: " << path << std::endl;
|
||||||
|
if (petType == PetType::Action) { // 如果播放的是动作
|
||||||
|
AudioOutput::getInstance()->playPcmFile(ToolsClass::makeFullPath(path).c_str());
|
||||||
|
}
|
||||||
|
if (petType == PetType::Stage) { // 如果播放的是阶段
|
||||||
|
// 暂时nothing to do
|
||||||
|
}
|
||||||
|
});
|
||||||
|
renderObserver = std::make_shared<PetRendererStrategy>(stageStrategy, actionStrategy);
|
||||||
|
renderObserver->setRenderCallback([&](PetType petType, const std::string& path){
|
||||||
|
std::cout << "🖼️ 渲染模型: " << path << std::endl;
|
||||||
|
if (petType == PetType::Action) { // 如果播放的是动作,则突发播放
|
||||||
|
gif_->burst(path.c_str(), 7000);
|
||||||
|
}
|
||||||
|
if (petType == PetType::Stage) { // 如果播放的是阶段,则持久循环播放
|
||||||
|
std::cout << "渲染模型路径: " << path << std::endl;
|
||||||
|
gif_->loop(path.c_str());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
audioObserver->subscribe(pet);
|
||||||
|
renderObserver->subscribe(pet);
|
||||||
|
|
||||||
|
// 触发初始渲染
|
||||||
|
pet->notifyStageChange(PetStageType::PET_STAGE_YOUNG, pet->getCurrentStage());
|
||||||
|
printPet(*pet);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化语音识别
|
||||||
|
void initSpeech() {
|
||||||
|
// 获取 SpeechRecognizer 全局单例实例
|
||||||
|
recognizer = SpeechRecognizer::getInstance();
|
||||||
|
// 初始化
|
||||||
|
recognizer->init(false, VAD_MODE_3, "/sdcard/srmodels");
|
||||||
|
// 添加自定义命令
|
||||||
|
std::vector<std::pair<int, std::string> > commands = {
|
||||||
|
{0, "mo tou"}, // 摸头
|
||||||
|
{1, "wei shi"}, // 喂食
|
||||||
|
{2, "jiao liang sheng"}, // 叫两声
|
||||||
|
};
|
||||||
|
// 添加命令
|
||||||
|
recognizer->addCommands(commands);
|
||||||
|
// 注册回调函数
|
||||||
|
recognizer->registerCommandCallback([this](int command_id, const std::string& phrase, float probability) {
|
||||||
|
this->commandCallback(command_id, phrase, probability);
|
||||||
|
});
|
||||||
|
recognizer->registerStateCallback([this](const std::string& state) {
|
||||||
|
this->stateCallback(state);
|
||||||
|
});
|
||||||
|
recognizer->start(); // 启动识别
|
||||||
|
}
|
||||||
|
// 状态回调函数
|
||||||
|
void stateCallback(const std::string &state) {
|
||||||
|
ESP_LOGI("Example", "状态改变到: %s", state.c_str());
|
||||||
|
}
|
||||||
|
// 命令回调函数
|
||||||
|
void commandCallback(int command_id, const std::string &phrase, float probability) {
|
||||||
|
ESP_LOGI("Example", "Received command: ID=%d, Phrase='%s', Probability=%.2f",
|
||||||
|
command_id, phrase.c_str(), probability);
|
||||||
|
// 根据命令执行相应操作
|
||||||
|
switch (command_id) {
|
||||||
|
case 0:
|
||||||
|
pet->play();
|
||||||
|
info_->text_fmt("HP: %d \n Dens: %d", pet->getPetInfo().pet_hp, pet->getPetInfo().pet_density);
|
||||||
|
printPet(*pet);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
pet->feed();
|
||||||
|
info_->text_fmt("HP: %d \n Dens: %d", pet->getPetInfo().pet_hp, pet->getPetInfo().pet_density);
|
||||||
|
printPet(*pet);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
pet->play();
|
||||||
|
info_->text_fmt("HP: %d \n Dens: %d", pet->getPetInfo().pet_hp, pet->getPetInfo().pet_density);
|
||||||
|
printPet(*pet);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ESP_LOGI("Example", "未知的命令ID: %d", command_id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void onShow() override {
|
||||||
|
lv_obj_set_style_bg_color(this->raw(), lv_color_black(), 0); // 背景
|
||||||
|
lv_obj_clear_flag(this->raw(), LV_OBJ_FLAG_SCROLLABLE); // 禁止滚动
|
||||||
|
gif_ = std::make_unique<lvgl_cpp::GifPlayer>(*this); // 注意初始化顺序
|
||||||
|
gif_->size(360, 360);
|
||||||
|
initPet(); // 初始化测试宠物信息
|
||||||
|
initSpeech(); // 初始化语音识别
|
||||||
|
|
||||||
|
// 居中按钮:180×60 px,圆角,现代蓝
|
||||||
|
btn_.emplace(*this);
|
||||||
|
btn_->size(120, 40)
|
||||||
|
.align(LV_ALIGN_CENTER, nullptr, 0, 80);
|
||||||
|
// 按钮文字
|
||||||
|
lv_obj_t* label = lv_label_create(btn_->raw());
|
||||||
|
lv_obj_set_style_text_font(label, &SiYuanHeiTiGoogleBan, LV_PART_MAIN);
|
||||||
|
lv_label_set_text(label, "长按交流");
|
||||||
|
lv_obj_center(label);
|
||||||
|
btn_->onShort([]() { // 短按事件(点一下)
|
||||||
|
ESP_LOGI("Btn", "short click");
|
||||||
|
});
|
||||||
|
|
||||||
|
btn_->onLong([](const std::atomic<bool>& stop) { // 长按循环按钮
|
||||||
|
std::vector<int16_t> audio_data;
|
||||||
|
std::vector<int16_t> audio_data_sum;
|
||||||
|
constexpr int SHIFT_AVE = 14; // 喂 AFE 时右移的位数
|
||||||
|
constexpr int GAIN_SHIFT = 14 - 9; // 想拉回 0 dB 需要左移多少
|
||||||
|
ESP_LOGI("LP","开始录音");
|
||||||
|
while(!stop){
|
||||||
|
// 获取所有可用的最新数据,并累加到 audio_data_sum 当中
|
||||||
|
if (LatestDataForwarder::getInstance()->retrieveLatestData(audio_data, 100)) {
|
||||||
|
// 放大到正常幅度再累加(放大声音)
|
||||||
|
for (auto &s : audio_data) {
|
||||||
|
int32_t tmp = static_cast<int32_t>(s) << GAIN_SHIFT; // 能量拉回 0 dB
|
||||||
|
if (tmp > 32767) tmp = 32767;
|
||||||
|
if (tmp < -32768) tmp = -32768;
|
||||||
|
audio_data_sum.push_back(static_cast<int16_t>(tmp));
|
||||||
|
}
|
||||||
|
// ESP_LOGI("LP", "got %zu samples, total now %zu",
|
||||||
|
// audio_data.size(), audio_data_sum.size());
|
||||||
|
} else {
|
||||||
|
ESP_LOGW("LP", "no data within 100 ms");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ESP_LOGI("LP","结束录音");
|
||||||
|
// 将数据封装成 json 后通过 websocket 发送给服务器
|
||||||
|
ESP_LOGI("LP","开始发送数据");
|
||||||
|
size_t pcm_bytes = audio_data_sum.size() * sizeof(int16_t);
|
||||||
|
size_t b64_len = 0;
|
||||||
|
mbedtls_base64_encode(nullptr, 0, &b64_len,
|
||||||
|
reinterpret_cast<const unsigned char*>(audio_data_sum.data()),
|
||||||
|
pcm_bytes);
|
||||||
|
// 再真正编码
|
||||||
|
std::vector<unsigned char> b64_buf(b64_len);
|
||||||
|
mbedtls_base64_encode(b64_buf.data(), b64_len, &b64_len,
|
||||||
|
reinterpret_cast<const unsigned char*>(audio_data_sum.data()),
|
||||||
|
pcm_bytes);
|
||||||
|
// 转成 std::string(不含 \0)
|
||||||
|
std::string b64_str(reinterpret_cast<char*>(b64_buf.data()), b64_len);
|
||||||
|
cppjson::Json audio_json = cppjson::Json::object(); // 创建 json 对象
|
||||||
|
cppjson::Json audio_json_body = cppjson::Json::object();
|
||||||
|
audio_json.set("type", "audio");
|
||||||
|
audio_json_body
|
||||||
|
.set("data", b64_str)
|
||||||
|
.set("size", cppjson::Json(audio_data_sum.size()));
|
||||||
|
audio_json.set("body", audio_json_body);
|
||||||
|
WebSocketManager::getInstance()->sendJson(audio_json);
|
||||||
|
ESP_LOGI("LP","发送数据 OVER!");
|
||||||
|
ESP_LOGI("LP","long exit");
|
||||||
|
});
|
||||||
|
|
||||||
|
// 透明文字浮层(初始提示)
|
||||||
|
info_.emplace(*this);
|
||||||
|
info_->text_fmt("HP: %d \n Dens: %d", pet->getPetInfo().pet_hp, pet->getPetInfo().pet_density)
|
||||||
|
.textColor(lv_color_black())
|
||||||
|
.font(&SiYuanHeiTiGoogleBan)
|
||||||
|
.alignText(LV_TEXT_ALIGN_CENTER)
|
||||||
|
.place(LV_ALIGN_CENTER, nullptr, 0, -120); // 屏幕正中央
|
||||||
|
}
|
||||||
|
|
||||||
|
void onCleanup() override {
|
||||||
|
if (gif_) gif_->stop(); // 对象还活着,立即释放
|
||||||
|
}
|
||||||
|
~PetApp() override = default; // unique_ptr 自动析构
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<PetBase> pet;
|
||||||
|
std::shared_ptr<PetAudioStrategy> audioObserver;
|
||||||
|
std::shared_ptr<PetRendererStrategy> renderObserver;
|
||||||
|
|
||||||
|
private:
|
||||||
|
SpeechRecognizer *recognizer; // 语音识别
|
||||||
|
std::unique_ptr<lvgl_cpp::GifPlayer> gif_; // gif 播放器
|
||||||
|
std::optional<lvgl_cpp::TextOverlay> info_; // 透明文字
|
||||||
|
std::optional<lvgl_cpp::LongPressButton> btn_; // 长按按钮
|
||||||
|
};
|
||||||
@@ -47,7 +47,7 @@ void SDFileManager::tryInitSDCard() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SDFileManager::writeFileSync(const char* path, const char* data) {
|
bool SDFileManager::writeFileSync(const char* path, const char* data, const size_t len, const char* type) {
|
||||||
std::lock_guard<std::mutex> lock(file_operation_mutex);
|
std::lock_guard<std::mutex> lock(file_operation_mutex);
|
||||||
|
|
||||||
if (!is_initialized) {
|
if (!is_initialized) {
|
||||||
@@ -55,8 +55,20 @@ bool SDFileManager::writeFileSync(const char* path, const char* data) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t result = s_example_write_file(path, const_cast<char*>(data));
|
ESP_LOGI("SDFileManager", "Opening file %s", path);
|
||||||
return result == ESP_OK;
|
FILE *f = fopen(path, type);
|
||||||
|
if (f == nullptr) {
|
||||||
|
ESP_LOGE("SDFileManager", "Failed to open file for writing");
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
const size_t written = fwrite(data, 1, len, f);
|
||||||
|
fclose(f);
|
||||||
|
if (written != len) {
|
||||||
|
ESP_LOGE("SDFileManager", "Only %zu/%zu bytes written", written, len);
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
ESP_LOGI("SDFileManager", "File written (%zu bytes)", written);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SDFileManager::readFileSync(const char* path) {
|
std::string SDFileManager::readFileSync(const char* path) {
|
||||||
@@ -133,9 +145,9 @@ std::vector<std::string> SDFileManager::listFilesSync(const char* directory, con
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const int max_files = 50;
|
constexpr int max_files = 50;
|
||||||
char file_names[max_files][100];
|
char file_names[max_files][100];
|
||||||
uint16_t file_count = Folder_retrieval(directory, extension, file_names, max_files);
|
const uint16_t file_count = Folder_retrieval(directory, extension, file_names, max_files);
|
||||||
|
|
||||||
std::vector<std::string> files;
|
std::vector<std::string> files;
|
||||||
for (uint16_t i = 0; i < file_count; ++i) {
|
for (uint16_t i = 0; i < file_count; ++i) {
|
||||||
@@ -163,12 +175,12 @@ bool SDFileManager::closeFileSync(FILE* file) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDFileManager::asyncWriteFile(const char* path, const char* data, WriteCallback callback) {
|
void SDFileManager::asyncWriteFile(const char* path, const char* data, const size_t len, const char* type, WriteCallback callback) {
|
||||||
ThreadConfig config = getThreadConfig("write_file");
|
ThreadConfig config = getThreadConfig("write_file");
|
||||||
|
|
||||||
ThreadManager::createThread(config, [this, path = std::string(path),
|
ThreadManager::createThread(config, [this, path = std::string(path),
|
||||||
data = std::string(data), callback]() {
|
data = std::string(data), callback, type, len]() {
|
||||||
bool success = this->writeFileSync(path.c_str(), data.c_str());
|
const bool success = this->writeFileSync(path.c_str(), data.c_str(), len, type);
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback(success, path.c_str());
|
callback(success, path.c_str());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,9 +34,11 @@ public:
|
|||||||
* 同步写入文件
|
* 同步写入文件
|
||||||
* @param path 文件路径
|
* @param path 文件路径
|
||||||
* @param data 数据
|
* @param data 数据
|
||||||
|
* @param len 数据长度
|
||||||
|
* @param type 文件类型
|
||||||
* @return 是否成功
|
* @return 是否成功
|
||||||
*/
|
*/
|
||||||
bool writeFileSync(const char* path, const char* data);
|
bool writeFileSync(const char* path, const char* data, const size_t len, const char* type);
|
||||||
/**
|
/**
|
||||||
* 同步读取文件
|
* 同步读取文件
|
||||||
* @param path 文件路径
|
* @param path 文件路径
|
||||||
@@ -79,9 +81,11 @@ public:
|
|||||||
* 异步写入文件
|
* 异步写入文件
|
||||||
* @param path 文件路径
|
* @param path 文件路径
|
||||||
* @param data 数据
|
* @param data 数据
|
||||||
|
* @param len 数据长度
|
||||||
|
* @param type 文件类型
|
||||||
* @param callback 回调函数
|
* @param callback 回调函数
|
||||||
*/
|
*/
|
||||||
void asyncWriteFile(const char* path, const char* data, WriteCallback callback = nullptr);
|
void asyncWriteFile(const char* path, const char* data, const size_t len, const char* type, WriteCallback callback = nullptr);
|
||||||
/**
|
/**
|
||||||
* 异步读取文件
|
* 异步读取文件
|
||||||
* @param path 文件路径
|
* @param path 文件路径
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
//
|
||||||
|
// Created by misaki on 2025/9/29.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "SimpleI2SForwarder.h"
|
||||||
|
|
||||||
|
// 静态成员初始化
|
||||||
|
LatestDataForwarder* LatestDataForwarder::instance = nullptr;
|
||||||
|
std::mutex LatestDataForwarder::instance_mutex;
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
//
|
||||||
|
// Created by misaki on 2025/9/29.
|
||||||
|
//
|
||||||
|
/**
|
||||||
|
* 音频数据转发器 单生产者单消费者模型
|
||||||
|
* 单纯只作为数据转发器,不进行任何处理
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <atomic>
|
||||||
|
#include <vector>
|
||||||
|
#include <mutex>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <deque>
|
||||||
|
|
||||||
|
class LatestDataForwarder {
|
||||||
|
private:
|
||||||
|
static LatestDataForwarder* instance;
|
||||||
|
static std::mutex instance_mutex;
|
||||||
|
|
||||||
|
std::deque<std::vector<int16_t>> queue_;
|
||||||
|
size_t max_size_;
|
||||||
|
std::mutex queue_mutex_;
|
||||||
|
std::condition_variable data_available_;
|
||||||
|
std::atomic<bool> is_running_;
|
||||||
|
public:
|
||||||
|
static LatestDataForwarder* getInstance() {
|
||||||
|
std::lock_guard<std::mutex> lock(instance_mutex);
|
||||||
|
if (!instance) {
|
||||||
|
instance = new LatestDataForwarder();
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
void initialize(const size_t max_size = 500) {
|
||||||
|
std::lock_guard<std::mutex> lock(queue_mutex_);
|
||||||
|
max_size_ = max_size;
|
||||||
|
is_running_ = true;
|
||||||
|
}
|
||||||
|
// 生产者:总是注入最新数据,队列满时丢弃最旧数据
|
||||||
|
void injectData(const int16_t* data, const size_t length) {
|
||||||
|
if (!is_running_ || !data || length == 0) return;
|
||||||
|
std::lock_guard<std::mutex> lock(queue_mutex_);
|
||||||
|
// 创建新数据
|
||||||
|
std::vector<int16_t> new_data(data, data + length);
|
||||||
|
// 如果队列已满,移除最旧的数据
|
||||||
|
if (queue_.size() >= max_size_) {
|
||||||
|
queue_.pop_front();
|
||||||
|
}
|
||||||
|
// 添加最新数据
|
||||||
|
queue_.push_back(std::move(new_data));
|
||||||
|
data_available_.notify_one();
|
||||||
|
}
|
||||||
|
// 消费者:获取所有可用的最新数据
|
||||||
|
bool retrieveLatestData(std::vector<int16_t>& output, const int timeout_ms = 0) {
|
||||||
|
if (!is_running_) return false;
|
||||||
|
std::unique_lock<std::mutex> lock(queue_mutex_);
|
||||||
|
// 如果队列当中数据不足,则等待数据可用
|
||||||
|
if (queue_.empty()) {
|
||||||
|
if (timeout_ms <= 0) return false;
|
||||||
|
if (data_available_.wait_for(lock,
|
||||||
|
std::chrono::milliseconds(timeout_ms)) == std::cv_status::timeout) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (queue_.empty()) return false;
|
||||||
|
}
|
||||||
|
if (!is_running_) return false;
|
||||||
|
// 合并队列中的所有数据(最新的数据)
|
||||||
|
output.clear();
|
||||||
|
for (const auto& chunk : queue_) {
|
||||||
|
output.insert(output.end(), chunk.begin(), chunk.end());
|
||||||
|
}
|
||||||
|
// 清空队列,准备接收新的实时数据
|
||||||
|
queue_.clear();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// 消费者:只获取最新的N帧数据
|
||||||
|
bool retrieveRecentData(std::vector<int16_t>& output, const size_t recent_frames = 10, const int timeout_ms = 0) {
|
||||||
|
if (!is_running_) return false;
|
||||||
|
std::unique_lock<std::mutex> lock(queue_mutex_);
|
||||||
|
// 等待数据可用
|
||||||
|
if (queue_.empty()) {
|
||||||
|
if (timeout_ms <= 0) return false;
|
||||||
|
if (data_available_.wait_for(lock,
|
||||||
|
std::chrono::milliseconds(timeout_ms)) == std::cv_status::timeout) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (queue_.empty()) return false;
|
||||||
|
}
|
||||||
|
if (!is_running_) return false;
|
||||||
|
// 只取最新的recent_frames帧数据
|
||||||
|
output.clear();
|
||||||
|
const size_t start_index = queue_.size() > recent_frames ? queue_.size() - recent_frames : 0;
|
||||||
|
for (size_t i = start_index; i < queue_.size(); ++i) {
|
||||||
|
output.insert(output.end(), queue_[i].begin(), queue_[i].end());
|
||||||
|
}
|
||||||
|
// 移除已取出的旧数据,保留最新的数据
|
||||||
|
if (start_index > 0) {
|
||||||
|
std::deque<std::vector<int16_t>> new_queue(queue_.begin() + start_index, queue_.end());
|
||||||
|
queue_.swap(new_queue);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t getQueueSize() {
|
||||||
|
std::lock_guard<std::mutex> lock(queue_mutex_);
|
||||||
|
return queue_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
std::lock_guard<std::mutex> lock(queue_mutex_);
|
||||||
|
queue_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void stop() {
|
||||||
|
is_running_ = false;
|
||||||
|
data_available_.notify_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
void start() {
|
||||||
|
is_running_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
LatestDataForwarder() : max_size_(500), is_running_(false) {}
|
||||||
|
};
|
||||||
@@ -2,20 +2,22 @@
|
|||||||
// Created by misaki on 2025/9/15.
|
// Created by misaki on 2025/9/15.
|
||||||
//
|
//
|
||||||
#include "SpeechRecognizer.h"
|
#include "SpeechRecognizer.h"
|
||||||
#include "esp_afe_sr_models.h"
|
#include "VadSlidingWindow.h"
|
||||||
#include "esp_mn_models.h"
|
#include "SimpleI2SForwarder.h"
|
||||||
#include "esp_wn_iface.h"
|
|
||||||
#include "esp_mn_speech_commands.h"
|
#include <esp_afe_sr_models.h>
|
||||||
#include "model_path.h"
|
#include <esp_mn_models.h>
|
||||||
#include "driver/gpio.h"
|
#include <esp_wn_iface.h>
|
||||||
#include "soc/soc_caps.h"
|
#include <esp_mn_speech_commands.h>
|
||||||
#include "esp_err.h"
|
#include <model_path.h>
|
||||||
#include "nvs_flash.h"
|
#include <driver/gpio.h>
|
||||||
#include "freertos/FreeRTOS.h"
|
#include <soc/soc_caps.h>
|
||||||
#include "freertos/task.h"
|
#include <esp_err.h>
|
||||||
|
#include <nvs_flash.h>
|
||||||
|
#include <freertos/FreeRTOS.h>
|
||||||
|
#include <freertos/task.h>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <memory>
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
// 初始化静态成员变量
|
// 初始化静态成员变量
|
||||||
@@ -40,8 +42,8 @@ SpeechRecognizer::SpeechRecognizer()
|
|||||||
models(nullptr),
|
models(nullptr),
|
||||||
multinet(nullptr),
|
multinet(nullptr),
|
||||||
model_data(nullptr),
|
model_data(nullptr),
|
||||||
tasksRunning(false) {
|
vad_state_(AFE_VAD_SILENCE),
|
||||||
}
|
tasksRunning(false){}
|
||||||
|
|
||||||
SpeechRecognizer::~SpeechRecognizer() {
|
SpeechRecognizer::~SpeechRecognizer() {
|
||||||
deinit();
|
deinit();
|
||||||
@@ -68,6 +70,29 @@ bool SpeechRecognizer::init(const SpeechRecognizerConfig& config) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SpeechRecognizer::init(const bool enable_vad, const vad_mode_t vad_mode, std::string model_path) {
|
||||||
|
if (initialized) {
|
||||||
|
ESP_LOGI("SpeechRecognizer", "Already initialized");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
this->config.enable_vad = enable_vad;
|
||||||
|
this->config.vad_mode = vad_mode;
|
||||||
|
this->config.model_path = std::move(model_path);
|
||||||
|
// 初始化I2S
|
||||||
|
if (!initI2S()) {
|
||||||
|
ESP_LOGE("SpeechRecognizer", "I2S initialization failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 初始化ESP-SR
|
||||||
|
if (!initESP_SR()) {
|
||||||
|
ESP_LOGE("SpeechRecognizer", "ESP-SR initialization failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
initialized = true;
|
||||||
|
ESP_LOGI("SpeechRecognizer", "Initialization completed successfully");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void SpeechRecognizer::deinit() {
|
void SpeechRecognizer::deinit() {
|
||||||
if (!initialized) {
|
if (!initialized) {
|
||||||
return;
|
return;
|
||||||
@@ -88,8 +113,8 @@ void SpeechRecognizer::deinit() {
|
|||||||
}
|
}
|
||||||
// 释放I2S资源
|
// 释放I2S资源
|
||||||
if (rx_handle) {
|
if (rx_handle) {
|
||||||
i2s_channel_disable(rx_handle);
|
i2s_channel_disable(rx_handle); // 删除通道之前必须先禁用通道
|
||||||
i2s_del_channel(rx_handle);
|
i2s_del_channel(rx_handle); // 删除该句柄以释放通道资源
|
||||||
rx_handle = nullptr;
|
rx_handle = nullptr;
|
||||||
}
|
}
|
||||||
initialized = false;
|
initialized = false;
|
||||||
@@ -98,30 +123,33 @@ void SpeechRecognizer::deinit() {
|
|||||||
|
|
||||||
bool SpeechRecognizer::initI2S() {
|
bool SpeechRecognizer::initI2S() {
|
||||||
esp_err_t ret = ESP_OK;
|
esp_err_t ret = ESP_OK;
|
||||||
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_1, I2S_ROLE_MASTER);
|
// 通过辅助宏获取默认的通道配置, 它可以帮助指定 I2S 角色和端口 ID
|
||||||
|
constexpr i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_1, I2S_ROLE_MASTER);
|
||||||
|
// 分配新的 TX 通道并获取该通道的句柄
|
||||||
ret = i2s_new_channel(&chan_cfg, nullptr, &rx_handle);
|
ret = i2s_new_channel(&chan_cfg, nullptr, &rx_handle);
|
||||||
if (ret != ESP_OK) {
|
if (ret != ESP_OK) {
|
||||||
ESP_LOGE("SpeechRecognizer", "Failed to create I2S channel: %s", esp_err_to_name(ret));
|
ESP_LOGE("SpeechRecognizer", "Failed to create I2S channel: %s", esp_err_to_name(ret));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// 进行配置,通过宏生成声道配置和时钟配置, 这两个辅助宏在 'i2s_std.h' 中定义,只能用于 STD 模式
|
||||||
i2s_std_config_t std_cfg = {
|
i2s_std_config_t std_cfg = {
|
||||||
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(16000),
|
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(16000), // 16KHz采样率
|
||||||
.slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_MONO),
|
.slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_MONO), // 32位单声道
|
||||||
.gpio_cfg = {
|
.gpio_cfg = {
|
||||||
.mclk = GPIO_NUM_NC,
|
.mclk = GPIO_NUM_NC, // 不使用MCLK
|
||||||
.bclk = config.bclk_pin,
|
.bclk = config.bclk_pin, // BCLK引脚
|
||||||
.ws = config.ws_pin,
|
.ws = config.ws_pin, // WS引脚
|
||||||
.dout = GPIO_NUM_NC,
|
.dout = GPIO_NUM_NC, // 不使用DOUT
|
||||||
.din = config.din_pin,
|
.din = config.din_pin, // DIN引脚
|
||||||
.invert_flags = {
|
.invert_flags = { // 不使用倒置
|
||||||
.mclk_inv = false,
|
.mclk_inv = false,
|
||||||
.bclk_inv = false,
|
.bclk_inv = false,
|
||||||
.ws_inv = false,
|
.ws_inv = false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
std_cfg.slot_cfg.slot_mask = I2S_STD_SLOT_RIGHT;
|
std_cfg.slot_cfg.slot_mask = I2S_STD_SLOT_RIGHT; // 右声道
|
||||||
ret = i2s_channel_init_std_mode(rx_handle, &std_cfg);
|
ret = i2s_channel_init_std_mode(rx_handle, &std_cfg); // 初始化STD标准模式
|
||||||
if (ret != ESP_OK) {
|
if (ret != ESP_OK) {
|
||||||
ESP_LOGE("SpeechRecognizer", "Failed to init I2S standard mode: %s", esp_err_to_name(ret));
|
ESP_LOGE("SpeechRecognizer", "Failed to init I2S standard mode: %s", esp_err_to_name(ret));
|
||||||
return false;
|
return false;
|
||||||
@@ -177,7 +205,7 @@ bool SpeechRecognizer::initESP_SR() {
|
|||||||
ESP_LOGE("SpeechRecognizer", "Failed to create AFE data from config");
|
ESP_LOGE("SpeechRecognizer", "Failed to create AFE data from config");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// 加载MultiNet模型(采用esp-sr提供的宏来处理不同语种的模型的处理问题)
|
// 加载MultiNet模型 (采用esp-sr提供的宏来处理不同语种的模型的处理问题)
|
||||||
#if defined(CONFIG_SR_MN_CN_MULTINET5_RECOGNITION_QUANT8) || defined(CONFIG_SR_MN_CN_MULTINET6_QUANT) || defined(CONFIG_SR_MN_CN_MULTINET6_AC_QUANT)
|
#if defined(CONFIG_SR_MN_CN_MULTINET5_RECOGNITION_QUANT8) || defined(CONFIG_SR_MN_CN_MULTINET6_QUANT) || defined(CONFIG_SR_MN_CN_MULTINET6_AC_QUANT)
|
||||||
char *mn_name = esp_srmodel_filter(models, ESP_MN_PREFIX, ESP_MN_CHINESE);
|
char *mn_name = esp_srmodel_filter(models, ESP_MN_PREFIX, ESP_MN_CHINESE);
|
||||||
#else
|
#else
|
||||||
@@ -211,7 +239,7 @@ bool SpeechRecognizer::start() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// 启用I2S通道
|
// 启用I2S通道
|
||||||
esp_err_t ret = i2s_channel_enable(rx_handle);
|
esp_err_t ret = i2s_channel_enable(rx_handle); // 在读取数据之前,先启动 RX 通道
|
||||||
if (ret != ESP_OK) {
|
if (ret != ESP_OK) {
|
||||||
ESP_LOGE("SpeechRecognizer", "Failed to enable I2S channel: %s", esp_err_to_name(ret));
|
ESP_LOGE("SpeechRecognizer", "Failed to enable I2S channel: %s", esp_err_to_name(ret));
|
||||||
return false;
|
return false;
|
||||||
@@ -253,29 +281,51 @@ void SpeechRecognizer::stop() {
|
|||||||
|
|
||||||
void SpeechRecognizer::feedTask() {
|
void SpeechRecognizer::feedTask() {
|
||||||
ThreadManager::printThreadInfo("Feed task started");
|
ThreadManager::printThreadInfo("Feed task started");
|
||||||
int audio_chunksize = afe_handle->get_feed_chunksize(afe_data);
|
const int audio_chunksize = afe_handle->get_feed_chunksize(afe_data);
|
||||||
int nch = afe_handle->get_channel_num(afe_data);
|
ESP_LOGW("SpeechRecognizer", "Feed task: audio_chunksize=%d", audio_chunksize);
|
||||||
size_t samp_len = audio_chunksize;
|
int nch = afe_handle->get_channel_num(afe_data); // 获取I2S通道的声道数, 此处为1, 因此并没有被下面所使用
|
||||||
size_t samp_len_bytes = samp_len * sizeof(int32_t); // 单声道32位
|
const size_t samp_len = audio_chunksize;
|
||||||
auto *i2s_buff = static_cast<int32_t *>(malloc(samp_len_bytes));
|
const size_t samp_len_bytes = samp_len * sizeof(int32_t); // 单声道32位
|
||||||
if (!i2s_buff) {
|
// 分配I2S缓冲区 放在PSRAM堆内存中
|
||||||
ESP_LOGE("SpeechRecognizer", "Failed to allocate memory for I2S buffer");
|
auto *i2s_buff = static_cast<int32_t *>(heap_caps_malloc((samp_len_bytes), MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM));
|
||||||
|
// 创建I2S转发副本 放在PSRAM堆内存中
|
||||||
|
auto *raw_pcm16 = static_cast<int16_t *>(heap_caps_malloc(samp_len * sizeof(int16_t), MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM));
|
||||||
|
if (!i2s_buff || !raw_pcm16) {
|
||||||
|
ESP_LOGE("SpeechRecognizer", "Failed to allocate memory for buffers");
|
||||||
|
if (i2s_buff) free(i2s_buff);
|
||||||
|
if (raw_pcm16) free(raw_pcm16);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
size_t bytes_read;
|
LatestDataForwarder::getInstance()->initialize(200); // 初始化转发队列,最多缓存 200 帧 I2S 数据
|
||||||
|
size_t bytes_read; // 读取的字节数
|
||||||
|
|
||||||
while (tasksRunning) {
|
while (tasksRunning) {
|
||||||
esp_err_t ret = i2s_channel_read(rx_handle, i2s_buff, samp_len_bytes, &bytes_read, portMAX_DELAY);
|
// 读取I2S数据
|
||||||
|
const esp_err_t ret = i2s_channel_read(rx_handle, i2s_buff, samp_len_bytes, &bytes_read, portMAX_DELAY);
|
||||||
if (ret != ESP_OK) {
|
if (ret != ESP_OK) {
|
||||||
ESP_LOGE("SpeechRecognizer", "I2S read error: %s", esp_err_to_name(ret));
|
ESP_LOGE("SpeechRecognizer", "I2S read error: %s", esp_err_to_name(ret));
|
||||||
vTaskDelay(pdMS_TO_TICKS(10));
|
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// 处理音频数据(32位转16位)
|
// 一次性处理所有数据转换
|
||||||
for (int i = 0; i < samp_len; ++i) {
|
for (int i = 0; i < samp_len; ++i) {
|
||||||
i2s_buff[i] = i2s_buff[i] >> 14; // 32:8是有效位,转换为16位音频数据
|
// 转发数据转换:32位转16位(取高16位)
|
||||||
|
raw_pcm16[i] = static_cast<int16_t>(i2s_buff[i] >> 16);
|
||||||
|
// AFE数据转换:右移14位(在原始数据上操作)
|
||||||
|
i2s_buff[i] = i2s_buff[i] >> 14; // 32:8 是有效位,8:0 是低 8 位,全部为 0,AFE 输入是 16 位语音数据,29:13 位用于放大语音信号。
|
||||||
}
|
}
|
||||||
|
// 转发原始数据
|
||||||
|
LatestDataForwarder::getInstance()->injectData(raw_pcm16, samp_len);
|
||||||
// 喂数据给AFE
|
// 喂数据给AFE
|
||||||
afe_handle->feed(afe_data, reinterpret_cast<int16_t *>(i2s_buff));
|
afe_handle->feed(afe_data, reinterpret_cast<int16_t *>(i2s_buff));
|
||||||
|
|
||||||
|
// 复制一份到滑动窗口人声检测区 (给网络) 注入音频帧到管理器
|
||||||
|
// AudioBufferManager::getInstance()->injectAudioFrame(
|
||||||
|
// reinterpret_cast<int16_t*>(i2s_buff),
|
||||||
|
// samp_len,
|
||||||
|
// this->vad_state_
|
||||||
|
// );
|
||||||
|
// std::this_thread::sleep_for(std::chrono::milliseconds(5)); // 休眠5ms
|
||||||
}
|
}
|
||||||
free(i2s_buff);
|
free(i2s_buff);
|
||||||
ESP_LOGI("SpeechRecognizer", "Feed task exited");
|
ESP_LOGI("SpeechRecognizer", "Feed task exited");
|
||||||
@@ -293,6 +343,8 @@ void SpeechRecognizer::detectTask() {
|
|||||||
ESP_LOGI("SpeechRecognizer", "Ready for speech recognition");
|
ESP_LOGI("SpeechRecognizer", "Ready for speech recognition");
|
||||||
while (tasksRunning) {
|
while (tasksRunning) {
|
||||||
afe_fetch_result_t* res = afe_handle->fetch(afe_data);
|
afe_fetch_result_t* res = afe_handle->fetch(afe_data);
|
||||||
|
// 从res中取出 vad 状态
|
||||||
|
this->vad_state_ = res->vad_state;
|
||||||
if (!res || res->ret_value == ESP_FAIL) {
|
if (!res || res->ret_value == ESP_FAIL) {
|
||||||
ESP_LOGE("SpeechRecognizer", "AFE fetch error");
|
ESP_LOGE("SpeechRecognizer", "AFE fetch error");
|
||||||
vTaskDelay(pdMS_TO_TICKS(10));
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
@@ -364,10 +416,6 @@ bool SpeechRecognizer::addCommand(int command_id, const std::string& phrase) {
|
|||||||
}
|
}
|
||||||
// 打印缓存的指令
|
// 打印缓存的指令
|
||||||
ESP_LOGI("SpeechRecognizer", "Added command: ID=%d, Phrase=%s", command_id, phrase.c_str());
|
ESP_LOGI("SpeechRecognizer", "Added command: ID=%d, Phrase=%s", command_id, phrase.c_str());
|
||||||
ESP_LOGI("SpeechRecognizer", "下面是当前已经缓存的指令:");
|
|
||||||
esp_mn_commands_print();
|
|
||||||
ESP_LOGI("SpeechRecognizer", "下面是当前已经应用的指令:");
|
|
||||||
esp_mn_active_commands_print();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -376,6 +424,7 @@ bool SpeechRecognizer::addCommands(const std::vector<std::pair<int, std::string>
|
|||||||
for (const auto& cmd : commands) {
|
for (const auto& cmd : commands) {
|
||||||
if (!addCommand(cmd.first, cmd.second)) {
|
if (!addCommand(cmd.first, cmd.second)) {
|
||||||
success = false;
|
success = false;
|
||||||
|
ESP_LOGE("main", "Failed to add some commands");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ESP_LOGI("SpeechRecognizer", "下面是当前已经缓存的指令:");
|
ESP_LOGI("SpeechRecognizer", "下面是当前已经缓存的指令:");
|
||||||
@@ -459,6 +508,11 @@ std::string SpeechRecognizer::getCurrentState() const {
|
|||||||
return currentState;
|
return currentState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
afe_vad_state_t SpeechRecognizer::getVadState() const {
|
||||||
|
return vad_state_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SpeechRecognizer::isRunning() const {
|
bool SpeechRecognizer::isRunning() const {
|
||||||
return running;
|
return running;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,8 @@ public:
|
|||||||
|
|
||||||
// 初始化语音识别系统
|
// 初始化语音识别系统
|
||||||
bool init(const SpeechRecognizerConfig& config = SpeechRecognizerConfig());
|
bool init(const SpeechRecognizerConfig& config = SpeechRecognizerConfig());
|
||||||
|
// 重载版本
|
||||||
|
bool init(const bool enable_vad, const vad_mode_t vad_mode, std::string model_path);
|
||||||
// 反初始化
|
// 反初始化
|
||||||
void deinit();
|
void deinit();
|
||||||
|
|
||||||
@@ -106,6 +107,8 @@ public:
|
|||||||
// 获取当前识别状态
|
// 获取当前识别状态
|
||||||
std::string getCurrentState() const;
|
std::string getCurrentState() const;
|
||||||
|
|
||||||
|
// 获取当前 VAD 识别状态(噪音、静音 or 人声) 需要开启 VAD
|
||||||
|
afe_vad_state_t getVadState() const;
|
||||||
private:
|
private:
|
||||||
SpeechRecognizer();
|
SpeechRecognizer();
|
||||||
~SpeechRecognizer();
|
~SpeechRecognizer();
|
||||||
@@ -149,7 +152,8 @@ private:
|
|||||||
esp_afe_sr_data_t* afe_data;
|
esp_afe_sr_data_t* afe_data;
|
||||||
srmodel_list_t* models;
|
srmodel_list_t* models;
|
||||||
esp_mn_iface_t* multinet;
|
esp_mn_iface_t* multinet;
|
||||||
model_iface_data_t* model_data;
|
model_iface_data_t* model_data; /// 模型数据
|
||||||
|
afe_vad_state_t vad_state_; /// 语音活动检测状态
|
||||||
|
|
||||||
// 命令回调
|
// 命令回调
|
||||||
SpeechCommandCallback commandCallback;
|
SpeechCommandCallback commandCallback;
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
//
|
||||||
|
// Created by misaki on 2025/9/29.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "VadSlidingWindow.h"
|
||||||
|
|
||||||
|
// 静态成员初始化
|
||||||
|
AudioBufferManager* AudioBufferManager::instance = nullptr;
|
||||||
|
std::mutex AudioBufferManager::instance_mutex;
|
||||||
@@ -0,0 +1,377 @@
|
|||||||
|
//
|
||||||
|
// Created by misaki on 2025/9/29.
|
||||||
|
//
|
||||||
|
/**
|
||||||
|
* 本模块用于处理音频数据,使用滑动窗口和VAD算法进行人声语音段过滤
|
||||||
|
* 依赖于VAD人声检测数据,并通过滑动窗口管理区间数据,以精确过滤出人声音频数据
|
||||||
|
* @author Misaki
|
||||||
|
* @date 2025/9/29
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <vector>
|
||||||
|
#include <queue>
|
||||||
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
|
// PCM帧数据结构
|
||||||
|
struct PCMFrame {
|
||||||
|
std::vector<int16_t> audio_data; // PCM音频数据
|
||||||
|
size_t data_length; // 数据长度(样本数)
|
||||||
|
bool vad_status; // VAD检测状态
|
||||||
|
uint64_t timestamp; // 时间戳(可选,用于调试)
|
||||||
|
|
||||||
|
PCMFrame() : data_length(0), vad_status(false), timestamp(0) {}
|
||||||
|
|
||||||
|
PCMFrame(const int16_t* data, const size_t len, const bool vad, const uint64_t ts = 0)
|
||||||
|
: data_length(len), vad_status(vad), timestamp(ts) {
|
||||||
|
audio_data.assign(data, data + len);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 滑动窗口结构
|
||||||
|
struct SlidingWindow {
|
||||||
|
std::vector<PCMFrame> frames; // 窗口内的所有帧
|
||||||
|
size_t total_frames; // 总帧数
|
||||||
|
size_t voice_frames; // 人声帧数
|
||||||
|
double voice_ratio; // 人声占比
|
||||||
|
bool is_active; // 窗口是否处于活跃状态
|
||||||
|
|
||||||
|
SlidingWindow() : total_frames(0), voice_frames(0), voice_ratio(0.0), is_active(false) {}
|
||||||
|
|
||||||
|
// 计算人声占比
|
||||||
|
void calculateVoiceRatio() {
|
||||||
|
if (total_frames > 0) {
|
||||||
|
voice_ratio = static_cast<double>(voice_frames) / total_frames;
|
||||||
|
} else {
|
||||||
|
voice_ratio = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class AudioBufferManager {
|
||||||
|
private:
|
||||||
|
// 单例实例
|
||||||
|
static AudioBufferManager* instance;
|
||||||
|
static std::mutex instance_mutex;
|
||||||
|
|
||||||
|
// 配置参数
|
||||||
|
struct Config {
|
||||||
|
size_t max_window_frames; // 单个窗口最大帧数
|
||||||
|
size_t max_queue_size; // 队列最大长度
|
||||||
|
size_t silence_threshold_frames; // 静音阈值帧数
|
||||||
|
double voice_ratio_threshold; // 人声占比阈值
|
||||||
|
size_t pre_voice_frames; // 人声开始前预保留帧数
|
||||||
|
size_t post_voice_frames; // 人声结束后保留帧数
|
||||||
|
} config;
|
||||||
|
|
||||||
|
// 内部状态
|
||||||
|
std::unique_ptr<SlidingWindow> current_window;
|
||||||
|
std::queue<std::unique_ptr<SlidingWindow>> completed_windows;
|
||||||
|
std::vector<PCMFrame> pre_voice_buffer; // 人声开始前的预缓存
|
||||||
|
|
||||||
|
// 状态跟踪
|
||||||
|
std::atomic<bool> in_voice_segment;
|
||||||
|
size_t consecutive_silence_frames;
|
||||||
|
size_t current_frame_count;
|
||||||
|
|
||||||
|
// 线程同步
|
||||||
|
std::mutex data_mutex;
|
||||||
|
std::condition_variable data_condition;
|
||||||
|
|
||||||
|
// 内存使用跟踪
|
||||||
|
size_t estimated_memory_usage;
|
||||||
|
const size_t MAX_MEMORY_BYTES = 512 * 1024; // 512KB
|
||||||
|
|
||||||
|
private:
|
||||||
|
AudioBufferManager() {
|
||||||
|
initializeDefaultConfig();
|
||||||
|
resetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void initializeDefaultConfig() {
|
||||||
|
// 默认配置:基于16kHz采样率,每帧20ms(320样本)
|
||||||
|
config.max_window_frames = 500; // 10秒音频(500 * 20ms)
|
||||||
|
config.max_queue_size = 8; // 队列最多8个窗口
|
||||||
|
config.silence_threshold_frames = 15; // 300ms静音判定结束(15 * 20ms)
|
||||||
|
config.voice_ratio_threshold = 0.3; // 30%人声占比阈值
|
||||||
|
config.pre_voice_frames = 5; // 人声开始前保留100ms
|
||||||
|
config.post_voice_frames = 10; // 人声结束后保留200ms
|
||||||
|
|
||||||
|
estimated_memory_usage = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetState() {
|
||||||
|
current_window = std::make_unique<SlidingWindow>();
|
||||||
|
in_voice_segment = false;
|
||||||
|
consecutive_silence_frames = 0;
|
||||||
|
current_frame_count = 0;
|
||||||
|
pre_voice_buffer.clear();
|
||||||
|
pre_voice_buffer.reserve(config.pre_voice_frames);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 估算单个帧的内存使用
|
||||||
|
size_t estimateFrameMemory(const PCMFrame& frame) const {
|
||||||
|
return sizeof(PCMFrame) + (frame.audio_data.capacity() * sizeof(int16_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 估算窗口内存使用
|
||||||
|
size_t estimateWindowMemory(const SlidingWindow& window) const {
|
||||||
|
size_t memory = sizeof(SlidingWindow);
|
||||||
|
for (const auto& frame : window.frames) {
|
||||||
|
memory += estimateFrameMemory(frame);
|
||||||
|
}
|
||||||
|
return memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查内存限制
|
||||||
|
bool checkMemoryConstraints() const {
|
||||||
|
return estimated_memory_usage < MAX_MEMORY_BYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
// 删除拷贝构造函数和赋值运算符
|
||||||
|
AudioBufferManager(const AudioBufferManager&) = delete;
|
||||||
|
AudioBufferManager& operator=(const AudioBufferManager&) = delete;
|
||||||
|
|
||||||
|
// 获取单例实例
|
||||||
|
static AudioBufferManager* getInstance() {
|
||||||
|
std::lock_guard<std::mutex> lock(instance_mutex);
|
||||||
|
if (!instance) {
|
||||||
|
instance = new AudioBufferManager();
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 配置管理器参数
|
||||||
|
* @param max_window_frames 单个窗口最大帧数
|
||||||
|
* @param max_queue_size 队列最大长度
|
||||||
|
* @param silence_threshold 静音阈值帧数
|
||||||
|
* @param voice_ratio_threshold 人声占比阈值
|
||||||
|
* @param pre_voice_frames 人声开始前预保留帧数
|
||||||
|
* @param post_voice_frames 人声结束后保留帧数
|
||||||
|
*/
|
||||||
|
void configure(const size_t max_window_frames = 500,
|
||||||
|
const size_t max_queue_size = 8,
|
||||||
|
const size_t silence_threshold = 15,
|
||||||
|
const double voice_ratio_threshold = 0.2,
|
||||||
|
const size_t pre_voice_frames = 5,
|
||||||
|
const size_t post_voice_frames = 10) {
|
||||||
|
std::lock_guard<std::mutex> lock(data_mutex);
|
||||||
|
|
||||||
|
config.max_window_frames = max_window_frames;
|
||||||
|
config.max_queue_size = max_queue_size;
|
||||||
|
config.silence_threshold_frames = silence_threshold;
|
||||||
|
config.voice_ratio_threshold = voice_ratio_threshold;
|
||||||
|
config.pre_voice_frames = pre_voice_frames;
|
||||||
|
config.post_voice_frames = post_voice_frames;
|
||||||
|
|
||||||
|
// 重新初始化状态
|
||||||
|
resetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 注入新的音频帧数据
|
||||||
|
* @param audio_data PCM音频数据指针
|
||||||
|
* @param data_length 数据长度(样本数)
|
||||||
|
* @param vad_status 当前帧的VAD状态
|
||||||
|
*/
|
||||||
|
void injectAudioFrame(const int16_t* audio_data, size_t data_length, bool vad_status) {
|
||||||
|
std::lock_guard<std::mutex> lock(data_mutex);
|
||||||
|
|
||||||
|
// 创建新帧
|
||||||
|
PCMFrame new_frame(audio_data, data_length, vad_status, current_frame_count++);
|
||||||
|
size_t frame_memory = estimateFrameMemory(new_frame);
|
||||||
|
|
||||||
|
// 检查内存限制
|
||||||
|
if (!checkMemoryConstraints()) {
|
||||||
|
// 内存不足,采取清理策略
|
||||||
|
if (!completed_windows.empty()) {
|
||||||
|
auto old_window = std::move(completed_windows.front());
|
||||||
|
completed_windows.pop();
|
||||||
|
estimated_memory_usage -= estimateWindowMemory(*old_window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新预缓存
|
||||||
|
updatePreVoiceBuffer(new_frame);
|
||||||
|
|
||||||
|
// 状态机处理
|
||||||
|
if (!in_voice_segment) {
|
||||||
|
handleNonVoiceState(new_frame, frame_memory);
|
||||||
|
} else {
|
||||||
|
handleVoiceState(new_frame, frame_memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
estimated_memory_usage += frame_memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取可用的音频窗口数据
|
||||||
|
* @param timeout_ms 超时时间(毫秒)
|
||||||
|
* @return 滑动窗口指针,如果没有可用数据则返回nullptr
|
||||||
|
*/
|
||||||
|
std::unique_ptr<SlidingWindow> getAudioWindow(int timeout_ms = 0) {
|
||||||
|
std::unique_lock<std::mutex> lock(data_mutex);
|
||||||
|
if (completed_windows.empty()) {
|
||||||
|
if (timeout_ms <= 0) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
// 等待数据可用
|
||||||
|
if (data_condition.wait_for(lock,
|
||||||
|
std::chrono::milliseconds(timeout_ms)) == std::cv_status::timeout) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (completed_windows.empty()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto window = std::move(completed_windows.front());
|
||||||
|
completed_windows.pop();
|
||||||
|
estimated_memory_usage -= estimateWindowMemory(*window);
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 检查是否有可用的音频数据
|
||||||
|
*/
|
||||||
|
bool hasAvailableData() {
|
||||||
|
std::lock_guard<std::mutex> lock(data_mutex);
|
||||||
|
return !completed_windows.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取当前队列大小
|
||||||
|
*/
|
||||||
|
size_t getQueueSize() {
|
||||||
|
std::lock_guard<std::mutex> lock(data_mutex);
|
||||||
|
return completed_windows.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取估计的内存使用量
|
||||||
|
*/
|
||||||
|
size_t getEstimatedMemoryUsage() const {
|
||||||
|
return estimated_memory_usage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 强制结束当前语音段(如果有)
|
||||||
|
*/
|
||||||
|
void forceEndCurrentSegment() {
|
||||||
|
std::lock_guard<std::mutex> lock(data_mutex);
|
||||||
|
if (in_voice_segment && current_window->total_frames > 0) {
|
||||||
|
finalizeCurrentWindow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 清空所有缓存数据
|
||||||
|
*/
|
||||||
|
void clearAllData() {
|
||||||
|
std::lock_guard<std::mutex> lock(data_mutex);
|
||||||
|
resetState();
|
||||||
|
std::queue<std::unique_ptr<SlidingWindow>> empty_queue;
|
||||||
|
std::swap(completed_windows, empty_queue);
|
||||||
|
estimated_memory_usage = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 更新人声开始前的预缓存
|
||||||
|
void updatePreVoiceBuffer(const PCMFrame& frame) {
|
||||||
|
pre_voice_buffer.push_back(frame);
|
||||||
|
|
||||||
|
// 保持预缓存大小不超过配置值
|
||||||
|
if (pre_voice_buffer.size() > config.pre_voice_frames) {
|
||||||
|
pre_voice_buffer.erase(pre_voice_buffer.begin());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理非人声状态
|
||||||
|
void handleNonVoiceState(const PCMFrame& frame, size_t frame_memory) {
|
||||||
|
if (frame.vad_status) {
|
||||||
|
// 检测到人声开始
|
||||||
|
in_voice_segment = true;
|
||||||
|
consecutive_silence_frames = 0;
|
||||||
|
|
||||||
|
// 将预缓存数据加入当前窗口
|
||||||
|
for (const auto& pre_frame : pre_voice_buffer) {
|
||||||
|
current_window->frames.push_back(pre_frame);
|
||||||
|
current_window->total_frames++;
|
||||||
|
if (pre_frame.vad_status) {
|
||||||
|
current_window->voice_frames++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加当前帧
|
||||||
|
addFrameToCurrentWindow(frame);
|
||||||
|
}
|
||||||
|
// 非人声状态下,不进行其他处理
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理人声状态
|
||||||
|
void handleVoiceState(const PCMFrame& frame, size_t frame_memory) {
|
||||||
|
if (frame.vad_status) {
|
||||||
|
// 仍然是人声,重置静音计数
|
||||||
|
consecutive_silence_frames = 0;
|
||||||
|
} else {
|
||||||
|
// 静音帧
|
||||||
|
consecutive_silence_frames++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加当前帧到窗口
|
||||||
|
addFrameToCurrentWindow(frame);
|
||||||
|
|
||||||
|
// 检查是否需要结束当前语音段
|
||||||
|
if (consecutive_silence_frames >= config.silence_threshold_frames ||
|
||||||
|
current_window->frames.size() >= config.max_window_frames) {
|
||||||
|
|
||||||
|
// 添加人声结束后的保留帧
|
||||||
|
addPostVoiceFrames();
|
||||||
|
|
||||||
|
// 完成当前窗口
|
||||||
|
finalizeCurrentWindow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加帧到当前窗口
|
||||||
|
void addFrameToCurrentWindow(const PCMFrame& frame) {
|
||||||
|
current_window->frames.push_back(frame);
|
||||||
|
current_window->total_frames++;
|
||||||
|
if (frame.vad_status) {
|
||||||
|
current_window->voice_frames++;
|
||||||
|
}
|
||||||
|
current_window->calculateVoiceRatio();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加人声结束后的保留帧
|
||||||
|
void addPostVoiceFrames() {
|
||||||
|
// 这个函数在实际实现中需要缓存后续的帧
|
||||||
|
// 简化实现:在当前设计中,我们依赖静音阈值来自然包含结束后的帧
|
||||||
|
}
|
||||||
|
|
||||||
|
// 完成当前窗口的处理
|
||||||
|
void finalizeCurrentWindow() {
|
||||||
|
// 计算最终的人声占比
|
||||||
|
current_window->calculateVoiceRatio();
|
||||||
|
|
||||||
|
// 检查人声占比是否达到阈值
|
||||||
|
if (current_window->voice_ratio >= config.voice_ratio_threshold) {
|
||||||
|
// 窗口有效,加入队列
|
||||||
|
if (completed_windows.size() >= config.max_queue_size) {
|
||||||
|
// 队列已满,移除最旧的数据
|
||||||
|
auto old_window = std::move(completed_windows.front());
|
||||||
|
completed_windows.pop();
|
||||||
|
estimated_memory_usage -= estimateWindowMemory(*old_window);
|
||||||
|
}
|
||||||
|
|
||||||
|
completed_windows.push(std::move(current_window));
|
||||||
|
data_condition.notify_one(); // 通知等待的消费者
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置状态,开始新的窗口
|
||||||
|
resetState();
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
#include "PCM5101.h"
|
#include "PCM5101.h"
|
||||||
|
|
||||||
static const char *TAG = "AUDIO PCM5101";
|
static const char *TAG = "AUDIO PCM5101";
|
||||||
|
|
||||||
static i2s_chan_handle_t i2s_tx_chan;
|
i2s_chan_handle_t i2s_tx_chan = NULL;
|
||||||
static i2s_chan_handle_t i2s_rx_chan;
|
static i2s_chan_handle_t i2s_rx_chan;
|
||||||
|
|
||||||
uint8_t Volume = Volume_MAX - 2;
|
uint8_t Volume = Volume_MAX - 2;
|
||||||
@@ -24,7 +23,7 @@ static esp_err_t bsp_i2s_write(void *audio_buffer, size_t len, size_t *bytes_wri
|
|||||||
|
|
||||||
return i2s_channel_write(i2s_tx_chan, (char *)audio_buffer, len, bytes_written, timeout_ms);
|
return i2s_channel_write(i2s_tx_chan, (char *)audio_buffer, len, bytes_written, timeout_ms);
|
||||||
}
|
}
|
||||||
static esp_err_t bsp_i2s_reconfig_clk(uint32_t rate, uint32_t bits_cfg, i2s_slot_mode_t ch) { // I2S Init
|
esp_err_t bsp_i2s_reconfig_clk(uint32_t rate, uint32_t bits_cfg, i2s_slot_mode_t ch) { // I2S Init
|
||||||
esp_err_t ret = ESP_OK;
|
esp_err_t ret = ESP_OK;
|
||||||
i2s_std_config_t std_cfg = {
|
i2s_std_config_t std_cfg = {
|
||||||
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(rate),
|
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(rate),
|
||||||
@@ -214,3 +213,6 @@ void Volume_adjustment(uint8_t Vol) {
|
|||||||
Volume = Vol;
|
Volume = Vol;
|
||||||
ESP_LOGI(TAG, "Volume set to %d", Volume);
|
ESP_LOGI(TAG, "Volume set to %d", Volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,15 @@ uint32_t Music_Elapsed(void);
|
|||||||
uint16_t Music_Energy(void);
|
uint16_t Music_Energy(void);
|
||||||
void Volume_adjustment(uint8_t Volume);
|
void Volume_adjustment(uint8_t Volume);
|
||||||
|
|
||||||
|
|
||||||
|
// 供 C++ 层调用的“重新配置时钟”包装
|
||||||
|
esp_err_t bsp_i2s_reconfig_clk(uint32_t rate,
|
||||||
|
uint32_t bits_cfg,
|
||||||
|
i2s_slot_mode_t ch);
|
||||||
|
|
||||||
|
// 供 C++ 层直接用的 tx channel 句柄
|
||||||
|
extern i2s_chan_handle_t i2s_tx_chan;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -33,8 +33,8 @@ extern "C" {
|
|||||||
|
|
||||||
#define ESP_PANEL_HOST_SPI_ID_DEFAULT (SPI2_HOST)
|
#define ESP_PANEL_HOST_SPI_ID_DEFAULT (SPI2_HOST)
|
||||||
#define ESP_PANEL_LCD_SPI_MODE (0) // 0/1/2/3, typically set to 0
|
#define ESP_PANEL_LCD_SPI_MODE (0) // 0/1/2/3, typically set to 0
|
||||||
#define ESP_PANEL_LCD_SPI_CLK_HZ (80 * 1000 * 1000) // Should be an integer divisor of 80M, typically set to 40M
|
#define ESP_PANEL_LCD_SPI_CLK_HZ (40 * 1000 * 1000) // Should be an integer divisor of 80M, typically set to 40M
|
||||||
#define ESP_PANEL_LCD_SPI_TRANS_QUEUE_SZ (10) // Typically set to 10
|
#define ESP_PANEL_LCD_SPI_TRANS_QUEUE_SZ (40) // Typically set to 10
|
||||||
#define ESP_PANEL_LCD_SPI_CMD_BITS (32) // Typically set to 32
|
#define ESP_PANEL_LCD_SPI_CMD_BITS (32) // Typically set to 32
|
||||||
#define ESP_PANEL_LCD_SPI_PARAM_BITS (8) // Typically set to 8
|
#define ESP_PANEL_LCD_SPI_PARAM_BITS (8) // Typically set to 8
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ extern "C" {
|
|||||||
#define EXAMPLE_LCD_BK_LIGHT_ON_LEVEL (1)
|
#define EXAMPLE_LCD_BK_LIGHT_ON_LEVEL (1)
|
||||||
#define EXAMPLE_LCD_BK_LIGHT_OFF_LEVEL !EXAMPLE_LCD_BK_LIGHT_ON_LEVEL
|
#define EXAMPLE_LCD_BK_LIGHT_OFF_LEVEL !EXAMPLE_LCD_BK_LIGHT_ON_LEVEL
|
||||||
|
|
||||||
#define ESP_PANEL_HOST_SPI_MAX_TRANSFER_SIZE (2048)
|
#define ESP_PANEL_HOST_SPI_MAX_TRANSFER_SIZE (8192)
|
||||||
|
|
||||||
#define LEDC_HS_TIMER LEDC_TIMER_0
|
#define LEDC_HS_TIMER LEDC_TIMER_0
|
||||||
#define LEDC_LS_MODE LEDC_LOW_SPEED_MODE
|
#define LEDC_LS_MODE LEDC_LOW_SPEED_MODE
|
||||||
|
|||||||
@@ -18,13 +18,12 @@ void example_increase_lvgl_tick(void *arg)
|
|||||||
void example_lvgl_flush_cb(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map)
|
void example_lvgl_flush_cb(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map)
|
||||||
{
|
{
|
||||||
esp_lcd_panel_handle_t panel_handle = (esp_lcd_panel_handle_t) drv->user_data;
|
esp_lcd_panel_handle_t panel_handle = (esp_lcd_panel_handle_t) drv->user_data;
|
||||||
int offsetx1 = area->x1;
|
// 立即通知LVGL传输开始,使用DMA传输
|
||||||
int offsetx2 = area->x2;
|
|
||||||
int offsety1 = area->y1;
|
|
||||||
int offsety2 = area->y2;
|
|
||||||
// copy a buffer's content to a specific area of the display
|
|
||||||
esp_lcd_panel_draw_bitmap(panel_handle, offsetx1, offsety1, offsetx2 +1, offsety2 + 1, color_map);
|
|
||||||
lv_disp_flush_ready(drv);
|
lv_disp_flush_ready(drv);
|
||||||
|
|
||||||
|
// copy a buffer's content to a specific area of the display
|
||||||
|
// 异步传输数据
|
||||||
|
esp_lcd_panel_draw_bitmap(panel_handle, area->x1, area->y1, area->x2 + 1, area->y2 + 1, color_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Read the touchpad*/
|
/*Read the touchpad*/
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ extern "C" {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define LVGL_BUF_LEN (EXAMPLE_LCD_WIDTH * EXAMPLE_LCD_HEIGHT / 20)
|
#define LVGL_BUF_LEN (EXAMPLE_LCD_WIDTH * EXAMPLE_LCD_HEIGHT / 8) // 1 byte per pixel
|
||||||
#define EXAMPLE_LVGL_TICK_PERIOD_MS 2
|
#define EXAMPLE_LVGL_TICK_PERIOD_MS 2
|
||||||
|
|
||||||
extern lv_disp_draw_buf_t disp_buf; // contains internal graphic buffer(s) called draw buffer(s)
|
extern lv_disp_draw_buf_t disp_buf; // contains internal graphic buffer(s) called draw buffer(s)
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ uint32_t Flash_Size = 0;
|
|||||||
uint32_t SDCard_Size = 0;
|
uint32_t SDCard_Size = 0;
|
||||||
|
|
||||||
|
|
||||||
esp_err_t s_example_write_file(const char *path, char *data)
|
esp_err_t s_example_write_file(const char *path, const char *data, const char *type)
|
||||||
{
|
{
|
||||||
ESP_LOGI(SD_TAG, "Opening file %s", path);
|
ESP_LOGI(SD_TAG, "Opening file %s", path);
|
||||||
FILE *f = fopen(path, "w");
|
FILE *f = fopen(path, type);
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
ESP_LOGE(SD_TAG, "Failed to open file for writing");
|
ESP_LOGE(SD_TAG, "Failed to open file for writing");
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ extern "C" {
|
|||||||
esp_err_t SD_Card_CS_EN(void);
|
esp_err_t SD_Card_CS_EN(void);
|
||||||
esp_err_t SD_Card_CS_Dis(void);
|
esp_err_t SD_Card_CS_Dis(void);
|
||||||
|
|
||||||
esp_err_t s_example_write_file(const char *path, char *data);
|
esp_err_t s_example_write_file(const char *path, const char *data, const char *type);
|
||||||
esp_err_t s_example_read_file(const char *path);
|
esp_err_t s_example_read_file(const char *path);
|
||||||
|
|
||||||
extern uint32_t SDCard_Size;
|
extern uint32_t SDCard_Size;
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ uint16_t WIFI_Scan(void)
|
|||||||
return ap_count;
|
return ap_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
#define GATTC_TAG "GATTC_TAG"
|
#define GATTC_TAG "GATTC_TAG"
|
||||||
#define SCAN_DURATION 5
|
#define SCAN_DURATION 5
|
||||||
#define MAX_DISCOVERED_DEVICES 100
|
#define MAX_DISCOVERED_DEVICES 100
|
||||||
@@ -266,7 +266,7 @@ uint16_t BLE_Scan(void)
|
|||||||
Scan_finish = 1;
|
Scan_finish = 1;
|
||||||
return BLE_NUM;
|
return BLE_NUM;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// 下面是新增的实现
|
// 下面是新增的实现
|
||||||
static EventGroupHandle_t s_wifi_event_group;
|
static EventGroupHandle_t s_wifi_event_group;
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ extern "C" {
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h> // For memcpy
|
#include <string.h> // For memcpy
|
||||||
#include "esp_system.h"
|
#include "esp_system.h"
|
||||||
#include "esp_bt.h"
|
// #include "esp_bt.h"
|
||||||
#include "esp_gap_ble_api.h"
|
// #include "esp_gap_ble_api.h"
|
||||||
#include "esp_bt_main.h"
|
// #include "esp_bt_main.h"
|
||||||
|
|
||||||
// WiFi AP信息结构体
|
// WiFi AP信息结构体
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|||||||
@@ -307,3 +307,88 @@ extern "C" void app_main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
```c++
|
||||||
|
// 有关lvgl_cpp的部分控件使用
|
||||||
|
/* LVGL 已经初始化,屏幕驱动已注册 */
|
||||||
|
auto scr = lvgl_cpp::Screen{}; // RAII,离开作用域自动 del
|
||||||
|
lv_scr_load(scr.raw()); // 让 LVGL 把它当活动屏幕
|
||||||
|
|
||||||
|
lvgl_cpp::Image img(scr);
|
||||||
|
img.bin("pic_no_alp_swap.bin", 720, 720)
|
||||||
|
.center();
|
||||||
|
|
||||||
|
/* 1. 创建按钮 */
|
||||||
|
/* 1. 黑色文字样式 */
|
||||||
|
static lvgl_cpp::Style txt_style;
|
||||||
|
txt_style.text_color(lv_color_black());
|
||||||
|
|
||||||
|
/* 2. 按钮 */
|
||||||
|
lvgl_cpp::Button btn{scr};
|
||||||
|
btn.size(150, 60).pos(40, 40);
|
||||||
|
/* 3. 先创建 Label 对象并保存,再链式调 */
|
||||||
|
lvgl_cpp::Label lbl{btn}; // 一定要存实例
|
||||||
|
lbl.text("Click Me")
|
||||||
|
.add_style(&txt_style.s, LV_PART_MAIN); // 样式作用到文字本身
|
||||||
|
/* 3. 注册点击事件 */
|
||||||
|
btn.on(LV_EVENT_CLICKED, [](lv_event_t*){
|
||||||
|
lvgl_cpp::Toast::show("Saved successfully !");
|
||||||
|
/* 2. 警告,3 s,顶部 */
|
||||||
|
lvgl_cpp::Toast::show("SD card missing", lvgl_cpp::Toast::Type::WARN, 3000, LV_ALIGN_TOP_MID, 20);
|
||||||
|
|
||||||
|
/* 3. 错误,1.5 s,底部右侧 */
|
||||||
|
lvgl_cpp::Toast::show("Network error", lvgl_cpp::Toast::Type::ERROR, 1500, LV_ALIGN_BOTTOM_RIGHT, -30);
|
||||||
|
ESP_LOGI("BTN", "pressed");
|
||||||
|
});
|
||||||
|
|
||||||
|
/* 1. 消息框 */
|
||||||
|
const char* btns[] = {"Yes", "No", ""};
|
||||||
|
auto mbox = lvgl_cpp::MsgBox::create("Hint", "Delete file ?", btns);
|
||||||
|
|
||||||
|
/* 3. 进度条(双向 + 动画) */
|
||||||
|
lvgl_cpp::Bar bar(scr);
|
||||||
|
bar.range(0, 100)
|
||||||
|
.start_value(20) // 左端
|
||||||
|
.value(80, LV_ANIM_ON) // 右端带动画
|
||||||
|
.anim_time(500)
|
||||||
|
.size(200, 15)
|
||||||
|
.align(LV_ALIGN_CENTER, nullptr, 0, 40);
|
||||||
|
|
||||||
|
/* 4. 折线:画一个 △ */
|
||||||
|
std::vector<lv_point_t> triangle = {{0,0}, {40,0}, {20,40}, {0,0}};
|
||||||
|
lvgl_cpp::Line line(scr);
|
||||||
|
line.points(triangle)
|
||||||
|
.y_invert(false)
|
||||||
|
.align(LV_ALIGN_CENTER, nullptr, 0, 100);
|
||||||
|
|
||||||
|
lvgl_cpp::Battery bat(scr);
|
||||||
|
bat.size(60, 30) // 手机经典尺寸
|
||||||
|
.percent(true) // 显示 50%
|
||||||
|
.onRead([]() -> uint8_t { // 替换成你的 ADC/INA219 回调
|
||||||
|
static uint8_t v = 100;
|
||||||
|
if (v) --v;
|
||||||
|
return v;
|
||||||
|
})
|
||||||
|
.align(LV_ALIGN_TOP_RIGHT, -10, 10); // 九宫格对齐
|
||||||
|
|
||||||
|
/* 3. 日期时间 */
|
||||||
|
lvgl_cpp::DateTime dt(scr);
|
||||||
|
dt.format("%m/%d %a %H:%M")
|
||||||
|
.onRead([](char* buf, size_t len){
|
||||||
|
/* 这里用 SNTP / RTC 填充,示例直接给假时间 */
|
||||||
|
snprintf(buf, len, "06/25 Tue 14:30");
|
||||||
|
})
|
||||||
|
.align(LV_ALIGN_BOTTOM_MID, nullptr, 0, -10);
|
||||||
|
|
||||||
|
|
||||||
|
lvgl_cpp::ColorPicker cp(scr);
|
||||||
|
cp.size(120, 120)
|
||||||
|
.align(LV_ALIGN_BOTTOM_MID, nullptr, 0, -20)
|
||||||
|
.on(LV_EVENT_VALUE_CHANGED, [&](lv_event_t*){
|
||||||
|
lv_color_t c = cp.color();
|
||||||
|
ESP_LOGI("CP", "rgb=%d,%d,%d", c.ch.red, c.ch.green_h, c.ch.blue);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
+11
-4
@@ -1,10 +1,9 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
#include <esp_log.h>
|
#include <esp_log.h>
|
||||||
|
#include <nvs.h>
|
||||||
|
#include <nvs_flash.h>
|
||||||
|
|
||||||
#include "err_handle.h"
|
#include "err_handle.h"
|
||||||
|
|
||||||
#include "drivers_test.h"
|
#include "drivers_test.h"
|
||||||
#include "CppHandle.h"
|
#include "CppHandle.h"
|
||||||
|
|
||||||
@@ -34,9 +33,17 @@ void app_main(void)
|
|||||||
|
|
||||||
// mic_speech_and_gif_and_music_test();
|
// mic_speech_and_gif_and_music_test();
|
||||||
|
|
||||||
|
// 初始化NVS
|
||||||
|
esp_err_t ret = nvs_flash_init();
|
||||||
|
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||||
|
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||||
|
ret = nvs_flash_init();
|
||||||
|
}
|
||||||
|
ESP_ERROR_CHECK(ret);
|
||||||
|
|
||||||
Cpp_Hand();
|
Cpp_Hand();
|
||||||
|
|
||||||
ESP_GOTO(err);
|
ESP_GOTO(err);
|
||||||
err:
|
err:
|
||||||
ESP_LOGI("app_main", "app_main error");
|
ESP_LOGE("app_main", "app_main error");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,10 +38,13 @@ idf_component_register(SRCS "Bionic_sphere.c"
|
|||||||
"../Bionic_Core/ToolsClass/ToolsClass.cpp" # 工具类库
|
"../Bionic_Core/ToolsClass/ToolsClass.cpp" # 工具类库
|
||||||
"../Bionic_Core/ToolsClass/AudioOutput/AudioOutput.cpp" # 音频输出类库
|
"../Bionic_Core/ToolsClass/AudioOutput/AudioOutput.cpp" # 音频输出类库
|
||||||
"../Bionic_Core/ToolsClass/LVGL_Render/LVGLRender.cpp" # LVGL渲染类库
|
"../Bionic_Core/ToolsClass/LVGL_Render/LVGLRender.cpp" # LVGL渲染类库
|
||||||
|
"../Bionic_Core/ToolsClass/LVGL_Render/LvppApp/BaseApp.cpp"
|
||||||
"../Bionic_Core/ToolsClass/LVGL_Render/Lvpp/SiYuanHeiTiGoogleBan.c" # 中文字体库
|
"../Bionic_Core/ToolsClass/LVGL_Render/Lvpp/SiYuanHeiTiGoogleBan.c" # 中文字体库
|
||||||
"../Bionic_Core/ToolsClass/LVGL_Render/Lvpp/lvpp.cpp"
|
"../Bionic_Core/ToolsClass/LVGL_Render/Lvpp/lvpp.cpp"
|
||||||
"../Bionic_Core/ToolsClass/SDFileManager/SDFileManager.cpp" # SD文件管理类库
|
"../Bionic_Core/ToolsClass/SDFileManager/SDFileManager.cpp" # SD文件管理类库
|
||||||
"../Bionic_Core/ToolsClass/SpeechRecognizer/SpeechRecognizer.cpp" # 语音识别类库
|
"../Bionic_Core/ToolsClass/SpeechRecognizer/SpeechRecognizer.cpp" # 语音识别类库
|
||||||
|
"../Bionic_Core/ToolsClass/SpeechRecognizer/VadSlidingWindow.cpp"
|
||||||
|
"../Bionic_Core/ToolsClass/SpeechRecognizer/SimpleI2SForwarder.cpp"
|
||||||
"../Bionic_Core/ToolsClass/WifiConnectors/WifiConnectors.cpp" # WIFI连接类库
|
"../Bionic_Core/ToolsClass/WifiConnectors/WifiConnectors.cpp" # WIFI连接类库
|
||||||
"../Bionic_Core/ToolsClass/ThreadManager/ThreadManager.cpp" # 线程管理类库
|
"../Bionic_Core/ToolsClass/ThreadManager/ThreadManager.cpp" # 线程管理类库
|
||||||
"../Bionic_Core/ToolsClass/Sys_Config/sys_conf_singleton.cpp" # 系统配置类库
|
"../Bionic_Core/ToolsClass/Sys_Config/sys_conf_singleton.cpp" # 系统配置类库
|
||||||
@@ -78,6 +81,7 @@ idf_component_register(SRCS "Bionic_sphere.c"
|
|||||||
"../Bionic_Core/ToolsClass"
|
"../Bionic_Core/ToolsClass"
|
||||||
"../Bionic_Core/ToolsClass/AudioOutput"
|
"../Bionic_Core/ToolsClass/AudioOutput"
|
||||||
"../Bionic_Core/ToolsClass/LVGL_Render"
|
"../Bionic_Core/ToolsClass/LVGL_Render"
|
||||||
|
"../Bionic_Core/ToolsClass/LVGL_Render/LvppApp"
|
||||||
"../Bionic_Core/ToolsClass/LVGL_Render/Lvpp"
|
"../Bionic_Core/ToolsClass/LVGL_Render/Lvpp"
|
||||||
"../Bionic_Core/ToolsClass/SDFileManager"
|
"../Bionic_Core/ToolsClass/SDFileManager"
|
||||||
"../Bionic_Core/ToolsClass/SpeechRecognizer"
|
"../Bionic_Core/ToolsClass/SpeechRecognizer"
|
||||||
|
|||||||
@@ -766,9 +766,9 @@ CONFIG_CN_SPEECH_COMMAND_ID199=""
|
|||||||
#
|
#
|
||||||
# Compiler options
|
# Compiler options
|
||||||
#
|
#
|
||||||
CONFIG_COMPILER_OPTIMIZATION_DEBUG=y
|
# CONFIG_COMPILER_OPTIMIZATION_DEBUG is not set
|
||||||
# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set
|
# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set
|
||||||
# CONFIG_COMPILER_OPTIMIZATION_PERF is not set
|
CONFIG_COMPILER_OPTIMIZATION_PERF=y
|
||||||
# CONFIG_COMPILER_OPTIMIZATION_NONE is not set
|
# CONFIG_COMPILER_OPTIMIZATION_NONE is not set
|
||||||
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y
|
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y
|
||||||
# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set
|
# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set
|
||||||
@@ -814,334 +814,10 @@ CONFIG_APPTRACE_LOCK_ENABLE=y
|
|||||||
#
|
#
|
||||||
# Bluetooth
|
# Bluetooth
|
||||||
#
|
#
|
||||||
CONFIG_BT_ENABLED=y
|
# CONFIG_BT_ENABLED is not set
|
||||||
CONFIG_BT_BLUEDROID_ENABLED=y
|
|
||||||
# CONFIG_BT_NIMBLE_ENABLED is not set
|
|
||||||
# CONFIG_BT_CONTROLLER_ONLY is not set
|
|
||||||
CONFIG_BT_CONTROLLER_ENABLED=y
|
|
||||||
# CONFIG_BT_CONTROLLER_DISABLED is not set
|
|
||||||
|
|
||||||
#
|
|
||||||
# Bluedroid Options
|
|
||||||
#
|
|
||||||
CONFIG_BT_BTC_TASK_STACK_SIZE=3072
|
|
||||||
CONFIG_BT_BLUEDROID_PINNED_TO_CORE_0=y
|
|
||||||
# CONFIG_BT_BLUEDROID_PINNED_TO_CORE_1 is not set
|
|
||||||
CONFIG_BT_BLUEDROID_PINNED_TO_CORE=0
|
|
||||||
CONFIG_BT_BTU_TASK_STACK_SIZE=4352
|
|
||||||
# CONFIG_BT_BLUEDROID_MEM_DEBUG is not set
|
|
||||||
CONFIG_BT_BLUEDROID_ESP_COEX_VSC=y
|
|
||||||
CONFIG_BT_BLE_ENABLED=y
|
|
||||||
CONFIG_BT_GATTS_ENABLE=y
|
|
||||||
# CONFIG_BT_GATTS_PPCP_CHAR_GAP is not set
|
|
||||||
# CONFIG_BT_BLE_BLUFI_ENABLE is not set
|
|
||||||
CONFIG_BT_GATT_MAX_SR_PROFILES=8
|
|
||||||
CONFIG_BT_GATT_MAX_SR_ATTRIBUTES=100
|
|
||||||
# CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MANUAL is not set
|
|
||||||
CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_AUTO=y
|
|
||||||
CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MODE=0
|
|
||||||
# CONFIG_BT_GATTS_ROBUST_CACHING_ENABLED is not set
|
|
||||||
# CONFIG_BT_GATTS_DEVICE_NAME_WRITABLE is not set
|
|
||||||
# CONFIG_BT_GATTS_APPEARANCE_WRITABLE is not set
|
|
||||||
CONFIG_BT_GATTC_ENABLE=y
|
|
||||||
CONFIG_BT_GATTC_MAX_CACHE_CHAR=40
|
|
||||||
CONFIG_BT_GATTC_NOTIF_REG_MAX=5
|
|
||||||
# CONFIG_BT_GATTC_CACHE_NVS_FLASH is not set
|
|
||||||
CONFIG_BT_GATTC_CONNECT_RETRY_COUNT=3
|
|
||||||
CONFIG_BT_BLE_SMP_ENABLE=y
|
|
||||||
# CONFIG_BT_SMP_SLAVE_CON_PARAMS_UPD_ENABLE is not set
|
|
||||||
# CONFIG_BT_BLE_SMP_ID_RESET_ENABLE is not set
|
|
||||||
# CONFIG_BT_STACK_NO_LOG is not set
|
|
||||||
|
|
||||||
#
|
|
||||||
# BT DEBUG LOG LEVEL
|
|
||||||
#
|
|
||||||
# CONFIG_BT_LOG_HCI_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_HCI_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_HCI_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_HCI_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_HCI_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_HCI_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_HCI_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_HCI_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_BTM_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_BTM_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_BTM_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_BTM_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_BTM_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_BTM_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_BTM_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_BTM_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_L2CAP_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_SDP_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_SDP_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_SDP_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_SDP_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_SDP_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_SDP_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_SDP_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_SDP_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_GAP_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_GAP_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_GAP_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_GAP_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_GAP_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_GAP_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_GAP_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_GAP_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_BNEP_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_BNEP_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_PAN_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_PAN_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_PAN_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_PAN_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_PAN_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_PAN_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_PAN_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_PAN_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_A2D_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_A2D_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_A2D_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_A2D_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_A2D_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_A2D_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_A2D_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_A2D_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_AVDT_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_AVDT_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_AVCT_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_AVCT_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_AVRC_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_AVRC_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_MCA_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_MCA_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_MCA_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_MCA_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_MCA_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_MCA_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_MCA_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_MCA_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_HID_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_HID_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_HID_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_HID_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_HID_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_HID_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_HID_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_HID_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_APPL_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_APPL_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_APPL_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_APPL_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_APPL_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_APPL_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_APPL_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_APPL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_GATT_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_GATT_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_GATT_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_GATT_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_GATT_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_GATT_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_GATT_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_GATT_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_SMP_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_SMP_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_SMP_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_SMP_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_SMP_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_SMP_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_SMP_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_SMP_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_BTIF_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_BTIF_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_BTC_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_BTC_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_BTC_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_BTC_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_BTC_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_BTC_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_BTC_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_BTC_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_OSI_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_OSI_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_OSI_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_OSI_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_OSI_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_OSI_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_OSI_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_OSI_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_BLUFI_TRACE_LEVEL=2
|
|
||||||
# end of BT DEBUG LOG LEVEL
|
|
||||||
|
|
||||||
CONFIG_BT_ACL_CONNECTIONS=4
|
|
||||||
CONFIG_BT_MULTI_CONNECTION_ENBALE=y
|
|
||||||
# CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST is not set
|
|
||||||
# CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY is not set
|
|
||||||
# CONFIG_BT_BLE_HOST_QUEUE_CONG_CHECK is not set
|
|
||||||
CONFIG_BT_SMP_ENABLE=y
|
|
||||||
CONFIG_BT_SMP_MAX_BONDS=15
|
|
||||||
# CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN is not set
|
|
||||||
CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30
|
|
||||||
CONFIG_BT_MAX_DEVICE_NAME_LEN=32
|
|
||||||
CONFIG_BT_BLE_RPA_TIMEOUT=900
|
|
||||||
CONFIG_BT_BLE_50_FEATURES_SUPPORTED=y
|
|
||||||
CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y
|
|
||||||
# CONFIG_BT_BLE_HIGH_DUTY_ADV_INTERVAL is not set
|
|
||||||
# CONFIG_BT_ABORT_WHEN_ALLOCATION_FAILS is not set
|
|
||||||
# end of Bluedroid Options
|
|
||||||
|
|
||||||
#
|
|
||||||
# Controller Options
|
|
||||||
#
|
|
||||||
CONFIG_BT_CTRL_MODE_EFF=1
|
|
||||||
CONFIG_BT_CTRL_BLE_MAX_ACT=6
|
|
||||||
CONFIG_BT_CTRL_BLE_MAX_ACT_EFF=6
|
|
||||||
CONFIG_BT_CTRL_BLE_STATIC_ACL_TX_BUF_NB=0
|
|
||||||
CONFIG_BT_CTRL_PINNED_TO_CORE_0=y
|
|
||||||
# CONFIG_BT_CTRL_PINNED_TO_CORE_1 is not set
|
|
||||||
CONFIG_BT_CTRL_PINNED_TO_CORE=0
|
|
||||||
CONFIG_BT_CTRL_HCI_MODE_VHCI=y
|
|
||||||
# CONFIG_BT_CTRL_HCI_MODE_UART_H4 is not set
|
|
||||||
CONFIG_BT_CTRL_HCI_TL=1
|
|
||||||
CONFIG_BT_CTRL_ADV_DUP_FILT_MAX=30
|
|
||||||
CONFIG_BT_BLE_CCA_MODE_NONE=y
|
|
||||||
# CONFIG_BT_BLE_CCA_MODE_HW is not set
|
|
||||||
# CONFIG_BT_BLE_CCA_MODE_SW is not set
|
|
||||||
CONFIG_BT_BLE_CCA_MODE=0
|
|
||||||
CONFIG_BT_CTRL_HW_CCA_VAL=20
|
|
||||||
CONFIG_BT_CTRL_HW_CCA_EFF=0
|
|
||||||
CONFIG_BT_CTRL_CE_LENGTH_TYPE_ORIG=y
|
|
||||||
# CONFIG_BT_CTRL_CE_LENGTH_TYPE_CE is not set
|
|
||||||
# CONFIG_BT_CTRL_CE_LENGTH_TYPE_SD is not set
|
|
||||||
CONFIG_BT_CTRL_CE_LENGTH_TYPE_EFF=0
|
|
||||||
CONFIG_BT_CTRL_TX_ANTENNA_INDEX_0=y
|
|
||||||
# CONFIG_BT_CTRL_TX_ANTENNA_INDEX_1 is not set
|
|
||||||
CONFIG_BT_CTRL_TX_ANTENNA_INDEX_EFF=0
|
|
||||||
CONFIG_BT_CTRL_RX_ANTENNA_INDEX_0=y
|
|
||||||
# CONFIG_BT_CTRL_RX_ANTENNA_INDEX_1 is not set
|
|
||||||
CONFIG_BT_CTRL_RX_ANTENNA_INDEX_EFF=0
|
|
||||||
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N24 is not set
|
|
||||||
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N21 is not set
|
|
||||||
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N18 is not set
|
|
||||||
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N15 is not set
|
|
||||||
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N12 is not set
|
|
||||||
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N9 is not set
|
|
||||||
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N6 is not set
|
|
||||||
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N3 is not set
|
|
||||||
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N0 is not set
|
|
||||||
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P3 is not set
|
|
||||||
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P6 is not set
|
|
||||||
CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P9=y
|
|
||||||
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P12 is not set
|
|
||||||
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P15 is not set
|
|
||||||
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P18 is not set
|
|
||||||
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P20 is not set
|
|
||||||
CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=11
|
|
||||||
CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y
|
|
||||||
CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM=100
|
|
||||||
CONFIG_BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD=20
|
|
||||||
CONFIG_BT_CTRL_BLE_SCAN_DUPL=y
|
|
||||||
CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DEVICE=y
|
|
||||||
# CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA is not set
|
|
||||||
# CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE is not set
|
|
||||||
CONFIG_BT_CTRL_SCAN_DUPL_TYPE=0
|
|
||||||
CONFIG_BT_CTRL_SCAN_DUPL_CACHE_SIZE=100
|
|
||||||
CONFIG_BT_CTRL_DUPL_SCAN_CACHE_REFRESH_PERIOD=0
|
|
||||||
# CONFIG_BT_CTRL_BLE_MESH_SCAN_DUPL_EN is not set
|
|
||||||
# CONFIG_BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_EN is not set
|
|
||||||
CONFIG_BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_DIS=y
|
|
||||||
CONFIG_BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_EFF=0
|
|
||||||
|
|
||||||
#
|
|
||||||
# MODEM SLEEP Options
|
|
||||||
#
|
|
||||||
# CONFIG_BT_CTRL_MODEM_SLEEP is not set
|
|
||||||
# end of MODEM SLEEP Options
|
|
||||||
|
|
||||||
CONFIG_BT_CTRL_SLEEP_MODE_EFF=0
|
|
||||||
CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0
|
|
||||||
CONFIG_BT_CTRL_HCI_TL_EFF=1
|
|
||||||
# CONFIG_BT_CTRL_AGC_RECORRECT_EN is not set
|
|
||||||
# CONFIG_BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX is not set
|
|
||||||
# CONFIG_BT_BLE_ADV_DATA_LENGTH_ZERO_AUX is not set
|
|
||||||
CONFIG_BT_CTRL_CHAN_ASS_EN=y
|
|
||||||
CONFIG_BT_CTRL_LE_PING_EN=y
|
|
||||||
|
|
||||||
#
|
|
||||||
# BLE disconnect when instant passed
|
|
||||||
#
|
|
||||||
# CONFIG_BT_CTRL_BLE_LLCP_CONN_UPDATE is not set
|
|
||||||
# CONFIG_BT_CTRL_BLE_LLCP_CHAN_MAP_UPDATE is not set
|
|
||||||
# CONFIG_BT_CTRL_BLE_LLCP_PHY_UPDATE is not set
|
|
||||||
# end of BLE disconnect when instant passed
|
|
||||||
|
|
||||||
# CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY is not set
|
|
||||||
# end of Controller Options
|
|
||||||
|
|
||||||
#
|
|
||||||
# Common Options
|
|
||||||
#
|
|
||||||
CONFIG_BT_ALARM_MAX_NUM=50
|
CONFIG_BT_ALARM_MAX_NUM=50
|
||||||
# end of Common Options
|
|
||||||
|
|
||||||
# CONFIG_BT_HCI_LOG_DEBUG_EN is not set
|
|
||||||
# end of Bluetooth
|
# end of Bluetooth
|
||||||
|
|
||||||
# CONFIG_BLE_MESH is not set
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Console Library
|
# Console Library
|
||||||
#
|
#
|
||||||
@@ -1248,8 +924,7 @@ CONFIG_ESP_TLS_USE_DS_PERIPHERAL=y
|
|||||||
# Wireless Coexistence
|
# Wireless Coexistence
|
||||||
#
|
#
|
||||||
CONFIG_ESP_COEX_ENABLED=y
|
CONFIG_ESP_COEX_ENABLED=y
|
||||||
CONFIG_ESP_COEX_SW_COEXIST_ENABLE=y
|
# CONFIG_ESP_COEX_EXTERNAL_COEXIST_ENABLE is not set
|
||||||
# CONFIG_ESP_COEX_POWER_MANAGEMENT is not set
|
|
||||||
# CONFIG_ESP_COEX_GPIO_DEBUG is not set
|
# CONFIG_ESP_COEX_GPIO_DEBUG is not set
|
||||||
# end of Wireless Coexistence
|
# end of Wireless Coexistence
|
||||||
|
|
||||||
@@ -1257,6 +932,7 @@ CONFIG_ESP_COEX_SW_COEXIST_ENABLE=y
|
|||||||
# Common ESP-related
|
# Common ESP-related
|
||||||
#
|
#
|
||||||
CONFIG_ESP_ERR_TO_NAME_LOOKUP=y
|
CONFIG_ESP_ERR_TO_NAME_LOOKUP=y
|
||||||
|
CONFIG_ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y
|
||||||
# end of Common ESP-related
|
# end of Common ESP-related
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -1328,7 +1004,7 @@ CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y
|
|||||||
#
|
#
|
||||||
# ESP-Driver:SPI Configurations
|
# ESP-Driver:SPI Configurations
|
||||||
#
|
#
|
||||||
# CONFIG_SPI_MASTER_IN_IRAM is not set
|
CONFIG_SPI_MASTER_IN_IRAM=y
|
||||||
CONFIG_SPI_MASTER_ISR_IN_IRAM=y
|
CONFIG_SPI_MASTER_ISR_IN_IRAM=y
|
||||||
# CONFIG_SPI_SLAVE_IN_IRAM is not set
|
# CONFIG_SPI_SLAVE_IN_IRAM is not set
|
||||||
CONFIG_SPI_SLAVE_ISR_IN_IRAM=y
|
CONFIG_SPI_SLAVE_ISR_IN_IRAM=y
|
||||||
@@ -1510,6 +1186,7 @@ CONFIG_XTAL_FREQ=40
|
|||||||
# end of Main XTAL Config
|
# end of Main XTAL Config
|
||||||
|
|
||||||
CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y
|
CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y
|
||||||
|
CONFIG_ESP_SPI_BUS_LOCK_FUNCS_IN_IRAM=y
|
||||||
# end of Hardware Settings
|
# end of Hardware Settings
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -1597,15 +1274,14 @@ CONFIG_SPIRAM_SPEED_80M=y
|
|||||||
CONFIG_SPIRAM_SPEED=80
|
CONFIG_SPIRAM_SPEED=80
|
||||||
# CONFIG_SPIRAM_ECC_ENABLE is not set
|
# CONFIG_SPIRAM_ECC_ENABLE is not set
|
||||||
CONFIG_SPIRAM_BOOT_INIT=y
|
CONFIG_SPIRAM_BOOT_INIT=y
|
||||||
# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set
|
|
||||||
# CONFIG_SPIRAM_USE_MEMMAP is not set
|
# CONFIG_SPIRAM_USE_MEMMAP is not set
|
||||||
# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set
|
# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set
|
||||||
CONFIG_SPIRAM_USE_MALLOC=y
|
CONFIG_SPIRAM_USE_MALLOC=y
|
||||||
CONFIG_SPIRAM_MEMTEST=y
|
CONFIG_SPIRAM_MEMTEST=y
|
||||||
CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384
|
CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=4096
|
||||||
# CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP is not set
|
CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y
|
||||||
CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768
|
CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=65536
|
||||||
# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set
|
CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y
|
||||||
# CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY is not set
|
# CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY is not set
|
||||||
# end of SPI RAM config
|
# end of SPI RAM config
|
||||||
# end of ESP PSRAM
|
# end of ESP PSRAM
|
||||||
@@ -1637,13 +1313,12 @@ CONFIG_ESP32S3_ICACHE_ASSOCIATED_WAYS=8
|
|||||||
CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_32B=y
|
CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_32B=y
|
||||||
CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_SIZE=32
|
CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_SIZE=32
|
||||||
# CONFIG_ESP32S3_DATA_CACHE_16KB is not set
|
# CONFIG_ESP32S3_DATA_CACHE_16KB is not set
|
||||||
CONFIG_ESP32S3_DATA_CACHE_32KB=y
|
# CONFIG_ESP32S3_DATA_CACHE_32KB is not set
|
||||||
# CONFIG_ESP32S3_DATA_CACHE_64KB is not set
|
CONFIG_ESP32S3_DATA_CACHE_64KB=y
|
||||||
CONFIG_ESP32S3_DATA_CACHE_SIZE=0x8000
|
CONFIG_ESP32S3_DATA_CACHE_SIZE=0x10000
|
||||||
# CONFIG_ESP32S3_DATA_CACHE_4WAYS is not set
|
# CONFIG_ESP32S3_DATA_CACHE_4WAYS is not set
|
||||||
CONFIG_ESP32S3_DATA_CACHE_8WAYS=y
|
CONFIG_ESP32S3_DATA_CACHE_8WAYS=y
|
||||||
CONFIG_ESP32S3_DCACHE_ASSOCIATED_WAYS=8
|
CONFIG_ESP32S3_DCACHE_ASSOCIATED_WAYS=8
|
||||||
# CONFIG_ESP32S3_DATA_CACHE_LINE_16B is not set
|
|
||||||
CONFIG_ESP32S3_DATA_CACHE_LINE_32B=y
|
CONFIG_ESP32S3_DATA_CACHE_LINE_32B=y
|
||||||
# CONFIG_ESP32S3_DATA_CACHE_LINE_64B is not set
|
# CONFIG_ESP32S3_DATA_CACHE_LINE_64B is not set
|
||||||
CONFIG_ESP32S3_DATA_CACHE_LINE_SIZE=32
|
CONFIG_ESP32S3_DATA_CACHE_LINE_SIZE=32
|
||||||
@@ -1758,11 +1433,11 @@ CONFIG_ESP_TIMER_IMPL_SYSTIMER=y
|
|||||||
# Wi-Fi
|
# Wi-Fi
|
||||||
#
|
#
|
||||||
CONFIG_ESP_WIFI_ENABLED=y
|
CONFIG_ESP_WIFI_ENABLED=y
|
||||||
CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10
|
CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=2
|
||||||
CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32
|
CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32
|
||||||
CONFIG_ESP_WIFI_STATIC_TX_BUFFER=y
|
CONFIG_ESP_WIFI_STATIC_TX_BUFFER=y
|
||||||
CONFIG_ESP_WIFI_TX_BUFFER_TYPE=0
|
CONFIG_ESP_WIFI_TX_BUFFER_TYPE=0
|
||||||
CONFIG_ESP_WIFI_STATIC_TX_BUFFER_NUM=16
|
CONFIG_ESP_WIFI_STATIC_TX_BUFFER_NUM=4
|
||||||
CONFIG_ESP_WIFI_CACHE_TX_BUFFER_NUM=32
|
CONFIG_ESP_WIFI_CACHE_TX_BUFFER_NUM=32
|
||||||
CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y
|
CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y
|
||||||
# CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set
|
# CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set
|
||||||
@@ -1770,9 +1445,9 @@ CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0
|
|||||||
CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5
|
CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5
|
||||||
# CONFIG_ESP_WIFI_CSI_ENABLED is not set
|
# CONFIG_ESP_WIFI_CSI_ENABLED is not set
|
||||||
CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y
|
CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y
|
||||||
CONFIG_ESP_WIFI_TX_BA_WIN=6
|
CONFIG_ESP_WIFI_TX_BA_WIN=2
|
||||||
CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y
|
CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y
|
||||||
CONFIG_ESP_WIFI_RX_BA_WIN=6
|
CONFIG_ESP_WIFI_RX_BA_WIN=2
|
||||||
# CONFIG_ESP_WIFI_AMSDU_TX_ENABLED is not set
|
# CONFIG_ESP_WIFI_AMSDU_TX_ENABLED is not set
|
||||||
CONFIG_ESP_WIFI_NVS_ENABLED=y
|
CONFIG_ESP_WIFI_NVS_ENABLED=y
|
||||||
CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y
|
CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y
|
||||||
@@ -1916,7 +1591,6 @@ CONFIG_FREERTOS_RUN_TIME_COUNTER_TYPE_U32=y
|
|||||||
#
|
#
|
||||||
# Port
|
# Port
|
||||||
#
|
#
|
||||||
CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y
|
|
||||||
# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set
|
# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set
|
||||||
CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y
|
CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y
|
||||||
# CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set
|
# CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set
|
||||||
@@ -2077,6 +1751,7 @@ CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4
|
|||||||
CONFIG_LWIP_TCP_OVERSIZE_MSS=y
|
CONFIG_LWIP_TCP_OVERSIZE_MSS=y
|
||||||
# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set
|
# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set
|
||||||
# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set
|
# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set
|
||||||
|
# CONFIG_LWIP_WND_SCALE is not set
|
||||||
CONFIG_LWIP_TCP_RTO_TIME=1500
|
CONFIG_LWIP_TCP_RTO_TIME=1500
|
||||||
# end of TCP
|
# end of TCP
|
||||||
|
|
||||||
@@ -2608,10 +2283,6 @@ CONFIG_WL_SECTOR_SIZE=4096
|
|||||||
#
|
#
|
||||||
CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16
|
CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16
|
||||||
CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30
|
CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30
|
||||||
# CONFIG_WIFI_PROV_BLE_BONDING is not set
|
|
||||||
# CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set
|
|
||||||
# CONFIG_WIFI_PROV_BLE_NOTIFY is not set
|
|
||||||
# CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV is not set
|
|
||||||
CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y
|
CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y
|
||||||
# CONFIG_WIFI_PROV_STA_FAST_SCAN is not set
|
# CONFIG_WIFI_PROV_STA_FAST_SCAN is not set
|
||||||
# end of Wi-Fi Provisioning Manager
|
# end of Wi-Fi Provisioning Manager
|
||||||
@@ -2680,8 +2351,8 @@ CONFIG_LV_MEM_BUF_MAX_NUM=16
|
|||||||
#
|
#
|
||||||
# HAL Settings
|
# HAL Settings
|
||||||
#
|
#
|
||||||
CONFIG_LV_DISP_DEF_REFR_PERIOD=30
|
CONFIG_LV_DISP_DEF_REFR_PERIOD=10
|
||||||
CONFIG_LV_INDEV_DEF_READ_PERIOD=30
|
CONFIG_LV_INDEV_DEF_READ_PERIOD=10
|
||||||
# CONFIG_LV_TICK_CUSTOM is not set
|
# CONFIG_LV_TICK_CUSTOM is not set
|
||||||
CONFIG_LV_DPI_DEF=130
|
CONFIG_LV_DPI_DEF=130
|
||||||
# end of HAL Settings
|
# end of HAL Settings
|
||||||
@@ -2694,10 +2365,10 @@ CONFIG_LV_DPI_DEF=130
|
|||||||
# Drawing
|
# Drawing
|
||||||
#
|
#
|
||||||
CONFIG_LV_DRAW_COMPLEX=y
|
CONFIG_LV_DRAW_COMPLEX=y
|
||||||
CONFIG_LV_SHADOW_CACHE_SIZE=0
|
CONFIG_LV_SHADOW_CACHE_SIZE=4
|
||||||
CONFIG_LV_CIRCLE_CACHE_SIZE=4
|
CONFIG_LV_CIRCLE_CACHE_SIZE=4
|
||||||
CONFIG_LV_LAYER_SIMPLE_BUF_SIZE=24576
|
CONFIG_LV_LAYER_SIMPLE_BUF_SIZE=10240
|
||||||
CONFIG_LV_IMG_CACHE_DEF_SIZE=0
|
CONFIG_LV_IMG_CACHE_DEF_SIZE=128
|
||||||
CONFIG_LV_GRADIENT_MAX_STOPS=2
|
CONFIG_LV_GRADIENT_MAX_STOPS=2
|
||||||
CONFIG_LV_GRAD_CACHE_DEF_SIZE=0
|
CONFIG_LV_GRAD_CACHE_DEF_SIZE=0
|
||||||
# CONFIG_LV_DITHER_GRADIENT is not set
|
# CONFIG_LV_DITHER_GRADIENT is not set
|
||||||
@@ -2727,9 +2398,9 @@ CONFIG_LV_DISP_ROT_MAX_BUF=10240
|
|||||||
#
|
#
|
||||||
CONFIG_LV_USE_ASSERT_NULL=y
|
CONFIG_LV_USE_ASSERT_NULL=y
|
||||||
CONFIG_LV_USE_ASSERT_MALLOC=y
|
CONFIG_LV_USE_ASSERT_MALLOC=y
|
||||||
# CONFIG_LV_USE_ASSERT_STYLE is not set
|
CONFIG_LV_USE_ASSERT_STYLE=y
|
||||||
# CONFIG_LV_USE_ASSERT_MEM_INTEGRITY is not set
|
# CONFIG_LV_USE_ASSERT_MEM_INTEGRITY is not set
|
||||||
# CONFIG_LV_USE_ASSERT_OBJ is not set
|
CONFIG_LV_USE_ASSERT_OBJ=y
|
||||||
CONFIG_LV_ASSERT_HANDLER_INCLUDE="assert.h"
|
CONFIG_LV_ASSERT_HANDLER_INCLUDE="assert.h"
|
||||||
# end of Asserts
|
# end of Asserts
|
||||||
|
|
||||||
@@ -2990,9 +2661,9 @@ CONFIG_LOG_BOOTLOADER_LEVEL=3
|
|||||||
CONFIG_FLASHMODE_DIO=y
|
CONFIG_FLASHMODE_DIO=y
|
||||||
# CONFIG_FLASHMODE_DOUT is not set
|
# CONFIG_FLASHMODE_DOUT is not set
|
||||||
CONFIG_MONITOR_BAUD=115200
|
CONFIG_MONITOR_BAUD=115200
|
||||||
CONFIG_OPTIMIZATION_LEVEL_DEBUG=y
|
# CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set
|
||||||
CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y
|
# CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG is not set
|
||||||
CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y
|
# CONFIG_COMPILER_OPTIMIZATION_DEFAULT is not set
|
||||||
# CONFIG_OPTIMIZATION_LEVEL_RELEASE is not set
|
# CONFIG_OPTIMIZATION_LEVEL_RELEASE is not set
|
||||||
# CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set
|
# CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set
|
||||||
CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y
|
CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y
|
||||||
@@ -3009,192 +2680,8 @@ CONFIG_STACK_CHECK_NONE=y
|
|||||||
# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set
|
# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set
|
||||||
CONFIG_ESP32_APPTRACE_DEST_NONE=y
|
CONFIG_ESP32_APPTRACE_DEST_NONE=y
|
||||||
CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y
|
CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y
|
||||||
CONFIG_BLUEDROID_ENABLED=y
|
# CONFIG_EXTERNAL_COEX_ENABLE is not set
|
||||||
# CONFIG_NIMBLE_ENABLED is not set
|
# CONFIG_ESP_WIFI_EXTERNAL_COEXIST_ENABLE is not set
|
||||||
CONFIG_BTC_TASK_STACK_SIZE=3072
|
|
||||||
CONFIG_BLUEDROID_PINNED_TO_CORE_0=y
|
|
||||||
# CONFIG_BLUEDROID_PINNED_TO_CORE_1 is not set
|
|
||||||
CONFIG_BLUEDROID_PINNED_TO_CORE=0
|
|
||||||
CONFIG_BTU_TASK_STACK_SIZE=4352
|
|
||||||
# CONFIG_BLUEDROID_MEM_DEBUG is not set
|
|
||||||
CONFIG_GATTS_ENABLE=y
|
|
||||||
# CONFIG_GATTS_SEND_SERVICE_CHANGE_MANUAL is not set
|
|
||||||
CONFIG_GATTS_SEND_SERVICE_CHANGE_AUTO=y
|
|
||||||
CONFIG_GATTS_SEND_SERVICE_CHANGE_MODE=0
|
|
||||||
CONFIG_GATTC_ENABLE=y
|
|
||||||
# CONFIG_GATTC_CACHE_NVS_FLASH is not set
|
|
||||||
CONFIG_BLE_SMP_ENABLE=y
|
|
||||||
# CONFIG_SMP_SLAVE_CON_PARAMS_UPD_ENABLE is not set
|
|
||||||
# CONFIG_HCI_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_HCI_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_HCI_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_HCI_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_HCI_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_HCI_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_HCI_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_HCI_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BTM_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BTM_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BTM_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BTM_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BTM_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BTM_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BTM_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BTM_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_L2CAP_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_L2CAP_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_L2CAP_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_L2CAP_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_L2CAP_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_L2CAP_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_L2CAP_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_L2CAP_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_RFCOMM_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_RFCOMM_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_RFCOMM_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_RFCOMM_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_RFCOMM_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_RFCOMM_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_RFCOMM_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_RFCOMM_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_SDP_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_SDP_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_SDP_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_SDP_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_SDP_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_SDP_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_SDP_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BTH_LOG_SDP_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_GAP_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_GAP_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_GAP_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_GAP_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_GAP_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_GAP_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_GAP_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_GAP_INITIAL_TRACE_LEVEL=2
|
|
||||||
CONFIG_BNEP_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_PAN_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_PAN_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_PAN_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_PAN_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_PAN_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_PAN_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_PAN_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_PAN_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_A2D_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_A2D_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_A2D_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_A2D_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_A2D_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_A2D_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_A2D_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_A2D_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_AVDT_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_AVDT_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_AVDT_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_AVDT_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_AVDT_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_AVDT_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_AVDT_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_AVDT_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_AVCT_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_AVCT_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_AVCT_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_AVCT_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_AVCT_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_AVCT_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_AVCT_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_AVCT_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_AVRC_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_AVRC_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_AVRC_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_AVRC_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_AVRC_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_AVRC_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_AVRC_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_AVRC_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_MCA_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_MCA_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_MCA_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_MCA_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_MCA_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_MCA_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_MCA_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_MCA_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_HID_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_HID_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_HID_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_HID_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_HID_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_HID_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_HID_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_HID_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_APPL_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_APPL_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_APPL_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_APPL_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_APPL_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_APPL_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_APPL_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_APPL_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_GATT_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_GATT_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_GATT_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_GATT_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_GATT_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_GATT_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_GATT_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_GATT_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_SMP_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_SMP_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_SMP_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_SMP_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_SMP_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_SMP_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_SMP_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_SMP_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BTIF_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BTIF_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BTIF_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BTIF_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BTIF_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BTIF_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BTIF_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BTIF_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BTC_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BTC_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BTC_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BTC_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BTC_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BTC_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BTC_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BTC_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_OSI_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_OSI_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_OSI_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_OSI_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_OSI_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_OSI_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_OSI_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_OSI_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BLUFI_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BLUFI_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BLUFI_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BLUFI_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BLUFI_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BLUFI_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BLUFI_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BLUFI_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BLE_HOST_QUEUE_CONGESTION_CHECK is not set
|
|
||||||
CONFIG_SMP_ENABLE=y
|
|
||||||
# CONFIG_BLE_ACTIVE_SCAN_REPORT_ADV_SCAN_RSP_INDIVIDUALLY is not set
|
|
||||||
CONFIG_BLE_ESTABLISH_LINK_CONNECTION_TIMEOUT=30
|
|
||||||
# CONFIG_BT_NIMBLE_COEX_PHY_CODED_TX_RX_TLIM_EN is not set
|
|
||||||
CONFIG_BT_NIMBLE_COEX_PHY_CODED_TX_RX_TLIM_DIS=y
|
|
||||||
CONFIG_SW_COEXIST_ENABLE=y
|
|
||||||
CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y
|
|
||||||
CONFIG_ESP_WIFI_SW_COEXIST_ENABLE=y
|
|
||||||
# CONFIG_MCPWM_ISR_IN_IRAM is not set
|
# CONFIG_MCPWM_ISR_IN_IRAM is not set
|
||||||
# CONFIG_EVENT_LOOP_PROFILING is not set
|
# CONFIG_EVENT_LOOP_PROFILING is not set
|
||||||
CONFIG_POST_EVENTS_FROM_ISR=y
|
CONFIG_POST_EVENTS_FROM_ISR=y
|
||||||
@@ -3267,19 +2754,19 @@ CONFIG_ESP32S3_BROWNOUT_DET_LVL=7
|
|||||||
CONFIG_IPC_TASK_STACK_SIZE=1280
|
CONFIG_IPC_TASK_STACK_SIZE=1280
|
||||||
CONFIG_TIMER_TASK_STACK_SIZE=3584
|
CONFIG_TIMER_TASK_STACK_SIZE=3584
|
||||||
CONFIG_ESP32_WIFI_ENABLED=y
|
CONFIG_ESP32_WIFI_ENABLED=y
|
||||||
CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10
|
CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=2
|
||||||
CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32
|
CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32
|
||||||
CONFIG_ESP32_WIFI_STATIC_TX_BUFFER=y
|
CONFIG_ESP32_WIFI_STATIC_TX_BUFFER=y
|
||||||
CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=0
|
CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=0
|
||||||
CONFIG_ESP32_WIFI_STATIC_TX_BUFFER_NUM=16
|
CONFIG_ESP32_WIFI_STATIC_TX_BUFFER_NUM=4
|
||||||
CONFIG_ESP32_WIFI_CACHE_TX_BUFFER_NUM=32
|
CONFIG_ESP32_WIFI_CACHE_TX_BUFFER_NUM=32
|
||||||
# CONFIG_ESP32_WIFI_CSI_ENABLED is not set
|
# CONFIG_ESP32_WIFI_CSI_ENABLED is not set
|
||||||
CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y
|
CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y
|
||||||
CONFIG_ESP32_WIFI_TX_BA_WIN=6
|
CONFIG_ESP32_WIFI_TX_BA_WIN=2
|
||||||
CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y
|
CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y
|
||||||
CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y
|
CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y
|
||||||
CONFIG_ESP32_WIFI_RX_BA_WIN=6
|
CONFIG_ESP32_WIFI_RX_BA_WIN=2
|
||||||
CONFIG_ESP32_WIFI_RX_BA_WIN=6
|
CONFIG_ESP32_WIFI_RX_BA_WIN=2
|
||||||
# CONFIG_ESP32_WIFI_AMSDU_TX_ENABLED is not set
|
# CONFIG_ESP32_WIFI_AMSDU_TX_ENABLED is not set
|
||||||
CONFIG_ESP32_WIFI_NVS_ENABLED=y
|
CONFIG_ESP32_WIFI_NVS_ENABLED=y
|
||||||
CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y
|
CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y
|
||||||
|
|||||||
+34
-547
@@ -766,9 +766,9 @@ CONFIG_CN_SPEECH_COMMAND_ID199=""
|
|||||||
#
|
#
|
||||||
# Compiler options
|
# Compiler options
|
||||||
#
|
#
|
||||||
CONFIG_COMPILER_OPTIMIZATION_DEBUG=y
|
# CONFIG_COMPILER_OPTIMIZATION_DEBUG is not set
|
||||||
# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set
|
# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set
|
||||||
# CONFIG_COMPILER_OPTIMIZATION_PERF is not set
|
CONFIG_COMPILER_OPTIMIZATION_PERF=y
|
||||||
# CONFIG_COMPILER_OPTIMIZATION_NONE is not set
|
# CONFIG_COMPILER_OPTIMIZATION_NONE is not set
|
||||||
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y
|
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y
|
||||||
# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set
|
# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set
|
||||||
@@ -814,334 +814,10 @@ CONFIG_APPTRACE_LOCK_ENABLE=y
|
|||||||
#
|
#
|
||||||
# Bluetooth
|
# Bluetooth
|
||||||
#
|
#
|
||||||
CONFIG_BT_ENABLED=y
|
# CONFIG_BT_ENABLED is not set
|
||||||
CONFIG_BT_BLUEDROID_ENABLED=y
|
|
||||||
# CONFIG_BT_NIMBLE_ENABLED is not set
|
|
||||||
# CONFIG_BT_CONTROLLER_ONLY is not set
|
|
||||||
CONFIG_BT_CONTROLLER_ENABLED=y
|
|
||||||
# CONFIG_BT_CONTROLLER_DISABLED is not set
|
|
||||||
|
|
||||||
#
|
|
||||||
# Bluedroid Options
|
|
||||||
#
|
|
||||||
CONFIG_BT_BTC_TASK_STACK_SIZE=3072
|
|
||||||
CONFIG_BT_BLUEDROID_PINNED_TO_CORE_0=y
|
|
||||||
# CONFIG_BT_BLUEDROID_PINNED_TO_CORE_1 is not set
|
|
||||||
CONFIG_BT_BLUEDROID_PINNED_TO_CORE=0
|
|
||||||
CONFIG_BT_BTU_TASK_STACK_SIZE=4352
|
|
||||||
# CONFIG_BT_BLUEDROID_MEM_DEBUG is not set
|
|
||||||
CONFIG_BT_BLUEDROID_ESP_COEX_VSC=y
|
|
||||||
CONFIG_BT_BLE_ENABLED=y
|
|
||||||
CONFIG_BT_GATTS_ENABLE=y
|
|
||||||
# CONFIG_BT_GATTS_PPCP_CHAR_GAP is not set
|
|
||||||
# CONFIG_BT_BLE_BLUFI_ENABLE is not set
|
|
||||||
CONFIG_BT_GATT_MAX_SR_PROFILES=8
|
|
||||||
CONFIG_BT_GATT_MAX_SR_ATTRIBUTES=100
|
|
||||||
# CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MANUAL is not set
|
|
||||||
CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_AUTO=y
|
|
||||||
CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MODE=0
|
|
||||||
# CONFIG_BT_GATTS_ROBUST_CACHING_ENABLED is not set
|
|
||||||
# CONFIG_BT_GATTS_DEVICE_NAME_WRITABLE is not set
|
|
||||||
# CONFIG_BT_GATTS_APPEARANCE_WRITABLE is not set
|
|
||||||
CONFIG_BT_GATTC_ENABLE=y
|
|
||||||
CONFIG_BT_GATTC_MAX_CACHE_CHAR=40
|
|
||||||
CONFIG_BT_GATTC_NOTIF_REG_MAX=5
|
|
||||||
# CONFIG_BT_GATTC_CACHE_NVS_FLASH is not set
|
|
||||||
CONFIG_BT_GATTC_CONNECT_RETRY_COUNT=3
|
|
||||||
CONFIG_BT_BLE_SMP_ENABLE=y
|
|
||||||
# CONFIG_BT_SMP_SLAVE_CON_PARAMS_UPD_ENABLE is not set
|
|
||||||
# CONFIG_BT_BLE_SMP_ID_RESET_ENABLE is not set
|
|
||||||
# CONFIG_BT_STACK_NO_LOG is not set
|
|
||||||
|
|
||||||
#
|
|
||||||
# BT DEBUG LOG LEVEL
|
|
||||||
#
|
|
||||||
# CONFIG_BT_LOG_HCI_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_HCI_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_HCI_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_HCI_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_HCI_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_HCI_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_HCI_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_HCI_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_BTM_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_BTM_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_BTM_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_BTM_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_BTM_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_BTM_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_BTM_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_BTM_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_L2CAP_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_L2CAP_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_RFCOMM_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_SDP_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_SDP_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_SDP_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_SDP_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_SDP_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_SDP_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_SDP_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_SDP_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_GAP_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_GAP_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_GAP_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_GAP_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_GAP_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_GAP_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_GAP_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_GAP_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_BNEP_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_BNEP_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_BNEP_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_PAN_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_PAN_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_PAN_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_PAN_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_PAN_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_PAN_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_PAN_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_PAN_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_A2D_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_A2D_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_A2D_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_A2D_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_A2D_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_A2D_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_A2D_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_A2D_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_AVDT_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_AVDT_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_AVDT_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_AVCT_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_AVCT_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_AVCT_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_AVRC_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_AVRC_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_AVRC_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_MCA_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_MCA_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_MCA_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_MCA_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_MCA_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_MCA_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_MCA_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_MCA_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_HID_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_HID_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_HID_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_HID_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_HID_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_HID_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_HID_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_HID_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_APPL_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_APPL_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_APPL_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_APPL_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_APPL_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_APPL_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_APPL_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_APPL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_GATT_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_GATT_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_GATT_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_GATT_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_GATT_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_GATT_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_GATT_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_GATT_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_SMP_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_SMP_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_SMP_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_SMP_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_SMP_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_SMP_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_SMP_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_SMP_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_BTIF_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_BTIF_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_BTIF_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_BTC_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_BTC_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_BTC_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_BTC_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_BTC_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_BTC_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_BTC_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_BTC_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_OSI_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_OSI_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_OSI_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_OSI_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_OSI_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_OSI_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_OSI_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_OSI_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BT_LOG_BLUFI_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BT_LOG_BLUFI_TRACE_LEVEL=2
|
|
||||||
# end of BT DEBUG LOG LEVEL
|
|
||||||
|
|
||||||
CONFIG_BT_ACL_CONNECTIONS=4
|
|
||||||
CONFIG_BT_MULTI_CONNECTION_ENBALE=y
|
|
||||||
# CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST is not set
|
|
||||||
# CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY is not set
|
|
||||||
# CONFIG_BT_BLE_HOST_QUEUE_CONG_CHECK is not set
|
|
||||||
CONFIG_BT_SMP_ENABLE=y
|
|
||||||
CONFIG_BT_SMP_MAX_BONDS=15
|
|
||||||
# CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN is not set
|
|
||||||
CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT=30
|
|
||||||
CONFIG_BT_MAX_DEVICE_NAME_LEN=32
|
|
||||||
CONFIG_BT_BLE_RPA_TIMEOUT=900
|
|
||||||
CONFIG_BT_BLE_50_FEATURES_SUPPORTED=y
|
|
||||||
CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y
|
|
||||||
# CONFIG_BT_BLE_HIGH_DUTY_ADV_INTERVAL is not set
|
|
||||||
# CONFIG_BT_ABORT_WHEN_ALLOCATION_FAILS is not set
|
|
||||||
# end of Bluedroid Options
|
|
||||||
|
|
||||||
#
|
|
||||||
# Controller Options
|
|
||||||
#
|
|
||||||
CONFIG_BT_CTRL_MODE_EFF=1
|
|
||||||
CONFIG_BT_CTRL_BLE_MAX_ACT=6
|
|
||||||
CONFIG_BT_CTRL_BLE_MAX_ACT_EFF=6
|
|
||||||
CONFIG_BT_CTRL_BLE_STATIC_ACL_TX_BUF_NB=0
|
|
||||||
CONFIG_BT_CTRL_PINNED_TO_CORE_0=y
|
|
||||||
# CONFIG_BT_CTRL_PINNED_TO_CORE_1 is not set
|
|
||||||
CONFIG_BT_CTRL_PINNED_TO_CORE=0
|
|
||||||
CONFIG_BT_CTRL_HCI_MODE_VHCI=y
|
|
||||||
# CONFIG_BT_CTRL_HCI_MODE_UART_H4 is not set
|
|
||||||
CONFIG_BT_CTRL_HCI_TL=1
|
|
||||||
CONFIG_BT_CTRL_ADV_DUP_FILT_MAX=30
|
|
||||||
CONFIG_BT_BLE_CCA_MODE_NONE=y
|
|
||||||
# CONFIG_BT_BLE_CCA_MODE_HW is not set
|
|
||||||
# CONFIG_BT_BLE_CCA_MODE_SW is not set
|
|
||||||
CONFIG_BT_BLE_CCA_MODE=0
|
|
||||||
CONFIG_BT_CTRL_HW_CCA_VAL=20
|
|
||||||
CONFIG_BT_CTRL_HW_CCA_EFF=0
|
|
||||||
CONFIG_BT_CTRL_CE_LENGTH_TYPE_ORIG=y
|
|
||||||
# CONFIG_BT_CTRL_CE_LENGTH_TYPE_CE is not set
|
|
||||||
# CONFIG_BT_CTRL_CE_LENGTH_TYPE_SD is not set
|
|
||||||
CONFIG_BT_CTRL_CE_LENGTH_TYPE_EFF=0
|
|
||||||
CONFIG_BT_CTRL_TX_ANTENNA_INDEX_0=y
|
|
||||||
# CONFIG_BT_CTRL_TX_ANTENNA_INDEX_1 is not set
|
|
||||||
CONFIG_BT_CTRL_TX_ANTENNA_INDEX_EFF=0
|
|
||||||
CONFIG_BT_CTRL_RX_ANTENNA_INDEX_0=y
|
|
||||||
# CONFIG_BT_CTRL_RX_ANTENNA_INDEX_1 is not set
|
|
||||||
CONFIG_BT_CTRL_RX_ANTENNA_INDEX_EFF=0
|
|
||||||
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N24 is not set
|
|
||||||
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N21 is not set
|
|
||||||
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N18 is not set
|
|
||||||
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N15 is not set
|
|
||||||
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N12 is not set
|
|
||||||
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N9 is not set
|
|
||||||
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N6 is not set
|
|
||||||
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N3 is not set
|
|
||||||
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_N0 is not set
|
|
||||||
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P3 is not set
|
|
||||||
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P6 is not set
|
|
||||||
CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P9=y
|
|
||||||
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P12 is not set
|
|
||||||
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P15 is not set
|
|
||||||
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P18 is not set
|
|
||||||
# CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_P20 is not set
|
|
||||||
CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=11
|
|
||||||
CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y
|
|
||||||
CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM=100
|
|
||||||
CONFIG_BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD=20
|
|
||||||
CONFIG_BT_CTRL_BLE_SCAN_DUPL=y
|
|
||||||
CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DEVICE=y
|
|
||||||
# CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA is not set
|
|
||||||
# CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE is not set
|
|
||||||
CONFIG_BT_CTRL_SCAN_DUPL_TYPE=0
|
|
||||||
CONFIG_BT_CTRL_SCAN_DUPL_CACHE_SIZE=100
|
|
||||||
CONFIG_BT_CTRL_DUPL_SCAN_CACHE_REFRESH_PERIOD=0
|
|
||||||
# CONFIG_BT_CTRL_BLE_MESH_SCAN_DUPL_EN is not set
|
|
||||||
# CONFIG_BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_EN is not set
|
|
||||||
CONFIG_BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_DIS=y
|
|
||||||
CONFIG_BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_EFF=0
|
|
||||||
|
|
||||||
#
|
|
||||||
# MODEM SLEEP Options
|
|
||||||
#
|
|
||||||
# CONFIG_BT_CTRL_MODEM_SLEEP is not set
|
|
||||||
# end of MODEM SLEEP Options
|
|
||||||
|
|
||||||
CONFIG_BT_CTRL_SLEEP_MODE_EFF=0
|
|
||||||
CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0
|
|
||||||
CONFIG_BT_CTRL_HCI_TL_EFF=1
|
|
||||||
# CONFIG_BT_CTRL_AGC_RECORRECT_EN is not set
|
|
||||||
# CONFIG_BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX is not set
|
|
||||||
# CONFIG_BT_BLE_ADV_DATA_LENGTH_ZERO_AUX is not set
|
|
||||||
CONFIG_BT_CTRL_CHAN_ASS_EN=y
|
|
||||||
CONFIG_BT_CTRL_LE_PING_EN=y
|
|
||||||
|
|
||||||
#
|
|
||||||
# BLE disconnect when instant passed
|
|
||||||
#
|
|
||||||
# CONFIG_BT_CTRL_BLE_LLCP_CONN_UPDATE is not set
|
|
||||||
# CONFIG_BT_CTRL_BLE_LLCP_CHAN_MAP_UPDATE is not set
|
|
||||||
# CONFIG_BT_CTRL_BLE_LLCP_PHY_UPDATE is not set
|
|
||||||
# end of BLE disconnect when instant passed
|
|
||||||
|
|
||||||
# CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY is not set
|
|
||||||
# end of Controller Options
|
|
||||||
|
|
||||||
#
|
|
||||||
# Common Options
|
|
||||||
#
|
|
||||||
CONFIG_BT_ALARM_MAX_NUM=50
|
CONFIG_BT_ALARM_MAX_NUM=50
|
||||||
# end of Common Options
|
|
||||||
|
|
||||||
# CONFIG_BT_HCI_LOG_DEBUG_EN is not set
|
|
||||||
# end of Bluetooth
|
# end of Bluetooth
|
||||||
|
|
||||||
# CONFIG_BLE_MESH is not set
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Console Library
|
# Console Library
|
||||||
#
|
#
|
||||||
@@ -1248,8 +924,7 @@ CONFIG_ESP_TLS_USE_DS_PERIPHERAL=y
|
|||||||
# Wireless Coexistence
|
# Wireless Coexistence
|
||||||
#
|
#
|
||||||
CONFIG_ESP_COEX_ENABLED=y
|
CONFIG_ESP_COEX_ENABLED=y
|
||||||
CONFIG_ESP_COEX_SW_COEXIST_ENABLE=y
|
# CONFIG_ESP_COEX_EXTERNAL_COEXIST_ENABLE is not set
|
||||||
# CONFIG_ESP_COEX_POWER_MANAGEMENT is not set
|
|
||||||
# CONFIG_ESP_COEX_GPIO_DEBUG is not set
|
# CONFIG_ESP_COEX_GPIO_DEBUG is not set
|
||||||
# end of Wireless Coexistence
|
# end of Wireless Coexistence
|
||||||
|
|
||||||
@@ -1328,7 +1003,7 @@ CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y
|
|||||||
#
|
#
|
||||||
# ESP-Driver:SPI Configurations
|
# ESP-Driver:SPI Configurations
|
||||||
#
|
#
|
||||||
# CONFIG_SPI_MASTER_IN_IRAM is not set
|
CONFIG_SPI_MASTER_IN_IRAM=y
|
||||||
CONFIG_SPI_MASTER_ISR_IN_IRAM=y
|
CONFIG_SPI_MASTER_ISR_IN_IRAM=y
|
||||||
# CONFIG_SPI_SLAVE_IN_IRAM is not set
|
# CONFIG_SPI_SLAVE_IN_IRAM is not set
|
||||||
CONFIG_SPI_SLAVE_ISR_IN_IRAM=y
|
CONFIG_SPI_SLAVE_ISR_IN_IRAM=y
|
||||||
@@ -1510,6 +1185,7 @@ CONFIG_XTAL_FREQ=40
|
|||||||
# end of Main XTAL Config
|
# end of Main XTAL Config
|
||||||
|
|
||||||
CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y
|
CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y
|
||||||
|
CONFIG_ESP_SPI_BUS_LOCK_FUNCS_IN_IRAM=y
|
||||||
# end of Hardware Settings
|
# end of Hardware Settings
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -1602,9 +1278,9 @@ CONFIG_SPIRAM_BOOT_INIT=y
|
|||||||
# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set
|
# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set
|
||||||
CONFIG_SPIRAM_USE_MALLOC=y
|
CONFIG_SPIRAM_USE_MALLOC=y
|
||||||
CONFIG_SPIRAM_MEMTEST=y
|
CONFIG_SPIRAM_MEMTEST=y
|
||||||
CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384
|
CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=4096
|
||||||
# CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP is not set
|
CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y
|
||||||
CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768
|
CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=65536
|
||||||
# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set
|
# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set
|
||||||
# CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY is not set
|
# CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY is not set
|
||||||
# end of SPI RAM config
|
# end of SPI RAM config
|
||||||
@@ -1637,13 +1313,12 @@ CONFIG_ESP32S3_ICACHE_ASSOCIATED_WAYS=8
|
|||||||
CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_32B=y
|
CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_32B=y
|
||||||
CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_SIZE=32
|
CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_SIZE=32
|
||||||
# CONFIG_ESP32S3_DATA_CACHE_16KB is not set
|
# CONFIG_ESP32S3_DATA_CACHE_16KB is not set
|
||||||
CONFIG_ESP32S3_DATA_CACHE_32KB=y
|
# CONFIG_ESP32S3_DATA_CACHE_32KB is not set
|
||||||
# CONFIG_ESP32S3_DATA_CACHE_64KB is not set
|
CONFIG_ESP32S3_DATA_CACHE_64KB=y
|
||||||
CONFIG_ESP32S3_DATA_CACHE_SIZE=0x8000
|
CONFIG_ESP32S3_DATA_CACHE_SIZE=0x10000
|
||||||
# CONFIG_ESP32S3_DATA_CACHE_4WAYS is not set
|
# CONFIG_ESP32S3_DATA_CACHE_4WAYS is not set
|
||||||
CONFIG_ESP32S3_DATA_CACHE_8WAYS=y
|
CONFIG_ESP32S3_DATA_CACHE_8WAYS=y
|
||||||
CONFIG_ESP32S3_DCACHE_ASSOCIATED_WAYS=8
|
CONFIG_ESP32S3_DCACHE_ASSOCIATED_WAYS=8
|
||||||
# CONFIG_ESP32S3_DATA_CACHE_LINE_16B is not set
|
|
||||||
CONFIG_ESP32S3_DATA_CACHE_LINE_32B=y
|
CONFIG_ESP32S3_DATA_CACHE_LINE_32B=y
|
||||||
# CONFIG_ESP32S3_DATA_CACHE_LINE_64B is not set
|
# CONFIG_ESP32S3_DATA_CACHE_LINE_64B is not set
|
||||||
CONFIG_ESP32S3_DATA_CACHE_LINE_SIZE=32
|
CONFIG_ESP32S3_DATA_CACHE_LINE_SIZE=32
|
||||||
@@ -1758,11 +1433,11 @@ CONFIG_ESP_TIMER_IMPL_SYSTIMER=y
|
|||||||
# Wi-Fi
|
# Wi-Fi
|
||||||
#
|
#
|
||||||
CONFIG_ESP_WIFI_ENABLED=y
|
CONFIG_ESP_WIFI_ENABLED=y
|
||||||
CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10
|
CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=2
|
||||||
CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32
|
CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32
|
||||||
CONFIG_ESP_WIFI_STATIC_TX_BUFFER=y
|
CONFIG_ESP_WIFI_STATIC_TX_BUFFER=y
|
||||||
CONFIG_ESP_WIFI_TX_BUFFER_TYPE=0
|
CONFIG_ESP_WIFI_TX_BUFFER_TYPE=0
|
||||||
CONFIG_ESP_WIFI_STATIC_TX_BUFFER_NUM=16
|
CONFIG_ESP_WIFI_STATIC_TX_BUFFER_NUM=4
|
||||||
CONFIG_ESP_WIFI_CACHE_TX_BUFFER_NUM=32
|
CONFIG_ESP_WIFI_CACHE_TX_BUFFER_NUM=32
|
||||||
CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y
|
CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y
|
||||||
# CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set
|
# CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set
|
||||||
@@ -1770,9 +1445,9 @@ CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0
|
|||||||
CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5
|
CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5
|
||||||
# CONFIG_ESP_WIFI_CSI_ENABLED is not set
|
# CONFIG_ESP_WIFI_CSI_ENABLED is not set
|
||||||
CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y
|
CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y
|
||||||
CONFIG_ESP_WIFI_TX_BA_WIN=6
|
CONFIG_ESP_WIFI_TX_BA_WIN=2
|
||||||
CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y
|
CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y
|
||||||
CONFIG_ESP_WIFI_RX_BA_WIN=6
|
CONFIG_ESP_WIFI_RX_BA_WIN=2
|
||||||
# CONFIG_ESP_WIFI_AMSDU_TX_ENABLED is not set
|
# CONFIG_ESP_WIFI_AMSDU_TX_ENABLED is not set
|
||||||
CONFIG_ESP_WIFI_NVS_ENABLED=y
|
CONFIG_ESP_WIFI_NVS_ENABLED=y
|
||||||
CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y
|
CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y
|
||||||
@@ -1916,7 +1591,6 @@ CONFIG_FREERTOS_RUN_TIME_COUNTER_TYPE_U32=y
|
|||||||
#
|
#
|
||||||
# Port
|
# Port
|
||||||
#
|
#
|
||||||
CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y
|
|
||||||
# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set
|
# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set
|
||||||
CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y
|
CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y
|
||||||
# CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set
|
# CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set
|
||||||
@@ -2077,6 +1751,7 @@ CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4
|
|||||||
CONFIG_LWIP_TCP_OVERSIZE_MSS=y
|
CONFIG_LWIP_TCP_OVERSIZE_MSS=y
|
||||||
# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set
|
# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set
|
||||||
# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set
|
# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set
|
||||||
|
# CONFIG_LWIP_WND_SCALE is not set
|
||||||
CONFIG_LWIP_TCP_RTO_TIME=1500
|
CONFIG_LWIP_TCP_RTO_TIME=1500
|
||||||
# end of TCP
|
# end of TCP
|
||||||
|
|
||||||
@@ -2608,10 +2283,6 @@ CONFIG_WL_SECTOR_SIZE=4096
|
|||||||
#
|
#
|
||||||
CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16
|
CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16
|
||||||
CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30
|
CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30
|
||||||
# CONFIG_WIFI_PROV_BLE_BONDING is not set
|
|
||||||
# CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set
|
|
||||||
# CONFIG_WIFI_PROV_BLE_NOTIFY is not set
|
|
||||||
# CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV is not set
|
|
||||||
CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y
|
CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y
|
||||||
# CONFIG_WIFI_PROV_STA_FAST_SCAN is not set
|
# CONFIG_WIFI_PROV_STA_FAST_SCAN is not set
|
||||||
# end of Wi-Fi Provisioning Manager
|
# end of Wi-Fi Provisioning Manager
|
||||||
@@ -2680,8 +2351,8 @@ CONFIG_LV_MEM_BUF_MAX_NUM=16
|
|||||||
#
|
#
|
||||||
# HAL Settings
|
# HAL Settings
|
||||||
#
|
#
|
||||||
CONFIG_LV_DISP_DEF_REFR_PERIOD=30
|
CONFIG_LV_DISP_DEF_REFR_PERIOD=10
|
||||||
CONFIG_LV_INDEV_DEF_READ_PERIOD=30
|
CONFIG_LV_INDEV_DEF_READ_PERIOD=10
|
||||||
# CONFIG_LV_TICK_CUSTOM is not set
|
# CONFIG_LV_TICK_CUSTOM is not set
|
||||||
CONFIG_LV_DPI_DEF=130
|
CONFIG_LV_DPI_DEF=130
|
||||||
# end of HAL Settings
|
# end of HAL Settings
|
||||||
@@ -2694,10 +2365,10 @@ CONFIG_LV_DPI_DEF=130
|
|||||||
# Drawing
|
# Drawing
|
||||||
#
|
#
|
||||||
CONFIG_LV_DRAW_COMPLEX=y
|
CONFIG_LV_DRAW_COMPLEX=y
|
||||||
CONFIG_LV_SHADOW_CACHE_SIZE=0
|
CONFIG_LV_SHADOW_CACHE_SIZE=4
|
||||||
CONFIG_LV_CIRCLE_CACHE_SIZE=4
|
CONFIG_LV_CIRCLE_CACHE_SIZE=4
|
||||||
CONFIG_LV_LAYER_SIMPLE_BUF_SIZE=24576
|
CONFIG_LV_LAYER_SIMPLE_BUF_SIZE=10240
|
||||||
CONFIG_LV_IMG_CACHE_DEF_SIZE=0
|
CONFIG_LV_IMG_CACHE_DEF_SIZE=128
|
||||||
CONFIG_LV_GRADIENT_MAX_STOPS=2
|
CONFIG_LV_GRADIENT_MAX_STOPS=2
|
||||||
CONFIG_LV_GRAD_CACHE_DEF_SIZE=0
|
CONFIG_LV_GRAD_CACHE_DEF_SIZE=0
|
||||||
# CONFIG_LV_DITHER_GRADIENT is not set
|
# CONFIG_LV_DITHER_GRADIENT is not set
|
||||||
@@ -2727,9 +2398,9 @@ CONFIG_LV_DISP_ROT_MAX_BUF=10240
|
|||||||
#
|
#
|
||||||
CONFIG_LV_USE_ASSERT_NULL=y
|
CONFIG_LV_USE_ASSERT_NULL=y
|
||||||
CONFIG_LV_USE_ASSERT_MALLOC=y
|
CONFIG_LV_USE_ASSERT_MALLOC=y
|
||||||
# CONFIG_LV_USE_ASSERT_STYLE is not set
|
CONFIG_LV_USE_ASSERT_STYLE=y
|
||||||
# CONFIG_LV_USE_ASSERT_MEM_INTEGRITY is not set
|
# CONFIG_LV_USE_ASSERT_MEM_INTEGRITY is not set
|
||||||
# CONFIG_LV_USE_ASSERT_OBJ is not set
|
CONFIG_LV_USE_ASSERT_OBJ=y
|
||||||
CONFIG_LV_ASSERT_HANDLER_INCLUDE="assert.h"
|
CONFIG_LV_ASSERT_HANDLER_INCLUDE="assert.h"
|
||||||
# end of Asserts
|
# end of Asserts
|
||||||
|
|
||||||
@@ -2990,9 +2661,9 @@ CONFIG_LOG_BOOTLOADER_LEVEL=3
|
|||||||
CONFIG_FLASHMODE_DIO=y
|
CONFIG_FLASHMODE_DIO=y
|
||||||
# CONFIG_FLASHMODE_DOUT is not set
|
# CONFIG_FLASHMODE_DOUT is not set
|
||||||
CONFIG_MONITOR_BAUD=115200
|
CONFIG_MONITOR_BAUD=115200
|
||||||
CONFIG_OPTIMIZATION_LEVEL_DEBUG=y
|
# CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set
|
||||||
CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y
|
# CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG is not set
|
||||||
CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y
|
# CONFIG_COMPILER_OPTIMIZATION_DEFAULT is not set
|
||||||
# CONFIG_OPTIMIZATION_LEVEL_RELEASE is not set
|
# CONFIG_OPTIMIZATION_LEVEL_RELEASE is not set
|
||||||
# CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set
|
# CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set
|
||||||
CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y
|
CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y
|
||||||
@@ -3009,192 +2680,8 @@ CONFIG_STACK_CHECK_NONE=y
|
|||||||
# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set
|
# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set
|
||||||
CONFIG_ESP32_APPTRACE_DEST_NONE=y
|
CONFIG_ESP32_APPTRACE_DEST_NONE=y
|
||||||
CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y
|
CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y
|
||||||
CONFIG_BLUEDROID_ENABLED=y
|
# CONFIG_EXTERNAL_COEX_ENABLE is not set
|
||||||
# CONFIG_NIMBLE_ENABLED is not set
|
# CONFIG_ESP_WIFI_EXTERNAL_COEXIST_ENABLE is not set
|
||||||
CONFIG_BTC_TASK_STACK_SIZE=3072
|
|
||||||
CONFIG_BLUEDROID_PINNED_TO_CORE_0=y
|
|
||||||
# CONFIG_BLUEDROID_PINNED_TO_CORE_1 is not set
|
|
||||||
CONFIG_BLUEDROID_PINNED_TO_CORE=0
|
|
||||||
CONFIG_BTU_TASK_STACK_SIZE=4352
|
|
||||||
# CONFIG_BLUEDROID_MEM_DEBUG is not set
|
|
||||||
CONFIG_GATTS_ENABLE=y
|
|
||||||
# CONFIG_GATTS_SEND_SERVICE_CHANGE_MANUAL is not set
|
|
||||||
CONFIG_GATTS_SEND_SERVICE_CHANGE_AUTO=y
|
|
||||||
CONFIG_GATTS_SEND_SERVICE_CHANGE_MODE=0
|
|
||||||
CONFIG_GATTC_ENABLE=y
|
|
||||||
# CONFIG_GATTC_CACHE_NVS_FLASH is not set
|
|
||||||
CONFIG_BLE_SMP_ENABLE=y
|
|
||||||
# CONFIG_SMP_SLAVE_CON_PARAMS_UPD_ENABLE is not set
|
|
||||||
# CONFIG_HCI_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_HCI_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_HCI_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_HCI_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_HCI_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_HCI_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_HCI_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_HCI_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BTM_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BTM_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BTM_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BTM_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BTM_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BTM_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BTM_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BTM_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_L2CAP_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_L2CAP_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_L2CAP_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_L2CAP_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_L2CAP_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_L2CAP_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_L2CAP_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_L2CAP_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_RFCOMM_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_RFCOMM_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_RFCOMM_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_RFCOMM_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_RFCOMM_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_RFCOMM_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_RFCOMM_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_RFCOMM_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_SDP_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_SDP_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_SDP_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_SDP_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_SDP_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_SDP_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_SDP_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BTH_LOG_SDP_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_GAP_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_GAP_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_GAP_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_GAP_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_GAP_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_GAP_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_GAP_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_GAP_INITIAL_TRACE_LEVEL=2
|
|
||||||
CONFIG_BNEP_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_PAN_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_PAN_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_PAN_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_PAN_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_PAN_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_PAN_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_PAN_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_PAN_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_A2D_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_A2D_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_A2D_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_A2D_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_A2D_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_A2D_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_A2D_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_A2D_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_AVDT_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_AVDT_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_AVDT_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_AVDT_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_AVDT_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_AVDT_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_AVDT_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_AVDT_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_AVCT_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_AVCT_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_AVCT_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_AVCT_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_AVCT_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_AVCT_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_AVCT_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_AVCT_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_AVRC_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_AVRC_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_AVRC_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_AVRC_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_AVRC_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_AVRC_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_AVRC_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_AVRC_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_MCA_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_MCA_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_MCA_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_MCA_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_MCA_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_MCA_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_MCA_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_MCA_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_HID_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_HID_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_HID_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_HID_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_HID_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_HID_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_HID_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_HID_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_APPL_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_APPL_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_APPL_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_APPL_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_APPL_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_APPL_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_APPL_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_APPL_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_GATT_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_GATT_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_GATT_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_GATT_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_GATT_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_GATT_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_GATT_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_GATT_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_SMP_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_SMP_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_SMP_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_SMP_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_SMP_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_SMP_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_SMP_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_SMP_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BTIF_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BTIF_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BTIF_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BTIF_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BTIF_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BTIF_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BTIF_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BTIF_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BTC_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BTC_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BTC_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BTC_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BTC_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BTC_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BTC_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BTC_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_OSI_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_OSI_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_OSI_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_OSI_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_OSI_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_OSI_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_OSI_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_OSI_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BLUFI_TRACE_LEVEL_NONE is not set
|
|
||||||
# CONFIG_BLUFI_TRACE_LEVEL_ERROR is not set
|
|
||||||
CONFIG_BLUFI_TRACE_LEVEL_WARNING=y
|
|
||||||
# CONFIG_BLUFI_TRACE_LEVEL_API is not set
|
|
||||||
# CONFIG_BLUFI_TRACE_LEVEL_EVENT is not set
|
|
||||||
# CONFIG_BLUFI_TRACE_LEVEL_DEBUG is not set
|
|
||||||
# CONFIG_BLUFI_TRACE_LEVEL_VERBOSE is not set
|
|
||||||
CONFIG_BLUFI_INITIAL_TRACE_LEVEL=2
|
|
||||||
# CONFIG_BLE_HOST_QUEUE_CONGESTION_CHECK is not set
|
|
||||||
CONFIG_SMP_ENABLE=y
|
|
||||||
# CONFIG_BLE_ACTIVE_SCAN_REPORT_ADV_SCAN_RSP_INDIVIDUALLY is not set
|
|
||||||
CONFIG_BLE_ESTABLISH_LINK_CONNECTION_TIMEOUT=30
|
|
||||||
# CONFIG_BT_NIMBLE_COEX_PHY_CODED_TX_RX_TLIM_EN is not set
|
|
||||||
CONFIG_BT_NIMBLE_COEX_PHY_CODED_TX_RX_TLIM_DIS=y
|
|
||||||
CONFIG_SW_COEXIST_ENABLE=y
|
|
||||||
CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y
|
|
||||||
CONFIG_ESP_WIFI_SW_COEXIST_ENABLE=y
|
|
||||||
# CONFIG_MCPWM_ISR_IN_IRAM is not set
|
# CONFIG_MCPWM_ISR_IN_IRAM is not set
|
||||||
# CONFIG_EVENT_LOOP_PROFILING is not set
|
# CONFIG_EVENT_LOOP_PROFILING is not set
|
||||||
CONFIG_POST_EVENTS_FROM_ISR=y
|
CONFIG_POST_EVENTS_FROM_ISR=y
|
||||||
@@ -3267,19 +2754,19 @@ CONFIG_ESP32S3_BROWNOUT_DET_LVL=7
|
|||||||
CONFIG_IPC_TASK_STACK_SIZE=1280
|
CONFIG_IPC_TASK_STACK_SIZE=1280
|
||||||
CONFIG_TIMER_TASK_STACK_SIZE=3584
|
CONFIG_TIMER_TASK_STACK_SIZE=3584
|
||||||
CONFIG_ESP32_WIFI_ENABLED=y
|
CONFIG_ESP32_WIFI_ENABLED=y
|
||||||
CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10
|
CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=2
|
||||||
CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32
|
CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32
|
||||||
CONFIG_ESP32_WIFI_STATIC_TX_BUFFER=y
|
CONFIG_ESP32_WIFI_STATIC_TX_BUFFER=y
|
||||||
CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=0
|
CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=0
|
||||||
CONFIG_ESP32_WIFI_STATIC_TX_BUFFER_NUM=16
|
CONFIG_ESP32_WIFI_STATIC_TX_BUFFER_NUM=4
|
||||||
CONFIG_ESP32_WIFI_CACHE_TX_BUFFER_NUM=32
|
CONFIG_ESP32_WIFI_CACHE_TX_BUFFER_NUM=32
|
||||||
# CONFIG_ESP32_WIFI_CSI_ENABLED is not set
|
# CONFIG_ESP32_WIFI_CSI_ENABLED is not set
|
||||||
CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y
|
CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y
|
||||||
CONFIG_ESP32_WIFI_TX_BA_WIN=6
|
CONFIG_ESP32_WIFI_TX_BA_WIN=2
|
||||||
CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y
|
CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y
|
||||||
CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y
|
CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y
|
||||||
CONFIG_ESP32_WIFI_RX_BA_WIN=6
|
CONFIG_ESP32_WIFI_RX_BA_WIN=2
|
||||||
CONFIG_ESP32_WIFI_RX_BA_WIN=6
|
CONFIG_ESP32_WIFI_RX_BA_WIN=2
|
||||||
# CONFIG_ESP32_WIFI_AMSDU_TX_ENABLED is not set
|
# CONFIG_ESP32_WIFI_AMSDU_TX_ENABLED is not set
|
||||||
CONFIG_ESP32_WIFI_NVS_ENABLED=y
|
CONFIG_ESP32_WIFI_NVS_ENABLED=y
|
||||||
CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y
|
CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ void sd_card_module_test(void)
|
|||||||
printf("3. 测试文件写入...\n");
|
printf("3. 测试文件写入...\n");
|
||||||
char test_file_path[] = MOUNT_POINT"/test.txt";
|
char test_file_path[] = MOUNT_POINT"/test.txt";
|
||||||
char test_data[] = "这是一段测试数据,用于验证SD卡写入功能。";
|
char test_data[] = "这是一段测试数据,用于验证SD卡写入功能。";
|
||||||
esp_err_t write_result = s_example_write_file(test_file_path, test_data);
|
esp_err_t write_result = s_example_write_file(test_file_path, test_data, "w");
|
||||||
if(write_result == ESP_OK) {
|
if(write_result == ESP_OK) {
|
||||||
printf(" 文件写入成功: %s\n", test_file_path);
|
printf(" 文件写入成功: %s\n", test_file_path);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -268,3 +268,32 @@
|
|||||||
|
|
||||||
- [x] 3. 修复和优化了一些地方
|
- [x] 3. 修复和优化了一些地方
|
||||||
|
|
||||||
|
#### Day19 2025.9.29
|
||||||
|
##### 主要目标:完成具体业务开发&各种优化
|
||||||
|
实际完成任务:
|
||||||
|
- [x] 1. 完成了客户端服务端语音相关的交互,涉及内容较多,看代码改动即可
|
||||||
|
|
||||||
|
#### Day20 2025.10.9(考研复习)
|
||||||
|
##### 主要目标:完成具体业务开发&各种优化
|
||||||
|
实际完成任务:
|
||||||
|
- [x] 1. 应用界面增加了返回主页的按钮
|
||||||
|
|
||||||
|
|
||||||
|
#### Day20 2025.10.12(考研复习)
|
||||||
|
##### 主要目标:完成具体业务开发&各种优化
|
||||||
|
实际完成任务:
|
||||||
|
- [x] 1. 修复了gif渲染内存泄漏的严重bug
|
||||||
|
|
||||||
|
|
||||||
|
#### Day20 2025.10.13(考研复习)
|
||||||
|
##### 主要目标:完成具体业务开发&各种优化
|
||||||
|
实际完成任务:
|
||||||
|
- [x] 1. 将PetDao当中的cJSON API替换为cpp_json,完美通过测试
|
||||||
|
|
||||||
|
|
||||||
|
#### Day20 2025.10.14(考研复习)
|
||||||
|
##### 主要目标:完成具体业务开发&各种优化
|
||||||
|
实际完成任务:
|
||||||
|
- [x] 1. 整合已经实现的各种上层建筑,实现了一个宠物对话基本业务应用,用于样品测试展示用
|
||||||
|
|
||||||
|
- [x] 2. 重构了音频播放类,使其更modern,更加便于移植和拓展
|
||||||
Reference in New Issue
Block a user