[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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 あく
						あく