mirror of
https://github.com/m5stack/StackChan.git
synced 2026-06-14 18:20:27 +00:00
update firmware v1.3.0
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
set(PROJECT_VER "1.2.6")
|
||||
set(PROJECT_VER "1.3.0")
|
||||
add_definitions(-DFIRMWARE_VERSION=\"${PROJECT_VER}\")
|
||||
|
||||
# Add this line to disable the specific warning
|
||||
|
||||
@@ -70,6 +70,15 @@ void AppSetup::onOpen()
|
||||
_worker = std::make_unique<TimezoneWorker>();
|
||||
}}},
|
||||
},
|
||||
{
|
||||
"AI.Agent",
|
||||
{{"Power Saving",
|
||||
[&]() {
|
||||
_destroy_menu = true;
|
||||
_need_warm_reset = true;
|
||||
_worker = std::make_unique<XiaozhiPowerSavingWorker>();
|
||||
}}},
|
||||
},
|
||||
{
|
||||
"Hardware Test",
|
||||
{{"Servo",
|
||||
|
||||
@@ -120,8 +120,7 @@ void AccountWorker::update()
|
||||
mclog::tagInfo(_tag, "unbind clicked");
|
||||
_page_account.reset();
|
||||
|
||||
// Unbind account
|
||||
{
|
||||
_worker_reset = std::make_unique<FactoryResetWorker>([]() {
|
||||
auto loading_page = std::make_unique<view::LoadingPage>(0xF6F6F6, 0x26206A);
|
||||
GetHAL().lvglUnlock();
|
||||
|
||||
@@ -135,10 +134,7 @@ void AccountWorker::update()
|
||||
}
|
||||
|
||||
GetHAL().lvglLock();
|
||||
}
|
||||
|
||||
// Factory reset
|
||||
_worker_reset = std::make_unique<FactoryResetWorker>();
|
||||
});
|
||||
} else if (_page_account->isQuitClicked()) {
|
||||
mclog::tagInfo(_tag, "quit clicked");
|
||||
_is_done = true;
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
#include "workers.h"
|
||||
#include <mooncake_log.h>
|
||||
#include <hal/hal.h>
|
||||
#include <vector>
|
||||
|
||||
using namespace smooth_ui_toolkit::lvgl_cpp;
|
||||
using namespace setup_workers;
|
||||
|
||||
static std::string _tag = "Setup-AIAgent";
|
||||
|
||||
XiaozhiPowerSavingWorker::XiaozhiPowerSavingWorker()
|
||||
{
|
||||
mclog::info("XiaozhiPowerSavingWorker start");
|
||||
|
||||
for (uint32_t seconds = 0; seconds <= 3600; seconds += 300) {
|
||||
_idle_shutdown_levels.push_back(seconds);
|
||||
}
|
||||
|
||||
_config = GetHAL().getXiaozhiConfig();
|
||||
|
||||
int current_index = static_cast<int>(_idle_shutdown_levels.size()) - 1;
|
||||
for (size_t i = 0; i < _idle_shutdown_levels.size(); ++i) {
|
||||
if (_idle_shutdown_levels[i] >= _config.idleShutdownTimeSeconds) {
|
||||
current_index = static_cast<int>(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_panel = std::make_unique<Container>(lv_screen_active());
|
||||
_panel->setBgColor(lv_color_hex(0xEDF4FF));
|
||||
_panel->align(LV_ALIGN_CENTER, 0, 0);
|
||||
_panel->setBorderWidth(0);
|
||||
_panel->setSize(320, 240);
|
||||
_panel->setRadius(0);
|
||||
_panel->setPadding(0, 50, 24, 18);
|
||||
_panel->setScrollDir(LV_DIR_VER);
|
||||
_panel->setScrollbarMode(LV_SCROLLBAR_MODE_ACTIVE);
|
||||
|
||||
_panel_idle_shutdown = std::make_unique<Container>(_panel->get());
|
||||
_panel_idle_shutdown->setSize(296, 148);
|
||||
_panel_idle_shutdown->align(LV_ALIGN_TOP_MID, 0, 20);
|
||||
_panel_idle_shutdown->setBgColor(lv_color_hex(0xD2E3FF));
|
||||
_panel_idle_shutdown->setBorderWidth(0);
|
||||
_panel_idle_shutdown->setRadius(18);
|
||||
_panel_idle_shutdown->setPadding(0, 0, 0, 0);
|
||||
_panel_idle_shutdown->removeFlag(LV_OBJ_FLAG_SCROLLABLE);
|
||||
|
||||
_label_idle_title = std::make_unique<Label>(_panel_idle_shutdown->get());
|
||||
_label_idle_title->setText("Automatically power off after being idle for:");
|
||||
_label_idle_title->setWidth(280);
|
||||
_label_idle_title->setTextAlign(LV_TEXT_ALIGN_CENTER);
|
||||
_label_idle_title->setTextFont(&lv_font_montserrat_16);
|
||||
_label_idle_title->setTextColor(lv_color_hex(0x26206A));
|
||||
_label_idle_title->align(LV_ALIGN_TOP_MID, 0, 18);
|
||||
|
||||
_label_idle_value = std::make_unique<Label>(_panel_idle_shutdown->get());
|
||||
_label_idle_value->setTextFont(&lv_font_montserrat_24);
|
||||
_label_idle_value->setTextColor(lv_color_hex(0x26206A));
|
||||
_label_idle_value->align(LV_ALIGN_TOP_MID, 0, 64);
|
||||
|
||||
_slider_idle_shutdown = std::make_unique<Slider>(_panel_idle_shutdown->get());
|
||||
_slider_idle_shutdown->align(LV_ALIGN_TOP_MID, 0, 106);
|
||||
_slider_idle_shutdown->setRange(0, _idle_shutdown_levels.size() - 1);
|
||||
_slider_idle_shutdown->setSize(250, 18);
|
||||
_slider_idle_shutdown->setBgColor(lv_color_hex(0x615B9E), LV_PART_KNOB);
|
||||
_slider_idle_shutdown->setBgColor(lv_color_hex(0x615B9E), LV_PART_INDICATOR);
|
||||
_slider_idle_shutdown->setBgColor(lv_color_hex(0xB8D3FD), LV_PART_MAIN);
|
||||
_slider_idle_shutdown->setBgOpa(255);
|
||||
_slider_idle_shutdown->setValue(current_index);
|
||||
_slider_idle_shutdown->onValueChanged().connect([this](int32_t value) { _pending_idle_index = value; });
|
||||
|
||||
_panel_charging = std::make_unique<Container>(_panel->get());
|
||||
_panel_charging->setSize(296, 120);
|
||||
_panel_charging->align(LV_ALIGN_TOP_MID, 0, 188);
|
||||
_panel_charging->setBgColor(lv_color_hex(0xD2E3FF));
|
||||
_panel_charging->setBorderWidth(0);
|
||||
_panel_charging->setRadius(18);
|
||||
_panel_charging->setPadding(0, 0, 0, 0);
|
||||
_panel_charging->removeFlag(LV_OBJ_FLAG_SCROLLABLE);
|
||||
|
||||
_label_charging_title = std::make_unique<Label>(_panel_charging->get());
|
||||
_label_charging_title->setText("Allow auto power off while charging:");
|
||||
_label_charging_title->setTextFont(&lv_font_montserrat_16);
|
||||
_label_charging_title->setTextColor(lv_color_hex(0x26206A));
|
||||
_label_charging_title->setWidth(260);
|
||||
_label_charging_title->setTextAlign(LV_TEXT_ALIGN_CENTER);
|
||||
_label_charging_title->align(LV_ALIGN_TOP_MID, 0, 18);
|
||||
|
||||
_switch_charging = std::make_unique<Switch>(_panel_charging->get());
|
||||
_switch_charging->setSize(64, 36);
|
||||
_switch_charging->align(LV_ALIGN_TOP_MID, 0, 66);
|
||||
_switch_charging->setBgColor(lv_color_hex(0xB8D3FD), LV_PART_MAIN);
|
||||
_switch_charging->setBgColor(lv_color_hex(0x615B9E), LV_PART_INDICATOR | LV_STATE_CHECKED);
|
||||
_switch_charging->setBgColor(lv_color_hex(0xFFFFFF), LV_PART_KNOB);
|
||||
if (_config.allowShutdownWhenCharging) {
|
||||
_switch_charging->addState(LV_STATE_CHECKED);
|
||||
}
|
||||
|
||||
_btn_confirm = std::make_unique<Button>(_panel->get());
|
||||
apply_button_common_style(*_btn_confirm);
|
||||
_btn_confirm->align(LV_ALIGN_TOP_MID, 0, 326);
|
||||
_btn_confirm->setSize(290, 50);
|
||||
_btn_confirm->label().setText("Confirm");
|
||||
_btn_confirm->onClick().connect([this]() { _confirm_flag = true; });
|
||||
|
||||
update_idle_label();
|
||||
}
|
||||
|
||||
void XiaozhiPowerSavingWorker::update()
|
||||
{
|
||||
if (_pending_idle_index != -1) {
|
||||
_config.idleShutdownTimeSeconds = _idle_shutdown_levels[_pending_idle_index];
|
||||
_pending_idle_index = -1;
|
||||
update_idle_label();
|
||||
}
|
||||
|
||||
if (_confirm_flag) {
|
||||
_confirm_flag = false;
|
||||
_config.allowShutdownWhenCharging = _switch_charging->getValue();
|
||||
GetHAL().setXiaozhiConfig(_config);
|
||||
mclog::tagInfo(_tag, "xiaozhi config updated: idleShutdownTimeSeconds={}, allowShutdownWhenCharging={}",
|
||||
_config.idleShutdownTimeSeconds, _config.allowShutdownWhenCharging);
|
||||
_is_done = true;
|
||||
}
|
||||
}
|
||||
|
||||
void XiaozhiPowerSavingWorker::update_idle_label()
|
||||
{
|
||||
if (_config.idleShutdownTimeSeconds == 0) {
|
||||
_label_idle_value->setText("Off");
|
||||
return;
|
||||
}
|
||||
|
||||
auto total_minutes = _config.idleShutdownTimeSeconds / 60;
|
||||
_label_idle_value->setText(fmt::format("{} min", total_minutes));
|
||||
}
|
||||
@@ -190,8 +190,10 @@ void TimezoneWorker::update()
|
||||
}
|
||||
}
|
||||
|
||||
FactoryResetWorker::FactoryResetWorker()
|
||||
FactoryResetWorker::FactoryResetWorker(std::function<void()> beforeResetAction)
|
||||
{
|
||||
_before_reset_action = std::move(beforeResetAction);
|
||||
|
||||
_panel = std::make_unique<uitk::lvgl_cpp::Container>(lv_screen_active());
|
||||
_panel->setPadding(0, 0, 0, 0);
|
||||
_panel->setBgColor(lv_color_hex(0xEDF4FF));
|
||||
@@ -261,6 +263,10 @@ void FactoryResetWorker::update()
|
||||
_label_info->setText("Factory Resetting...\nDo not turn off power.");
|
||||
_label_info->align(LV_ALIGN_CENTER, 0, 0);
|
||||
|
||||
if (_before_reset_action) {
|
||||
_before_reset_action();
|
||||
}
|
||||
|
||||
GetHAL().lvglUnlock();
|
||||
GetHAL().delay(200);
|
||||
GetHAL().factoryReset();
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <uitk/short_namespace.hpp>
|
||||
#include <hal/hal.h>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string_view>
|
||||
|
||||
@@ -262,6 +263,34 @@ private:
|
||||
int32_t _target_volume = -1;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
*/
|
||||
class XiaozhiPowerSavingWorker : public WorkerBase {
|
||||
public:
|
||||
XiaozhiPowerSavingWorker();
|
||||
void update() override;
|
||||
|
||||
private:
|
||||
void update_idle_label();
|
||||
|
||||
std::unique_ptr<uitk::lvgl_cpp::Container> _panel;
|
||||
std::unique_ptr<uitk::lvgl_cpp::Container> _panel_idle_shutdown;
|
||||
std::unique_ptr<uitk::lvgl_cpp::Container> _panel_charging;
|
||||
std::unique_ptr<uitk::lvgl_cpp::Label> _label_idle_title;
|
||||
std::unique_ptr<uitk::lvgl_cpp::Label> _label_idle_value;
|
||||
std::unique_ptr<uitk::lvgl_cpp::Slider> _slider_idle_shutdown;
|
||||
std::unique_ptr<uitk::lvgl_cpp::Label> _label_charging_title;
|
||||
std::unique_ptr<uitk::lvgl_cpp::Switch> _switch_charging;
|
||||
std::unique_ptr<uitk::lvgl_cpp::Button> _btn_confirm;
|
||||
|
||||
XiaozhiConfig_t _config;
|
||||
std::vector<uint32_t> _idle_shutdown_levels;
|
||||
int32_t _pending_idle_index = -1;
|
||||
bool _confirm_flag = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
@@ -286,7 +315,7 @@ private:
|
||||
*/
|
||||
class FactoryResetWorker : public WorkerBase {
|
||||
public:
|
||||
FactoryResetWorker();
|
||||
FactoryResetWorker(std::function<void()> beforeResetAction = {});
|
||||
~FactoryResetWorker();
|
||||
void update() override;
|
||||
|
||||
@@ -300,6 +329,7 @@ private:
|
||||
int _confirm_count = 0;
|
||||
bool _cancel_flag = false;
|
||||
bool _confirm_flag = false;
|
||||
std::function<void()> _before_reset_action;
|
||||
|
||||
void update_ui();
|
||||
};
|
||||
|
||||
@@ -16,9 +16,14 @@
|
||||
#include <display.h>
|
||||
#include <mutex>
|
||||
#include <assets.h>
|
||||
#include <settings.h>
|
||||
|
||||
static const char* _tag = "HAL_BRIDGE";
|
||||
|
||||
static constexpr std::string_view _xiaozhi_config_nvs_ns = "xiaozhi";
|
||||
static constexpr std::string_view _xiaozhi_config_idle_shutdown_time_key = "idle_shutdown";
|
||||
static constexpr std::string_view _xiaozhi_config_allow_shutdown_when_charging_key = "shutdown_charge";
|
||||
|
||||
namespace hal_bridge {
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@@ -112,6 +117,26 @@ void start_xiaozhi_app()
|
||||
app.Run(); // This function runs the main event loop and never returns
|
||||
}
|
||||
|
||||
XiaozhiConfig_t get_xiaozhi_config()
|
||||
{
|
||||
XiaozhiConfig_t config;
|
||||
|
||||
Settings settings(_xiaozhi_config_nvs_ns.data(), false);
|
||||
config.idleShutdownTimeSeconds = settings.GetInt(_xiaozhi_config_idle_shutdown_time_key.data(),
|
||||
static_cast<int>(config.idleShutdownTimeSeconds));
|
||||
config.allowShutdownWhenCharging =
|
||||
settings.GetBool(_xiaozhi_config_allow_shutdown_when_charging_key.data(), config.allowShutdownWhenCharging);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
void set_xiaozhi_config(const XiaozhiConfig_t& config)
|
||||
{
|
||||
Settings settings(_xiaozhi_config_nvs_ns.data(), true);
|
||||
settings.SetInt(_xiaozhi_config_idle_shutdown_time_key.data(), config.idleShutdownTimeSeconds);
|
||||
settings.SetBool(_xiaozhi_config_allow_shutdown_when_charging_key.data(), config.allowShutdownWhenCharging);
|
||||
}
|
||||
|
||||
void app_play_sound(const std::string_view& sound)
|
||||
{
|
||||
auto& app = Application::GetInstance();
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
#pragma once
|
||||
#include "stackchan_camera.h"
|
||||
#include <cstdint>
|
||||
#include <lvgl.h>
|
||||
#include <driver/i2c_master.h>
|
||||
#include <string_view>
|
||||
@@ -23,6 +24,11 @@ struct Data_t {
|
||||
bool isXiaozhiModeToggleEnabled = false;
|
||||
};
|
||||
|
||||
struct XiaozhiConfig_t {
|
||||
uint32_t idleShutdownTimeSeconds = 600;
|
||||
bool allowShutdownWhenCharging = false;
|
||||
};
|
||||
|
||||
void lock();
|
||||
void unlock();
|
||||
Data_t& get_data();
|
||||
@@ -42,6 +48,8 @@ void xiaozhi_board_init();
|
||||
void start_xiaozhi_app();
|
||||
bool is_xiaozhi_ready();
|
||||
bool is_xiaozhi_idle();
|
||||
XiaozhiConfig_t get_xiaozhi_config();
|
||||
void set_xiaozhi_config(const XiaozhiConfig_t& config);
|
||||
|
||||
i2c_master_bus_handle_t board_get_i2c_bus();
|
||||
StackChanCamera* board_get_camera();
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <esp_lcd_panel_ops.h>
|
||||
#include <esp_lcd_ili9341.h>
|
||||
#include <esp_timer.h>
|
||||
#include <algorithm>
|
||||
#include "stackchan_camera.h"
|
||||
#include "hal_bridge.h"
|
||||
|
||||
@@ -112,6 +113,17 @@ public:
|
||||
WriteReg(XPOWERS_AXP2101_ICC_CHG_SET, val | opt);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsExternalPowerConnected()
|
||||
{
|
||||
const uint8_t power_status = ReadReg(0x01);
|
||||
const uint8_t current_direction = (power_status & 0b01100000) >> 5;
|
||||
const bool is_charging_done = (power_status & 0b00000111) == 0b00000100;
|
||||
|
||||
// Treat any non-discharging state as externally powered so a plugged-in cable
|
||||
// still counts even after the battery is full.
|
||||
return current_direction != 2 || is_charging_done;
|
||||
}
|
||||
};
|
||||
|
||||
class CustomBacklight : public Backlight {
|
||||
@@ -222,6 +234,9 @@ private:
|
||||
|
||||
class M5StackCoreS3Board : public WifiBoard {
|
||||
private:
|
||||
static constexpr int kPowerSaveSleepDelaySeconds = 300;
|
||||
static constexpr int kPowerStatePollIntervalMs = 1000;
|
||||
|
||||
i2c_master_bus_handle_t i2c_bus_;
|
||||
Pmic* pmic_;
|
||||
Aw9523* aw9523_;
|
||||
@@ -230,10 +245,55 @@ private:
|
||||
StackChanCamera* camera_;
|
||||
esp_timer_handle_t touchpad_timer_;
|
||||
PowerSaveTimer* power_save_timer_;
|
||||
hal_bridge::XiaozhiConfig_t xiaozhi_config_;
|
||||
bool last_power_save_enabled_ = false;
|
||||
int64_t last_power_state_check_ms_ = 0;
|
||||
|
||||
bool ShouldEnablePowerSave(bool has_external_power, bool is_discharging) const
|
||||
{
|
||||
return is_discharging || (has_external_power && xiaozhi_config_.allowShutdownWhenCharging);
|
||||
}
|
||||
|
||||
void UpdatePowerSaveEnabled(bool has_external_power, bool is_discharging)
|
||||
{
|
||||
const bool should_enable_power_save = ShouldEnablePowerSave(has_external_power, is_discharging);
|
||||
if (should_enable_power_save == last_power_save_enabled_) {
|
||||
return;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Power save timer %s: external_power=%d, discharging=%d, allowShutdownWhenCharging=%d",
|
||||
should_enable_power_save ? "enabled" : "disabled", has_external_power, is_discharging,
|
||||
xiaozhi_config_.allowShutdownWhenCharging);
|
||||
power_save_timer_->SetEnabled(should_enable_power_save);
|
||||
last_power_save_enabled_ = should_enable_power_save;
|
||||
}
|
||||
|
||||
void PollPowerSaveState()
|
||||
{
|
||||
const int64_t now_ms = esp_timer_get_time() / 1000;
|
||||
if (last_power_state_check_ms_ != 0 && (now_ms - last_power_state_check_ms_) < kPowerStatePollIntervalMs) {
|
||||
return;
|
||||
}
|
||||
last_power_state_check_ms_ = now_ms;
|
||||
|
||||
UpdatePowerSaveEnabled(pmic_->IsExternalPowerConnected(), pmic_->IsDischarging());
|
||||
}
|
||||
|
||||
void InitializePowerSaveTimer()
|
||||
{
|
||||
power_save_timer_ = new PowerSaveTimer(-1, 300, 600);
|
||||
xiaozhi_config_ = hal_bridge::get_xiaozhi_config();
|
||||
|
||||
const int seconds_to_shutdown = xiaozhi_config_.idleShutdownTimeSeconds > 0
|
||||
? static_cast<int>(xiaozhi_config_.idleShutdownTimeSeconds)
|
||||
: -1;
|
||||
const int seconds_to_sleep = seconds_to_shutdown == -1
|
||||
? kPowerSaveSleepDelaySeconds
|
||||
: std::min(kPowerSaveSleepDelaySeconds, seconds_to_shutdown);
|
||||
|
||||
ESP_LOGI(TAG, "Init power save timer: sleep=%d s, shutdown=%d s, allow_shutdown_when_charging=%d",
|
||||
seconds_to_sleep, seconds_to_shutdown, xiaozhi_config_.allowShutdownWhenCharging);
|
||||
|
||||
power_save_timer_ = new PowerSaveTimer(-1, seconds_to_sleep, seconds_to_shutdown);
|
||||
power_save_timer_->OnEnterSleepMode([this]() {
|
||||
GetDisplay()->SetPowerSaveMode(true);
|
||||
// GetBacklight()->SetBrightness(10);
|
||||
@@ -243,7 +303,7 @@ private:
|
||||
GetBacklight()->RestoreBrightness();
|
||||
});
|
||||
power_save_timer_->OnShutdownRequest([this]() { pmic_->PowerOff(); });
|
||||
power_save_timer_->SetEnabled(true);
|
||||
UpdatePowerSaveEnabled(pmic_->IsExternalPowerConnected(), pmic_->IsDischarging());
|
||||
}
|
||||
|
||||
void InitializeI2c()
|
||||
@@ -322,6 +382,7 @@ private:
|
||||
[](void* arg) {
|
||||
M5StackCoreS3Board* board = (M5StackCoreS3Board*)arg;
|
||||
board->PollTouchpad();
|
||||
board->PollPowerSaveState();
|
||||
},
|
||||
.arg = this,
|
||||
.dispatch_method = ESP_TIMER_TASK,
|
||||
@@ -432,9 +493,9 @@ private:
|
||||
public:
|
||||
M5StackCoreS3Board()
|
||||
{
|
||||
InitializePowerSaveTimer();
|
||||
InitializeI2c();
|
||||
InitializeAxp2101();
|
||||
InitializePowerSaveTimer();
|
||||
InitializeAw9523();
|
||||
I2cDetect();
|
||||
InitializeSpi();
|
||||
|
||||
@@ -202,6 +202,23 @@ void Hal::startXiaozhi()
|
||||
hal_bridge::start_xiaozhi_app();
|
||||
}
|
||||
|
||||
XiaozhiConfig_t Hal::getXiaozhiConfig()
|
||||
{
|
||||
auto bridge_config = hal_bridge::get_xiaozhi_config();
|
||||
return XiaozhiConfig_t{
|
||||
.idleShutdownTimeSeconds = bridge_config.idleShutdownTimeSeconds,
|
||||
.allowShutdownWhenCharging = bridge_config.allowShutdownWhenCharging,
|
||||
};
|
||||
}
|
||||
|
||||
void Hal::setXiaozhiConfig(XiaozhiConfig_t config)
|
||||
{
|
||||
hal_bridge::set_xiaozhi_config({
|
||||
.idleShutdownTimeSeconds = config.idleShutdownTimeSeconds,
|
||||
.allowShutdownWhenCharging = config.allowShutdownWhenCharging,
|
||||
});
|
||||
}
|
||||
|
||||
uint8_t Hal::getBatteryLevel()
|
||||
{
|
||||
return hal_bridge::board_get_battery_level();
|
||||
|
||||
@@ -110,6 +110,15 @@ struct UserAccountInfo_t {
|
||||
std::string deviceName;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
*/
|
||||
struct XiaozhiConfig_t {
|
||||
uint32_t idleShutdownTimeSeconds = 600;
|
||||
bool allowShutdownWhenCharging = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
@@ -189,6 +198,8 @@ public:
|
||||
return _xiaozhi_start_requested;
|
||||
}
|
||||
void startXiaozhi();
|
||||
XiaozhiConfig_t getXiaozhiConfig();
|
||||
void setXiaozhiConfig(XiaozhiConfig_t config);
|
||||
|
||||
/* ----------------------------------- BLE ---------------------------------- */
|
||||
uitk::Signal<const char*> onBleMotionData;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
#include "hal.h"
|
||||
#include <mooncake_log.h>
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
#include <ota.h>
|
||||
|
||||
@@ -45,11 +46,19 @@ bool Hal::updateFirmware(std::function<void(std::string_view)> onLog)
|
||||
}
|
||||
|
||||
onLog("Starting firmware upgrade...");
|
||||
bool upgrade_success = Ota::Upgrade(firmware_url, [&](int progress, size_t speed) {
|
||||
auto msg = fmt::format("Upgrading firmware: {}% at {}KB/s", progress, speed / 1024);
|
||||
mclog::tagInfo(_tag, "upgrade progress: {}", msg);
|
||||
int last_reported_progress = -1;
|
||||
bool upgrade_success = Ota::Upgrade(firmware_url, [&](int progress, size_t speed) {
|
||||
if (progress == last_reported_progress) {
|
||||
return;
|
||||
}
|
||||
|
||||
last_reported_progress = progress;
|
||||
|
||||
char msg[48];
|
||||
std::snprintf(msg, sizeof(msg), "Upgrading firmware: %d%% at %uKB/s", progress,
|
||||
static_cast<unsigned>(speed / 1024));
|
||||
onLog(msg);
|
||||
});
|
||||
});
|
||||
|
||||
if (!upgrade_success) {
|
||||
mclog::tagError(_tag, "firmware upgrade failed: version={}, url={}", firmware_version, firmware_url);
|
||||
|
||||
@@ -9,6 +9,7 @@ CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_LANGUAGE_EN_US=y
|
||||
CONFIG_BOARD_TYPE_M5STACK_STACK_CHAN=y
|
||||
CONFIG_SEND_WAKE_WORD_DATA=n
|
||||
CONFIG_SR_WN_WN9_HISTACKCHAN_TTS3=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_COMPILER_CXX_EXCEPTIONS=y
|
||||
|
||||
Reference in New Issue
Block a user