From f6d6e3be4c354799e228ae3f0bad67321815444b Mon Sep 17 00:00:00 2001 From: Totoo Date: Mon, 22 Jun 2026 16:20:49 +0200 Subject: [PATCH] Fix battery display bug, and the flash time (#3232) * battfix * por again, but nicer --- .../application/apps/ui_flash_utility.cpp | 2 +- firmware/application/apps/ui_settings.cpp | 6 ++++- firmware/common/battery.cpp | 2 +- firmware/common/i2cdev_max17055.cpp | 25 +++++++++++++------ firmware/common/i2cdev_max17055.hpp | 12 +++++++-- 5 files changed, 35 insertions(+), 12 deletions(-) diff --git a/firmware/application/apps/ui_flash_utility.cpp b/firmware/application/apps/ui_flash_utility.cpp index 74108c684..98b0aa3cc 100644 --- a/firmware/application/apps/ui_flash_utility.cpp +++ b/firmware/application/apps/ui_flash_utility.cpp @@ -168,7 +168,7 @@ bool FlashUtilityView::flash_firmware(std::filesystem::path::string_type path) { {0, 0, portapack::display.width(), portapack::display.height()}, Theme::getInstance()->bg_darkest->background); - painter.draw_string({12, 24}, this->nav_.style(), "This will take 15 seconds."); + painter.draw_string({12, 24}, this->nav_.style(), "This will take 15-45 sec."); painter.draw_string({12, 64}, this->nav_.style(), "Please wait while LED RX"); painter.draw_string({12, 84}, this->nav_.style(), "is on and TX is flashing."); painter.draw_string({12, 124}, this->nav_.style(), "Device will then restart."); diff --git a/firmware/application/apps/ui_settings.cpp b/firmware/application/apps/ui_settings.cpp index 47eebeba1..05ca91bee 100644 --- a/firmware/application/apps/ui_settings.cpp +++ b/firmware/application/apps/ui_settings.cpp @@ -1174,13 +1174,17 @@ SetBatteryView::SetBatteryView(NavigationView& nav) { pmem::set_battery_replaceable(checkbox_battery_replaceable.value()); battery::BatteryManagement::set_calc_override(checkbox_overridebatt.value()); i2cdev::I2cDev_MAX17055* dev = (i2cdev::I2cDev_MAX17055*)i2cdev::I2CDevManager::get_dev_by_model(I2C_DEVMDL::I2CDEVMDL_MAX17055); + if (dev) dev->resetChangedFlag(); if ((((uint32_t)field_battcap.value() != pmem::battery_cap_mah()) || (!pmem::battery_cap_valid())) || (dev && dev->getIsBattChanged())) { pmem::set_battery_cap_mah(field_battcap.value()); - if (dev) dev->resetChangedFlag(); if (dev && !dev->reInit()) { nav.display_modal("Error", "Battery gauge re-init failed"); return; } + if (dev) { + dev->resetChangedFlag(); + dev->update(); // resend the new data + } } send_system_refresh(); nav.pop(); diff --git a/firmware/common/battery.cpp b/firmware/common/battery.cpp index 85dc2ac23..e74130d01 100644 --- a/firmware/common/battery.cpp +++ b/firmware/common/battery.cpp @@ -41,7 +41,7 @@ void BatteryManagement::getBatteryInfo(uint8_t& valid_mask, uint8_t& percent, ui if (dev) { voltage = ((i2cdev::I2cDev_ADS1110*)dev)->readVoltage(); percent = calc_percent_voltage(voltage); - valid_mask = 1; + valid_mask = BATT_VALID_VOLTAGE | BATT_VALID_PERCENT; return; } diff --git a/firmware/common/i2cdev_max17055.cpp b/firmware/common/i2cdev_max17055.cpp index 38a9161db..e1e2a15da 100644 --- a/firmware/common/i2cdev_max17055.cpp +++ b/firmware/common/i2cdev_max17055.cpp @@ -192,7 +192,10 @@ void I2cDev_MAX17055::update() { bool battChanged = false; getBatteryInfo(validity, batteryPercentage, voltage, current, battChanged); - + if (validity == 0) { + // no valid data, don't send message + return; + } // send local message BatteryStateMessage msg{validity, batteryPercentage, current >= 25, voltage, battChanged}; EventDispatcher::send_message(msg); @@ -225,6 +228,7 @@ bool I2cDev_MAX17055::init(uint8_t addr_) { bool return_status = true; if (needsInitialization()) { // First-time or POR initialization + was_por = true; return_status = full_reset_and_init(); } chThdSleepMilliseconds(300); // wait for adc to fully wake up! @@ -252,10 +256,9 @@ bool I2cDev_MAX17055::full_reset_and_init() { if (!load_custom_parameters()) { return false; } - /*if (!clear_por()) { + if (!clear_por()) { return false; - }*/ - // don't clear it, we'll need to know the state + } return true; } @@ -390,17 +393,25 @@ void I2cDev_MAX17055::getBatteryInfo(uint8_t& valid_mask, uint8_t& batteryPercen valid_mask = 0; return; } + if (status == 0xFFFF) { + valid_mask = 0; + return; + } bool requires_reset = false; if (((status & 0xFF) >> 1) & 0x01) { // POR FLAG requires_reset = true; + was_por = true; } // Execute the reset if either flag was tripped if (requires_reset) { - reInit(); // todo maybe don't do it automatically, just signal. but for now it is safer to do it. - // battMayChanged = true && portapack::persistent_memory::battery_replaceable(); // only signal a change if the battery is replaceable. othervise do it silently - // We don't want to signal this for now. the Voltage drop during power up messes this up a bit. + reInit(); // reinit the ic. that takes time, so we'll return + valid_mask = 0; + return; } +#ifdef MAX17055_REPORT_POR_FLAG + battMayChanged = was_por && portapack::persistent_memory::battery_replaceable(); // only signal a change if the battery is replaceable. othervise do it silently +#endif batteryPercentage = stateOfCharge(); current = instantCurrent(); diff --git a/firmware/common/i2cdev_max17055.hpp b/firmware/common/i2cdev_max17055.hpp index 87dd60d99..7b7430413 100644 --- a/firmware/common/i2cdev_max17055.hpp +++ b/firmware/common/i2cdev_max17055.hpp @@ -29,6 +29,9 @@ #include "i2cdevmanager.hpp" +// if this define is set, the UI will show the battery has changed (POR flag is set) until the settings are saved (not ic reinited, but settings applyed by user!) +#define MAX17055_REPORT_POR_FLAG 1 + #define MAX17055_POR 0 #define MAX17055_IMin 1 #define MAX17055_IMax 2 @@ -292,8 +295,11 @@ class I2cDev_MAX17055 : public I2cDev { uint16_t stateOfCharge(void); bool reInit(); // call when battery parameters changed from ui. don't call if not needed, or the battery is not changed!!! bool getIsBattChanged() { return statusControl(MAX17055_POR); } // true if the ic thinks we have a new battery - void resetChangedFlag() { clear_por(); } // reset the flag - void sleep_config(bool enable_sleep); // if true, the ic can sleep after 3 minutes of inactivity (over i2c). can be waken up on any i2c communication (first packet may be dropped) + void resetChangedFlag() { + clear_por(); + was_por = false; + } // reset the flag + void sleep_config(bool enable_sleep); // if true, the ic can sleep after 3 minutes of inactivity (over i2c). can be waken up on any i2c communication (first packet may be dropped) private: const RegisterEntry* findEntry(const char* name) const; @@ -326,6 +332,8 @@ class I2cDev_MAX17055 : public I2cDev { bool setModelCfg(const uint8_t _Model_ID); bool setHibCFG(const uint16_t _Config); void config(void); + + bool was_por = false; }; } /* namespace i2cdev */