FuriHal, Power, UnitTests: fix, rename battery charging voltage limit API (#2228)

* FuriHal, Power, UnitTests: rename battery charge voltage limit API
* FuriHal: bump API, power info major versions
* Power: fix battery charge voltage limit for > 7.935v

Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
Shane Synan
2023-02-26 12:23:39 -05:00
committed by GitHub
parent 1d55aee39c
commit 09edf66a2a
11 changed files with 69 additions and 57 deletions

View File

@@ -3,56 +3,63 @@
#include "../minunit.h"
static void power_test_deinit(void) {
// Try to reset to default charging voltage
furi_hal_power_set_battery_charging_voltage(4.208f);
// Try to reset to default charge voltage limit
furi_hal_power_set_battery_charge_voltage_limit(4.208f);
}
MU_TEST(test_power_charge_voltage_exact) {
// Power of 16mV charge voltages get applied exactly
MU_TEST(test_power_charge_voltage_limit_exact) {
// Power of 16mV charge voltage limits get applied exactly
// (bq25896 charge controller works in 16mV increments)
//
// This test may need adapted if other charge controllers are used in the future.
for(uint16_t charge_mv = 3840; charge_mv <= 4208; charge_mv += 16) {
float charge_volt = (float)charge_mv / 1000.0f;
furi_hal_power_set_battery_charging_voltage(charge_volt);
mu_assert_double_eq(charge_volt, furi_hal_power_get_battery_charging_voltage());
furi_hal_power_set_battery_charge_voltage_limit(charge_volt);
mu_assert_double_eq(charge_volt, furi_hal_power_get_battery_charge_voltage_limit());
}
}
MU_TEST(test_power_charge_voltage_floating_imprecision) {
MU_TEST(test_power_charge_voltage_limit_floating_imprecision) {
// 4.016f should act as 4.016 V, even with floating point imprecision
furi_hal_power_set_battery_charging_voltage(4.016f);
mu_assert_double_eq(4.016f, furi_hal_power_get_battery_charging_voltage());
furi_hal_power_set_battery_charge_voltage_limit(4.016f);
mu_assert_double_eq(4.016f, furi_hal_power_get_battery_charge_voltage_limit());
}
MU_TEST(test_power_charge_voltage_inexact) {
// Charge voltages that are not power of 16mV get truncated down
furi_hal_power_set_battery_charging_voltage(3.841f);
mu_assert_double_eq(3.840, furi_hal_power_get_battery_charging_voltage());
MU_TEST(test_power_charge_voltage_limit_inexact) {
// Charge voltage limits that are not power of 16mV get truncated down
furi_hal_power_set_battery_charge_voltage_limit(3.841f);
mu_assert_double_eq(3.840, furi_hal_power_get_battery_charge_voltage_limit());
furi_hal_power_set_battery_charging_voltage(3.900f);
mu_assert_double_eq(3.888, furi_hal_power_get_battery_charging_voltage());
furi_hal_power_set_battery_charge_voltage_limit(3.900f);
mu_assert_double_eq(3.888, furi_hal_power_get_battery_charge_voltage_limit());
furi_hal_power_set_battery_charging_voltage(4.200f);
mu_assert_double_eq(4.192, furi_hal_power_get_battery_charging_voltage());
furi_hal_power_set_battery_charge_voltage_limit(4.200f);
mu_assert_double_eq(4.192, furi_hal_power_get_battery_charge_voltage_limit());
}
MU_TEST(test_power_charge_voltage_invalid_clamped) {
// Out-of-range charge voltages get clamped to 3.840 V and 4.208 V
furi_hal_power_set_battery_charging_voltage(3.808f);
mu_assert_double_eq(3.840, furi_hal_power_get_battery_charging_voltage());
MU_TEST(test_power_charge_voltage_limit_invalid_clamped) {
// Out-of-range charge voltage limits get clamped to 3.840 V and 4.208 V
furi_hal_power_set_battery_charge_voltage_limit(3.808f);
mu_assert_double_eq(3.840, furi_hal_power_get_battery_charge_voltage_limit());
furi_hal_power_set_battery_charge_voltage_limit(1.0f);
mu_assert_double_eq(3.840, furi_hal_power_get_battery_charge_voltage_limit());
// NOTE: Intentionally picking a small increment above 4.208 V to reduce the risk of an
// unhappy battery if this fails.
furi_hal_power_set_battery_charging_voltage(4.240f);
mu_assert_double_eq(4.208, furi_hal_power_get_battery_charging_voltage());
furi_hal_power_set_battery_charge_voltage_limit(4.240f);
mu_assert_double_eq(4.208, furi_hal_power_get_battery_charge_voltage_limit());
// Likewise, picking a number that the uint8_t wraparound in the driver would result in a
// VREG value under 23 if this test fails.
// E.g. (uint8_t)((8105-3840)/16) -> 10
furi_hal_power_set_battery_charge_voltage_limit(8.105f);
mu_assert_double_eq(4.208, furi_hal_power_get_battery_charge_voltage_limit());
}
MU_TEST_SUITE(test_power_suite) {
MU_RUN_TEST(test_power_charge_voltage_exact);
MU_RUN_TEST(test_power_charge_voltage_floating_imprecision);
MU_RUN_TEST(test_power_charge_voltage_inexact);
MU_RUN_TEST(test_power_charge_voltage_invalid_clamped);
MU_RUN_TEST(test_power_charge_voltage_limit_exact);
MU_RUN_TEST(test_power_charge_voltage_limit_floating_imprecision);
MU_RUN_TEST(test_power_charge_voltage_limit_inexact);
MU_RUN_TEST(test_power_charge_voltage_limit_invalid_clamped);
power_test_deinit();
}

View File

@@ -13,8 +13,8 @@ void power_draw_battery_callback(Canvas* canvas, void* context) {
if(power->info.gauge_is_ok) {
canvas_draw_box(canvas, 2, 2, (power->info.charge + 4) / 5, 4);
if(power->info.voltage_battery_charging < 4.2) {
// Battery charging voltage is modified, indicate with cross pattern
if(power->info.voltage_battery_charge_limit < 4.2) {
// Battery charge voltage limit is modified, indicate with cross pattern
canvas_invert_color(canvas);
uint8_t battery_bar_width = (power->info.charge + 4) / 5;
bool cross_odd = false;
@@ -147,7 +147,7 @@ static bool power_update_info(Power* power) {
info.capacity_full = furi_hal_power_get_battery_full_capacity();
info.current_charger = furi_hal_power_get_battery_current(FuriHalPowerICCharger);
info.current_gauge = furi_hal_power_get_battery_current(FuriHalPowerICFuelGauge);
info.voltage_battery_charging = furi_hal_power_get_battery_charging_voltage();
info.voltage_battery_charge_limit = furi_hal_power_get_battery_charge_voltage_limit();
info.voltage_charger = furi_hal_power_get_battery_voltage(FuriHalPowerICCharger);
info.voltage_gauge = furi_hal_power_get_battery_voltage(FuriHalPowerICFuelGauge);
info.voltage_vbus = furi_hal_power_get_usb_voltage();

View File

@@ -41,7 +41,7 @@ typedef struct {
float current_charger;
float current_gauge;
float voltage_battery_charging;
float voltage_battery_charge_limit;
float voltage_charger;
float voltage_gauge;
float voltage_vbus;

View File

@@ -7,7 +7,7 @@ static void power_settings_scene_battery_info_update_model(PowerSettingsApp* app
.gauge_voltage = app->info.voltage_gauge,
.gauge_current = app->info.current_gauge,
.gauge_temperature = app->info.temperature_gauge,
.charging_voltage = app->info.voltage_battery_charging,
.charge_voltage_limit = app->info.voltage_battery_charge_limit,
.charge = app->info.charge,
.health = app->info.health,
};

View File

@@ -69,7 +69,7 @@ static void draw_battery(Canvas* canvas, BatteryInfoModel* data, int x, int y) {
drain_current > HIGH_DRAIN_CURRENT_THRESHOLD ? "mA!" : "mA");
} else if(drain_current != 0) {
snprintf(header, 20, "...");
} else if(data->charging_voltage < 4.2) {
} else if(data->charge_voltage_limit < 4.2) {
// Non-default battery charging limit, mention it
snprintf(emote, sizeof(emote), "Charged!");
snprintf(header, sizeof(header), "Limited to");
@@ -77,8 +77,8 @@ static void draw_battery(Canvas* canvas, BatteryInfoModel* data, int x, int y) {
value,
sizeof(value),
"%lu.%luV",
(uint32_t)(data->charging_voltage),
(uint32_t)(data->charging_voltage * 10) % 10);
(uint32_t)(data->charge_voltage_limit),
(uint32_t)(data->charge_voltage_limit * 10) % 10);
} else {
snprintf(header, sizeof(header), "Charged!");
}

View File

@@ -9,7 +9,7 @@ typedef struct {
float gauge_voltage;
float gauge_current;
float gauge_temperature;
float charging_voltage;
float charge_voltage_limit;
uint8_t charge;
uint8_t health;
} BatteryInfoModel;