diff --git a/applications/app-loader/app-loader.c b/applications/app-loader/app-loader.c index 732766ec..7c353265 100644 --- a/applications/app-loader/app-loader.c +++ b/applications/app-loader/app-loader.c @@ -31,7 +31,7 @@ static void app_loader_menu_callback(void* _ctx) { furi_thread_start(state.thread); } -static void app_loader_cli_callback(string_t args, void* _ctx) { +static void app_loader_cli_callback(Cli* cli, string_t args, void* _ctx) { furi_assert(_ctx); const FlipperApplication* flipper_app = (FlipperApplication*)_ctx; furi_assert(flipper_app->app); diff --git a/applications/bt/bt.c b/applications/bt/bt.c index b4624090..f3a97cff 100644 --- a/applications/bt/bt.c +++ b/applications/bt/bt.c @@ -134,7 +134,7 @@ void bt_menu_start_app(void* context) { furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); } -void bt_cli_info(string_t args, void* context) { +void bt_cli_info(Cli* cli, string_t args, void* context) { string_t buffer; string_init(buffer); api_hal_bt_dump_state(buffer); diff --git a/applications/bt/bt_i.h b/applications/bt/bt_i.h index f7213c7f..2a5ae26c 100644 --- a/applications/bt/bt_i.h +++ b/applications/bt/bt_i.h @@ -43,7 +43,7 @@ void bt_draw_statusbar_callback(Canvas* canvas, void* context); BtTestChannel bt_switch_channel(InputKey key, BtTestChannel inst_chan); -void bt_cli_info(string_t args, void* context); +void bt_cli_info(Cli* cli, string_t args, void* context); void bt_draw_statusbar_callback(Canvas* canvas, void* context); diff --git a/applications/cli/cli.c b/applications/cli/cli.c index 06f53814..361d899b 100644 --- a/applications/cli/cli.c +++ b/applications/cli/cli.c @@ -130,7 +130,7 @@ void cli_enter(Cli* cli) { furi_check(osMutexRelease(cli->mutex) == osOK); if(cli_command) { cli_nl(); - cli_command->callback(cli->line, cli_command->context); + cli_command->callback(cli, cli->line, cli_command->context); cli_prompt(); } else { cli_nl(); diff --git a/applications/cli/cli.h b/applications/cli/cli.h index 9d493d4f..cf792075 100644 --- a/applications/cli/cli.h +++ b/applications/cli/cli.h @@ -16,7 +16,7 @@ typedef struct Cli Cli; * @param args - string with what was passed after command * @param context - pointer to whatever you gave us on cli_add_command */ -typedef void (*CliCallback)(string_t args, void* context); +typedef void (*CliCallback)(Cli* cli, string_t args, void* context); /* Add cli command * Registers you command callback diff --git a/applications/cli/cli_commands.c b/applications/cli/cli_commands.c index 99c6cff5..5f5a8494 100644 --- a/applications/cli/cli_commands.c +++ b/applications/cli/cli_commands.c @@ -4,9 +4,8 @@ #include #include -void cli_command_help(string_t args, void* context) { +void cli_command_help(Cli* cli, string_t args, void* context) { (void)args; - Cli* cli = context; printf("Commands we have:"); furi_check(osMutexAcquire(cli->mutex, osWaitForever) == osOK); @@ -38,7 +37,7 @@ void cli_command_help(string_t args, void* context) { } } -void cli_command_version(string_t args, void* context) { +void cli_command_version(Cli* cli, string_t args, void* context) { (void)args; (void)context; printf("Bootloader\r\n"); @@ -48,7 +47,7 @@ void cli_command_version(string_t args, void* context) { cli_print_version(api_hal_version_get_fw_version()); } -void cli_command_uuid(string_t args, void* context) { +void cli_command_uuid(Cli* cli, string_t args, void* context) { (void)args; (void)context; size_t uid_size = api_hal_uid_size(); @@ -64,7 +63,7 @@ void cli_command_uuid(string_t args, void* context) { printf(string_get_cstr(byte_str)); } -void cli_command_date(string_t args, void* context) { +void cli_command_date(Cli* cli, string_t args, void* context) { RTC_DateTypeDef date; RTC_TimeTypeDef time; @@ -84,15 +83,14 @@ void cli_command_date(string_t args, void* context) { string_clear(datetime_str); } -void cli_command_log(string_t args, void* context) { - Cli* cli = context; +void cli_command_log(Cli* cli, string_t args, void* context) { furi_stdglue_set_global_stdout_callback(cli_stdout_callback); printf("Press any key to stop...\r\n"); cli_getc(cli); furi_stdglue_set_global_stdout_callback(NULL); } -void cli_command_vibro(string_t args, void* context) { +void cli_command_vibro(Cli* cli, string_t args, void* context) { if(!string_cmp(args, "0")) { api_hal_vibro_on(false); } else if(!string_cmp(args, "1")) { @@ -102,7 +100,7 @@ void cli_command_vibro(string_t args, void* context) { } } -void cli_command_led(string_t args, void* context) { +void cli_command_led(Cli* cli, string_t args, void* context) { // Get first word as light name Light light; string_t light_name; @@ -142,7 +140,7 @@ void cli_command_led(string_t args, void* context) { api_hal_light_set(light, value); } -void cli_command_gpio_set(string_t args, void* context) { +void cli_command_gpio_set(Cli* cli, string_t args, void* context) { char pin_names[][4] = {"PC0", "PC1", "PC3", "PB2", "PB3", "PA4", "PA6", "PA7"}; GpioPin gpio[] = { {.port = GPIOC, .pin = LL_GPIO_PIN_0}, @@ -200,7 +198,7 @@ void cli_command_gpio_set(string_t args, void* context) { return; } -void cli_command_os_info(string_t args, void* context) { +void cli_command_os_info(Cli* cli, string_t args, void* context) { const uint8_t threads_num_max = 32; osThreadId_t threads_id[threads_num_max]; uint8_t thread_num = osThreadEnumerate(threads_id, threads_num_max); @@ -222,15 +220,15 @@ void cli_command_os_info(string_t args, void* context) { } void cli_commands_init(Cli* cli) { - cli_add_command(cli, "help", cli_command_help, cli); - cli_add_command(cli, "?", cli_command_help, cli); - cli_add_command(cli, "version", cli_command_version, cli); - cli_add_command(cli, "!", cli_command_version, cli); - cli_add_command(cli, "uid", cli_command_uuid, cli); - cli_add_command(cli, "date", cli_command_date, cli); - cli_add_command(cli, "log", cli_command_log, cli); - cli_add_command(cli, "vibro", cli_command_vibro, cli); - cli_add_command(cli, "led", cli_command_led, cli); - cli_add_command(cli, "gpio_set", cli_command_gpio_set, cli); - cli_add_command(cli, "os_info", cli_command_os_info, cli); + cli_add_command(cli, "help", cli_command_help, NULL); + cli_add_command(cli, "?", cli_command_help, NULL); + cli_add_command(cli, "version", cli_command_version, NULL); + cli_add_command(cli, "!", cli_command_version, NULL); + cli_add_command(cli, "uid", cli_command_uuid, NULL); + cli_add_command(cli, "date", cli_command_date, NULL); + cli_add_command(cli, "log", cli_command_log, NULL); + cli_add_command(cli, "vibro", cli_command_vibro, NULL); + cli_add_command(cli, "led", cli_command_led, NULL); + cli_add_command(cli, "gpio_set", cli_command_gpio_set, NULL); + cli_add_command(cli, "os_info", cli_command_os_info, NULL); } diff --git a/applications/gui/gui.c b/applications/gui/gui.c index 05e4a51d..6ef701b9 100644 --- a/applications/gui/gui.c +++ b/applications/gui/gui.c @@ -213,7 +213,7 @@ void gui_cli_screen_stream_callback(uint8_t* data, size_t size, void* context) { cli_write(gui->cli, data, size); } -void gui_cli_screen_stream(string_t args, void* context) { +void gui_cli_screen_stream(Cli* cli, string_t args, void* context) { furi_assert(context); Gui* gui = context; gui_set_framebuffer_callback_context(gui, gui); diff --git a/applications/gui/gui_i.h b/applications/gui/gui_i.h index 86f1ab26..441722c7 100644 --- a/applications/gui/gui_i.h +++ b/applications/gui/gui_i.h @@ -62,4 +62,4 @@ void gui_unlock(Gui* gui); void gui_cli_screen_stream_callback(uint8_t* data, size_t size, void* context); -void gui_cli_screen_stream(string_t args, void* context); \ No newline at end of file +void gui_cli_screen_stream(Cli* cli, string_t args, void* context); \ No newline at end of file diff --git a/applications/ibutton/ibutton-app.cpp b/applications/ibutton/ibutton-app.cpp index 1f7aa630..c2663d62 100644 --- a/applications/ibutton/ibutton-app.cpp +++ b/applications/ibutton/ibutton-app.cpp @@ -65,7 +65,7 @@ bool iButtonApp::read_hex_byte(string_t args, uint8_t* byte) { return true; } -void iButtonApp::cli_cmd_callback(string_t args, void* context) { +void iButtonApp::cli_cmd_callback(Cli* cli, string_t args, void* context) { iButtonApp::Scene scene; string_t cmd; string_init(cmd); diff --git a/applications/ibutton/ibutton-app.h b/applications/ibutton/ibutton-app.h index 837204c6..64bae52a 100644 --- a/applications/ibutton/ibutton-app.h +++ b/applications/ibutton/ibutton-app.h @@ -110,7 +110,7 @@ public: char* get_file_name(); uint8_t get_file_name_size(); - void cli_cmd_callback(string_t args, void* context); + void cli_cmd_callback(Cli* cli, string_t args, void* context); void cli_send_event(CliEvent scene); void generate_random_name(char* name, uint8_t max_name_size); diff --git a/applications/input/input.c b/applications/input/input.c index fda9a5f1..882304b7 100644 --- a/applications/input/input.c +++ b/applications/input/input.c @@ -39,7 +39,7 @@ void input_isr(void* _ctx) { osThreadFlagsSet(input->thread, INPUT_THREAD_FLAG_ISR); } -void input_cli_send(string_t args, void* context) { +void input_cli_send(Cli* cli, string_t args, void* context) { InputEvent event; // Get first word as key name diff --git a/applications/internal-storage/internal-storage.c b/applications/internal-storage/internal-storage.c index 31c34647..32867bd3 100644 --- a/applications/internal-storage/internal-storage.c +++ b/applications/internal-storage/internal-storage.c @@ -124,27 +124,50 @@ int32_t internal_storage_task(void* p) { internal_storage->config.block_count, internal_storage->config.block_cycles); - int err = lfs_mount(&internal_storage->lfs, &internal_storage->config); - if(err == 0) { - FURI_LOG_I("internal-storage", "Mounted"); - internal_storage->state = InternalStorageStateReady; - } else { - FURI_LOG_E("internal-storage", "Mount failed, formatting"); + int err; + ApiHalBootFlag boot_flags = api_hal_boot_get_flags(); + if(boot_flags & ApiHalBootFlagFactoryReset) { + // Factory reset err = lfs_format(&internal_storage->lfs, &internal_storage->config); if(err == 0) { - FURI_LOG_I("internal-storage", "Format successful, trying to mount"); + FURI_LOG_I("internal-storage", "Factory reset: Format successful, trying to mount"); + api_hal_boot_set_flags(boot_flags & ~ApiHalBootFlagFactoryReset); err = lfs_mount(&internal_storage->lfs, &internal_storage->config); if(err == 0) { - FURI_LOG_I("internal-storage", "Mounted"); + FURI_LOG_I("internal-storage", "Factory reset: Mounted"); internal_storage->state = InternalStorageStateReady; } else { - FURI_LOG_E("internal-storage", "Mount after format failed"); + FURI_LOG_E("internal-storage", "Factory reset: Mount after format failed"); internal_storage->state = InternalStorageStateBroken; } } else { - FURI_LOG_E("internal-storage", "Format failed"); + FURI_LOG_E("internal-storage", "Factory reset: Format failed"); internal_storage->state = InternalStorageStateBroken; } + } else { + // Normal + err = lfs_mount(&internal_storage->lfs, &internal_storage->config); + if(err == 0) { + FURI_LOG_I("internal-storage", "Mounted"); + internal_storage->state = InternalStorageStateReady; + } else { + FURI_LOG_E("internal-storage", "Mount failed, formatting"); + err = lfs_format(&internal_storage->lfs, &internal_storage->config); + if(err == 0) { + FURI_LOG_I("internal-storage", "Format successful, trying to mount"); + err = lfs_mount(&internal_storage->lfs, &internal_storage->config); + if(err == 0) { + FURI_LOG_I("internal-storage", "Mounted"); + internal_storage->state = InternalStorageStateReady; + } else { + FURI_LOG_E("internal-storage", "Mount after format failed"); + internal_storage->state = InternalStorageStateBroken; + } + } else { + FURI_LOG_E("internal-storage", "Format failed"); + internal_storage->state = InternalStorageStateBroken; + } + } } furi_record_create("internal-storage", internal_storage); diff --git a/applications/irda/irda_app.c b/applications/irda/irda_app.c index 2833fc71..896cb7aa 100644 --- a/applications/irda/irda_app.c +++ b/applications/irda/irda_app.c @@ -185,7 +185,7 @@ void init_packet( state->packets[index].command = command; } -void irda_cli_cmd_rx(string_t args, void* context) { +void irda_cli_cmd_rx(Cli* cli, string_t args, void* context) { furi_assert(context); IrDAPacket packet; IrDAApp* app = context; @@ -211,7 +211,7 @@ void irda_cli_cmd_rx(string_t args, void* context) { return; } -void irda_cli_cmd_tx(string_t args, void* context) { +void irda_cli_cmd_tx(Cli* cli, string_t args, void* context) { furi_assert(context); ValueMutex* state_mutex = context; // Read protocol name diff --git a/applications/nfc/nfc.c b/applications/nfc/nfc.c index 1cbf88a6..9faa761a 100755 --- a/applications/nfc/nfc.c +++ b/applications/nfc/nfc.c @@ -130,10 +130,7 @@ void nfc_free(Nfc* nfc) { free(nfc); } -void nfc_cli_detect(string_t args, void* context) { - furi_assert(context); - Cli* cli = context; - +void nfc_cli_detect(Cli* cli, string_t args, void* context) { // Check if nfc worker is not busy if(api_hal_nfc_is_busy()) { printf("Nfc is busy"); @@ -167,7 +164,7 @@ void nfc_cli_detect(string_t args, void* context) { void nfc_cli_init() { Cli* cli = furi_record_open("cli"); - cli_add_command(cli, "nfc_detect", nfc_cli_detect, cli); + cli_add_command(cli, "nfc_detect", nfc_cli_detect, NULL); furi_record_close("cli"); } diff --git a/applications/power/power_cli.c b/applications/power/power_cli.c index ea7caf58..2a535ab1 100644 --- a/applications/power/power_cli.c +++ b/applications/power/power_cli.c @@ -1,36 +1,50 @@ #include "power_cli.h" #include -void power_cli_poweroff(string_t args, void* context) { +void power_cli_poweroff(Cli* cli, string_t args, void* context) { Power* power = context; power_off(power); } -void power_cli_reset(string_t args, void* context) { +void power_cli_reset(Cli* cli, string_t args, void* context) { Power* power = context; power_reset(power, PowerBootModeNormal); } -void power_cli_dfu(string_t args, void* context) { +void power_cli_dfu(Cli* cli, string_t args, void* context) { Power* power = context; power_reset(power, PowerBootModeDfu); } -void power_cli_test(string_t args, void* context) { +void power_cli_factory_reset(Cli* cli, string_t args, void* context) { + Power* power = context; + printf("All data will be lost. Are you sure (y/n)?\r\n"); + char c = cli_getc(cli); + if(c == 'y' || c == 'Y') { + printf("Data will be wiped after reboot.\r\n"); + api_hal_boot_set_flags(ApiHalBootFlagFactoryReset); + power_reset(power, PowerBootModeNormal); + } else { + printf("Safe choice.\r\n"); + } +} + +void power_cli_test(Cli* cli, string_t args, void* context) { api_hal_power_dump_state(); } -void power_cli_otg_on(string_t args, void* context) { +void power_cli_otg_on(Cli* cli, string_t args, void* context) { api_hal_power_enable_otg(); } -void power_cli_otg_off(string_t args, void* context) { +void power_cli_otg_off(Cli* cli, string_t args, void* context) { api_hal_power_disable_otg(); } void power_cli_init(Cli* cli, Power* power) { cli_add_command(cli, "poweroff", power_cli_poweroff, power); cli_add_command(cli, "reset", power_cli_reset, power); + cli_add_command(cli, "factory_reset", power_cli_factory_reset, power); cli_add_command(cli, "dfu", power_cli_dfu, power); cli_add_command(cli, "power_test", power_cli_test, power); cli_add_command(cli, "power_otg_on", power_cli_otg_on, power); diff --git a/applications/sd-card-test/sd-card-test.cpp b/applications/sd-card-test/sd-card-test.cpp index 7233e597..467c804a 100644 --- a/applications/sd-card-test/sd-card-test.cpp +++ b/applications/sd-card-test/sd-card-test.cpp @@ -82,8 +82,8 @@ public: void hash_benchmark(); // cli tests - void cli_read_benchmark(string_t args, void* _ctx); - void cli_write_benchmark(string_t args, void* _ctx); + void cli_read_benchmark(Cli* cli, string_t args, void* _ctx); + void cli_write_benchmark(Cli* cli, string_t args, void* _ctx); }; // start app @@ -579,7 +579,7 @@ void SdTest::hash_benchmark() { wait_for_button(InputKeyOk); } -void SdTest::cli_read_benchmark(string_t args, void* _ctx) { +void SdTest::cli_read_benchmark(Cli* cli, string_t args, void* _ctx) { SdTest* _this = static_cast(_ctx); const uint32_t benchmark_data_size = 16384 * 8; @@ -691,7 +691,7 @@ void SdTest::cli_read_benchmark(string_t args, void* _ctx) { printf("test completed\r\n"); } -void SdTest::cli_write_benchmark(string_t args, void* _ctx) { +void SdTest::cli_write_benchmark(Cli* cli, string_t args, void* _ctx) { SdTest* _this = static_cast(_ctx); const uint32_t b1_size = 1; diff --git a/applications/sd-filesystem/sd-filesystem.c b/applications/sd-filesystem/sd-filesystem.c index 42024836..dbeb1075 100644 --- a/applications/sd-filesystem/sd-filesystem.c +++ b/applications/sd-filesystem/sd-filesystem.c @@ -478,7 +478,7 @@ void app_sd_eject_callback(void* context) { /******************* Cli callbacks *******************/ -static void cli_sd_status(string_t args, void* _ctx) { +static void cli_sd_status(Cli* cli, string_t args, void* _ctx) { SdApp* sd_app = (SdApp*)_ctx; printf("SD status: "); @@ -486,7 +486,7 @@ static void cli_sd_status(string_t args, void* _ctx) { printf("\r\n"); } -static void cli_sd_format(string_t args, void* _ctx) { +static void cli_sd_format(Cli* cli, string_t args, void* _ctx) { SdApp* sd_app = (SdApp*)_ctx; printf("formatting SD card, please wait\r\n"); @@ -503,7 +503,7 @@ static void cli_sd_format(string_t args, void* _ctx) { } } -static void cli_sd_info(string_t args, void* _ctx) { +static void cli_sd_info(Cli* cli, string_t args, void* _ctx) { SdApp* sd_app = (SdApp*)_ctx; SDInfo sd_info; diff --git a/bootloader/targets/include/target.h b/bootloader/targets/include/target.h index e5ff7fb8..e16d4f78 100644 --- a/bootloader/targets/include/target.h +++ b/bootloader/targets/include/target.h @@ -1,25 +1,25 @@ #ifndef TARGET_H #define TARGET_H -/* +/** * Initialize hardware */ void target_init(); -/* +/** * Check if dfu mode requested * @return 1 if dfu mode requested, 0 if not -*/ + */ int target_is_dfu_requested(); -/* +/** * Switch to dfu mode -*/ + */ void target_switch2dfu(); -/* +/** * Switch to OS -*/ + */ void target_switch2os(); #endif \ No newline at end of file diff --git a/firmware/targets/api-hal-include/api-hal-boot.h b/firmware/targets/api-hal-include/api-hal-boot.h index 0b247c5c..45e46bab 100644 --- a/firmware/targets/api-hal-include/api-hal-boot.h +++ b/firmware/targets/api-hal-include/api-hal-boot.h @@ -11,9 +11,21 @@ typedef enum { ApiHalBootModeDFU } ApiHalBootMode; +/** Boot flags */ +typedef enum { + ApiHalBootFlagDefault=0, + ApiHalBootFlagFactoryReset=1, +} ApiHalBootFlag; + /** Set boot mode */ void api_hal_boot_set_mode(ApiHalBootMode mode); +/** Set boot flags */ +void api_hal_boot_set_flags(ApiHalBootFlag flags); + +/** Get boot flag */ +ApiHalBootFlag api_hal_boot_get_flags(); + #ifdef __cplusplus } #endif diff --git a/firmware/targets/f5/api-hal/api-hal-boot.c b/firmware/targets/f5/api-hal/api-hal-boot.c index 9193b939..1ea252fb 100644 --- a/firmware/targets/f5/api-hal/api-hal-boot.c +++ b/firmware/targets/f5/api-hal/api-hal-boot.c @@ -12,3 +12,10 @@ void api_hal_boot_set_mode(ApiHalBootMode mode) { } } +void api_hal_boot_set_flags(ApiHalBootFlag flags) { + LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR2, flags); +} + +ApiHalBootFlag api_hal_boot_get_flags() { + return LL_RTC_BAK_GetRegister(RTC, LL_RTC_BKP_DR2); +} \ No newline at end of file diff --git a/firmware/targets/f6/api-hal/api-hal-boot.c b/firmware/targets/f6/api-hal/api-hal-boot.c index 9193b939..1ea252fb 100644 --- a/firmware/targets/f6/api-hal/api-hal-boot.c +++ b/firmware/targets/f6/api-hal/api-hal-boot.c @@ -12,3 +12,10 @@ void api_hal_boot_set_mode(ApiHalBootMode mode) { } } +void api_hal_boot_set_flags(ApiHalBootFlag flags) { + LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR2, flags); +} + +ApiHalBootFlag api_hal_boot_get_flags() { + return LL_RTC_BAK_GetRegister(RTC, LL_RTC_BKP_DR2); +} \ No newline at end of file