mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2025-04-25 17:50:47 +00:00
Merge pull request #896 from gullradriel/looking-fast-slow
Looking fast slow
This commit is contained in:
commit
8382eaf45f
@ -27,7 +27,6 @@ using namespace portapack;
|
|||||||
|
|
||||||
namespace ui
|
namespace ui
|
||||||
{
|
{
|
||||||
|
|
||||||
void GlassView::focus()
|
void GlassView::focus()
|
||||||
{
|
{
|
||||||
field_marker.focus();
|
field_marker.focus();
|
||||||
@ -40,6 +39,19 @@ namespace ui
|
|||||||
baseband::shutdown();
|
baseband::shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GlassView::adjust_range(int64_t* f_min, int64_t* f_max, int64_t width) {
|
||||||
|
int64_t span = *f_max - *f_min;
|
||||||
|
int64_t num_intervals = span / width;
|
||||||
|
if( span % width != 0 )
|
||||||
|
{
|
||||||
|
num_intervals++;
|
||||||
|
}
|
||||||
|
int64_t new_span = num_intervals * width;
|
||||||
|
int64_t delta_span = (new_span - span) / 2;
|
||||||
|
*f_min -= delta_span;
|
||||||
|
*f_max += delta_span;
|
||||||
|
}
|
||||||
|
|
||||||
void GlassView::on_lna_changed(int32_t v_db)
|
void GlassView::on_lna_changed(int32_t v_db)
|
||||||
{
|
{
|
||||||
receiver_model.set_lna(v_db);
|
receiver_model.set_lna(v_db);
|
||||||
@ -64,12 +76,12 @@ namespace ui
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlassView::add_spectrum_pixel(int16_t color)
|
void GlassView::add_spectrum_pixel( uint8_t power )
|
||||||
{
|
{
|
||||||
static uint64_t last_max_freq = 0 ;
|
static int64_t last_max_freq = 0 ;
|
||||||
|
|
||||||
spectrum_row[pixel_index] = spectrum_rgb3_lut[color] ;
|
spectrum_row[pixel_index] = spectrum_rgb3_lut[power] ; // row of colors
|
||||||
spectrum_data[pixel_index] = ( live_frequency_integrate * spectrum_data[pixel_index] + color ) / (live_frequency_integrate + 1); // smoothing
|
spectrum_data[pixel_index] = ( live_frequency_integrate * spectrum_data[pixel_index] + power ) / (live_frequency_integrate + 1); // smoothing
|
||||||
pixel_index ++ ;
|
pixel_index ++ ;
|
||||||
|
|
||||||
if (pixel_index == 240) // got an entire waterfall line
|
if (pixel_index == 240) // got an entire waterfall line
|
||||||
@ -107,7 +119,7 @@ namespace ui
|
|||||||
if( last_max_freq != max_freq_hold )
|
if( last_max_freq != max_freq_hold )
|
||||||
{
|
{
|
||||||
last_max_freq = max_freq_hold ;
|
last_max_freq = max_freq_hold ;
|
||||||
freq_stats.set( "MAX:"+to_string_short_freq( max_freq_hold ) );
|
freq_stats.set( "MAX HOLD: "+to_string_short_freq( max_freq_hold ) );
|
||||||
}
|
}
|
||||||
PlotMarker(field_marker.value());
|
PlotMarker(field_marker.value());
|
||||||
}
|
}
|
||||||
@ -124,51 +136,84 @@ namespace ui
|
|||||||
void GlassView::on_channel_spectrum(const ChannelSpectrum &spectrum)
|
void GlassView::on_channel_spectrum(const ChannelSpectrum &spectrum)
|
||||||
{
|
{
|
||||||
baseband::spectrum_streaming_stop();
|
baseband::spectrum_streaming_stop();
|
||||||
|
if( fast_scan )
|
||||||
// Convert bins of this spectrum slice into a representative max_power and when enough, into pixels
|
|
||||||
// Spectrum.db has 256 bins. Center 12 bins are ignored (DC spike is blanked) Leftmost and rightmost 2 bins are ignored
|
|
||||||
// All things said and done, we actually need 240 of those bins:
|
|
||||||
for (uint8_t bin = 0; bin < 240; bin++)
|
|
||||||
{
|
{
|
||||||
if (bin < 120)
|
// Convert bins of this spectrum slice into a representative max_power and when enough, into pixels
|
||||||
|
// Spectrum.db has 256 bins. Center 12 bins are ignored (DC spike is blanked) Leftmost and rightmost 2 bins are ignored
|
||||||
|
// All things said and done, we actually need 240 of those bins:
|
||||||
|
for (uint8_t bin = 0; bin < 240; bin++)
|
||||||
|
{
|
||||||
|
if (bin < 120)
|
||||||
|
{
|
||||||
|
if (spectrum.db[134 + bin] > max_power) // 134
|
||||||
|
max_power = spectrum.db[134 + bin];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (spectrum.db[bin - 118] > max_power) // 118
|
||||||
|
max_power = spectrum.db[bin - 118];
|
||||||
|
}
|
||||||
|
|
||||||
|
bins_Hz_size += each_bin_size; // add this bin Hz count into the "pixel fulfilled bag of Hz"
|
||||||
|
|
||||||
|
if (bins_Hz_size >= marker_pixel_step) // new pixel fullfilled
|
||||||
|
{
|
||||||
|
if (min_color_power < max_power)
|
||||||
|
add_spectrum_pixel(max_power); // Pixel will represent max_power
|
||||||
|
else
|
||||||
|
add_spectrum_pixel(0); // Filtered out, show black
|
||||||
|
|
||||||
|
max_power = 0;
|
||||||
|
|
||||||
|
if (!pixel_index) // Received indication that a waterfall line has been completed
|
||||||
|
{
|
||||||
|
bins_Hz_size = 0; // Since this is an entire pixel line, we don't carry "Pixels into next bin"
|
||||||
|
f_center = f_center_ini; // Start a new sweep
|
||||||
|
radio::set_tuning_frequency(f_center); // tune rx for this new slice directly, faster than using persistent memory saving
|
||||||
|
chThdSleepMilliseconds(10);
|
||||||
|
baseband::spectrum_streaming_start(); // Do the RX
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bins_Hz_size -= marker_pixel_step; // reset bins size, but carrying the eventual excess Hz into next pixel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
f_center += LOOKING_GLASS_SLICE_WIDTH; // Move into the next bandwidth slice NOTE: spectrum.sampling_rate = LOOKING_GLASS_SLICE_WIDTH
|
||||||
|
}
|
||||||
|
else //slow scan
|
||||||
|
{
|
||||||
|
for( int16_t bin = 0 ; bin < 120 ; bin++)
|
||||||
{
|
{
|
||||||
if (spectrum.db[134 + bin] > max_power) // 134
|
if (spectrum.db[134 + bin] > max_power) // 134
|
||||||
max_power = spectrum.db[134 + bin];
|
max_power = spectrum.db[134 + bin];
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (spectrum.db[bin - 118] > max_power) // 118
|
|
||||||
max_power = spectrum.db[bin - 118];
|
|
||||||
}
|
|
||||||
|
|
||||||
bins_Hz_size += each_bin_size; // add this bin Hz count into the "pixel fulfilled bag of Hz"
|
bins_Hz_size += each_bin_size; // add this bin Hz count into the "pixel fulfilled bag of Hz"
|
||||||
|
|
||||||
if (bins_Hz_size >= marker_pixel_step) // new pixel fullfilled
|
if (bins_Hz_size >= marker_pixel_step) // new pixel fullfilled
|
||||||
{
|
|
||||||
if (min_color_power < max_power)
|
|
||||||
add_spectrum_pixel(max_power); // Pixel will represent max_power
|
|
||||||
else
|
|
||||||
add_spectrum_pixel(0); // Filtered out, show black
|
|
||||||
|
|
||||||
max_power = 0;
|
|
||||||
|
|
||||||
if (!pixel_index) // Received indication that a waterfall line has been completed
|
|
||||||
{
|
{
|
||||||
bins_Hz_size = 0; // Since this is an entire pixel line, we don't carry "Pixels into next bin"
|
if (min_color_power < max_power)
|
||||||
f_center = f_center_ini; // Start a new sweep
|
add_spectrum_pixel(max_power); // Pixel will represent max_power
|
||||||
radio::set_tuning_frequency(f_center); // tune rx for this new slice directly, faster than using persistent memory saving
|
else
|
||||||
chThdSleepMilliseconds(10);
|
add_spectrum_pixel(0); // Filtered out, show black
|
||||||
baseband::spectrum_streaming_start(); // Do the RX
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bins_Hz_size -= marker_pixel_step; // reset bins size, but carrying the eventual excess Hz into next pixel
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
f_center += LOOKING_GLASS_SLICE_WIDTH; // Move into the next bandwidth slice NOTE: spectrum.sampling_rate = LOOKING_GLASS_SLICE_WIDTH
|
max_power = 0;
|
||||||
|
|
||||||
|
if (!pixel_index) // Received indication that a waterfall line has been completed
|
||||||
|
{
|
||||||
|
bins_Hz_size = 0; // Since this is an entire pixel line, we don't carry "Pixels into next bin"
|
||||||
|
f_center = f_center_ini; // Start a new sweep
|
||||||
|
radio::set_tuning_frequency(f_center); // tune rx for this new slice directly, faster than using persistent memory saving
|
||||||
|
chThdSleepMilliseconds(10);
|
||||||
|
baseband::spectrum_streaming_start(); // Do the RX
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bins_Hz_size -= marker_pixel_step; // reset bins size, but carrying the eventual excess Hz into next pixel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f_center += LOOKING_GLASS_SLICE_WIDTH / 2 ;
|
||||||
|
}
|
||||||
radio::set_tuning_frequency(f_center); // tune rx for this new slice directly, faster than using persistent memory saving
|
radio::set_tuning_frequency(f_center); // tune rx for this new slice directly, faster than using persistent memory saving
|
||||||
chThdSleepMilliseconds(5);
|
chThdSleepMilliseconds(5);
|
||||||
|
|
||||||
// receiver_model.set_tuning_frequency(f_center); //tune rx for this slice
|
// receiver_model.set_tuning_frequency(f_center); //tune rx for this slice
|
||||||
baseband::spectrum_streaming_start(); // Do the RX
|
baseband::spectrum_streaming_start(); // Do the RX
|
||||||
}
|
}
|
||||||
@ -194,13 +239,20 @@ namespace ui
|
|||||||
|
|
||||||
field_marker.set_range(f_min, f_max); // Move the marker between range
|
field_marker.set_range(f_min, f_max); // Move the marker between range
|
||||||
field_marker.set_value(f_min + (search_span / 2)); // Put MARKER AT MIDDLE RANGE
|
field_marker.set_value(f_min + (search_span / 2)); // Put MARKER AT MIDDLE RANGE
|
||||||
text_range.set(to_string_dec_uint(search_span));
|
if( locked_range )
|
||||||
|
{
|
||||||
|
button_range.set_text(">"+to_string_dec_uint(search_span)+"<");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
button_range.set_text(" "+to_string_dec_uint(search_span)+" ");
|
||||||
|
}
|
||||||
|
|
||||||
f_min = (f_min)*MHZ_DIV; // Transpose into full frequency realm
|
f_min = (f_min)*MHZ_DIV; // Transpose into full frequency realm
|
||||||
f_max = (f_max)*MHZ_DIV;
|
f_max = (f_max)*MHZ_DIV;
|
||||||
search_span = search_span * MHZ_DIV;
|
adjust_range( &f_min , &f_max , 240 );
|
||||||
|
|
||||||
marker_pixel_step = search_span / 240; // Each pixel value in Hz
|
marker_pixel_step = (f_max - f_min) / 240; // Each pixel value in Hz
|
||||||
text_marker_pm.set(to_string_dec_uint((marker_pixel_step / X2_MHZ_DIV) + 1)); // Give idea of +/- marker precision
|
text_marker_pm.set(to_string_dec_uint((marker_pixel_step / X2_MHZ_DIV) + 1)); // Give idea of +/- marker precision
|
||||||
|
|
||||||
int32_t marker_step = marker_pixel_step / MHZ_DIV;
|
int32_t marker_step = marker_pixel_step / MHZ_DIV;
|
||||||
@ -249,8 +301,9 @@ namespace ui
|
|||||||
&field_frequency_max,
|
&field_frequency_max,
|
||||||
&field_lna,
|
&field_lna,
|
||||||
&field_vga,
|
&field_vga,
|
||||||
&text_range,
|
&button_range,
|
||||||
&steps_config,
|
&steps_config,
|
||||||
|
&scan_type,
|
||||||
&view_config,
|
&view_config,
|
||||||
&level_integration,
|
&level_integration,
|
||||||
&filter_config,
|
&filter_config,
|
||||||
@ -265,89 +318,100 @@ namespace ui
|
|||||||
|
|
||||||
load_Presets(); // Load available presets from TXT files (or default)
|
load_Presets(); // Load available presets from TXT files (or default)
|
||||||
|
|
||||||
field_frequency_min.set_value(presets_db[0].min); // Defaults to first preset
|
|
||||||
field_frequency_min.set_step( steps );
|
|
||||||
field_frequency_min.on_change = [this](int32_t v)
|
field_frequency_min.on_change = [this](int32_t v)
|
||||||
{
|
{
|
||||||
reset_live_view( true );
|
reset_live_view( true );
|
||||||
int32_t steps_ = steps ;
|
int32_t min_size = steps ;
|
||||||
if( steps_ < 24 )
|
if( locked_range )
|
||||||
steps_ = 24 ;
|
min_size = search_span ;
|
||||||
if( v > 7200 - steps_ )
|
if( min_size < 20 )
|
||||||
|
min_size = 20 ;
|
||||||
|
if( v > 7200 - min_size )
|
||||||
{
|
{
|
||||||
v = 7200 - steps_ ;
|
v = 7200 - min_size ;
|
||||||
field_frequency_min.set_value( v );
|
field_frequency_min.set_value( v );
|
||||||
}
|
}
|
||||||
if (v >= (field_frequency_max.value() - steps_ ) )
|
if (v > (field_frequency_max.value() - min_size ) )
|
||||||
field_frequency_max.set_value( v + steps_ );
|
field_frequency_max.set_value( v + min_size );
|
||||||
|
if( locked_range )
|
||||||
|
field_frequency_max.set_value( v + min_size );
|
||||||
this->on_range_changed();
|
this->on_range_changed();
|
||||||
};
|
};
|
||||||
|
field_frequency_min.set_value(presets_db[0].min); // Defaults to first preset
|
||||||
|
field_frequency_min.set_step( steps );
|
||||||
|
|
||||||
field_frequency_min.on_select = [this, &nav](NumberField& field) {
|
field_frequency_min.on_select = [this, &nav](NumberField& field) {
|
||||||
auto new_view = nav_.push<FrequencyKeypadView>(field_frequency_min.value()*1000000);
|
auto new_view = nav_.push<FrequencyKeypadView>(field_frequency_min.value()*1000000);
|
||||||
new_view->on_changed = [this, &field](rf::Frequency f) {
|
new_view->on_changed = [this, &field](rf::Frequency f) {
|
||||||
int32_t freq = f / 1000000 ;
|
int32_t freq = f / 1000000 ;
|
||||||
int32_t steps_ = steps ;
|
int32_t min_size = steps ;
|
||||||
if( steps_ < 24 )
|
if( locked_range )
|
||||||
steps_ = 24 ;
|
min_size = search_span ;
|
||||||
if( freq > (7200 - steps_ ) )
|
if( min_size < 20 )
|
||||||
freq= 7200 - steps_ ;
|
min_size = 20 ;
|
||||||
|
if( freq > (7200 - min_size ) )
|
||||||
|
freq = 7200 - min_size ;
|
||||||
field_frequency_min.set_value( freq );
|
field_frequency_min.set_value( freq );
|
||||||
if( field_frequency_max.value() < ( freq + steps_ ) )
|
if( field_frequency_max.value() < ( freq + min_size ) )
|
||||||
field_frequency_max.set_value( freq + steps_ );
|
field_frequency_max.set_value( freq + min_size );
|
||||||
this->on_range_changed();
|
this->on_range_changed();
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
field_frequency_max.set_value(presets_db[0].max); // Defaults to first preset
|
|
||||||
field_frequency_max.set_step( steps );
|
|
||||||
field_frequency_max.on_change = [this](int32_t v)
|
field_frequency_max.on_change = [this](int32_t v)
|
||||||
{
|
{
|
||||||
reset_live_view( true );
|
reset_live_view( true );
|
||||||
int32_t steps_ = steps ;
|
int32_t min_size = steps ;
|
||||||
if( steps_ < 24 )
|
if( locked_range )
|
||||||
steps_ = 24 ;
|
min_size = search_span ;
|
||||||
if( v < steps_ )
|
if( min_size < 20 )
|
||||||
|
min_size = 20 ;
|
||||||
|
if( v < min_size )
|
||||||
{
|
{
|
||||||
v = steps_ ;
|
v = min_size ;
|
||||||
field_frequency_max.set_value( v );
|
field_frequency_max.set_value( v );
|
||||||
}
|
}
|
||||||
if (v < (field_frequency_min.value() + steps_) )
|
if (v < (field_frequency_min.value() + min_size) )
|
||||||
field_frequency_min.set_value(v - steps_);
|
field_frequency_min.set_value(v - min_size);
|
||||||
|
if( locked_range )
|
||||||
|
field_frequency_min.set_value( v - min_size );
|
||||||
this->on_range_changed();
|
this->on_range_changed();
|
||||||
};
|
};
|
||||||
|
field_frequency_max.set_value(presets_db[0].max); // Defaults to first preset
|
||||||
|
field_frequency_max.set_step( steps );
|
||||||
|
|
||||||
field_frequency_max.on_select = [this, &nav](NumberField& field) {
|
field_frequency_max.on_select = [this, &nav](NumberField& field) {
|
||||||
auto new_view = nav_.push<FrequencyKeypadView>(field_frequency_max.value()*1000000);
|
auto new_view = nav_.push<FrequencyKeypadView>(field_frequency_max.value()*1000000);
|
||||||
new_view->on_changed = [this, &field](rf::Frequency f) {
|
new_view->on_changed = [this, &field](rf::Frequency f) {
|
||||||
int32_t steps_ = steps ;
|
int32_t min_size = steps ;
|
||||||
if( steps_ < 24 )
|
if( locked_range )
|
||||||
steps_ = 24 ;
|
min_size = search_span ;
|
||||||
|
if( min_size < 20 )
|
||||||
|
min_size = 20 ;
|
||||||
int32_t freq = f / 1000000 ;
|
int32_t freq = f / 1000000 ;
|
||||||
if( freq < 24 )
|
if( freq < min_size )
|
||||||
freq = 24 ;
|
freq = min_size ;
|
||||||
field_frequency_max.set_value( freq );
|
field_frequency_max.set_value( freq );
|
||||||
if( field_frequency_min.value() > ( freq - steps) )
|
if( field_frequency_min.value() > ( freq - min_size) )
|
||||||
field_frequency_min.set_value( freq - steps );
|
field_frequency_min.set_value( freq - min_size );
|
||||||
this->on_range_changed();
|
this->on_range_changed();
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
field_lna.set_value(receiver_model.lna());
|
|
||||||
field_lna.on_change = [this](int32_t v)
|
field_lna.on_change = [this](int32_t v)
|
||||||
{
|
{
|
||||||
reset_live_view( true );
|
reset_live_view( true );
|
||||||
this->on_lna_changed(v);
|
this->on_lna_changed(v);
|
||||||
};
|
};
|
||||||
|
field_lna.set_value(receiver_model.lna());
|
||||||
|
|
||||||
field_vga.set_value(receiver_model.vga());
|
|
||||||
field_vga.on_change = [this](int32_t v_db)
|
field_vga.on_change = [this](int32_t v_db)
|
||||||
{
|
{
|
||||||
reset_live_view( true );
|
reset_live_view( true );
|
||||||
this->on_vga_changed(v_db);
|
this->on_vga_changed(v_db);
|
||||||
};
|
};
|
||||||
|
field_vga.set_value(receiver_model.vga());
|
||||||
|
|
||||||
steps_config.set_selected_index(3); //default of 250 Mhz steps
|
|
||||||
steps_config.on_change = [this](size_t n, OptionsField::value_t v)
|
steps_config.on_change = [this](size_t n, OptionsField::value_t v)
|
||||||
{
|
{
|
||||||
(void)n;
|
(void)n;
|
||||||
@ -355,6 +419,14 @@ namespace ui
|
|||||||
field_frequency_max.set_step( v );
|
field_frequency_max.set_step( v );
|
||||||
steps = v ;
|
steps = v ;
|
||||||
};
|
};
|
||||||
|
steps_config.set_selected_index(0); //default of 1 Mhz steps
|
||||||
|
|
||||||
|
scan_type.on_change = [this](size_t n, OptionsField::value_t v)
|
||||||
|
{
|
||||||
|
(void)n;
|
||||||
|
fast_scan = v ;
|
||||||
|
};
|
||||||
|
scan_type.set_selected_index(0); // default legacy fast scan
|
||||||
|
|
||||||
view_config.on_change = [this](size_t n, OptionsField::value_t v)
|
view_config.on_change = [this](size_t n, OptionsField::value_t v)
|
||||||
{
|
{
|
||||||
@ -400,14 +472,14 @@ namespace ui
|
|||||||
reset_live_view( true );
|
reset_live_view( true );
|
||||||
live_frequency_integrate = v ;
|
live_frequency_integrate = v ;
|
||||||
};
|
};
|
||||||
level_integration.set_selected_index(2); //default integration of ( 3 * old value + new_value ) / 4
|
level_integration.set_selected_index(3); //default integration of ( 3 * old value + new_value ) / 4
|
||||||
|
|
||||||
filter_config.set_selected_index(0);
|
|
||||||
filter_config.on_change = [this](size_t n, OptionsField::value_t v) {
|
filter_config.on_change = [this](size_t n, OptionsField::value_t v) {
|
||||||
(void)n;
|
(void)n;
|
||||||
reset_live_view( true );
|
reset_live_view( true );
|
||||||
min_color_power = v;
|
min_color_power = v;
|
||||||
};
|
};
|
||||||
|
filter_config.set_selected_index(0);
|
||||||
|
|
||||||
range_presets.on_change = [this](size_t n, OptionsField::value_t v)
|
range_presets.on_change = [this](size_t n, OptionsField::value_t v)
|
||||||
{
|
{
|
||||||
@ -432,11 +504,26 @@ namespace ui
|
|||||||
nav_.push<AnalogAudioView>(); // Jump into audio view
|
nav_.push<AnalogAudioView>(); // Jump into audio view
|
||||||
};
|
};
|
||||||
|
|
||||||
field_trigger.set_value(32); // Defaults to 32, as normal triggering resolution
|
|
||||||
field_trigger.on_change = [this](int32_t v)
|
field_trigger.on_change = [this](int32_t v)
|
||||||
{
|
{
|
||||||
baseband::set_spectrum(LOOKING_GLASS_SLICE_WIDTH, v);
|
baseband::set_spectrum(LOOKING_GLASS_SLICE_WIDTH, v);
|
||||||
};
|
};
|
||||||
|
field_trigger.set_value(32); // Defaults to 32, as normal triggering resolution
|
||||||
|
|
||||||
|
button_range.on_select = [this](Button&) {
|
||||||
|
if( locked_range )
|
||||||
|
{
|
||||||
|
locked_range = false ;
|
||||||
|
button_range.set_style(&style_white);
|
||||||
|
button_range.set_text(" "+to_string_dec_uint(search_span)+" ");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
locked_range = true ;
|
||||||
|
button_range.set_style(&style_red);
|
||||||
|
button_range.set_text(">"+to_string_dec_uint(search_span)+"<");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
button_jump.on_select = [this](Button&) {
|
button_jump.on_select = [this](Button&) {
|
||||||
receiver_model.set_tuning_frequency(max_freq_hold); // Center tune rx in marker freq.
|
receiver_model.set_tuning_frequency(max_freq_hold); // Center tune rx in marker freq.
|
||||||
|
@ -37,15 +37,13 @@
|
|||||||
|
|
||||||
namespace ui
|
namespace ui
|
||||||
{
|
{
|
||||||
#define LOOKING_GLASS_SLICE_WIDTH 19999920 // Each slice bandwidth 20 MHz and a multiple of 240
|
|
||||||
// since we are using LOOKING_GLASS_SLICE_WIDTH/240 as the each_bin_size
|
|
||||||
// it should also be a multiple of 2 since we are using LOOKING_GLASS_SLICE_WIDTH / 2 as centering freq
|
|
||||||
#define MHZ_DIV 1000000
|
#define MHZ_DIV 1000000
|
||||||
#define X2_MHZ_DIV 2000000
|
#define X2_MHZ_DIV 2000000
|
||||||
|
|
||||||
class GlassView : public View
|
class GlassView : public View
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
GlassView(NavigationView &nav);
|
GlassView(NavigationView &nav);
|
||||||
|
|
||||||
GlassView( const GlassView &);
|
GlassView( const GlassView &);
|
||||||
@ -68,15 +66,32 @@ namespace ui
|
|||||||
std::string label{};
|
std::string label{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const Style style_white { // free range
|
||||||
|
.font = font::fixed_8x16,
|
||||||
|
.background = Color::black(),
|
||||||
|
.foreground = Color::white(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const Style style_red { // locked range
|
||||||
|
.font = font::fixed_8x16,
|
||||||
|
.background = Color::black(),
|
||||||
|
.foreground = Color::red(),
|
||||||
|
};
|
||||||
|
|
||||||
std::vector<preset_entry> presets_db{};
|
std::vector<preset_entry> presets_db{};
|
||||||
|
|
||||||
|
int64_t LOOKING_GLASS_SLICE_WIDTH = 19999920; // Each slice bandwidth 20 MHz and a multiple of 240
|
||||||
|
// since we are using LOOKING_GLASS_SLICE_WIDTH/240 as the each_bin_size
|
||||||
|
// it should also be a multiple of 2 since we are using LOOKING_GLASS_SLICE_WIDTH / 2 as centering freq
|
||||||
|
|
||||||
|
void adjust_range(int64_t* f_min, int64_t* f_max, int64_t width);
|
||||||
void on_channel_spectrum(const ChannelSpectrum& spectrum);
|
void on_channel_spectrum(const ChannelSpectrum& spectrum);
|
||||||
void do_timers();
|
void do_timers();
|
||||||
void on_range_changed();
|
void on_range_changed();
|
||||||
void on_lna_changed(int32_t v_db);
|
void on_lna_changed(int32_t v_db);
|
||||||
void on_vga_changed(int32_t v_db);
|
void on_vga_changed(int32_t v_db);
|
||||||
void reset_live_view( bool clear_screen );
|
void reset_live_view( bool clear_screen );
|
||||||
void add_spectrum_pixel(int16_t color);
|
void add_spectrum_pixel(uint8_t power);
|
||||||
void PlotMarker(rf::Frequency pos);
|
void PlotMarker(rf::Frequency pos);
|
||||||
void load_Presets();
|
void load_Presets();
|
||||||
void txtline_process(std::string& line);
|
void txtline_process(std::string& line);
|
||||||
@ -96,15 +111,17 @@ namespace ui
|
|||||||
std::array<uint8_t, 240> spectrum_data = { 0 };
|
std::array<uint8_t, 240> spectrum_data = { 0 };
|
||||||
ChannelSpectrumFIFO* fifo { nullptr };
|
ChannelSpectrumFIFO* fifo { nullptr };
|
||||||
uint8_t max_power = 0;
|
uint8_t max_power = 0;
|
||||||
int32_t steps = 250 ; // default of 250 Mhz steps
|
int32_t steps = 0 ;
|
||||||
uint8_t live_frequency_view = 0 ;
|
uint8_t live_frequency_view = 0 ;
|
||||||
int16_t live_frequency_integrate = 3 ;
|
int16_t live_frequency_integrate = 3 ;
|
||||||
uint64_t max_freq_hold = 0 ;
|
int64_t max_freq_hold = 0 ;
|
||||||
int16_t max_freq_power = -1000 ;
|
int16_t max_freq_power = -1000 ;
|
||||||
|
bool fast_scan = true ; // default to legacy fast scan
|
||||||
|
bool locked_range = false ;
|
||||||
|
|
||||||
Labels labels{
|
Labels labels{
|
||||||
{{0, 0}, "MIN: MAX: LNA VGA ", Color::light_grey()},
|
{{0, 0}, "MIN: MAX: LNA VGA ", Color::light_grey()},
|
||||||
{{0, 1 * 16}, " RANGE: FILTER: AMP:", Color::light_grey()},
|
{{0, 1 * 16}, "RANGE: FILTER: AMP:", Color::light_grey()},
|
||||||
{{0, 2 * 16}, "PRESET:", Color::light_grey()},
|
{{0, 2 * 16}, "PRESET:", Color::light_grey()},
|
||||||
{{0, 3 * 16}, "MARKER: MHz +/- MHz", Color::light_grey()},
|
{{0, 3 * 16}, "MARKER: MHz +/- MHz", Color::light_grey()},
|
||||||
{{0, 4 * 16}, "RES: STEP:", Color::light_grey()}
|
{{0, 4 * 16}, "RES: STEP:", Color::light_grey()}
|
||||||
@ -134,12 +151,12 @@ namespace ui
|
|||||||
{ 27 * 8, 0 * 16 }
|
{ 27 * 8, 0 * 16 }
|
||||||
};
|
};
|
||||||
|
|
||||||
Text text_range{
|
Button button_range{
|
||||||
{7 * 8, 1 * 16, 4 * 8, 16},
|
{7 * 8, 1 * 16, 4 * 8, 16},
|
||||||
""};
|
""};
|
||||||
|
|
||||||
OptionsField filter_config{
|
OptionsField filter_config{
|
||||||
{19 * 8, 1 * 16},
|
{20 * 8, 1 * 16},
|
||||||
4,
|
4,
|
||||||
{
|
{
|
||||||
{"OFF ", 0},
|
{"OFF ", 0},
|
||||||
@ -176,38 +193,51 @@ namespace ui
|
|||||||
' '};
|
' '};
|
||||||
|
|
||||||
OptionsField steps_config{
|
OptionsField steps_config{
|
||||||
{ 14 * 8, 4 * 16},
|
{ 13 * 8, 4 * 16},
|
||||||
4,
|
3,
|
||||||
{
|
{
|
||||||
{"1", 1},
|
{"1", 1},
|
||||||
{"50", 50},
|
{"25", 25},
|
||||||
{"100", 100},
|
{"50", 50},
|
||||||
{"250", 250},
|
{"100", 100},
|
||||||
{"500", 500},
|
{"250", 250},
|
||||||
}};
|
{"500", 500},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
OptionsField view_config{
|
OptionsField scan_type{
|
||||||
|
{ 17 * 8, 4 * 16},
|
||||||
|
2,
|
||||||
|
{
|
||||||
|
{"F-", true },
|
||||||
|
{"S-", false },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
OptionsField view_config{
|
||||||
{ 19 * 8, 4 * 16},
|
{ 19 * 8, 4 * 16},
|
||||||
7,
|
7,
|
||||||
{
|
{
|
||||||
{"SPCTR-V", 0 },
|
{"SPCTR-V", 0 },
|
||||||
{"LEVEL-V", 1 },
|
{"LEVEL-V", 1 },
|
||||||
{"PEAK-V" , 2 },
|
{"PEAK-V" , 2 },
|
||||||
}};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
OptionsField level_integration{
|
OptionsField level_integration{
|
||||||
{ 27 * 8, 4 * 16},
|
{ 27 * 8, 4 * 16},
|
||||||
2,
|
2,
|
||||||
{
|
{
|
||||||
{"x1", 1 },
|
{"x0", 0 },
|
||||||
{"x2", 2 },
|
{"x1", 1 },
|
||||||
{"x3", 3 },
|
{"x2", 2 },
|
||||||
{"x4", 4 },
|
{"x3", 3 },
|
||||||
{"x5", 5 },
|
{"x4", 4 },
|
||||||
{"x6", 6 },
|
{"x5", 5 },
|
||||||
{"x7", 7 },
|
{"x6", 6 },
|
||||||
{"x8", 8 },
|
{"x7", 7 },
|
||||||
{"x9", 9 },
|
{"x8", 8 },
|
||||||
|
{"x9", 9 },
|
||||||
}};
|
}};
|
||||||
|
|
||||||
Button button_jump {
|
Button button_jump {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user