From 99bbd8805ce00fee81c3c615a8eff430fc3bdd04 Mon Sep 17 00:00:00 2001 From: Mark Thompson <129641948+NotherNgineer@users.noreply.github.com> Date: Tue, 16 Jan 2024 23:59:35 -0600 Subject: [PATCH] Added Settings app to disable Config Mode (#1781) --- firmware/application/apps/ui_settings.cpp | 30 ++++++++++++++-- firmware/application/apps/ui_settings.hpp | 30 ++++++++++++++++ firmware/application/config_mode.cpp | 9 +++-- firmware/application/config_mode.hpp | 2 ++ .../common/portapack_persistent_memory.cpp | 34 ++++++++++++++----- .../common/portapack_persistent_memory.hpp | 13 ++++--- 6 files changed, 101 insertions(+), 17 deletions(-) diff --git a/firmware/application/apps/ui_settings.cpp b/firmware/application/apps/ui_settings.cpp index 56c96eac..4bd03760 100644 --- a/firmware/application/apps/ui_settings.cpp +++ b/firmware/application/apps/ui_settings.cpp @@ -43,6 +43,7 @@ namespace fs = std::filesystem; #include "string_format.hpp" #include "ui_styles.hpp" #include "cpld_update.hpp" +#include "config_mode.hpp" namespace pmem = portapack::persistent_memory; @@ -657,6 +658,30 @@ void AppSettingsView::focus() { menu_view.focus(); } +/* SetConfigModeView ************************************/ + +SetConfigModeView::SetConfigModeView(NavigationView& nav) { + add_children({&labels, + &checkbox_config_mode_enabled, + &button_save, + &button_cancel}); + + checkbox_config_mode_enabled.set_value(!pmem::config_disable_config_mode()); + + button_save.on_select = [&nav, this](Button&) { + pmem::set_config_disable_config_mode(!checkbox_config_mode_enabled.value()); + nav.pop(); + }; + + button_cancel.on_select = [&nav, this](Button&) { + nav.pop(); + }; +} + +void SetConfigModeView::focus() { + button_save.focus(); +} + /* SettingsMenuView **************************************/ SettingsMenuView::SettingsMenuView(NavigationView& nav) { @@ -667,15 +692,16 @@ SettingsMenuView::SettingsMenuView(NavigationView& nav) { {"App Settings", ui::Color::dark_cyan(), &bitmap_icon_notepad, [&nav]() { nav.push(); }}, {"Audio", ui::Color::dark_cyan(), &bitmap_icon_speaker, [&nav]() { nav.push(); }}, {"Calibration", ui::Color::dark_cyan(), &bitmap_icon_options_touch, [&nav]() { nav.push(); }}, + {"Config Mode", ui::Color::dark_cyan(), &bitmap_icon_clk_ext, [&nav]() { nav.push(); }}, {"Converter", ui::Color::dark_cyan(), &bitmap_icon_options_radio, [&nav]() { nav.push(); }}, {"Date/Time", ui::Color::dark_cyan(), &bitmap_icon_options_datetime, [&nav]() { nav.push(); }}, {"Encoder Dial", ui::Color::dark_cyan(), &bitmap_icon_setup, [&nav]() { nav.push(); }}, {"Freq. Correct", ui::Color::dark_cyan(), &bitmap_icon_options_radio, [&nav]() { nav.push(); }}, {"P.Memory Mgmt", ui::Color::dark_cyan(), &bitmap_icon_memory, [&nav]() { nav.push(); }}, - {"QR Code", ui::Color::dark_cyan(), &bitmap_icon_qr_code, [&nav]() { nav.push(); }}, {"Radio", ui::Color::dark_cyan(), &bitmap_icon_options_radio, [&nav]() { nav.push(); }}, - {"User Interface", ui::Color::dark_cyan(), &bitmap_icon_options_ui, [&nav]() { nav.push(); }}, {"SD Card", ui::Color::dark_cyan(), &bitmap_icon_sdcard, [&nav]() { nav.push(); }}, + {"User Interface", ui::Color::dark_cyan(), &bitmap_icon_options_ui, [&nav]() { nav.push(); }}, + {"QR Code", ui::Color::dark_cyan(), &bitmap_icon_qr_code, [&nav]() { nav.push(); }}, }); set_max_rows(2); // allow wider buttons } diff --git a/firmware/application/apps/ui_settings.hpp b/firmware/application/apps/ui_settings.hpp index e3973b0c..4016de66 100644 --- a/firmware/application/apps/ui_settings.hpp +++ b/firmware/application/apps/ui_settings.hpp @@ -581,6 +581,36 @@ class AppSettingsView : public View { true}; }; +class SetConfigModeView : public View { + public: + SetConfigModeView(NavigationView& nav); + + void focus() override; + + std::string title() const override { return "Config Mode"; }; + + private: + Labels labels{ + {{1 * 8, 1 * 16}, "Controls whether firmware", Color::light_grey()}, + {{1 * 8, 2 * 16}, "will enter Config Mode", Color::light_grey()}, + {{1 * 8, 3 * 16}, "after a boot failure.", Color::light_grey()}, + }; + + Checkbox checkbox_config_mode_enabled{ + {2 * 8, 6 * 16}, + 16, + "Config Mode enable"}; + + Button button_save{ + {2 * 8, 16 * 16, 12 * 8, 32}, + "Save"}; + + Button button_cancel{ + {16 * 8, 16 * 16, 12 * 8, 32}, + "Cancel", + }; +}; + class SettingsMenuView : public BtnGridView { public: SettingsMenuView(NavigationView& nav); diff --git a/firmware/application/config_mode.cpp b/firmware/application/config_mode.cpp index 1256bc11..65decf11 100644 --- a/firmware/application/config_mode.cpp +++ b/firmware/application/config_mode.cpp @@ -27,15 +27,18 @@ void config_mode_blink_until_dfu(); void config_mode_set() { - portapack::persistent_memory::set_config_mode_storage(CONFIG_MODE_GUARD_VALUE); + portapack::persistent_memory::set_config_mode_storage_direct(CONFIG_MODE_GUARD_VALUE); } bool config_mode_should_enter() { - return portapack::persistent_memory::config_mode_storage() == CONFIG_MODE_GUARD_VALUE; + if (portapack::persistent_memory::config_disable_config_mode_direct()) + return false; + else + return portapack::persistent_memory::config_mode_storage_direct() == CONFIG_MODE_GUARD_VALUE; } void config_mode_clear() { - portapack::persistent_memory::set_config_mode_storage(CONFIG_MODE_NORMAL_VALUE); + portapack::persistent_memory::set_config_mode_storage_direct(CONFIG_MODE_NORMAL_VALUE); } uint32_t blink_patterns[] = { diff --git a/firmware/application/config_mode.hpp b/firmware/application/config_mode.hpp index b3945ac5..e4f2f51c 100644 --- a/firmware/application/config_mode.hpp +++ b/firmware/application/config_mode.hpp @@ -31,6 +31,8 @@ void config_mode_set(); bool config_mode_should_enter(); void config_mode_clear(); +void config_mode_enable(bool v); +bool config_mode_disabled(); void config_mode_run(); diff --git a/firmware/common/portapack_persistent_memory.cpp b/firmware/common/portapack_persistent_memory.cpp index d05b4af3..87b1e842 100644 --- a/firmware/common/portapack_persistent_memory.cpp +++ b/firmware/common/portapack_persistent_memory.cpp @@ -145,7 +145,7 @@ struct misc_config_t { bool disable_speaker : 1; bool config_disable_external_tcxo : 1; bool config_sdcard_high_speed_io : 1; - bool UNUSED_4 : 1; + bool config_disable_config_mode : 1; bool UNUSED_5 : 1; bool UNUSED_6 : 1; bool UNUSED_7 : 1; @@ -156,6 +156,8 @@ struct misc_config_t { }; static_assert(sizeof(misc_config_t) == sizeof(uint32_t)); +#define MC_CONFIG_DISABLE_CONFIG_MODE 0x00000010 // config_disable_config_mode bit in struct above + /* IMPORTANT: Update dump_persistent_memory (below) when changing data_t. */ /* Struct must pack the same way on M4 and M0 cores. @@ -386,6 +388,7 @@ namespace cache { void defaults() { cached_backup_ram = backup_ram_t(); + // If the desired default is 0/false, then no need to set it here (buffer is initialized to 0) set_config_backlight_timer(backlight_config_t{}); set_config_splash(true); set_config_disable_external_tcxo(false); @@ -416,8 +419,8 @@ void init() { const auto switches_state = get_switches_state(); // ignore for valid check - auto config_mode_backup = config_mode_storage(); - set_config_mode_storage(CONFIG_MODE_NORMAL_VALUE); + auto config_mode_backup = config_mode_storage_direct(); + set_config_mode_storage_direct(CONFIG_MODE_NORMAL_VALUE); if (!(switches_state[(size_t)ui::KeyEvent::Left] && switches_state[(size_t)ui::KeyEvent::Right]) && backup_ram->is_valid()) { // Copy valid persistent data into cache. @@ -434,7 +437,7 @@ void init() { // Copy defaults into cache. defaults(); } - set_config_mode_storage(config_mode_backup); + set_config_mode_storage_direct(config_mode_backup); } void persist() { @@ -598,6 +601,10 @@ bool config_disable_external_tcxo() { return data->misc_config.config_disable_external_tcxo; } +bool config_disable_config_mode() { + return data->misc_config.config_disable_config_mode; +} + bool config_sdcard_high_speed_io() { return data->misc_config.config_sdcard_high_speed_io; } @@ -667,6 +674,10 @@ void set_config_disable_external_tcxo(bool v) { data->misc_config.config_disable_external_tcxo = v; } +void set_config_disable_config_mode(bool v) { + data->misc_config.config_disable_config_mode = v; +} + void set_config_sdcard_high_speed_io(bool v, bool save) { if (v) { /* 200MHz / (2 * 2) = 50MHz */ @@ -948,12 +959,18 @@ void set_encoder_dial_sensitivity(uint8_t v) { // Recovery mode magic value storage static data_t* data_direct_access = reinterpret_cast(memory::map::backup_ram.base()); -uint32_t config_mode_storage() { +uint32_t config_mode_storage_direct() { return data_direct_access->config_mode_storage; } -void set_config_mode_storage(uint32_t v) { +void set_config_mode_storage_direct(uint32_t v) { data_direct_access->config_mode_storage = v; } +bool config_disable_config_mode_direct() { + // "return data_direct_access->misc_config.config_disable_config_mode" + // Casting as U32 as workaround for misaligned memory access + uint32_t misc_config_u32 = *(uint32_t*)&data_direct_access->misc_config; + return ((misc_config_u32 & MC_CONFIG_DISABLE_CONFIG_MODE) != 0); +} // PMem to sdcard settings @@ -1088,8 +1105,9 @@ bool debug_dump() { // misc_config bits pmem_dump_file.write_line("misc_config config_audio_mute: " + to_string_dec_int(config_audio_mute())); pmem_dump_file.write_line("misc_config config_speaker_disable: " + to_string_dec_int(config_speaker_disable())); - pmem_dump_file.write_line("ui_config config_disable_external_tcxo: " + to_string_dec_uint(config_disable_external_tcxo())); - pmem_dump_file.write_line("ui_config config_sdcard_high_speed_io: " + to_string_dec_uint(config_sdcard_high_speed_io())); + pmem_dump_file.write_line("misc_config config_disable_external_tcxo: " + to_string_dec_uint(config_disable_external_tcxo())); + pmem_dump_file.write_line("misc_config config_sdcard_high_speed_io: " + to_string_dec_uint(config_sdcard_high_speed_io())); + pmem_dump_file.write_line("misc_config config_disable_config_mode: " + to_string_dec_uint(config_disable_config_mode())); // receiver_model pmem_dump_file.write_line("\n[Receiver Model]"); diff --git a/firmware/common/portapack_persistent_memory.hpp b/firmware/common/portapack_persistent_memory.hpp index aeeffaf7..bf90da7f 100644 --- a/firmware/common/portapack_persistent_memory.hpp +++ b/firmware/common/portapack_persistent_memory.hpp @@ -178,6 +178,8 @@ void set_config_cpld(uint8_t i); bool config_disable_external_tcxo(); bool config_sdcard_high_speed_io(); +bool config_disable_config_mode(); + bool config_splash(); bool config_converter(); bool config_updown_converter(); @@ -198,6 +200,8 @@ void set_save_app_settings(bool v); void set_show_bigger_qr_code(bool v); void set_config_disable_external_tcxo(bool v); void set_config_sdcard_high_speed_io(bool v, bool save); +void set_config_disable_config_mode(bool v); + void set_config_splash(bool v); bool config_converter(); bool config_updown_converter(); @@ -223,10 +227,11 @@ void set_disable_touchscreen(bool v); uint8_t config_encoder_dial_sensitivity(); void set_encoder_dial_sensitivity(uint8_t v); -#define CONFIG_MODE_GUARD_VALUE 2001 -#define CONFIG_MODE_NORMAL_VALUE 1999 -uint32_t config_mode_storage(); -void set_config_mode_storage(uint32_t v); +#define CONFIG_MODE_GUARD_VALUE 0x000007d1 +#define CONFIG_MODE_NORMAL_VALUE 0x000007cf +uint32_t config_mode_storage_direct(); +void set_config_mode_storage_direct(uint32_t v); +bool config_disable_config_mode_direct(); uint32_t pocsag_last_address(); void set_pocsag_last_address(uint32_t address);