[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 vibro_test_app(void* p); | ||||
| extern int32_t bt_hid_app(void* p); | ||||
| extern int32_t battery_test_app(void* p); | ||||
| 
 | ||||
| // Plugins
 | ||||
| extern int32_t music_player_app(void* p); | ||||
| @ -278,6 +279,10 @@ const FlipperApplication FLIPPER_DEBUG_APPS[] = { | ||||
| #ifdef APP_DISPLAY_TEST | ||||
|     {.app = display_test_app, .name = "Display Test", .stack_size = 1024, .icon = NULL}, | ||||
| #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); | ||||
|  | ||||
| @ -155,6 +155,11 @@ CFLAGS		+= -DAPP_DISPLAY_TEST | ||||
| SRV_GUI = 1 | ||||
| endif | ||||
| 
 | ||||
| APP_BATTERY_TEST ?= 0 | ||||
| ifeq ($(APP_BATTERY_TEST), 1) | ||||
| CFLAGS		+= -DAPP_BATTERY_TEST | ||||
| SRV_GUI = 1 | ||||
| endif | ||||
| 
 | ||||
| APP_USB_MOUSE ?= 0 | ||||
| ifeq ($(APP_USB_MOUSE), 1) | ||||
|  | ||||
| @ -268,9 +268,7 @@ static StorageAnimation* | ||||
|     animation_storage_fill_animation_list(&animation_list); | ||||
| 
 | ||||
|     Power* power = furi_record_open("power"); | ||||
|     PowerInfo info; | ||||
|     power_get_info(power, &info); | ||||
|     bool battery_is_well = power_is_battery_well(&info); | ||||
|     bool battery_is_well = power_is_battery_healthy(power); | ||||
|     furi_record_close("power"); | ||||
| 
 | ||||
|     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> | ||||
| 
 | ||||
| #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) { | ||||
|     furi_assert(context); | ||||
| @ -50,7 +45,7 @@ Power* power_alloc() { | ||||
|     power->state = PowerStateNotCharging; | ||||
|     power->battery_low = false; | ||||
|     power->power_off_timeout = POWER_OFF_TIMEOUT; | ||||
|     power->info_mtx = osMutexNew(NULL); | ||||
|     power->api_mtx = osMutexNew(NULL); | ||||
| 
 | ||||
|     // Gui
 | ||||
|     power->view_dispatcher = view_dispatcher_alloc(); | ||||
| @ -66,6 +61,7 @@ Power* power_alloc() { | ||||
| 
 | ||||
|     // Battery view port
 | ||||
|     power->battery_view_port = power_battery_view_port_alloc(power); | ||||
|     power->show_low_bat_level_message = true; | ||||
| 
 | ||||
|     return power; | ||||
| } | ||||
| @ -81,7 +77,7 @@ void power_free(Power* power) { | ||||
|     view_port_free(power->battery_view_port); | ||||
| 
 | ||||
|     // State
 | ||||
|     osMutexDelete(power->info_mtx); | ||||
|     osMutexDelete(power->api_mtx); | ||||
| 
 | ||||
|     // FuriPubSub
 | ||||
|     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_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; | ||||
|     power->info = info; | ||||
|     osMutexRelease(power->info_mtx); | ||||
|     osMutexRelease(power->api_mtx); | ||||
| 
 | ||||
|     return need_refresh; | ||||
| } | ||||
| 
 | ||||
| static void power_check_low_battery(Power* power) { | ||||
|     // 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) { | ||||
|             view_dispatcher_send_to_front(power->view_dispatcher); | ||||
|             view_dispatcher_switch_to_view(power->view_dispatcher, PowerViewOff); | ||||
|  | ||||
| @ -50,19 +50,35 @@ typedef struct { | ||||
| void power_off(Power* power); | ||||
| 
 | ||||
| /** Reboot device
 | ||||
|  * @param mode - PowerBootMode | ||||
|  * | ||||
|  * @param mode      PowerBootMode | ||||
|  */ | ||||
| void power_reboot(PowerBootMode mode); | ||||
| 
 | ||||
| /** 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); | ||||
| 
 | ||||
| /** Get power event pubsub handler
 | ||||
|  * @param power - Power instance | ||||
|  * | ||||
|  * @param power     Power instance | ||||
|  * | ||||
|  * @return          FuriPubSub instance | ||||
|  */ | ||||
| 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(info); | ||||
| 
 | ||||
|     osMutexAcquire(power->info_mtx, osWaitForever); | ||||
|     osMutexAcquire(power->api_mtx, osWaitForever); | ||||
|     memcpy(info, &power->info, sizeof(power->info)); | ||||
|     osMutexRelease(power->info_mtx); | ||||
|     osMutexRelease(power->api_mtx); | ||||
| } | ||||
| 
 | ||||
| FuriPubSub* power_get_pubsub(Power* power) { | ||||
|     furi_assert(power); | ||||
|     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> | ||||
| 
 | ||||
| #define POWER_BATTERY_HEALTHY_LEVEL 70 | ||||
| 
 | ||||
| typedef enum { | ||||
|     PowerStateNotCharging, | ||||
|     PowerStateCharging, | ||||
| @ -30,11 +32,13 @@ struct Power { | ||||
| 
 | ||||
|     PowerState state; | ||||
|     PowerInfo info; | ||||
|     osMutexId_t info_mtx; | ||||
| 
 | ||||
|     bool battery_low; | ||||
|     bool show_low_bat_level_message; | ||||
|     uint8_t battery_level; | ||||
|     uint8_t power_off_timeout; | ||||
| 
 | ||||
|     osMutexId_t api_mtx; | ||||
| }; | ||||
| 
 | ||||
| typedef enum { | ||||
|  | ||||
| @ -74,7 +74,7 @@ void power_settings_app_free(PowerSettingsApp* app) { | ||||
|     free(app); | ||||
| } | ||||
| 
 | ||||
| extern int32_t power_settings_app(void* p) { | ||||
| int32_t power_settings_app(void* p) { | ||||
|     PowerSettingsApp* app = power_settings_app_alloc(); | ||||
|     view_dispatcher_run(app->view_dispatcher); | ||||
|     power_settings_app_free(app); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 gornekich
						gornekich