[FL-1818] System setting and debug options. RTC HAL refactoring. (#902)
* FuriHal: RTC API refactoring. System Setting application. FuriCore: adjustable log levels. Minor code cleanup. * Storage: change logging levels for internal storage. * FuriCore: fix broken trace logging level
This commit is contained in:
@@ -65,6 +65,7 @@ extern int32_t bt_settings_app(void* p);
|
||||
extern int32_t desktop_settings_app(void* p);
|
||||
extern int32_t about_settings_app(void* p);
|
||||
extern int32_t power_settings_app(void* p);
|
||||
extern int32_t system_settings_app(void* p);
|
||||
|
||||
const FlipperApplication FLIPPER_SERVICES[] = {
|
||||
/* Services */
|
||||
@@ -312,6 +313,10 @@ const FlipperApplication FLIPPER_SETTINGS_APPS[] = {
|
||||
{.app = passport_app, .name = "Passport", .stack_size = 1024, .icon = NULL},
|
||||
#endif
|
||||
|
||||
#ifdef SRV_GUI
|
||||
{.app = system_settings_app, .name = "System", .stack_size = 1024, .icon = NULL},
|
||||
#endif
|
||||
|
||||
#ifdef APP_ABOUT
|
||||
{.app = about_settings_app, .name = "About", .stack_size = 1024, .icon = NULL},
|
||||
#endif
|
||||
|
@@ -316,9 +316,3 @@ SRV_STORAGE ?= 0
|
||||
ifeq ($(SRV_STORAGE), 1)
|
||||
CFLAGS += -DSRV_STORAGE
|
||||
endif
|
||||
|
||||
|
||||
LAB_TESTS ?= 0
|
||||
ifeq ($(LAB_TESTS), 1)
|
||||
CFLAGS += -DLAB_TESTS
|
||||
endif
|
@@ -2,7 +2,6 @@
|
||||
#include <furi-hal.h>
|
||||
#include <furi-hal-gpio.h>
|
||||
#include <furi-hal-info.h>
|
||||
#include <rtc.h>
|
||||
#include <task-control-block.h>
|
||||
#include <time.h>
|
||||
#include <notification/notification-messages.h>
|
||||
@@ -58,46 +57,40 @@ void cli_command_help(Cli* cli, string_t args, void* context) {
|
||||
}
|
||||
|
||||
void cli_command_date(Cli* cli, string_t args, void* context) {
|
||||
RTC_TimeTypeDef time;
|
||||
RTC_DateTypeDef date;
|
||||
FuriHalRtcDateTime datetime = {0};
|
||||
|
||||
if(string_size(args) > 0) {
|
||||
uint16_t Hours, Minutes, Seconds, Month, Date, Year, WeekDay;
|
||||
uint16_t hours, minutes, seconds, month, day, year, weekday;
|
||||
int ret = sscanf(
|
||||
string_get_cstr(args),
|
||||
"%hu:%hu:%hu %hu-%hu-%hu %hu",
|
||||
&Hours,
|
||||
&Minutes,
|
||||
&Seconds,
|
||||
&Month,
|
||||
&Date,
|
||||
&Year,
|
||||
&WeekDay);
|
||||
&hours,
|
||||
&minutes,
|
||||
&seconds,
|
||||
&month,
|
||||
&day,
|
||||
&year,
|
||||
&weekday);
|
||||
if(ret == 7) {
|
||||
time.Hours = Hours;
|
||||
time.Minutes = Minutes;
|
||||
time.Seconds = Seconds;
|
||||
time.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
|
||||
time.StoreOperation = RTC_STOREOPERATION_RESET;
|
||||
date.WeekDay = WeekDay;
|
||||
date.Month = Month;
|
||||
date.Date = Date;
|
||||
date.Year = Year - 2000;
|
||||
HAL_RTC_SetTime(&hrtc, &time, RTC_FORMAT_BIN);
|
||||
HAL_RTC_SetDate(&hrtc, &date, RTC_FORMAT_BIN);
|
||||
|
||||
datetime.hour = hours;
|
||||
datetime.minute = minutes;
|
||||
datetime.second = seconds;
|
||||
datetime.weekday = weekday;
|
||||
datetime.month = month;
|
||||
datetime.day = day;
|
||||
datetime.year = year;
|
||||
furi_hal_rtc_set_datetime(&datetime);
|
||||
// Verification
|
||||
HAL_RTC_GetTime(&hrtc, &time, RTC_FORMAT_BIN);
|
||||
HAL_RTC_GetDate(&hrtc, &date, RTC_FORMAT_BIN);
|
||||
furi_hal_rtc_get_datetime(&datetime);
|
||||
printf(
|
||||
"New time is: %.2d:%.2d:%.2d %.2d-%.2d-%.2d %d",
|
||||
time.Hours,
|
||||
time.Minutes,
|
||||
time.Seconds,
|
||||
date.Month,
|
||||
date.Date,
|
||||
2000 + date.Year,
|
||||
date.WeekDay);
|
||||
datetime.hour,
|
||||
datetime.minute,
|
||||
datetime.second,
|
||||
datetime.month,
|
||||
datetime.day,
|
||||
datetime.year,
|
||||
datetime.weekday);
|
||||
} else {
|
||||
printf(
|
||||
"Invalid time format, use `hh:mm:ss MM-DD-YYYY WD`. sscanf %d %s",
|
||||
@@ -106,19 +99,16 @@ void cli_command_date(Cli* cli, string_t args, void* context) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// TODO add get_datetime to core, not use HAL here
|
||||
// READ ORDER MATTERS! Time then date.
|
||||
HAL_RTC_GetTime(&hrtc, &time, RTC_FORMAT_BIN);
|
||||
HAL_RTC_GetDate(&hrtc, &date, RTC_FORMAT_BIN);
|
||||
furi_hal_rtc_get_datetime(&datetime);
|
||||
printf(
|
||||
"%.2d:%.2d:%.2d %.2d-%.2d-%.2d %d",
|
||||
time.Hours,
|
||||
time.Minutes,
|
||||
time.Seconds,
|
||||
date.Month,
|
||||
date.Date,
|
||||
2000 + date.Year,
|
||||
date.WeekDay);
|
||||
datetime.hour,
|
||||
datetime.minute,
|
||||
datetime.second,
|
||||
datetime.month,
|
||||
datetime.day,
|
||||
datetime.year,
|
||||
datetime.weekday);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -2,6 +2,7 @@
|
||||
#include <stdint.h>
|
||||
#include <storage/storage.h>
|
||||
#include <furi.h>
|
||||
#include <furi-hal.h>
|
||||
#include <math.h>
|
||||
#include <toolbox/saved_struct.h>
|
||||
|
||||
@@ -70,20 +71,18 @@ bool dolphin_state_load(DolphinState* dolphin_state) {
|
||||
}
|
||||
|
||||
uint64_t dolphin_state_timestamp() {
|
||||
RTC_TimeTypeDef time;
|
||||
RTC_DateTypeDef date;
|
||||
FuriHalRtcDateTime datetime;
|
||||
struct tm current;
|
||||
|
||||
HAL_RTC_GetTime(&hrtc, &time, RTC_FORMAT_BIN);
|
||||
HAL_RTC_GetDate(&hrtc, &date, RTC_FORMAT_BIN);
|
||||
furi_hal_rtc_get_datetime(&datetime);
|
||||
|
||||
current.tm_year = date.Year + 100;
|
||||
current.tm_mday = date.Date;
|
||||
current.tm_mon = date.Month - 1;
|
||||
current.tm_year = datetime.year - 1900;
|
||||
current.tm_mday = datetime.day;
|
||||
current.tm_mon = datetime.month - 1;
|
||||
|
||||
current.tm_hour = time.Hours;
|
||||
current.tm_min = time.Minutes;
|
||||
current.tm_sec = time.Seconds;
|
||||
current.tm_hour = datetime.hour;
|
||||
current.tm_min = datetime.minute;
|
||||
current.tm_sec = datetime.second;
|
||||
|
||||
return mktime(¤t);
|
||||
}
|
||||
|
@@ -3,7 +3,6 @@
|
||||
#include "dolphin_deed.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <rtc.h>
|
||||
#include <time.h>
|
||||
|
||||
typedef struct DolphinState DolphinState;
|
||||
|
@@ -6,6 +6,7 @@
|
||||
#include "nfc_device.h"
|
||||
|
||||
#include <furi.h>
|
||||
#include <furi-hal.h>
|
||||
|
||||
#include <gui/gui.h>
|
||||
#include <gui/view.h>
|
||||
|
13
applications/nfc/scenes/nfc_scene_start.c
Executable file → Normal file
13
applications/nfc/scenes/nfc_scene_start.c
Executable file → Normal file
@@ -5,9 +5,7 @@ enum SubmenuIndex {
|
||||
SubmenuIndexRunScript,
|
||||
SubmenuIndexSaved,
|
||||
SubmenuIndexAddManualy,
|
||||
#ifdef LAB_TESTS
|
||||
SubmenuIndexDebug,
|
||||
#endif
|
||||
};
|
||||
|
||||
void nfc_scene_start_submenu_callback(void* context, uint32_t index) {
|
||||
@@ -32,9 +30,12 @@ void nfc_scene_start_on_enter(void* context) {
|
||||
submenu, "Saved cards", SubmenuIndexSaved, nfc_scene_start_submenu_callback, nfc);
|
||||
submenu_add_item(
|
||||
submenu, "Add manually", SubmenuIndexAddManualy, nfc_scene_start_submenu_callback, nfc);
|
||||
#ifdef LAB_TESTS
|
||||
submenu_add_item(submenu, "Debug", SubmenuIndexDebug, nfc_scene_start_submenu_callback, nfc);
|
||||
#endif
|
||||
|
||||
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
|
||||
submenu_add_item(
|
||||
submenu, "Debug", SubmenuIndexDebug, nfc_scene_start_submenu_callback, nfc);
|
||||
}
|
||||
|
||||
submenu_set_selected_item(
|
||||
submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneStart));
|
||||
|
||||
@@ -65,12 +66,10 @@ bool nfc_scene_start_on_event(void* context, SceneManagerEvent event) {
|
||||
nfc->scene_manager, NfcSceneStart, SubmenuIndexAddManualy);
|
||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneSetType);
|
||||
consumed = true;
|
||||
#ifdef LAB_TESTS
|
||||
} else if(event.event == SubmenuIndexDebug) {
|
||||
scene_manager_set_scene_state(nfc->scene_manager, NfcSceneStart, SubmenuIndexDebug);
|
||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateApduSequence);
|
||||
consumed = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return consumed;
|
||||
|
@@ -2,8 +2,7 @@
|
||||
#include "rpc_i.h"
|
||||
#include "status.pb.h"
|
||||
|
||||
#include <furi-hal-info.h>
|
||||
#include <furi-hal-bootloader.h>
|
||||
#include <furi-hal.h>
|
||||
#include <power/power_service/power.h>
|
||||
|
||||
void rpc_system_system_ping_process(const PB_Main* msg_request, void* context) {
|
||||
@@ -104,7 +103,7 @@ void rpc_system_system_factory_reset_process(const PB_Main* request, void* conte
|
||||
furi_assert(request->which_content == PB_Main_system_factory_reset_request_tag);
|
||||
furi_assert(context);
|
||||
|
||||
furi_hal_bootloader_set_flags(FuriHalBootloaderFlagFactoryReset);
|
||||
furi_hal_rtc_set_flag(FuriHalRtcFlagFactoryReset);
|
||||
power_reboot(PowerBootModeNormal);
|
||||
}
|
||||
|
||||
|
@@ -322,7 +322,7 @@ int32_t snake_game_app(void* p) {
|
||||
|
||||
ValueMutex state_mutex;
|
||||
if(!init_mutex(&state_mutex, snake_state, sizeof(SnakeState))) {
|
||||
furi_log_print(FURI_LOG_ERROR, "cannot create mutex\r\n");
|
||||
FURI_LOG_E("SnakeGame", "cannot create mutex\r\n");
|
||||
free(snake_state);
|
||||
return 255;
|
||||
}
|
||||
|
@@ -526,7 +526,7 @@ static void storage_cli_factory_reset(Cli* cli, string_t args, void* context) {
|
||||
char c = cli_getc(cli);
|
||||
if(c == 'y' || c == 'Y') {
|
||||
printf("Data will be wiped after reboot.\r\n");
|
||||
furi_hal_bootloader_set_flags(FuriHalBootloaderFlagFactoryReset);
|
||||
furi_hal_rtc_set_flag(FuriHalRtcFlagFactoryReset);
|
||||
power_reboot(PowerBootModeNormal);
|
||||
} else {
|
||||
printf("Safe choice.\r\n");
|
||||
|
@@ -69,7 +69,7 @@ static int storage_int_device_read(
|
||||
LFSData* lfs_data = c->context;
|
||||
size_t address = lfs_data->start_address + block * c->block_size + off;
|
||||
|
||||
FURI_LOG_D(
|
||||
FURI_LOG_T(
|
||||
TAG,
|
||||
"Device read: block %d, off %d, buffer: %p, size %d, translated address: %p",
|
||||
block,
|
||||
@@ -92,7 +92,7 @@ static int storage_int_device_prog(
|
||||
LFSData* lfs_data = c->context;
|
||||
size_t address = lfs_data->start_address + block * c->block_size + off;
|
||||
|
||||
FURI_LOG_D(
|
||||
FURI_LOG_T(
|
||||
TAG,
|
||||
"Device prog: block %d, off %d, buffer: %p, size %d, translated address: %p",
|
||||
block,
|
||||
@@ -163,15 +163,14 @@ static LFSData* storage_int_lfs_data_alloc() {
|
||||
|
||||
static void storage_int_lfs_mount(LFSData* lfs_data, StorageData* storage) {
|
||||
int err;
|
||||
FuriHalBootloaderFlag bootloader_flags = furi_hal_bootloader_get_flags();
|
||||
lfs_t* lfs = &lfs_data->lfs;
|
||||
|
||||
if(bootloader_flags & FuriHalBootloaderFlagFactoryReset) {
|
||||
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagFactoryReset)) {
|
||||
// Factory reset
|
||||
err = lfs_format(lfs, &lfs_data->config);
|
||||
if(err == 0) {
|
||||
FURI_LOG_I(TAG, "Factory reset: Format successful, trying to mount");
|
||||
furi_hal_bootloader_set_flags(bootloader_flags & ~FuriHalBootloaderFlagFactoryReset);
|
||||
furi_hal_rtc_reset_flag(FuriHalRtcFlagFactoryReset);
|
||||
err = lfs_mount(lfs, &lfs_data->config);
|
||||
if(err == 0) {
|
||||
FURI_LOG_I(TAG, "Factory reset: Mounted");
|
||||
@@ -687,4 +686,4 @@ void storage_int_init(StorageData* storage) {
|
||||
storage->fs_api.common.rename = storage_int_common_rename;
|
||||
storage->fs_api.common.remove = storage_int_common_remove;
|
||||
storage->fs_api.common.fs_info = storage_int_common_fs_info;
|
||||
}
|
||||
}
|
||||
|
@@ -63,7 +63,7 @@ bool storage_settings_scene_factory_reset_on_event(void* context, SceneManagerEv
|
||||
scene_manager_set_scene_state(
|
||||
app->scene_manager, StorageSettingsFactoryReset, counter);
|
||||
} else {
|
||||
furi_hal_bootloader_set_flags(FuriHalBootloaderFlagFactoryReset);
|
||||
furi_hal_rtc_set_flag(FuriHalRtcFlagFactoryReset);
|
||||
power_reboot(PowerBootModeNormal);
|
||||
}
|
||||
|
||||
|
@@ -3,9 +3,7 @@
|
||||
enum SubmenuIndex {
|
||||
SubmenuIndexRead = 10,
|
||||
SubmenuIndexSaved,
|
||||
#ifdef LAB_TESTS
|
||||
SubmenuIndexTest,
|
||||
#endif
|
||||
SubmenuIndexAddManualy,
|
||||
SubmenuIndexFrequencyAnalyzer,
|
||||
SubmenuIndexReadRAW,
|
||||
@@ -43,10 +41,10 @@ void subghz_scene_start_on_enter(void* context) {
|
||||
SubmenuIndexFrequencyAnalyzer,
|
||||
subghz_scene_start_submenu_callback,
|
||||
subghz);
|
||||
#ifdef LAB_TESTS
|
||||
submenu_add_item(
|
||||
subghz->submenu, "Test", SubmenuIndexTest, subghz_scene_start_submenu_callback, subghz);
|
||||
#endif
|
||||
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
|
||||
submenu_add_item(
|
||||
subghz->submenu, "Test", SubmenuIndexTest, subghz_scene_start_submenu_callback, subghz);
|
||||
}
|
||||
submenu_set_selected_item(
|
||||
subghz->submenu, scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneStart));
|
||||
|
||||
@@ -83,13 +81,11 @@ bool subghz_scene_start_on_event(void* context, SceneManagerEvent event) {
|
||||
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexFrequencyAnalyzer);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneFrequencyAnalyzer);
|
||||
return true;
|
||||
#ifdef LAB_TESTS
|
||||
} else if(event.event == SubmenuIndexTest) {
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneStart, SubmenuIndexTest);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTest);
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
121
applications/system/system_settings.c
Normal file
121
applications/system/system_settings.c
Normal file
@@ -0,0 +1,121 @@
|
||||
#include "system_settings.h"
|
||||
|
||||
static uint8_t
|
||||
uint32_value_index(const uint32_t value, const uint32_t values[], uint8_t values_count) {
|
||||
int64_t last_value = INT64_MIN;
|
||||
uint8_t index = 0;
|
||||
for(uint8_t i = 0; i < values_count; i++) {
|
||||
if((value >= last_value) && (value <= values[i])) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
last_value = values[i];
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
const char* const log_level_text[] = {
|
||||
"Default",
|
||||
"None",
|
||||
"Error",
|
||||
"Warning",
|
||||
"Info",
|
||||
"Debug",
|
||||
"Trace",
|
||||
};
|
||||
|
||||
const uint32_t log_level_value[] = {
|
||||
FuriLogLevelDefault,
|
||||
FuriLogLevelNone,
|
||||
FuriLogLevelError,
|
||||
FuriLogLevelWarn,
|
||||
FuriLogLevelInfo,
|
||||
FuriLogLevelDebug,
|
||||
FuriLogLevelTrace,
|
||||
};
|
||||
|
||||
static void log_level_changed(VariableItem* item) {
|
||||
// SystemSettings* app = variable_item_get_context(item);
|
||||
uint8_t index = variable_item_get_current_value_index(item);
|
||||
variable_item_set_current_value_text(item, log_level_text[index]);
|
||||
furi_hal_rtc_set_log_level(log_level_value[index]);
|
||||
}
|
||||
|
||||
const char* const debug_text[] = {
|
||||
"Disable",
|
||||
"Enable",
|
||||
};
|
||||
|
||||
static void debug_changed(VariableItem* item) {
|
||||
uint8_t index = variable_item_get_current_value_index(item);
|
||||
variable_item_set_current_value_text(item, debug_text[index]);
|
||||
if(index) {
|
||||
furi_hal_rtc_set_flag(FuriHalRtcFlagDebug);
|
||||
} else {
|
||||
furi_hal_rtc_reset_flag(FuriHalRtcFlagDebug);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t system_settings_exit(void* context) {
|
||||
return VIEW_NONE;
|
||||
}
|
||||
|
||||
SystemSettings* system_settings_alloc() {
|
||||
SystemSettings* app = furi_alloc(sizeof(SystemSettings));
|
||||
|
||||
// Load settings
|
||||
app->gui = furi_record_open("gui");
|
||||
|
||||
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_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
|
||||
|
||||
VariableItem* item;
|
||||
uint8_t value_index;
|
||||
app->var_item_list = variable_item_list_alloc();
|
||||
|
||||
item = variable_item_list_add(
|
||||
app->var_item_list, "Log Level", COUNT_OF(log_level_text), log_level_changed, app);
|
||||
value_index = uint32_value_index(
|
||||
furi_hal_rtc_get_log_level(), log_level_value, COUNT_OF(log_level_text));
|
||||
variable_item_set_current_value_index(item, value_index);
|
||||
variable_item_set_current_value_text(item, log_level_text[value_index]);
|
||||
|
||||
item = variable_item_list_add(
|
||||
app->var_item_list, "Debug", COUNT_OF(debug_text), debug_changed, app);
|
||||
value_index = furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug) ? 1 : 0;
|
||||
variable_item_set_current_value_index(item, value_index);
|
||||
variable_item_set_current_value_text(item, debug_text[value_index]);
|
||||
|
||||
view_set_previous_callback(
|
||||
variable_item_list_get_view(app->var_item_list), system_settings_exit);
|
||||
view_dispatcher_add_view(
|
||||
app->view_dispatcher,
|
||||
SystemSettingsViewVarItemList,
|
||||
variable_item_list_get_view(app->var_item_list));
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, SystemSettingsViewVarItemList);
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
void system_settings_free(SystemSettings* app) {
|
||||
furi_assert(app);
|
||||
// Variable item list
|
||||
view_dispatcher_remove_view(app->view_dispatcher, SystemSettingsViewVarItemList);
|
||||
variable_item_list_free(app->var_item_list);
|
||||
// View dispatcher
|
||||
view_dispatcher_free(app->view_dispatcher);
|
||||
// Records
|
||||
furi_record_close("gui");
|
||||
free(app);
|
||||
}
|
||||
|
||||
int32_t system_settings_app(void* p) {
|
||||
SystemSettings* app = system_settings_alloc();
|
||||
view_dispatcher_run(app->view_dispatcher);
|
||||
system_settings_free(app);
|
||||
return 0;
|
||||
}
|
18
applications/system/system_settings.h
Executable file
18
applications/system/system_settings.h
Executable file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <furi.h>
|
||||
#include <furi-hal.h>
|
||||
|
||||
#include <gui/gui.h>
|
||||
#include <gui/view_dispatcher.h>
|
||||
#include <gui/modules/variable-item-list.h>
|
||||
|
||||
typedef struct {
|
||||
Gui* gui;
|
||||
ViewDispatcher* view_dispatcher;
|
||||
VariableItemList* var_item_list;
|
||||
} SystemSettings;
|
||||
|
||||
typedef enum {
|
||||
SystemSettingsViewVarItemList,
|
||||
} SystemSettingsView;
|
Reference in New Issue
Block a user