diff --git a/firmware/application/apps/ui_level.cpp b/firmware/application/apps/ui_level.cpp index 51cb98cc..cd6d8093 100644 --- a/firmware/application/apps/ui_level.cpp +++ b/firmware/application/apps/ui_level.cpp @@ -62,6 +62,7 @@ namespace ui { &field_bw, &field_mode, &step_mode, + &rssi_resolution, &button_frequency, &text_ctcss, &freq_stats_rssi, @@ -143,6 +144,13 @@ namespace ui { } }; + 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) { if( v == 0 ) { @@ -215,7 +223,7 @@ namespace ui { last_min_rssi = rssi.get_min(); last_avg_rssi = rssi.get_avg(); last_max_rssi = rssi.get_max(); - freq_stats_rssi.set( "RSSI: "+to_string_dec_int( rssi.get_min() )+"/"+to_string_dec_int( rssi.get_avg() )+"/"+to_string_dec_int( rssi.get_max() )+" db, dt: "+to_string_dec_int( rssi.get_delta() )+" db" ); + freq_stats_rssi.set( "RSSI: "+to_string_dec_int( rssi.get_min() )+"/"+to_string_dec_int( rssi.get_avg() )+"/"+to_string_dec_int( rssi.get_max() )+",dt: "+to_string_dec_int( rssi.get_delta() ) ); } } /* on_statistic_updates */ @@ -290,7 +298,7 @@ namespace ui { { last_idx = min_idx ; if (min_diff < 40) - text_ctcss.set(tone_keys[min_idx].first); + text_ctcss.set("T: "+tone_keys[min_idx].first); else text_ctcss.set(" "); } diff --git a/firmware/application/apps/ui_level.hpp b/firmware/application/apps/ui_level.hpp index e4c573bd..7d645f67 100644 --- a/firmware/application/apps/ui_level.hpp +++ b/firmware/application/apps/ui_level.hpp @@ -174,12 +174,13 @@ namespace ui { Text text_ctcss { - { 20 * 8, 3 * 16 + 4 , 14 * 8, 1 * 8 }, + { 22 * 8, 3 * 16 + 4 , 14 * 8, 1 * 8 }, "" }; + // RSSI: XX/XX/XXX,dt: XX Text freq_stats_rssi { - { 0 * 8 , 3 * 16 + 4 , 20 * 8, 16 }, + { 0 * 8 , 3 * 16 + 4 , 22 * 8, 16 }, }; Text freq_stats_db { @@ -188,7 +189,7 @@ namespace ui { OptionsField peak_mode { - { 44 + 10 * 8, 4 * 16 + 4 }, + { 40 + 10 * 8, 4 * 16 + 4 }, 10, { {"peak:none", 0}, @@ -200,6 +201,18 @@ namespace ui { {"peak:10s",10000}, } }; + OptionsField rssi_resolution { + { 44 + 20 * 8, 4 * 16 + 4}, + 4, + { + {"16x", 16}, + {"32x", 32}, + {"64x", 64}, + {"128x", 128}, + {"240x", 240}, + } + }; + void handle_coded_squelch(const uint32_t value); void on_headphone_volume_changed(int32_t v); diff --git a/firmware/application/apps/ui_looking_glass_app.cpp b/firmware/application/apps/ui_looking_glass_app.cpp index 8854b974..35c852ce 100644 --- a/firmware/application/apps/ui_looking_glass_app.cpp +++ b/firmware/application/apps/ui_looking_glass_app.cpp @@ -184,6 +184,7 @@ namespace ui &field_lna, &field_vga, &text_range, + &steps_config, &filter_config, &field_rf_amp, &range_presets, @@ -194,21 +195,71 @@ namespace ui 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) { - if (v >= field_frequency_max.value()) - field_frequency_max.set_value(v + 240); + int32_t steps_ = steps ; + if( steps_ < 20 ) + steps_ = 20 ; + if( v > 7200 - steps_ ) + { + v = 7200 - steps_ ; + field_frequency_min.set_value( v ); + } + if (v >= (field_frequency_max.value() - steps_ ) ) + field_frequency_max.set_value( v + steps_ ); this->on_range_changed(); }; + field_frequency_min.on_select = [this, &nav](NumberField& field) { + auto new_view = nav_.push(field_frequency_min.value()*1000000); + new_view->on_changed = [this, &field](rf::Frequency f) { + int32_t freq = f / 1000000 ; + int32_t steps_ = steps ; + if( steps_ < 20 ) + steps_ = 20 ; + if( freq > (7200 - steps_ ) ) + freq= 7200 - steps_ ; + field_frequency_min.set_value( freq ); + if( field_frequency_max.value() < ( freq + steps_ ) ) + field_frequency_max.set_value( freq + steps_ ); + 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) - { - if (v <= field_frequency_min.value()) - field_frequency_min.set_value(v - 240); + { + int32_t steps_ = steps ; + if( steps_ < 20 ) + steps_ = 20 ; + if( v < steps_ ) + { + v = steps_ ; + field_frequency_max.set_value( v ); + } + if (v < (field_frequency_min.value() + steps_) ) + field_frequency_min.set_value(v - steps_); this->on_range_changed(); }; + field_frequency_max.on_select = [this, &nav](NumberField& field) { + auto new_view = nav_.push(field_frequency_max.value()*1000000); + new_view->on_changed = [this, &field](rf::Frequency f) { + int32_t steps_ = steps ; + if( steps_ < 20 ) + steps_ = 20 ; + int32_t freq = f / 1000000 ; + if( freq < 20 ) + freq = 20 ; + field_frequency_max.set_value( freq ); + if( field_frequency_min.value() > ( freq - steps) ) + field_frequency_min.set_value( freq - steps ); + this->on_range_changed(); + }; + }; + field_lna.set_value(receiver_model.lna()); field_lna.on_change = [this](int32_t v) { @@ -221,11 +272,13 @@ namespace ui this->on_vga_changed(v_db); }; - filter_config.set_selected_index(0); - filter_config.on_change = [this](size_t n, OptionsField::value_t v) + steps_config.set_selected_index(3); //default of 250 Mhz steps + steps_config.on_change = [this](size_t n, OptionsField::value_t v) { (void)n; - min_color_power = v; + field_frequency_min.set_step( v ); + field_frequency_max.set_step( v ); + steps = v ; }; range_presets.on_change = [this](size_t n, OptionsField::value_t v) diff --git a/firmware/application/apps/ui_looking_glass_app.hpp b/firmware/application/apps/ui_looking_glass_app.hpp index 33e4c937..f9089b1e 100644 --- a/firmware/application/apps/ui_looking_glass_app.hpp +++ b/firmware/application/apps/ui_looking_glass_app.hpp @@ -1,190 +1,202 @@ /* - * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. - * Copyright (C) 2020 euquiq - * - * This file is part of PortaPack. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ + * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2020 euquiq + * + * This file is part of PortaPack. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ #ifndef _UI_GLASS #define _UI_GLASS - #include "ui.hpp" - #include "portapack.hpp" - #include "baseband_api.hpp" - #include "receiver_model.hpp" - #include "ui_widget.hpp" - #include "ui_navigation.hpp" - #include "ui_receiver.hpp" - #include "string_format.hpp" - #include "analog_audio_app.hpp" - #include "spectrum_color_lut.hpp" +#include "ui.hpp" +#include "portapack.hpp" +#include "baseband_api.hpp" +#include "receiver_model.hpp" +#include "ui_widget.hpp" +#include "ui_navigation.hpp" +#include "ui_receiver.hpp" +#include "string_format.hpp" +#include "analog_audio_app.hpp" +#include "spectrum_color_lut.hpp" - namespace ui - { - #define LOOKING_GLASS_SLICE_WIDTH 20000000 // Each slice bandwidth 20 MHz - #define MHZ_DIV 1000000 - #define X2_MHZ_DIV 2000000 +namespace ui +{ +#define LOOKING_GLASS_SLICE_WIDTH 20000000 // Each slice bandwidth 20 MHz +#define MHZ_DIV 1000000 +#define X2_MHZ_DIV 2000000 - class GlassView : public View - { - public: - GlassView(NavigationView &nav); + class GlassView : public View + { + public: + GlassView(NavigationView &nav); - GlassView( const GlassView &); - GlassView& operator=(const GlassView &nav); + GlassView( const GlassView &); + GlassView& operator=(const GlassView &nav); - ~GlassView(); - std::string title() const override { return "Looking Glass"; }; + ~GlassView(); + std::string title() const override { return "Looking Glass"; }; - void on_show() override; - void on_hide() override; - void focus() override; + void on_show() override; + void on_hide() override; + void focus() override; - private: - NavigationView& nav_; + private: + NavigationView& nav_; - struct preset_entry - { - rf::Frequency min{}; - rf::Frequency max{}; - std::string label{}; - }; - - std::vector presets_db{}; - - void on_channel_spectrum(const ChannelSpectrum& spectrum); - void do_timers(); - void on_range_changed(); - void on_lna_changed(int32_t v_db); - void on_vga_changed(int32_t v_db); - void add_spectrum_pixel(Color color); - void PlotMarker(rf::Frequency pos); - void load_Presets(); - void txtline_process(std::string& line); - void populate_Presets(); - void presets_Default(); - - rf::Frequency f_min { 0 }, f_max { 0 }; - rf::Frequency search_span { 0 }; - rf::Frequency f_center { 0 }; - rf::Frequency f_center_ini { 0 }; - rf::Frequency marker_pixel_step { 0 }; - rf::Frequency each_bin_size { LOOKING_GLASS_SLICE_WIDTH / 240 }; - rf::Frequency bins_Hz_size { 0 }; - uint8_t min_color_power { 0 }; - uint32_t pixel_index { 0 }; - std::array spectrum_row = { 0 }; - ChannelSpectrumFIFO* fifo { nullptr }; - uint8_t max_power = 0; - - Labels labels{ - {{0, 0}, "MIN: MAX: LNA VGA ", Color::light_grey()}, - {{0, 1 * 16}, " RANGE: FILTER: AMP:", Color::light_grey()}, - {{0, 2 * 16}, "PRESET:", Color::light_grey()}, - {{0, 3 * 16}, "MARKER: MHz +/- MHz", Color::light_grey()}, - {{0, 4 * 16}, "RESOLUTION: (fft trigger)", Color::light_grey()} - }; - - NumberField field_frequency_min { - { 4 * 8, 0 * 16 }, - 4, - { 0, 6960 }, - 240, - ' ' - }; - - NumberField field_frequency_max { - { 13 * 8, 0 * 16 }, - 4, - { 240, 7200 }, - 240, - ' ' - }; - - LNAGainField field_lna { - { 21 * 8, 0 * 16 } - }; - - VGAGainField field_vga { - { 27 * 8, 0 * 16 } - }; - - Text text_range{ - {7 * 8, 1 * 16, 4 * 8, 16}, - ""}; - - OptionsField filter_config{ - {19 * 8, 1 * 16}, - 4, + struct preset_entry { - {"OFF ", 0}, - {"MID ", 118}, //85 +25 (110) + a bit more to kill all blue - {"HIGH", 202}, //168 + 25 (193) - }}; + rf::Frequency min{}; + rf::Frequency max{}; + std::string label{}; + }; - RFAmpField field_rf_amp{ - {29 * 8, 1 * 16}}; + std::vector presets_db{}; - OptionsField range_presets{ - {7 * 8, 2 * 16}, - 20, - { - {" NONE (WIFI 2.4GHz)", 0}, - }}; + void on_channel_spectrum(const ChannelSpectrum& spectrum); + void do_timers(); + void on_range_changed(); + void on_lna_changed(int32_t v_db); + void on_vga_changed(int32_t v_db); + void add_spectrum_pixel(Color color); + void PlotMarker(rf::Frequency pos); + void load_Presets(); + void txtline_process(std::string& line); + void populate_Presets(); + void presets_Default(); - NumberField field_marker{ - {7 * 8, 3 * 16}, - 4, - {0, 7200}, - 25, - ' '}; + rf::Frequency f_min { 0 }, f_max { 0 }; + rf::Frequency search_span { 0 }; + rf::Frequency f_center { 0 }; + rf::Frequency f_center_ini { 0 }; + rf::Frequency marker_pixel_step { 0 }; + rf::Frequency each_bin_size { LOOKING_GLASS_SLICE_WIDTH / 240 }; + rf::Frequency bins_Hz_size { 0 }; + uint8_t min_color_power { 0 }; + uint32_t pixel_index { 0 }; + std::array spectrum_row = { 0 }; + ChannelSpectrumFIFO* fifo { nullptr }; + uint8_t max_power = 0; + int32_t steps = 250 ; // default of 250 Mhz steps - Text text_marker_pm{ - {20 * 8, 3 * 16, 2 * 8, 16}, - ""}; + Labels labels{ + {{0, 0}, "MIN: MAX: LNA VGA ", Color::light_grey()}, + {{0, 1 * 16}, " RANGE: FILTER: AMP:", Color::light_grey()}, + {{0, 2 * 16}, "PRESET:", Color::light_grey()}, + {{0, 3 * 16}, "MARKER: MHz +/- MHz", Color::light_grey()}, + {{0, 4 * 16}, "RESOLUTION: STEPS:", Color::light_grey()} + }; - NumberField field_trigger{ - {11 * 8, 4 * 16}, - 3, - {2, 128}, - 2, - ' '}; + NumberField field_frequency_min { + { 4 * 8, 0 * 16 }, + 4, + { 0, 7199 }, + 1, // number of steps by encoder delta + ' ' + }; + + NumberField field_frequency_max { + { 13 * 8, 0 * 16 }, + 4, + { 1, 7200 }, + 1, // number of steps by encoder delta + ' ' + }; + + LNAGainField field_lna { + { 21 * 8, 0 * 16 } + }; + + VGAGainField field_vga { + { 27 * 8, 0 * 16 } + }; + + Text text_range{ + {7 * 8, 1 * 16, 4 * 8, 16}, + ""}; + + OptionsField steps_config{ + { 22 * 8, 4 * 16}, + 4, + { + {"1", 1}, + {"50", 50}, + {"100", 100}, + {"250", 250}, + {"500", 500}, + {"1000", 1000}, + }}; + + OptionsField filter_config{ + {19 * 8, 1 * 16}, + 4, + { + {"OFF ", 0}, + {"MID ", 118}, //85 +25 (110) + a bit more to kill all blue + {"HIGH", 202}, //168 + 25 (193) + }}; + + RFAmpField field_rf_amp{ + {29 * 8, 1 * 16}}; + + OptionsField range_presets{ + {7 * 8, 2 * 16}, + 20, + { + {" NONE (WIFI 2.4GHz)", 0}, + }}; + + NumberField field_marker{ + {7 * 8, 3 * 16}, + 4, + {0, 7200}, + 25, + ' '}; + + Text text_marker_pm{ + {20 * 8, 3 * 16, 2 * 8, 16}, + ""}; + + NumberField field_trigger{ + {11 * 8, 4 * 16}, + 3, + {2, 128}, + 2, + ' '}; - MessageHandlerRegistration message_handler_spectrum_config { - Message::ID::ChannelSpectrumConfig, - [this](const Message* const p) { - const auto message = *reinterpret_cast(p); - this->fifo = message.fifo; - } - }; - MessageHandlerRegistration message_handler_frame_sync { - Message::ID::DisplayFrameSync, - [this](const Message* const) { - if( this->fifo ) { - ChannelSpectrum channel_spectrum; - while( fifo->out(channel_spectrum) ) { - this->on_channel_spectrum(channel_spectrum); - } - } - } - }; - - }; - } + MessageHandlerRegistration message_handler_spectrum_config { + Message::ID::ChannelSpectrumConfig, + [this](const Message* const p) { + const auto message = *reinterpret_cast(p); + this->fifo = message.fifo; + } + }; + MessageHandlerRegistration message_handler_frame_sync { + Message::ID::DisplayFrameSync, + [this](const Message* const) { + if( this->fifo ) { + ChannelSpectrum channel_spectrum; + while( fifo->out(channel_spectrum) ) { + this->on_channel_spectrum(channel_spectrum); + } + } + } + }; + }; +} #endif diff --git a/firmware/application/ui/ui_rssi.cpp b/firmware/application/ui/ui_rssi.cpp index 8721c715..fc22019e 100644 --- a/firmware/application/ui/ui_rssi.cpp +++ b/firmware/application/ui/ui_rssi.cpp @@ -57,12 +57,12 @@ namespace ui { { // horizontal left to right level meters const range_t x_avg_range { 0, r.width() - 1 }; - const auto x_avg = x_avg_range.clip((avg_ - raw_min) * r.width() / raw_delta); + const int16_t x_avg = x_avg_range.clip((avg_ - raw_min) * r.width() / raw_delta); const range_t x_min_range { 0, x_avg }; - const auto x_min = x_min_range.clip((min_ - raw_min) * r.width() / raw_delta); + const int16_t x_min = x_min_range.clip((min_ - raw_min) * r.width() / raw_delta); const range_t x_max_range { x_avg + 1, r.width() - 1 }; - const auto x_max = x_max_range.clip((max_ - raw_min) * r.width() / raw_delta); - const auto peak = x_max_range.clip((peak_ - raw_min) * r.width() / raw_delta); + const int16_t x_max = x_max_range.clip((max_ - raw_min) * r.width() / raw_delta); + const int16_t peak = x_max_range.clip((peak_ - raw_min) * r.width() / raw_delta); // x_min const Rect r0 { r.left(), r.top(), x_min, r.height() }; @@ -113,13 +113,13 @@ namespace ui { { // vertical bottom to top level meters const range_t y_avg_range { 0, r.height() - 1 }; - const auto y_avg = y_avg_range.clip((avg_ - raw_min) * r.height() / raw_delta); + const int16_t y_avg = y_avg_range.clip((avg_ - raw_min) * r.height() / raw_delta); const range_t y_min_range { 0, y_avg }; - const auto y_min = y_min_range.clip((min_ - raw_min) * r.height() / raw_delta); + const int16_t y_min = y_min_range.clip((min_ - raw_min) * r.height() / raw_delta); const range_t y_max_range { y_avg + 1, r.height() - 1 }; - const auto y_max = y_max_range.clip((max_ - raw_min) * r.height() / raw_delta); + const int16_t y_max = y_max_range.clip((max_ - raw_min) * r.height() / raw_delta); const range_t peak_range { 0, r.height() - 1 }; - const auto peak = peak_range.clip((peak_ - raw_min) * r.height() / raw_delta); + const int16_t peak = peak_range.clip((peak_ - raw_min) * r.height() / raw_delta); // y_min const Rect r0 { r.left(), r.bottom() - y_min, r.width() , y_min }; @@ -180,22 +180,22 @@ namespace ui { } } - int32_t RSSI::get_min() + int16_t RSSI::get_min() { return min_ ; } - int32_t RSSI::get_avg() + int16_t RSSI::get_avg() { return avg_ ; } - int32_t RSSI::get_max() + int16_t RSSI::get_max() { return max_ ; } - int32_t RSSI::get_delta() + int16_t RSSI::get_delta() { return max_ - min_ ; } @@ -241,27 +241,32 @@ namespace ui { void RSSIGraph::paint(Painter& painter) { const auto r = screen_rect(); + int16_t size = r.width() / nb_columns ; + int16_t top_y_val = 0 ; + int16_t width_y = 0 ; + if( size < 1 ) + size = 1 ; + + int xpos = r.right() ; for ( int n = 2 ; (unsigned)n <= graph_list.size(); n++) { auto& entry = graph_list[graph_list.size()-n]; auto& prev_entry = graph_list[graph_list.size()-(n-1)]; // black - const Point p0{ r.right() - n , r.top() }; - painter.draw_vline( - p0, - r.height(), - Color::black()); + const Rect r0{ xpos - size , r.top() , size , r.height() }; + painter.fill_rectangle( + r0, + Color::black()); // y_max - int32_t top_y_val = max( entry.rssi_max , prev_entry.rssi_max ); - int32_t width_y = abs( entry.rssi_max - prev_entry.rssi_max ); + top_y_val = max( entry.rssi_max , prev_entry.rssi_max ); + width_y = abs( entry.rssi_max - prev_entry.rssi_max ); if( width_y == 0 ) width_y = 1 ; - const Point p1{ r.right() - n , r.bottom() - top_y_val }; - painter.draw_vline( - p1, - width_y, + const Rect r1{ xpos - size , r.bottom() - top_y_val , size , width_y }; + painter.fill_rectangle( + r1, Color::red()); // y_avg @@ -269,10 +274,9 @@ namespace ui { width_y = abs( entry.rssi_avg - prev_entry.rssi_avg ); if( width_y == 0 ) width_y = 1 ; - const Point p2{ r.right() - n , r.bottom() - top_y_val }; - painter.draw_vline( - p2, - width_y, + const Rect r2{ xpos - size , r.bottom() - top_y_val , size , width_y }; + painter.fill_rectangle( + r2, Color::white()); // y_min @@ -280,10 +284,9 @@ namespace ui { width_y = abs( entry.rssi_min - prev_entry.rssi_min ); if( width_y == 0 ) width_y = 1 ; - const Point p3{ r.right() - n , r.bottom() - top_y_val }; - painter.draw_vline( - p3, - width_y, + const Rect r3{ xpos - size , r.bottom() - top_y_val , size , width_y }; + painter.fill_rectangle( + r3, Color::blue()); // hack to display db @@ -291,15 +294,22 @@ namespace ui { width_y = abs( entry.db - prev_entry.db ); if( width_y == 0 ) width_y = 1 ; - const Point p4{ r.right() - n , r.bottom() - top_y_val }; - painter.draw_vline( - p4, - width_y, - Color::green() ); + const Rect r4{ xpos - size , r.bottom() - top_y_val , size , width_y }; + painter.fill_rectangle( + r4, + Color::green()); + xpos = xpos - size ; + } + if( xpos > r.left() ) + { + const Rect r5{ r.left() , r.top() , xpos - r.left() , r.height() }; + painter.fill_rectangle( + r5, + Color::black()); } } - void RSSIGraph::add_values(int32_t rssi_min, int32_t rssi_avg, int32_t rssi_max, int32_t db ) + void RSSIGraph::add_values(int16_t rssi_min, int16_t rssi_avg, int16_t rssi_max, int16_t db ) { const auto r = screen_rect(); @@ -314,25 +324,30 @@ namespace ui { // vertical bottom to top level meters const range_t y_avg_range { 0, r.height() - 1 }; - const auto y_avg = y_avg_range.clip((rssi_avg - raw_min) * r.height() / raw_delta); + const int16_t y_avg = y_avg_range.clip((rssi_avg - raw_min) * r.height() / raw_delta); const range_t y_min_range { 0, y_avg }; - const auto y_min = y_min_range.clip((rssi_min - raw_min) * r.height() / raw_delta); + const int16_t y_min = y_min_range.clip((rssi_min - raw_min) * r.height() / raw_delta); const range_t y_max_range { y_avg + 1, r.height() - 1 }; - const auto y_max = y_max_range.clip((rssi_max - raw_min) * r.height() / raw_delta); - const range_t db_range { -100 , 20 }; - auto db_ = db_range.clip( db ); - db_ = db_ - 20 ; - db_ = db_ * r.height() / 120 ; + const int16_t y_max = y_max_range.clip((rssi_max - raw_min) * r.height() / raw_delta); + const range_t db_range { -80 , 10 }; + int16_t db_ = db_range.clip( db ); + db_ = db_ - 10 ; + db_ = db_ * r.height() / 90 ; db_ = r.height() + db_ ; graph_list . push_back( { y_min, y_avg, y_max , db_ } ); - if( graph_list.size() > (unsigned)r.width() ) + while( graph_list.size() > nb_columns ) { graph_list.erase( graph_list.begin() ); } set_dirty(); } + void RSSIGraph::set_nb_columns( int16_t nb ) + { + nb_columns = nb ; + } + void RSSI::on_focus() { if( on_highlight ) on_highlight(*this); diff --git a/firmware/application/ui/ui_rssi.hpp b/firmware/application/ui/ui_rssi.hpp index d4adf6ce..b9f35717 100644 --- a/firmware/application/ui/ui_rssi.hpp +++ b/firmware/application/ui/ui_rssi.hpp @@ -51,10 +51,10 @@ namespace ui { { } - int32_t get_min(); - int32_t get_avg(); - int32_t get_max(); - int32_t get_delta(); + int16_t get_min(); + int16_t get_avg(); + int16_t get_max(); + int16_t get_delta(); void set_vertical_rssi(bool enabled); void set_peak(bool enabled, size_t duration); @@ -64,10 +64,10 @@ namespace ui { bool on_touch(const TouchEvent event) override; private: - int32_t min_ = 0; - int32_t avg_ = 0; - int32_t max_ = 0; - int32_t peak_ = 0 ; + int16_t min_ = 0; + int16_t avg_ = 0; + int16_t max_ = 0; + int16_t peak_ = 0 ; size_t peak_duration_ = 0 ; bool instant_exec_ { false }; @@ -97,10 +97,10 @@ namespace ui { }; struct RSSIGraph_entry { - int32_t rssi_min { 0 }; - int32_t rssi_avg { 0 }; - int32_t rssi_max { 0 }; - int32_t db { 0 }; + int16_t rssi_min { 0 }; + int16_t rssi_avg { 0 }; + int16_t rssi_max { 0 }; + int16_t db { 0 }; }; using RSSIGraphList = std::vector; @@ -113,9 +113,11 @@ namespace ui { { } void paint(Painter& painter) override; - void add_values(int32_t rssi_min, int32_t rssi_avg, int32_t rssi_max, int32_t db ); + void add_values(int16_t rssi_min, int16_t rssi_avg, int16_t rssi_max, int16_t db ); + void set_nb_columns( int16_t nb ); private: + uint16_t nb_columns = 16 ; RSSIGraphList graph_list { } ; };