mirror of
https://github.com/eried/portapack-mayhem.git
synced 2025-02-03 10:00:12 -05:00
Radio state initialization (#1236)
* WIP RadioState init * TX/RX cleanup * Update all apps using RadioState and setting modulation mode * Set apps to use AM mode * Don't push modulation update in RadioState. * Support passing overrides to Audio and MicTX * Support set_nearest on OptionsField, fix recon step * Fix audio, typo --------- Co-authored-by: kallanreed <kylereed@manzana.lan> Co-authored-by: kallanreed <kallanreed@noreply.github.com>
This commit is contained in:
parent
80c769b97d
commit
9b665a43c5
@ -114,6 +114,8 @@ ResultCode load_settings(const std::string& app_name, AppSettings& settings) {
|
||||
|
||||
if (flags_enabled(settings.mode, Mode::RX)) {
|
||||
read_setting(*data, setting::rx_frequency, settings.rx_frequency);
|
||||
read_setting(*data, setting::lna, settings.lna);
|
||||
read_setting(*data, setting::vga, settings.vga);
|
||||
read_setting(*data, setting::rx_amp, settings.rx_amp);
|
||||
read_setting(*data, setting::modulation, settings.modulation);
|
||||
read_setting(*data, setting::am_config_index, settings.am_config_index);
|
||||
@ -124,8 +126,6 @@ ResultCode load_settings(const std::string& app_name, AppSettings& settings) {
|
||||
|
||||
read_setting(*data, setting::baseband_bandwidth, settings.baseband_bandwidth);
|
||||
read_setting(*data, setting::sampling_rate, settings.sampling_rate);
|
||||
read_setting(*data, setting::lna, settings.lna);
|
||||
read_setting(*data, setting::vga, settings.vga);
|
||||
read_setting(*data, setting::step, settings.step);
|
||||
read_setting(*data, setting::volume, settings.volume);
|
||||
|
||||
@ -153,6 +153,8 @@ ResultCode save_settings(const std::string& app_name, AppSettings& settings) {
|
||||
|
||||
if (flags_enabled(settings.mode, Mode::RX)) {
|
||||
write_setting(settings_file, setting::rx_frequency, settings.rx_frequency);
|
||||
write_setting(settings_file, setting::lna, settings.lna);
|
||||
write_setting(settings_file, setting::vga, settings.vga);
|
||||
write_setting(settings_file, setting::rx_amp, settings.rx_amp);
|
||||
write_setting(settings_file, setting::modulation, settings.modulation);
|
||||
write_setting(settings_file, setting::am_config_index, settings.am_config_index);
|
||||
@ -163,8 +165,6 @@ ResultCode save_settings(const std::string& app_name, AppSettings& settings) {
|
||||
|
||||
write_setting(settings_file, setting::baseband_bandwidth, settings.baseband_bandwidth);
|
||||
write_setting(settings_file, setting::sampling_rate, settings.sampling_rate);
|
||||
write_setting(settings_file, setting::lna, settings.lna);
|
||||
write_setting(settings_file, setting::vga, settings.vga);
|
||||
write_setting(settings_file, setting::step, settings.step);
|
||||
write_setting(settings_file, setting::volume, settings.volume);
|
||||
|
||||
@ -173,6 +173,7 @@ 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.
|
||||
// Specifically 'modulation' which requires a running baseband.
|
||||
|
||||
if (flags_enabled(settings.mode, Mode::TX)) {
|
||||
if (!flags_enabled(settings.options, Options::UseGlobalTargetFrequency))
|
||||
@ -203,14 +204,10 @@ void copy_from_radio_model(AppSettings& settings) {
|
||||
if (flags_enabled(settings.mode, Mode::TX)) {
|
||||
settings.tx_frequency = transmitter_model.target_frequency();
|
||||
settings.baseband_bandwidth = transmitter_model.baseband_bandwidth();
|
||||
settings.sampling_rate = transmitter_model.sampling_rate();
|
||||
settings.tx_amp = transmitter_model.rf_amp();
|
||||
settings.tx_gain = transmitter_model.tx_gain();
|
||||
settings.channel_bandwidth = transmitter_model.channel_bandwidth();
|
||||
|
||||
// TODO: Do these make sense for TX?
|
||||
settings.sampling_rate = transmitter_model.sampling_rate();
|
||||
settings.lna = transmitter_model.lna();
|
||||
settings.vga = transmitter_model.vga();
|
||||
}
|
||||
|
||||
if (flags_enabled(settings.mode, Mode::RX)) {
|
||||
|
@ -31,8 +31,6 @@
|
||||
#include "string_format.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
#include "debug.hpp"
|
||||
|
||||
using namespace portapack;
|
||||
using namespace tonekey;
|
||||
|
||||
@ -135,8 +133,7 @@ SPECOptionsView::SPECOptionsView(
|
||||
AnalogAudioView::AnalogAudioView(
|
||||
NavigationView& nav)
|
||||
: nav_(nav) {
|
||||
// A baseband image _must_ be running before
|
||||
// interacting with the waterfall view.
|
||||
// A baseband image _must_ be running before add waterfall view.
|
||||
baseband::run_image(portapack::spi_flash::image_tag_wideband_spectrum);
|
||||
|
||||
add_children({&rssi,
|
||||
@ -194,6 +191,15 @@ AnalogAudioView::AnalogAudioView(
|
||||
on_modulation_changed(modulation);
|
||||
}
|
||||
|
||||
AnalogAudioView::AnalogAudioView(
|
||||
NavigationView& nav,
|
||||
ReceiverModel::settings_t override)
|
||||
: AnalogAudioView(nav) {
|
||||
// TODO: Which other settings make sense to override?
|
||||
on_frequency_step_changed(override.frequency_step);
|
||||
options_modulation.set_by_value(toUType(override.mode));
|
||||
}
|
||||
|
||||
size_t AnalogAudioView::get_spec_bw_index() {
|
||||
return spec_bw_index;
|
||||
}
|
||||
|
@ -138,6 +138,7 @@ class SPECOptionsView : public View {
|
||||
class AnalogAudioView : public View {
|
||||
public:
|
||||
AnalogAudioView(NavigationView& nav);
|
||||
AnalogAudioView(NavigationView& nav, ReceiverModel::settings_t override);
|
||||
~AnalogAudioView();
|
||||
|
||||
void set_parent_rect(Rect new_parent_rect) override;
|
||||
|
@ -71,8 +71,6 @@ CaptureAppView::CaptureAppView(NavigationView& nav)
|
||||
};
|
||||
|
||||
option_bandwidth.set_selected_index(7); // Preselected default option 500kHz.
|
||||
|
||||
receiver_model.set_modulation(ReceiverModel::Mode::Capture);
|
||||
receiver_model.enable();
|
||||
|
||||
record_view.on_error = [&nav](std::string message) {
|
||||
@ -81,8 +79,6 @@ CaptureAppView::CaptureAppView(NavigationView& nav)
|
||||
}
|
||||
|
||||
CaptureAppView::~CaptureAppView() {
|
||||
// Most other apps can't handle "Capture" mode, set to something standard.
|
||||
receiver_model.set_modulation(ReceiverModel::Mode::WidebandFMAudio);
|
||||
receiver_model.disable();
|
||||
baseband::shutdown();
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ class CaptureAppView : public View {
|
||||
static constexpr ui::Dim header_height = 3 * 16;
|
||||
|
||||
NavigationView& nav_;
|
||||
RxRadioState radio_state_{};
|
||||
RxRadioState radio_state_{ReceiverModel::Mode::Capture};
|
||||
app_settings::SettingsManager settings_{
|
||||
"rx_capture", app_settings::Mode::RX,
|
||||
app_settings::Options::UseGlobalTargetFrequency};
|
||||
|
@ -130,8 +130,7 @@ class ERTAppView : public View {
|
||||
|
||||
RxRadioState radio_state_{
|
||||
2500000 /* bandwidth */,
|
||||
4194304 /* sampling rate */
|
||||
};
|
||||
4194304 /* sampling rate */};
|
||||
app_settings::SettingsManager settings_{
|
||||
"rx_ert", app_settings::Mode::RX};
|
||||
|
||||
|
@ -71,7 +71,6 @@ POCSAGAppView::POCSAGAppView(NavigationView& nav)
|
||||
if (!settings_.loaded())
|
||||
field_frequency.set_value(initial_target_frequency);
|
||||
|
||||
receiver_model.set_modulation(ReceiverModel::Mode::NarrowbandFMAudio);
|
||||
receiver_model.enable();
|
||||
|
||||
// TODO: app setting instead?
|
||||
|
@ -106,8 +106,7 @@ class TPMSAppView : public View {
|
||||
|
||||
RxRadioState radio_state_{
|
||||
1750000 /* bandwidth */,
|
||||
2457600 /* sampling rate */
|
||||
};
|
||||
2457600 /* sampling rate */};
|
||||
app_settings::SettingsManager settings_{
|
||||
"rx_tpms", app_settings::Mode::RX};
|
||||
|
||||
|
@ -513,8 +513,7 @@ ADSBRxView::ADSBRxView(NavigationView& nav) {
|
||||
|
||||
baseband::set_adsb();
|
||||
|
||||
receiver_model.set_target_frequency(1090000000);
|
||||
receiver_model.set_modulation(ReceiverModel::Mode::SpectrumAnalysis);
|
||||
receiver_model.set_target_frequency(1'090'000'000);
|
||||
receiver_model.enable();
|
||||
}
|
||||
|
||||
|
@ -343,8 +343,8 @@ class ADSBRxView : public View {
|
||||
private:
|
||||
RxRadioState radio_state_{
|
||||
2500000 /* bandwidth */,
|
||||
2000000 /* sampling rate */
|
||||
};
|
||||
2000000 /* sampling rate */,
|
||||
ReceiverModel::Mode::SpectrumAnalysis};
|
||||
app_settings::SettingsManager settings_{
|
||||
"rx_adsb", app_settings::Mode::RX};
|
||||
|
||||
|
@ -91,7 +91,6 @@ AFSKRxView::AFSKRxView(NavigationView& nav)
|
||||
audio::set_rate(audio::Rate::Hz_24000);
|
||||
audio::output::start();
|
||||
|
||||
receiver_model.set_modulation(ReceiverModel::Mode::NarrowbandFMAudio);
|
||||
receiver_model.enable();
|
||||
}
|
||||
|
||||
|
@ -119,7 +119,6 @@ APRSRxView::APRSRxView(NavigationView& nav, Rect parent_rect)
|
||||
audio::set_rate(audio::Rate::Hz_24000);
|
||||
audio::output::start();
|
||||
|
||||
receiver_model.set_modulation(ReceiverModel::Mode::NarrowbandFMAudio);
|
||||
receiver_model.enable();
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,6 @@ BTLERxView::BTLERxView(NavigationView& nav)
|
||||
audio::set_rate(audio::Rate::Hz_24000);
|
||||
audio::output::start();
|
||||
|
||||
receiver_model.set_modulation(ReceiverModel::Mode::WidebandFMAudio);
|
||||
receiver_model.enable();
|
||||
}
|
||||
|
||||
|
@ -51,8 +51,8 @@ class BTLERxView : public View {
|
||||
NavigationView& nav_;
|
||||
RxRadioState radio_state_{
|
||||
4000000 /* bandwidth */,
|
||||
4000000 /* sampling rate */
|
||||
};
|
||||
4000000 /* sampling rate */,
|
||||
ReceiverModel::Mode::WidebandFMAudio};
|
||||
app_settings::SettingsManager settings_{
|
||||
"rx_btle", app_settings::Mode::RX};
|
||||
|
||||
|
@ -471,9 +471,9 @@ GlassView::GlassView(
|
||||
|
||||
button_marker.on_select = [this](ButtonWithEncoder&) {
|
||||
receiver_model.set_target_frequency(marker); // Center tune rx in marker freq.
|
||||
receiver_model.set_frequency_step(MHZ_DIV); // Preset a 1 MHz frequency step into RX -> AUDIO
|
||||
nav_.pop();
|
||||
nav_.push<AnalogAudioView>(); // Jump into audio view
|
||||
auto settings = receiver_model.settings();
|
||||
settings.frequency_step = MHZ_DIV; // Preset a 1 MHz frequency step into RX -> AUDIO
|
||||
nav_.replace<AnalogAudioView>(settings); // Jump into audio view
|
||||
};
|
||||
|
||||
field_trigger.on_change = [this](int32_t v) {
|
||||
@ -495,9 +495,9 @@ GlassView::GlassView(
|
||||
|
||||
button_jump.on_select = [this](Button&) {
|
||||
receiver_model.set_target_frequency(max_freq_hold); // Center tune rx in marker freq.
|
||||
receiver_model.set_frequency_step(MHZ_DIV); // Preset a 1 MHz frequency step into RX -> AUDIO
|
||||
nav_.pop();
|
||||
nav_.push<AnalogAudioView>(); // Jump into audio view
|
||||
auto settings = receiver_model.settings();
|
||||
settings.frequency_step = MHZ_DIV; // Preset a 1 MHz frequency step into RX -> AUDIO
|
||||
nav_.replace<AnalogAudioView>(settings); // Jump into audio view
|
||||
};
|
||||
|
||||
button_rst.on_select = [this](Button&) {
|
||||
@ -513,7 +513,6 @@ GlassView::GlassView(
|
||||
marker_pixel_index = 120;
|
||||
on_range_changed();
|
||||
|
||||
receiver_model.set_modulation(ReceiverModel::Mode::SpectrumAnalysis);
|
||||
receiver_model.set_sampling_rate(looking_glass_sampling_rate); // 20mhz
|
||||
receiver_model.set_baseband_bandwidth(looking_glass_bandwidth); // possible values: 1.75/2.5/3.5/5/5.5/6/7/8/9/10/12/14/15/20/24/28MHz
|
||||
receiver_model.set_squelch_level(0);
|
||||
|
@ -71,7 +71,7 @@ class GlassView : public View {
|
||||
|
||||
private:
|
||||
NavigationView& nav_;
|
||||
RxRadioState radio_state_{};
|
||||
RxRadioState radio_state_{ReceiverModel::Mode::SpectrumAnalysis};
|
||||
app_settings::SettingsManager settings_{
|
||||
"rx_glass", app_settings::Mode::RX};
|
||||
|
||||
|
@ -155,7 +155,7 @@ void MicTXView::rxaudio(bool is_on) {
|
||||
if (enable_wfm) { // WFM, BW 200Khz aprox, or the two new addional BW filters (180k, 40k)
|
||||
baseband::run_image(portapack::spi_flash::image_tag_wfm_audio);
|
||||
receiver_model.set_modulation(ReceiverModel::Mode::WidebandFMAudio);
|
||||
// receiver_model.set_wfm_configuration(n); // it is called above , depending user's selection (200k, 180k,40k).
|
||||
// receiver_model.set_wfm_configuration(n); // it is called above, depending user's selection (200k, 180k, 0k).
|
||||
} else { // NFM BW:8k5 or 11k / FM BW 16k
|
||||
baseband::run_image(portapack::spi_flash::image_tag_nfm_audio);
|
||||
receiver_model.set_modulation(ReceiverModel::Mode::NarrowbandFMAudio); //
|
||||
@ -281,15 +281,15 @@ MicTXView::MicTXView(
|
||||
shift_bits_s16 = 6; // -08 dB’s respect ref level, (when +20dB's boost OFF)
|
||||
break; // now mic-boost off (+00dBs) shift bits (6) (+0+12dB's)=12 dBs => -08dB's respect ref.
|
||||
}
|
||||
ak4951_alc_and_wm8731_boost_GUI = v; // 0,..4 WM8731_boost dB's options, (combination boost on/off , and effective gain in captured data >>x)
|
||||
audio::input::start(ak4951_alc_and_wm8731_boost_GUI); // Detected (WM8731) , set up the proper wm_boost on/off , 0..4 (0,1) boost_on , (2,3,4) boost_0ff
|
||||
ak4951_alc_and_wm8731_boost_GUI = v; // 0..4, WM8731_boost dB's options, (combination boost on/off, and effective gain in captured data >>x)
|
||||
audio::input::start(ak4951_alc_and_wm8731_boost_GUI); // Detected (WM8731), set up the proper wm_boost on/off, 0..4 (0,1) boost_on, (2,3,4) boost_off
|
||||
configure_baseband(); // to update in real time, sending msg, var-parameters >>shift_bits FM msg, to audio_tx from M0 to M4 Proc -
|
||||
};
|
||||
options_wm8731_boost_mode.set_selected_index(3); // preset GUI index 3 as default WM -> -02 dB's.
|
||||
} else {
|
||||
shift_bits_s16 = 8; // Initialized default fixed >>8_FM for FM tx mod, shift audio data for AK4951, using top 8 bits s16 data (>>8)
|
||||
options_ak4951_alc_mode.on_change = [this](size_t, int8_t v) {
|
||||
ak4951_alc_and_wm8731_boost_GUI = v; // 0,..11, AK4951 Mic -Automatic volume Level Control options,
|
||||
ak4951_alc_and_wm8731_boost_GUI = v; // 0..11, AK4951 Mic -Automatic volume Level Control options,
|
||||
audio::input::start(ak4951_alc_and_wm8731_boost_GUI); // Detected (AK4951) ==> Set up proper ALC mode from 0..11 options
|
||||
configure_baseband(); // sending fixed >>8_FM, var-parameters msg, to audiotx from this M0 to M4 process.
|
||||
};
|
||||
@ -607,6 +607,36 @@ MicTXView::MicTXView(
|
||||
audio::input::start(ak4951_alc_and_wm8731_boost_GUI); // When detected AK4951 => set up ALC mode; when detected WM8731 => set up mic_boost ON/OFF.
|
||||
}
|
||||
|
||||
MicTXView::MicTXView(
|
||||
NavigationView& nav,
|
||||
ReceiverModel::settings_t override)
|
||||
: MicTXView(nav) {
|
||||
// Try to use the modulation/bandwidth from RX settings.
|
||||
// TODO: These concepts should be merged so there's only one.
|
||||
// TODO: enums/constants for these indexes.
|
||||
switch (override.mode) {
|
||||
case ReceiverModel::Mode::AMAudio:
|
||||
options_mode.set_selected_index(2);
|
||||
break;
|
||||
case ReceiverModel::Mode::NarrowbandFMAudio:
|
||||
options_mode.set_selected_index(0);
|
||||
break;
|
||||
case ReceiverModel::Mode::WidebandFMAudio:
|
||||
options_mode.set_selected_index(1);
|
||||
break;
|
||||
|
||||
// Unsupported modulations.
|
||||
case ReceiverModel::Mode::SpectrumAnalysis:
|
||||
case ReceiverModel::Mode::Capture:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO: bandwidth selection is tied too tightly to the UI
|
||||
// controls. It's not possible to set the bandwidth here without
|
||||
// refactoring. Also options_mode seems to have a category error.
|
||||
}
|
||||
|
||||
MicTXView::~MicTXView() {
|
||||
audio::input::stop();
|
||||
transmitter_model.set_target_frequency(tx_frequency); // Save Tx frequency instead of Rx. Or maybe we need some "System Wide" changes to seperate Tx and Rx frequency.
|
||||
|
@ -20,6 +20,8 @@
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
// TODO: Consolidate Modulation/Bandwidth modes/settings with freqman/receiver_model.
|
||||
|
||||
#ifndef __UI_MICTX_H__
|
||||
#define __UI_MICTX_H__
|
||||
|
||||
@ -43,6 +45,7 @@ namespace ui {
|
||||
class MicTXView : public View {
|
||||
public:
|
||||
MicTXView(NavigationView& nav);
|
||||
MicTXView(NavigationView& nav, ReceiverModel::settings_t override);
|
||||
~MicTXView();
|
||||
|
||||
MicTXView(const MicTXView&) = delete;
|
||||
@ -117,6 +120,7 @@ class MicTXView : public View {
|
||||
uint8_t shift_bits_s16{4}; // shift bits factor to the captured ADC S16 audio sample.
|
||||
|
||||
// AM TX Stuff
|
||||
// TODO: Some of this stuff is mutually exclusive. Need a better representation.
|
||||
bool enable_am{false};
|
||||
bool enable_dsb{false};
|
||||
bool enable_usb{false};
|
||||
@ -176,7 +180,7 @@ class MicTXView : public View {
|
||||
{"x2.0", 20}}};
|
||||
|
||||
OptionsField options_ak4951_alc_mode{
|
||||
{20 * 8, 1 * 8}, // Coordinates are: int:x (px), int:y (px)
|
||||
{20 * 8, 1 * 8},
|
||||
11,
|
||||
{
|
||||
{" OFF-12kHz", 0}, // Nothing changed from ORIGINAL, keeping ALL programmable AK4951 Digital Block->OFF, sampling 24Khz)
|
||||
@ -194,7 +198,7 @@ class MicTXView : public View {
|
||||
}};
|
||||
|
||||
OptionsField options_wm8731_boost_mode{
|
||||
{22 * 8, 1 * 8}, // Coordinates are: int:x (px), int:y (px)
|
||||
{22 * 8, 1 * 8},
|
||||
5,
|
||||
{
|
||||
{"ON +12dB", 0}, // WM8731 Mic Boost ON, original+12dBs condition, easy to saturate ADC sat in high voice, relative G = +12 dB's respect ref level
|
||||
|
@ -76,7 +76,6 @@ NRFRxView::NRFRxView(NavigationView& nav)
|
||||
audio::set_rate(audio::Rate::Hz_24000);
|
||||
audio::output::start();
|
||||
|
||||
receiver_model.set_modulation(ReceiverModel::Mode::WidebandFMAudio);
|
||||
receiver_model.enable();
|
||||
}
|
||||
|
||||
|
@ -51,8 +51,8 @@ class NRFRxView : public View {
|
||||
NavigationView& nav_;
|
||||
RxRadioState radio_state_{
|
||||
4000000 /* bandwidth */,
|
||||
4000000 /* sampling rate */
|
||||
};
|
||||
4000000 /* sampling rate */,
|
||||
ReceiverModel::Mode::WidebandFMAudio};
|
||||
app_settings::SettingsManager settings_{
|
||||
"rx_nrf", app_settings::Mode::RX};
|
||||
|
||||
|
@ -80,8 +80,7 @@ bool POCSAGTXView::start_tx() {
|
||||
progressbar.set_max(total_frames);
|
||||
|
||||
transmitter_model.set_rf_amp(true);
|
||||
transmitter_model.set_lna(40);
|
||||
transmitter_model.set_vga(40);
|
||||
transmitter_model.set_tx_gain(40);
|
||||
transmitter_model.enable();
|
||||
|
||||
uint8_t* data_ptr = shared_memory.bb_data.data;
|
||||
|
@ -366,7 +366,6 @@ ReconView::~ReconView() {
|
||||
recon_save_config_to_sd();
|
||||
if (field_mode.selected_index_value() != SPEC_MODULATION)
|
||||
audio::output::stop();
|
||||
receiver_model.set_modulation(ReceiverModel::Mode::WidebandFMAudio);
|
||||
receiver_model.disable();
|
||||
baseband::shutdown();
|
||||
}
|
||||
@ -549,8 +548,9 @@ ReconView::ReconView(NavigationView& nav)
|
||||
};
|
||||
|
||||
button_audio_app.on_select = [this](Button&) {
|
||||
nav_.pop();
|
||||
nav_.push<AnalogAudioView>();
|
||||
auto settings = receiver_model.settings();
|
||||
settings.frequency_step = step_mode.selected_index_value();
|
||||
nav_.replace<AnalogAudioView>(settings);
|
||||
};
|
||||
|
||||
button_loop_config.on_select = [this](Button&) {
|
||||
@ -569,9 +569,9 @@ ReconView::ReconView(NavigationView& nav)
|
||||
button_mic_app.on_select = [this](Button&) {
|
||||
if (frequency_list.size() > 0 && current_index >= 0 && (unsigned)current_index < frequency_list.size()) {
|
||||
if (frequency_list[current_index].type == HAMRADIO) {
|
||||
// if it's a HAMRADIO entry, then frequency_a is the freq at which the repeater reveive, so we have to set it in transmit in mic app
|
||||
// if it's a HAMRADIO entry, then frequency_a is the freq at which the repeater receives, so we have to set it in transmit in mic app
|
||||
transmitter_model.set_target_frequency(frequency_list[current_index].frequency_a);
|
||||
// if it's a HAMRADIO entry, then frequency_b is the freq at which the repeater transmit, so we have to set it in receive in mic app
|
||||
// if it's a HAMRADIO entry, then frequency_b is the freq at which the repeater transmits, so we have to set it in receive in mic app
|
||||
receiver_model.set_target_frequency(frequency_list[current_index].frequency_b);
|
||||
} else {
|
||||
// it's single or range so we us actual tuned frequency
|
||||
@ -579,9 +579,9 @@ ReconView::ReconView(NavigationView& nav)
|
||||
receiver_model.set_target_frequency(freq);
|
||||
}
|
||||
}
|
||||
// there is no way yet to set modulation and bandwidth from Recon to MicApp
|
||||
nav_.pop();
|
||||
nav_.push<MicTXView>();
|
||||
|
||||
// MicTX wants Modulation and Bandwidth overrides, but that's only stored on the RX model.
|
||||
nav_.replace<MicTXView>(receiver_model.settings());
|
||||
};
|
||||
|
||||
button_remove.on_select = [this](ButtonWithEncoder&) {
|
||||
|
@ -392,16 +392,17 @@ ScannerView::ScannerView(
|
||||
button_audio_app.on_select = [this](Button&) {
|
||||
if (scan_thread)
|
||||
scan_thread->stop();
|
||||
nav_.pop();
|
||||
nav_.push<AnalogAudioView>();
|
||||
auto settings = receiver_model.settings();
|
||||
settings.frequency_step = field_step.selected_index_value();
|
||||
nav_.replace<AnalogAudioView>(settings);
|
||||
};
|
||||
|
||||
// Button to switch to Mic app
|
||||
button_mic_app.on_select = [this](Button&) {
|
||||
if (scan_thread)
|
||||
scan_thread->stop();
|
||||
nav_.pop();
|
||||
nav_.push<MicTXView>();
|
||||
// MicTX wants Modulation and Bandwidth overrides, but that's only stored on the RX model.
|
||||
nav_.replace<MicTXView>(receiver_model.settings());
|
||||
};
|
||||
|
||||
// Button to delete current frequency from scan Freq List
|
||||
|
@ -122,17 +122,7 @@ void SearchView::do_detection() {
|
||||
locked = true;
|
||||
locked_bin = bin_max;
|
||||
|
||||
// TODO
|
||||
/*nav_.pop();
|
||||
receiver_model.disable();
|
||||
baseband::shutdown();
|
||||
nav_.pop();*/
|
||||
|
||||
/*if (options_goto.selected_index() == 1)
|
||||
nav_.push<AnalogAudioView>(false);
|
||||
else if (options_goto.selected_index() == 2)
|
||||
nav_.push<POCSAGAppView>();
|
||||
*/
|
||||
// TODO: open Audio.
|
||||
} else
|
||||
text_infos.set("Out of range");
|
||||
}
|
||||
@ -414,7 +404,6 @@ SearchView::SearchView(
|
||||
|
||||
on_range_changed();
|
||||
|
||||
receiver_model.set_modulation(ReceiverModel::Mode::SpectrumAnalysis);
|
||||
receiver_model.enable();
|
||||
}
|
||||
|
||||
|
@ -92,8 +92,8 @@ class SearchView : public View {
|
||||
NavigationView& nav_;
|
||||
RxRadioState radio_state_{
|
||||
2500000 /* bandwidth */,
|
||||
SEARCH_SLICE_WIDTH /* sampling rate */
|
||||
};
|
||||
SEARCH_SLICE_WIDTH /* sampling rate */,
|
||||
ReceiverModel::Mode::SpectrumAnalysis};
|
||||
|
||||
struct slice_t {
|
||||
rf::Frequency center_frequency;
|
||||
|
@ -27,6 +27,8 @@
|
||||
using option_t = std::pair<std::string, int32_t>;
|
||||
using options_t = std::vector<option_t>;
|
||||
|
||||
// TODO: Consolidate with receiver_model.
|
||||
// These definitions are spread all over and stiched together with indices.
|
||||
options_t freqman_entry_modulations = {
|
||||
{"AM", 0},
|
||||
{"NFM", 1},
|
||||
|
@ -28,38 +28,47 @@
|
||||
#include "receiver_model.hpp"
|
||||
#include "transmitter_model.hpp"
|
||||
|
||||
/* Stashes current radio bandwidth and sampling rate.
|
||||
* Inits to defaults, and restores previous when destroyed.
|
||||
* The idea here is that an app will eventually call enable
|
||||
* on the model which will sync all of the model state into
|
||||
* the radio. We tried lazily setting these using the
|
||||
* set_configuration_without_update function, but there are
|
||||
* still various UI components (mainly Waterfall) that need
|
||||
* the radio set in order to load properly.
|
||||
/* Reinitialized model with defaults so each app can start
|
||||
* with a clean, default model instance. We tried lazily
|
||||
* setting these using the set_configuration_without_update
|
||||
* function, but there are still various UI components
|
||||
* (e.g. Waterfall) that need the radio set in order to load.
|
||||
* NB: This member must be added before SettingsManager. */
|
||||
template <typename TModel, TModel* model>
|
||||
class RadioState {
|
||||
public:
|
||||
RadioState()
|
||||
: RadioState(max2837::filter::bandwidth_minimum, 3072000) {
|
||||
RadioState() {
|
||||
model->initialize();
|
||||
}
|
||||
|
||||
RadioState(uint32_t new_bandwidth, uint32_t new_sampling_rate)
|
||||
: prev_bandwidth_{model->baseband_bandwidth()},
|
||||
prev_sampling_rate_{model->sampling_rate()} {
|
||||
// Update the new settings in the radio.
|
||||
RadioState(uint32_t new_bandwidth, uint32_t new_sampling_rate) {
|
||||
model->initialize();
|
||||
model->set_sampling_rate(new_sampling_rate);
|
||||
model->set_baseband_bandwidth(new_bandwidth);
|
||||
}
|
||||
|
||||
~RadioState() {
|
||||
model->set_configuration_without_update(
|
||||
prev_bandwidth_, prev_sampling_rate_);
|
||||
// NB: only enabled for RX model.
|
||||
template <
|
||||
typename U = TModel,
|
||||
typename Mode = std::enable_if_t<sizeof(typename U::Mode), typename U::Mode> >
|
||||
RadioState(Mode new_mode) {
|
||||
model->initialize();
|
||||
model->settings().mode = new_mode;
|
||||
}
|
||||
|
||||
private:
|
||||
const uint32_t prev_bandwidth_;
|
||||
const uint32_t prev_sampling_rate_;
|
||||
// NB: only enabled for RX model.
|
||||
template <
|
||||
typename U = TModel,
|
||||
typename Mode = std::enable_if_t<sizeof(typename U::Mode), typename U::Mode> >
|
||||
RadioState(
|
||||
uint32_t new_bandwidth,
|
||||
uint32_t new_sampling_rate,
|
||||
Mode new_mode) {
|
||||
model->initialize();
|
||||
model->set_sampling_rate(new_sampling_rate);
|
||||
model->set_baseband_bandwidth(new_bandwidth);
|
||||
model->settings().mode = new_mode;
|
||||
}
|
||||
};
|
||||
|
||||
using RxRadioState = RadioState<ReceiverModel, &portapack::receiver_model>;
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
|
||||
* Copyright (C) 2023 Kyle Reed
|
||||
*
|
||||
* This file is part of PortaPack.
|
||||
*
|
||||
@ -70,72 +71,114 @@ void ReceiverModel::set_target_frequency(rf::Frequency f) {
|
||||
update_tuning_frequency();
|
||||
}
|
||||
|
||||
uint32_t ReceiverModel::baseband_bandwidth() const {
|
||||
return settings_.baseband_bandwidth;
|
||||
}
|
||||
|
||||
void ReceiverModel::set_baseband_bandwidth(uint32_t v) {
|
||||
settings_.baseband_bandwidth = v;
|
||||
update_baseband_bandwidth();
|
||||
}
|
||||
|
||||
uint32_t ReceiverModel::sampling_rate() const {
|
||||
return settings_.sampling_rate;
|
||||
}
|
||||
|
||||
void ReceiverModel::set_sampling_rate(uint32_t v) {
|
||||
settings_.sampling_rate = v;
|
||||
update_sampling_rate();
|
||||
}
|
||||
|
||||
rf::Frequency ReceiverModel::frequency_step() const {
|
||||
return frequency_step_;
|
||||
return settings_.frequency_step;
|
||||
}
|
||||
|
||||
void ReceiverModel::set_frequency_step(rf::Frequency f) {
|
||||
frequency_step_ = f;
|
||||
settings_.frequency_step = f;
|
||||
}
|
||||
|
||||
uint8_t ReceiverModel::lna() const {
|
||||
return settings_.lna_gain_db;
|
||||
}
|
||||
|
||||
void ReceiverModel::set_lna(uint8_t v_db) {
|
||||
settings_.lna_gain_db = v_db;
|
||||
update_lna();
|
||||
}
|
||||
|
||||
uint8_t ReceiverModel::vga() const {
|
||||
return settings_.vga_gain_db;
|
||||
}
|
||||
|
||||
void ReceiverModel::set_vga(uint8_t v_db) {
|
||||
settings_.vga_gain_db = v_db;
|
||||
update_vga();
|
||||
}
|
||||
|
||||
bool ReceiverModel::rf_amp() const {
|
||||
return settings_.rf_amp;
|
||||
}
|
||||
|
||||
void ReceiverModel::set_rf_amp(bool enabled) {
|
||||
settings_.rf_amp = enabled;
|
||||
update_rf_amp();
|
||||
}
|
||||
|
||||
ReceiverModel::Mode ReceiverModel::modulation() const {
|
||||
return settings_.mode;
|
||||
}
|
||||
|
||||
void ReceiverModel::set_modulation(Mode v) {
|
||||
settings_.mode = v;
|
||||
update_modulation();
|
||||
}
|
||||
|
||||
uint8_t ReceiverModel::am_configuration() const {
|
||||
return settings_.am_config_index;
|
||||
}
|
||||
|
||||
void ReceiverModel::set_am_configuration(uint8_t n) {
|
||||
if (n < am_configs.size()) {
|
||||
settings_.am_config_index = n;
|
||||
update_modulation();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ReceiverModel::nbfm_configuration() const {
|
||||
return settings_.nbfm_config_index;
|
||||
}
|
||||
|
||||
void ReceiverModel::set_nbfm_configuration(uint8_t n) {
|
||||
if (n < nbfm_configs.size()) {
|
||||
settings_.nbfm_config_index = n;
|
||||
update_modulation();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ReceiverModel::wfm_configuration() const {
|
||||
return settings_.wfm_config_index;
|
||||
}
|
||||
|
||||
void ReceiverModel::set_wfm_configuration(uint8_t n) {
|
||||
if (n < wfm_configs.size()) {
|
||||
settings_.wfm_config_index = n;
|
||||
update_modulation();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ReceiverModel::squelch_level() const {
|
||||
return settings_.squelch_level;
|
||||
}
|
||||
|
||||
void ReceiverModel::set_squelch_level(uint8_t v) {
|
||||
settings_.squelch_level = v;
|
||||
update_modulation();
|
||||
}
|
||||
|
||||
void ReceiverModel::set_antenna_bias() {
|
||||
update_antenna_bias();
|
||||
}
|
||||
|
||||
bool ReceiverModel::rf_amp() const {
|
||||
return rf_amp_;
|
||||
}
|
||||
|
||||
void ReceiverModel::set_rf_amp(bool enabled) {
|
||||
rf_amp_ = enabled;
|
||||
update_rf_amp();
|
||||
}
|
||||
|
||||
int32_t ReceiverModel::lna() const {
|
||||
return lna_gain_db_;
|
||||
}
|
||||
|
||||
void ReceiverModel::set_lna(int32_t v_db) {
|
||||
lna_gain_db_ = v_db;
|
||||
update_lna();
|
||||
}
|
||||
|
||||
uint32_t ReceiverModel::baseband_bandwidth() const {
|
||||
return baseband_bandwidth_;
|
||||
}
|
||||
|
||||
void ReceiverModel::set_baseband_bandwidth(uint32_t v) {
|
||||
baseband_bandwidth_ = v;
|
||||
update_baseband_bandwidth();
|
||||
}
|
||||
|
||||
int32_t ReceiverModel::vga() const {
|
||||
return vga_gain_db_;
|
||||
}
|
||||
|
||||
void ReceiverModel::set_vga(int32_t v_db) {
|
||||
vga_gain_db_ = v_db;
|
||||
update_vga();
|
||||
}
|
||||
|
||||
uint32_t ReceiverModel::sampling_rate() const {
|
||||
return sampling_rate_;
|
||||
}
|
||||
|
||||
void ReceiverModel::set_sampling_rate(uint32_t v) {
|
||||
sampling_rate_ = v;
|
||||
update_sampling_rate();
|
||||
}
|
||||
|
||||
ReceiverModel::Mode ReceiverModel::modulation() const {
|
||||
return mode_;
|
||||
}
|
||||
|
||||
void ReceiverModel::set_modulation(const Mode v) {
|
||||
mode_ = v;
|
||||
update_modulation();
|
||||
}
|
||||
|
||||
volume_t ReceiverModel::headphone_volume() const {
|
||||
return persistent_memory::headphone_volume();
|
||||
}
|
||||
@ -157,15 +200,6 @@ void ReceiverModel::set_normalized_headphone_volume(uint8_t v) {
|
||||
set_headphone_volume(new_volume);
|
||||
}
|
||||
|
||||
uint8_t ReceiverModel::squelch_level() const {
|
||||
return squelch_level_;
|
||||
}
|
||||
|
||||
void ReceiverModel::set_squelch_level(uint8_t v) {
|
||||
squelch_level_ = v;
|
||||
update_modulation();
|
||||
}
|
||||
|
||||
void ReceiverModel::enable() {
|
||||
enabled_ = true;
|
||||
radio::set_direction(rf::Direction::Receive);
|
||||
@ -193,6 +227,35 @@ void ReceiverModel::disable() {
|
||||
led_rx.off();
|
||||
}
|
||||
|
||||
void ReceiverModel::initialize() {
|
||||
settings_ = settings_t{};
|
||||
}
|
||||
|
||||
void ReceiverModel::set_configuration_without_update(
|
||||
Mode new_mode,
|
||||
rf::Frequency new_frequency_step,
|
||||
size_t new_am_config_index,
|
||||
size_t new_nbfm_config_index,
|
||||
size_t new_wfm_config_index,
|
||||
uint8_t new_squelch_level) {
|
||||
settings_.mode = new_mode;
|
||||
settings_.frequency_step = new_frequency_step;
|
||||
settings_.am_config_index = new_am_config_index;
|
||||
settings_.nbfm_config_index = new_nbfm_config_index;
|
||||
settings_.wfm_config_index = new_wfm_config_index;
|
||||
settings_.squelch_level = new_squelch_level;
|
||||
}
|
||||
|
||||
void ReceiverModel::configure_from_app_settings(
|
||||
const app_settings::AppSettings& settings) {
|
||||
settings_.baseband_bandwidth = settings.baseband_bandwidth;
|
||||
settings_.sampling_rate = settings.sampling_rate;
|
||||
settings_.lna_gain_db = settings.lna;
|
||||
settings_.vga_gain_db = settings.vga;
|
||||
settings_.rf_amp = settings.rx_amp;
|
||||
settings_.squelch_level = settings.squelch;
|
||||
}
|
||||
|
||||
int32_t ReceiverModel::tuning_offset() {
|
||||
if ((modulation() == Mode::SpectrumAnalysis)) {
|
||||
return 0;
|
||||
@ -206,78 +269,8 @@ void ReceiverModel::update_tuning_frequency() {
|
||||
radio::set_tuning_frequency(target_frequency() + tuning_offset());
|
||||
}
|
||||
|
||||
void ReceiverModel::update_antenna_bias() {
|
||||
if (enabled_)
|
||||
radio::set_antenna_bias(portapack::get_antenna_bias());
|
||||
}
|
||||
|
||||
void ReceiverModel::update_rf_amp() {
|
||||
radio::set_rf_amp(rf_amp_);
|
||||
}
|
||||
|
||||
void ReceiverModel::update_lna() {
|
||||
radio::set_lna_gain(lna_gain_db_);
|
||||
}
|
||||
|
||||
void ReceiverModel::update_baseband_bandwidth() {
|
||||
radio::set_baseband_filter_bandwidth(baseband_bandwidth_);
|
||||
}
|
||||
|
||||
void ReceiverModel::update_vga() {
|
||||
radio::set_vga_gain(vga_gain_db_);
|
||||
}
|
||||
|
||||
void ReceiverModel::set_am_configuration(const size_t n) {
|
||||
if (n < am_configs.size()) {
|
||||
am_config_index = n;
|
||||
update_modulation();
|
||||
}
|
||||
}
|
||||
|
||||
void ReceiverModel::set_nbfm_configuration(const size_t n) {
|
||||
if (n < nbfm_configs.size()) {
|
||||
nbfm_config_index = n;
|
||||
update_modulation();
|
||||
}
|
||||
}
|
||||
|
||||
void ReceiverModel::set_wfm_configuration(const size_t n) {
|
||||
if (n < wfm_configs.size()) {
|
||||
wfm_config_index = n;
|
||||
update_modulation();
|
||||
}
|
||||
}
|
||||
|
||||
void ReceiverModel::set_configuration_without_update(
|
||||
uint32_t baseband_bandwidth,
|
||||
uint32_t sampling_rate) {
|
||||
baseband_bandwidth_ = baseband_bandwidth;
|
||||
sampling_rate_ = sampling_rate;
|
||||
}
|
||||
|
||||
void ReceiverModel::set_configuration_without_update(
|
||||
Mode new_mode,
|
||||
rf::Frequency new_frequency_step,
|
||||
size_t new_am_config_index,
|
||||
size_t new_nbfm_config_index,
|
||||
size_t new_wfm_config_index,
|
||||
uint8_t new_squelch_level) {
|
||||
mode_ = new_mode;
|
||||
frequency_step_ = new_frequency_step;
|
||||
am_config_index = new_am_config_index;
|
||||
nbfm_config_index = new_nbfm_config_index;
|
||||
wfm_config_index = new_wfm_config_index;
|
||||
squelch_level_ = new_squelch_level;
|
||||
}
|
||||
|
||||
void ReceiverModel::configure_from_app_settings(
|
||||
const app_settings::AppSettings& settings) {
|
||||
baseband_bandwidth_ = settings.baseband_bandwidth;
|
||||
sampling_rate_ = settings.sampling_rate;
|
||||
lna_gain_db_ = settings.lna;
|
||||
vga_gain_db_ = settings.vga;
|
||||
rf_amp_ = settings.rx_amp;
|
||||
squelch_level_ = settings.squelch;
|
||||
radio::set_baseband_filter_bandwidth(baseband_bandwidth());
|
||||
}
|
||||
|
||||
void ReceiverModel::update_sampling_rate() {
|
||||
@ -290,8 +283,16 @@ void ReceiverModel::update_sampling_rate() {
|
||||
update_tuning_frequency();
|
||||
}
|
||||
|
||||
void ReceiverModel::update_headphone_volume() {
|
||||
audio::headphone::set_volume(headphone_volume());
|
||||
void ReceiverModel::update_lna() {
|
||||
radio::set_lna_gain(lna());
|
||||
}
|
||||
|
||||
void ReceiverModel::update_vga() {
|
||||
radio::set_vga_gain(vga());
|
||||
}
|
||||
|
||||
void ReceiverModel::update_rf_amp() {
|
||||
radio::set_rf_amp(rf_amp());
|
||||
}
|
||||
|
||||
void ReceiverModel::update_modulation() {
|
||||
@ -315,26 +316,23 @@ void ReceiverModel::update_modulation() {
|
||||
}
|
||||
}
|
||||
|
||||
size_t ReceiverModel::am_configuration() const {
|
||||
return am_config_index;
|
||||
}
|
||||
|
||||
void ReceiverModel::update_am_configuration() {
|
||||
am_configs[am_config_index].apply();
|
||||
}
|
||||
|
||||
size_t ReceiverModel::nbfm_configuration() const {
|
||||
return nbfm_config_index;
|
||||
am_configs[am_configuration()].apply();
|
||||
}
|
||||
|
||||
void ReceiverModel::update_nbfm_configuration() {
|
||||
nbfm_configs[nbfm_config_index].apply(squelch_level_);
|
||||
}
|
||||
|
||||
size_t ReceiverModel::wfm_configuration() const {
|
||||
return wfm_config_index;
|
||||
nbfm_configs[nbfm_configuration()].apply(squelch_level());
|
||||
}
|
||||
|
||||
void ReceiverModel::update_wfm_configuration() {
|
||||
wfm_configs[wfm_config_index].apply();
|
||||
wfm_configs[wfm_configuration()].apply();
|
||||
}
|
||||
|
||||
void ReceiverModel::update_antenna_bias() {
|
||||
if (enabled_)
|
||||
radio::set_antenna_bias(portapack::get_antenna_bias());
|
||||
}
|
||||
|
||||
void ReceiverModel::update_headphone_volume() {
|
||||
audio::headphone::set_volume(headphone_volume());
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
|
||||
* Copyright (C) 2023 Kyle Reed
|
||||
*
|
||||
* This file is part of PortaPack.
|
||||
*
|
||||
@ -26,16 +27,16 @@
|
||||
#include <cstddef>
|
||||
|
||||
#include "app_settings.hpp"
|
||||
#include "max283x.hpp"
|
||||
#include "message.hpp"
|
||||
#include "rf_path.hpp"
|
||||
#include "max283x.hpp"
|
||||
#include "volume.hpp"
|
||||
|
||||
// TODO: consider a base class for ReceiverModel & TransmitterModel.
|
||||
// There are multiple values that are actually shared by both.
|
||||
class ReceiverModel {
|
||||
public:
|
||||
enum class Mode {
|
||||
enum class Mode : uint8_t {
|
||||
AMAudio = 0,
|
||||
NarrowbandFMAudio = 1,
|
||||
WidebandFMAudio = 2,
|
||||
@ -43,33 +44,59 @@ class ReceiverModel {
|
||||
Capture = 4
|
||||
};
|
||||
|
||||
struct settings_t {
|
||||
uint32_t baseband_bandwidth = max283x::filter::bandwidth_minimum;
|
||||
uint32_t sampling_rate = 3'072'000;
|
||||
rf::Frequency frequency_step = 25'000;
|
||||
uint8_t lna_gain_db = 32;
|
||||
uint8_t vga_gain_db = 32;
|
||||
bool rf_amp = false;
|
||||
Mode mode = Mode::NarrowbandFMAudio;
|
||||
uint8_t am_config_index = 0;
|
||||
uint8_t nbfm_config_index = 0;
|
||||
uint8_t wfm_config_index = 0;
|
||||
uint8_t squelch_level = 80;
|
||||
};
|
||||
|
||||
/* The frequency to receive (no offset). */
|
||||
rf::Frequency target_frequency() const;
|
||||
void set_target_frequency(rf::Frequency f);
|
||||
|
||||
rf::Frequency frequency_step() const;
|
||||
void set_frequency_step(rf::Frequency f);
|
||||
|
||||
void set_antenna_bias();
|
||||
|
||||
bool rf_amp() const;
|
||||
void set_rf_amp(bool enabled);
|
||||
|
||||
int32_t lna() const;
|
||||
void set_lna(int32_t v_db);
|
||||
|
||||
uint32_t baseband_bandwidth() const;
|
||||
void set_baseband_bandwidth(uint32_t v);
|
||||
|
||||
int32_t vga() const;
|
||||
void set_vga(int32_t v_db);
|
||||
|
||||
uint32_t sampling_rate() const;
|
||||
void set_sampling_rate(uint32_t v);
|
||||
|
||||
rf::Frequency frequency_step() const;
|
||||
void set_frequency_step(rf::Frequency f);
|
||||
|
||||
uint8_t lna() const;
|
||||
void set_lna(uint8_t v_db);
|
||||
|
||||
uint8_t vga() const;
|
||||
void set_vga(uint8_t v_db);
|
||||
|
||||
bool rf_amp() const;
|
||||
void set_rf_amp(bool enabled);
|
||||
|
||||
Mode modulation() const;
|
||||
void set_modulation(Mode v);
|
||||
|
||||
uint8_t am_configuration() const;
|
||||
void set_am_configuration(uint8_t n);
|
||||
|
||||
uint8_t nbfm_configuration() const;
|
||||
void set_nbfm_configuration(uint8_t n);
|
||||
|
||||
uint8_t wfm_configuration() const;
|
||||
void set_wfm_configuration(uint8_t n);
|
||||
|
||||
uint8_t squelch_level() const;
|
||||
void set_squelch_level(uint8_t v);
|
||||
|
||||
void set_antenna_bias();
|
||||
|
||||
volume_t headphone_volume() const;
|
||||
void set_headphone_volume(volume_t v);
|
||||
|
||||
@ -77,25 +104,11 @@ class ReceiverModel {
|
||||
uint8_t normalized_headphone_volume() const;
|
||||
void set_normalized_headphone_volume(uint8_t v);
|
||||
|
||||
uint8_t squelch_level() const;
|
||||
void set_squelch_level(uint8_t v);
|
||||
|
||||
void enable();
|
||||
void disable();
|
||||
|
||||
size_t am_configuration() const;
|
||||
void set_am_configuration(const size_t n);
|
||||
|
||||
size_t nbfm_configuration() const;
|
||||
void set_nbfm_configuration(const size_t n);
|
||||
|
||||
size_t wfm_configuration() const;
|
||||
void set_wfm_configuration(const size_t n);
|
||||
|
||||
/* Sets the model values without updating the radio. */
|
||||
void set_configuration_without_update(
|
||||
uint32_t baseband_bandwidth,
|
||||
uint32_t sampling_rate);
|
||||
/* Resets some members back to default. */
|
||||
void initialize();
|
||||
|
||||
void set_configuration_without_update(
|
||||
Mode new_mode,
|
||||
@ -107,35 +120,30 @@ class ReceiverModel {
|
||||
|
||||
void configure_from_app_settings(const app_settings::AppSettings& settings);
|
||||
|
||||
/* Get access to the underlying settings to allow
|
||||
* values to be set directly without calling update. */
|
||||
settings_t& settings() { return settings_; }
|
||||
|
||||
private:
|
||||
rf::Frequency frequency_step_{25000};
|
||||
bool enabled_{false};
|
||||
bool rf_amp_{false};
|
||||
int32_t lna_gain_db_{32};
|
||||
uint32_t baseband_bandwidth_{max283x::filter::bandwidth_minimum};
|
||||
int32_t vga_gain_db_{32};
|
||||
Mode mode_{Mode::NarrowbandFMAudio};
|
||||
uint32_t sampling_rate_{3072000};
|
||||
size_t am_config_index = 0;
|
||||
size_t nbfm_config_index = 0;
|
||||
size_t wfm_config_index = 0;
|
||||
uint8_t squelch_level_{80};
|
||||
settings_t settings_{};
|
||||
bool enabled_ = false;
|
||||
|
||||
int32_t tuning_offset();
|
||||
|
||||
void update_tuning_frequency();
|
||||
void update_antenna_bias();
|
||||
void update_rf_amp();
|
||||
void update_lna();
|
||||
void update_baseband_bandwidth();
|
||||
void update_vga();
|
||||
void update_sampling_rate();
|
||||
void update_headphone_volume();
|
||||
void update_lna();
|
||||
void update_vga();
|
||||
void update_rf_amp();
|
||||
|
||||
void update_modulation();
|
||||
void update_am_configuration();
|
||||
void update_nbfm_configuration();
|
||||
void update_wfm_configuration();
|
||||
|
||||
void update_antenna_bias();
|
||||
void update_headphone_volume();
|
||||
};
|
||||
|
||||
#endif /*__RECEIVER_MODEL_H__*/
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
|
||||
* Copyright (C) 2016 Furrtek
|
||||
* Copyright (C) 2023 Kyle Reed
|
||||
*
|
||||
* This file is part of PortaPack.
|
||||
*
|
||||
@ -22,15 +23,13 @@
|
||||
|
||||
#include "transmitter_model.hpp"
|
||||
|
||||
#include "audio.hpp"
|
||||
#include "baseband_api.hpp"
|
||||
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
#include "event_m0.hpp"
|
||||
#include "hackrf_gpio.hpp"
|
||||
#include "portapack.hpp"
|
||||
#include "rtc_time.hpp"
|
||||
#include "event_m0.hpp"
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
#include "radio.hpp"
|
||||
#include "audio.hpp"
|
||||
|
||||
using namespace hackrf::one;
|
||||
using namespace portapack;
|
||||
@ -44,75 +43,52 @@ void TransmitterModel::set_target_frequency(rf::Frequency f) {
|
||||
update_tuning_frequency();
|
||||
}
|
||||
|
||||
void TransmitterModel::set_antenna_bias() {
|
||||
update_antenna_bias();
|
||||
}
|
||||
|
||||
bool TransmitterModel::rf_amp() const {
|
||||
return rf_amp_;
|
||||
}
|
||||
|
||||
void TransmitterModel::set_rf_amp(bool enabled) {
|
||||
rf_amp_ = enabled;
|
||||
update_rf_amp();
|
||||
}
|
||||
|
||||
int32_t TransmitterModel::lna() const {
|
||||
return lna_gain_db_;
|
||||
}
|
||||
|
||||
void TransmitterModel::set_lna(int32_t v_db) {
|
||||
lna_gain_db_ = v_db;
|
||||
update_lna();
|
||||
}
|
||||
|
||||
uint32_t TransmitterModel::baseband_bandwidth() const {
|
||||
return baseband_bandwidth_;
|
||||
return settings_.baseband_bandwidth;
|
||||
}
|
||||
|
||||
void TransmitterModel::set_baseband_bandwidth(uint32_t v) {
|
||||
baseband_bandwidth_ = v;
|
||||
settings_.baseband_bandwidth = v;
|
||||
update_baseband_bandwidth();
|
||||
}
|
||||
|
||||
int32_t TransmitterModel::vga() const {
|
||||
return vga_gain_db_;
|
||||
}
|
||||
|
||||
void TransmitterModel::set_vga(int32_t v_db) {
|
||||
vga_gain_db_ = v_db;
|
||||
update_vga();
|
||||
}
|
||||
|
||||
uint32_t TransmitterModel::channel_bandwidth() const {
|
||||
return channel_bandwidth_;
|
||||
}
|
||||
|
||||
void TransmitterModel::set_channel_bandwidth(uint32_t v) {
|
||||
channel_bandwidth_ = v;
|
||||
}
|
||||
|
||||
uint32_t TransmitterModel::sampling_rate() const {
|
||||
return sampling_rate_;
|
||||
return settings_.sampling_rate;
|
||||
}
|
||||
|
||||
void TransmitterModel::set_sampling_rate(uint32_t v) {
|
||||
sampling_rate_ = v;
|
||||
settings_.sampling_rate = v;
|
||||
update_sampling_rate();
|
||||
}
|
||||
|
||||
int32_t TransmitterModel::tx_gain() const {
|
||||
return tx_gain_db_;
|
||||
uint32_t TransmitterModel::channel_bandwidth() const {
|
||||
return settings_.channel_bandwidth;
|
||||
}
|
||||
|
||||
void TransmitterModel::set_tx_gain(int32_t v_db) {
|
||||
tx_gain_db_ = v_db;
|
||||
void TransmitterModel::set_channel_bandwidth(uint32_t v) {
|
||||
settings_.channel_bandwidth = v;
|
||||
}
|
||||
|
||||
uint8_t TransmitterModel::tx_gain() const {
|
||||
return settings_.tx_gain_db;
|
||||
}
|
||||
|
||||
void TransmitterModel::set_tx_gain(uint8_t v_db) {
|
||||
settings_.tx_gain_db = v_db;
|
||||
update_tx_gain();
|
||||
}
|
||||
|
||||
void TransmitterModel::on_tick_second() {
|
||||
if (portapack::persistent_memory::stealth_mode())
|
||||
led_tx.toggle();
|
||||
bool TransmitterModel::rf_amp() const {
|
||||
return settings_.rf_amp;
|
||||
}
|
||||
|
||||
void TransmitterModel::set_rf_amp(bool enabled) {
|
||||
settings_.rf_amp = enabled;
|
||||
update_rf_amp();
|
||||
}
|
||||
|
||||
void TransmitterModel::set_antenna_bias() {
|
||||
update_antenna_bias();
|
||||
}
|
||||
|
||||
void TransmitterModel::enable() {
|
||||
@ -121,8 +97,6 @@ void TransmitterModel::enable() {
|
||||
update_tuning_frequency();
|
||||
update_antenna_bias();
|
||||
update_rf_amp();
|
||||
update_lna();
|
||||
update_vga();
|
||||
update_baseband_bandwidth();
|
||||
update_sampling_rate();
|
||||
update_tx_gain();
|
||||
@ -147,53 +121,25 @@ void TransmitterModel::disable() {
|
||||
led_tx.off();
|
||||
}
|
||||
|
||||
void TransmitterModel::set_configuration_without_update(
|
||||
uint32_t baseband_bandwidth,
|
||||
uint32_t sampling_rate) {
|
||||
baseband_bandwidth_ = baseband_bandwidth;
|
||||
sampling_rate_ = sampling_rate;
|
||||
void TransmitterModel::initialize() {
|
||||
settings_ = settings_t{};
|
||||
}
|
||||
|
||||
void TransmitterModel::configure_from_app_settings(
|
||||
const app_settings::AppSettings& settings) {
|
||||
baseband_bandwidth_ = settings.baseband_bandwidth;
|
||||
channel_bandwidth_ = settings.channel_bandwidth;
|
||||
tx_gain_db_ = settings.tx_gain;
|
||||
rf_amp_ = settings.tx_amp;
|
||||
|
||||
// TODO: Do these make sense for TX?
|
||||
lna_gain_db_ = settings.lna;
|
||||
vga_gain_db_ = settings.vga;
|
||||
sampling_rate_ = settings.sampling_rate;
|
||||
settings_.baseband_bandwidth = settings.baseband_bandwidth;
|
||||
settings_.sampling_rate = settings.sampling_rate;
|
||||
settings_.channel_bandwidth = settings.channel_bandwidth;
|
||||
settings_.tx_gain_db = settings.tx_gain;
|
||||
settings_.rf_amp = settings.tx_amp;
|
||||
}
|
||||
|
||||
void TransmitterModel::update_tuning_frequency() {
|
||||
radio::set_tuning_frequency(target_frequency());
|
||||
}
|
||||
|
||||
void TransmitterModel::update_antenna_bias() {
|
||||
if (enabled_)
|
||||
radio::set_antenna_bias(portapack::get_antenna_bias());
|
||||
}
|
||||
|
||||
void TransmitterModel::update_rf_amp() {
|
||||
radio::set_rf_amp(rf_amp_);
|
||||
}
|
||||
|
||||
void TransmitterModel::update_lna() {
|
||||
radio::set_lna_gain(lna_gain_db_);
|
||||
}
|
||||
|
||||
void TransmitterModel::update_baseband_bandwidth() {
|
||||
radio::set_baseband_filter_bandwidth(baseband_bandwidth_);
|
||||
}
|
||||
|
||||
void TransmitterModel::update_vga() {
|
||||
radio::set_vga_gain(vga_gain_db_);
|
||||
}
|
||||
|
||||
void TransmitterModel::update_tx_gain() {
|
||||
radio::set_tx_gain(tx_gain_db_);
|
||||
radio::set_baseband_filter_bandwidth(baseband_bandwidth());
|
||||
}
|
||||
|
||||
void TransmitterModel::update_sampling_rate() {
|
||||
@ -206,3 +152,21 @@ void TransmitterModel::update_sampling_rate() {
|
||||
radio::set_baseband_rate(sampling_rate());
|
||||
update_tuning_frequency();
|
||||
}
|
||||
|
||||
void TransmitterModel::update_tx_gain() {
|
||||
radio::set_tx_gain(tx_gain());
|
||||
}
|
||||
|
||||
void TransmitterModel::update_rf_amp() {
|
||||
radio::set_rf_amp(rf_amp());
|
||||
}
|
||||
|
||||
void TransmitterModel::update_antenna_bias() {
|
||||
if (enabled_)
|
||||
radio::set_antenna_bias(portapack::get_antenna_bias());
|
||||
}
|
||||
|
||||
void TransmitterModel::on_tick_second() {
|
||||
if (portapack::persistent_memory::stealth_mode())
|
||||
led_tx.toggle();
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
|
||||
* Copyright (C) 2016 Furrtek
|
||||
* Copyright (C) 2023 Kyle Reed
|
||||
*
|
||||
* This file is part of PortaPack.
|
||||
*
|
||||
@ -26,77 +27,68 @@
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
#include "receiver_model.hpp"
|
||||
#include "app_settings.hpp"
|
||||
#include "message.hpp"
|
||||
#include "rf_path.hpp"
|
||||
#include "max2837.hpp"
|
||||
#include "volume.hpp"
|
||||
#include "message.hpp"
|
||||
#include "receiver_model.hpp"
|
||||
#include "rf_path.hpp"
|
||||
#include "signal.hpp"
|
||||
|
||||
class TransmitterModel {
|
||||
public:
|
||||
struct settings_t {
|
||||
uint32_t baseband_bandwidth = max283x::filter::bandwidth_minimum;
|
||||
uint32_t sampling_rate = 3'072'000;
|
||||
uint32_t channel_bandwidth = 1;
|
||||
/* 35 should give approx 1m transmission range. */
|
||||
uint8_t tx_gain_db = 35;
|
||||
bool rf_amp = false;
|
||||
};
|
||||
|
||||
/* The frequency to transmit on. */
|
||||
rf::Frequency target_frequency() const;
|
||||
void set_target_frequency(rf::Frequency f);
|
||||
|
||||
void set_antenna_bias();
|
||||
|
||||
bool rf_amp() const;
|
||||
void set_rf_amp(bool enabled);
|
||||
|
||||
// TODO: does this make sense on TX?
|
||||
int32_t lna() const;
|
||||
void set_lna(int32_t v_db);
|
||||
|
||||
uint32_t baseband_bandwidth() const;
|
||||
void set_baseband_bandwidth(uint32_t v);
|
||||
|
||||
// TODO: does this make sense on TX?
|
||||
int32_t vga() const;
|
||||
void set_vga(int32_t v_db);
|
||||
|
||||
int32_t tx_gain() const;
|
||||
void set_tx_gain(int32_t v_db);
|
||||
|
||||
// TODO: Doesn't actually affect radio.
|
||||
uint32_t channel_bandwidth() const;
|
||||
void set_channel_bandwidth(uint32_t v);
|
||||
|
||||
// TODO: does this make sense on TX?
|
||||
uint32_t sampling_rate() const;
|
||||
void set_sampling_rate(uint32_t v);
|
||||
|
||||
uint8_t tx_gain() const;
|
||||
void set_tx_gain(uint8_t v_db);
|
||||
|
||||
bool rf_amp() const;
|
||||
void set_rf_amp(bool enabled);
|
||||
|
||||
void set_antenna_bias();
|
||||
|
||||
void enable();
|
||||
void disable();
|
||||
|
||||
/* Sets the model values without updating the radio. */
|
||||
void set_configuration_without_update(
|
||||
uint32_t baseband_bandwidth,
|
||||
uint32_t sampling_rate);
|
||||
void initialize();
|
||||
|
||||
void configure_from_app_settings(const app_settings::AppSettings& settings);
|
||||
|
||||
/* Get access to the underlying settings to allow
|
||||
* values to be set directly without calling update. */
|
||||
settings_t& settings() { return settings_; }
|
||||
|
||||
private:
|
||||
bool enabled_{false};
|
||||
bool rf_amp_{false};
|
||||
int32_t lna_gain_db_{0};
|
||||
uint32_t channel_bandwidth_{1};
|
||||
uint32_t baseband_bandwidth_{max2837::filter::bandwidth_minimum};
|
||||
int32_t vga_gain_db_{8};
|
||||
/* 35 should give approx 1m transmission range. */
|
||||
int32_t tx_gain_db_{35};
|
||||
uint32_t sampling_rate_{3072000};
|
||||
settings_t settings_{};
|
||||
bool enabled_ = false;
|
||||
SignalToken signal_token_tick_second{};
|
||||
|
||||
void update_tuning_frequency();
|
||||
void update_antenna_bias();
|
||||
void update_rf_amp();
|
||||
void update_lna();
|
||||
void update_baseband_bandwidth();
|
||||
void update_vga();
|
||||
void update_tx_gain();
|
||||
void update_sampling_rate();
|
||||
void update_tx_gain();
|
||||
void update_rf_amp();
|
||||
void update_antenna_bias();
|
||||
void on_tick_second();
|
||||
};
|
||||
|
||||
|
@ -280,7 +280,7 @@ FrequencyOptionsView::FrequencyOptionsView(
|
||||
}
|
||||
|
||||
void FrequencyOptionsView::set_step(rf::Frequency f) {
|
||||
field_step.set_by_value(f);
|
||||
field_step.set_by_nearest_value(f);
|
||||
}
|
||||
|
||||
void FrequencyOptionsView::set_reference_ppm_correction(int32_t v) {
|
||||
|
@ -1001,8 +1001,6 @@ bool debug_dump() {
|
||||
// transmitter_model
|
||||
pmem_dump_file.write_line("\n[Transmitter Model]");
|
||||
pmem_dump_file.write_line("target_frequency: " + to_string_dec_uint(transmitter_model.target_frequency()));
|
||||
pmem_dump_file.write_line("lna: " + to_string_dec_int(transmitter_model.lna()));
|
||||
pmem_dump_file.write_line("vga: " + to_string_dec_int(transmitter_model.vga()));
|
||||
pmem_dump_file.write_line("rf_amp: " + to_string_dec_int(transmitter_model.rf_amp()));
|
||||
pmem_dump_file.write_line("baseband_bandwidth: " + to_string_dec_uint(transmitter_model.baseband_bandwidth()));
|
||||
pmem_dump_file.write_line("sampling_rate: " + to_string_dec_uint(transmitter_model.sampling_rate()));
|
||||
|
@ -1524,6 +1524,24 @@ void OptionsField::set_by_value(value_t v) {
|
||||
set_selected_index(0);
|
||||
}
|
||||
|
||||
void OptionsField::set_by_nearest_value(value_t v) {
|
||||
size_t new_index = 0;
|
||||
size_t curr_index = 0;
|
||||
int32_t min_diff = INT32_MAX;
|
||||
|
||||
for (const auto& option : options) {
|
||||
auto diff = abs(v - option.second);
|
||||
if (diff < min_diff) {
|
||||
min_diff = diff;
|
||||
new_index = curr_index;
|
||||
}
|
||||
|
||||
curr_index++;
|
||||
}
|
||||
|
||||
set_selected_index(new_index);
|
||||
}
|
||||
|
||||
void OptionsField::set_options(options_t new_options) {
|
||||
options = new_options;
|
||||
|
||||
|
@ -624,6 +624,7 @@ class OptionsField : public Widget {
|
||||
void set_selected_index(const size_t new_index, bool trigger_change = true);
|
||||
|
||||
void set_by_value(value_t v);
|
||||
void set_by_nearest_value(value_t v);
|
||||
|
||||
void paint(Painter& painter) override;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user