Skip to content

Commit

Permalink
Level fix and beep, RSSI avg fix (#2027)
Browse files Browse the repository at this point in the history
* fix average value being overflow'd
* fix audio and mod changes, preps for beep mode
* fixed beep_freq range, added a stop and set a variable sooner
* added support for audio beep messages
* better scaler for beep
* added bip squelch and saving of bip squelch and audio mode
* saving modulation, fixing audio
* added save and restore of bandwidth
* simpler ctcss clean on change mode
  • Loading branch information
gullradriel committed Mar 23, 2024
1 parent 1a87f2d commit 5369819
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 47 deletions.
111 changes: 84 additions & 27 deletions firmware/application/apps/ui_level.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,25 @@ using portapack::memory::map::backup_ram;

namespace ui {

void LevelView::m4_manage_stat_update() {
if (audio_mode) {
if (radio_mode == WFM_MODULATION || radio_mode == SPEC_MODULATION) {
shared_memory.request_m4_performance_counter = 0;
} else {
shared_memory.request_m4_performance_counter = 2;
}
if (radio_mode == SPEC_MODULATION) {
beep = true;
}
} else {
shared_memory.request_m4_performance_counter = 2;
if (radio_mode == SPEC_MODULATION) {
beep = false;
baseband::request_beep_stop();
}
}
}

void LevelView::focus() {
button_frequency.focus();
}
Expand Down Expand Up @@ -62,18 +81,15 @@ LevelView::LevelView(NavigationView& nav)
&freq_stats_rssi,
&freq_stats_db,
&freq_stats_rx,
&audio_mode,
&text_beep_squelch,
&field_beep_squelch,
&field_audio_mode,
&peak_mode,
&rssi,
&rssi_graph});

// activate vertical bar mode
rssi.set_vertical_rssi(true);
// activate counters for RxSat
shared_memory.request_m4_performance_counter = 2;

change_mode(NFM_MODULATION); // Start on AM
field_mode.set_by_value(NFM_MODULATION); // Reflect the mode into the manual selector

freq_ = receiver_model.target_frequency();
button_frequency.set_text("<" + to_string_short_freq(freq_) + " MHz>");
Expand All @@ -87,6 +103,11 @@ LevelView::LevelView(NavigationView& nav)
};
};

field_beep_squelch.set_value(beep_squelch);
field_beep_squelch.on_change = [this](int32_t v) {
beep_squelch = v;
};

button_frequency.on_change = [this]() {
int64_t def_step = freqman_entry_get_step_value(step_mode.selected_index());
freq_ = freq_ + (button_frequency.get_encoder_delta() * def_step);
Expand All @@ -102,33 +123,33 @@ LevelView::LevelView(NavigationView& nav)
button_frequency.set_text("<" + to_string_short_freq(freq_) + " MHz>");
};

freqman_set_modulation_option(field_mode);
field_mode.on_change = [this](size_t, OptionsField::value_t v) {
if (v != -1) {
receiver_model.disable();
baseband::shutdown();
change_mode(v);
if (audio_mode.selected_index() != 0) {
audio::output::start();
}
receiver_model.enable();
}
};
field_mode.set_by_value(radio_mode); // Reflect the mode into the manual selector
field_bw.set_selected_index(radio_bw);

rssi_resolution.on_change = [this](size_t, OptionsField::value_t v) {
if (v != -1) {
rssi_graph.set_nb_columns(v);
}
};

