Fix LF/MF RX centering with adaptive FS4 tuning (#3319)

* Fix LF/MF RX tuning with adaptive FS4 shift

* Enable adaptive FS4 tuning in Waterfall Designer
This commit is contained in:
Brumi-2021
2026-09-15 19:11:30 +02:00
committed by GitHub
parent b8ad44c431
commit b01b23981a
14 changed files with 191 additions and 16 deletions
+21 -1
View File
@@ -470,6 +470,18 @@ void set_hunter_config(uint32_t threshold, uint32_t hangtime_ms, bool start) {
}
static bool baseband_image_running = false;
static bool rx_fs4_supported = false;
bool supports_rx_fs4() {
return baseband_image_running && rx_fs4_supported;
}
void set_rx_fs4_direction(RxFs4Direction direction) {
if (supports_rx_fs4()) {
const RxFs4ConfigMessage message{direction};
send_message(&message);
}
}
bool is_image_running() {
return baseband_image_running;
@@ -484,6 +496,10 @@ void run_image(const spi_flash::image_tag_t image_tag, bool enforce_core_sync) {
shared_memory.clear_baseband_ready();
m4_init(image_tag, memory::map::m4_code, false);
rx_fs4_supported = image_tag == spi_flash::image_tag_am_audio ||
image_tag == spi_flash::image_tag_nfm_audio ||
image_tag == spi_flash::image_tag_wfm_audio ||
image_tag == spi_flash::image_tag_capture;
baseband_image_running = true;
creg::m4txevent::enable();
@@ -499,7 +515,8 @@ void run_image(const spi_flash::image_tag_t image_tag, bool enforce_core_sync) {
}
}
void run_prepared_image(const uint32_t m4_code, bool enforce_core_sync) {
void run_prepared_image(const uint32_t m4_code, bool enforce_core_sync, const spi_flash::image_tag_t prepared_image_tag) {
rx_fs4_supported = false;
if (baseband_image_running) {
chDbgPanic("BBRunning");
}
@@ -508,6 +525,8 @@ void run_prepared_image(const uint32_t m4_code, bool enforce_core_sync) {
shared_memory.clear_baseband_ready();
m4_init_prepared(m4_code, false);
// Only explicitly identified Capture images support application FS4 control.
rx_fs4_supported = prepared_image_tag == spi_flash::image_tag_capture;
baseband_image_running = true;
creg::m4txevent::enable();
@@ -524,6 +543,7 @@ void run_prepared_image(const uint32_t m4_code, bool enforce_core_sync) {
}
void shutdown() {
rx_fs4_supported = false;
if (!baseband_image_running) {
return;
}
+3 -1
View File
@@ -132,8 +132,10 @@ void request_beep_stop();
void request_audio_beep(uint32_t freq, uint32_t sample_rate, uint32_t duration_ms);
bool is_image_running();
bool supports_rx_fs4();
void set_rx_fs4_direction(RxFs4Direction direction);
void run_image(const portapack::spi_flash::image_tag_t image_tag, bool enforce_core_sync = true);
void run_prepared_image(const uint32_t m4_code, bool enforce_core_sync = true);
void run_prepared_image(const uint32_t m4_code, bool enforce_core_sync = true, const portapack::spi_flash::image_tag_t prepared_image_tag = portapack::spi_flash::image_tag_none);
void shutdown();
void spectrum_streaming_start();
@@ -71,7 +71,8 @@ bool is_color_level(const std::string& line) {
WaterfallDesignerView::WaterfallDesignerView(NavigationView& nav)
: nav_{nav} {
baseband::run_prepared_image(portapack::memory::map::m4_code.base());
baseband::run_prepared_image(portapack::memory::map::m4_code.base(), true,
portapack::spi_flash::image_tag_capture);
add_children({&labels,
&field_frequency,
+20 -3
View File
@@ -334,6 +334,8 @@ void ReceiverModel::disable() {
void ReceiverModel::initialize() {
settings_ = settings_t{};
hidden_offset = 0;
application_fs4_direction_ = RxFs4Direction::Down;
am_spectrum_zoom_ = spectrum_zoom_for_am_config(settings_.am_config_index);
}
@@ -369,14 +371,29 @@ int32_t ReceiverModel::tuning_offset() {
if ((modulation() == Mode::SpectrumAnalysis)) {
return 0;
} else {
return -(sampling_rate() / 4);
const int32_t quarter_rate = static_cast<int32_t>(sampling_rate() / 4);
const rf::Frequency effective_frequency = target_frequency() + hidden_offset;
return baseband::supports_rx_fs4() && effective_frequency - quarter_rate < 0
? quarter_rate
: -quarter_rate;
}
}
void ReceiverModel::update_tuning_frequency() {
// TODO: use positive offset if freq < offset.
if (enabled_) {
radio::set_tuning_frequency(target_frequency() + hidden_offset + tuning_offset());
const auto offset = tuning_offset();
if (!radio::set_tuning_frequency(target_frequency() + hidden_offset + offset))
return;
if (modulation() != Mode::SpectrumAnalysis && baseband::supports_rx_fs4()) {
application_fs4_direction_ = offset > 0 ? RxFs4Direction::Up : RxFs4Direction::Down;
// Re-send on enable too: the active processor may have restarted.
baseband::set_rx_fs4_direction(application_fs4_direction_);
}
#ifdef PRALINE
// A tune can change the FPGA shift (including the special zero entry).
update_baseband_bandwidth();
#endif
}
}
+1
View File
@@ -149,6 +149,7 @@ class ReceiverModel {
AMConfigureMessage::Zoom_waterfall am_spectrum_zoom_{AMConfigureMessage::Zoom_waterfall::ZOOM_x_1};
settings_t settings_{};
bool enabled_ = false;
RxFs4Direction application_fs4_direction_{RxFs4Direction::Down};
rf::Frequency hidden_offset = 0; // when we need to hide the offset from user, we set this. like when WeFax needs -300Hz.
int32_t tuning_offset();