[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_cli.h" | ||||
| #include "power_views.h" | ||||
| 
 | ||||
| #include <furi.h> | ||||
| @ -13,12 +14,14 @@ | ||||
| #include <gui/view_dispatcher.h> | ||||
| #include <gui/modules/dialog.h> | ||||
| #include <assets_icons.h> | ||||
| #include <cli/cli.h> | ||||
| #include <stm32wbxx.h> | ||||
| 
 | ||||
| #define POWER_OFF_TIMEOUT 30 | ||||
| 
 | ||||
| struct Power { | ||||
|     ViewDispatcher* view_dispatcher; | ||||
|     View* info_view; | ||||
|     View* off_view; | ||||
| 
 | ||||
|     Icon* usb_icon; | ||||
|     ViewPort* usb_view_port; | ||||
| @ -97,6 +100,7 @@ Power* power_alloc() { | ||||
|     power->menu_vm = furi_record_open("menu"); | ||||
| 
 | ||||
|     power->cli = furi_record_open("cli"); | ||||
|     power_cli_init(power->cli); | ||||
| 
 | ||||
|     power->menu = menu_item_alloc_menu("Power", NULL); | ||||
|     menu_item_subitem_add( | ||||
| @ -119,6 +123,11 @@ Power* power_alloc() { | ||||
|     view_set_previous_callback(power->info_view, power_info_back_callback); | ||||
|     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(); | ||||
|     dialog_set_context(power->dialog, power); | ||||
|     view_dispatcher_add_view( | ||||
| @ -142,44 +151,10 @@ void power_free(Power* 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) { | ||||
|     (void)p; | ||||
|     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_add_view_port(gui, power->usb_view_port, GuiLayerStatusBarLeft); | ||||
|     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); | ||||
| 
 | ||||
|     while(1) { | ||||
|         bool battery_low = false; | ||||
| 
 | ||||
|         with_view_model( | ||||
|             power->info_view, (PowerInfoModel * model) { | ||||
|                 model->charge = api_hal_power_get_pct(); | ||||
| @ -207,11 +184,39 @@ int32_t power_task(void* p) { | ||||
|                 model->temperature_gauge = | ||||
|                     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; | ||||
|             }); | ||||
| 
 | ||||
|         view_port_update(power->battery_view_port); | ||||
|         view_port_enabled_set(power->usb_view_port, api_hal_power_is_charging()); | ||||
| 
 | ||||
|         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) { | ||||
|     furi_assert(context); | ||||
|     PowerInfoModel* data = context; | ||||
| 
 | ||||
|     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, 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/view.h> | ||||
| 
 | ||||
| typedef enum { PowerViewInfo, PowerViewDialog } PowerView; | ||||
| typedef enum { PowerViewInfo, PowerViewDialog, PowerViewOff } PowerView; | ||||
| 
 | ||||
| typedef struct { | ||||
|     float current_charger; | ||||
| @ -26,4 +26,11 @@ typedef struct { | ||||
|     uint8_t health; | ||||
| } PowerInfoModel; | ||||
| 
 | ||||
| typedef struct { | ||||
|     uint32_t poweroff_tick; | ||||
|     bool battery_low; | ||||
| } PowerOffModel; | ||||
| 
 | ||||
| void power_info_draw_callback(Canvas* canvas, void* context); | ||||
| 
 | ||||
| void power_off_draw_callback(Canvas* canvas, void* context); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 あく
						あく