diff --git a/firmware/application/app_settings.cpp b/firmware/application/app_settings.cpp index 38fc9d2a6..df93a20bf 100644 --- a/firmware/application/app_settings.cpp +++ b/firmware/application/app_settings.cpp @@ -27,56 +27,30 @@ #include "portapack.hpp" #include "portapack_persistent_memory.hpp" #include +#include namespace std { -int app_settings::load(std::string application, AppSettings* settings){ +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); - } + auto error = settings_file.read(file_content, std::min((int)settings_file.size(), MAX_FILE_CONTENT_SIZE)); + settings->baseband_bandwidth=std::app_settings::read_long_long(file_content, "baseband_bandwidth="); + settings->channel_bandwidth=std::app_settings::read_long_long(file_content, "channel_bandwidth="); + settings->lna=std::app_settings::read_long_long(file_content, "lna="); + settings->modulation=std::app_settings::read_long_long(file_content, "modulation="); + settings->rx_amp=std::app_settings::read_long_long(file_content, "rx_amp="); + settings->rx_frequency=std::app_settings::read_long_long(file_content, "rx_frequency="); + settings->sampling_rate=std::app_settings::read_long_long(file_content, "sampling_rate="); + settings->vga=std::app_settings::read_long_long(file_content, "vga="); + settings->tx_amp=std::app_settings::read_long_long(file_content, "tx_amp="); + settings->tx_frequency=std::app_settings::read_long_long(file_content, "tx_frequency="); + settings->tx_gain=std::app_settings::read_long_long(file_content, "tx_gain="); rc = SETTINGS_OK; } else rc = SETTINGS_UNABLE_TO_LOAD; @@ -85,7 +59,7 @@ int app_settings::load(std::string application, AppSettings* settings){ return(rc); } -int app_settings::save(std::string application, AppSettings* settings){ +int app_settings::save(std::string application, AppSettings* settings) { if (portapack::persistent_memory::save_app_settings()) { file_path = folder+"/"+application+".ini"; @@ -95,12 +69,16 @@ int app_settings::save(std::string application, AppSettings* settings){ 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("channel_bandwidth="+to_string_dec_uint(portapack::transmitter_model.channel_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("tx_amp="+to_string_dec_uint(portapack::transmitter_model.rf_amp())); + settings_file.write_line("tx_gain="+to_string_dec_uint(portapack::transmitter_model.tx_gain())); 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)); + settings_file.write_line("tx_frequency="+to_string_dec_uint(settings->tx_frequency)); rc = SETTINGS_OK; } @@ -110,4 +88,15 @@ int app_settings::save(std::string application, AppSettings* settings){ return(rc); } + +long long int app_settings::read_long_long(char* file_content, const char* setting_text) { + auto position = strstr(file_content, (char *)setting_text); + if (position) { + position += strlen((char *)setting_text); + setting_value = strtoll(position, nullptr, 10); + } + return(setting_value); +} + + } /* namespace std */ diff --git a/firmware/application/app_settings.hpp b/firmware/application/app_settings.hpp index 6205a596d..9a8779782 100644 --- a/firmware/application/app_settings.hpp +++ b/firmware/application/app_settings.hpp @@ -46,13 +46,18 @@ public: #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; + uint32_t channel_bandwidth; uint8_t lna; + uint8_t modulation; uint8_t rx_amp; uint32_t rx_frequency; uint32_t sampling_rate; + uint8_t tx_amp; + uint32_t tx_frequency; + uint8_t tx_gain; uint8_t vga; }; @@ -62,12 +67,16 @@ public: private: +#define MAX_FILE_CONTENT_SIZE 1000 - char file_content[257] = {}; + char file_content[MAX_FILE_CONTENT_SIZE] = {}; std::string file_path = ""; std::string folder = "SETTINGS"; int rc = SETTINGS_OK; - File settings_file { }; + File settings_file { }; + long long int setting_value {} ; + + long long int read_long_long(char* file_content, const char* setting_text); }; // class app_settings diff --git a/firmware/application/apps/analog_audio_app.cpp b/firmware/application/apps/analog_audio_app.cpp index 9777847ff..422633daf 100644 --- a/firmware/application/apps/analog_audio_app.cpp +++ b/firmware/application/apps/analog_audio_app.cpp @@ -139,7 +139,6 @@ AnalogAudioView::AnalogAudioView( } else field_frequency.set_value(receiver_model.tuning_frequency()); - //Filename Datetime and Frequency record_view.set_filename_date_frequency(true); @@ -170,6 +169,7 @@ AnalogAudioView::AnalogAudioView( const auto modulation = receiver_model.modulation(); options_modulation.set_by_value(toUType(modulation)); + options_modulation.on_change = [this](size_t, OptionsField::value_t v) { this->on_modulation_changed(static_cast(v)); }; @@ -193,7 +193,7 @@ AnalogAudioView::AnalogAudioView( audio::output::start(); update_modulation(static_cast(modulation)); - on_modulation_changed(static_cast(modulation)); + on_modulation_changed(static_cast(modulation)); } size_t AnalogAudioView::get_spec_bw_index() { @@ -412,9 +412,6 @@ void AnalogAudioView::update_modulation(const ReceiverModel::Mode modulation) { } } -/*void AnalogAudioView::squelched() { - if (exit_on_squelch) nav_.pop(); -}*/ void AnalogAudioView::handle_coded_squelch(const uint32_t value) { float diff, min_diff = value; diff --git a/firmware/application/apps/lge_app.cpp b/firmware/application/apps/lge_app.cpp index c1f4ea0f8..ad3b6d0a7 100644 --- a/firmware/application/apps/lge_app.cpp +++ b/firmware/application/apps/lge_app.cpp @@ -39,10 +39,14 @@ using namespace portapack; namespace ui { void LGEView::focus() { - options_trame.focus(); + options_frame.focus(); } LGEView::~LGEView() { + // save app settings + app_settings.tx_frequency = transmitter_model.tuning_frequency(); + settings.save("tx_lge", &app_settings); + transmitter_model.disable(); baseband::shutdown(); } @@ -70,10 +74,10 @@ void LGEView::generate_frame_touche() { std::vector data { 0x46, 0x28, 0x01, 0x45, 0x27, 0x01, 0x44, 0x23 }; console.write("\n\x1B\x07Touche:\x1B\x10"); - generate_lge_frame(0x96, (field_joueur.value() << 8) | field_salle.value(), 0x0001, data); + generate_lge_frame(0x96, (field_player.value() << 8) | field_room.value(), 0x0001, data); } -void LGEView::generate_frame_pseudo() { +void LGEView::generate_frame_nickname() { // 0040.48s: // 30 02 1A 00 19 00 FF 00 02 19 42 52 45 42 49 53 20 00 00 00 00 00 00 00 00 00 // 04 01 B0 04 7F 1F 11 33 40 1F 22 01 07 00 00 01 07 00 00 63 05 00 00 99 A2 @@ -90,15 +94,15 @@ void LGEView::generate_frame_pseudo() { }; uint32_t c; - //data_header[2] = field_salle.value(); // ? - //data_footer[0] = field_salle.value(); // ? + //data_header[2] = field_room.value(); // ? + //data_footer[0] = field_room.value(); // ? data.insert(data.begin(), data_header.begin(), data_header.end()); - data.push_back(field_joueur.value()); + data.push_back(field_player.value()); c = 0; - for (auto &ch : pseudo) { + for (auto &ch : nickname) { data.push_back(ch); c++; } @@ -108,16 +112,16 @@ void LGEView::generate_frame_pseudo() { while (++c < 16) data.push_back(0x00); - data.push_back(field_equipe.value()); + data.push_back(field_team.value()); data.insert(data.end(), data_footer.begin(), data_footer.end()); - console.write("\n\x1B\x0ESet pseudo:\x1B\x10"); + console.write("\n\x1B\x0ESet nickname:\x1B\x10"); - generate_lge_frame(0x02, 0x001A, field_joueur.value(), data); + generate_lge_frame(0x02, 0x001A, field_player.value(), data); } -void LGEView::generate_frame_equipe() { +void LGEView::generate_frame_team() { // 0041.83s: // 3D 03 FF FF FF FF 02 03 01 52 4F 55 47 45 00 00 00 00 00 00 00 00 00 00 00 00 // 02 56 45 52 54 45 00 00 00 00 00 00 00 00 00 00 00 01 03 42 4C 45 55 45 00 00 @@ -129,10 +133,10 @@ void LGEView::generate_frame_equipe() { data.insert(data.begin(), data_header.begin(), data_header.end()); - data.push_back(field_equipe.value()); + data.push_back(field_team.value()); c = 0; - for (auto &ch : pseudo) { + for (auto &ch : nickname) { data.push_back(ch); c++; } @@ -140,14 +144,14 @@ void LGEView::generate_frame_equipe() { while (c++ < 16) data.push_back(0x00); - data.push_back(field_equipe.value() - 1); // Color ? + data.push_back(field_team.value() - 1); // Color ? - console.write("\n\x1B\x0ASet equipe:\x1B\x10"); + console.write("\n\x1B\x0ASet team:\x1B\x10"); generate_lge_frame(0x03, data); } -void LGEView::generate_frame_broadcast_pseudo() { +void LGEView::generate_frame_broadcast_nickname() { // 0043.86s: // 3D 04 FF FF FF FF 02 03 19 42 52 45 42 49 53 20 00 00 00 00 00 00 00 00 00 04 // 07 50 4F 4E 45 59 20 00 00 00 00 00 00 00 00 00 00 05 1B 41 42 42 59 20 00 00 @@ -159,10 +163,10 @@ void LGEView::generate_frame_broadcast_pseudo() { data.insert(data.begin(), data_header.begin(), data_header.end()); - data.push_back(field_joueur.value()); + data.push_back(field_player.value()); c = 0; - for (auto &ch : pseudo) { + for (auto &ch : nickname) { data.push_back(ch); c++; } @@ -172,9 +176,9 @@ void LGEView::generate_frame_broadcast_pseudo() { while (++c < 16) data.push_back(0x00); - data.push_back(field_equipe.value()); + data.push_back(field_team.value()); - console.write("\n\x1B\x09" "Broadcast pseudo:\x1B\x10"); + console.write("\n\x1B\x09" "Broadcast nickname:\x1B\x10"); generate_lge_frame(0x04, data); } @@ -184,14 +188,14 @@ void LGEView::generate_frame_start() { // 0A 05 FF FF FF FF 02 EC FF FF FF A3 35 std::vector data { 0x02, 0xEC, 0xFF, 0xFF, 0xFF }; - //data[0] = field_salle.value(); // ? + //data[0] = field_room.value(); // ? console.write("\n\x1B\x0DStart:\x1B\x10"); generate_lge_frame(0x05, data); } void LGEView::generate_frame_gameover() { - std::vector data { (uint8_t)field_salle.value() }; + std::vector data { (uint8_t)field_room.value() }; console.write("\n\x1B\x0CGameover:\x1B\x10"); generate_lge_frame(0x0D, data); @@ -203,7 +207,7 @@ void LGEView::generate_frame_collier() { // Custom // 0C 00 13 37 13 37 id flags channel playerid zapduty zaptime checksum CRC CRC // channel: field_channel - // playerid: field_joueur + // playerid: field_player // zapduty: field_power // zaptime: field_duration @@ -218,8 +222,8 @@ void LGEView::generate_frame_collier() { std::vector data { id, flags, - (uint8_t)field_salle.value(), - (uint8_t)field_joueur.value(), + (uint8_t)field_room.value(), + (uint8_t)field_player.value(), (uint8_t)field_power.value(), (uint8_t)(field_duration.value() * 10) }; @@ -285,11 +289,11 @@ LGEView::LGEView(NavigationView& nav) { add_children({ &labels, - &options_trame, - &field_salle, - &button_texte, - &field_equipe, - &field_joueur, + &options_frame, + &field_room, + &button_text, + &field_team, + &field_player, &field_id, &field_power, &field_duration, @@ -300,20 +304,29 @@ LGEView::LGEView(NavigationView& nav) { &tx_view }); - field_salle.set_value(1); - field_equipe.set_value(1); - field_joueur.set_value(1); + // load app settings + auto rc = settings.load("tx_lge", &app_settings); + if(rc == SETTINGS_OK) { + transmitter_model.set_rf_amp(app_settings.tx_amp); + transmitter_model.set_channel_bandwidth(app_settings.channel_bandwidth); + transmitter_model.set_tuning_frequency(app_settings.tx_frequency); + transmitter_model.set_tx_gain(app_settings.tx_gain); + } + + field_room.set_value(1); + field_team.set_value(1); + field_player.set_value(1); field_id.set_value(1); field_power.set_value(1); field_duration.set_value(2); - button_texte.on_select = [this, &nav](Button&) { + button_text.on_select = [this, &nav](Button&) { text_prompt( nav, - pseudo, + nickname, 15, [this](std::string& buffer) { - button_texte.set_text(buffer); + button_text.set_text(buffer); }); }; @@ -326,15 +339,15 @@ LGEView::LGEView(NavigationView& nav) { tx_view.on_start = [this]() { if (tx_mode == IDLE) { - auto i = options_trame.selected_index_value(); + auto i = options_frame.selected_index_value(); if (i == 0) generate_frame_touche(); else if (i == 1) - generate_frame_pseudo(); + generate_frame_nickname(); else if (i == 2) - generate_frame_equipe(); + generate_frame_team(); else if (i == 3) - generate_frame_broadcast_pseudo(); + generate_frame_broadcast_nickname(); else if (i == 4) generate_frame_start(); else if (i == 5) diff --git a/firmware/application/apps/lge_app.hpp b/firmware/application/apps/lge_app.hpp index 99c5014db..75377b29e 100644 --- a/firmware/application/apps/lge_app.hpp +++ b/firmware/application/apps/lge_app.hpp @@ -30,6 +30,7 @@ #include "message.hpp" #include "transmitter_model.hpp" #include "portapack.hpp" +#include "app_settings.hpp" namespace ui { @@ -48,15 +49,19 @@ private: SINGLE, ALL }; + + // app save settings + std::app_settings settings { }; + std::app_settings::AppSettings app_settings { }; tx_modes tx_mode = IDLE; - RFM69 rfm69 { 5, 0x2DD4, true, true }; + RFM69 rfm69 { 5, 0x2DD4, true, true }; uint32_t frame_size { 0 }; uint32_t repeats { 0 }; uint32_t channel_index { 0 }; - std::string pseudo { "ABCDEF" }; + std::string nickname { "ABCDEF" }; rf::Frequency channels[3] = { 868067000, 868183000, 868295000 }; @@ -68,9 +73,9 @@ private: } void generate_lge_frame(const uint8_t command, const uint16_t address_a, const uint16_t address_b, std::vector& data); void generate_frame_touche(); - void generate_frame_pseudo(); - void generate_frame_equipe(); - void generate_frame_broadcast_pseudo(); + void generate_frame_nickname(); + void generate_frame_team(); + void generate_frame_broadcast_nickname(); void generate_frame_start(); void generate_frame_gameover(); void generate_frame_collier(); @@ -79,28 +84,28 @@ private: Labels labels { //{ { 7 * 8, 1 * 8 }, "NO FUN ALLOWED !", Color::red() }, - { { 1 * 8, 1 * 8 }, "Trame:", Color::light_grey() }, - { { 1 * 8, 3 * 8 }, "Salle:", Color::light_grey() }, - { { 14 * 8, 3 * 8 }, "Texte:", Color::light_grey() }, - { { 0 * 8, 5 * 8 }, "Equipe:", Color::light_grey() }, - { { 0 * 8, 7 * 8 }, "Joueur:", Color::light_grey() }, - { { 0 * 8, 10 * 8 }, "Collier:", Color::light_grey() }, + { { 1 * 8, 1 * 8 }, "Frame:", Color::light_grey() }, + { { 2 * 8, 3 * 8 }, "Room:", Color::light_grey() }, + { { 14 * 8, 3 * 8 }, "Text:", Color::light_grey() }, + { { 2 * 8, 5 * 8 }, "Team:", Color::light_grey() }, + { { 0 * 8, 7 * 8 }, "Player:", Color::light_grey() }, + { { 0 * 8, 10 * 8 }, "Vest:", Color::light_grey() }, { { 4 * 8, 12 * 8 }, "ID:", Color::light_grey() }, { { 3 * 8, 14 * 8 }, "Pow: /10", Color::light_grey() }, - { { 1 * 8, 16 * 8 }, "Duree: x100ms", Color::light_grey() } + { { 2 * 8, 16 * 8 }, "Time: x100ms", Color::light_grey() } }; - OptionsField options_trame { + OptionsField options_frame { { 7 * 8, 1 * 8 }, 13, { - { "Touche", 0 }, - { "Set pseudo", 1 }, - { "Set equipe", 2 }, - { "Brdcst pseudo", 3 }, + { "Key", 0 }, + { "Set nickname", 1 }, + { "Set team", 2 }, + { "Brdcst nick", 3 }, { "Start", 4 }, { "Game over", 5 }, - { "Set collier", 6 } + { "Set vest", 6 } } }; @@ -111,7 +116,7 @@ private: true }; - NumberField field_salle { + NumberField field_room { { 7 * 8, 3 * 8 }, 1, { 1, 2 }, @@ -119,12 +124,12 @@ private: '0' }; - Button button_texte { + Button button_text { { 14 * 8, 5 * 8, 16 * 8, 3 * 8 }, "ABCDEF" }; - NumberField field_equipe { + NumberField field_team { { 7 * 8, 5 * 8 }, 1, { 1, 6 }, @@ -132,7 +137,7 @@ private: '0' }; - NumberField field_joueur { + NumberField field_player { { 7 * 8, 7 * 8 }, 2, { 1, 50 }, diff --git a/firmware/application/apps/soundboard_app.cpp b/firmware/application/apps/soundboard_app.cpp index 2c93822f2..97e6ad706 100644 --- a/firmware/application/apps/soundboard_app.cpp +++ b/firmware/application/apps/soundboard_app.cpp @@ -240,6 +240,15 @@ SoundBoardView::SoundBoardView( &button_next_page, &tx_view }); + + // load app settings + auto rc = settings.load("tx_soundboard", &app_settings); + if(rc == SETTINGS_OK) { + transmitter_model.set_rf_amp(app_settings.tx_amp); + transmitter_model.set_channel_bandwidth(app_settings.channel_bandwidth); + transmitter_model.set_tuning_frequency(app_settings.tx_frequency); + transmitter_model.set_tx_gain(app_settings.tx_gain); + } refresh_list(); @@ -280,6 +289,10 @@ SoundBoardView::SoundBoardView( } SoundBoardView::~SoundBoardView() { + // save app settings + app_settings.tx_frequency = transmitter_model.tuning_frequency(); + settings.save("tx_soundboard", &app_settings); + stop(); transmitter_model.disable(); baseband::shutdown(); diff --git a/firmware/application/apps/soundboard_app.hpp b/firmware/application/apps/soundboard_app.hpp index ee9e1b124..a8afb73ca 100644 --- a/firmware/application/apps/soundboard_app.hpp +++ b/firmware/application/apps/soundboard_app.hpp @@ -30,6 +30,7 @@ #include "lfsr_random.hpp" #include "io_wave.hpp" #include "tone_key.hpp" +#include "app_settings.hpp" namespace ui { @@ -49,6 +50,10 @@ public: private: NavigationView& nav_; + + // app save settings + std::app_settings settings { }; + std::app_settings::AppSettings app_settings { }; enum tx_modes { NORMAL = 0, diff --git a/firmware/application/apps/ui_adsb_rx.cpp b/firmware/application/apps/ui_adsb_rx.cpp index a9d619286..1ae332ee8 100644 --- a/firmware/application/apps/ui_adsb_rx.cpp +++ b/firmware/application/apps/ui_adsb_rx.cpp @@ -313,6 +313,7 @@ ADSBRxView::~ADSBRxView() { // save app settings settings.save("rx_adsb", &app_settings); + //TODO: once all apps keep there own settin previous frequency logic can be removed receiver_model.set_tuning_frequency(prevFreq); rtc_time::signal_tick_second -= signal_token_tick_second; receiver_model.disable(); diff --git a/firmware/application/apps/ui_adsb_tx.cpp b/firmware/application/apps/ui_adsb_tx.cpp index 198d22959..918e744cb 100644 --- a/firmware/application/apps/ui_adsb_tx.cpp +++ b/firmware/application/apps/ui_adsb_tx.cpp @@ -284,6 +284,11 @@ void ADSBTxView::focus() { } ADSBTxView::~ADSBTxView() { + + // save app settings + app_settings.tx_frequency = transmitter_model.tuning_frequency(); + settings.save("tx_adsb", &app_settings); + transmitter_model.disable(); baseband::shutdown(); } @@ -334,8 +339,16 @@ ADSBTxView::ADSBTxView( &view_squawk, &text_frame, &tx_view - }); - + }); + + // load app settings + auto rc = settings.load("tx_adsb", &app_settings); + if(rc == SETTINGS_OK) { + transmitter_model.set_tuning_frequency(app_settings.tx_frequency); + transmitter_model.set_rf_amp(app_settings.tx_amp); + transmitter_model.set_tx_gain(app_settings.tx_gain); + } + tx_view.on_edit_frequency = [this, &nav]() { auto new_view = nav.push(receiver_model.tuning_frequency()); new_view->on_changed = [this](rf::Frequency f) { diff --git a/firmware/application/apps/ui_adsb_tx.hpp b/firmware/application/apps/ui_adsb_tx.hpp index 0cf07f19e..8556f6e8a 100644 --- a/firmware/application/apps/ui_adsb_tx.hpp +++ b/firmware/application/apps/ui_adsb_tx.hpp @@ -28,6 +28,7 @@ #include "ui_transmitter.hpp" #include "message.hpp" #include "transmitter_model.hpp" +#include "app_settings.hpp" #include "portapack.hpp" using namespace adsb; @@ -189,6 +190,10 @@ private: -1, -1 };*/ + + // app save settings + std::app_settings settings { }; + std::app_settings::AppSettings app_settings { }; //tx_modes tx_mode = IDLE; NavigationView& nav_; diff --git a/firmware/application/apps/ui_aprs_tx.cpp b/firmware/application/apps/ui_aprs_tx.cpp index 87ff69278..5d2759314 100644 --- a/firmware/application/apps/ui_aprs_tx.cpp +++ b/firmware/application/apps/ui_aprs_tx.cpp @@ -43,6 +43,10 @@ void APRSTXView::focus() { } APRSTXView::~APRSTXView() { + // save app settings + app_settings.tx_frequency = transmitter_model.tuning_frequency(); + settings.save("tx_aprs", &app_settings); + transmitter_model.disable(); baseband::shutdown(); } @@ -66,7 +70,7 @@ void APRSTXView::start_tx() { 1200, 2200, 1, - 10000, //transmitter_model.channel_bandwidth(), + 10000, //APRS uses fixed 10k bandwidth 8 ); } @@ -95,6 +99,15 @@ APRSTXView::APRSTXView(NavigationView& nav) { &tx_view }); + + // load app settings + auto rc = settings.load("tx_aprs", &app_settings); + if(rc == SETTINGS_OK) { + transmitter_model.set_rf_amp(app_settings.tx_amp); + transmitter_model.set_tuning_frequency(app_settings.tx_frequency); + transmitter_model.set_tx_gain(app_settings.tx_gain); + } + button_set.on_select = [this, &nav](Button&) { text_prompt( nav, diff --git a/firmware/application/apps/ui_aprs_tx.hpp b/firmware/application/apps/ui_aprs_tx.hpp index 970321072..16872b11a 100644 --- a/firmware/application/apps/ui_aprs_tx.hpp +++ b/firmware/application/apps/ui_aprs_tx.hpp @@ -29,6 +29,7 @@ #include "message.hpp" #include "transmitter_model.hpp" +#include "app_settings.hpp" #include "portapack.hpp" namespace ui { @@ -40,17 +41,14 @@ public: void focus() override; - std::string title() const override { return "APRS TX (beta)"; }; + std::string title() const override { return "APRS TX"; }; private: - /*enum tx_modes { - IDLE = 0, - SINGLE, - SEQUENCE - }; - - tx_modes tx_mode = IDLE;*/ + // app save settings + std::app_settings settings { }; + std::app_settings::AppSettings app_settings { }; + std::string payload { "" }; void start_tx(); @@ -103,7 +101,7 @@ private: TransmitterView tx_view { 16 * 16, 5000, - 10 + 0 // disable setting bandwith, since APRS used fixed 10k bandwidth }; MessageHandlerRegistration message_handler_tx_progress { diff --git a/firmware/application/apps/ui_bht_tx.cpp b/firmware/application/apps/ui_bht_tx.cpp index 6021a240e..b70f4d17d 100644 --- a/firmware/application/apps/ui_bht_tx.cpp +++ b/firmware/application/apps/ui_bht_tx.cpp @@ -96,9 +96,9 @@ void BHTView::on_tx_progress(const uint32_t progress, const bool done) { if (target_system == XYLOS) { if (done) { if (tx_mode == SINGLE) { - if (checkbox_cligno.value()) { + if (checkbox_flashing.value()) { // TODO: Thread ! - chThdSleepMilliseconds(field_tempo.value() * 1000); // Dirty :( + chThdSleepMilliseconds(field_speed.value() * 1000); // Dirty :( view_xylos.flip_relays(); start_tx(); } else @@ -120,9 +120,9 @@ void BHTView::on_tx_progress(const uint32_t progress, const bool done) { } else { view_EPAR.half = false; if (tx_mode == SINGLE) { - if (checkbox_cligno.value()) { + if (checkbox_flashing.value()) { // TODO: Thread ! - chThdSleepMilliseconds(field_tempo.value() * 1000); // Dirty :( + chThdSleepMilliseconds(field_speed.value() * 1000); // Dirty :( view_EPAR.flip_relays(); start_tx(); } else @@ -140,6 +140,10 @@ void BHTView::on_tx_progress(const uint32_t progress, const bool done) { } BHTView::~BHTView() { + // save app settings + app_settings.tx_frequency = transmitter_model.tuning_frequency(); + settings.save("tx_bht", &app_settings); + transmitter_model.disable(); } @@ -150,13 +154,22 @@ BHTView::BHTView(NavigationView& nav) { &view_xylos, &view_EPAR, &checkbox_scan, - &checkbox_cligno, - &field_tempo, + &checkbox_flashing, + &field_speed, &progressbar, &tx_view }); - field_tempo.set_value(1); + // load app settings + auto rc = settings.load("tx_bht", &app_settings); + if(rc == SETTINGS_OK) { + transmitter_model.set_rf_amp(app_settings.tx_amp); + transmitter_model.set_channel_bandwidth(app_settings.channel_bandwidth); + transmitter_model.set_tuning_frequency(app_settings.tx_frequency); + transmitter_model.set_tx_gain(app_settings.tx_gain); + } + + field_speed.set_value(1); tx_view.on_edit_frequency = [this, &nav]() { auto new_view = nav.push(receiver_model.tuning_frequency()); diff --git a/firmware/application/apps/ui_bht_tx.hpp b/firmware/application/apps/ui_bht_tx.hpp index 01e6b48c5..17768e2ba 100644 --- a/firmware/application/apps/ui_bht_tx.hpp +++ b/firmware/application/apps/ui_bht_tx.hpp @@ -32,6 +32,7 @@ #include "message.hpp" #include "transmitter_model.hpp" #include "encoders.hpp" +#include "app_settings.hpp" #include "portapack.hpp" namespace ui { @@ -50,11 +51,11 @@ public: private: Labels labels { { { 8 * 8, 1 * 8 }, "Header:", Color::light_grey() }, - { { 4 * 8, 3 * 8 }, "Code ville:", Color::light_grey() }, - { { 7 * 8, 5 * 8 }, "Famille:", Color::light_grey() }, - { { 2 * 8, 7 * 8 + 2 }, "Sous-famille:", Color::light_grey() }, - { { 2 * 8, 11 * 8 }, "ID recepteur:", Color::light_grey() }, - { { 2 * 8, 14 * 8 }, "Relais:", Color::light_grey() } + { { 4 * 8, 3 * 8 }, "City code:", Color::light_grey() }, + { { 7 * 8, 5 * 8 }, "Family:", Color::light_grey() }, + { { 2 * 8, 7 * 8 + 2 }, "Subfamily:", Color::light_grey() }, + { { 2 * 8, 11 * 8 }, "Receiver ID:", Color::light_grey() }, + { { 2 * 8, 14 * 8 }, "Relay:", Color::light_grey() } }; NumberField field_header_a { @@ -98,8 +99,8 @@ private: Checkbox checkbox_wcsubfamily { { 20 * 8, 6 * 8 + 6 }, - 6, - "Toutes" + 3, + "All" }; NumberField field_receiver { @@ -111,8 +112,8 @@ private: }; Checkbox checkbox_wcid { { 20 * 8, 10 * 8 + 4 }, - 4, - "Tous" + 3, + "All" }; std::array relay_states { }; @@ -139,9 +140,9 @@ public: private: Labels labels { - { { 4 * 8, 1 * 8 }, "Code ville:", Color::light_grey() }, - { { 8 * 8, 3 * 8 }, "Groupe:", Color::light_grey() }, - { { 8 * 8, 7 * 8 }, "Relais:", Color::light_grey() } + { { 4 * 8, 1 * 8 }, "City code:", Color::light_grey() }, + { { 8 * 8, 3 * 8 }, "Group:", Color::light_grey() }, + { { 8 * 8, 7 * 8 }, "Relay:", Color::light_grey() } }; NumberField field_city { @@ -181,6 +182,10 @@ public: std::string title() const override { return "BHT Xy/EP TX"; }; private: + // app save settings + std::app_settings settings { }; + std::app_settings::AppSettings app_settings { }; + void on_tx_progress(const uint32_t progress, const bool done); void start_tx(); void stop_tx(); @@ -220,12 +225,12 @@ private: "Scan" }; - Checkbox checkbox_cligno { + Checkbox checkbox_flashing { { 16 * 8, 25 * 8 }, - 6, - "Cligno" + 8, + "Flashing" }; - NumberField field_tempo { + NumberField field_speed { { 26 * 8, 25 * 8 + 4 }, 2, { 1, 99 }, diff --git a/firmware/application/apps/ui_coasterp.cpp b/firmware/application/apps/ui_coasterp.cpp index cd918dda5..446ad8416 100644 --- a/firmware/application/apps/ui_coasterp.cpp +++ b/firmware/application/apps/ui_coasterp.cpp @@ -37,6 +37,10 @@ void CoasterPagerView::focus() { } CoasterPagerView::~CoasterPagerView() { + // save app settings + app_settings.tx_frequency = transmitter_model.tuning_frequency(); + settings.save("tx_coaster", &app_settings); + transmitter_model.disable(); baseband::shutdown(); } @@ -119,6 +123,15 @@ CoasterPagerView::CoasterPagerView(NavigationView& nav) { &tx_view }); + // load app settings + auto rc = settings.load("tx_coaster", &app_settings); + if(rc == SETTINGS_OK) { + transmitter_model.set_rf_amp(app_settings.tx_amp); + transmitter_model.set_channel_bandwidth(app_settings.channel_bandwidth); + transmitter_model.set_tuning_frequency(app_settings.tx_frequency); + transmitter_model.set_tx_gain(app_settings.tx_gain); + } + // Bytes to nibbles for (c = 0; c < 16; c++) sym_data.set_sym(c, (data_init[c >> 1] >> ((c & 1) ? 0 : 4)) & 0x0F); diff --git a/firmware/application/apps/ui_coasterp.hpp b/firmware/application/apps/ui_coasterp.hpp index 68963302e..873d3abe0 100644 --- a/firmware/application/apps/ui_coasterp.hpp +++ b/firmware/application/apps/ui_coasterp.hpp @@ -28,6 +28,7 @@ #include "message.hpp" #include "transmitter_model.hpp" +#include "app_settings.hpp" #include "portapack.hpp" namespace ui { @@ -50,6 +51,10 @@ private: tx_modes tx_mode = IDLE; + // app save settings + std::app_settings settings { }; + std::app_settings::AppSettings app_settings { }; + void start_tx(); void generate_frame(); void on_tx_progress(const uint32_t progress, const bool done); diff --git a/firmware/application/apps/ui_encoders.cpp b/firmware/application/apps/ui_encoders.cpp index e15defd10..05c90a3f5 100644 --- a/firmware/application/apps/ui_encoders.cpp +++ b/firmware/application/apps/ui_encoders.cpp @@ -203,6 +203,10 @@ void EncodersView::focus() { } EncodersView::~EncodersView() { + // save app settings + app_settings.tx_frequency = transmitter_model.tuning_frequency(); + settings.save("tx_ook", &app_settings); + transmitter_model.disable(); baseband::shutdown(); } @@ -335,6 +339,15 @@ EncodersView::EncodersView( &tx_view }); + // load app settings + auto rc = settings.load("tx_ook", &app_settings); + if(rc == SETTINGS_OK) { + transmitter_model.set_rf_amp(app_settings.tx_amp); + transmitter_model.set_channel_bandwidth(app_settings.channel_bandwidth); + transmitter_model.set_tuning_frequency(app_settings.tx_frequency); + transmitter_model.set_tx_gain(app_settings.tx_gain); + } + tx_view.on_edit_frequency = [this, &nav]() { auto new_view = nav.push(transmitter_model.tuning_frequency()); new_view->on_changed = [this](rf::Frequency f) { diff --git a/firmware/application/apps/ui_encoders.hpp b/firmware/application/apps/ui_encoders.hpp index 7eef80d51..ac206f6e4 100644 --- a/firmware/application/apps/ui_encoders.hpp +++ b/firmware/application/apps/ui_encoders.hpp @@ -26,6 +26,7 @@ #include "transmitter_model.hpp" #include "encoders.hpp" #include "de_bruijn.hpp" +#include "app_settings.hpp" using namespace encoders; @@ -169,6 +170,10 @@ private: SCAN }; + // app save settings + std::app_settings settings { }; + std::app_settings::AppSettings app_settings { }; + tx_modes tx_mode = IDLE; uint8_t repeat_index { 0 }; uint8_t repeat_min { 0 }; diff --git a/firmware/application/apps/ui_keyfob.cpp b/firmware/application/apps/ui_keyfob.cpp index 6492cd6be..b5bfb145e 100644 --- a/firmware/application/apps/ui_keyfob.cpp +++ b/firmware/application/apps/ui_keyfob.cpp @@ -136,6 +136,9 @@ void KeyfobView::focus() { } KeyfobView::~KeyfobView() { + // save app settings + settings.save("tx_keyfob", &app_settings); + transmitter_model.disable(); baseband::shutdown(); } @@ -214,6 +217,13 @@ KeyfobView::KeyfobView( &tx_view }); + // load app settings + auto rc = settings.load("tx_keyfob", &app_settings); + if(rc == SETTINGS_OK) { + transmitter_model.set_rf_amp(app_settings.tx_amp); + transmitter_model.set_tx_gain(app_settings.tx_gain); + } + frame[0] = 0x55; update_symfields(); diff --git a/firmware/application/apps/ui_keyfob.hpp b/firmware/application/apps/ui_keyfob.hpp index 18685ded6..3cc8419ab 100644 --- a/firmware/application/apps/ui_keyfob.hpp +++ b/firmware/application/apps/ui_keyfob.hpp @@ -23,6 +23,7 @@ #include "ui.hpp" #include "ui_transmitter.hpp" #include "transmitter_model.hpp" +#include "app_settings.hpp" #include "encoders.hpp" using namespace encoders; @@ -41,6 +42,10 @@ public: private: NavigationView& nav_; + // app save settings + std::app_settings settings { }; + std::app_settings::AppSettings app_settings { }; + // 1013210ns / bit static constexpr uint32_t subaru_samples_per_bit = (OOK_SAMPLERATE * 0.00101321); static constexpr uint32_t repeats = 4; diff --git a/firmware/application/apps/ui_lcr.cpp b/firmware/application/apps/ui_lcr.cpp index e664f82ee..6f5b14892 100644 --- a/firmware/application/apps/ui_lcr.cpp +++ b/firmware/application/apps/ui_lcr.cpp @@ -39,6 +39,10 @@ void LCRView::focus() { } LCRView::~LCRView() { + // save app settings + app_settings.tx_frequency = transmitter_model.tuning_frequency(); + settings.save("tx_lcr", &app_settings); + transmitter_model.disable(); baseband::shutdown(); } @@ -173,6 +177,15 @@ LCRView::LCRView(NavigationView& nav) { &tx_view }); + // load app settings + auto rc = settings.load("tx_lcr", &app_settings); + if(rc == SETTINGS_OK) { + transmitter_model.set_rf_amp(app_settings.tx_amp); + transmitter_model.set_channel_bandwidth(app_settings.channel_bandwidth); + transmitter_model.set_tuning_frequency(app_settings.tx_frequency); + transmitter_model.set_tx_gain(app_settings.tx_gain); + } + options_scanlist.set_selected_index(0); const auto button_set_am_fn = [this, &nav](Button& button) { diff --git a/firmware/application/apps/ui_lcr.hpp b/firmware/application/apps/ui_lcr.hpp index 096a597af..bd5b4aacc 100644 --- a/firmware/application/apps/ui_lcr.hpp +++ b/firmware/application/apps/ui_lcr.hpp @@ -27,6 +27,7 @@ #include "message.hpp" #include "transmitter_model.hpp" +#include "app_settings.hpp" namespace ui { @@ -81,6 +82,10 @@ private: SCAN }; + // app save settings + std::app_settings settings { }; + std::app_settings::AppSettings app_settings { }; + tx_modes tx_mode = IDLE; uint8_t scan_count { 0 }, scan_index { 0 }; uint32_t scan_progress { 0 }; diff --git a/firmware/application/apps/ui_morse.cpp b/firmware/application/apps/ui_morse.cpp index ebe44b6d2..1c9468d90 100644 --- a/firmware/application/apps/ui_morse.cpp +++ b/firmware/application/apps/ui_morse.cpp @@ -97,6 +97,10 @@ void MorseView::focus() { } MorseView::~MorseView() { + // save app settings + app_settings.tx_frequency = transmitter_model.tuning_frequency(); + settings.save("tx_morse", &app_settings); + transmitter_model.disable(); baseband::shutdown(); } @@ -203,6 +207,15 @@ MorseView::MorseView( &tx_view }); + // load app settings + auto rc = settings.load("tx_morse", &app_settings); + if(rc == SETTINGS_OK) { + transmitter_model.set_rf_amp(app_settings.tx_amp); + transmitter_model.set_channel_bandwidth(app_settings.channel_bandwidth); + transmitter_model.set_tuning_frequency(app_settings.tx_frequency); + transmitter_model.set_tx_gain(app_settings.tx_gain); + } + // Default settings field_speed.set_value(15); // 15wps field_tone.set_value(700); // 700Hz FM tone diff --git a/firmware/application/apps/ui_morse.hpp b/firmware/application/apps/ui_morse.hpp index 5079fea8d..90b60b499 100644 --- a/firmware/application/apps/ui_morse.hpp +++ b/firmware/application/apps/ui_morse.hpp @@ -27,7 +27,7 @@ #include "ui_widget.hpp" #include "ui_navigation.hpp" #include "ui_transmitter.hpp" - +#include "app_settings.hpp" #include "portapack.hpp" #include "message.hpp" #include "volume.hpp" @@ -67,6 +67,10 @@ private: std::string message { }; uint32_t time_units { 0 }; + // app save settings + std::app_settings settings { }; + std::app_settings::AppSettings app_settings { }; + enum modulation_t { CW = 0, FM = 1 diff --git a/firmware/application/apps/ui_pocsag_tx.cpp b/firmware/application/apps/ui_pocsag_tx.cpp index 56ced719c..58de068e2 100644 --- a/firmware/application/apps/ui_pocsag_tx.cpp +++ b/firmware/application/apps/ui_pocsag_tx.cpp @@ -38,6 +38,10 @@ void POCSAGTXView::focus() { } POCSAGTXView::~POCSAGTXView() { + // save app settings + app_settings.tx_frequency = transmitter_model.tuning_frequency(); + settings.save("tx_pocsag", &app_settings); + transmitter_model.disable(); baseband::shutdown(); } @@ -141,6 +145,15 @@ POCSAGTXView::POCSAGTXView( &tx_view }); + // load app settings + auto rc = settings.load("tx_pocsag", &app_settings); + if(rc == SETTINGS_OK) { + transmitter_model.set_rf_amp(app_settings.tx_amp); + transmitter_model.set_channel_bandwidth(app_settings.channel_bandwidth); + transmitter_model.set_tuning_frequency(app_settings.tx_frequency); + transmitter_model.set_tx_gain(app_settings.tx_gain); + } + options_bitrate.set_selected_index(1); // 1200bps options_type.set_selected_index(0); // Address only diff --git a/firmware/application/apps/ui_pocsag_tx.hpp b/firmware/application/apps/ui_pocsag_tx.hpp index 0dfbc30ac..470ce0fea 100644 --- a/firmware/application/apps/ui_pocsag_tx.hpp +++ b/firmware/application/apps/ui_pocsag_tx.hpp @@ -31,6 +31,7 @@ #include "bch_code.hpp" #include "message.hpp" #include "transmitter_model.hpp" +#include "app_settings.hpp" #include "pocsag.hpp" using namespace pocsag; @@ -62,6 +63,10 @@ private: 5, 31, 21, 2 }; + // app save settings + std::app_settings settings { }; + std::app_settings::AppSettings app_settings { }; + void on_set_text(NavigationView& nav); void on_tx_progress(const uint32_t progress, const bool done); bool start_tx(); diff --git a/firmware/application/apps/ui_rds.cpp b/firmware/application/apps/ui_rds.cpp index db9e2d2a4..7e8f1da87 100644 --- a/firmware/application/apps/ui_rds.cpp +++ b/firmware/application/apps/ui_rds.cpp @@ -175,6 +175,10 @@ void RDSView::focus() { } RDSView::~RDSView() { + // save app settings + app_settings.tx_frequency = transmitter_model.tuning_frequency(); + settings.save("tx_rds", &app_settings); + transmitter_model.disable(); baseband::shutdown(); } @@ -226,11 +230,17 @@ RDSView::RDSView( &view_radiotext, &view_datetime, &view_audio, - //&options_countrycode, - //&options_coverage, &tx_view, }); - + + // load app settings + auto rc = settings.load("tx_rds", &app_settings); + if(rc == SETTINGS_OK) { + transmitter_model.set_rf_amp(app_settings.tx_amp); + transmitter_model.set_channel_bandwidth(app_settings.channel_bandwidth); + transmitter_model.set_tuning_frequency(app_settings.tx_frequency); + transmitter_model.set_tx_gain(app_settings.tx_gain); + } check_TP.set_value(true); sym_pi_code.set_sym(0, 0xF); @@ -242,8 +252,6 @@ RDSView::RDSView( }; options_pty.set_selected_index(0); // None - //options_countrycode.set_selected_index(18); // Baguette du fromage - //options_coverage.set_selected_index(0); // Local tx_view.on_edit_frequency = [this, &nav]() { auto new_view = nav.push(receiver_model.tuning_frequency()); diff --git a/firmware/application/apps/ui_rds.hpp b/firmware/application/apps/ui_rds.hpp index 35d80ba4f..bbffb1ed9 100644 --- a/firmware/application/apps/ui_rds.hpp +++ b/firmware/application/apps/ui_rds.hpp @@ -24,7 +24,7 @@ #include "ui_transmitter.hpp" #include "ui_textentry.hpp" #include "ui_tabview.hpp" - +#include "app_settings.hpp" #include "rds.hpp" using namespace rds; @@ -150,6 +150,11 @@ private: NavigationView& nav_; RDS_flags rds_flags { }; + // app save settings + std::app_settings settings { }; + std::app_settings::AppSettings app_settings { }; + + std::vector frame_psn { }; std::vector frame_radiotext { }; std::vector frame_datetime { }; diff --git a/firmware/application/apps/ui_sstvtx.cpp b/firmware/application/apps/ui_sstvtx.cpp index 4943315d2..55e882d22 100644 --- a/firmware/application/apps/ui_sstvtx.cpp +++ b/firmware/application/apps/ui_sstvtx.cpp @@ -88,6 +88,10 @@ void SSTVTXView::paint(Painter&) { } SSTVTXView::~SSTVTXView() { + // save app settings + app_settings.tx_frequency = transmitter_model.tuning_frequency(); + settings.save("tx_sstv", &app_settings); + transmitter_model.disable(); baseband::shutdown(); } @@ -215,6 +219,15 @@ SSTVTXView::SSTVTXView( options_t mode_options; uint32_t c; + // load app settings + auto rc = settings.load("tx_sstv", &app_settings); + if(rc == SETTINGS_OK) { + transmitter_model.set_rf_amp(app_settings.tx_amp); + transmitter_model.set_channel_bandwidth(app_settings.channel_bandwidth); + transmitter_model.set_tuning_frequency(app_settings.tx_frequency); + transmitter_model.set_tx_gain(app_settings.tx_gain); + } + // Search for valid bitmaps file_list = scan_root_files(u"/sstv", u"*.bmp"); if (!file_list.size()) { diff --git a/firmware/application/apps/ui_sstvtx.hpp b/firmware/application/apps/ui_sstvtx.hpp index 8c3206800..97f2cd684 100644 --- a/firmware/application/apps/ui_sstvtx.hpp +++ b/firmware/application/apps/ui_sstvtx.hpp @@ -34,6 +34,7 @@ #include "sstv.hpp" #include "file.hpp" #include "bmp.hpp" +#include "app_settings.hpp" using namespace sstv; @@ -58,7 +59,10 @@ private: NavigationView& nav_; sstv_scanline scanline_buffer { }; - + // app save settings + std::app_settings settings { }; + std::app_settings::AppSettings app_settings { }; + bool file_error { false }; File bmp_file { }; bmp_header_t bmp_header { };