audio_mode.on_change = [this](size_t, OptionsField::value_t v) {
field_audio_mode.on_change = [this](size_t, OptionsField::value_t v) {
audio_mode = v;
if (v == 0) {
audio::output::stop();
} else if (v == 1) {
audio::set_rate(audio_sampling_rate);
audio::output::start();
receiver_model.set_headphone_volume(receiver_model.headphone_volume()); // WM8731 hack.
} else {
}
m4_manage_stat_update(); // rx_sat hack
};
field_audio_mode.set_selected_index(audio_mode);

peak_mode.on_change = [this](size_t, OptionsField::value_t v) {
if (v == 0) {
Expand All @@ -142,7 +163,6 @@ LevelView::LevelView(NavigationView& nav)
peak_mode.set_selected_index(2);
rssi_resolution.set_selected_index(1);
// FILL STEP OPTIONS
freqman_set_modulation_option(field_mode);
freqman_set_step_option_short(step_mode);
freq_stats_rssi.set_style(&Styles::white);
freq_stats_db.set_style(&Styles::white);
Expand All @@ -168,13 +188,28 @@ void LevelView::on_statistics_update(const ChannelStatistics& statistics) {
last_min_rssi = rssi_graph.get_graph_min();
last_avg_rssi = rssi_graph.get_graph_avg();
last_max_rssi = rssi_graph.get_graph_max();
freq_stats_rssi.set("RSSI: " + to_string_dec_uint(last_min_rssi) + "/" + to_string_dec_uint(last_avg_rssi) + "/" + to_string_dec_uint(last_max_rssi) + ", dt: " + to_string_dec_uint(rssi_graph.get_graph_delta()));
freq_stats_rssi.set("RSSI: " + to_string_dec_uint(last_min_rssi) + "/" + to_string_dec_uint(last_avg_rssi) + "/" + to_string_dec_uint(last_max_rssi));
}

if (beep && statistics.max_db > beep_squelch) {
baseband::request_audio_beep(((132 + statistics.max_db) * 2000) / 120, 24000, 250);
}

// refresh sat
if (radio_mode == SPEC_MODULATION || (radio_mode == WFM_MODULATION && audio_mode == 1)) {
Style style_freq_stats_rx{
.font = font::fixed_8x16,
.background = {55, 55, 55},
.foreground = {155, 155, 155},
};
freq_stats_rx.set_style(&style_freq_stats_rx);
freq_stats_rx.set("RxSat off");
return;
}
uint8_t rx_sat = ((uint32_t)shared_memory.m4_performance_counter) * 100 / 127;
if (last_rx_sat != rx_sat) {
last_rx_sat = rx_sat;
freq_stats_rx.set("RxSat: " + to_string_dec_uint(rx_sat) + "%");

uint8_t br = 0;
uint8_t bg = 0;
uint8_t bb = 0;
Expand All @@ -191,57 +226,67 @@ void LevelView::on_statistics_update(const ChannelStatistics& statistics) {
.foreground = {255, 255, 255},
};
freq_stats_rx.set_style(&style_freq_stats_rx);
freq_stats_rx.set("RxSat: " + to_string_dec_uint(rx_sat) + "%");
}

} /* on_statistic_updates */

size_t LevelView::change_mode(freqman_index_t new_mod) {
field_bw.on_change = [this](size_t n, OptionsField::value_t) { (void)n; };

radio_mode = new_mod;

audio::output::stop();
receiver_model.disable();
baseband::shutdown();

switch (new_mod) {
case AM_MODULATION:
audio_sampling_rate = audio::Rate::Hz_12000;
freqman_set_bandwidth_option(new_mod, field_bw);
baseband::run_image(portapack::spi_flash::image_tag_am_audio);
receiver_model.set_modulation(ReceiverModel::Mode::AMAudio);
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); };
// bw DSB (0) default
field_bw.set_by_value(0);
text_ctcss.set(" ");
receiver_model.set_am_configuration(0);
field_bw.on_change = [this](size_t index, OptionsField::value_t n) { radio_bw = index ; receiver_model.set_am_configuration(n); };
break;
case NFM_MODULATION:
audio_sampling_rate = audio::Rate::Hz_24000;
freqman_set_bandwidth_option(new_mod, field_bw);
baseband::run_image(portapack::spi_flash::image_tag_nfm_audio);
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); };
// bw 16k (2) default
field_bw.set_by_value(2);
field_bw.on_change = [this](size_t index, OptionsField::value_t n) { radio_bw = index ; receiver_model.set_nbfm_configuration(n); };
break;
case WFM_MODULATION:
audio_sampling_rate = audio::Rate::Hz_48000;
freqman_set_bandwidth_option(new_mod, field_bw);
baseband::run_image(portapack::spi_flash::image_tag_wfm_audio);
receiver_model.set_modulation(ReceiverModel::Mode::WidebandFMAudio);
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); };
// bw 200k (0) only/default
// bw 200k (0) default
field_bw.set_by_value(0);
text_ctcss.set(" ");
field_bw.on_change = [this](size_t index, OptionsField::value_t n) { radio_bw = index ; receiver_model.set_wfm_configuration(n); };
break;
case SPEC_MODULATION:
audio_sampling_rate = audio::Rate::Hz_24000;
freqman_set_bandwidth_option(new_mod, field_bw);
baseband::run_image(portapack::spi_flash::image_tag_capture);
receiver_model.set_modulation(ReceiverModel::Mode::Capture);
field_bw.on_change = [this](size_t, OptionsField::value_t sampling_rate) {
// 12k5 (0) default
field_bw.set_by_value(0);
field_bw.on_change = [this](size_t index, OptionsField::value_t sampling_rate) {
radio_bw = index;
// Baseband needs to know the desired sampling and oversampling rates.
baseband::set_sample_rate(sampling_rate, get_oversample_rate(sampling_rate));

// The radio needs to know the effective sampling rate.
auto actual_sampling_rate = get_actual_sample_rate(sampling_rate);
receiver_model.set_sampling_rate(actual_sampling_rate);
receiver_model.set_baseband_bandwidth(filter_bandwidth_for_sampling_rate(actual_sampling_rate));
};
field_bw.set_by_value(0);
default:
break;
}
Expand All @@ -250,6 +295,18 @@ size_t LevelView::change_mode(freqman_index_t new_mod) {
receiver_model.set_sampling_rate(3072000);
receiver_model.set_baseband_bandwidth(1750000);
}
if (new_mod != NFM_MODULATION) {
text_ctcss.set(" ");
}

m4_manage_stat_update(); // rx_sat hack

if (audio_mode) {
audio::set_rate(audio_sampling_rate);
audio::output::start();
receiver_model.set_headphone_volume(receiver_model.headphone_volume()); // WM8731 hack.
}
receiver_model.enable();

