mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-13 12:28:36 -07:00
Merge branch 'fz-dev' into dev
This commit is contained in:
@@ -3,56 +3,63 @@
|
|||||||
#include "../minunit.h"
|
#include "../minunit.h"
|
||||||
|
|
||||||
static void power_test_deinit(void) {
|
static void power_test_deinit(void) {
|
||||||
// Try to reset to default charging voltage
|
// Try to reset to default charge voltage limit
|
||||||
furi_hal_power_set_battery_charging_voltage(4.208f);
|
furi_hal_power_set_battery_charge_voltage_limit(4.208f);
|
||||||
}
|
}
|
||||||
|
|
||||||
MU_TEST(test_power_charge_voltage_exact) {
|
MU_TEST(test_power_charge_voltage_limit_exact) {
|
||||||
// Power of 16mV charge voltages get applied exactly
|
// Power of 16mV charge voltage limits get applied exactly
|
||||||
// (bq25896 charge controller works in 16mV increments)
|
// (bq25896 charge controller works in 16mV increments)
|
||||||
//
|
//
|
||||||
// This test may need adapted if other charge controllers are used in the future.
|
// 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) {
|
for(uint16_t charge_mv = 3840; charge_mv <= 4208; charge_mv += 16) {
|
||||||
float charge_volt = (float)charge_mv / 1000.0f;
|
float charge_volt = (float)charge_mv / 1000.0f;
|
||||||
furi_hal_power_set_battery_charging_voltage(charge_volt);
|
furi_hal_power_set_battery_charge_voltage_limit(charge_volt);
|
||||||
mu_assert_double_eq(charge_volt, furi_hal_power_get_battery_charging_voltage());
|
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
|
// 4.016f should act as 4.016 V, even with floating point imprecision
|
||||||
furi_hal_power_set_battery_charging_voltage(4.016f);
|
furi_hal_power_set_battery_charge_voltage_limit(4.016f);
|
||||||
mu_assert_double_eq(4.016f, furi_hal_power_get_battery_charging_voltage());
|
mu_assert_double_eq(4.016f, furi_hal_power_get_battery_charge_voltage_limit());
|
||||||
}
|
}
|
||||||
|
|
||||||
MU_TEST(test_power_charge_voltage_inexact) {
|
MU_TEST(test_power_charge_voltage_limit_inexact) {
|
||||||
// Charge voltages that are not power of 16mV get truncated down
|
// Charge voltage limits that are not power of 16mV get truncated down
|
||||||
furi_hal_power_set_battery_charging_voltage(3.841f);
|
furi_hal_power_set_battery_charge_voltage_limit(3.841f);
|
||||||
mu_assert_double_eq(3.840, furi_hal_power_get_battery_charging_voltage());
|
mu_assert_double_eq(3.840, furi_hal_power_get_battery_charge_voltage_limit());
|
||||||
|
|
||||||
furi_hal_power_set_battery_charging_voltage(3.900f);
|
furi_hal_power_set_battery_charge_voltage_limit(3.900f);
|
||||||
mu_assert_double_eq(3.888, furi_hal_power_get_battery_charging_voltage());
|
mu_assert_double_eq(3.888, furi_hal_power_get_battery_charge_voltage_limit());
|
||||||
|
|
||||||
furi_hal_power_set_battery_charging_voltage(4.200f);
|
furi_hal_power_set_battery_charge_voltage_limit(4.200f);
|
||||||
mu_assert_double_eq(4.192, furi_hal_power_get_battery_charging_voltage());
|
mu_assert_double_eq(4.192, furi_hal_power_get_battery_charge_voltage_limit());
|
||||||
}
|
}
|
||||||
|
|
||||||
MU_TEST(test_power_charge_voltage_invalid_clamped) {
|
MU_TEST(test_power_charge_voltage_limit_invalid_clamped) {
|
||||||
// Out-of-range charge voltages get clamped to 3.840 V and 4.208 V
|
// Out-of-range charge voltage limits get clamped to 3.840 V and 4.208 V
|
||||||
furi_hal_power_set_battery_charging_voltage(3.808f);
|
furi_hal_power_set_battery_charge_voltage_limit(3.808f);
|
||||||
mu_assert_double_eq(3.840, furi_hal_power_get_battery_charging_voltage());
|
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
|
// NOTE: Intentionally picking a small increment above 4.208 V to reduce the risk of an
|
||||||
// unhappy battery if this fails.
|
// unhappy battery if this fails.
|
||||||
furi_hal_power_set_battery_charging_voltage(4.240f);
|
furi_hal_power_set_battery_charge_voltage_limit(4.240f);
|
||||||
mu_assert_double_eq(4.208, furi_hal_power_get_battery_charging_voltage());
|
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_TEST_SUITE(test_power_suite) {
|
||||||
MU_RUN_TEST(test_power_charge_voltage_exact);
|
MU_RUN_TEST(test_power_charge_voltage_limit_exact);
|
||||||
MU_RUN_TEST(test_power_charge_voltage_floating_imprecision);
|
MU_RUN_TEST(test_power_charge_voltage_limit_floating_imprecision);
|
||||||
MU_RUN_TEST(test_power_charge_voltage_inexact);
|
MU_RUN_TEST(test_power_charge_voltage_limit_inexact);
|
||||||
MU_RUN_TEST(test_power_charge_voltage_invalid_clamped);
|
MU_RUN_TEST(test_power_charge_voltage_limit_invalid_clamped);
|
||||||
power_test_deinit();
|
power_test_deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -373,7 +373,7 @@ int32_t bt_srv(void* p) {
|
|||||||
Bt* bt = bt_alloc();
|
Bt* bt = bt_alloc();
|
||||||
|
|
||||||
if(furi_hal_rtc_get_boot_mode() != FuriHalRtcBootModeNormal) {
|
if(furi_hal_rtc_get_boot_mode() != FuriHalRtcBootModeNormal) {
|
||||||
FURI_LOG_W(TAG, "Skipped BT init: device in special startup mode");
|
FURI_LOG_W(TAG, "Skipping start in special boot mode");
|
||||||
ble_glue_wait_for_c2_start(FURI_HAL_BT_C2_START_TIMEOUT);
|
ble_glue_wait_for_c2_start(FURI_HAL_BT_C2_START_TIMEOUT);
|
||||||
furi_record_create(RECORD_BT, bt);
|
furi_record_create(RECORD_BT, bt);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -461,7 +461,7 @@ int32_t cli_srv(void* p) {
|
|||||||
if(furi_hal_rtc_get_boot_mode() == FuriHalRtcBootModeNormal) {
|
if(furi_hal_rtc_get_boot_mode() == FuriHalRtcBootModeNormal) {
|
||||||
cli_session_open(cli, &cli_vcp);
|
cli_session_open(cli, &cli_vcp);
|
||||||
} else {
|
} else {
|
||||||
FURI_LOG_W(TAG, "Skipped CLI session open: device in special startup mode");
|
FURI_LOG_W(TAG, "Skipping start in special boot mode");
|
||||||
}
|
}
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
|
|||||||
@@ -12,20 +12,42 @@
|
|||||||
// Close to ISO, `date +'%Y-%m-%d %H:%M:%S %u'`
|
// Close to ISO, `date +'%Y-%m-%d %H:%M:%S %u'`
|
||||||
#define CLI_DATE_FORMAT "%.4d-%.2d-%.2d %.2d:%.2d:%.2d %d"
|
#define CLI_DATE_FORMAT "%.4d-%.2d-%.2d %.2d:%.2d:%.2d %d"
|
||||||
|
|
||||||
void cli_command_device_info_callback(const char* key, const char* value, bool last, void* context) {
|
void cli_command_info_callback(const char* key, const char* value, bool last, void* context) {
|
||||||
UNUSED(context);
|
|
||||||
UNUSED(last);
|
UNUSED(last);
|
||||||
|
UNUSED(context);
|
||||||
printf("%-30s: %s\r\n", key, value);
|
printf("%-30s: %s\r\n", key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/** Info Command
|
||||||
* Device Info Command
|
*
|
||||||
* This command is intended to be used by humans
|
* This command is intended to be used by humans
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* - device - print device info
|
||||||
|
* - power - print power info
|
||||||
|
* - power_debug - print power debug info
|
||||||
|
*
|
||||||
|
* @param cli The cli instance
|
||||||
|
* @param args The arguments
|
||||||
|
* @param context The context
|
||||||
*/
|
*/
|
||||||
void cli_command_device_info(Cli* cli, FuriString* args, void* context) {
|
void cli_command_info(Cli* cli, FuriString* args, void* context) {
|
||||||
UNUSED(cli);
|
UNUSED(cli);
|
||||||
UNUSED(args);
|
|
||||||
furi_hal_info_get(cli_command_device_info_callback, '_', context);
|
if(context) {
|
||||||
|
furi_hal_info_get(cli_command_info_callback, '_', NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!furi_string_cmp(args, "device")) {
|
||||||
|
furi_hal_info_get(cli_command_info_callback, '.', NULL);
|
||||||
|
} else if(!furi_string_cmp(args, "power")) {
|
||||||
|
furi_hal_power_info_get(cli_command_info_callback, '.', NULL);
|
||||||
|
} else if(!furi_string_cmp(args, "power_debug")) {
|
||||||
|
furi_hal_power_debug_get(cli_command_info_callback, NULL);
|
||||||
|
} else {
|
||||||
|
cli_print_usage("info", "<device|power|power_debug>", furi_string_get_cstr(args));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cli_command_help(Cli* cli, FuriString* args, void* context) {
|
void cli_command_help(Cli* cli, FuriString* args, void* context) {
|
||||||
@@ -420,9 +442,9 @@ void cli_command_i2c(Cli* cli, FuriString* args, void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cli_commands_init(Cli* cli) {
|
void cli_commands_init(Cli* cli) {
|
||||||
cli_add_command(cli, "!", CliCommandFlagParallelSafe, cli_command_device_info, NULL);
|
cli_add_command(cli, "!", CliCommandFlagParallelSafe, cli_command_info, (void*)true);
|
||||||
cli_add_command(cli, "device_info", CliCommandFlagParallelSafe, cli_command_device_info, NULL);
|
cli_add_command(cli, "info", CliCommandFlagParallelSafe, cli_command_info, NULL);
|
||||||
cli_add_command(cli, "src", CliCommandFlagParallelSafe, cli_command_src, NULL);
|
cli_add_command(cli, "device_info", CliCommandFlagParallelSafe, cli_command_info, (void*)true);
|
||||||
cli_add_command(cli, "source", CliCommandFlagParallelSafe, cli_command_src, NULL);
|
cli_add_command(cli, "source", CliCommandFlagParallelSafe, cli_command_src, NULL);
|
||||||
|
|
||||||
cli_add_command(cli, "?", CliCommandFlagParallelSafe, cli_command_help, NULL);
|
cli_add_command(cli, "?", CliCommandFlagParallelSafe, cli_command_help, NULL);
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
#include "helpers/pin_lock.h"
|
#include "helpers/pin_lock.h"
|
||||||
#include "helpers/slideshow_filename.h"
|
#include "helpers/slideshow_filename.h"
|
||||||
|
|
||||||
|
#define TAG "Desktop"
|
||||||
|
|
||||||
static void desktop_auto_lock_arm(Desktop*);
|
static void desktop_auto_lock_arm(Desktop*);
|
||||||
static void desktop_auto_lock_inhibit(Desktop*);
|
static void desktop_auto_lock_inhibit(Desktop*);
|
||||||
static void desktop_start_auto_lock_timer(Desktop*);
|
static void desktop_start_auto_lock_timer(Desktop*);
|
||||||
@@ -324,6 +326,12 @@ static bool desktop_check_file_flag(const char* flag_path) {
|
|||||||
|
|
||||||
int32_t desktop_srv(void* p) {
|
int32_t desktop_srv(void* p) {
|
||||||
UNUSED(p);
|
UNUSED(p);
|
||||||
|
|
||||||
|
if(furi_hal_rtc_get_boot_mode() != FuriHalRtcBootModeNormal) {
|
||||||
|
FURI_LOG_W(TAG, "Skipping start in special boot mode");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Desktop* desktop = desktop_alloc();
|
Desktop* desktop = desktop_alloc();
|
||||||
|
|
||||||
bool loaded = DESKTOP_SETTINGS_LOAD(&desktop->settings);
|
bool loaded = DESKTOP_SETTINGS_LOAD(&desktop->settings);
|
||||||
|
|||||||
@@ -154,6 +154,12 @@ static void dolphin_update_clear_limits_timer_period(Dolphin* dolphin) {
|
|||||||
|
|
||||||
int32_t dolphin_srv(void* p) {
|
int32_t dolphin_srv(void* p) {
|
||||||
UNUSED(p);
|
UNUSED(p);
|
||||||
|
|
||||||
|
if(furi_hal_rtc_get_boot_mode() != FuriHalRtcBootModeNormal) {
|
||||||
|
FURI_LOG_W(TAG, "Skipping start in special boot mode");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Dolphin* dolphin = dolphin_alloc();
|
Dolphin* dolphin = dolphin_alloc();
|
||||||
furi_record_create(RECORD_DOLPHIN, dolphin);
|
furi_record_create(RECORD_DOLPHIN, dolphin);
|
||||||
|
|
||||||
|
|||||||
@@ -26,24 +26,6 @@ void power_cli_reboot2dfu(Cli* cli, FuriString* args) {
|
|||||||
power_reboot(PowerBootModeDfu);
|
power_reboot(PowerBootModeDfu);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void power_cli_callback(const char* key, const char* value, bool last, void* context) {
|
|
||||||
UNUSED(last);
|
|
||||||
UNUSED(context);
|
|
||||||
printf("%-24s: %s\r\n", key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void power_cli_info(Cli* cli, FuriString* args) {
|
|
||||||
UNUSED(cli);
|
|
||||||
UNUSED(args);
|
|
||||||
furi_hal_power_info_get(power_cli_callback, '_', NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void power_cli_debug(Cli* cli, FuriString* args) {
|
|
||||||
UNUSED(cli);
|
|
||||||
UNUSED(args);
|
|
||||||
furi_hal_power_debug_get(power_cli_callback, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void power_cli_5v(Cli* cli, FuriString* args) {
|
void power_cli_5v(Cli* cli, FuriString* args) {
|
||||||
UNUSED(cli);
|
UNUSED(cli);
|
||||||
if(!furi_string_cmp(args, "0")) {
|
if(!furi_string_cmp(args, "0")) {
|
||||||
@@ -74,8 +56,6 @@ static void power_cli_command_print_usage() {
|
|||||||
printf("\toff\t - shutdown power\r\n");
|
printf("\toff\t - shutdown power\r\n");
|
||||||
printf("\treboot\t - reboot\r\n");
|
printf("\treboot\t - reboot\r\n");
|
||||||
printf("\treboot2dfu\t - reboot to dfu bootloader\r\n");
|
printf("\treboot2dfu\t - reboot to dfu bootloader\r\n");
|
||||||
printf("\tinfo\t - show power info\r\n");
|
|
||||||
printf("\tdebug\t - show debug information\r\n");
|
|
||||||
printf("\t5v <0 or 1>\t - enable or disable 5v ext\r\n");
|
printf("\t5v <0 or 1>\t - enable or disable 5v ext\r\n");
|
||||||
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
|
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
|
||||||
printf("\t3v3 <0 or 1>\t - enable or disable 3v3 ext\r\n");
|
printf("\t3v3 <0 or 1>\t - enable or disable 3v3 ext\r\n");
|
||||||
@@ -108,16 +88,6 @@ void power_cli(Cli* cli, FuriString* args, void* context) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(furi_string_cmp_str(cmd, "info") == 0) {
|
|
||||||
power_cli_info(cli, args);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(furi_string_cmp_str(cmd, "debug") == 0) {
|
|
||||||
power_cli_debug(cli, args);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(furi_string_cmp_str(cmd, "5v") == 0) {
|
if(furi_string_cmp_str(cmd, "5v") == 0) {
|
||||||
power_cli_5v(cli, args);
|
power_cli_5v(cli, args);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <furi_hal.h>
|
#include <furi_hal.h>
|
||||||
|
|
||||||
#define POWER_OFF_TIMEOUT 90
|
#define POWER_OFF_TIMEOUT 90
|
||||||
|
#define TAG "Power"
|
||||||
|
|
||||||
void power_draw_battery_callback(Canvas* canvas, void* context) {
|
void power_draw_battery_callback(Canvas* canvas, void* context) {
|
||||||
furi_assert(context);
|
furi_assert(context);
|
||||||
@@ -62,7 +63,7 @@ void power_draw_battery_callback(Canvas* canvas, void* context) {
|
|||||||
} else if(
|
} else if(
|
||||||
(power->displayBatteryPercentage == DISPLAY_BATTERY_BAR_PERCENT) &&
|
(power->displayBatteryPercentage == DISPLAY_BATTERY_BAR_PERCENT) &&
|
||||||
(power->state != PowerStateCharging) && // Default bar display with percentage
|
(power->state != PowerStateCharging) && // Default bar display with percentage
|
||||||
(power->info.voltage_battery_charging >=
|
(power->info.voltage_battery_charge_limit >=
|
||||||
4.2)) { // not looking nice with low voltage indicator
|
4.2)) { // not looking nice with low voltage indicator
|
||||||
canvas_set_font(canvas, FontBatteryPercent);
|
canvas_set_font(canvas, FontBatteryPercent);
|
||||||
|
|
||||||
@@ -117,7 +118,7 @@ void power_draw_battery_callback(Canvas* canvas, void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Verify if it displays correctly with custom battery skins !!!
|
// TODO: Verify if it displays correctly with custom battery skins !!!
|
||||||
if(power->info.voltage_battery_charging < 4.2) {
|
if(power->info.voltage_battery_charge_limit < 4.2) {
|
||||||
// Battery charging voltage is modified, indicate with cross pattern
|
// Battery charging voltage is modified, indicate with cross pattern
|
||||||
canvas_invert_color(canvas);
|
canvas_invert_color(canvas);
|
||||||
uint8_t battery_bar_width = (power->info.charge + 4) / 5;
|
uint8_t battery_bar_width = (power->info.charge + 4) / 5;
|
||||||
@@ -329,7 +330,7 @@ static bool power_update_info(Power* power) {
|
|||||||
info.capacity_full = furi_hal_power_get_battery_full_capacity();
|
info.capacity_full = furi_hal_power_get_battery_full_capacity();
|
||||||
info.current_charger = furi_hal_power_get_battery_current(FuriHalPowerICCharger);
|
info.current_charger = furi_hal_power_get_battery_current(FuriHalPowerICCharger);
|
||||||
info.current_gauge = furi_hal_power_get_battery_current(FuriHalPowerICFuelGauge);
|
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_charger = furi_hal_power_get_battery_voltage(FuriHalPowerICCharger);
|
||||||
info.voltage_gauge = furi_hal_power_get_battery_voltage(FuriHalPowerICFuelGauge);
|
info.voltage_gauge = furi_hal_power_get_battery_voltage(FuriHalPowerICFuelGauge);
|
||||||
info.voltage_vbus = furi_hal_power_get_usb_voltage();
|
info.voltage_vbus = furi_hal_power_get_usb_voltage();
|
||||||
@@ -400,6 +401,12 @@ static void power_check_battery_level_change(Power* power) {
|
|||||||
|
|
||||||
int32_t power_srv(void* p) {
|
int32_t power_srv(void* p) {
|
||||||
UNUSED(p);
|
UNUSED(p);
|
||||||
|
|
||||||
|
if(furi_hal_rtc_get_boot_mode() != FuriHalRtcBootModeNormal) {
|
||||||
|
FURI_LOG_W(TAG, "Skipping start in special boot mode");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Power* power = power_alloc();
|
Power* power = power_alloc();
|
||||||
power_update_info(power);
|
power_update_info(power);
|
||||||
furi_record_create(RECORD_POWER, power);
|
furi_record_create(RECORD_POWER, power);
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ typedef struct {
|
|||||||
float current_charger;
|
float current_charger;
|
||||||
float current_gauge;
|
float current_gauge;
|
||||||
|
|
||||||
float voltage_battery_charging;
|
float voltage_battery_charge_limit;
|
||||||
float voltage_charger;
|
float voltage_charger;
|
||||||
float voltage_gauge;
|
float voltage_gauge;
|
||||||
float voltage_vbus;
|
float voltage_vbus;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ static void power_settings_scene_battery_info_update_model(PowerSettingsApp* app
|
|||||||
.gauge_voltage = app->info.voltage_gauge,
|
.gauge_voltage = app->info.voltage_gauge,
|
||||||
.gauge_current = app->info.current_gauge,
|
.gauge_current = app->info.current_gauge,
|
||||||
.gauge_temperature = app->info.temperature_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,
|
.charge = app->info.charge,
|
||||||
.health = app->info.health,
|
.health = app->info.health,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ static void draw_battery(Canvas* canvas, BatteryInfoModel* data, int x, int y) {
|
|||||||
drain_current > HIGH_DRAIN_CURRENT_THRESHOLD ? "mA!" : "mA");
|
drain_current > HIGH_DRAIN_CURRENT_THRESHOLD ? "mA!" : "mA");
|
||||||
} else if(drain_current != 0) {
|
} else if(drain_current != 0) {
|
||||||
snprintf(header, 20, "...");
|
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
|
// Non-default battery charging limit, mention it
|
||||||
snprintf(emote, sizeof(emote), "Charged!");
|
snprintf(emote, sizeof(emote), "Charged!");
|
||||||
snprintf(header, sizeof(header), "Limited to");
|
snprintf(header, sizeof(header), "Limited to");
|
||||||
@@ -77,8 +77,8 @@ static void draw_battery(Canvas* canvas, BatteryInfoModel* data, int x, int y) {
|
|||||||
value,
|
value,
|
||||||
sizeof(value),
|
sizeof(value),
|
||||||
"%lu.%luV",
|
"%lu.%luV",
|
||||||
(uint32_t)(data->charging_voltage),
|
(uint32_t)(data->charge_voltage_limit),
|
||||||
(uint32_t)(data->charging_voltage * 10) % 10);
|
(uint32_t)(data->charge_voltage_limit * 10) % 10);
|
||||||
} else {
|
} else {
|
||||||
snprintf(header, sizeof(header), "Charged!");
|
snprintf(header, sizeof(header), "Charged!");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ typedef struct {
|
|||||||
float gauge_voltage;
|
float gauge_voltage;
|
||||||
float gauge_current;
|
float gauge_current;
|
||||||
float gauge_temperature;
|
float gauge_temperature;
|
||||||
float charging_voltage;
|
float charge_voltage_limit;
|
||||||
uint8_t charge;
|
uint8_t charge;
|
||||||
uint8_t health;
|
uint8_t health;
|
||||||
} BatteryInfoModel;
|
} BatteryInfoModel;
|
||||||
|
|||||||
@@ -97,7 +97,16 @@ static void update_task_cleanup_resources(UpdateTask* update_task, const uint32_
|
|||||||
path_concat(
|
path_concat(
|
||||||
STORAGE_EXT_PATH_PREFIX, furi_string_get_cstr(entry_ptr->name), file_path);
|
STORAGE_EXT_PATH_PREFIX, furi_string_get_cstr(entry_ptr->name), file_path);
|
||||||
FURI_LOG_D(TAG, "Removing %s", furi_string_get_cstr(file_path));
|
FURI_LOG_D(TAG, "Removing %s", furi_string_get_cstr(file_path));
|
||||||
storage_simply_remove(update_task->storage, furi_string_get_cstr(file_path));
|
|
||||||
|
FS_Error result =
|
||||||
|
storage_common_remove(update_task->storage, furi_string_get_cstr(file_path));
|
||||||
|
if(result != FSE_OK && result != FSE_EXIST) {
|
||||||
|
FURI_LOG_E(
|
||||||
|
TAG,
|
||||||
|
"%s remove failed, cause %s",
|
||||||
|
furi_string_get_cstr(file_path),
|
||||||
|
storage_error_get_desc(result));
|
||||||
|
}
|
||||||
furi_string_free(file_path);
|
furi_string_free(file_path);
|
||||||
} else if(entry_ptr->type == ResourceManifestEntryTypeDirectory) {
|
} else if(entry_ptr->type == ResourceManifestEntryTypeDirectory) {
|
||||||
n_dir_entries++;
|
n_dir_entries++;
|
||||||
@@ -116,7 +125,6 @@ static void update_task_cleanup_resources(UpdateTask* update_task, const uint32_
|
|||||||
n_dir_entries);
|
n_dir_entries);
|
||||||
|
|
||||||
FuriString* folder_path = furi_string_alloc();
|
FuriString* folder_path = furi_string_alloc();
|
||||||
File* folder_file = storage_file_alloc(update_task->storage);
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
path_concat(
|
path_concat(
|
||||||
@@ -125,24 +133,17 @@ static void update_task_cleanup_resources(UpdateTask* update_task, const uint32_
|
|||||||
folder_path);
|
folder_path);
|
||||||
|
|
||||||
FURI_LOG_D(TAG, "Removing folder %s", furi_string_get_cstr(folder_path));
|
FURI_LOG_D(TAG, "Removing folder %s", furi_string_get_cstr(folder_path));
|
||||||
if(!storage_dir_open(folder_file, furi_string_get_cstr(folder_path))) {
|
FS_Error result = storage_common_remove(
|
||||||
FURI_LOG_W(
|
update_task->storage, furi_string_get_cstr(folder_path));
|
||||||
|
if(result != FSE_OK && result != FSE_EXIST) {
|
||||||
|
FURI_LOG_E(
|
||||||
TAG,
|
TAG,
|
||||||
"%s can't be opened, skipping",
|
"%s remove failed, cause %s",
|
||||||
furi_string_get_cstr(folder_path));
|
furi_string_get_cstr(folder_path),
|
||||||
break;
|
storage_error_get_desc(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(storage_dir_read(folder_file, NULL, NULL, 0)) {
|
|
||||||
FURI_LOG_I(
|
|
||||||
TAG, "%s is not empty, skipping", furi_string_get_cstr(folder_path));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
storage_simply_remove(update_task->storage, furi_string_get_cstr(folder_path));
|
|
||||||
} while(false);
|
} while(false);
|
||||||
|
|
||||||
storage_file_free(folder_file);
|
|
||||||
furi_string_free(folder_path);
|
furi_string_free(folder_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
entry,status,name,type,params
|
entry,status,name,type,params
|
||||||
Version,+,14.0,,
|
Version,+,15.0,,
|
||||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||||
Header,+,applications/services/cli/cli.h,,
|
Header,+,applications/services/cli/cli.h,,
|
||||||
Header,+,applications/services/cli/cli_vcp.h,,
|
Header,+,applications/services/cli/cli_vcp.h,,
|
||||||
@@ -979,7 +979,7 @@ Function,+,furi_hal_power_enable_external_3_3v,void,
|
|||||||
Function,+,furi_hal_power_enable_otg,void,
|
Function,+,furi_hal_power_enable_otg,void,
|
||||||
Function,+,furi_hal_power_gauge_is_ok,_Bool,
|
Function,+,furi_hal_power_gauge_is_ok,_Bool,
|
||||||
Function,+,furi_hal_power_get_bat_health_pct,uint8_t,
|
Function,+,furi_hal_power_get_bat_health_pct,uint8_t,
|
||||||
Function,+,furi_hal_power_get_battery_charging_voltage,float,
|
Function,+,furi_hal_power_get_battery_charge_voltage_limit,float,
|
||||||
Function,+,furi_hal_power_get_battery_current,float,FuriHalPowerIC
|
Function,+,furi_hal_power_get_battery_current,float,FuriHalPowerIC
|
||||||
Function,+,furi_hal_power_get_battery_design_capacity,uint32_t,
|
Function,+,furi_hal_power_get_battery_design_capacity,uint32_t,
|
||||||
Function,+,furi_hal_power_get_battery_full_capacity,uint32_t,
|
Function,+,furi_hal_power_get_battery_full_capacity,uint32_t,
|
||||||
@@ -998,7 +998,7 @@ Function,+,furi_hal_power_is_charging_done,_Bool,
|
|||||||
Function,+,furi_hal_power_is_otg_enabled,_Bool,
|
Function,+,furi_hal_power_is_otg_enabled,_Bool,
|
||||||
Function,+,furi_hal_power_off,void,
|
Function,+,furi_hal_power_off,void,
|
||||||
Function,+,furi_hal_power_reset,void,
|
Function,+,furi_hal_power_reset,void,
|
||||||
Function,+,furi_hal_power_set_battery_charging_voltage,void,float
|
Function,+,furi_hal_power_set_battery_charge_voltage_limit,void,float
|
||||||
Function,+,furi_hal_power_shutdown,void,
|
Function,+,furi_hal_power_shutdown,void,
|
||||||
Function,+,furi_hal_power_sleep,void,
|
Function,+,furi_hal_power_sleep,void,
|
||||||
Function,+,furi_hal_power_sleep_available,_Bool,
|
Function,+,furi_hal_power_sleep_available,_Bool,
|
||||||
|
|||||||
|
@@ -1,5 +1,5 @@
|
|||||||
entry,status,name,type,params
|
entry,status,name,type,params
|
||||||
Version,+,14.1,,
|
Version,+,15.0,,
|
||||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||||
Header,+,applications/services/cli/cli.h,,
|
Header,+,applications/services/cli/cli.h,,
|
||||||
Header,+,applications/services/cli/cli_vcp.h,,
|
Header,+,applications/services/cli/cli_vcp.h,,
|
||||||
@@ -1233,7 +1233,7 @@ Function,+,furi_hal_power_enable_external_3_3v,void,
|
|||||||
Function,+,furi_hal_power_enable_otg,void,
|
Function,+,furi_hal_power_enable_otg,void,
|
||||||
Function,+,furi_hal_power_gauge_is_ok,_Bool,
|
Function,+,furi_hal_power_gauge_is_ok,_Bool,
|
||||||
Function,+,furi_hal_power_get_bat_health_pct,uint8_t,
|
Function,+,furi_hal_power_get_bat_health_pct,uint8_t,
|
||||||
Function,+,furi_hal_power_get_battery_charging_voltage,float,
|
Function,+,furi_hal_power_get_battery_charge_voltage_limit,float,
|
||||||
Function,+,furi_hal_power_get_battery_current,float,FuriHalPowerIC
|
Function,+,furi_hal_power_get_battery_current,float,FuriHalPowerIC
|
||||||
Function,+,furi_hal_power_get_battery_design_capacity,uint32_t,
|
Function,+,furi_hal_power_get_battery_design_capacity,uint32_t,
|
||||||
Function,+,furi_hal_power_get_battery_full_capacity,uint32_t,
|
Function,+,furi_hal_power_get_battery_full_capacity,uint32_t,
|
||||||
@@ -1252,7 +1252,7 @@ Function,+,furi_hal_power_is_charging_done,_Bool,
|
|||||||
Function,+,furi_hal_power_is_otg_enabled,_Bool,
|
Function,+,furi_hal_power_is_otg_enabled,_Bool,
|
||||||
Function,+,furi_hal_power_off,void,
|
Function,+,furi_hal_power_off,void,
|
||||||
Function,+,furi_hal_power_reset,void,
|
Function,+,furi_hal_power_reset,void,
|
||||||
Function,+,furi_hal_power_set_battery_charging_voltage,void,float
|
Function,+,furi_hal_power_set_battery_charge_voltage_limit,void,float
|
||||||
Function,+,furi_hal_power_shutdown,void,
|
Function,+,furi_hal_power_shutdown,void,
|
||||||
Function,+,furi_hal_power_sleep,void,
|
Function,+,furi_hal_power_sleep,void,
|
||||||
Function,+,furi_hal_power_sleep_available,_Bool,
|
Function,+,furi_hal_power_sleep_available,_Bool,
|
||||||
|
|||||||
|
@@ -341,14 +341,14 @@ bool furi_hal_power_is_otg_enabled() {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
float furi_hal_power_get_battery_charging_voltage() {
|
float furi_hal_power_get_battery_charge_voltage_limit() {
|
||||||
furi_hal_i2c_acquire(&furi_hal_i2c_handle_power);
|
furi_hal_i2c_acquire(&furi_hal_i2c_handle_power);
|
||||||
float ret = (float)bq25896_get_vreg_voltage(&furi_hal_i2c_handle_power) / 1000.0f;
|
float ret = (float)bq25896_get_vreg_voltage(&furi_hal_i2c_handle_power) / 1000.0f;
|
||||||
furi_hal_i2c_release(&furi_hal_i2c_handle_power);
|
furi_hal_i2c_release(&furi_hal_i2c_handle_power);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_power_set_battery_charging_voltage(float voltage) {
|
void furi_hal_power_set_battery_charge_voltage_limit(float voltage) {
|
||||||
furi_hal_i2c_acquire(&furi_hal_i2c_handle_power);
|
furi_hal_i2c_acquire(&furi_hal_i2c_handle_power);
|
||||||
// Adding 0.0005 is necessary because 4.016f is 4.015999794000, which gets truncated
|
// Adding 0.0005 is necessary because 4.016f is 4.015999794000, which gets truncated
|
||||||
bq25896_set_vreg_voltage(&furi_hal_i2c_handle_power, (uint16_t)(voltage * 1000.0f + 0.0005f));
|
bq25896_set_vreg_voltage(&furi_hal_i2c_handle_power, (uint16_t)(voltage * 1000.0f + 0.0005f));
|
||||||
@@ -486,7 +486,7 @@ void furi_hal_power_info_get(PropertyValueCallback out, char sep, void* context)
|
|||||||
property_value_out(&property_context, NULL, 2, "format", "major", "2");
|
property_value_out(&property_context, NULL, 2, "format", "major", "2");
|
||||||
property_value_out(&property_context, NULL, 2, "format", "minor", "1");
|
property_value_out(&property_context, NULL, 2, "format", "minor", "1");
|
||||||
} else {
|
} else {
|
||||||
property_value_out(&property_context, NULL, 3, "power", "info", "major", "1");
|
property_value_out(&property_context, NULL, 3, "power", "info", "major", "2");
|
||||||
property_value_out(&property_context, NULL, 3, "power", "info", "minor", "1");
|
property_value_out(&property_context, NULL, 3, "power", "info", "minor", "1");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -505,8 +505,10 @@ void furi_hal_power_info_get(PropertyValueCallback out, char sep, void* context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
property_value_out(&property_context, NULL, 2, "charge", "state", charge_state);
|
property_value_out(&property_context, NULL, 2, "charge", "state", charge_state);
|
||||||
uint16_t charge_voltage = (uint16_t)(furi_hal_power_get_battery_charging_voltage() * 1000.f);
|
uint16_t charge_voltage_limit =
|
||||||
property_value_out(&property_context, "%u", 2, "charge", "voltage", charge_voltage);
|
(uint16_t)(furi_hal_power_get_battery_charge_voltage_limit() * 1000.f);
|
||||||
|
property_value_out(
|
||||||
|
&property_context, "%u", 3, "charge", "voltage", "limit", charge_voltage_limit);
|
||||||
uint16_t voltage =
|
uint16_t voltage =
|
||||||
(uint16_t)(furi_hal_power_get_battery_voltage(FuriHalPowerICFuelGauge) * 1000.f);
|
(uint16_t)(furi_hal_power_get_battery_voltage(FuriHalPowerICFuelGauge) * 1000.f);
|
||||||
property_value_out(&property_context, "%u", 2, "battery", "voltage", voltage);
|
property_value_out(&property_context, "%u", 2, "battery", "voltage", voltage);
|
||||||
|
|||||||
@@ -121,21 +121,21 @@ void furi_hal_power_check_otg_status();
|
|||||||
*/
|
*/
|
||||||
bool furi_hal_power_is_otg_enabled();
|
bool furi_hal_power_is_otg_enabled();
|
||||||
|
|
||||||
/** Get battery charging voltage in V
|
/** Get battery charge voltage limit in V
|
||||||
*
|
*
|
||||||
* @return voltage in V
|
* @return voltage in V
|
||||||
*/
|
*/
|
||||||
float furi_hal_power_get_battery_charging_voltage();
|
float furi_hal_power_get_battery_charge_voltage_limit();
|
||||||
|
|
||||||
/** Set battery charging voltage in V
|
/** Set battery charge voltage limit in V
|
||||||
*
|
*
|
||||||
* Invalid values will be clamped to the nearest valid value.
|
* Invalid values will be clamped downward to the nearest valid value.
|
||||||
*
|
*
|
||||||
* @param voltage[in] voltage in V
|
* @param voltage[in] voltage in V
|
||||||
*
|
*
|
||||||
* @return voltage in V
|
* @return voltage in V
|
||||||
*/
|
*/
|
||||||
void furi_hal_power_set_battery_charging_voltage(float voltage);
|
void furi_hal_power_set_battery_charge_voltage_limit(float voltage);
|
||||||
|
|
||||||
/** Get remaining battery battery capacity in mAh
|
/** Get remaining battery battery capacity in mAh
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -96,9 +96,9 @@ static void furi_thread_body(void* context) {
|
|||||||
furi_assert(thread->state == FuriThreadStateRunning);
|
furi_assert(thread->state == FuriThreadStateRunning);
|
||||||
|
|
||||||
if(thread->is_service) {
|
if(thread->is_service) {
|
||||||
FURI_LOG_E(
|
FURI_LOG_W(
|
||||||
TAG,
|
TAG,
|
||||||
"%s service thread exited. Thread memory cannot be reclaimed.",
|
"%s service thread TCB memory will not be reclaimed",
|
||||||
thread->name ? thread->name : "<unknown service>");
|
thread->name ? thread->name : "<unknown service>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
#include <furi_hal_version.h>
|
#include <furi_hal_version.h>
|
||||||
#include <furi_hal_memory.h>
|
#include <furi_hal_memory.h>
|
||||||
|
#include <furi_hal_rtc.h>
|
||||||
|
|
||||||
#define TAG "Flipper"
|
#define TAG "Flipper"
|
||||||
|
|
||||||
@@ -29,10 +30,10 @@ static void flipper_print_version(const char* target, const Version* version) {
|
|||||||
void flipper_init() {
|
void flipper_init() {
|
||||||
flipper_print_version("Firmware", furi_hal_version_get_firmware_version());
|
flipper_print_version("Firmware", furi_hal_version_get_firmware_version());
|
||||||
|
|
||||||
FURI_LOG_I(TAG, "starting services");
|
FURI_LOG_I(TAG, "Boot mode %d, starting services", furi_hal_rtc_get_boot_mode());
|
||||||
|
|
||||||
for(size_t i = 0; i < FLIPPER_SERVICES_COUNT; i++) {
|
for(size_t i = 0; i < FLIPPER_SERVICES_COUNT; i++) {
|
||||||
FURI_LOG_I(TAG, "starting service %s", FLIPPER_SERVICES[i].name);
|
FURI_LOG_I(TAG, "Starting service %s", FLIPPER_SERVICES[i].name);
|
||||||
|
|
||||||
FuriThread* thread = furi_thread_alloc_ex(
|
FuriThread* thread = furi_thread_alloc_ex(
|
||||||
FLIPPER_SERVICES[i].name,
|
FLIPPER_SERVICES[i].name,
|
||||||
@@ -44,7 +45,7 @@ void flipper_init() {
|
|||||||
furi_thread_start(thread);
|
furi_thread_start(thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
FURI_LOG_I(TAG, "services startup complete");
|
FURI_LOG_I(TAG, "Startup complete");
|
||||||
}
|
}
|
||||||
|
|
||||||
void vApplicationGetIdleTaskMemory(
|
void vApplicationGetIdleTaskMemory(
|
||||||
|
|||||||
@@ -140,19 +140,16 @@ uint16_t bq25896_get_vreg_voltage(FuriHalI2cBusHandle* handle) {
|
|||||||
|
|
||||||
void bq25896_set_vreg_voltage(FuriHalI2cBusHandle* handle, uint16_t vreg_voltage) {
|
void bq25896_set_vreg_voltage(FuriHalI2cBusHandle* handle, uint16_t vreg_voltage) {
|
||||||
if(vreg_voltage < 3840) {
|
if(vreg_voltage < 3840) {
|
||||||
// Minimum value is 3840 mV
|
// Minimum valid value is 3840 mV
|
||||||
bq25896_regs.r06.VREG = 0;
|
vreg_voltage = 3840;
|
||||||
} else {
|
} else if(vreg_voltage > 4208) {
|
||||||
// Find the nearest voltage value (subtract offset, divide into sections)
|
// Maximum safe value is 4208 mV
|
||||||
// Values are truncated downward as needed (e.g. 4200mV -> 4192 mV)
|
vreg_voltage = 4208;
|
||||||
bq25896_regs.r06.VREG = (uint8_t)((vreg_voltage - 3840) / 16);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not allow values above 23 (0x17, 4208mV)
|
// Find the nearest voltage value (subtract offset, divide into sections)
|
||||||
// Exceeding 4.2v will overcharge the battery!
|
// Values are truncated downward as needed (e.g. 4200mV -> 4192 mV)
|
||||||
if(bq25896_regs.r06.VREG > 23) {
|
bq25896_regs.r06.VREG = (uint8_t)((vreg_voltage - 3840) / 16);
|
||||||
bq25896_regs.r06.VREG = 23;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply changes
|
// Apply changes
|
||||||
furi_hal_i2c_write_reg_8(
|
furi_hal_i2c_write_reg_8(
|
||||||
|
|||||||
@@ -36,10 +36,10 @@ void bq25896_disable_otg(FuriHalI2cBusHandle* handle);
|
|||||||
/** Is otg enabled */
|
/** Is otg enabled */
|
||||||
bool bq25896_is_otg_enabled(FuriHalI2cBusHandle* handle);
|
bool bq25896_is_otg_enabled(FuriHalI2cBusHandle* handle);
|
||||||
|
|
||||||
/** Get VREG (charging) voltage in mV */
|
/** Get VREG (charging limit) voltage in mV */
|
||||||
uint16_t bq25896_get_vreg_voltage(FuriHalI2cBusHandle* handle);
|
uint16_t bq25896_get_vreg_voltage(FuriHalI2cBusHandle* handle);
|
||||||
|
|
||||||
/** Set VREG (charging) voltage in mV
|
/** Set VREG (charging limit) voltage in mV
|
||||||
*
|
*
|
||||||
* Valid range: 3840mV - 4208mV, in steps of 16mV
|
* Valid range: 3840mV - 4208mV, in steps of 16mV
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ def file2image(file):
|
|||||||
data_enc = bytearray([len(data_enc) & 0xFF, len(data_enc) >> 8]) + data_enc
|
data_enc = bytearray([len(data_enc) & 0xFF, len(data_enc) >> 8]) + data_enc
|
||||||
|
|
||||||
# Use encoded data only if its length less than original, including header
|
# Use encoded data only if its length less than original, including header
|
||||||
if len(data_enc) < len(data_bin) + 1:
|
if len(data_enc) + 2 < len(data_bin) + 1:
|
||||||
data = b"\x01\x00" + data_enc
|
data = b"\x01\x00" + data_enc
|
||||||
else:
|
else:
|
||||||
data = b"\x00" + data_bin
|
data = b"\x00" + data_bin
|
||||||
|
|||||||
Reference in New Issue
Block a user