Allows apps using app settings to use global frequency (#1148)

* Allow apps to not use persisted freq.
* use rx_freq for RX mode
* remove direct call to persistant_memory in tx_model
* app_setting defaults, and tx_view to use ctor value
This commit is contained in:
Kyle Reed 2023-06-12 10:40:32 -07:00 committed by GitHub
parent ccd7bd6fc2
commit 3db2053c21
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 81 additions and 32 deletions

View File

@ -189,10 +189,17 @@ ResultCode save_settings(const std::string& app_name, AppSettings& settings) {
void copy_to_radio_model(const AppSettings& settings) {
// NB: Don't actually adjust the radio here or it will hang.
if (flags_enabled(settings.mode, Mode::TX))
if (flags_enabled(settings.mode, Mode::TX)) {
if (!flags_enabled(settings.options, Options::UseGlobalTargetFrequency))
transmitter_model.set_target_frequency(settings.tx_frequency);
transmitter_model.configure_from_app_settings(settings);
}
if (flags_enabled(settings.mode, Mode::RX)) {
if (!flags_enabled(settings.options, Options::UseGlobalTargetFrequency))
transmitter_model.set_target_frequency(settings.rx_frequency);
receiver_model.configure_from_app_settings(settings);
receiver_model.set_configuration_without_init(
static_cast<ReceiverModel::Mode>(settings.modulation),
@ -241,11 +248,15 @@ void copy_from_radio_model(AppSettings& settings) {
}
/* SettingsManager *************************************************/
SettingsManager::SettingsManager(std::string app_name, Mode mode)
SettingsManager::SettingsManager(
std::string app_name,
Mode mode,
Options options)
: app_name_{std::move(app_name)},
settings_{},
loaded_{false} {
settings_.mode = mode;
settings_.options = options;
auto result = load_settings(app_name_, settings_);
if (result == ResultCode::Ok) {

View File

@ -30,6 +30,7 @@
#include <utility>
#include "file.hpp"
#include "max283x.hpp"
#include "string_format.hpp"
namespace app_settings {
@ -47,25 +48,34 @@ enum class Mode : uint8_t {
RX_TX = 0x03, // Both TX/RX
};
enum class Options {
None = 0x0000,
/* Don't use target frequency from app settings. */
UseGlobalTargetFrequency = 0x0001,
};
// TODO: separate types for TX/RX or union?
/* NB: See RX/TX model headers for default values. */
struct AppSettings {
Mode mode;
uint32_t baseband_bandwidth;
uint32_t sampling_rate;
uint8_t lna;
uint8_t vga;
uint8_t rx_amp;
uint8_t tx_amp;
uint8_t tx_gain;
uint32_t channel_bandwidth;
Mode mode = Mode::RX;
Options options = Options::None;
uint32_t baseband_bandwidth = max283x::filter::bandwidth_minimum;
uint32_t sampling_rate = 3072000; // Good for 48k audio.
uint8_t lna = 32;
uint8_t vga = 32;
uint8_t rx_amp = 0;
uint8_t tx_amp = 0;
uint8_t tx_gain = 35;
uint32_t channel_bandwidth = 1;
uint32_t rx_frequency;
uint32_t tx_frequency;
uint32_t step;
uint8_t modulation;
uint8_t am_config_index;
uint8_t nbfm_config_index;
uint8_t wfm_config_index;
uint8_t squelch;
uint32_t step = 25000;
uint8_t modulation = 1; // NFM
uint8_t am_config_index = 0;
uint8_t nbfm_config_index = 0;
uint8_t wfm_config_index = 0;
uint8_t squelch = 80;
uint8_t volume;
};
@ -84,7 +94,7 @@ void copy_from_radio_model(AppSettings& settings);
* the receiver/transmitter models are set before the control ctors run. */
class SettingsManager {
public:
SettingsManager(std::string app_name, Mode mode);
SettingsManager(std::string app_name, Mode mode, Options options = Options::None);
~SettingsManager();
SettingsManager(const SettingsManager&) = delete;
@ -106,4 +116,7 @@ class SettingsManager {
} // namespace app_settings
ENABLE_FLAGS_OPERATORS(app_settings::Mode);
ENABLE_FLAGS_OPERATORS(app_settings::Options);
#endif /*__APP_SETTINGS_H__*/

View File

@ -156,7 +156,8 @@ class AnalogAudioView : public View {
static constexpr ui::Dim header_height = 3 * 16;
app_settings::SettingsManager settings_{
"rx_audio", app_settings::Mode::RX};
"rx_audio", app_settings::Mode::RX,
app_settings::Options::UseGlobalTargetFrequency};
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};

View File

@ -81,7 +81,8 @@ class MicTXView : public View {
void set_ptt_visibility(bool v);
app_settings::SettingsManager settings_{
"tx_mic", app_settings::Mode::RX_TX};
"tx_mic", app_settings::Mode::RX_TX,
app_settings::Options::UseGlobalTargetFrequency};
bool transmitting{false};
bool va_enabled{false};

View File

@ -265,7 +265,6 @@ void ReceiverModel::set_configuration_without_init(
void ReceiverModel::configure_from_app_settings(
const app_settings::AppSettings& settings) {
set_target_frequency(settings.rx_frequency);
baseband_bandwidth_ = settings.baseband_bandwidth;
sampling_rate_ = settings.sampling_rate;
lna_gain_db_ = settings.lna;

View File

@ -149,8 +149,6 @@ void TransmitterModel::disable() {
void TransmitterModel::configure_from_app_settings(
const app_settings::AppSettings& settings) {
set_target_frequency(settings.tx_frequency);
baseband_bandwidth_ = settings.baseband_bandwidth;
channel_bandwidth_ = settings.channel_bandwidth;
tx_gain_db_ = settings.tx_gain;
@ -163,7 +161,7 @@ void TransmitterModel::configure_from_app_settings(
}
void TransmitterModel::update_tuning_frequency() {
radio::set_tuning_frequency(persistent_memory::target_frequency());
radio::set_tuning_frequency(target_frequency());
}
void TransmitterModel::update_antenna_bias() {

View File

@ -104,7 +104,6 @@ void TransmitterView::set_transmitting(const bool transmitting) {
void TransmitterView::on_show() {
field_frequency.set_value(transmitter_model.target_frequency());
field_frequency_step.set_by_value(receiver_model.frequency_step());
field_gain.set_value(transmitter_model.tx_gain());
field_amp.set_value(transmitter_model.rf_amp() ? 14 : 0);
@ -152,7 +151,6 @@ TransmitterView::TransmitterView(
}
}
field_frequency.set_step(frequency_step);
field_frequency.on_change = [this](rf::Frequency f) {
on_target_frequency_changed(f);
};
@ -162,8 +160,11 @@ TransmitterView::TransmitterView(
};
field_frequency_step.on_change = [this](size_t, OptionsField::value_t v) {
receiver_model.set_frequency_step(v);
this->field_frequency.set_step(v);
};
// TODO: Shouldn't be a ctor parameter because it doesn't work with app settings.
field_frequency_step.set_by_value(frequency_step);
field_gain.on_change = [this](uint32_t tx_gain) {
on_tx_gain_changed(tx_gain);

View File

@ -95,7 +95,25 @@ int int_atan2(int y, int x);
int32_t int16_sin_s4(int32_t x);
template <typename TEnum>
bool flags_enabled(TEnum value, TEnum flags) {
struct is_flags_type {
static constexpr bool value = false;
};
template <typename TEnum>
constexpr bool is_flags_type_v = is_flags_type<TEnum>::value;
#define ENABLE_FLAGS_OPERATORS(type) \
template <> \
struct is_flags_type<type> { static constexpr bool value = true; };
template <typename TEnum>
constexpr std::enable_if_t<is_flags_type_v<TEnum>, TEnum> operator|(TEnum a, TEnum b) {
using under_t = std::underlying_type_t<TEnum>;
return static_cast<TEnum>(static_cast<under_t>(a) | static_cast<under_t>(b));
}
template <typename TEnum>
constexpr std::enable_if_t<is_flags_type_v<TEnum>, bool> flags_enabled(TEnum value, TEnum flags) {
auto i_value = static_cast<std::underlying_type_t<TEnum>>(value);
auto i_flags = static_cast<std::underlying_type_t<TEnum>>(flags);

View File

@ -22,7 +22,7 @@
#include "doctest.h"
#include "utility.hpp"
TEST_SUITE_BEGIN("flags_enabled");
TEST_SUITE_BEGIN("Flags operators");
enum class Flags : uint8_t {
A = 0x1,
@ -30,14 +30,21 @@ enum class Flags : uint8_t {
C = 0x4,
};
ENABLE_FLAGS_OPERATORS(Flags);
TEST_CASE("operator| should combine flags.") {
constexpr Flags f = Flags::A | Flags::C;
static_assert(static_cast<int>(f) == 5);
}
TEST_CASE("When flag set, flags_enabled should be true.") {
Flags f = Flags::A;
CHECK(flags_enabled(f, Flags::A));
constexpr Flags f = Flags::A;
static_assert(flags_enabled(f, Flags::A));
}
TEST_CASE("When flag not set, flags_enabled should be false.") {
Flags f = Flags::B;
CHECK(flags_enabled(f, Flags::A) == false);
constexpr Flags f = Flags::B;
static_assert(flags_enabled(f, Flags::A) == false);
}
TEST_SUITE_END();