mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2024-11-28 11:26:32 +03:00
[FL-2019] Battery test application (#940)
* Power: rework API * Applications: introduce battery test application * Power: fix typo * Desktop: cleanup merge artifacts Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
parent
7522b111c2
commit
2cbf99e15a
@ -42,6 +42,7 @@ extern int32_t usb_mouse_app(void* p);
|
|||||||
extern int32_t usb_test_app(void* p);
|
extern int32_t usb_test_app(void* p);
|
||||||
extern int32_t vibro_test_app(void* p);
|
extern int32_t vibro_test_app(void* p);
|
||||||
extern int32_t bt_hid_app(void* p);
|
extern int32_t bt_hid_app(void* p);
|
||||||
|
extern int32_t battery_test_app(void* p);
|
||||||
|
|
||||||
// Plugins
|
// Plugins
|
||||||
extern int32_t music_player_app(void* p);
|
extern int32_t music_player_app(void* p);
|
||||||
@ -278,6 +279,10 @@ const FlipperApplication FLIPPER_DEBUG_APPS[] = {
|
|||||||
#ifdef APP_DISPLAY_TEST
|
#ifdef APP_DISPLAY_TEST
|
||||||
{.app = display_test_app, .name = "Display Test", .stack_size = 1024, .icon = NULL},
|
{.app = display_test_app, .name = "Display Test", .stack_size = 1024, .icon = NULL},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef APP_BATTERY_TEST
|
||||||
|
{.app = battery_test_app, .name = "Battery Test", .stack_size = 1024, .icon = NULL},
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
const size_t FLIPPER_DEBUG_APPS_COUNT = sizeof(FLIPPER_DEBUG_APPS) / sizeof(FlipperApplication);
|
const size_t FLIPPER_DEBUG_APPS_COUNT = sizeof(FLIPPER_DEBUG_APPS) / sizeof(FlipperApplication);
|
||||||
|
@ -155,6 +155,11 @@ CFLAGS += -DAPP_DISPLAY_TEST
|
|||||||
SRV_GUI = 1
|
SRV_GUI = 1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
APP_BATTERY_TEST ?= 0
|
||||||
|
ifeq ($(APP_BATTERY_TEST), 1)
|
||||||
|
CFLAGS += -DAPP_BATTERY_TEST
|
||||||
|
SRV_GUI = 1
|
||||||
|
endif
|
||||||
|
|
||||||
APP_USB_MOUSE ?= 0
|
APP_USB_MOUSE ?= 0
|
||||||
ifeq ($(APP_USB_MOUSE), 1)
|
ifeq ($(APP_USB_MOUSE), 1)
|
||||||
|
@ -268,9 +268,7 @@ static StorageAnimation*
|
|||||||
animation_storage_fill_animation_list(&animation_list);
|
animation_storage_fill_animation_list(&animation_list);
|
||||||
|
|
||||||
Power* power = furi_record_open("power");
|
Power* power = furi_record_open("power");
|
||||||
PowerInfo info;
|
bool battery_is_well = power_is_battery_healthy(power);
|
||||||
power_get_info(power, &info);
|
|
||||||
bool battery_is_well = power_is_battery_well(&info);
|
|
||||||
furi_record_close("power");
|
furi_record_close("power");
|
||||||
|
|
||||||
Storage* storage = furi_record_open("storage");
|
Storage* storage = furi_record_open("storage");
|
||||||
|
100
applications/power/battery_test_app/battery_test_app.c
Executable file
100
applications/power/battery_test_app/battery_test_app.c
Executable file
@ -0,0 +1,100 @@
|
|||||||
|
#include "battery_test_app.h"
|
||||||
|
|
||||||
|
#include <notification/notification-messages.h>
|
||||||
|
|
||||||
|
void battery_test_dialog_callback(DialogExResult result, void* context) {
|
||||||
|
furi_assert(context);
|
||||||
|
BatteryTestApp* app = context;
|
||||||
|
if(result == DialogExResultLeft) {
|
||||||
|
view_dispatcher_stop(app->view_dispatcher);
|
||||||
|
} else if(result == DialogExResultRight) {
|
||||||
|
view_dispatcher_switch_to_view(app->view_dispatcher, BatteryTestAppViewBatteryInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t battery_test_exit_confirm_view() {
|
||||||
|
return BatteryTestAppViewExitDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void battery_test_battery_info_update_model(void* context) {
|
||||||
|
BatteryTestApp* app = context;
|
||||||
|
power_get_info(app->power, &app->info);
|
||||||
|
BatteryInfoModel battery_info_data = {
|
||||||
|
.vbus_voltage = app->info.voltage_vbus,
|
||||||
|
.gauge_voltage = app->info.voltage_gauge,
|
||||||
|
.gauge_current = app->info.current_gauge,
|
||||||
|
.gauge_temperature = app->info.temperature_gauge,
|
||||||
|
.charge = app->info.charge,
|
||||||
|
.health = app->info.health,
|
||||||
|
};
|
||||||
|
battery_info_set_data(app->batery_info, &battery_info_data);
|
||||||
|
notification_message(app->notifications, &sequence_display_on);
|
||||||
|
}
|
||||||
|
|
||||||
|
BatteryTestApp* battery_test_alloc() {
|
||||||
|
BatteryTestApp* app = furi_alloc(sizeof(BatteryTestApp));
|
||||||
|
|
||||||
|
// Records
|
||||||
|
app->gui = furi_record_open("gui");
|
||||||
|
app->power = furi_record_open("power");
|
||||||
|
app->notifications = furi_record_open("notification");
|
||||||
|
|
||||||
|
// View dispatcher
|
||||||
|
app->view_dispatcher = view_dispatcher_alloc();
|
||||||
|
view_dispatcher_enable_queue(app->view_dispatcher);
|
||||||
|
view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
|
||||||
|
view_dispatcher_set_tick_event_callback(
|
||||||
|
app->view_dispatcher, battery_test_battery_info_update_model, 500);
|
||||||
|
view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
|
||||||
|
|
||||||
|
// Views
|
||||||
|
app->batery_info = battery_info_alloc();
|
||||||
|
view_set_previous_callback(
|
||||||
|
battery_info_get_view(app->batery_info), battery_test_exit_confirm_view);
|
||||||
|
view_dispatcher_add_view(
|
||||||
|
app->view_dispatcher,
|
||||||
|
BatteryTestAppViewBatteryInfo,
|
||||||
|
battery_info_get_view(app->batery_info));
|
||||||
|
|
||||||
|
app->dialog = dialog_ex_alloc();
|
||||||
|
dialog_ex_set_header(app->dialog, "Close battery test?", 64, 12, AlignCenter, AlignTop);
|
||||||
|
dialog_ex_set_left_button_text(app->dialog, "Exit");
|
||||||
|
dialog_ex_set_right_button_text(app->dialog, "Stay");
|
||||||
|
dialog_ex_set_result_callback(app->dialog, battery_test_dialog_callback);
|
||||||
|
dialog_ex_set_context(app->dialog, app);
|
||||||
|
|
||||||
|
view_dispatcher_add_view(
|
||||||
|
app->view_dispatcher, BatteryTestAppViewExitDialog, dialog_ex_get_view(app->dialog));
|
||||||
|
|
||||||
|
battery_test_battery_info_update_model(app);
|
||||||
|
view_dispatcher_switch_to_view(app->view_dispatcher, BatteryTestAppViewBatteryInfo);
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
|
||||||
|
void battery_test_free(BatteryTestApp* app) {
|
||||||
|
furi_assert(app);
|
||||||
|
|
||||||
|
// Views
|
||||||
|
view_dispatcher_remove_view(app->view_dispatcher, BatteryTestAppViewBatteryInfo);
|
||||||
|
battery_info_free(app->batery_info);
|
||||||
|
view_dispatcher_remove_view(app->view_dispatcher, BatteryTestAppViewExitDialog);
|
||||||
|
dialog_ex_free(app->dialog);
|
||||||
|
// View dispatcher
|
||||||
|
view_dispatcher_free(app->view_dispatcher);
|
||||||
|
// Records
|
||||||
|
furi_record_close("power");
|
||||||
|
furi_record_close("gui");
|
||||||
|
furi_record_close("notification");
|
||||||
|
free(app);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t battery_test_app(void* p) {
|
||||||
|
BatteryTestApp* app = battery_test_alloc();
|
||||||
|
// Disable battery low level notification
|
||||||
|
power_enable_low_battery_level_notification(app->power, false);
|
||||||
|
|
||||||
|
view_dispatcher_run(app->view_dispatcher);
|
||||||
|
power_enable_low_battery_level_notification(app->power, true);
|
||||||
|
battery_test_free(app);
|
||||||
|
return 0;
|
||||||
|
}
|
24
applications/power/battery_test_app/battery_test_app.h
Normal file
24
applications/power/battery_test_app/battery_test_app.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#include <furi.h>
|
||||||
|
#include <power/power_service/power.h>
|
||||||
|
#include <gui/gui.h>
|
||||||
|
#include <gui/view.h>
|
||||||
|
#include <gui/view_dispatcher.h>
|
||||||
|
#include <notification/notification.h>
|
||||||
|
|
||||||
|
#include <gui/modules/dialog_ex.h>
|
||||||
|
#include <power/power_settings_app/views/battery_info.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Power* power;
|
||||||
|
Gui* gui;
|
||||||
|
NotificationApp* notifications;
|
||||||
|
ViewDispatcher* view_dispatcher;
|
||||||
|
BatteryInfo* batery_info;
|
||||||
|
DialogEx* dialog;
|
||||||
|
PowerInfo info;
|
||||||
|
} BatteryTestApp;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BatteryTestAppViewBatteryInfo,
|
||||||
|
BatteryTestAppViewExitDialog,
|
||||||
|
} BatteryTestAppView;
|
17
applications/power/power_service/power.c
Normal file → Executable file
17
applications/power/power_service/power.c
Normal file → Executable file
@ -7,11 +7,6 @@
|
|||||||
#include <gui/view.h>
|
#include <gui/view.h>
|
||||||
|
|
||||||
#define POWER_OFF_TIMEOUT 90
|
#define POWER_OFF_TIMEOUT 90
|
||||||
#define POWER_BATTERY_WELL_LEVEL 70
|
|
||||||
|
|
||||||
bool power_is_battery_well(PowerInfo* info) {
|
|
||||||
return info->health > POWER_BATTERY_WELL_LEVEL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void power_draw_battery_callback(Canvas* canvas, void* context) {
|
void power_draw_battery_callback(Canvas* canvas, void* context) {
|
||||||
furi_assert(context);
|
furi_assert(context);
|
||||||
@ -50,7 +45,7 @@ Power* power_alloc() {
|
|||||||
power->state = PowerStateNotCharging;
|
power->state = PowerStateNotCharging;
|
||||||
power->battery_low = false;
|
power->battery_low = false;
|
||||||
power->power_off_timeout = POWER_OFF_TIMEOUT;
|
power->power_off_timeout = POWER_OFF_TIMEOUT;
|
||||||
power->info_mtx = osMutexNew(NULL);
|
power->api_mtx = osMutexNew(NULL);
|
||||||
|
|
||||||
// Gui
|
// Gui
|
||||||
power->view_dispatcher = view_dispatcher_alloc();
|
power->view_dispatcher = view_dispatcher_alloc();
|
||||||
@ -66,6 +61,7 @@ Power* power_alloc() {
|
|||||||
|
|
||||||
// Battery view port
|
// Battery view port
|
||||||
power->battery_view_port = power_battery_view_port_alloc(power);
|
power->battery_view_port = power_battery_view_port_alloc(power);
|
||||||
|
power->show_low_bat_level_message = true;
|
||||||
|
|
||||||
return power;
|
return power;
|
||||||
}
|
}
|
||||||
@ -81,7 +77,7 @@ void power_free(Power* power) {
|
|||||||
view_port_free(power->battery_view_port);
|
view_port_free(power->battery_view_port);
|
||||||
|
|
||||||
// State
|
// State
|
||||||
osMutexDelete(power->info_mtx);
|
osMutexDelete(power->api_mtx);
|
||||||
|
|
||||||
// FuriPubSub
|
// FuriPubSub
|
||||||
furi_pubsub_free(power->event_pubsub);
|
furi_pubsub_free(power->event_pubsub);
|
||||||
@ -135,17 +131,18 @@ static bool power_update_info(Power* power) {
|
|||||||
info.temperature_charger = furi_hal_power_get_battery_temperature(FuriHalPowerICCharger);
|
info.temperature_charger = furi_hal_power_get_battery_temperature(FuriHalPowerICCharger);
|
||||||
info.temperature_gauge = furi_hal_power_get_battery_temperature(FuriHalPowerICFuelGauge);
|
info.temperature_gauge = furi_hal_power_get_battery_temperature(FuriHalPowerICFuelGauge);
|
||||||
|
|
||||||
osMutexAcquire(power->info_mtx, osWaitForever);
|
osMutexAcquire(power->api_mtx, osWaitForever);
|
||||||
bool need_refresh = power->info.charge != info.charge;
|
bool need_refresh = power->info.charge != info.charge;
|
||||||
power->info = info;
|
power->info = info;
|
||||||
osMutexRelease(power->info_mtx);
|
osMutexRelease(power->api_mtx);
|
||||||
|
|
||||||
return need_refresh;
|
return need_refresh;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void power_check_low_battery(Power* power) {
|
static void power_check_low_battery(Power* power) {
|
||||||
// Check battery charge and vbus voltage
|
// Check battery charge and vbus voltage
|
||||||
if((power->info.charge == 0) && (power->info.voltage_vbus < 4.0f)) {
|
if((power->info.charge == 0) && (power->info.voltage_vbus < 4.0f) &&
|
||||||
|
power->show_low_bat_level_message) {
|
||||||
if(!power->battery_low) {
|
if(!power->battery_low) {
|
||||||
view_dispatcher_send_to_front(power->view_dispatcher);
|
view_dispatcher_send_to_front(power->view_dispatcher);
|
||||||
view_dispatcher_switch_to_view(power->view_dispatcher, PowerViewOff);
|
view_dispatcher_switch_to_view(power->view_dispatcher, PowerViewOff);
|
||||||
|
@ -50,19 +50,35 @@ typedef struct {
|
|||||||
void power_off(Power* power);
|
void power_off(Power* power);
|
||||||
|
|
||||||
/** Reboot device
|
/** Reboot device
|
||||||
* @param mode - PowerBootMode
|
*
|
||||||
|
* @param mode PowerBootMode
|
||||||
*/
|
*/
|
||||||
void power_reboot(PowerBootMode mode);
|
void power_reboot(PowerBootMode mode);
|
||||||
|
|
||||||
/** Get power info
|
/** Get power info
|
||||||
* @param power - Power instance
|
*
|
||||||
* @param info - PowerInfo instance
|
* @param power Power instance
|
||||||
|
* @param info PowerInfo instance
|
||||||
*/
|
*/
|
||||||
void power_get_info(Power* power, PowerInfo* info);
|
void power_get_info(Power* power, PowerInfo* info);
|
||||||
|
|
||||||
/** Get power event pubsub handler
|
/** Get power event pubsub handler
|
||||||
* @param power - Power instance
|
*
|
||||||
|
* @param power Power instance
|
||||||
|
*
|
||||||
|
* @return FuriPubSub instance
|
||||||
*/
|
*/
|
||||||
FuriPubSub* power_get_pubsub(Power* power);
|
FuriPubSub* power_get_pubsub(Power* power);
|
||||||
|
|
||||||
bool power_is_battery_well(PowerInfo* info);
|
/** Check battery health
|
||||||
|
*
|
||||||
|
* @return true if battery is healthy
|
||||||
|
*/
|
||||||
|
bool power_is_battery_healthy(Power* power);
|
||||||
|
|
||||||
|
/** Enable or disable battery low level notification mesage
|
||||||
|
*
|
||||||
|
* @param power Power instance
|
||||||
|
* @param enable true - enable, false - disable
|
||||||
|
*/
|
||||||
|
void power_enable_low_battery_level_notification(Power* power, bool enable);
|
||||||
|
@ -26,12 +26,28 @@ void power_get_info(Power* power, PowerInfo* info) {
|
|||||||
furi_assert(power);
|
furi_assert(power);
|
||||||
furi_assert(info);
|
furi_assert(info);
|
||||||
|
|
||||||
osMutexAcquire(power->info_mtx, osWaitForever);
|
osMutexAcquire(power->api_mtx, osWaitForever);
|
||||||
memcpy(info, &power->info, sizeof(power->info));
|
memcpy(info, &power->info, sizeof(power->info));
|
||||||
osMutexRelease(power->info_mtx);
|
osMutexRelease(power->api_mtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
FuriPubSub* power_get_pubsub(Power* power) {
|
FuriPubSub* power_get_pubsub(Power* power) {
|
||||||
furi_assert(power);
|
furi_assert(power);
|
||||||
return power->event_pubsub;
|
return power->event_pubsub;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool power_is_battery_healthy(Power* power) {
|
||||||
|
furi_assert(power);
|
||||||
|
bool is_healthy = false;
|
||||||
|
osMutexAcquire(power->api_mtx, osWaitForever);
|
||||||
|
is_healthy = power->info.health > POWER_BATTERY_HEALTHY_LEVEL;
|
||||||
|
osMutexRelease(power->api_mtx);
|
||||||
|
return is_healthy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void power_enable_low_battery_level_notification(Power* power, bool enable) {
|
||||||
|
furi_assert(power);
|
||||||
|
osMutexAcquire(power->api_mtx, osWaitForever);
|
||||||
|
power->show_low_bat_level_message = enable;
|
||||||
|
osMutexRelease(power->api_mtx);
|
||||||
|
}
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
#include <notification/notification-messages.h>
|
#include <notification/notification-messages.h>
|
||||||
|
|
||||||
|
#define POWER_BATTERY_HEALTHY_LEVEL 70
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PowerStateNotCharging,
|
PowerStateNotCharging,
|
||||||
PowerStateCharging,
|
PowerStateCharging,
|
||||||
@ -30,11 +32,13 @@ struct Power {
|
|||||||
|
|
||||||
PowerState state;
|
PowerState state;
|
||||||
PowerInfo info;
|
PowerInfo info;
|
||||||
osMutexId_t info_mtx;
|
|
||||||
|
|
||||||
bool battery_low;
|
bool battery_low;
|
||||||
|
bool show_low_bat_level_message;
|
||||||
uint8_t battery_level;
|
uint8_t battery_level;
|
||||||
uint8_t power_off_timeout;
|
uint8_t power_off_timeout;
|
||||||
|
|
||||||
|
osMutexId_t api_mtx;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -74,7 +74,7 @@ void power_settings_app_free(PowerSettingsApp* app) {
|
|||||||
free(app);
|
free(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int32_t power_settings_app(void* p) {
|
int32_t power_settings_app(void* p) {
|
||||||
PowerSettingsApp* app = power_settings_app_alloc();
|
PowerSettingsApp* app = power_settings_app_alloc();
|
||||||
view_dispatcher_run(app->view_dispatcher);
|
view_dispatcher_run(app->view_dispatcher);
|
||||||
power_settings_app_free(app);
|
power_settings_app_free(app);
|
||||||
|
Loading…
Reference in New Issue
Block a user