Merge pull request #17 from 78/ui

add power save timer
This commit is contained in:
Xiaoxia
2024-11-19 08:56:22 +08:00
committed by GitHub
7 changed files with 74 additions and 29 deletions

View File

@@ -4,7 +4,7 @@
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
set(PROJECT_VER "0.9.0")
set(PROJECT_VER "0.9.1")
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(xiaozhi)

View File

@@ -61,6 +61,8 @@ void Application::CheckNewVersion() {
display->SetIcon(FONT_AWESOME_DOWNLOAD);
display->SetStatus("新版本 " + ota_.GetFirmwareVersion());
// 预先关闭音频输出,避免升级过程有音频操作
board.GetAudioCodec()->EnableOutput(false);
ota_.StartUpgrade([display](int progress, size_t speed) {

View File

@@ -1,46 +1,46 @@
#include "axp2101.h"
#include "board.h"
#include "display.h"
#include <esp_log.h>
static const char *TAG = "AXP2101";
static const char *TAG = "Axp2101";
Axp2101::Axp2101(i2c_master_bus_handle_t i2c_bus, uint8_t addr) : I2cDevice(i2c_bus, addr) {
// ** EFUSE defaults **
WriteReg(0x22, 0b110); // PWRON > OFFLEVEL as POWEROFF Source enable
WriteReg(0x27, 0x10); // hold 4s to power off
WriteReg(0x93, 0x1c); // 配置aldo2输出为3.3v
WriteReg(0x93, 0x1C); // 配置 aldo2 输出为 3.3V
uint8_t value = ReadReg(0x90); // XPOWERS_AXP2101_LDO_ONOFF_CTRL0
uint8_t value = ReadReg(0x90); // XPOWERS_AXP2101_LDO_ONOFF_CTRL0
value = value | 0x02; // set bit 1 (ALDO2)
WriteReg(0x90, value); // and power channels now enabled
WriteReg(0x64, 0x03); // CV charger voltage setting to 42V
value = ReadReg(0x62);
ESP_LOGI(TAG, "axp2101 read 0x62 get: 0x%X", value);
WriteReg(0x64, 0x03); // CV charger voltage setting to 4.2V
WriteReg(0x61, 0x05); // set Main battery precharge current to 125mA
WriteReg(0x62, 0x10); // set Main battery charger current to 900mA ( 0x08-200mA, 0x09-300mA, 0x0A-400mA )
WriteReg(0x62, 0x10); // set Main battery charger current to 1000mA ( 0x08-200mA, 0x09-300mA, 0x0A-400mA )
WriteReg(0x63, 0x15); // set Main battery term charge current to 125mA
value = ReadReg(0x62);
ESP_LOGI(TAG, "axp2101 read 0x62 get: 0x%X", value);
value = ReadReg(0x18);
ESP_LOGI(TAG, "axp2101 read 0x18 get: 0x%X", value);
value = value & 0b11100000;
value = value | 0b00001110;
WriteReg(0x18, value);
value = ReadReg(0x18);
ESP_LOGI(TAG, "axp2101 read 0x18 get: 0x%X", value);
WriteReg(0x14, 0x00); // set minimum system voltage to 4.1V (default 4.7V), for poor USB cables
WriteReg(0x15, 0x00); // set input voltage limit to 3.88v, for poor USB cables
WriteReg(0x16, 0x05); // set input voltage limit to 3.88v, for poor USB cables
WriteReg(0x16, 0x05); // set input current limit to 2000mA
WriteReg(0x24, 0x01); // set Vsys for PWROFF threshold to 3.2V (default - 2.6V and kill battery)
WriteReg(0x50, 0x14); // set TS pin to EXTERNAL input (not temperature)
}
int Axp2101::GetBatteryCurrentDirection() {
return (ReadReg(0x01) & 0b01100000) >> 5;
}
bool Axp2101::IsCharging() {
uint8_t value = ReadReg(0x01);
return (value & 0b01100000) == 0b00100000;
return GetBatteryCurrentDirection() == 1;
}
bool Axp2101::IsDischarging() {
return GetBatteryCurrentDirection() == 2;
}
bool Axp2101::IsChargingDone() {
@@ -49,8 +49,7 @@ bool Axp2101::IsChargingDone() {
}
int Axp2101::GetBatteryLevel() {
uint8_t value = ReadReg(0xA4);
return value;
return ReadReg(0xA4);
}
void Axp2101::PowerOff() {

View File

@@ -7,9 +7,13 @@ class Axp2101 : public I2cDevice {
public:
Axp2101(i2c_master_bus_handle_t i2c_bus, uint8_t addr);
bool IsCharging();
bool IsDischarging();
bool IsChargingDone();
int GetBatteryLevel();
void PowerOff();
private:
int GetBatteryCurrentDirection();
};
#endif

View File

@@ -11,6 +11,7 @@
#include <esp_spiffs.h>
#include <driver/gpio.h>
#include <driver/i2c_master.h>
#include <esp_timer.h>
static const char *TAG = "KevinBoxBoard";
@@ -23,6 +24,41 @@ private:
Button volume_up_button_;
Button volume_down_button_;
uint8_t _data_buffer[2];
esp_timer_handle_t power_save_timer_ = nullptr;
void InitializePowerSaveTimer() {
esp_timer_create_args_t power_save_timer_args = {
.callback = [](void *arg) {
auto board = static_cast<KevinBoxBoard*>(arg);
board->PowerSaveCheck();
},
.arg = this,
.dispatch_method = ESP_TIMER_TASK,
.name = "Power Save Timer",
.skip_unhandled_events = false,
};
ESP_ERROR_CHECK(esp_timer_create(&power_save_timer_args, &power_save_timer_));
ESP_ERROR_CHECK(esp_timer_start_periodic(power_save_timer_, 1000000));
}
void PowerSaveCheck() {
// 电池放电模式下,如果待机超过一定时间,则自动关机
const int seconds_to_shutdown = 600;
static int seconds = 0;
if (Application::GetInstance().GetChatState() != kChatStateIdle) {
seconds = 0;
return;
}
if (!axp2101_->IsDischarging()) {
seconds = 0;
return;
}
seconds++;
if (seconds >= seconds_to_shutdown) {
axp2101_->PowerOff();
}
}
void MountStorage() {
// Mount the storage partition
@@ -86,10 +122,6 @@ private:
Application::GetInstance().ToggleChatState();
});
boot_button_.OnLongPress([this]() {
axp2101_->PowerOff();
});
volume_up_button_.OnClick([this]() {
auto codec = GetAudioCodec();
auto volume = codec->output_volume() + 10;
@@ -140,6 +172,7 @@ public:
Enable4GModule();
InitializeButtons();
InitializePowerSaveTimer();
Ml307Board::Initialize();
}
@@ -162,8 +195,15 @@ public:
}
virtual bool GetBatteryLevel(int &level, bool& charging) override {
static int last_level = 0;
static bool last_charging = false;
level = axp2101_->GetBatteryLevel();
charging = axp2101_->IsCharging();
if (level != last_level || charging != last_charging) {
last_level = level;
last_charging = charging;
ESP_LOGI(TAG, "Battery level: %d, charging: %d", level, charging);
}
return true;
}
};

View File

@@ -120,7 +120,7 @@ void Display::Update() {
}
}
// 仅在聊天状态为空闲时,更新网络图标
// 仅在聊天状态为空闲时,读取网络状态(避免升级时占用 UART 资源)
auto chat_state = Application::GetInstance().GetChatState();
if (chat_state == kChatStateIdle || chat_state == kChatStateUnknown) {
icon = board.GetNetworkStateIcon();

View File

@@ -64,7 +64,7 @@ def get_board_name(folder):
return "bread-compact-wifi"
elif "KevinBox1" in basename:
return "kevin-box-1"
if basename.startswith("v0.7") or basename.startswith("v0.8"):
if basename.startswith("v0.7") or basename.startswith("v0.8") or basename.startswith("v0.9"):
return basename.split("_")[1]
raise Exception(f"Unknown board name: {basename}")