Skip to content

Commit

Permalink
Max17055 improvements (#2197)
Browse files Browse the repository at this point in the history
* fixes

* more fixes

* more fixes

* fix

* more fixes

* fix icon updates

* fix init unk error

* simplify

* improve icon init

* code format

* Update ui_battinfo.cpp
  • Loading branch information
htotoo committed Jul 17, 2024
1 parent 19eb6b4 commit 2bedb5f
Show file tree
Hide file tree
Showing 13 changed files with 112 additions and 63 deletions.
22 changes: 10 additions & 12 deletions firmware/application/apps/ui_battinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,13 @@

#include "event_m0.hpp"
#include "portapack.hpp"

#include "battery.hpp"
#include <cstring>

using namespace portapack;

namespace ui {

bool BattinfoView::needRun = true;
void BattinfoView::focus() {
button_exit.focus();
}
Expand All @@ -53,23 +52,24 @@ void BattinfoView::update_result() {
return;
}
bool uichg = false;
battery::BatteryManagement::getBatteryInfo(percent, voltage, current);
uint8_t valid_mask = 0;
battery::BatteryManagement::getBatteryInfo(valid_mask, percent, voltage, current);
// update text fields
if (percent <= 100)
if (percent <= 100 && (valid_mask & battery::BatteryManagement::BATT_VALID_VOLTAGE) == battery::BatteryManagement::BATT_VALID_VOLTAGE)
text_percent.set(to_string_dec_uint(percent) + " %");
else
text_percent.set("UNKNOWN");
if (voltage > 1) {
if (voltage > 1 && (valid_mask & battery::BatteryManagement::BATT_VALID_VOLTAGE) == battery::BatteryManagement::BATT_VALID_VOLTAGE) {
text_voltage.set(to_string_decimal(voltage / 1000.0, 3) + " V");
} else {
text_voltage.set("UNKNOWN");
}
if (current != 0) {
if ((valid_mask & battery::BatteryManagement::BATT_VALID_CURRENT) == battery::BatteryManagement::BATT_VALID_CURRENT) {
if (labels_opt.hidden()) uichg = true;
labels_opt.hidden(false);
text_current.hidden(false);
text_charge.hidden(false);
text_current.set(to_string_decimal(current / 100000.0, 3) + " mA");
text_current.set(to_string_dec_int(current) + " mA");
text_charge.set(current >= 0 ? "Charging" : "Discharging");
labels_opt.hidden(false);
} else {
Expand All @@ -80,7 +80,7 @@ void BattinfoView::update_result() {
}
if (uichg) set_dirty();
// to update status bar too, send message in behalf of batt manager
BatteryStateMessage msg{percent, current >= 0, voltage};
BatteryStateMessage msg{valid_mask, percent, current >= 0, voltage};
EventDispatcher::send_message(msg);
}

Expand All @@ -99,21 +99,19 @@ BattinfoView::BattinfoView(NavigationView& nav)
};

update_result();
needRun = true;
thread = chThdCreateFromHeap(NULL, 512, NORMALPRIO + 10, BattinfoView::static_fn, this);
if (thread == nullptr) thread = chThdCreateFromHeap(NULL, 1024, NORMALPRIO + 10, BattinfoView::static_fn, this);
}

msg_t BattinfoView::static_fn(void* arg) {
auto obj = static_cast<BattinfoView*>(arg);
while (needRun) {
while (!chThdShouldTerminate()) {
chThdSleepMilliseconds(16);
obj->on_timer();
}
return 0;
}

BattinfoView::~BattinfoView() {
needRun = false;
if (thread) {
chThdTerminate(thread);
chThdWait(thread);
Expand Down
1 change: 0 additions & 1 deletion firmware/application/apps/ui_battinfo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ class BattinfoView : public View {
{72, 17 * 16, 96, 32},
"Back"};
static msg_t static_fn(void* arg);
static bool needRun;
Thread* thread{nullptr};
};

Expand Down
14 changes: 10 additions & 4 deletions firmware/application/ui_navigation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -385,11 +385,16 @@ void SystemStatusView::on_battery_details() {
}

void SystemStatusView::on_battery_data(const BatteryStateMessage* msg) {
if (!batt_was_inited) {
batt_was_inited = true;
refresh();
return;
}
if (!pmem::ui_hide_numeric_battery()) {
battery_text.set_battery(msg->percent, msg->on_charger);
battery_text.set_battery(msg->valid_mask, msg->percent, msg->on_charger);
}
if (!pmem::ui_hide_battery_icon()) {
battery_icon.set_battery(msg->percent, msg->on_charger);
battery_icon.set_battery(msg->valid_mask, msg->percent, msg->on_charger);
};
}

Expand All @@ -410,14 +415,15 @@ void SystemStatusView::refresh() {

if (!pmem::ui_hide_fake_brightness()) status_icons.add(&button_fake_brightness);
if (battery::BatteryManagement::isDetected()) {
batt_was_inited = true;
uint8_t percent = battery::BatteryManagement::getPercent();
if (!pmem::ui_hide_battery_icon()) {
status_icons.add(&battery_icon);
battery_text.set_battery(percent, false); // got an on select, that may pop up the details of the battery.
battery_text.set_battery(percent <= 100 ? 1 : 0, percent, false); // got an on select, that may pop up the details of the battery.
};
if (!pmem::ui_hide_numeric_battery()) {
status_icons.add(&battery_text);
battery_text.set_battery(percent, false);
battery_text.set_battery(percent <= 100 ? 1 : 0, percent, false);
}
}

Expand Down
3 changes: 2 additions & 1 deletion firmware/application/ui_navigation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,8 @@ class SystemStatusView : public View {

private:
static constexpr auto default_title = "";
bool batt_info_up = false; // to prevent show multiple batt info dialog
bool batt_was_inited = false; // if the battery was off on tart, but later turned on.
bool batt_info_up = false; // to prevent show multiple batt info dialog
NavigationView& nav_;

Rectangle backdrop{
Expand Down
3 changes: 2 additions & 1 deletion firmware/common/ads1110.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ uint16_t ADS1110::readVoltage() {
return (uint16_t)voltage;
}

void ADS1110::getBatteryInfo(uint8_t& batteryPercentage, uint16_t& voltage) {
void ADS1110::getBatteryInfo(uint8_t& valid_mask, uint8_t& batteryPercentage, uint16_t& voltage) {
voltage = readVoltage();

// Calculate the remaining battery percentage
Expand All @@ -127,6 +127,7 @@ void ADS1110::getBatteryInfo(uint8_t& batteryPercentage, uint16_t& voltage) {
// Limit the values to the valid range
batteryPercentage = (batteryPercentage > 100) ? 100 : batteryPercentage;
// ToDo: if its > 4, then 100%, if < 3 then 0%
valid_mask = 1; // BATT_VALID_VOLTAGE
}

} /* namespace ads1110 */
Expand Down
2 changes: 1 addition & 1 deletion firmware/common/ads1110.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class ADS1110 {
bool isDetected() const { return detected_; }

uint16_t readVoltage();
void getBatteryInfo(uint8_t& batteryPercentage, uint16_t& voltage);
void getBatteryInfo(uint8_t& valid_mask, uint8_t& batteryPercentage, uint16_t& voltage);

private:
I2C& bus;
Expand Down
56 changes: 35 additions & 21 deletions firmware/common/battery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,49 +11,55 @@ extern I2C portapack::i2c0;

namespace battery {

constexpr uint32_t BATTERY_UPDATE_INTERVAL = 30000;
constexpr uint32_t BATTERY_UPDATE_INTERVAL = 20000;
BatteryManagement::BatteryModules BatteryManagement::detected_ = BatteryManagement::BATT_NONE;

ads1110::ADS1110 battery_ads1110{portapack::i2c0, 0x48};
max17055::MAX17055 battery_max17055{portapack::i2c0, 0x36};

Thread* BatteryManagement::thread = nullptr;

void BatteryManagement::init() {
void BatteryManagement::detect() {
// try to detect supported modules
detected_ = BATT_NONE;
if (battery_ads1110.detect()) {
battery_ads1110.init();
detected_ = BATT_ADS1110;
} else if (battery_max17055.detect()) {
battery_max17055.init();
return;
}
if (battery_max17055.detect()) {
// battery_max17055.init(); //detect will call this on each "re detect"
detected_ = BATT_MAX17055;
return;
}

// add new supported module detect + init here

#ifdef USE_BATT_EMULATOR
if (detected_ == BATT_NONE) {
detected_ = BATT_EMULATOR;
return;
}
#endif
}

if (detected_ != BATT_NONE) {
// sets timer to query and broadcats this info
create_thread();
}
void BatteryManagement::init() {
detect();
// sets timer to query and broadcats this info
create_thread();
}

// sets the values, it the currend module supports it.
bool BatteryManagement::getBatteryInfo(uint8_t& batteryPercentage, uint16_t& voltage, int32_t& current) {
void BatteryManagement::getBatteryInfo(uint8_t& valid_mask, uint8_t& batteryPercentage, uint16_t& voltage, int32_t& current) {
if (detected_ == BATT_NONE) {
return false;
valid_mask = BATT_VALID_NONE;
return;
} else if (detected_ == BATT_ADS1110) {
battery_ads1110.getBatteryInfo(batteryPercentage, voltage);
return true;
battery_ads1110.getBatteryInfo(valid_mask, batteryPercentage, voltage);
return;
} else if (detected_ == BATT_MAX17055) {
battery_max17055.getBatteryInfo(batteryPercentage, voltage, current);
return true;
battery_max17055.getBatteryInfo(valid_mask, batteryPercentage, voltage, current);
return;
}
// add new module query here

Expand All @@ -64,12 +70,12 @@ bool BatteryManagement::getBatteryInfo(uint8_t& batteryPercentage, uint16_t& vol
voltage = rand() % 1000 + 3000; // mV
current = rand() % 150; // mA
isCharging = rand() % 2;
valid_mask = 3;
return true;
}
#endif

(void)current;
return false;
}

uint16_t BatteryManagement::read_register(const uint8_t reg) {
Expand All @@ -88,34 +94,42 @@ bool BatteryManagement::write_register(const uint8_t reg, const uint16_t value)

uint8_t BatteryManagement::getPercent() {
if (detected_ == BATT_NONE) return 102;
uint8_t validity = 0;
uint8_t batteryPercentage = 0;
uint16_t voltage = 0;
int32_t current = 0;
getBatteryInfo(batteryPercentage, voltage, current);
getBatteryInfo(validity, batteryPercentage, voltage, current);
if ((validity & BATT_VALID_VOLTAGE) != BATT_VALID_VOLTAGE) return 102;
return batteryPercentage;
}

uint16_t BatteryManagement::getVoltage() {
if (detected_ == BATT_NONE) return 0;
if (detected_ == BATT_NONE) return 102;
uint8_t validity = 0;
uint8_t batteryPercentage = 0;
uint16_t voltage = 0;
int32_t current = 0;
getBatteryInfo(batteryPercentage, voltage, current);
getBatteryInfo(validity, batteryPercentage, voltage, current);
if ((validity & BATT_VALID_VOLTAGE) != BATT_VALID_VOLTAGE) return 0;
return voltage;
}

msg_t BatteryManagement::timer_fn(void* arg) {
(void)arg;
if (!detected_) return 0;
uint8_t validity = 0;
uint8_t batteryPercentage = 102;
uint16_t voltage = 0;
int32_t current = 0;
chThdSleepMilliseconds(1000); // wait ui for fully load
while (1) {
if (BatteryManagement::getBatteryInfo(batteryPercentage, voltage, current)) {
if (!detected_) {
detect(); // try to detect it again, it maybe disconnected while pp was powered up
chThdSleepMilliseconds(500);
}
if (detected_) {
BatteryManagement::getBatteryInfo(validity, batteryPercentage, voltage, current);
// send local message
BatteryStateMessage msg{batteryPercentage, current >= 0, voltage};
BatteryStateMessage msg{validity, batteryPercentage, current >= 0, voltage};
EventDispatcher::send_message(msg);
}
chThdSleepMilliseconds(BATTERY_UPDATE_INTERVAL);
Expand Down
8 changes: 7 additions & 1 deletion firmware/common/battery.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,16 @@ class BatteryManagement {
BATT_MAX17055 = 2,
BATT_EMULATOR = 254
};
enum BatteryValidMask {
BATT_VALID_NONE = 0,
BATT_VALID_VOLTAGE = 1,
BATT_VALID_CURRENT = 2,
};
static void init();
static void detect();
static bool isDetected() { return detected_ != BATT_NONE; }
static BatteryModules detectedModule() { return detected_; }
static bool getBatteryInfo(uint8_t& batteryPercentage, uint16_t& voltage, int32_t& current);
static void getBatteryInfo(uint8_t& valid_mask, uint8_t& batteryPercentage, uint16_t& voltage, int32_t& current);
static uint16_t getVoltage();
static uint8_t getPercent();
static uint16_t read_register(const uint8_t reg);
Expand Down
33 changes: 24 additions & 9 deletions firmware/common/max17055.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ namespace max17055 {
void MAX17055::init() {
if (!detected_) {
detected_ = detect();
} else {
}
if (detected_) { // check again if it is detected
config();
setHibCFG(0x0000);

Expand Down Expand Up @@ -81,8 +82,15 @@ bool MAX17055::detect() {

// Get Data from IC
if (readMultipleRegister(0x00, _MAX17055_Data, 2, false)) {
detected_ = true;
return true;
if (((_MAX17055_Data[0] != 0x00) && (_MAX17055_Data[0] != 0x02)) || (_MAX17055_Data[1] != 0x00)) {
// validate result, since i2c gives a bit of power to the ic, and sometimes it sets the init value.
// this will return false when the ic is in init state (0x0002), but on the next iteration it'll give the good value
if (detected_ == false) {
detected_ = true;
init();
}
return true;
}
}
detected_ = false;
return false;
Expand Down Expand Up @@ -153,10 +161,17 @@ bool MAX17055::writeMultipleRegister(uint8_t reg, const uint8_t* data, uint8_t l
return false;
}

void MAX17055::getBatteryInfo(uint8_t& batteryPercentage, uint16_t& voltage, int32_t& current) {
voltage = averageVoltage();
batteryPercentage = stateOfCharge();
current = instantCurrent();
void MAX17055::getBatteryInfo(uint8_t& valid_mask, uint8_t& batteryPercentage, uint16_t& voltage, int32_t& current) {
detect(); // need to detect again, since user can disconnect the ic anytime, and that could send garbage causing flickering data.
if (detected_) {
voltage = averageVoltage();
batteryPercentage = stateOfCharge();
current = instantCurrent();
valid_mask = 3; // BATT_VALID_VOLTAGE + CURRENT
} else {
// let's indicate the data is wrong. ui will handle this by display UNK values.
valid_mask = 0;
}
}

bool MAX17055::setEmptyVoltage(uint16_t _Empty_Voltage) {
Expand Down Expand Up @@ -553,7 +568,7 @@ int32_t MAX17055::instantCurrent(void) {
// Convert to signed int16_t (two's complement)
int32_t _Signed_Raw = static_cast<int16_t>(_Measurement_Raw);

int32_t _Value = (_Signed_Raw * 15625) / (__MAX17055_Resistor__ * 100);
int32_t _Value = (_Signed_Raw * 15625) / (__MAX17055_Resistor__ * 100) / 100000;

// End Function
return _Value;
Expand All @@ -566,7 +581,7 @@ int32_t MAX17055::averageCurrent(void) {
// Convert to signed int16_t (two's complement)
int32_t _Signed_Raw = static_cast<int16_t>(_Measurement_Raw);

int32_t _Value = (_Signed_Raw * 15625) / (__MAX17055_Resistor__ * 100);
int32_t _Value = (_Signed_Raw * 15625) / (__MAX17055_Resistor__ * 100) / 100000;

// End Function
return _Value;
Expand Down
Loading

0 comments on commit 2bedb5f

Please sign in to comment.