diff --git a/firmware/application/apps/ui_settings.cpp b/firmware/application/apps/ui_settings.cpp index 0575ed1f..06fdd12e 100644 --- a/firmware/application/apps/ui_settings.cpp +++ b/firmware/application/apps/ui_settings.cpp @@ -316,8 +316,7 @@ SetConverterSettingsView::SetConverterSettingsView(NavigationView& nav) { &check_converter, &converter_mode, &button_converter_freq, - &button_save, - &button_cancel}); + &button_return}); check_show_converter.set_value(!portapack::persistent_memory::config_hide_converter()); check_show_converter.on_select = [this](Checkbox&, bool v) { @@ -365,16 +364,69 @@ SetConverterSettingsView::SetConverterSettingsView(NavigationView& nav) { }; }; - button_save.on_select = [&nav, this](Button&) { - nav.pop(); - }; - button_cancel.on_select = [&nav, this](Button&) { + button_return.on_select = [&nav, this](Button&) { nav.pop(); }; } void SetConverterSettingsView::focus() { - button_save.focus(); + button_return.focus(); +} + +// --------------------------------------------------------- +// Frequency Correction Settings +// --------------------------------------------------------- +SetFrequencyCorrectionView::SetFrequencyCorrectionView(NavigationView& nav) { + add_children({&text_freqCorrection_about, + &frequency_rx_correction_mode, + &frequency_tx_correction_mode, + &button_freq_rx_correction, + &button_freq_tx_correction, + &button_return}); + + frequency_rx_correction_mode.set_by_value(portapack::persistent_memory::config_freq_rx_correction_updown()); + frequency_rx_correction_mode.on_change = [this](size_t, OptionsField::value_t v) { + portapack::persistent_memory::set_freq_rx_correction_updown(v); + }; + + frequency_tx_correction_mode.set_by_value(portapack::persistent_memory::config_freq_rx_correction_updown()); + frequency_tx_correction_mode.on_change = [this](size_t, OptionsField::value_t v) { + portapack::persistent_memory::set_freq_tx_correction_updown(v); + }; + + button_freq_rx_correction.set_text(to_string_short_freq(portapack::persistent_memory::config_freq_rx_correction()) + "MHz (Rx)"); + button_freq_rx_correction.on_select = [this, &nav](Button& button) { + auto new_view = nav.push(portapack::persistent_memory::config_converter_freq()); + new_view->on_changed = [this, &button](rf::Frequency f) { + if (f > 4000000) + f = 4000000; + portapack::persistent_memory::set_config_freq_rx_correction(f); + // Retune to take converter change in account + receiver_model.set_tuning_frequency(portapack::persistent_memory::tuned_frequency()); + button_freq_rx_correction.set_text("<" + to_string_short_freq(f) + " MHz>"); + }; + }; + + button_freq_tx_correction.set_text(to_string_short_freq(portapack::persistent_memory::config_freq_tx_correction()) + "MHz (Tx)"); + button_freq_tx_correction.on_select = [this, &nav](Button& button) { + auto new_view = nav.push(portapack::persistent_memory::config_converter_freq()); + new_view->on_changed = [this, &button](rf::Frequency f) { + if (f > 4000000) + f = 4000000; + portapack::persistent_memory::set_config_freq_tx_correction(f); + // Retune to take converter change in account + receiver_model.set_tuning_frequency(portapack::persistent_memory::tuned_frequency()); + button_freq_tx_correction.set_text("<" + to_string_short_freq(f) + " MHz>"); + }; + }; + + button_return.on_select = [&nav, this](Button&) { + nav.pop(); + }; +} + +void SetFrequencyCorrectionView::focus() { + button_return.focus(); } // --------------------------------------------------------- @@ -528,6 +580,7 @@ SettingsMenuView::SettingsMenuView(NavigationView& nav) { {"Calibration", ui::Color::dark_cyan(), &bitmap_icon_options_touch, [&nav]() { nav.push(); }}, {"App Settings", ui::Color::dark_cyan(), &bitmap_icon_setup, [&nav]() { nav.push(); }}, {"Converter", ui::Color::dark_cyan(), &bitmap_icon_options_radio, [&nav]() { nav.push(); }}, + {"FreqCorrection", ui::Color::dark_cyan(), &bitmap_icon_options_radio, [&nav]() { nav.push(); }}, {"QR Code", ui::Color::dark_cyan(), &bitmap_icon_qr_code, [&nav]() { nav.push(); }}, {"P.Memory Mgmt", ui::Color::dark_cyan(), &bitmap_icon_memory, [&nav]() { nav.push(); }}, }); diff --git a/firmware/application/apps/ui_settings.hpp b/firmware/application/apps/ui_settings.hpp index 4ab1afd2..730b0cac 100644 --- a/firmware/application/apps/ui_settings.hpp +++ b/firmware/application/apps/ui_settings.hpp @@ -329,13 +329,49 @@ class SetConverterSettingsView : public View { "", }; - Button button_save{ - {2 * 8, 16 * 16, 12 * 8, 32}, - "Save"}; - - Button button_cancel{ + Button button_return{ {16 * 8, 16 * 16, 12 * 8, 32}, - "Cancel", + "return", + }; +}; + +class SetFrequencyCorrectionView : public View { + public: + SetFrequencyCorrectionView(NavigationView& nav); + + void focus() override; + + std::string title() const override { return "FreqCorrect"; }; + + private: + Text text_freqCorrection_about{ + {0, 2 * 16, 240, 16}, + "Set Frequency correction:"}; + + OptionsField frequency_rx_correction_mode{ + {18, 5 * 16 + 4}, + 0, + {{" + ", 0}, + {" - ", 1}}}; + + OptionsField frequency_tx_correction_mode{ + {18, 9 * 16 + 4}, + 0, + {{" + ", 0}, + {" - ", 1}}}; + + Button button_freq_rx_correction{ + {18 + 4 * 8, 5 * 16, 20 * 8, 24}, + "", + }; + Button button_freq_tx_correction{ + {18 + 4 * 8, 9 * 16, 20 * 8, 24}, + "", + }; + + Button button_return{ + {16 * 8, 16 * 16, 12 * 8, 32}, + "Return", }; }; diff --git a/firmware/application/radio.cpp b/firmware/application/radio.cpp index 159924e4..4d811b46 100644 --- a/firmware/application/radio.cpp +++ b/firmware/application/radio.cpp @@ -161,7 +161,7 @@ void set_direction(const rf::Direction new_direction) { bool set_tuning_frequency(const rf::Frequency frequency) { rf::Frequency final_frequency = frequency; - // if feature is enabled + // if converter feature is enabled if (portapack::persistent_memory::config_converter()) { // downconvert if (portapack::persistent_memory::config_updown_converter()) { @@ -171,6 +171,19 @@ bool set_tuning_frequency(const rf::Frequency frequency) { final_frequency = frequency + portapack::persistent_memory::config_converter_freq(); } } + // apply frequency correction + if (direction == rf::Direction::Transmit) { + if (portapack::persistent_memory::config_freq_tx_correction_updown()) // tx freq correction down + final_frequency = final_frequency - portapack::persistent_memory::config_freq_tx_correction(); + else // tx freq correction up + final_frequency = final_frequency + portapack::persistent_memory::config_freq_tx_correction(); + } else { + if (portapack::persistent_memory::config_freq_rx_correction_updown()) // rx freq correction down + final_frequency = final_frequency - portapack::persistent_memory::config_freq_rx_correction(); + else // rx freq correction up + final_frequency = final_frequency + portapack::persistent_memory::config_freq_rx_correction(); + } + const auto tuning_config = tuning::config::create(final_frequency); if (tuning_config.is_valid()) { first_if.disable(); diff --git a/firmware/application/receiver_model.cpp b/firmware/application/receiver_model.cpp index 5419368e..58999f17 100644 --- a/firmware/application/receiver_model.cpp +++ b/firmware/application/receiver_model.cpp @@ -206,7 +206,7 @@ int32_t ReceiverModel::tuning_offset() { } void ReceiverModel::update_tuning_frequency() { - radio::set_tuning_frequency(persistent_memory::tuned_frequency() + tuning_offset()); + radio::set_tuning_frequency(persistent_memory::tuned_frequency()); } void ReceiverModel::update_antenna_bias() { diff --git a/firmware/common/portapack_persistent_memory.cpp b/firmware/common/portapack_persistent_memory.cpp index 9afe5d9d..33722cbd 100644 --- a/firmware/common/portapack_persistent_memory.cpp +++ b/firmware/common/portapack_persistent_memory.cpp @@ -296,6 +296,12 @@ struct data_t { // up/down converter offset int64_t converter_frequency_offset; + // frequency correction + int16_t frequency_rx_correction; + bool updown_frequency_rx_correction; + int16_t frequency_tx_correction; + bool updown_frequency_tx_correction; + constexpr data_t() : structure_version(data_structure_version_enum::VERSION_CURRENT), tuned_frequency(tuned_frequency_reset_value), @@ -327,7 +333,11 @@ struct data_t { hide_converter(0), converter(0), updown_converter(0), - converter_frequency_offset(0) { + converter_frequency_offset(0), + frequency_rx_correction(0), + updown_frequency_rx_correction(0), + frequency_tx_correction(0), + updown_frequency_tx_correction(0) { } }; @@ -755,22 +765,49 @@ bool config_updown_converter() { int64_t config_converter_freq() { return data->converter_frequency_offset; } -void set_config_hide_converter(const bool v) { + +void set_config_hide_converter(bool v) { data->hide_converter = v; if (v) { data->converter = false; } } -void set_config_converter(const bool v) { +void set_config_converter(bool v) { data->converter = v; } -void set_config_updown_converter(const bool v) { +void set_config_updown_converter(bool v) { data->updown_converter = v; } -void set_config_converter_freq(const int64_t v) { +void set_config_converter_freq(int64_t v) { data->converter_frequency_offset = v; } +// frequency correction settings +bool config_freq_tx_correction_updown() { + return data->updown_frequency_tx_correction; +} +void set_freq_tx_correction_updown(bool v) { + data->updown_frequency_tx_correction = v; +} +bool config_freq_rx_correction_updown() { + return data->updown_frequency_rx_correction; +} +void set_freq_rx_correction_updown(bool v) { + data->updown_frequency_rx_correction = v; +} +int16_t config_freq_tx_correction() { + return data->frequency_tx_correction; +} +int16_t config_freq_rx_correction() { + return data->frequency_rx_correction; +} +void set_config_freq_tx_correction(uint16_t v) { + data->frequency_tx_correction = v; +} +void set_config_freq_rx_correction(uint16_t v) { + data->frequency_rx_correction = v; +} + // sd persisting settings int save_persistent_settings_to_file(std::string filename) { delete_file(filename); diff --git a/firmware/common/portapack_persistent_memory.hpp b/firmware/common/portapack_persistent_memory.hpp index 24739f82..3cb1a265 100644 --- a/firmware/common/portapack_persistent_memory.hpp +++ b/firmware/common/portapack_persistent_memory.hpp @@ -177,10 +177,22 @@ void set_load_app_settings(bool v); void set_save_app_settings(bool v); void set_show_bigger_qr_code(bool v); void set_config_splash(bool v); +bool config_hide_converter(); +bool config_converter(); +bool config_updown_converter(); +int64_t config_converter_freq(); void set_config_hide_converter(bool v); void set_config_converter(bool v); -void set_config_updown_converter(const bool v); -void set_config_converter_freq(const int64_t v); +void set_config_updown_converter(bool v); +void set_config_converter_freq(int64_t v); +bool config_freq_tx_correction_updown(); +void set_freq_tx_correction_updown(bool v); +bool config_freq_rx_correction_updown(); +void set_freq_rx_correction_updown(bool v); +int16_t config_freq_tx_correction(); +int16_t config_freq_rx_correction(); +void set_config_freq_tx_correction(uint16_t v); +void set_config_freq_rx_correction(uint16_t v); void set_clock_hidden(bool v); void set_clock_with_date(bool v); void set_config_login(bool v);