diff --git a/firmware/application/CMakeLists.txt b/firmware/application/CMakeLists.txt index a422aaaf..2def6164 100644 --- a/firmware/application/CMakeLists.txt +++ b/firmware/application/CMakeLists.txt @@ -154,6 +154,7 @@ set(CPPSRC ${COMMON}/ui_widget.cpp ${COMMON}/utility.cpp ${COMMON}/wm8731.cpp + app_settings.cpp audio.cpp baseband_api.cpp capture_thread.cpp diff --git a/firmware/application/app_settings.cpp b/firmware/application/app_settings.cpp new file mode 100644 index 00000000..38fc9d2a --- /dev/null +++ b/firmware/application/app_settings.cpp @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2016 Furrtek + * Copyright (C) 2022 Arjan Onwezen + * + * This file is part of PortaPack. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "app_settings.hpp" + +#include "file.hpp" +#include "portapack.hpp" +#include "portapack_persistent_memory.hpp" +#include + +namespace std { + +int app_settings::load(std::string application, AppSettings* settings){ + + if (portapack::persistent_memory::load_app_settings()) { + file_path = folder+"/"+application+".ini"; + + auto error = settings_file.open(file_path); + if (!error.is_valid()) { + auto error = settings_file.read(file_content, 256); + + // Retrieve settings + auto position1 = strstr(file_content, "baseband_bandwidth="); + if (position1) { + position1 += 19; + settings->baseband_bandwidth=strtoll(position1, nullptr, 10); + } + + auto position2 = strstr(file_content, "rx_frequency="); + if (position2) { + position2 += 13; + settings->rx_frequency=strtoll(position2, nullptr, 10); + } + + auto position3 = strstr(file_content, "lna="); + if (position3) { + position3 += 4; + settings->lna=strtoll(position3, nullptr, 10); + } + + auto position4 = strstr(file_content, "rx_amp="); + if (position4) { + position4 += 7; + settings->rx_amp=strtoll(position4, nullptr, 10); + } + + auto position5 = strstr(file_content, "sampling_rate="); + if (position5) { + position5 += 13; + settings->sampling_rate=strtoll(position5, nullptr, 10); + } + + + auto position6 = strstr(file_content, "vga="); + if (position6) { + position6 += 4; + settings->vga=strtoll(position6, nullptr, 10); + } + + rc = SETTINGS_OK; + } + else rc = SETTINGS_UNABLE_TO_LOAD; + } + else rc = SETTINGS_DISABLED; + return(rc); +} + +int app_settings::save(std::string application, AppSettings* settings){ + + if (portapack::persistent_memory::save_app_settings()) { + file_path = folder+"/"+application+".ini"; + make_new_directory(folder); + + auto error = settings_file.create(file_path); + if (!error.is_valid()) { + // Save common setting + settings_file.write_line("baseband_bandwidth="+to_string_dec_uint(portapack::receiver_model.baseband_bandwidth())); + settings_file.write_line("lna="+to_string_dec_uint(portapack::receiver_model.lna())); + settings_file.write_line("rx_amp="+to_string_dec_uint(portapack::receiver_model.rf_amp())); + settings_file.write_line("sampling_rate="+to_string_dec_uint(portapack::receiver_model.sampling_rate())); + settings_file.write_line("vga="+to_string_dec_uint(portapack::receiver_model.vga())); + // Save other settings from struct + settings_file.write_line("rx_frequency="+to_string_dec_uint(settings->rx_frequency)); + + rc = SETTINGS_OK; + } + else rc = SETTINGS_UNABLE_TO_SAVE; + } + else rc = SETTINGS_DISABLED; + return(rc); +} + +} /* namespace std */ diff --git a/firmware/application/app_settings.hpp b/firmware/application/app_settings.hpp new file mode 100644 index 00000000..6205a596 --- /dev/null +++ b/firmware/application/app_settings.hpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2016 Furrtek + * Copyright (C) 2022 Arjan Onwezen + * + * This file is part of PortaPack. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __APP_SETTINGS_H__ +#define __APP_SETTINGS_H__ + + +#include +#include +#include + +#include "file.hpp" +#include "string_format.hpp" + + +namespace std { +class app_settings { + + + +public: + +#define SETTINGS_OK 0 // settings found +#define SETTINGS_UNABLE_TO_LOAD -1 // settings (file) not found +#define SETTINGS_UNABLE_TO_SAVE -2 // unable to save settings +#define SETTINGS_DISABLED -3 // load/save settings disabled in settings + + + // store settings that can't be set directly, but have to be stored in app + struct AppSettings { + uint32_t baseband_bandwidth; + uint8_t lna; + uint8_t rx_amp; + uint32_t rx_frequency; + uint32_t sampling_rate; + uint8_t vga; + }; + + int load(std::string application, AppSettings* settings); + int save(std::string application, AppSettings* settings); + + +private: + + + char file_content[257] = {}; + std::string file_path = ""; + std::string folder = "SETTINGS"; + int rc = SETTINGS_OK; + File settings_file { }; + + +}; // class app_settings +} // namespace std + + + +#endif/*__APP_SETTINGS_H__*/ diff --git a/firmware/application/apps/ais_app.cpp b/firmware/application/apps/ais_app.cpp index a5c25a55..1561fee2 100644 --- a/firmware/application/apps/ais_app.cpp +++ b/firmware/application/apps/ais_app.cpp @@ -335,24 +335,23 @@ AISAppView::AISAppView(NavigationView& nav) : nav_ { nav } { &recent_entry_detail_view, }); + + // load app settings + auto rc = settings.load("rx_ais", &app_settings); + if(rc == SETTINGS_OK) { + field_lna.set_value(app_settings.lna); + field_vga.set_value(app_settings.vga); + field_rf_amp.set_value(app_settings.rx_amp); + target_frequency_ = app_settings.rx_frequency; + } + else target_frequency_ = initial_target_frequency; + recent_entry_detail_view.hidden(true); - target_frequency_ = initial_target_frequency; - - receiver_model.set_tuning_frequency(tuning_frequency()); - receiver_model.set_sampling_rate(sampling_rate); - receiver_model.set_baseband_bandwidth(baseband_bandwidth); - receiver_model.enable(); // Before using radio::enable(), but not updating Ant.DC-Bias. - -/* radio::enable({ // this can be removed, previous version,no DC-bias control. - tuning_frequency(), - sampling_rate, - baseband_bandwidth, - rf::Direction::Receive, - receiver_model.rf_amp(), - static_cast(receiver_model.lna()), - static_cast(receiver_model.vga()), - }); */ + receiver_model.set_tuning_frequency(tuning_frequency()); + receiver_model.set_sampling_rate(sampling_rate); + receiver_model.set_baseband_bandwidth(baseband_bandwidth); + receiver_model.enable(); // Before using radio::enable(), but not updating Ant.DC-Bias. options_channel.on_change = [this](size_t, OptionsField::value_t v) { this->on_frequency_changed(v); @@ -373,7 +372,11 @@ AISAppView::AISAppView(NavigationView& nav) : nav_ { nav } { } AISAppView::~AISAppView() { -/* radio::disable(); */ + + // save app settings + app_settings.rx_frequency = target_frequency_; + settings.save("rx_ais", &app_settings); + receiver_model.disable(); // to switch off all, including DC bias. baseband::shutdown(); diff --git a/firmware/application/apps/ais_app.hpp b/firmware/application/apps/ais_app.hpp index c6a8a7d5..6d319ba0 100644 --- a/firmware/application/apps/ais_app.hpp +++ b/firmware/application/apps/ais_app.hpp @@ -33,7 +33,7 @@ #include "event_m0.hpp" #include "log_file.hpp" - +#include "app_settings.hpp" #include "ais_packet.hpp" #include "lpc43xx_cpp.hpp" @@ -173,6 +173,11 @@ private: static constexpr uint32_t sampling_rate = 2457600; static constexpr uint32_t baseband_bandwidth = 1750000; + + // app save settings + std::app_settings settings { }; + std::app_settings::AppSettings app_settings { }; + NavigationView& nav_; AISRecentEntries recent { }; diff --git a/firmware/application/apps/analog_audio_app.cpp b/firmware/application/apps/analog_audio_app.cpp index 6c4dec74..9777847f 100644 --- a/firmware/application/apps/analog_audio_app.cpp +++ b/firmware/application/apps/analog_audio_app.cpp @@ -129,10 +129,20 @@ AnalogAudioView::AnalogAudioView( &waterfall }); + // load app settings + auto rc = settings.load("rx_audio", &app_settings); + if(rc == SETTINGS_OK) { + field_lna.set_value(app_settings.lna); + field_vga.set_value(app_settings.vga); + receiver_model.set_rf_amp(app_settings.rx_amp); + field_frequency.set_value(app_settings.rx_frequency); + } + else field_frequency.set_value(receiver_model.tuning_frequency()); + + //Filename Datetime and Frequency record_view.set_filename_date_frequency(true); - field_frequency.set_value(receiver_model.tuning_frequency()); field_frequency.set_step(receiver_model.frequency_step()); field_frequency.on_change = [this](rf::Frequency f) { this->on_tuning_frequency_changed(f); @@ -210,6 +220,11 @@ void AnalogAudioView::set_spec_trigger(uint16_t trigger) { } AnalogAudioView::~AnalogAudioView() { + + // save app settings + app_settings.rx_frequency = field_frequency.value(); + settings.save("rx_audio", &app_settings); + // TODO: Manipulating audio codec here, and in ui_receiver.cpp. Good to do // both? audio::output::stop(); diff --git a/firmware/application/apps/analog_audio_app.hpp b/firmware/application/apps/analog_audio_app.hpp index 04795e47..fd6f5bc1 100644 --- a/firmware/application/apps/analog_audio_app.hpp +++ b/firmware/application/apps/analog_audio_app.hpp @@ -29,7 +29,7 @@ #include "ui_spectrum.hpp" #include "ui_record_view.hpp" #include "ui_font_fixed_8x16.hpp" - +#include "app_settings.hpp" #include "tone_key.hpp" @@ -154,6 +154,10 @@ public: private: static constexpr ui::Dim header_height = 3 * 16; + // app save settings + std::app_settings settings { }; + std::app_settings::AppSettings app_settings { }; + const Rect options_view_rect { 0 * 8, 1 * 16, 30 * 8, 1 * 16 }; const Rect nbfm_view_rect { 0 * 8, 1 * 16, 18 * 8, 1 * 16 }; diff --git a/firmware/application/apps/analog_tv_app.cpp b/firmware/application/apps/analog_tv_app.cpp index b3710573..50a1cb20 100644 --- a/firmware/application/apps/analog_tv_app.cpp +++ b/firmware/application/apps/analog_tv_app.cpp @@ -57,7 +57,18 @@ AnalogTvView::AnalogTvView( &tv }); - field_frequency.set_value(receiver_model.tuning_frequency()); + + // load app settings + auto rc = settings.load("rx_tv", &app_settings); + if(rc == SETTINGS_OK) { + field_lna.set_value(app_settings.lna); + field_vga.set_value(app_settings.vga); + receiver_model.set_rf_amp(app_settings.rx_amp); + field_frequency.set_value(app_settings.rx_frequency); + } + else field_frequency.set_value(receiver_model.tuning_frequency()); + + field_frequency.set_step(receiver_model.frequency_step()); field_frequency.on_change = [this](rf::Frequency f) { this->on_tuning_frequency_changed(f); @@ -106,12 +117,15 @@ AnalogTvView::AnalogTvView( } AnalogTvView::~AnalogTvView() { + + // save app settings + app_settings.rx_frequency = field_frequency.value(); + settings.save("rx_tv", &app_settings); + // TODO: Manipulating audio codec here, and in ui_receiver.cpp. Good to do // both? audio::output::stop(); - receiver_model.disable(); - baseband::shutdown(); } diff --git a/firmware/application/apps/analog_tv_app.hpp b/firmware/application/apps/analog_tv_app.hpp index 81ac8ea5..def1c940 100644 --- a/firmware/application/apps/analog_tv_app.hpp +++ b/firmware/application/apps/analog_tv_app.hpp @@ -29,7 +29,7 @@ #include "ui_receiver.hpp" #include "ui_tv.hpp" #include "ui_record_view.hpp" - +#include "app_settings.hpp" #include "ui_font_fixed_8x16.hpp" #include "tone_key.hpp" @@ -58,6 +58,10 @@ public: private: static constexpr ui::Dim header_height = 3 * 16; + // app save settings + std::app_settings settings { }; + std::app_settings::AppSettings app_settings { }; + const Rect options_view_rect { 0 * 8, 1 * 16, 30 * 8, 1 * 16 }; const Rect nbfm_view_rect { 0 * 8, 1 * 16, 18 * 8, 1 * 16 }; diff --git a/firmware/application/apps/ert_app.cpp b/firmware/application/apps/ert_app.cpp index 91b3e5e1..5ab68fa9 100644 --- a/firmware/application/apps/ert_app.cpp +++ b/firmware/application/apps/ert_app.cpp @@ -105,6 +105,15 @@ ERTAppView::ERTAppView(NavigationView&) { &recent_entries_view, }); + // load app settings + auto rc = settings.load("rx_ert", &app_settings); + if(rc == SETTINGS_OK) { + field_lna.set_value(app_settings.lna); + field_vga.set_value(app_settings.vga); + field_rf_amp.set_value(app_settings.rx_amp); + } + + radio::enable({ initial_target_frequency, sampling_rate, @@ -122,6 +131,10 @@ ERTAppView::ERTAppView(NavigationView&) { } ERTAppView::~ERTAppView() { + + // save app settings + settings.save("rx_ert", &app_settings); + radio::disable(); baseband::shutdown(); diff --git a/firmware/application/apps/ert_app.hpp b/firmware/application/apps/ert_app.hpp index 19cf70d0..ea4e11c6 100644 --- a/firmware/application/apps/ert_app.hpp +++ b/firmware/application/apps/ert_app.hpp @@ -28,7 +28,7 @@ #include "ui_channel.hpp" #include "event_m0.hpp" - +#include "app_settings.hpp" #include "log_file.hpp" #include "ert_packet.hpp" @@ -131,6 +131,11 @@ private: ERTRecentEntries recent { }; std::unique_ptr logger { }; + // app save settings + std::app_settings settings { }; + std::app_settings::AppSettings app_settings { }; + + const RecentEntriesColumns columns { { { "ID", 10 }, { "Tp", 2 }, diff --git a/firmware/application/apps/pocsag_app.cpp b/firmware/application/apps/pocsag_app.cpp index cb5cacfe..d5f28508 100644 --- a/firmware/application/apps/pocsag_app.cpp +++ b/firmware/application/apps/pocsag_app.cpp @@ -77,11 +77,20 @@ POCSAGAppView::POCSAGAppView(NavigationView& nav) { &console }); + // load app settings + auto rc = settings.load("rx_pocsag", &app_settings); + if(rc == SETTINGS_OK) { + field_lna.set_value(app_settings.lna); + field_vga.set_value(app_settings.vga); + field_rf_amp.set_value(app_settings.rx_amp); + field_frequency.set_value(app_settings.rx_frequency); + } + else field_frequency.set_value(receiver_model.tuning_frequency()); + receiver_model.set_sampling_rate(3072000); receiver_model.set_baseband_bandwidth(1750000); receiver_model.enable(); - field_frequency.set_value(receiver_model.tuning_frequency()); field_frequency.set_step(receiver_model.frequency_step()); field_frequency.on_change = [this](rf::Frequency f) { update_freq(f); @@ -127,6 +136,11 @@ POCSAGAppView::POCSAGAppView(NavigationView& nav) { } POCSAGAppView::~POCSAGAppView() { + + // save app settings + app_settings.rx_frequency = field_frequency.value(); + settings.save("rx_pocsag", &app_settings); + audio::output::stop(); // Save ignored address diff --git a/firmware/application/apps/pocsag_app.hpp b/firmware/application/apps/pocsag_app.hpp index b917926c..8ea3c4b9 100644 --- a/firmware/application/apps/pocsag_app.hpp +++ b/firmware/application/apps/pocsag_app.hpp @@ -28,7 +28,7 @@ #include "ui_rssi.hpp" #include "log_file.hpp" - +#include "app_settings.hpp" #include "pocsag.hpp" #include "pocsag_packet.hpp" @@ -60,6 +60,10 @@ public: private: static constexpr uint32_t initial_target_frequency = 466175000; + // app save settings + std::app_settings settings { }; + std::app_settings::AppSettings app_settings { }; + bool logging { true }; bool ignore { true }; uint32_t last_address = 0xFFFFFFFF; diff --git a/firmware/application/apps/tpms_app.cpp b/firmware/application/apps/tpms_app.cpp index 7858d7a2..69e137e9 100644 --- a/firmware/application/apps/tpms_app.cpp +++ b/firmware/application/apps/tpms_app.cpp @@ -151,6 +151,16 @@ TPMSAppView::TPMSAppView(NavigationView&) { &options_type, }); + // load app settings + auto rc = settings.load("rx_tpms", &app_settings); + if(rc == SETTINGS_OK) { + field_lna.set_value(app_settings.lna); + field_vga.set_value(app_settings.vga); + field_rf_amp.set_value(app_settings.rx_amp); + options_band.set_by_value(app_settings.rx_frequency); + } + else options_band.set_by_value(receiver_model.tuning_frequency()); + radio::enable({ tuning_frequency(), sampling_rate, @@ -184,6 +194,12 @@ TPMSAppView::TPMSAppView(NavigationView&) { } TPMSAppView::~TPMSAppView() { + + + // save app settings + app_settings.rx_frequency = target_frequency_; + settings.save("rx_tpms", &app_settings); + radio::disable(); baseband::shutdown(); diff --git a/firmware/application/apps/tpms_app.hpp b/firmware/application/apps/tpms_app.hpp index 2d9b670d..9544554f 100644 --- a/firmware/application/apps/tpms_app.hpp +++ b/firmware/application/apps/tpms_app.hpp @@ -27,7 +27,7 @@ #include "ui_receiver.hpp" #include "ui_rssi.hpp" #include "ui_channel.hpp" - +#include "app_settings.hpp" #include "event_m0.hpp" #include "log_file.hpp" @@ -110,6 +110,10 @@ private: static constexpr uint32_t sampling_rate = 2457600; static constexpr uint32_t baseband_bandwidth = 1750000; + // app save settings + std::app_settings settings { }; + std::app_settings::AppSettings app_settings { }; + MessageHandlerRegistration message_handler_packet { Message::ID::TPMSPacket, [this](Message* const p) { diff --git a/firmware/application/apps/ui_adsb_rx.cpp b/firmware/application/apps/ui_adsb_rx.cpp index 1731061f..a9d61928 100644 --- a/firmware/application/apps/ui_adsb_rx.cpp +++ b/firmware/application/apps/ui_adsb_rx.cpp @@ -309,8 +309,11 @@ void ADSBRxView::focus() { } ADSBRxView::~ADSBRxView() { - receiver_model.set_tuning_frequency(prevFreq); + // save app settings + settings.save("rx_adsb", &app_settings); + + receiver_model.set_tuning_frequency(prevFreq); rtc_time::signal_tick_second -= signal_token_tick_second; receiver_model.disable(); baseband::shutdown(); @@ -458,6 +461,21 @@ ADSBRxView::ADSBRxView(NavigationView& nav) { &recent_entries_view }); + + // load app settings + auto rc = settings.load("rx_adsb", &app_settings); + if(rc == SETTINGS_OK) { + field_lna.set_value(app_settings.lna); + field_vga.set_value(app_settings.vga); + field_rf_amp.set_value(app_settings.rx_amp); + } + else + { + field_lna.set_value(40); + field_vga.set_value(40); + } + + recent_entries_view.set_parent_rect({ 0, 16, 240, 272 }); recent_entries_view.on_select = [this, &nav](const AircraftRecentEntry& entry) { detailed_entry_key = entry.key(); @@ -478,8 +496,6 @@ ADSBRxView::ADSBRxView(NavigationView& nav) { baseband::set_adsb(); receiver_model.set_tuning_frequency(1090000000); - field_lna.set_value(40); - field_vga.set_value(40); receiver_model.set_modulation(ReceiverModel::Mode::SpectrumAnalysis); receiver_model.set_sampling_rate(2000000); receiver_model.set_baseband_bandwidth(2500000); diff --git a/firmware/application/apps/ui_adsb_rx.hpp b/firmware/application/apps/ui_adsb_rx.hpp index 879e9d8c..e882b8db 100644 --- a/firmware/application/apps/ui_adsb_rx.hpp +++ b/firmware/application/apps/ui_adsb_rx.hpp @@ -32,7 +32,7 @@ #include "log_file.hpp" #include "adsb.hpp" #include "message.hpp" - +#include "app_settings.hpp" #include "crc.hpp" using namespace adsb; @@ -372,6 +372,9 @@ private: std::unique_ptr logger { }; void on_frame(const ADSBFrameMessage * message); void on_tick_second(); + // app save settings + std::app_settings settings { }; + std::app_settings::AppSettings app_settings { }; const RecentEntriesColumns columns { { #if false diff --git a/firmware/application/apps/ui_afsk_rx.cpp b/firmware/application/apps/ui_afsk_rx.cpp index 4b8fc3e7..54792f57 100644 --- a/firmware/application/apps/ui_afsk_rx.cpp +++ b/firmware/application/apps/ui_afsk_rx.cpp @@ -66,6 +66,15 @@ AFSKRxView::AFSKRxView(NavigationView& nav) { &console }); + // load app settings + auto rc = settings.load("rx_afsk", &app_settings); + if(rc == SETTINGS_OK) { + field_lna.set_value(app_settings.lna); + field_vga.set_value(app_settings.vga); + field_rf_amp.set_value(app_settings.rx_amp); + } + + // DEBUG record_view.on_error = [&nav](std::string message) { nav.display_modal("Error", message); @@ -164,6 +173,11 @@ void AFSKRxView::on_data(uint32_t value, bool is_data) { } AFSKRxView::~AFSKRxView() { + + // save app settings + app_settings.rx_frequency = field_frequency.value(); + settings.save("rx_afsk", &app_settings); + audio::output::stop(); receiver_model.disable(); baseband::shutdown(); diff --git a/firmware/application/apps/ui_afsk_rx.hpp b/firmware/application/apps/ui_afsk_rx.hpp index 86f0f28f..dccf0e01 100644 --- a/firmware/application/apps/ui_afsk_rx.hpp +++ b/firmware/application/apps/ui_afsk_rx.hpp @@ -27,7 +27,7 @@ #include "ui_navigation.hpp" #include "ui_receiver.hpp" #include "ui_record_view.hpp" // DEBUG - +#include "app_settings.hpp" #include "log_file.hpp" #include "utility.hpp" @@ -57,6 +57,10 @@ public: private: void on_data(uint32_t value, bool is_data); + // app save settings + std::app_settings settings { }; + std::app_settings::AppSettings app_settings { }; + uint8_t console_color { 0 }; uint32_t prev_value { 0 }; std::string str_log { "" }; diff --git a/firmware/application/apps/ui_aprs_rx.cpp b/firmware/application/apps/ui_aprs_rx.cpp index 1bcfd273..c1f16893 100644 --- a/firmware/application/apps/ui_aprs_rx.cpp +++ b/firmware/application/apps/ui_aprs_rx.cpp @@ -98,6 +98,15 @@ APRSRxView::APRSRxView(NavigationView& nav, Rect parent_rect) : View(parent_rect &console }); + // load app settings + auto rc = settings.load("rx_aprs", &app_settings); + if(rc == SETTINGS_OK) { + field_lna.set_value(app_settings.lna); + field_vga.set_value(app_settings.vga); + field_rf_amp.set_value(app_settings.rx_amp); + } + + // DEBUG record_view.on_error = [&nav](std::string message) { nav.display_modal("Error", message); @@ -211,6 +220,10 @@ void APRSRxView::on_show(){ } APRSRxView::~APRSRxView() { + + // save app settings + settings.save("rx_aprs", &app_settings); + audio::output::stop(); receiver_model.disable(); baseband::shutdown(); diff --git a/firmware/application/apps/ui_aprs_rx.hpp b/firmware/application/apps/ui_aprs_rx.hpp index 9ea29559..1a37df92 100644 --- a/firmware/application/apps/ui_aprs_rx.hpp +++ b/firmware/application/apps/ui_aprs_rx.hpp @@ -28,7 +28,7 @@ #include "ui_receiver.hpp" #include "ui_record_view.hpp" // DEBUG #include "ui_geomap.hpp" - +#include "app_settings.hpp" #include "recent_entries.hpp" #include "ui_tabview.hpp" @@ -131,6 +131,7 @@ private: GeoMapView* geomap_view { nullptr }; bool send_updates { false }; + Console console { { 0, 0 * 16, 240, 224 } }; @@ -192,6 +193,11 @@ private: void on_data(uint32_t value, bool is_data); bool reset_console = false; + // app save settings + std::app_settings settings { }; + std::app_settings::AppSettings app_settings { }; + + uint8_t console_color { 0 }; std::string str_log { "" }; diff --git a/firmware/application/apps/ui_btle_rx.cpp b/firmware/application/apps/ui_btle_rx.cpp index d4b9afee..226f9dc1 100644 --- a/firmware/application/apps/ui_btle_rx.cpp +++ b/firmware/application/apps/ui_btle_rx.cpp @@ -60,6 +60,15 @@ BTLERxView::BTLERxView(NavigationView& nav) { &console }); + // load app settings + auto rc = settings.load("rx_btle", &app_settings); + if(rc == SETTINGS_OK) { + field_lna.set_value(app_settings.lna); + field_vga.set_value(app_settings.vga); + field_rf_amp.set_value(app_settings.rx_amp); + } + + // DEBUG record_view.on_error = [&nav](std::string message) { nav.display_modal("Error", message); @@ -152,6 +161,11 @@ void BTLERxView::on_data(uint32_t value, bool is_data) { } BTLERxView::~BTLERxView() { + + // save app settings + app_settings.rx_frequency = field_frequency.value(); + settings.save("rx_btle", &app_settings); + audio::output::stop(); receiver_model.disable(); baseband::shutdown(); diff --git a/firmware/application/apps/ui_btle_rx.hpp b/firmware/application/apps/ui_btle_rx.hpp index 9e331eef..91bf0710 100644 --- a/firmware/application/apps/ui_btle_rx.hpp +++ b/firmware/application/apps/ui_btle_rx.hpp @@ -27,6 +27,7 @@ #include "ui.hpp" #include "ui_navigation.hpp" #include "ui_receiver.hpp" +#include "app_settings.hpp" #include "ui_record_view.hpp" // DEBUG #include "utility.hpp" @@ -45,6 +46,11 @@ public: private: void on_data(uint32_t value, bool is_data); + + // app save settings + std::app_settings settings { }; + std::app_settings::AppSettings app_settings { }; + uint8_t console_color { 0 }; uint32_t prev_value { 0 }; std::string str_log { "" }; diff --git a/firmware/application/apps/ui_nrf_rx.cpp b/firmware/application/apps/ui_nrf_rx.cpp index 32982ae6..d5d916f8 100644 --- a/firmware/application/apps/ui_nrf_rx.cpp +++ b/firmware/application/apps/ui_nrf_rx.cpp @@ -60,6 +60,14 @@ NRFRxView::NRFRxView(NavigationView& nav) { &console }); + // load app settings + auto rc = settings.load("rx_nrf", &app_settings); + if(rc == SETTINGS_OK) { + field_lna.set_value(app_settings.lna); + field_vga.set_value(app_settings.vga); + field_rf_amp.set_value(app_settings.rx_amp); + } + // DEBUG record_view.on_error = [&nav](std::string message) { nav.display_modal("Error", message); @@ -157,6 +165,11 @@ void NRFRxView::on_data(uint32_t value, bool is_data) { } NRFRxView::~NRFRxView() { + + // save app settings + app_settings.rx_frequency = field_frequency.value(); + settings.save("rx_nrf", &app_settings); + audio::output::stop(); receiver_model.disable(); baseband::shutdown(); diff --git a/firmware/application/apps/ui_nrf_rx.hpp b/firmware/application/apps/ui_nrf_rx.hpp index 4f72b25b..18a6f814 100644 --- a/firmware/application/apps/ui_nrf_rx.hpp +++ b/firmware/application/apps/ui_nrf_rx.hpp @@ -27,6 +27,7 @@ #include "ui.hpp" #include "ui_navigation.hpp" #include "ui_receiver.hpp" +#include "app_settings.hpp" #include "ui_record_view.hpp" // DEBUG #include "utility.hpp" @@ -45,6 +46,10 @@ public: private: void on_data(uint32_t value, bool is_data); + // app save settings + std::app_settings settings { }; + std::app_settings::AppSettings app_settings { }; + uint8_t console_color { 0 }; uint32_t prev_value { 0 }; std::string str_log { "" }; diff --git a/firmware/application/apps/ui_settings.cpp b/firmware/application/apps/ui_settings.cpp index 5b3cc4d3..bb1792b5 100644 --- a/firmware/application/apps/ui_settings.cpp +++ b/firmware/application/apps/ui_settings.cpp @@ -257,12 +257,6 @@ SetUIView::SetUIView(NavigationView& nav) { options_clockformat.set_selected_index(0); } - //checkbox_speaker.on_select = [this](Checkbox&, bool v) { - // if (v) audio::output::speaker_mute(); //Just mute audio if speaker is disabled - // persistent_memory::set_config_speaker(v); //Store Speaker status - // StatusRefreshMessage message { }; //Refresh status bar with/out speaker - // EventDispatcher::send_message(message); - //}; button_save.on_select = [&nav, this](Button&) { if (checkbox_bloff.value()) @@ -296,6 +290,36 @@ void SetUIView::focus() { button_save.focus(); } + +// --------------------------------------------------------- +// Appl. Settings +// --------------------------------------------------------- +SetAppSettingsView::SetAppSettingsView(NavigationView& nav) { + add_children({ + &checkbox_load_app_settings, + &checkbox_save_app_settings, + &button_save, + &button_cancel + }); + + checkbox_load_app_settings.set_value(persistent_memory::load_app_settings()); + checkbox_save_app_settings.set_value(persistent_memory::save_app_settings()); + + + button_save.on_select = [&nav, this](Button&) { + persistent_memory::set_load_app_settings(checkbox_load_app_settings.value()); + persistent_memory::set_save_app_settings(checkbox_save_app_settings.value()); + nav.pop(); + }; + button_cancel.on_select = [&nav, this](Button&) { + nav.pop(); + }; +} + +void SetAppSettingsView::focus() { + button_save.focus(); +} + SetAudioView::SetAudioView(NavigationView& nav) { add_children({ &labels, @@ -344,14 +368,18 @@ void SetQRCodeView::focus() { button_save.focus(); } +// --------------------------------------------------------- +// Settings main menu +// --------------------------------------------------------- SettingsMenuView::SettingsMenuView(NavigationView& nav) { add_items({ { "Audio", ui::Color::dark_cyan(), &bitmap_icon_speaker, [&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(); } }, + { "User Interface", ui::Color::dark_cyan(), &bitmap_icon_options_ui, [&nav](){ nav.push(); } }, { "Date/Time", ui::Color::dark_cyan(), &bitmap_icon_options_datetime, [&nav](){ nav.push(); } }, { "Calibration", ui::Color::dark_cyan(), &bitmap_icon_options_touch, [&nav](){ nav.push(); } }, - { "QR Code", ui::Color::dark_cyan(), &bitmap_icon_qr_code, [&nav](){ nav.push(); } } + { "App Settings", ui::Color::dark_cyan(), &bitmap_icon_setup, [&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 68c1e750..562cf636 100644 --- a/firmware/application/apps/ui_settings.hpp +++ b/firmware/application/apps/ui_settings.hpp @@ -283,6 +283,39 @@ private: }; }; +class SetAppSettingsView : public View { +public: + SetAppSettingsView(NavigationView& nav); + + void focus() override; + + std::string title() const override { return "App Settings"; }; + +private: + + Checkbox checkbox_load_app_settings { + { 3 * 8, 2 * 16 }, + 25, + "Load app settings" + }; + + Checkbox checkbox_save_app_settings { + { 3 * 8, 4 * 16 }, + 25, + "Save app settings" + }; + + Button button_save { + { 2 * 8, 16 * 16, 12 * 8, 32 }, + "Save" + }; + + Button button_cancel { + { 16 * 8, 16 * 16, 12 * 8, 32 }, + "Cancel", + }; +}; + class SetAudioView : public View { public: SetAudioView(NavigationView& nav); diff --git a/firmware/application/apps/ui_sonde.cpp b/firmware/application/apps/ui_sonde.cpp index f38fc3dd..5ddf157e 100644 --- a/firmware/application/apps/ui_sonde.cpp +++ b/firmware/application/apps/ui_sonde.cpp @@ -23,6 +23,7 @@ #include "ui_sonde.hpp" #include "baseband_api.hpp" #include "audio.hpp" +#include "app_settings.hpp" #include "portapack.hpp" #include @@ -43,6 +44,8 @@ namespace ui { SondeView::SondeView(NavigationView& nav) { + + baseband::run_image(portapack::spi_flash::image_tag_sonde); add_children({ @@ -68,8 +71,17 @@ SondeView::SondeView(NavigationView& nav) { &button_see_map }); - // start from the frequency currently stored in the receiver_model: - target_frequency_ = receiver_model.tuning_frequency(); + + // load app settings + auto rc = settings.load("rx_sonde", &app_settings); + if(rc == SETTINGS_OK) { + field_lna.set_value(app_settings.lna); + field_vga.set_value(app_settings.vga); + field_rf_amp.set_value(app_settings.rx_amp); + target_frequency_ = app_settings.rx_frequency; + } + else target_frequency_ = receiver_model.tuning_frequency(); + field_frequency.set_value(target_frequency_); field_frequency.set_step(500); //euquiq: was 10000, but we are using this for fine-tunning @@ -104,16 +116,6 @@ SondeView::SondeView(NavigationView& nav) { receiver_model.set_sampling_rate(sampling_rate); receiver_model.set_baseband_bandwidth(baseband_bandwidth); receiver_model.enable(); // Before using radio::enable(), but not updating Ant.DC-Bias. - - /* radio::enable({ // this can be removed, previous version, no DC-bias ant. control. - tuning_frequency(), - sampling_rate, - baseband_bandwidth, - rf::Direction::Receive, - receiver_model.rf_amp(), - static_cast(receiver_model.lna()), - static_cast(receiver_model.vga()), - }); */ // QR code with geo URI @@ -157,9 +159,13 @@ SondeView::SondeView(NavigationView& nav) { } SondeView::~SondeView() { + // save app settings + app_settings.rx_frequency = target_frequency_; + settings.save("rx_sonde", &app_settings); + baseband::set_pitch_rssi(0, false); -/* radio::disable(); */ - receiver_model.disable(); // to switch off all, including DC bias. + + receiver_model.disable(); // to switch off all, including DC bias. baseband::shutdown(); audio::output::stop(); } diff --git a/firmware/application/apps/ui_sonde.hpp b/firmware/application/apps/ui_sonde.hpp index b1fab391..3129c72b 100644 --- a/firmware/application/apps/ui_sonde.hpp +++ b/firmware/application/apps/ui_sonde.hpp @@ -34,7 +34,7 @@ #include "log_file.hpp" #include "sonde_packet.hpp" - +#include "app_settings.hpp" #include #include @@ -74,6 +74,9 @@ private: bool beep { false }; char geo_uri[32] = {}; + // app save settings + std::app_settings settings { }; + std::app_settings::AppSettings app_settings { }; sonde::GPS_data gps_info { }; sonde::temp_humid temp_humid_info { }; diff --git a/firmware/common/portapack_persistent_memory.cpp b/firmware/common/portapack_persistent_memory.cpp index 1b577336..c7bd2bf9 100644 --- a/firmware/common/portapack_persistent_memory.cpp +++ b/firmware/common/portapack_persistent_memory.cpp @@ -200,44 +200,26 @@ void set_serial_format(const serial_format_t new_value) { data->serial_format = new_value; } -/* static constexpr uint32_t playdead_magic = 0x88d3bb57; - -uint32_t playing_dead() { - return data->playing_dead; -} - -void set_playing_dead(const uint32_t new_value) { - if( data->playdead_magic != playdead_magic ) { - set_playdead_sequence(0x8D1); // U D L R - } - data->playing_dead = new_value; -} - -uint32_t playdead_sequence() { - if( data->playdead_magic != playdead_magic ) { - set_playdead_sequence(0x8D1); // U D L R - } - return data->playdead_sequence; -} - -void set_playdead_sequence(const uint32_t new_value) { - data->playdead_sequence = new_value; - data->playdead_magic = playdead_magic; -} */ - // ui_config is an uint32_t var storing information bitwise -// bits 0,1,2 store the backlight timer -// bits 31, 30,29,28,27, 26, 25, 24 stores the different single bit configs depicted below -// bits on position 4 to 19 (16 bits) store the clkout frequency +// bits 0-2 store the backlight timer +// bits 4-19 (16 bits) store the clkout frequency +// bits 21-31 store the different single bit configs depicted below +bool load_app_settings() { // load (last saved) app settings on startup of app + return data->ui_config & (1 << 21); +} -bool disable_touchscreen() { // Option to disable touch screen - return data->ui_config & (1 << 24); +bool save_app_settings() { // save app settings when closing app + return data->ui_config & (1 << 22); } bool show_bigger_qr_code() { // show bigger QR code return data->ui_config & (1 << 23); } +bool disable_touchscreen() { // Option to disable touch screen + return data->ui_config & (1 << 24); +} + bool hide_clock() { // clock hidden from main menu return data->ui_config & (1 << 25); } @@ -274,14 +256,22 @@ uint32_t config_backlight_timer() { return timer_seconds[data->ui_config & 7]; //first three bits, 8 possible values } -void set_disable_touchscreen(bool v) { - data->ui_config = (data->ui_config & ~(1 << 24)) | (v << 24); +void set_load_app_settings(bool v) { + data->ui_config = (data->ui_config & ~(1 << 21)) | (v << 21); } - + +void set_save_app_settings(bool v) { + data->ui_config = (data->ui_config & ~(1 << 22)) | (v << 22); +} + void set_show_bigger_qr_code(bool v) { data->ui_config = (data->ui_config & ~(1 << 23)) | (v << 23); } +void set_disable_touchscreen(bool v) { + data->ui_config = (data->ui_config & ~(1 << 24)) | (v << 24); +} + void set_clock_hidden(bool v) { data->ui_config = (data->ui_config & ~(1 << 25)) | (v << 25); } diff --git a/firmware/common/portapack_persistent_memory.hpp b/firmware/common/portapack_persistent_memory.hpp index bdfc1fef..174fdbfe 100644 --- a/firmware/common/portapack_persistent_memory.hpp +++ b/firmware/common/portapack_persistent_memory.hpp @@ -78,6 +78,8 @@ uint8_t config_cpld(); void set_config_cpld(uint8_t i); bool config_splash(); +bool load_app_settings(); +bool save_app_settings(); bool show_bigger_qr_code(); bool hide_clock(); bool clock_with_date(); @@ -87,6 +89,8 @@ uint32_t config_backlight_timer(); bool disable_touchscreen(); void set_config_splash(bool v); +void set_load_app_settings(bool v); +void set_save_app_settings(bool v); void set_show_bigger_qr_code(bool v); void set_clock_hidden(bool v); void set_clock_with_date(bool v);