return step_mode.selected_index();
}
Expand Down
57 changes: 40 additions & 17 deletions firmware/application/apps/ui_level.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,29 @@ class LevelView : public View {
NavigationView& nav_;

RxRadioState radio_state_{};
app_settings::SettingsManager settings_{
"rx_level", app_settings::Mode::RX};

size_t change_mode(freqman_index_t mod_type);
void on_statistics_update(const ChannelStatistics& statistics);
void set_display_freq(int64_t freq);
void m4_manage_stat_update(); // to finely adjust the RxSaturation usage

rf::Frequency freq_ = {0};
bool beep = false;
uint8_t radio_mode = 0;
uint8_t radio_bw = 0;
uint8_t audio_mode = 0;
int32_t beep_squelch = 0;
audio::Rate audio_sampling_rate = audio::Rate::Hz_48000;

app_settings::SettingsManager settings_{
"rx_level",
app_settings::Mode::RX,
{
{"beep_squelch"sv, &beep_squelch},
{"audio_mode"sv, &audio_mode},
{"radio_mode"sv, &radio_mode},
{"radio_bw"sv, &radio_bw},
}};

Labels labels{
{{0 * 8, 0 * 16}, "LNA: VGA: AMP: VOL: ", Color::light_grey()},
Expand Down Expand Up @@ -100,23 +115,27 @@ class LevelView : public View {
{0 * 8, 2 * 16 + 8, 15 * 8, 1 * 8},
""};

OptionsField audio_mode{
OptionsField field_audio_mode{
{21 * 8, 1 * 16},
9,
{
{"audio off", 0},
{"audio on", 1}
//{"tone on", 2},
//{"tone off", 3},
}};

Text text_ctcss{
{22 * 8, 3 * 16 + 4, 8 * 8, 1 * 8},
""};
{{"audio off", 0},
{"audio on", 1}}};

Text text_beep_squelch{
{21 * 8, 3 * 16 + 4, 4 * 8, 1 * 8},
"Bip>"};

NumberField field_beep_squelch{
{25 * 8, 3 * 16 + 4},
3,
{-120, 12},
1,
' ',
};

// RSSI: XX/XX/XXX,dt: XX
// RSSI: XX/XX/XXX
Text freq_stats_rssi{
{0 * 8, 3 * 16 + 4, 22 * 8, 1 * 16},
{0 * 8, 3 * 16 + 4, 15 * 8, 1 * 16},
};

// Power: -XXX db
Expand Down Expand Up @@ -153,14 +172,18 @@ class LevelView : public View {
{0 * 8, 5 * 16 + 4, 10 * 8, 1 * 16},
};

Text text_ctcss{
{12 * 8, 5 * 16 + 4, 8 * 8, 1 * 8},
""};

RSSIGraph rssi_graph{
// 240x320 =>
{0, 6 * 16 + 4, 240 - 5 * 8, 320 - (6 * 16 + 4)},
{0, 6 * 16 + 8, 240 - 5 * 8, 320 - (6 * 16)},
};

RSSI rssi{
// 240x320 =>
{240 - 5 * 8, 6 * 16 + 4, 5 * 8, 320 - (6 * 16 + 4)},
{240 - 5 * 8, 6 * 16 + 8, 5 * 8, 320 - (6 * 16)},
};

void handle_coded_squelch(const uint32_t value);
Expand Down
23 changes: 21 additions & 2 deletions firmware/baseband/proc_capture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
*/

#include "proc_capture.hpp"

#include "audio_dma.hpp"
#include "dsp_fir_taps.hpp"
#include "event_m4.hpp"
#include "utility.hpp"
Expand Down Expand Up @@ -55,6 +55,16 @@ void CaptureProcessor::execute(const buffer_c8_t& buffer) {
}
}

void CaptureProcessor::on_signal_message(const RequestSignalMessage& message) {
if (message.signal == RequestSignalMessage::Signal::BeepStopRequest) {
audio::dma::beep_stop();
}
}

void CaptureProcessor::on_beep_message(const AudioBeepMessage& message) {
audio::dma::beep_start(message.freq, message.sample_rate, message.duration_ms);
}

void CaptureProcessor::on_message(const Message* const message) {
switch (message->id) {
case Message::ID::UpdateSpectrum:
Expand All @@ -70,6 +80,14 @@ void CaptureProcessor::on_message(const Message* const message) {
capture_config(*reinterpret_cast<const CaptureConfigMessage*>(message));
break;

case Message::ID::RequestSignal:
on_signal_message(*reinterpret_cast<const RequestSignalMessage*>(message));
break;

case Message::ID::AudioBeep:
on_beep_message(*reinterpret_cast<const AudioBeepMessage*>(message));
break;

default:
break;
}
Expand Down Expand Up @@ -152,7 +170,8 @@ void CaptureProcessor::capture_config(const CaptureConfigMessage& message) {
}

int main() {
audio::dma::init_audio_out();
EventDispatcher event_dispatcher{std::make_unique<CaptureProcessor>()};
event_dispatcher.run();
return 0;
}
}
Loading

0 comments on commit 5369819

Please sign in to comment.