mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2024-12-25 22:32:29 +03:00
[FL-1151] Power: Low Battery power off routine (#418)
This commit is contained in:
parent
8ada9b817b
commit
202673aed1
@ -1,4 +1,5 @@
|
|||||||
#include "power.h"
|
#include "power.h"
|
||||||
|
#include "power_cli.h"
|
||||||
#include "power_views.h"
|
#include "power_views.h"
|
||||||
|
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
@ -13,12 +14,14 @@
|
|||||||
#include <gui/view_dispatcher.h>
|
#include <gui/view_dispatcher.h>
|
||||||
#include <gui/modules/dialog.h>
|
#include <gui/modules/dialog.h>
|
||||||
#include <assets_icons.h>
|
#include <assets_icons.h>
|
||||||
#include <cli/cli.h>
|
|
||||||
#include <stm32wbxx.h>
|
#include <stm32wbxx.h>
|
||||||
|
|
||||||
|
#define POWER_OFF_TIMEOUT 30
|
||||||
|
|
||||||
struct Power {
|
struct Power {
|
||||||
ViewDispatcher* view_dispatcher;
|
ViewDispatcher* view_dispatcher;
|
||||||
View* info_view;
|
View* info_view;
|
||||||
|
View* off_view;
|
||||||
|
|
||||||
Icon* usb_icon;
|
Icon* usb_icon;
|
||||||
ViewPort* usb_view_port;
|
ViewPort* usb_view_port;
|
||||||
@ -97,6 +100,7 @@ Power* power_alloc() {
|
|||||||
power->menu_vm = furi_record_open("menu");
|
power->menu_vm = furi_record_open("menu");
|
||||||
|
|
||||||
power->cli = furi_record_open("cli");
|
power->cli = furi_record_open("cli");
|
||||||
|
power_cli_init(power->cli);
|
||||||
|
|
||||||
power->menu = menu_item_alloc_menu("Power", NULL);
|
power->menu = menu_item_alloc_menu("Power", NULL);
|
||||||
menu_item_subitem_add(
|
menu_item_subitem_add(
|
||||||
@ -119,6 +123,11 @@ Power* power_alloc() {
|
|||||||
view_set_previous_callback(power->info_view, power_info_back_callback);
|
view_set_previous_callback(power->info_view, power_info_back_callback);
|
||||||
view_dispatcher_add_view(power->view_dispatcher, PowerViewInfo, power->info_view);
|
view_dispatcher_add_view(power->view_dispatcher, PowerViewInfo, power->info_view);
|
||||||
|
|
||||||
|
power->off_view = view_alloc();
|
||||||
|
view_allocate_model(power->off_view, ViewModelTypeLockFree, sizeof(PowerOffModel));
|
||||||
|
view_set_draw_callback(power->off_view, power_off_draw_callback);
|
||||||
|
view_dispatcher_add_view(power->view_dispatcher, PowerViewOff, power->off_view);
|
||||||
|
|
||||||
power->dialog = dialog_alloc();
|
power->dialog = dialog_alloc();
|
||||||
dialog_set_context(power->dialog, power);
|
dialog_set_context(power->dialog, power);
|
||||||
view_dispatcher_add_view(
|
view_dispatcher_add_view(
|
||||||
@ -142,44 +151,10 @@ void power_free(Power* power) {
|
|||||||
free(power);
|
free(power);
|
||||||
}
|
}
|
||||||
|
|
||||||
void power_cli_poweroff(string_t args, void* context) {
|
|
||||||
api_hal_power_off();
|
|
||||||
}
|
|
||||||
|
|
||||||
void power_cli_reset(string_t args, void* context) {
|
|
||||||
NVIC_SystemReset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void power_cli_dfu(string_t args, void* context) {
|
|
||||||
api_hal_boot_set_mode(ApiHalBootModeDFU);
|
|
||||||
NVIC_SystemReset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void power_cli_test(string_t args, void* context) {
|
|
||||||
api_hal_power_dump_state();
|
|
||||||
}
|
|
||||||
|
|
||||||
void power_cli_otg_on(string_t args, void* context) {
|
|
||||||
api_hal_power_enable_otg();
|
|
||||||
}
|
|
||||||
|
|
||||||
void power_cli_otg_off(string_t args, void* context) {
|
|
||||||
api_hal_power_disable_otg();
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t power_task(void* p) {
|
int32_t power_task(void* p) {
|
||||||
(void)p;
|
(void)p;
|
||||||
Power* power = power_alloc();
|
Power* power = power_alloc();
|
||||||
|
|
||||||
if(power->cli) {
|
|
||||||
cli_add_command(power->cli, "poweroff", power_cli_poweroff, power);
|
|
||||||
cli_add_command(power->cli, "reset", power_cli_reset, power);
|
|
||||||
cli_add_command(power->cli, "dfu", power_cli_dfu, power);
|
|
||||||
cli_add_command(power->cli, "power_test", power_cli_test, power);
|
|
||||||
cli_add_command(power->cli, "power_otg_on", power_cli_otg_on, power);
|
|
||||||
cli_add_command(power->cli, "power_otg_off", power_cli_otg_off, power);
|
|
||||||
}
|
|
||||||
|
|
||||||
Gui* gui = furi_record_open("gui");
|
Gui* gui = furi_record_open("gui");
|
||||||
gui_add_view_port(gui, power->usb_view_port, GuiLayerStatusBarLeft);
|
gui_add_view_port(gui, power->usb_view_port, GuiLayerStatusBarLeft);
|
||||||
gui_add_view_port(gui, power->battery_view_port, GuiLayerStatusBarRight);
|
gui_add_view_port(gui, power->battery_view_port, GuiLayerStatusBarRight);
|
||||||
@ -191,6 +166,8 @@ int32_t power_task(void* p) {
|
|||||||
furi_record_create("power", power);
|
furi_record_create("power", power);
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
|
bool battery_low = false;
|
||||||
|
|
||||||
with_view_model(
|
with_view_model(
|
||||||
power->info_view, (PowerInfoModel * model) {
|
power->info_view, (PowerInfoModel * model) {
|
||||||
model->charge = api_hal_power_get_pct();
|
model->charge = api_hal_power_get_pct();
|
||||||
@ -207,11 +184,39 @@ int32_t power_task(void* p) {
|
|||||||
model->temperature_gauge =
|
model->temperature_gauge =
|
||||||
api_hal_power_get_battery_temperature(ApiHalPowerICFuelGauge);
|
api_hal_power_get_battery_temperature(ApiHalPowerICFuelGauge);
|
||||||
|
|
||||||
|
if(model->voltage_gauge < 3.3f && model->voltage_vbus < 4.0f) {
|
||||||
|
battery_low = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
with_view_model(
|
||||||
|
power->off_view, (PowerOffModel * model) {
|
||||||
|
if(battery_low) {
|
||||||
|
if(model->poweroff_tick == 0) {
|
||||||
|
model->poweroff_tick =
|
||||||
|
osKernelGetTickCount() + osKernelGetTickFreq() * POWER_OFF_TIMEOUT;
|
||||||
|
} else {
|
||||||
|
if(osKernelGetTickCount() > model->poweroff_tick) {
|
||||||
|
api_hal_power_off();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
model->poweroff_tick = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(model->battery_low != battery_low) {
|
||||||
|
model->battery_low = battery_low;
|
||||||
|
view_dispatcher_switch_to_view(
|
||||||
|
power->view_dispatcher, battery_low ? PowerViewOff : VIEW_NONE);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
view_port_update(power->battery_view_port);
|
view_port_update(power->battery_view_port);
|
||||||
view_port_enabled_set(power->usb_view_port, api_hal_power_is_charging());
|
view_port_enabled_set(power->usb_view_port, api_hal_power_is_charging());
|
||||||
|
|
||||||
osDelay(1024);
|
osDelay(1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
36
applications/power/power_cli.c
Normal file
36
applications/power/power_cli.c
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#include "power_cli.h"
|
||||||
|
#include <api-hal.h>
|
||||||
|
|
||||||
|
void power_cli_poweroff(string_t args, void* context) {
|
||||||
|
api_hal_power_off();
|
||||||
|
}
|
||||||
|
|
||||||
|
void power_cli_reset(string_t args, void* context) {
|
||||||
|
NVIC_SystemReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void power_cli_dfu(string_t args, void* context) {
|
||||||
|
api_hal_boot_set_mode(ApiHalBootModeDFU);
|
||||||
|
NVIC_SystemReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void power_cli_test(string_t args, void* context) {
|
||||||
|
api_hal_power_dump_state();
|
||||||
|
}
|
||||||
|
|
||||||
|
void power_cli_otg_on(string_t args, void* context) {
|
||||||
|
api_hal_power_enable_otg();
|
||||||
|
}
|
||||||
|
|
||||||
|
void power_cli_otg_off(string_t args, void* context) {
|
||||||
|
api_hal_power_disable_otg();
|
||||||
|
}
|
||||||
|
|
||||||
|
void power_cli_init(Cli* cli) {
|
||||||
|
cli_add_command(cli, "poweroff", power_cli_poweroff, NULL);
|
||||||
|
cli_add_command(cli, "reset", power_cli_reset, NULL);
|
||||||
|
cli_add_command(cli, "dfu", power_cli_dfu, NULL);
|
||||||
|
cli_add_command(cli, "power_test", power_cli_test, NULL);
|
||||||
|
cli_add_command(cli, "power_otg_on", power_cli_otg_on, NULL);
|
||||||
|
cli_add_command(cli, "power_otg_off", power_cli_otg_off, NULL);
|
||||||
|
}
|
5
applications/power/power_cli.h
Normal file
5
applications/power/power_cli.h
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cli/cli.h>
|
||||||
|
|
||||||
|
void power_cli_init(Cli* cli);
|
@ -76,6 +76,7 @@ static void draw_battery(Canvas* canvas, PowerInfoModel* data, int x, int y) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void power_info_draw_callback(Canvas* canvas, void* context) {
|
void power_info_draw_callback(Canvas* canvas, void* context) {
|
||||||
|
furi_assert(context);
|
||||||
PowerInfoModel* data = context;
|
PowerInfoModel* data = context;
|
||||||
|
|
||||||
canvas_clear(canvas);
|
canvas_clear(canvas);
|
||||||
@ -102,3 +103,22 @@ void power_info_draw_callback(Canvas* canvas, void* context) {
|
|||||||
draw_stat(canvas, 72, 42, I_Voltage_16x16, voltage);
|
draw_stat(canvas, 72, 42, I_Voltage_16x16, voltage);
|
||||||
draw_stat(canvas, 104, 42, I_Health_16x16, health);
|
draw_stat(canvas, 104, 42, I_Health_16x16, health);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void power_off_draw_callback(Canvas* canvas, void* context) {
|
||||||
|
furi_assert(context);
|
||||||
|
PowerOffModel* model = context;
|
||||||
|
|
||||||
|
canvas_set_color(canvas, ColorBlack);
|
||||||
|
canvas_set_font(canvas, FontPrimary);
|
||||||
|
canvas_draw_str(canvas, 2, 15, "!!! Low Battery !!!");
|
||||||
|
|
||||||
|
char buffer[64];
|
||||||
|
canvas_set_font(canvas, FontSecondary);
|
||||||
|
canvas_draw_str(canvas, 5, 30, "Connect to charger");
|
||||||
|
snprintf(
|
||||||
|
buffer,
|
||||||
|
64,
|
||||||
|
"Or poweroff in %lds",
|
||||||
|
(model->poweroff_tick - osKernelGetTickCount()) / osKernelGetTickFreq());
|
||||||
|
canvas_draw_str(canvas, 5, 42, buffer);
|
||||||
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include <gui/canvas.h>
|
#include <gui/canvas.h>
|
||||||
#include <gui/view.h>
|
#include <gui/view.h>
|
||||||
|
|
||||||
typedef enum { PowerViewInfo, PowerViewDialog } PowerView;
|
typedef enum { PowerViewInfo, PowerViewDialog, PowerViewOff } PowerView;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
float current_charger;
|
float current_charger;
|
||||||
@ -26,4 +26,11 @@ typedef struct {
|
|||||||
uint8_t health;
|
uint8_t health;
|
||||||
} PowerInfoModel;
|
} PowerInfoModel;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t poweroff_tick;
|
||||||
|
bool battery_low;
|
||||||
|
} PowerOffModel;
|
||||||
|
|
||||||
void power_info_draw_callback(Canvas* canvas, void* context);
|
void power_info_draw_callback(Canvas* canvas, void* context);
|
||||||
|
|
||||||
|
void power_off_draw_callback(Canvas* canvas, void* context);
|
||||||
|
Loading…
Reference in New Issue
Block a user