Recon record (#1182)

* added auto record checbox and functions (audio and raw)
* Changed baseband compile option from -O3 to -O2. Trying lower gave unexpeted and crashing results.
* added 650k SPEC bw
* fix hang if wait is -100
* fixing no SPEC support in scanner
This commit is contained in:
gullradriel 2023-06-25 08:16:49 +02:00 committed by GitHub
parent e08273b8b8
commit 5cd9c377d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 231 additions and 53 deletions

View File

@ -30,13 +30,25 @@ using portapack::memory::map::backup_ram;
namespace ui {
static RecordView* record_view = NULL;
void ReconView::set_loop_config(bool v) {
continuous = v;
button_loop_config.set_style(v ? &Styles::green : &Styles::white);
persistent_memory::set_recon_continuous(continuous);
}
void ReconView::recon_stop_recording() {
if (is_recording) {
button_audio_app.set_style(&Styles::white);
record_view->stop();
is_recording = false;
}
}
void ReconView::clear_freqlist_for_ui_action() {
recon_stop_recording();
if (field_mode.selected_index_value() != SPEC_MODULATION)
audio::output::stop();
// flag to detect and reload frequency_list
if (!manual_mode) {
@ -232,8 +244,8 @@ bool ReconView::recon_save_config_to_sd() {
make_new_directory(u"SETTINGS");
auto result = settings_file.create(RECON_CFG_FILE);
if (result.is_valid())
auto error = settings_file.create(RECON_CFG_FILE);
if (error)
return false;
settings_file.write_line(input_file);
settings_file.write_line(output_file);
@ -246,6 +258,7 @@ bool ReconView::recon_save_config_to_sd() {
}
void ReconView::audio_output_start() {
if (field_mode.selected_index_value() != SPEC_MODULATION)
audio::output::start();
receiver_model.set_headphone_volume(receiver_model.headphone_volume()); // WM8731 hack.
}
@ -279,10 +292,6 @@ void ReconView::recon_redraw() {
} else if (freq_lock >= recon_lock_nb_match) {
big_display.set_style(&Styles::green);
button_pause.set_text("<UNLOCK>");
// FREQ IS STRONG: GREEN and recon will pause when on_statistics_update()
if ((!scanner_mode) && autosave && frequency_list.size() > 0) {
recon_save_freq(freq_file_path, current_index, false);
}
}
}
if (last_db != db || last_list_size != frequency_list.size()) {
@ -354,16 +363,20 @@ void ReconView::focus() {
}
ReconView::~ReconView() {
// Save recon config.
recon_stop_recording();
delete record_view;
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();
}
ReconView::ReconView(NavigationView& nav)
: nav_{nav} {
chrono_start = chTimeNow();
record_view = new RecordView({0, 0, 30 * 8, 1 * 16}, u"AUTO_AUDIO_", u"AUDIO", RecordView::FileType::WAV, 4096, 4);
add_children({&labels,
&field_lna,
&field_vga,
@ -399,7 +412,14 @@ ReconView::ReconView(NavigationView& nav)
&button_dir,
&button_restart,
&button_mic_app,
&button_remove});
&button_remove,
record_view});
record_view->hidden(true);
record_view->set_filename_date_frequency(true);
record_view->on_error = [&nav](std::string message) {
nav.display_modal("Error", message);
};
def_step = 0;
// HELPER: Pre-setting a manual range, based on stored frequency
@ -424,6 +444,7 @@ ReconView::ReconView(NavigationView& nav)
load_ranges = persistent_memory::recon_load_ranges();
load_hamradios = persistent_memory::recon_load_hamradios();
update_ranges = persistent_memory::recon_update_ranges_when_recon();
auto_record_locked = persistent_memory::recon_auto_record_locked();
button_manual_start.on_select = [this, &nav](ButtonWithEncoder& button) {
clear_freqlist_for_ui_action();
@ -680,6 +701,7 @@ ReconView::ReconView(NavigationView& nav)
} else if (frequency_range.min > frequency_range.max) {
nav_.display_modal("Error", "END freq\nis lower than START");
} else {
if (field_mode.selected_index_value() != SPEC_MODULATION)
audio::output::stop();
// clear and shrink_to_fit are not enough to really start with a new, clean, empty vector
// swap is the only way to achieve a perfect memory liberation
@ -760,6 +782,9 @@ ReconView::ReconView(NavigationView& nav)
button_scanner_mode.set_style(&Styles::blue);
button_scanner_mode.set_text("RECON");
}
if (frequency_list.size() > FREQMAN_MAX_PER_FILE) {
file_name.set_style(&Styles::yellow);
}
};
button_add.on_select = [this](ButtonWithEncoder&) { // frequency_list[current_index]
@ -796,7 +821,8 @@ ReconView::ReconView(NavigationView& nav)
button_config.on_select = [this, &nav](Button&) {
clear_freqlist_for_ui_action();
freq_lock = 0;
timer = 0;
auto open_view = nav.push<ReconSetupView>(input_file, output_file);
open_view->on_changed = [this](std::vector<std::string> result) {
input_file = result[0];
@ -811,6 +837,7 @@ ReconView::ReconView(NavigationView& nav)
load_ranges = persistent_memory::recon_load_ranges();
load_hamradios = persistent_memory::recon_load_hamradios();
update_ranges = persistent_memory::recon_update_ranges_when_recon();
auto_record_locked = persistent_memory::recon_auto_record_locked();
frequency_file_load(false);
freqlist_cleared_for_ui_action = false;
@ -830,6 +857,9 @@ ReconView::ReconView(NavigationView& nav)
field_wait.on_change = [this](int32_t v) {
wait = v;
// replacing -100 by 200 else it's freezing the device
if (wait == -100)
wait = -200;
colorize_waits();
};
@ -888,6 +918,7 @@ ReconView::ReconView(NavigationView& nav)
void ReconView::frequency_file_load(bool stop_all_before) {
(void)(stop_all_before);
if (field_mode.selected_index_value() != SPEC_MODULATION)
audio::output::stop();
def_step = step_mode.selected_index(); // use def_step from manual selector
@ -896,29 +927,27 @@ void ReconView::frequency_file_load(bool stop_all_before) {
file_input = output_file;
file_name.set_style(&Styles::red);
button_scanner_mode.set_style(&Styles::red);
desc_cycle.set_style(&Styles::red);
button_scanner_mode.set_text("SCANNER");
} else {
file_name.set_style(&Styles::blue);
button_scanner_mode.set_style(&Styles::blue);
desc_cycle.set_style(&Styles::blue);
button_scanner_mode.set_text("RECON");
}
desc_cycle.set_style(&Styles::white);
if (!load_freqman_file(file_input, frequency_list, load_freqs, load_ranges, load_hamradios)) {
file_name.set_style(&Styles::red);
desc_cycle.set_style(&Styles::red);
desc_cycle.set(" NO " + file_input + ".TXT FILE ...");
file_name.set("=> NO DATA");
} else {
file_name.set(file_input + "=>" + output_file);
if (frequency_list.size() == 0) {
file_name.set_style(&Styles::red);
desc_cycle.set_style(&Styles::red);
desc_cycle.set("/0 no entries in list");
file_name.set("BadOrEmpty " + file_input);
} else {
if (frequency_list.size() > FREQMAN_MAX_PER_FILE) {
file_name.set_style(&Styles::yellow);
desc_cycle.set_style(&Styles::yellow);
}
}
}
@ -992,6 +1021,14 @@ void ReconView::frequency_file_load(bool stop_all_before) {
}
void ReconView::on_statistics_update(const ChannelStatistics& statistics) {
systime_t time_interval = 100;
if (field_mode.selected_index_value() == SPEC_MODULATION) {
chrono_end = chTimeNow();
time_interval = chrono_end - chrono_start;
chrono_start = chrono_end;
}
// hack to reload the list if it was cleared by going into CONFIG
if (freqlist_cleared_for_ui_action) {
if (!manual_mode) {
@ -1018,6 +1055,8 @@ void ReconView::on_statistics_update(const ChannelStatistics& statistics) {
if (status != 1) {
status = 1;
if (wait != 0) {
recon_stop_recording();
if (field_mode.selected_index_value() != SPEC_MODULATION)
audio::output::stop();
}
}
@ -1040,8 +1079,23 @@ void ReconView::on_statistics_update(const ChannelStatistics& statistics) {
if (status != 2) {
continuous_lock = false;
status = 2;
// FREQ IS STRONG: GREEN and recon will pause when on_statistics_update()
if ((!scanner_mode) && autosave && frequency_list.size() > 0) {
recon_save_freq(freq_file_path, current_index, false);
}
if (wait != 0) {
if (field_mode.selected_index_value() != SPEC_MODULATION)
audio_output_start();
// contents of a possible recon_start_recording(), but not yet since it's only called once
if (auto_record_locked && !is_recording) {
button_audio_app.set_style(&Styles::red);
record_view->start();
is_recording = true;
}
// FREQ IS STRONG: GREEN and recon will pause when on_statistics_update()
if ((!scanner_mode) && autosave && frequency_list.size() > 0) {
recon_save_freq(freq_file_path, current_index, false);
}
}
if (wait >= 0) {
timer = wait;
@ -1060,8 +1114,9 @@ void ReconView::on_statistics_update(const ChannelStatistics& statistics) {
text_timer.set("TIMER: " + to_string_dec_int(timer));
}
if (timer) {
if (!continuous_lock || recon_match_mode == RECON_MATCH_SPARSE)
timer -= STATS_UPDATE_INTERVAL;
if (!continuous_lock || recon_match_mode == RECON_MATCH_SPARSE) {
timer -= time_interval;
}
if (timer < 0) {
timer = 0;
}
@ -1072,7 +1127,6 @@ void ReconView::on_statistics_update(const ChannelStatistics& statistics) {
if (frequency_list.size() > 0) {
has_looped = false;
entry_has_changed = false;
if (recon || stepper != 0 || index_stepper != 0) {
if (index_stepper == 0) {
/* we are doing a range */
@ -1172,7 +1226,8 @@ void ReconView::on_statistics_update(const ChannelStatistics& statistics) {
entry_has_changed = true;
if (!recon) // for some motive, audio output gets stopped.
// for some motive, audio output gets stopped.
if (!recon && field_mode.selected_index_value() != SPEC_MODULATION)
audio_output_start();
}
// reload entry if changed
@ -1224,6 +1279,7 @@ void ReconView::recon_pause() {
continuous_lock = false;
recon = false;
if (field_mode.selected_index_value() != SPEC_MODULATION)
audio_output_start();
big_display.set_style(&Styles::white);
@ -1236,6 +1292,7 @@ void ReconView::recon_resume() {
continuous_lock = false;
recon = true;
if (field_mode.selected_index_value() != SPEC_MODULATION)
audio::output::stop();
big_display.set_style(&Styles::white);
@ -1277,10 +1334,29 @@ void ReconView::on_stepper_delta(int32_t v) {
size_t ReconView::change_mode(freqman_index_t new_mod) {
field_mode.on_change = [this](size_t, OptionsField::value_t) {};
field_bw.on_change = [this](size_t, OptionsField::value_t) {};
recon_stop_recording();
if (new_mod != SPEC_MODULATION) {
remove_children({record_view});
delete record_view;
record_view = new RecordView({0, 0, 30 * 8, 1 * 16}, u"AUTO_AUDIO_", u"AUDIO", RecordView::FileType::WAV, 4096, 4);
record_view->set_filename_date_frequency(true);
add_children({record_view});
}
if (new_mod == SPEC_MODULATION) {
audio::output::stop();
remove_children({record_view});
delete record_view;
record_view = new RecordView({0, 0, 30 * 8, 1 * 16}, u"AUTO_RAW_", u"CAPTURES", RecordView::FileType::RawS16, 16384, 3);
record_view->set_filename_date_frequency(true);
add_children({record_view});
}
record_view->hidden(true);
record_view->on_error = [this](std::string message) {
nav_.display_modal("Error", message);
};
receiver_model.disable();
baseband::shutdown();
size_t recording_sampling_rate = 0;
switch (new_mod) {
case AM_MODULATION:
freqman_set_bandwidth_option(new_mod, field_bw);
@ -1291,6 +1367,7 @@ size_t ReconView::change_mode(freqman_index_t new_mod) {
receiver_model.set_am_configuration(field_bw.selected_index_value());
field_bw.on_change = [this](size_t, OptionsField::value_t n) { receiver_model.set_am_configuration(n); };
text_ctcss.set(" ");
recording_sampling_rate = 12000;
break;
case NFM_MODULATION:
freqman_set_bandwidth_option(new_mod, field_bw);
@ -1300,6 +1377,7 @@ size_t ReconView::change_mode(freqman_index_t new_mod) {
receiver_model.set_modulation(ReceiverModel::Mode::NarrowbandFMAudio);
receiver_model.set_nbfm_configuration(field_bw.selected_index_value());
field_bw.on_change = [this](size_t, OptionsField::value_t n) { receiver_model.set_nbfm_configuration(n); };
recording_sampling_rate = 24000;
break;
case WFM_MODULATION:
freqman_set_bandwidth_option(new_mod, field_bw);
@ -1310,10 +1388,55 @@ size_t ReconView::change_mode(freqman_index_t new_mod) {
receiver_model.set_wfm_configuration(field_bw.selected_index_value());
field_bw.on_change = [this](size_t, OptionsField::value_t n) { receiver_model.set_wfm_configuration(n); };
text_ctcss.set(" ");
recording_sampling_rate = 48000;
break;
case SPEC_MODULATION:
freqman_set_bandwidth_option(new_mod, field_bw);
// bw 200k (0) default
baseband::run_image(portapack::spi_flash::image_tag_capture);
receiver_model.set_modulation(ReceiverModel::Mode::Capture);
field_bw.set_by_value(0);
field_bw.on_change = [this](size_t, OptionsField::value_t sampling_rate) {
uint32_t anti_alias_baseband_bandwidth_filter = 2500000;
switch (sampling_rate) { // we use the var fs (sampling_rate) , to set up BPF aprox < fs_max/2 by Nyquist theorem.
case 0 ... 2000000: // BW Captured range (0 <= 250kHz max ) fs = 8 x 250 kHz
anti_alias_baseband_bandwidth_filter = 1750000; // Minimum BPF MAX2837 for all those lower BW options.
break;
case 4000000 ... 6000000: // BW capture range (500k ... 750kHz max ) fs_max = 8 x 750kHz = 6Mhz
// BW 500k ... 750kHz , ex. 500kHz (fs = 8*BW = 4Mhz) , BW 600kHz (fs = 4,8Mhz) , BW 750 kHz (fs = 6Mhz)
anti_alias_baseband_bandwidth_filter = 2500000; // in some IC MAX2837 appear 2250000 , but both works similar.
break;
case 8800000: // BW capture 1,1Mhz fs = 8 x 1,1Mhz = 8,8Mhz . (1Mhz showed slightly higher noise background).
anti_alias_baseband_bandwidth_filter = 3500000;
break;
case 14000000: // BW capture 1,75Mhz , fs = 8 x 1,75Mhz = 14Mhz
// good BPF, good matching, but LCD making flicker , refresh rate should be < 20 Hz , but reasonable picture
anti_alias_baseband_bandwidth_filter = 5000000;
break;
case 16000000: // BW capture 2Mhz , fs = 8 x 2Mhz = 16Mhz
// good BPF, good matching, but LCD making flicker , refresh rate should be < 20 Hz , but reasonable picture
anti_alias_baseband_bandwidth_filter = 6000000;
break;
case 20000000: // BW capture 2,5Mhz , fs= 8 x 2,5 Mhz = 20Mhz
// good BPF, good matching, but LCD making flicker , refresh rate should be < 20 Hz , but reasonable picture
anti_alias_baseband_bandwidth_filter = 7000000;
break;
default: // BW capture 2,75Mhz, fs = 8 x 2,75Mhz= 22Mhz max ADC sampling) and others.
// We tested also 9Mhz FPB stightly too much noise floor, better 8Mhz
anti_alias_baseband_bandwidth_filter = 8000000;
}
record_view->set_sampling_rate(sampling_rate);
receiver_model.set_sampling_rate(sampling_rate);
receiver_model.set_baseband_bandwidth(anti_alias_baseband_bandwidth_filter);
};
text_ctcss.set(" ");
break;
default:
break;
}
if (new_mod != SPEC_MODULATION)
record_view->set_sampling_rate(recording_sampling_rate);
field_mode.set_selected_index(new_mod);
field_mode.on_change = [this](size_t, OptionsField::value_t v) {
if (v != -1) {
@ -1321,7 +1444,8 @@ size_t ReconView::change_mode(freqman_index_t new_mod) {
}
};
if (!recon) // for some motive, audio output gets stopped.
// for some motive, audio output gets stopped.
if (!recon && field_mode.selected_index_value() != SPEC_MODULATION)
audio::output::start(); // so if recon was stopped we resume audio
receiver_model.enable();

View File

@ -84,6 +84,8 @@ class ReconView : public View {
bool recon_load_config_from_sd();
bool recon_save_config_to_sd();
bool recon_save_freq(const std::string& freq_file_path, size_t index, bool warn_if_exists);
// placeholder for possible void recon_start_recording();
void recon_stop_recording();
jammer::jammer_range_t frequency_range{false, 0, MAX_UFREQ}; // perfect for manual recon task too...
int32_t squelch{0};
@ -108,6 +110,8 @@ class ReconView : public View {
bool fwd{true};
bool recon{true};
bool user_pause{false};
bool auto_record_locked{false};
bool is_recording{false};
uint32_t recon_lock_nb_match{3};
uint32_t recon_lock_duration{RECON_MIN_LOCK_DURATION};
uint32_t recon_match_mode{RECON_MATCH_CONTINUOUS};
@ -118,10 +122,7 @@ class ReconView : public View {
int32_t index_stepper{0};
int64_t freq{0};
uint32_t step{0};
freqman_index_t def_modulation{0};
freqman_index_t def_bandwidth{0};
freqman_index_t def_step{0};
tone_index tone{0};
freqman_entry last_entry{};
bool entry_has_changed{false};
uint32_t freq_lock{0};
@ -141,6 +142,8 @@ class ReconView : public View {
int32_t last_squelch_index{-1};
int64_t last_freq{0};
std::string freq_file_path{};
systime_t chrono_start{};
systime_t chrono_end{};
Labels labels{
{{0 * 8, 0 * 16}, "LNA: VGA: AMP: VOL: ", Color::light_grey()},
@ -272,11 +275,11 @@ class ReconView : public View {
OptionsField field_mode{
{6 * 8, (26 * 8) + 4},
3,
4,
{}};
OptionsField field_bw{
{10 * 8, (26 * 8) + 4},
{11 * 8, (26 * 8) + 4},
6,
{}};

View File

@ -103,6 +103,7 @@ void ReconSetupViewMore::save() {
persistent_memory::set_recon_load_ranges(checkbox_load_ranges.value());
persistent_memory::set_recon_load_hamradios(checkbox_load_hamradios.value());
persistent_memory::set_recon_update_ranges_when_recon(checkbox_update_ranges_when_recon.value());
persistent_memory::set_recon_auto_record_locked(checkbox_auto_record_locked.value());
};
void ReconSetupViewMain::focus() {
@ -117,12 +118,14 @@ ReconSetupViewMore::ReconSetupViewMore(NavigationView& nav, Rect parent_rect)
add_children({&checkbox_load_freqs,
&checkbox_load_ranges,
&checkbox_load_hamradios,
&checkbox_update_ranges_when_recon});
&checkbox_update_ranges_when_recon,
&checkbox_auto_record_locked});
checkbox_load_freqs.set_value(persistent_memory::recon_load_freqs());
checkbox_load_ranges.set_value(persistent_memory::recon_load_ranges());
checkbox_load_hamradios.set_value(persistent_memory::recon_load_hamradios());
checkbox_update_ranges_when_recon.set_value(persistent_memory::recon_update_ranges_when_recon());
checkbox_auto_record_locked.set_value(persistent_memory::recon_auto_record_locked());
};
void ReconSetupViewMore::focus() {

View File

@ -132,6 +132,10 @@ class ReconSetupViewMore : public View {
{1 * 8, 102},
3,
"auto update m-ranges"};
Checkbox checkbox_auto_record_locked{
{1 * 8, 132},
3,
"auto record locked periods"};
};
class ReconSetupView : public View {

View File

@ -447,6 +447,16 @@ ScannerView::ScannerView(
// Mode field was changed (AM/NFM/WFM)
field_mode.on_change = [this](size_t, OptionsField::value_t v) {
static freqman_index_t last_mode = AM_MODULATION;
// unsupported SPEC mode fix
if (v == SPEC_MODULATION) {
if (last_mode == AM_MODULATION)
v = WFM_MODULATION;
else
v = AM_MODULATION;
field_mode.set_selected_index(v);
}
last_mode = v;
receiver_model.disable();
baseband::shutdown();
change_mode((freqman_index_t)v);

View File

@ -30,7 +30,8 @@ using options_t = std::vector<option_t>;
options_t freqman_entry_modulations = {
{"AM", 0},
{"NFM", 1},
{"WFM", 2}};
{"WFM", 2},
{"SPEC", 3}};
options_t freqman_entry_bandwidths[4] = {
{// AM
@ -48,6 +49,25 @@ options_t freqman_entry_bandwidths[4] = {
{"40k", 2},
{"180k", 1},
{"200k", 0},
},
{
// SPEC
{"8k5", 8500},
{"11k", 11000},
{"16k", 16000},
{"25k", 25000},
{"50k", 50000},
{"100k", 100000},
{"250k", 250000},
{"500k", 500000}, /* Previous Limit bandwith Option with perfect micro SD write .C16 format operaton.*/
{"600k", 600000}, /* That extended option is still possible to record with FW version Mayhem v1.41 (< 2,5MB/sec) */
{"650k", 650000},
{"750k", 750000}, /* From this BW onwards, the LCD is ok, but the recorded file is decimated, (not real file size) */
{"1100k", 1100000},
{"1750k", 1750000},
{"2000k", 2000000},
{"2500k", 2500000},
{"2750k", 2750000}, // That is our max Capture option, to keep using later / 8 decimation (22Mhz sampling ADC)
}};
options_t freqman_entry_steps = {

View File

@ -59,10 +59,11 @@ enum freqman_entry_type : int8_t {
NOTYPE // undetected
};
enum freqman_entry_modulation : int8_t {
enum freqman_entry_modulation : uint8_t {
AM_MODULATION = 0,
NFM_MODULATION,
WFM_MODULATION,
SPEC_MODULATION,
};
// Entry step placed for AlainD freqman version (or any other enhanced version)

View File

@ -32,7 +32,7 @@ include(CheckCXXCompilerFlag)
project(baseband_shared)
# Compiler options here.
set(USE_OPT "-O3 -g -falign-functions=16 -fno-math-errno --specs=nano.specs")
set(USE_OPT "-O2 -g -falign-functions=16 -fno-math-errno --specs=nano.specs")
# C specific options here (added to USE_OPT).
set(USE_COPT "-std=gnu99")

View File

@ -822,6 +822,9 @@ bool recon_load_hamradios() {
bool recon_match_mode() {
return (data->recon_config & 0x00800000UL) ? true : false;
}
bool recon_auto_record_locked() {
return (data->recon_config & 0x00400000UL) ? true : false;
}
void set_recon_autosave_freqs(const bool v) {
data->recon_config = (data->recon_config & ~0x80000000UL) | (v << 31);
@ -850,6 +853,9 @@ void set_recon_load_hamradios(const bool v) {
void set_recon_match_mode(const bool v) {
data->recon_config = (data->recon_config & ~0x00800000UL) | (v << 23);
}
void set_recon_auto_record_locked(const bool v) {
data->recon_config = (data->recon_config & ~0x00400000UL) | (v << 22);
}
/* UI Config 2 */
bool ui_hide_speaker() {
@ -925,25 +931,26 @@ void set_config_converter_freq(int64_t v) {
data->converter_frequency_offset = v;
}
// frequency correction settings
// 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;
}
uint32_t config_freq_tx_correction() {
return data->frequency_tx_correction;
}
uint32_t config_freq_rx_correction() {
return data->frequency_rx_correction;
}
void set_freq_tx_correction_updown(bool v) {
data->updown_frequency_tx_correction = v;
}
void set_freq_rx_correction_updown(bool v) {
data->updown_frequency_rx_correction = v;
}
void set_config_freq_tx_correction(uint32_t v) {
data->frequency_tx_correction = v;
}
@ -951,7 +958,8 @@ void set_config_freq_rx_correction(uint32_t v) {
data->frequency_rx_correction = v;
}
// rotary encoder dial settings
// Rotary encoder dial settings
uint8_t config_encoder_dial_sensitivity() {
return data->encoder_dial_sensitivity;
}
@ -959,11 +967,12 @@ void set_encoder_dial_sensitivity(uint8_t v) {
data->encoder_dial_sensitivity = v;
}
// PMem to sdcard settings
bool should_use_sdcard_for_pmem() {
return std::filesystem::file_exists(PMEM_FILEFLAG);
}
// sd persisting settings
int save_persistent_settings_to_file() {
std::string filename = PMEM_SETTING_FILE;
delete_file(filename);
@ -987,10 +996,14 @@ int load_persistent_settings_from_file() {
return false;
}
// Pmem size helper
size_t data_size() {
return sizeof(data_t);
}
// Dump pmem, receiver and transmitter models internals in human readable format
bool debug_dump() {
ui::Painter painter{};
std::string debug_dir = "DEBUG";
@ -1000,6 +1013,7 @@ bool debug_dump() {
make_new_directory(debug_dir);
filename = next_filename_matching_pattern(debug_dir + "/DEBUG_DUMP_????.TXT");
if (filename.empty()) {
painter.draw_string({0, 320 - 16}, ui::Styles::red, "COULD NOT GET DUMP NAME !");
return false;
}
// dump data fo filename
@ -1008,7 +1022,6 @@ bool debug_dump() {
painter.draw_string({0, 320 - 16}, ui::Styles::red, "ERROR DUMPING " + filename.filename().string() + " !");
return false;
}
// write persistent memory
pmem_dump_file.write_line("[Persistent Memory]");
@ -1075,7 +1088,6 @@ bool debug_dump() {
// misc_config bits
pmem_dump_file.write_line("misc_config config_audio_mute: " + to_string_dec_int(config_audio_mute()));
pmem_dump_file.write_line("misc_config config_speaker_disable: " + to_string_dec_int(config_speaker_disable()));
// receiver_model
pmem_dump_file.write_line("[Receiver Model]");
pmem_dump_file.write_line("target_frequency: " + to_string_dec_uint(receiver_model.target_frequency()));
@ -1121,9 +1133,8 @@ bool debug_dump() {
pmem_dump_file.write_line("sampling_rate: " + to_string_dec_uint(transmitter_model.sampling_rate()));
pmem_dump_file.write_line("tx_gain: " + to_string_dec_int(transmitter_model.tx_gain()));
pmem_dump_file.write_line("channel_bandwidth: " + to_string_dec_uint(transmitter_model.channel_bandwidth()));
// on screen information
painter.draw_string({0, 320 - 16}, ui::Styles::green, filename.filename().string() + " DUMPED !");
return true;
}

View File

@ -236,6 +236,7 @@ bool recon_clear_output();
bool recon_load_freqs();
bool recon_load_ranges();
bool recon_update_ranges_when_recon();
bool recon_auto_record_locked();
bool recon_load_hamradios();
bool recon_match_mode();
void set_recon_autosave_freqs(const bool v);
@ -245,6 +246,7 @@ void set_recon_clear_output(const bool v);
void set_recon_load_freqs(const bool v);
void set_recon_load_ranges(const bool v);
void set_recon_update_ranges_when_recon(const bool v);
void set_recon_auto_record_locked(const bool v);
void set_recon_load_hamradios(const bool v);
void set_recon_match_mode(const bool v);