From dbdb0bd3793dfa34fb6b0a48fa5550eadddf0952 Mon Sep 17 00:00:00 2001 From: Rascafr Date: Fri, 11 Sep 2020 21:11:42 +0200 Subject: [PATCH 01/18] Added ui_scanner load button for any .txt frequency file --- firmware/application/apps/ui_scanner.cpp | 58 +++++++++++++++++++----- firmware/application/apps/ui_scanner.hpp | 6 +++ 2 files changed, 53 insertions(+), 11 deletions(-) diff --git a/firmware/application/apps/ui_scanner.cpp b/firmware/application/apps/ui_scanner.cpp index 65c4788d..3024901d 100644 --- a/firmware/application/apps/ui_scanner.cpp +++ b/firmware/application/apps/ui_scanner.cpp @@ -21,6 +21,7 @@ */ #include "ui_scanner.hpp" +#include "ui_fileman.hpp" using namespace portapack; @@ -182,6 +183,7 @@ ScannerView::ScannerView( &field_bw, &field_squelch, &field_wait, + &button_load, &rssi, &text_cycle, &text_max, @@ -211,6 +213,26 @@ ScannerView::ScannerView( frequency_range.max = stored_freq + 1000000; button_manual_end.set_text(to_string_short_freq(frequency_range.max)); + button_load.on_select = [this, &nav](Button&) { + // load txt files from the FREQMAN folder + auto open_view = nav.push(".TXT"); + open_view->on_changed = [this](std::filesystem::path new_file_path) { + + std::string dir_filter = "FREQMAN/"; + std::string str_file_path = new_file_path.string(); + + if (str_file_path.find(dir_filter) != string::npos) { // assert file from the FREQMAN folder + scan_pause(); + // get the filename without txt extension so we can use load_freqman_file fcn + std::string str_file_name = new_file_path.stem().string(); + frequency_file_load(str_file_name, true); + nav_.display_modal("LOAD FREQ FILE", "Successfully loaded:\n" + str_file_name + ".TXT"); + } else { + nav_.display_modal("LOAD ERROR", "A valid file from\nFREQMAN directory is\nrequired."); + } + }; + }; + button_manual_start.on_select = [this, &nav](Button& button) { auto new_view = nav_.push(frequency_range.min); new_view->on_changed = [this, &button](rf::Frequency f) { @@ -357,22 +379,36 @@ ScannerView::ScannerView( field_squelch.on_change = [this](int32_t v) { squelch = v; }; field_squelch.set_value(-10); field_volume.set_value((receiver_model.headphone_volume() - audio::headphone::volume_range().max).decibel() + 99); field_volume.on_change = [this](int32_t v) { this->on_headphone_volume_changed(v); }; + // LEARN FREQUENCIES std::string scanner_txt = "SCANNER"; - if ( load_freqman_file(scanner_txt, database) ) { + frequency_file_load(scanner_txt); +} + +void ScannerView::frequency_file_load(std::string file_name, bool stop_all_before) { + + // stop everything running now if required + if (stop_all_before) { + scan_thread->stop(); + frequency_list.clear(); // clear the existing frequency list (expected behavior) + description_list.clear(); + def_step = step_mode.selected_index_value(); //Use def_step from manual selector + } + + if ( load_freqman_file(file_name, database) ) { for(auto& entry : database) { // READ LINE PER LINE if (frequency_list.size() < MAX_DB_ENTRY) { //We got space! if (entry.type == RANGE) { //RANGE switch (entry.step) { - case AM_US: def_step = 10000; break ; - case AM_EUR:def_step = 9000; break ; - case NFM_1: def_step = 12500; break ; - case NFM_2: def_step = 6250; break ; - case FM_1: def_step = 100000; break ; - case FM_2: def_step = 50000; break ; - case N_1: def_step = 25000; break ; - case N_2: def_step = 250000; break ; - case AIRBAND:def_step= 8330; break ; + case AM_US: def_step = 10000; break ; + case AM_EUR:def_step = 9000; break ; + case NFM_1: def_step = 12500; break ; + case NFM_2: def_step = 6250; break ; + case FM_1: def_step = 100000; break ; + case FM_2: def_step = 50000; break ; + case N_1: def_step = 25000; break ; + case N_2: def_step = 250000; break ; + case AIRBAND:def_step= 8330; break ; } frequency_list.push_back(entry.frequency_a); //Store starting freq and description description_list.push_back("R:" + to_string_short_freq(entry.frequency_a) @@ -397,7 +433,7 @@ ScannerView::ScannerView( } else { - desc_cycle.set(" NO SCANNER.TXT FILE ..." ); + desc_cycle.set(" NO " + file_name + ".TXT FILE ..." ); } audio::output::stop(); step_mode.set_by_value(def_step); //Impose the default step into the manual step selector diff --git a/firmware/application/apps/ui_scanner.hpp b/firmware/application/apps/ui_scanner.hpp index d2befbfe..e637d71d 100644 --- a/firmware/application/apps/ui_scanner.hpp +++ b/firmware/application/apps/ui_scanner.hpp @@ -126,6 +126,7 @@ private: void scan_pause(); void scan_resume(); void user_resume(); + void frequency_file_load(std::string file_name, bool stop_all_before = false); void on_statistics_update(const ChannelStatistics& statistics); void on_headphone_volume_changed(int32_t v); @@ -278,6 +279,11 @@ private: "ADD FQ" }; + Button button_load { + { 24 * 8, 3 * 16 - 8, 6 * 8, 22 }, + "Load" + }; + Button button_remove { { 168, (35 * 8) - 4, 72, 28 }, "DEL FQ" From d2c66f4515ef6d6a7db98d8afacf1e865fef09a5 Mon Sep 17 00:00:00 2001 From: Rascafr Date: Fri, 11 Sep 2020 22:07:12 +0200 Subject: [PATCH 02/18] Removed confirmation modal after load is successful --- firmware/application/apps/ui_scanner.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/firmware/application/apps/ui_scanner.cpp b/firmware/application/apps/ui_scanner.cpp index 3024901d..7399a78f 100644 --- a/firmware/application/apps/ui_scanner.cpp +++ b/firmware/application/apps/ui_scanner.cpp @@ -226,7 +226,6 @@ ScannerView::ScannerView( // get the filename without txt extension so we can use load_freqman_file fcn std::string str_file_name = new_file_path.stem().string(); frequency_file_load(str_file_name, true); - nav_.display_modal("LOAD FREQ FILE", "Successfully loaded:\n" + str_file_name + ".TXT"); } else { nav_.display_modal("LOAD ERROR", "A valid file from\nFREQMAN directory is\nrequired."); } From 200c57f990e9b40073aedd7c9c40d4588446d13f Mon Sep 17 00:00:00 2001 From: Rascafr Date: Fri, 11 Sep 2020 22:15:35 +0200 Subject: [PATCH 03/18] Save new frequencies into the default / user loaded freqman txt file --- firmware/application/apps/ui_scanner.cpp | 9 ++++++--- firmware/application/apps/ui_scanner.hpp | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/firmware/application/apps/ui_scanner.cpp b/firmware/application/apps/ui_scanner.cpp index 7399a78f..1b8d2698 100644 --- a/firmware/application/apps/ui_scanner.cpp +++ b/firmware/application/apps/ui_scanner.cpp @@ -335,7 +335,8 @@ ScannerView::ScannerView( button_add.on_select = [this](Button&) { //frequency_list[current_index] File scanner_file; - auto result = scanner_file.open("FREQMAN/SCANNER.TXT"); //First search if freq is already in txt + std::string freq_file_path = "FREQMAN/" + loaded_file_name + ".TXT"; + auto result = scanner_file.open(freq_file_path); //First search if freq is already in txt if (!result.is_valid()) { std::string frequency_to_add = "f=" + to_string_dec_uint(frequency_list[current_index] / 1000) @@ -363,12 +364,12 @@ ScannerView::ScannerView( big_display.set(frequency_list[current_index]); //After showing an error } else { - auto result = scanner_file.append("FREQMAN/SCANNER.TXT"); //Second: append if it is not there + auto result = scanner_file.append(freq_file_path); //Second: append if it is not there scanner_file.write_line(frequency_to_add + ",d=ADD FQ"); } } else { - nav_.display_modal("Error", "Cannot open SCANNER.TXT\nfor appending freq."); + nav_.display_modal("Error", "Cannot open " + loaded_file_name + ".TXT\nfor appending freq."); big_display.set(frequency_list[current_index]); //After showing an error } }; @@ -386,6 +387,8 @@ ScannerView::ScannerView( void ScannerView::frequency_file_load(std::string file_name, bool stop_all_before) { + loaded_file_name = file_name; // keep loaded filename in memory + // stop everything running now if required if (stop_all_before) { scan_thread->stop(); diff --git a/firmware/application/apps/ui_scanner.hpp b/firmware/application/apps/ui_scanner.hpp index e637d71d..264a7f7c 100644 --- a/firmware/application/apps/ui_scanner.hpp +++ b/firmware/application/apps/ui_scanner.hpp @@ -138,6 +138,7 @@ private: uint32_t wait { 0 }; size_t def_step { 0 }; freqman_db database { }; + std::string loaded_file_name; uint32_t current_index { 0 }; bool userpause { false }; From f95467d71b74169718b2cf5df160974c32749f30 Mon Sep 17 00:00:00 2001 From: Rascafr Date: Fri, 11 Sep 2020 22:17:40 +0200 Subject: [PATCH 04/18] loaded_file_name goes back to default 'scanner' file if load step fails --- firmware/application/apps/ui_scanner.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/application/apps/ui_scanner.cpp b/firmware/application/apps/ui_scanner.cpp index 1b8d2698..754853a2 100644 --- a/firmware/application/apps/ui_scanner.cpp +++ b/firmware/application/apps/ui_scanner.cpp @@ -387,8 +387,6 @@ ScannerView::ScannerView( void ScannerView::frequency_file_load(std::string file_name, bool stop_all_before) { - loaded_file_name = file_name; // keep loaded filename in memory - // stop everything running now if required if (stop_all_before) { scan_thread->stop(); @@ -398,6 +396,7 @@ void ScannerView::frequency_file_load(std::string file_name, bool stop_all_befor } if ( load_freqman_file(file_name, database) ) { + loaded_file_name = file_name; // keep loaded filename in memory for(auto& entry : database) { // READ LINE PER LINE if (frequency_list.size() < MAX_DB_ENTRY) { //We got space! if (entry.type == RANGE) { //RANGE @@ -435,6 +434,7 @@ void ScannerView::frequency_file_load(std::string file_name, bool stop_all_befor } else { + loaded_file_name = 'SCANNER'; // back to the default frequency file desc_cycle.set(" NO " + file_name + ".TXT FILE ..." ); } audio::output::stop(); From b15b78103938628fd01918c9cdf6012b73973688 Mon Sep 17 00:00:00 2001 From: dqs105 Date: Wed, 16 Sep 2020 19:27:56 +0800 Subject: [PATCH 05/18] Added options for enabling CLKOUT. - CLKOUT can be enabled in Radio settings and status bar. - Fixed a typo(I believe) in ui_navigation. --- firmware/application/apps/ui_settings.cpp | 9 ++++++ firmware/application/apps/ui_settings.hpp | 12 +++++-- firmware/application/clock_manager.cpp | 14 +++++++++ firmware/application/clock_manager.hpp | 2 ++ firmware/application/ui_navigation.cpp | 31 ++++++++++++++++--- firmware/application/ui_navigation.hpp | 3 +- .../common/portapack_persistent_memory.cpp | 15 +++++++++ .../common/portapack_persistent_memory.hpp | 3 ++ 8 files changed, 80 insertions(+), 9 deletions(-) diff --git a/firmware/application/apps/ui_settings.cpp b/firmware/application/apps/ui_settings.cpp index 3f5708b3..3d919bbe 100644 --- a/firmware/application/apps/ui_settings.cpp +++ b/firmware/application/apps/ui_settings.cpp @@ -144,6 +144,7 @@ SetRadioView::SetRadioView( } add_children({ + &check_clkout, &labels_bias, &check_bias, &button_done, @@ -156,6 +157,14 @@ SetRadioView::SetRadioView( form_init(model); + check_clkout.set_value(portapack::persistent_memory::clkout_enabled()); + check_clkout.on_select = [this](Checkbox&, bool v) { + clock_manager.enable_clock_output(v); + portapack::persistent_memory::set_clkout_enabled(v); + StatusRefreshMessage message { }; + EventDispatcher::send_message(message); + }; + check_bias.set_value(portapack::get_antenna_bias()); check_bias.on_select = [this](Checkbox&, bool v) { portapack::set_antenna_bias(v); diff --git a/firmware/application/apps/ui_settings.hpp b/firmware/application/apps/ui_settings.hpp index 076ede03..4b9f99d4 100644 --- a/firmware/application/apps/ui_settings.hpp +++ b/firmware/application/apps/ui_settings.hpp @@ -147,8 +147,14 @@ private: }; Labels labels_correction { - { { 2 * 8, 4 * 16 }, "Frequency correction:", Color::light_grey() }, - { { 6 * 8, 5 * 16 }, "PPM", Color::light_grey() }, + { { 2 * 8, 3 * 16 }, "Frequency correction:", Color::light_grey() }, + { { 6 * 8, 4 * 16 }, "PPM", Color::light_grey() }, + }; + + Checkbox check_clkout { + { 28, (6 * 16 - 4) }, + 4, + "Enable 10MHz CLKOUT" }; Labels labels_bias { @@ -159,7 +165,7 @@ private: }; NumberField field_ppm { - { 2 * 8, 5 * 16 }, + { 2 * 8, 4 * 16 }, 3, { -50, 50 }, 1, diff --git a/firmware/application/clock_manager.cpp b/firmware/application/clock_manager.cpp index 088cf17f..ec08452b 100644 --- a/firmware/application/clock_manager.cpp +++ b/firmware/application/clock_manager.cpp @@ -463,3 +463,17 @@ void ClockManager::stop_audio_pll() { cgu::pll0audio::power_down(); while( cgu::pll0audio::is_locked() ); } + +void ClockManager::enable_clock_output(bool enable) { + if(enable) { + clock_generator.enable_output(clock_generator_output_clkout); + clock_generator.set_ms_frequency(clock_generator_output_clkout, 10000000, si5351_vco_f, 0); + } else { + clock_generator.disable_output(clock_generator_output_clkout); + } + + if(enable) + clock_generator.set_clock_control(clock_generator_output_clkout, si5351_clock_control_common[clock_generator_output_clkout].ms_src(get_reference_clock_generator_pll(reference.source)).clk_pdn(ClockControl::ClockPowerDown::Power_On)); + else + clock_generator.set_clock_control(clock_generator_output_clkout, ClockControl::power_off()); +} diff --git a/firmware/application/clock_manager.hpp b/firmware/application/clock_manager.hpp index 98af620a..0c88bab5 100644 --- a/firmware/application/clock_manager.hpp +++ b/firmware/application/clock_manager.hpp @@ -79,6 +79,8 @@ public: Reference get_reference() const; + void enable_clock_output(bool enable); + private: I2C& i2c0; si5351::Si5351& clock_generator; diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp index ca6a6334..57ffd403 100644 --- a/firmware/application/ui_navigation.cpp +++ b/firmware/application/ui_navigation.cpp @@ -113,7 +113,7 @@ SystemStatusView::SystemStatusView( &button_camera, &button_sleep, &button_bias_tee, - &image_clock_status, + &button_clock_status, &sd_card_status_view, }); @@ -168,6 +168,10 @@ SystemStatusView::SystemStatusView( DisplaySleepMessage message; EventDispatcher::send_message(message); }; + + button_clock_status.on_select = [this](ImageButton&) { + this->on_clk(); + }; } void SystemStatusView::refresh() { @@ -188,11 +192,16 @@ void SystemStatusView::refresh() { } if (portapack::clock_manager.get_reference().source == ClockManager::ReferenceSource::External) { - image_clock_status.set_bitmap(&bitmap_icon_clk_ext); - button_bias_tee.set_foreground(ui::Color::green()); + button_clock_status.set_bitmap(&bitmap_icon_clk_ext); +// button_bias_tee.set_foreground(ui::Color::green()); Typo? } else { - image_clock_status.set_bitmap(&bitmap_icon_clk_int); - button_bias_tee.set_foreground(ui::Color::light_grey()); + button_clock_status.set_bitmap(&bitmap_icon_clk_int); +// button_bias_tee.set_foreground(ui::Color::green()); + } + if(portapack::persistent_memory::clkout_enabled()) { + button_clock_status.set_foreground(ui::Color::green()); + } else { + button_clock_status.set_foreground(ui::Color::light_grey()); } set_dirty(); @@ -302,6 +311,18 @@ void SystemStatusView::on_camera() { } } +void SystemStatusView::on_clk() { + bool v = portapack::persistent_memory::clkout_enabled(); + if(v) { + v = false; + } else { + v = true; + } + portapack::clock_manager.enable_clock_output(v); + portapack::persistent_memory::set_clkout_enabled(v); + refresh(); +} + void SystemStatusView::on_title() { if(nav_.is_top()) nav_.push(); diff --git a/firmware/application/ui_navigation.hpp b/firmware/application/ui_navigation.hpp index 7edf6a9d..1537ce4e 100644 --- a/firmware/application/ui_navigation.hpp +++ b/firmware/application/ui_navigation.hpp @@ -180,7 +180,7 @@ private: Color::dark_grey() }; - Image image_clock_status { + ImageButton button_clock_status { { 27 * 8, 0 * 16, 2 * 8, 1 * 16 }, &bitmap_icon_clk_int, Color::light_grey(), @@ -198,6 +198,7 @@ private: void on_camera(); void on_title(); void refresh(); + void on_clk(); MessageHandlerRegistration message_handler_refresh { Message::ID::StatusRefresh, diff --git a/firmware/common/portapack_persistent_memory.cpp b/firmware/common/portapack_persistent_memory.cpp index 1ee81ffa..97b9e006 100644 --- a/firmware/common/portapack_persistent_memory.cpp +++ b/firmware/common/portapack_persistent_memory.cpp @@ -63,6 +63,10 @@ using modem_repeat_range_t = range_t; constexpr modem_repeat_range_t modem_repeat_range { 1, 99 }; constexpr int32_t modem_repeat_reset_value { 5 }; +using clkout_config_range_t = range_t; +constexpr clkout_config_range_t clkout_config_range { 0, 1 }; +constexpr uint32_t clkout_config_reset_value { 0 }; + /* struct must pack the same way on M4 and M0 cores. */ struct data_t { int64_t tuned_frequency; @@ -91,6 +95,8 @@ struct data_t { uint32_t pocsag_ignore_address; int32_t tone_mix; + + uint32_t clkout_config; // TODO: Add custom frequency output? }; static_assert(sizeof(data_t) <= backup_ram.size(), "Persistent memory structure too large for VBAT-maintained region"); @@ -287,5 +293,14 @@ void set_pocsag_ignore_address(uint32_t address) { data->pocsag_ignore_address = address; } +bool clkout_enabled() { + clkout_config_range.reset_if_outside(data->clkout_config, clkout_config_reset_value); + return (bool)(data->clkout_config & 1); +} + +void set_clkout_enabled(bool enable) { + data->clkout_config = (uint32_t)enable; +} + } /* namespace persistent_memory */ } /* namespace portapack */ diff --git a/firmware/common/portapack_persistent_memory.hpp b/firmware/common/portapack_persistent_memory.hpp index be740edb..6422567a 100644 --- a/firmware/common/portapack_persistent_memory.hpp +++ b/firmware/common/portapack_persistent_memory.hpp @@ -93,6 +93,9 @@ void set_pocsag_last_address(uint32_t address); uint32_t pocsag_ignore_address(); void set_pocsag_ignore_address(uint32_t address); +bool clkout_enabled(); +void set_clkout_enabled(bool enable); + } /* namespace persistent_memory */ } /* namespace portapack */ From 66a841e079f268c2cfa8d47899d2a7e92b31cace Mon Sep 17 00:00:00 2001 From: dqs105 Date: Thu, 17 Sep 2020 12:47:34 +0800 Subject: [PATCH 06/18] combine clkout_config => ui_config --- firmware/common/portapack_persistent_memory.cpp | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/firmware/common/portapack_persistent_memory.cpp b/firmware/common/portapack_persistent_memory.cpp index 97b9e006..e7fcbba6 100644 --- a/firmware/common/portapack_persistent_memory.cpp +++ b/firmware/common/portapack_persistent_memory.cpp @@ -63,10 +63,6 @@ using modem_repeat_range_t = range_t; constexpr modem_repeat_range_t modem_repeat_range { 1, 99 }; constexpr int32_t modem_repeat_reset_value { 5 }; -using clkout_config_range_t = range_t; -constexpr clkout_config_range_t clkout_config_range { 0, 1 }; -constexpr uint32_t clkout_config_reset_value { 0 }; - /* struct must pack the same way on M4 and M0 cores. */ struct data_t { int64_t tuned_frequency; @@ -89,14 +85,12 @@ struct data_t { uint32_t playdead_sequence; // UI - uint32_t ui_config; + uint32_t ui_config; uint32_t pocsag_last_address; uint32_t pocsag_ignore_address; int32_t tone_mix; - - uint32_t clkout_config; // TODO: Add custom frequency output? }; static_assert(sizeof(data_t) <= backup_ram.size(), "Persistent memory structure too large for VBAT-maintained region"); @@ -294,12 +288,11 @@ void set_pocsag_ignore_address(uint32_t address) { } bool clkout_enabled() { - clkout_config_range.reset_if_outside(data->clkout_config, clkout_config_reset_value); - return (bool)(data->clkout_config & 1); + return (data->ui_config & 0x08000000UL); } void set_clkout_enabled(bool enable) { - data->clkout_config = (uint32_t)enable; + data->ui_config = (data->ui_config & ~0x08000000UL) | (enable << 27); } } /* namespace persistent_memory */ From b22448de7547bd46c06b6f746a0e52bd1b7c9f02 Mon Sep 17 00:00:00 2001 From: euquiq <31453004+euquiq@users.noreply.github.com> Date: Mon, 28 Sep 2020 17:54:27 -0300 Subject: [PATCH 07/18] Fixes SSID value error on APX TX Values where left bit-shifted upon being entered by the user, so resulting SSID being transmitted was a different number. This shifting was happening both on Source and Destination SSID values. --- firmware/application/apps/ui_aprs_tx.hpp | 1 + firmware/application/protocols/aprs.cpp | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/firmware/application/apps/ui_aprs_tx.hpp b/firmware/application/apps/ui_aprs_tx.hpp index 173d9fd7..97032107 100644 --- a/firmware/application/apps/ui_aprs_tx.hpp +++ b/firmware/application/apps/ui_aprs_tx.hpp @@ -82,6 +82,7 @@ private: 6, SymField::SYMFIELD_ALPHANUM }; + NumberField num_ssid_dest { { 19 * 8, 2 * 16 }, 2, diff --git a/firmware/application/protocols/aprs.cpp b/firmware/application/protocols/aprs.cpp index 96cf8df6..6caab866 100644 --- a/firmware/application/protocols/aprs.cpp +++ b/firmware/application/protocols/aprs.cpp @@ -38,9 +38,9 @@ void make_aprs_frame(const char * src_address, const uint32_t src_ssid, char address[14] = { 0 }; memcpy(&address[0], dest_address, 6); - address[6] = (dest_ssid & 15) << 1; + address[6] = (dest_ssid & 15); memcpy(&address[7], src_address, 6); - address[13] = (src_ssid & 15) << 1; + address[13] = (src_ssid & 15); frame.make_ui_frame(address, 0x03, protocol_id_t::NO_LAYER3, payload); } From 3419ece6829360322c1f3d85354b51adfb04c6a7 Mon Sep 17 00:00:00 2001 From: AD5NL Date: Fri, 2 Oct 2020 16:47:04 -0500 Subject: [PATCH 08/18] Create TIMEFREQ.TXT HF Time and frequency standard stations --- sdcard/FREQMAN/TIMEFREQ.TXT | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 sdcard/FREQMAN/TIMEFREQ.TXT diff --git a/sdcard/FREQMAN/TIMEFREQ.TXT b/sdcard/FREQMAN/TIMEFREQ.TXT new file mode 100644 index 00000000..923fb782 --- /dev/null +++ b/sdcard/FREQMAN/TIMEFREQ.TXT @@ -0,0 +1,14 @@ +f=2500000,d=WWV/BPM 2 MHz +f=5000000,d=WWV/BPM 5 MHz +f=10000000,d=WWV/BPM 10 MHz +f=15000000,d=WWV/BPM 15 MHz +f=20000000,d=WWV 20 MHz +f=3300000,d=CHU 3 MHz +f=7850000,d=CHU 7 MHz +f=14670000,d=CHU 14 MHz +f=3810000,d=HD2IOA 3 MHz +f=4996000,d=RWM 4 MHz +f=9996000,d=RWM 9 MHz +f=14996000,d=RWM 14 MHz +f=4998000,d=EBC 4 MHz +f=15006000,d=EBC 15 MHz From 95f7eda9c536d90601056689cacbc6c6340a8ddc Mon Sep 17 00:00:00 2001 From: euquiq <31453004+euquiq@users.noreply.github.com> Date: Sat, 10 Oct 2020 20:24:11 -0300 Subject: [PATCH 09/18] APRS TX app is working fine now! Several old bugs squashed. On the APRS side, most notably, SSID numbers where shifted left twice, instead of once, and bits 5,6 where not properly set. On AX.25 side, the bit stuffing part of the encoder was not placing the zero bit on the right place. Finally, I changed APRS icon from ORANGE to GREEN, since even this may be a simple app, now it's doing its work as intended. --- firmware/application/protocols/aprs.cpp | 8 ++++-- firmware/application/protocols/ax25.cpp | 35 ++++++++++++++----------- firmware/application/ui_navigation.cpp | 2 +- 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/firmware/application/protocols/aprs.cpp b/firmware/application/protocols/aprs.cpp index 6caab866..6dbbbb72 100644 --- a/firmware/application/protocols/aprs.cpp +++ b/firmware/application/protocols/aprs.cpp @@ -38,9 +38,13 @@ void make_aprs_frame(const char * src_address, const uint32_t src_ssid, char address[14] = { 0 }; memcpy(&address[0], dest_address, 6); - address[6] = (dest_ssid & 15); memcpy(&address[7], src_address, 6); - address[13] = (src_ssid & 15); + //euquiq: According to ax.25 doc section 2.2.13.x.x and 2.4.1.2 + // SSID need bits 5.6 set, so later when shifted it will end up being 011xxxx0 (xxxx = SSID number) + // Notice that if need to signal usage of AX.25 V2.0, (dest_ssid | 112); (MSb will need to be set at the end) + address[6] = (dest_ssid | 48); + address[13] = (src_ssid | 48); + frame.make_ui_frame(address, 0x03, protocol_id_t::NO_LAYER3, payload); } diff --git a/firmware/application/protocols/ax25.cpp b/firmware/application/protocols/ax25.cpp index ea1744f6..492f6cfd 100644 --- a/firmware/application/protocols/ax25.cpp +++ b/firmware/application/protocols/ax25.cpp @@ -51,32 +51,37 @@ void AX25Frame::NRZI_add_bit(const uint32_t bit) { } } -void AX25Frame::add_byte(uint8_t byte, bool is_flag, bool is_data) { - uint32_t bit; - +void AX25Frame::add_byte(uint8_t byte, bool is_flag, bool is_data) +{ + bool bit; + if (is_data) crc_ccitt.process_byte(byte); - - for (uint32_t i = 0; i < 8; i++) { + + for (uint32_t i = 0; i < 8; i++) + { bit = (byte >> i) & 1; - + + NRZI_add_bit(bit); + if (bit) + { ones_counter++; + if ((ones_counter == 5) && (!is_flag)) + { + NRZI_add_bit(0); + ones_counter = 0; + } + } else ones_counter = 0; - - if ((ones_counter == 6) && (!is_flag)) { - NRZI_add_bit(0); - ones_counter = 0; - } - - NRZI_add_bit(bit); } } -void AX25Frame::flush() { +void AX25Frame::flush() +{ if (bit_counter) - *bb_data_ptr = current_byte << (7 - bit_counter); + *bb_data_ptr = current_byte << (8 - bit_counter); //euquiq: This was 7 but there are 8 bits }; void AX25Frame::add_flag() { diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp index ca6a6334..558f64d5 100644 --- a/firmware/application/ui_navigation.cpp +++ b/firmware/application/ui_navigation.cpp @@ -464,7 +464,7 @@ TransmittersMenuView::TransmittersMenuView(NavigationView& nav) { add_items({ //{ "..", ui::Color::light_grey(),&bitmap_icon_previous, [&nav](){ nav.pop(); } }, { "ADS-B [S]", ui::Color::yellow(), &bitmap_icon_adsb, [&nav](){ nav.push(); } }, - { "APRS", ui::Color::orange(), &bitmap_icon_aprs, [&nav](){ nav.push(); } }, + { "APRS", ui::Color::green(), &bitmap_icon_aprs, [&nav](){ nav.push(); } }, { "BHT Xy/EP", ui::Color::green(), &bitmap_icon_bht, [&nav](){ nav.push(); } }, { "GPS Sim", ui::Color::yellow(), &bitmap_icon_gps_sim, [&nav](){ nav.push(); } }, { "Jammer", ui::Color::yellow(), &bitmap_icon_jammer, [&nav](){ nav.push(); } }, From 699504a7033d9cc74cb2923fa56bdaf1041eb32d Mon Sep 17 00:00:00 2001 From: dqs105 Date: Wed, 14 Oct 2020 20:35:51 +0800 Subject: [PATCH 10/18] Removed trailing spaces. --- firmware/common/portapack_persistent_memory.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/common/portapack_persistent_memory.cpp b/firmware/common/portapack_persistent_memory.cpp index e7fcbba6..b25cc894 100644 --- a/firmware/common/portapack_persistent_memory.cpp +++ b/firmware/common/portapack_persistent_memory.cpp @@ -85,7 +85,7 @@ struct data_t { uint32_t playdead_sequence; // UI - uint32_t ui_config; + uint32_t ui_config; uint32_t pocsag_last_address; uint32_t pocsag_ignore_address; @@ -292,7 +292,7 @@ bool clkout_enabled() { } void set_clkout_enabled(bool enable) { - data->ui_config = (data->ui_config & ~0x08000000UL) | (enable << 27); + data->ui_config = (data->ui_config & ~0x08000000UL) | (enable << 27); } } /* namespace persistent_memory */ From 01ba7a57ea8adc8d4a3a484c6a6423d0e6be5b14 Mon Sep 17 00:00:00 2001 From: euquiq <31453004+euquiq@users.noreply.github.com> Date: Wed, 21 Oct 2020 13:21:34 -0300 Subject: [PATCH 11/18] New "looking Glass" app Capable of showing a cascade with full bandwidth scan. You can select Min and Max Mhz for the cascade. You can move a marker so to (aproximately) know a particular frequency on the cascade. If you press the select button, the app will jump into the RX -> AUDIO app, already tuned into the just "marked" frequency. This first version SURELY has space for lots of optimizations and improvement in general. --- firmware/application/CMakeLists.txt | 1 + .../application/apps/ui_looking_glass_app.cpp | 226 ++++++++++++++++++ .../application/apps/ui_looking_glass_app.hpp | 162 +++++++++++++ firmware/application/ui_navigation.cpp | 3 +- 4 files changed, 391 insertions(+), 1 deletion(-) create mode 100644 firmware/application/apps/ui_looking_glass_app.cpp create mode 100644 firmware/application/apps/ui_looking_glass_app.hpp diff --git a/firmware/application/CMakeLists.txt b/firmware/application/CMakeLists.txt index f551f676..3ee7d074 100644 --- a/firmware/application/CMakeLists.txt +++ b/firmware/application/CMakeLists.txt @@ -231,6 +231,7 @@ set(CPPSRC apps/ui_keyfob.cpp apps/ui_lcr.cpp apps/lge_app.cpp + apps/ui_looking_glass_app.cpp apps/ui_mictx.cpp apps/ui_modemsetup.cpp apps/ui_morse.cpp diff --git a/firmware/application/apps/ui_looking_glass_app.cpp b/firmware/application/apps/ui_looking_glass_app.cpp new file mode 100644 index 00000000..9f80b8d1 --- /dev/null +++ b/firmware/application/apps/ui_looking_glass_app.cpp @@ -0,0 +1,226 @@ +/* + * 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. + */ + +#include "ui_looking_glass_app.hpp" + + +using namespace portapack; + +namespace ui +{ + +void GlassView::focus() { + field_marker.focus(); +} + +GlassView::~GlassView() { + receiver_model.set_sampling_rate(3072000); // Just a hack to avoid hanging other apps + receiver_model.disable(); + baseband::shutdown(); +} + +void GlassView::on_lna_changed(int32_t v_db) { + receiver_model.set_lna(v_db); +} + +void GlassView::on_vga_changed(int32_t v_db) { + receiver_model.set_vga(v_db); +} + +void GlassView::add_spectrum_pixel(Color color) +{ + spectrum_row[pixel_index++] = color; + if (pixel_index == 240) //got an entire waterfall line + { + const auto draw_y = display.scroll(1); //Scroll 1 pixel down + display.draw_pixels( {{0, draw_y}, {240, 1}}, spectrum_row); //new line at top + pixel_index = 0; //Start New cascade line + } +} + +//Apparently, the spectrum object returns an array of 256 bins +//Each having the radio signal power for it's corresponding frequency slot +void GlassView::on_channel_spectrum(const ChannelSpectrum &spectrum) +{ + uint8_t max_power = 0; + baseband::spectrum_streaming_stop(); + + // Convert bins of this spectrum slice into a representative max_power and when enough, into pixels + for (uint16_t bin = 0; bin < 256; bin++) //Spectrum.db has 256 bins + { // Center 12 bins are ignored (DC spike is blanked) Leftmost and rightmost 2 bins are ignored + if (bin > 1 && bin < 122) //> 1 + { + if (spectrum.db[128 + bin] > max_power) + max_power = spectrum.db[128 + bin]; + } + else if (bin > 133 && bin < 254) // < 254 + { + if (spectrum.db[bin - 128] > max_power) + max_power = spectrum.db[bin - 128]; + } + + 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(spectrum_rgb3_lut[max_power]); //Pixel will represent max_power + else + add_spectrum_pixel(0); //Filtered out, show black + + max_power = 0; + bins_Hz_size = 0; + if (!pixel_index) //a waterfall line has been completed + break; + } + } + + if (pixel_index) + f_center += SEARCH_SLICE_WIDTH; //Move into the next bandwidth slice + else + f_center = f_center_ini; //Start a new sweep + + receiver_model.set_tuning_frequency(f_center); //tune rx for this slice + baseband::spectrum_streaming_start(); //Do the RX +} + +void GlassView::on_hide() +{ + baseband::spectrum_streaming_stop(); + display.scroll_disable(); +} + +void GlassView::on_show() +{ + baseband::spectrum_streaming_start(); +} + +void GlassView::on_range_changed() +{ + f_min = field_frequency_min.value(); + f_max = field_frequency_max.value(); + search_span = f_max - f_min; + + 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 + text_range.set(to_string_dec_uint(search_span)); + + f_min = (f_min)*MHZ_DIV; //Transpose into full frequency realm + f_max = (f_max)*MHZ_DIV; + search_span = search_span * MHZ_DIV; + + marker_pixel_step = search_span / 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 + field_marker.set_step(marker_pixel_step / MHZ_DIV); //step needs to be a pixel wide. + f_center_ini = f_min + (SEARCH_SLICE_WIDTH / 2); //Initial center frequency for sweep + f_center_ini += SEARCH_SLICE_WIDTH; //euquiq: Why do I need to move the center ???!!! (shift needed for marker accuracy) + + PlotMarker(field_marker.value()); //Refresh marker on screen + + f_center = f_center_ini; //Reset sweep into first slice + pixel_index = 0; //reset pixel counter + bins_Hz_size = 0; //reset amount of Hz filled up by pixels + receiver_model.set_tuning_frequency(f_center_ini); //tune rx for this slice +} + +void GlassView::PlotMarker(double pos) +{ + pos = pos * MHZ_DIV; + pos -= f_min; + pos = pos / marker_pixel_step; //Real pixel + + portapack::display.fill_rectangle({0, 84, 240, 4}, Color::black()); //Clear old marker and whole marker rectangle btw + portapack::display.fill_rectangle({pos - 1, 84, 3, 4}, Color::red()); //Red marker middle +} + +GlassView::GlassView( + NavigationView &nav) : nav_(nav) +{ + baseband::run_image(portapack::spi_flash::image_tag_wideband_spectrum); + + add_children({&labels, + &field_frequency_min, + &field_frequency_max, + &field_lna, + &field_vga, + &text_range, + &filter_config, + &field_rf_amp, + &field_marker, + &text_marker_pm + }); + + field_frequency_min.set_value(2400); + field_frequency_min.on_change = [this](int32_t v) { + if (v >= field_frequency_max.value()) + field_frequency_max.set_value(v + 240); + this->on_range_changed(); + }; + + field_frequency_max.set_value(2640); + field_frequency_max.on_change = [this](int32_t v) { + if (v <= field_frequency_min.value()) + field_frequency_min.set_value(v - 240); + this->on_range_changed(); + }; + + field_lna.set_value(receiver_model.lna()); + field_lna.on_change = [this](int32_t v) { + this->on_lna_changed(v); + }; + + field_vga.set_value(receiver_model.vga()); + field_vga.on_change = [this](int32_t v_db) { + this->on_vga_changed(v_db); + }; + + filter_config.set_selected_index(0); + filter_config.on_change = [this](size_t n, OptionsField::value_t v) { + min_color_power = v; + }; + + field_marker.on_change = [this](int32_t v) { + PlotMarker(v); //Refresh marker on screen + }; + + field_marker.on_select = [this](NumberField&) { + f_center = field_marker.value(); + f_center = f_center * MHZ_DIV; + receiver_model.set_tuning_frequency(f_center); //Center tune rx in marker freq. + receiver_model.set_frequency_step(MHZ_DIV); // Preset a 1 MHz frequency step into RX -> AUDIO + nav_.pop(); + nav_.push(); //Jump into audio view + }; + + display.scroll_set_area( 88, 319); + baseband::set_spectrum(SEARCH_SLICE_WIDTH, 16); // Trigger was 31. Need to understand this parameter. + + on_range_changed(); + + receiver_model.set_modulation(ReceiverModel::Mode::SpectrumAnalysis); + receiver_model.set_sampling_rate(SEARCH_SLICE_WIDTH); //20mhz + receiver_model.set_baseband_bandwidth(SEARCH_SLICE_WIDTH); // possible values: 1.75/2.5/3.5/5/5.5/6/7/8/9/10/12/14/15/20/24/28MHz + receiver_model.set_squelch_level(0); + receiver_model.enable(); +} + +} diff --git a/firmware/application/apps/ui_looking_glass_app.hpp b/firmware/application/apps/ui_looking_glass_app.hpp new file mode 100644 index 00000000..c2390490 --- /dev/null +++ b/firmware/application/apps/ui_looking_glass_app.hpp @@ -0,0 +1,162 @@ +/* + * 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. + */ + +#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 SEARCH_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); + ~GlassView(); + std::string title() const override { return "Looking Glass"; }; + + void on_show() override; + void on_hide() override; + void focus() override; + + private: + NavigationView& nav_; + + 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(double pos); + + rf::Frequency f_min { 0 }, f_max { 0 }; + rf::Frequency search_span { 0 }; + rf::Frequency f_center { 0 }; + rf::Frequency f_center_ini { 0 }; + double marker_pixel_step { 0 }; + rf::Frequency each_bin_size { SEARCH_SLICE_WIDTH / 256 }; + rf::Frequency bins_Hz_size { 0 }; + uint8_t timing_div { 0 }; + uint8_t min_color_power { 0 }; + uint32_t pixel_index { 0 }; + std::array spectrum_row = { 0 }; + ChannelSpectrumFIFO* fifo { nullptr }; + + Labels labels { + { { 0, 0 }, "MIN: MAX: LNA VGA ", Color::light_grey() }, + { { 0, 1 * 16 }, "RANGE: FILTER: AMP:", Color::light_grey() }, + { { 0, 2 * 16 }, "MARKER: MHz +/- MHz", 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 { + { 6 * 8, 1 * 16, 4 * 8, 16 }, + "" + }; + + OptionsField filter_config { + { 18 * 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 } + }; + + Text text_marker { + { 8 * 8, 2 * 16, 4 * 8, 16 }, + "" + }; + + NumberField field_marker { + { 7 * 8, 2 * 16 }, + 4, + { 0, 6000 }, + 25, + ' ' + }; + + Text text_marker_pm { + { 20 * 8, 2 * 16, 2 * 8, 16 }, + "" + }; + + 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); + } + } + } + }; + + }; +} diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp index ca6a6334..abec3d23 100644 --- a/firmware/application/ui_navigation.cpp +++ b/firmware/application/ui_navigation.cpp @@ -81,7 +81,7 @@ #include "tpms_app.hpp" #include "core_control.hpp" - +#include "ui_looking_glass_app.hpp" #include "file.hpp" #include "png_writer.hpp" @@ -527,6 +527,7 @@ SystemMenuView::SystemMenuView(NavigationView& nav) { { "Tools", ui::Color::cyan(), &bitmap_icon_utilities, [&nav](){ nav.push(); } }, { "Options", ui::Color::cyan(), &bitmap_icon_setup, [&nav](){ nav.push(); } }, { "Debug", ui::Color::light_grey(), &bitmap_icon_debug, [&nav](){ nav.push(); } }, + { "Lookin'Glass", ui::Color::red(), &bitmap_icon_search, [&nav](){ nav.push(); } }, { "HackRF", ui::Color::cyan(), &bitmap_icon_hackrf, [this, &nav](){ hackrf_mode(nav); } }, //{ "About", ui::Color::cyan(), nullptr, [&nav](){ nav.push(); } } }); From 3e1d726064b8df9eb93da37d622d7340cddd9a7e Mon Sep 17 00:00:00 2001 From: euquiq <31453004+euquiq@users.noreply.github.com> Date: Fri, 23 Oct 2020 12:19:57 -0300 Subject: [PATCH 12/18] Enhancement and bug Added a nicer MARKER (thanks to XSX(H1) contributor for the suggestion) Fixed a bug that made the screen scroll from top, when using a popup "window" and returning (like, when pressing the DC VOLTAGE enable / disable" button on top bar) THanks to GregoryFenton for the testing and bug spotting! --- firmware/application/apps/ui_looking_glass_app.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/firmware/application/apps/ui_looking_glass_app.cpp b/firmware/application/apps/ui_looking_glass_app.cpp index 9f80b8d1..52e6f2ea 100644 --- a/firmware/application/apps/ui_looking_glass_app.cpp +++ b/firmware/application/apps/ui_looking_glass_app.cpp @@ -111,6 +111,7 @@ void GlassView::on_hide() void GlassView::on_show() { + display.scroll_set_area( 88, 319); //Restart scrolling on the correct coordinates baseband::spectrum_streaming_start(); } @@ -148,8 +149,10 @@ void GlassView::PlotMarker(double pos) pos -= f_min; pos = pos / marker_pixel_step; //Real pixel - portapack::display.fill_rectangle({0, 84, 240, 4}, Color::black()); //Clear old marker and whole marker rectangle btw - portapack::display.fill_rectangle({pos - 1, 84, 3, 4}, Color::red()); //Red marker middle + portapack::display.fill_rectangle({0, 82, 240, 8}, Color::black()); //Clear old marker and whole marker rectangle btw + portapack::display.fill_rectangle({pos - 2, 82, 5, 3}, Color::red()); //Red marker middle + portapack::display.fill_rectangle({pos - 1, 84, 3, 3}, Color::red()); //Red marker middle + portapack::display.fill_rectangle({pos, 86, 1, 2}, Color::red()); //Red marker middle } GlassView::GlassView( From 7ca322fed4ec123a20d5a5e68aa667de26d18a02 Mon Sep 17 00:00:00 2001 From: dqs105 Date: Sat, 24 Oct 2020 00:24:05 +0800 Subject: [PATCH 13/18] Added options for tuning CLKOUT freq. - Now we have variable CLKOUT. - CLKOUT can be set between 10kHz and 60MHz. (The output signal will become mostly sine shape when reaching 50MHz.) - Click on freq setting field to change tuning step. --- firmware/application/apps/ui_settings.cpp | 31 +++++++++++++++++++ firmware/application/apps/ui_settings.hpp | 25 +++++++++++++-- firmware/application/clock_manager.cpp | 7 ++++- .../common/portapack_persistent_memory.cpp | 19 ++++++++++++ .../common/portapack_persistent_memory.hpp | 2 ++ 5 files changed, 80 insertions(+), 4 deletions(-) diff --git a/firmware/application/apps/ui_settings.cpp b/firmware/application/apps/ui_settings.cpp index 3d919bbe..c6ccb817 100644 --- a/firmware/application/apps/ui_settings.cpp +++ b/firmware/application/apps/ui_settings.cpp @@ -145,6 +145,9 @@ SetRadioView::SetRadioView( add_children({ &check_clkout, + &field_clkout_freq, + &labels_clkout_khz, + &value_freq_step, &labels_bias, &check_bias, &button_done, @@ -165,6 +168,31 @@ SetRadioView::SetRadioView( EventDispatcher::send_message(message); }; + field_clkout_freq.set_value(portapack::persistent_memory::clkout_freq()); + value_freq_step.set_style(&style_text); + + field_clkout_freq.on_select = [this](NumberField&) { + freq_step_khz++; + if(freq_step_khz > 3) { + freq_step_khz = 0; + } + switch(freq_step_khz) { + case 0: + value_freq_step.set(" |"); + break; + case 1: + value_freq_step.set(" | "); + break; + case 2: + value_freq_step.set(" | "); + break; + case 3: + value_freq_step.set("| "); + break; + } + field_clkout_freq.set_step(pow(10, freq_step_khz)); + }; + check_bias.set_value(portapack::get_antenna_bias()); check_bias.on_select = [this](Checkbox&, bool v) { portapack::set_antenna_bias(v); @@ -175,6 +203,8 @@ SetRadioView::SetRadioView( button_done.on_select = [this, &nav](Button&){ const auto model = this->form_collect(); portapack::persistent_memory::set_correction_ppb(model.ppm * 1000); + portapack::persistent_memory::set_clkout_freq(model.freq); + clock_manager.enable_clock_output(portapack::persistent_memory::clkout_enabled()); nav.pop(); }; } @@ -190,6 +220,7 @@ void SetRadioView::form_init(const SetFrequencyCorrectionModel& model) { SetFrequencyCorrectionModel SetRadioView::form_collect() { return { .ppm = static_cast(field_ppm.value()), + .freq = static_cast(field_clkout_freq.value()), }; } diff --git a/firmware/application/apps/ui_settings.hpp b/firmware/application/apps/ui_settings.hpp index 4b9f99d4..c66ccd2b 100644 --- a/firmware/application/apps/ui_settings.hpp +++ b/firmware/application/apps/ui_settings.hpp @@ -114,6 +114,7 @@ private: struct SetFrequencyCorrectionModel { int8_t ppm; + uint32_t freq; }; class SetRadioView : public View { @@ -130,6 +131,7 @@ private: .background = Color::black(), .foreground = Color::light_grey(), }; + uint8_t freq_step_khz = 3; Text label_source { { 0, 1 * 16, 17 * 8, 16 }, @@ -152,9 +154,26 @@ private: }; Checkbox check_clkout { - { 28, (6 * 16 - 4) }, - 4, - "Enable 10MHz CLKOUT" + { 18, (6 * 16 - 4) }, + 13, + "Enable CLKOUT" + }; + + NumberField field_clkout_freq { + { 20 * 8, 6 * 16 }, + 5, + { 10, 60000 }, + 1000, + ' ' + }; + + Labels labels_clkout_khz { + { { 26 * 8, 6 * 16 }, "kHz", Color::light_grey() } + }; + + Text value_freq_step { + { 21 * 8, (7 * 16 ), 4 * 8, 16 }, + "| " }; Labels labels_bias { diff --git a/firmware/application/clock_manager.cpp b/firmware/application/clock_manager.cpp index ec08452b..93eecc13 100644 --- a/firmware/application/clock_manager.cpp +++ b/firmware/application/clock_manager.cpp @@ -21,6 +21,7 @@ #include "clock_manager.hpp" +#include "portapack_persistent_memory.hpp" #include "portapack_io.hpp" #include "hackrf_hal.hpp" @@ -467,7 +468,11 @@ void ClockManager::stop_audio_pll() { void ClockManager::enable_clock_output(bool enable) { if(enable) { clock_generator.enable_output(clock_generator_output_clkout); - clock_generator.set_ms_frequency(clock_generator_output_clkout, 10000000, si5351_vco_f, 0); + if(portapack::persistent_memory::clkout_freq() < 1000) { + clock_generator.set_ms_frequency(clock_generator_output_clkout, portapack::persistent_memory::clkout_freq() * 128000, si5351_vco_f, 7); + } else { + clock_generator.set_ms_frequency(clock_generator_output_clkout, portapack::persistent_memory::clkout_freq() * 1000, si5351_vco_f, 0); + } } else { clock_generator.disable_output(clock_generator_output_clkout); } diff --git a/firmware/common/portapack_persistent_memory.cpp b/firmware/common/portapack_persistent_memory.cpp index b25cc894..48486f1a 100644 --- a/firmware/common/portapack_persistent_memory.cpp +++ b/firmware/common/portapack_persistent_memory.cpp @@ -63,6 +63,10 @@ using modem_repeat_range_t = range_t; constexpr modem_repeat_range_t modem_repeat_range { 1, 99 }; constexpr int32_t modem_repeat_reset_value { 5 }; +using clkout_freq_range_t = range_t; +constexpr clkout_freq_range_t clkout_freq_range { 10, 60000 }; +constexpr uint32_t clkout_freq_reset_value { 10000 }; + /* struct must pack the same way on M4 and M0 cores. */ struct data_t { int64_t tuned_frequency; @@ -295,5 +299,20 @@ void set_clkout_enabled(bool enable) { data->ui_config = (data->ui_config & ~0x08000000UL) | (enable << 27); } +uint32_t clkout_freq() { + uint16_t freq = (data->ui_config & 0x000FFFF0) >> 4; + if(freq < clkout_freq_range.minimum || freq > clkout_freq_range.maximum) { + data->ui_config = (data->ui_config & ~0x000FFFF0) | clkout_freq_reset_value << 4; + return clkout_freq_reset_value; + } + else { + return freq; + } +} + +void set_clkout_freq(uint32_t freq) { + data->ui_config = (data->ui_config & ~0x000FFFF0) | (clkout_freq_range.clip(freq) << 4); +} + } /* namespace persistent_memory */ } /* namespace portapack */ diff --git a/firmware/common/portapack_persistent_memory.hpp b/firmware/common/portapack_persistent_memory.hpp index 6422567a..c05489b0 100644 --- a/firmware/common/portapack_persistent_memory.hpp +++ b/firmware/common/portapack_persistent_memory.hpp @@ -95,6 +95,8 @@ void set_pocsag_ignore_address(uint32_t address); bool clkout_enabled(); void set_clkout_enabled(bool enable); +uint32_t clkout_freq(); +void set_clkout_freq(uint32_t freq); } /* namespace persistent_memory */ } /* namespace portapack */ From 47c5c1e9e53d38a92b8e8edffd4366d2a8c97a53 Mon Sep 17 00:00:00 2001 From: Erwin Ried <1091420+eried@users.noreply.github.com> Date: Sat, 24 Oct 2020 22:38:43 +0200 Subject: [PATCH 14/18] Update generate_world_map.bin.py Fix for https://github.com/eried/portapack-mayhem/issues/217 --- firmware/tools/generate_world_map.bin.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/firmware/tools/generate_world_map.bin.py b/firmware/tools/generate_world_map.bin.py index b766f9a4..1e2865c2 100644 --- a/firmware/tools/generate_world_map.bin.py +++ b/firmware/tools/generate_world_map.bin.py @@ -33,6 +33,8 @@ pix = im.load() outfile.write(struct.pack('H', im.size[0])) outfile.write(struct.pack('H', im.size[1])) +print("Generating: \t" + outfile.name + "\n from\t\t" + im.filename + "\n please wait..."); + for y in range (0, im.size[1]): line = '' for x in range (0, im.size[0]): @@ -45,6 +47,8 @@ for y in range (0, im.size[1]): # pixel_lcd = (pix[x, y][0] >> 5) << 5 # pixel_lcd |= (pix[x, y][1] >> 5) << 2 # pixel_lcd |= (pix[x, y][2] >> 6) - line += struct.pack('H', pixel_lcd) - outfile.write(line) + line += str(struct.pack('H', pixel_lcd)) + outfile.write(line.encode('utf-8')) print(str(y) + '/' + str(im.size[1]) + '\r', end="") + +print("Ready."); From 210ec9dd1bbd3df63999c196921f2cc44850ed7e Mon Sep 17 00:00:00 2001 From: euquiq <31453004+euquiq@users.noreply.github.com> Date: Mon, 26 Oct 2020 12:53:10 -0300 Subject: [PATCH 15/18] Looking Glass with PRESETS Added a PRESETS.TXT file (inside /LOOKINGGLASS folder). Also optimized the way the spectrum signal is integrated into the cascade. Added provision for ranges lower than 240MHz but I am afraid that at this time it will not be advisable to lower ranges any more than 240MHz, since some artifacts and frequency running - moving out of place- occurs. I can only hope that someone with a better understanding of hackrf's inner code can fix this issue and perhaps enhance the scanning speed. I found some "original commenting" inside the code: // TODO: Move more low-level radio control stuff to M4. It'll enable tighter // synchronization for things like wideband (sweeping) spectrum analysis, and // protocols that need quick RX/TX turn-around. Which makes me think that there are things "missing" from the portapack side of the code, for allowing serious speed sweeping. So I am concluding that with current "portapack framework" this might be "the best possible thing". It is to be noted that the "new" internal sweep mode code is signed by: * Copyright 2016 Mike Walters, Dominic Spill * * This file is part of HackRF. Maybe Mike or Dominic can be contacted and hopefully lend a hand on enhancing this code. --- .../application/apps/ui_looking_glass_app.cpp | 144 +++++++-- .../application/apps/ui_looking_glass_app.hpp | 289 +++++++++--------- sdcard/LOOKINGGLASS/PRESETS.TXT | 11 + 3 files changed, 282 insertions(+), 162 deletions(-) create mode 100644 sdcard/LOOKINGGLASS/PRESETS.TXT diff --git a/firmware/application/apps/ui_looking_glass_app.cpp b/firmware/application/apps/ui_looking_glass_app.cpp index 52e6f2ea..c690983b 100644 --- a/firmware/application/apps/ui_looking_glass_app.cpp +++ b/firmware/application/apps/ui_looking_glass_app.cpp @@ -61,21 +61,21 @@ void GlassView::add_spectrum_pixel(Color color) //Each having the radio signal power for it's corresponding frequency slot void GlassView::on_channel_spectrum(const ChannelSpectrum &spectrum) { - uint8_t max_power = 0; baseband::spectrum_streaming_stop(); // Convert bins of this spectrum slice into a representative max_power and when enough, into pixels - for (uint16_t bin = 0; bin < 256; bin++) //Spectrum.db has 256 bins - { // Center 12 bins are ignored (DC spike is blanked) Leftmost and rightmost 2 bins are ignored - if (bin > 1 && bin < 122) //> 1 + // 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) + max_power = spectrum.db[134 + bin]; + } + else { - if (spectrum.db[128 + bin] > max_power) - max_power = spectrum.db[128 + bin]; - } - else if (bin > 133 && bin < 254) // < 254 - { - if (spectrum.db[bin - 128] > max_power) - max_power = spectrum.db[bin - 128]; + if (spectrum.db[bin - 118] > max_power) + max_power = spectrum.db[bin - 118]; } bins_Hz_size += each_bin_size; //add this bin Hz count into the "pixel fulfilled bag of Hz" @@ -88,9 +88,14 @@ void GlassView::on_channel_spectrum(const ChannelSpectrum &spectrum) add_spectrum_pixel(0); //Filtered out, show black max_power = 0; - bins_Hz_size = 0; - if (!pixel_index) //a waterfall line has been completed + + 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" break; + } else { + bins_Hz_size -= marker_pixel_step; //reset bins size, but carrying the eventual excess Hz into next pixel + } } } @@ -111,7 +116,7 @@ void GlassView::on_hide() void GlassView::on_show() { - display.scroll_set_area( 88, 319); //Restart scrolling on the correct coordinates + display.scroll_set_area( 109, 319); //Restart scroll on the correct coordinates baseband::spectrum_streaming_start(); } @@ -131,7 +136,13 @@ void GlassView::on_range_changed() marker_pixel_step = search_span / 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 - field_marker.set_step(marker_pixel_step / MHZ_DIV); //step needs to be a pixel wide. + + int32_t marker_step = marker_pixel_step / MHZ_DIV; + if (!marker_step) + field_marker.set_step(1); //in case selected range is less than 240 (pixels) + else + field_marker.set_step(marker_step); //step needs to be a pixel wide. + f_center_ini = f_min + (SEARCH_SLICE_WIDTH / 2); //Initial center frequency for sweep f_center_ini += SEARCH_SLICE_WIDTH; //euquiq: Why do I need to move the center ???!!! (shift needed for marker accuracy) @@ -139,20 +150,23 @@ void GlassView::on_range_changed() f_center = f_center_ini; //Reset sweep into first slice pixel_index = 0; //reset pixel counter + max_power = 0; bins_Hz_size = 0; //reset amount of Hz filled up by pixels + + baseband::set_spectrum(SEARCH_SLICE_WIDTH, 31); // Trigger was 31. Need to understand this parameter. receiver_model.set_tuning_frequency(f_center_ini); //tune rx for this slice } -void GlassView::PlotMarker(double pos) +void GlassView::PlotMarker(rf::Frequency pos) { pos = pos * MHZ_DIV; pos -= f_min; pos = pos / marker_pixel_step; //Real pixel - portapack::display.fill_rectangle({0, 82, 240, 8}, Color::black()); //Clear old marker and whole marker rectangle btw - portapack::display.fill_rectangle({pos - 2, 82, 5, 3}, Color::red()); //Red marker middle - portapack::display.fill_rectangle({pos - 1, 84, 3, 3}, Color::red()); //Red marker middle - portapack::display.fill_rectangle({pos, 86, 1, 2}, Color::red()); //Red marker middle + portapack::display.fill_rectangle({0, 100, 240, 8}, Color::black()); //Clear old marker and whole marker rectangle btw + portapack::display.fill_rectangle({pos - 2, 100, 5, 3}, Color::red()); //Red marker middle + portapack::display.fill_rectangle({pos - 1, 103, 3, 3}, Color::red()); //Red marker middle + portapack::display.fill_rectangle({pos, 106, 1, 2}, Color::red()); //Red marker middle } GlassView::GlassView( @@ -168,18 +182,21 @@ GlassView::GlassView( &text_range, &filter_config, &field_rf_amp, + &range_presets, &field_marker, &text_marker_pm }); + + load_Presets(); //Load available presets from TXT files (or default) - field_frequency_min.set_value(2400); + field_frequency_min.set_value(presets_db[0].min); //Defaults to first preset field_frequency_min.on_change = [this](int32_t v) { if (v >= field_frequency_max.value()) field_frequency_max.set_value(v + 240); this->on_range_changed(); }; - field_frequency_max.set_value(2640); + field_frequency_max.set_value(presets_db[0].max); //Defaults to first preset field_frequency_max.on_change = [this](int32_t v) { if (v <= field_frequency_min.value()) field_frequency_min.set_value(v - 240); @@ -201,6 +218,12 @@ GlassView::GlassView( min_color_power = v; }; + range_presets.on_change = [this](size_t n, OptionsField::value_t v) { + field_frequency_min.set_value(presets_db[v].min,false); + field_frequency_max.set_value(presets_db[v].max,false); + this->on_range_changed(); + }; + field_marker.on_change = [this](int32_t v) { PlotMarker(v); //Refresh marker on screen }; @@ -214,8 +237,8 @@ GlassView::GlassView( nav_.push(); //Jump into audio view }; - display.scroll_set_area( 88, 319); - baseband::set_spectrum(SEARCH_SLICE_WIDTH, 16); // Trigger was 31. Need to understand this parameter. + display.scroll_set_area( 109, 319); + baseband::set_spectrum(SEARCH_SLICE_WIDTH, 31); // Trigger was 31. Need to understand this parameter. on_range_changed(); @@ -226,4 +249,77 @@ GlassView::GlassView( receiver_model.enable(); } +void GlassView::load_Presets() { + File presets_file; //LOAD /WHIPCALC/ANTENNAS.TXT from microSD + auto result = presets_file.open("LOOKINGGLASS/PRESETS.TXT"); + presets_db.clear(); //Start with fresh db + if (result.is_valid()) { + presets_Default(); //There is no txt, store a default range + } else { + + std::string line; //There is a txt file + char one_char[1]; //Read it char by char + for (size_t pointer=0; pointer < presets_file.size();pointer++) { + presets_file.seek(pointer); + presets_file.read(one_char, 1); + if ((int)one_char[0] > 31) { //ascii space upwards + line += one_char[0]; //Add it to the textline + } + else if (one_char[0] == '\n') { //New Line + txtline_process(line); //make sense of this textline + line.clear(); //Ready for next textline + } + } + if (line.length() > 0) txtline_process(line); //Last line had no newline at end ? + if (!presets_db.size()) presets_Default(); //no antenna on txt, use default + } + + populate_Presets(); +} + +void GlassView::txtline_process(std::string& line) +{ + if (line.find("#") != std::string::npos) return; //Line is just a comment + + size_t comma = line.find(","); //Get first comma position + if (comma == std::string::npos) return; //No comma at all + + size_t previous = 0; + preset_entry new_preset; + + new_preset.min = std::stoi(line.substr(0,comma)); + if (!new_preset.min) return; //No frequency! + + previous = comma + 1; + comma = line.find(",",previous); //Search for next delimiter + if (comma == std::string::npos) return; //No comma at all + + new_preset.max = std::stoi(line.substr(previous,comma - previous)); + if (!new_preset.max) return; //No frequency! + + new_preset.label = line.substr(comma + 1); + if (new_preset.label.size() == 0) return; //No label ? + + presets_db.push_back(new_preset); //Add this preset. +} + +void GlassView::populate_Presets() +{ + using option_t = std::pair; + using options_t = std::vector; + options_t entries; + + for (preset_entry preset : presets_db) + { //go thru all available presets + entries.emplace_back(preset.label,entries.size()); + } + range_presets.set_options(entries); +} + +void GlassView::presets_Default() +{ + presets_db.clear(); + presets_db.push_back({2320, 2560, "DEFAULT WIFI 2.4GHz"}); +} + } diff --git a/firmware/application/apps/ui_looking_glass_app.hpp b/firmware/application/apps/ui_looking_glass_app.hpp index c2390490..bb6d6134 100644 --- a/firmware/application/apps/ui_looking_glass_app.hpp +++ b/firmware/application/apps/ui_looking_glass_app.hpp @@ -1,162 +1,175 @@ /* - * 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. + */ -#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 SEARCH_SLICE_WIDTH 20000000 // Each slice bandwidth 20 MHz - #define MHZ_DIV 1000000 - #define X2_MHZ_DIV 2000000 + namespace ui + { + #define SEARCH_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); - ~GlassView(); - std::string title() const override { return "Looking Glass"; }; + class GlassView : public View + { + public: + GlassView(NavigationView &nav); + ~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_; - 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(double pos); - - rf::Frequency f_min { 0 }, f_max { 0 }; - rf::Frequency search_span { 0 }; - rf::Frequency f_center { 0 }; - rf::Frequency f_center_ini { 0 }; - double marker_pixel_step { 0 }; - rf::Frequency each_bin_size { SEARCH_SLICE_WIDTH / 256 }; - rf::Frequency bins_Hz_size { 0 }; - uint8_t timing_div { 0 }; - uint8_t min_color_power { 0 }; - uint32_t pixel_index { 0 }; - std::array spectrum_row = { 0 }; - ChannelSpectrumFIFO* fifo { nullptr }; - - Labels labels { - { { 0, 0 }, "MIN: MAX: LNA VGA ", Color::light_grey() }, - { { 0, 1 * 16 }, "RANGE: FILTER: AMP:", Color::light_grey() }, - { { 0, 2 * 16 }, "MARKER: MHz +/- MHz", Color::light_grey() } + struct preset_entry + { + rf::Frequency min{}; + rf::Frequency max{}; + std::string label{}; }; - NumberField field_frequency_min { - { 4 * 8, 0 * 16 }, - 4, - { 0, 6960 }, - 240, - ' ' + 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 { SEARCH_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()} + }; - NumberField field_frequency_max { - { 13 * 8, 0 * 16 }, - 4, - { 240, 7200 }, - 240, - ' ' - }; + NumberField field_frequency_min { + { 4 * 8, 0 * 16 }, + 4, + { 0, 6960 }, + 240, + ' ' + }; - LNAGainField field_lna { - { 21 * 8, 0 * 16 } - }; - - VGAGainField field_vga { - { 27 * 8, 0 * 16 } - }; + NumberField field_frequency_max { + { 13 * 8, 0 * 16 }, + 4, + { 240, 7200 }, + 240, + ' ' + }; - Text text_range { - { 6 * 8, 1 * 16, 4 * 8, 16 }, - "" - }; + LNAGainField field_lna { + { 21 * 8, 0 * 16 } + }; - OptionsField filter_config { - { 18 * 8, 1 * 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, { - { "OFF ", 0 }, - { "MID ", 118 }, //85 +25 (110) + a bit more to kill all blue - { "HIGH", 202 }, //168 + 25 (193) - } - }; + {"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 } - }; + RFAmpField field_rf_amp{ + {29 * 8, 1 * 16}}; - Text text_marker { - { 8 * 8, 2 * 16, 4 * 8, 16 }, - "" - }; + OptionsField range_presets{ + {7 * 8, 2 * 16}, + 20, + { + {" NONE (WIFI 2.4GHz)", 0}, + }}; - NumberField field_marker { - { 7 * 8, 2 * 16 }, + NumberField field_marker{ + {7 * 8, 3 * 16}, 4, - { 0, 6000 }, + {0, 7200}, 25, - ' ' - }; + ' '}; - Text text_marker_pm { - { 20 * 8, 2 * 16, 2 * 8, 16 }, - "" - }; + Text text_marker_pm{ + {20 * 8, 3 * 16, 2 * 8, 16}, + ""}; - 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); + } + } + } + }; - }; -} + }; + } + \ No newline at end of file diff --git a/sdcard/LOOKINGGLASS/PRESETS.TXT b/sdcard/LOOKINGGLASS/PRESETS.TXT new file mode 100644 index 00000000..cd179d54 --- /dev/null +++ b/sdcard/LOOKINGGLASS/PRESETS.TXT @@ -0,0 +1,11 @@ +# INI,END,DESCRIPTION +# (Freq range in MHz, min separation 240MHz) +# (Description up to 20 char) +# (fields comma delimiter) +260,500,315/433 MHz KEYFOBS +2320,2560,BL / WIFI 2.4GHz +5160,5900,WIFI 5GHz +10,7250,FULL RANGE +140,380,VHF MICS AND MARINE +390,420,RADIOSONDES +420,660,UHF MICS \ No newline at end of file From 13ce56f7bf44b1020840bfe82fc7200356ebbb1a Mon Sep 17 00:00:00 2001 From: euquiq <31453004+euquiq@users.noreply.github.com> Date: Mon, 26 Oct 2020 23:43:35 -0300 Subject: [PATCH 16/18] Added "RESOLUTION" parameter Discord User jteich did some investigation (Thanks!) and helped me understanding this rather obscure parameter: Internally, is called "TRIGGER", and is passed into the baseband when configuring the desired spectrum sample rate. Please forgive me in advance if this explanation is not 100% correct. It's only my interpretation, based on my own observation and jteich's comments over Discord chat. This trigger parameter apparently determines the amount of data over time used for calculating the signal's power inside each specttrum's bin, before considering it "done". In short, if you lower this resolution value then the cascade will tend to be rendered a bit faster, while kind of blind to tiny signals. On the other hand, a bigger value will help rendering and distinguishing different signals on the cascade. Too big a value can easily clutter up the cascade. But then it may be a "blessing" when inspecting higher freuqencies -where hackrf is more deaf" The default value of 32 is quite decent. But then, now you can experiment with it. Cheers --- .../application/apps/ui_looking_glass_app.cpp | 17 +++++++++++++---- .../application/apps/ui_looking_glass_app.hpp | 12 ++++++++++-- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/firmware/application/apps/ui_looking_glass_app.cpp b/firmware/application/apps/ui_looking_glass_app.cpp index c690983b..e18bba62 100644 --- a/firmware/application/apps/ui_looking_glass_app.cpp +++ b/firmware/application/apps/ui_looking_glass_app.cpp @@ -100,7 +100,7 @@ void GlassView::on_channel_spectrum(const ChannelSpectrum &spectrum) } if (pixel_index) - f_center += SEARCH_SLICE_WIDTH; //Move into the next bandwidth slice + f_center += SEARCH_SLICE_WIDTH; //Move into the next bandwidth slice NOTE: spectrum.sampling_rate = SEARCH_SLICE_WIDTH else f_center = f_center_ini; //Start a new sweep @@ -153,7 +153,7 @@ void GlassView::on_range_changed() max_power = 0; bins_Hz_size = 0; //reset amount of Hz filled up by pixels - baseband::set_spectrum(SEARCH_SLICE_WIDTH, 31); // Trigger was 31. Need to understand this parameter. + baseband::set_spectrum(SEARCH_SLICE_WIDTH, field_trigger.value()); receiver_model.set_tuning_frequency(f_center_ini); //tune rx for this slice } @@ -184,7 +184,8 @@ GlassView::GlassView( &field_rf_amp, &range_presets, &field_marker, - &text_marker_pm + &text_marker_pm, + &field_trigger }); load_Presets(); //Load available presets from TXT files (or default) @@ -237,8 +238,16 @@ GlassView::GlassView( nav_.push(); //Jump into audio view }; + field_trigger.set_value(32); //Defaults to 32, as normal triggering resolution + field_trigger.on_change = [this](int32_t v) { + baseband::set_spectrum(SEARCH_SLICE_WIDTH, v); + }; + display.scroll_set_area( 109, 319); - baseband::set_spectrum(SEARCH_SLICE_WIDTH, 31); // Trigger was 31. Need to understand this parameter. + baseband::set_spectrum(SEARCH_SLICE_WIDTH, field_trigger.value()); //trigger: + // Discord User jteich: WidebandSpectrum::on_message to set the trigger value. In WidebandSpectrum::execute , + // it keeps adding the output of the fft to the buffer until "trigger" number of calls are made, + //at which time it pushes the buffer up with channel_spectrum.feed on_range_changed(); diff --git a/firmware/application/apps/ui_looking_glass_app.hpp b/firmware/application/apps/ui_looking_glass_app.hpp index bb6d6134..3313a55f 100644 --- a/firmware/application/apps/ui_looking_glass_app.hpp +++ b/firmware/application/apps/ui_looking_glass_app.hpp @@ -89,8 +89,8 @@ {{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, 3 * 16}, "MARKER: MHz +/- MHz", Color::light_grey()}, + {{0, 4 * 16}, "RESOLUTION: (fft trigger)", Color::light_grey()} }; NumberField field_frequency_min { @@ -151,6 +151,14 @@ {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) { From aeefecf5c697af8e007c5876ddbb250e96c6f611 Mon Sep 17 00:00:00 2001 From: Erwin Ried <1091420+eried@users.noreply.github.com> Date: Sat, 31 Oct 2020 22:00:19 +0100 Subject: [PATCH 17/18] Version bump --- firmware/application/ui_navigation.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/application/ui_navigation.hpp b/firmware/application/ui_navigation.hpp index 8e69e856..782c92e7 100644 --- a/firmware/application/ui_navigation.hpp +++ b/firmware/application/ui_navigation.hpp @@ -214,7 +214,7 @@ public: InformationView(NavigationView& nav); private: - static constexpr auto version_string = "v1.2.3"; + static constexpr auto version_string = "v1.3.0"; NavigationView& nav_; Rectangle backdrop { From 2fa6df596a0ff0219c59917ef18fef53b9869dd4 Mon Sep 17 00:00:00 2001 From: Erwin Ried <1091420+eried@users.noreply.github.com> Date: Sun, 1 Nov 2020 17:26:29 +0100 Subject: [PATCH 18/18] New icon and shortcut --- firmware/application/bitmap.hpp | 3912 ++++++++++++------------ firmware/application/ui_navigation.cpp | 4 +- firmware/graphics/icon_looking.png | Bin 0 -> 180 bytes 3 files changed, 1969 insertions(+), 1947 deletions(-) create mode 100644 firmware/graphics/icon_looking.png diff --git a/firmware/application/bitmap.hpp b/firmware/application/bitmap.hpp index e33913aa..8cb98a43 100644 --- a/firmware/application/bitmap.hpp +++ b/firmware/application/bitmap.hpp @@ -29,426 +29,6 @@ namespace ui { -static constexpr uint8_t bitmap_bulb_on_data[] = { - 0x04, 0x3C, 0x20, - 0x08, 0xFF, 0x10, - 0x90, 0xFF, 0x09, - 0xC0, 0xFF, 0x03, - 0xE0, 0xFF, 0x07, - 0xE0, 0xFF, 0x07, - 0xF0, 0xE7, 0x0F, - 0xF0, 0xBD, 0x0F, - 0xF7, 0xBD, 0xEF, - 0xF0, 0xDB, 0x0F, - 0xF0, 0xDB, 0x0F, - 0xE0, 0xDB, 0x07, - 0xE0, 0xCB, 0x07, - 0xC0, 0xD3, 0x03, - 0x90, 0xCB, 0x09, - 0x08, 0xFD, 0x10, - 0x04, 0xE3, 0x20, - 0x00, 0xBD, 0x00, - 0x00, 0xC3, 0x00, - 0x00, 0xBD, 0x00, - 0x00, 0xC3, 0x00, - 0x00, 0xBD, 0x00, - 0x00, 0x42, 0x00, - 0x00, 0x3C, 0x00, -}; -static constexpr Bitmap bitmap_bulb_on { - { 24, 24 }, bitmap_bulb_on_data -}; - -static constexpr uint8_t bitmap_icon_jammer_data[] = { - 0xE0, 0x07, - 0xF8, 0x1F, - 0x1C, 0x38, - 0x0E, 0x78, - 0x06, 0x7C, - 0x03, 0xCE, - 0x03, 0xC7, - 0x83, 0xC3, - 0xC3, 0xC1, - 0xE3, 0xC0, - 0x73, 0xC0, - 0x3E, 0x60, - 0x1E, 0x70, - 0x1C, 0x38, - 0xF8, 0x1F, - 0xE0, 0x07, -}; -static constexpr Bitmap bitmap_icon_jammer { - { 16, 16 }, bitmap_icon_jammer_data -}; - -static constexpr uint8_t bitmap_sig_saw_down_data[] = { - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x0E, 0x80, 0x00, 0x60, - 0x1E, 0x80, 0x01, 0x60, - 0x3E, 0x80, 0x03, 0x60, - 0x76, 0x80, 0x07, 0x60, - 0xE6, 0x80, 0x0F, 0x60, - 0xC6, 0x81, 0x1D, 0x60, - 0x86, 0x83, 0x39, 0x60, - 0x06, 0x87, 0x71, 0x60, - 0x06, 0x8E, 0xE1, 0x60, - 0x06, 0x9C, 0xC1, 0x61, - 0x06, 0xB8, 0x81, 0x63, - 0x06, 0xF0, 0x01, 0x67, - 0x06, 0xE0, 0x01, 0x6E, - 0x06, 0xC0, 0x01, 0x7C, - 0x06, 0x80, 0x01, 0x78, - 0x06, 0x00, 0x01, 0x70, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, -}; -static constexpr Bitmap bitmap_sig_saw_down { - { 32, 32 }, bitmap_sig_saw_down_data -}; - -static constexpr uint8_t bitmap_icon_sdcard_data[] = { - 0xF0, 0x3F, - 0x58, 0x35, - 0x5C, 0x35, - 0xFC, 0x3F, - 0xFC, 0x3F, - 0xFC, 0x3F, - 0xFC, 0x3F, - 0xFC, 0x3F, - 0xFC, 0x3F, - 0xAC, 0x3A, - 0x5C, 0x35, - 0xAC, 0x3A, - 0x5C, 0x35, - 0xAC, 0x3A, - 0x5C, 0x35, - 0xAC, 0x3A, -}; -static constexpr Bitmap bitmap_icon_sdcard { - { 16, 16 }, bitmap_icon_sdcard_data -}; - -static constexpr uint8_t bitmap_icon_morse_data[] = { - 0x00, 0x00, - 0xFE, 0x7F, - 0xFF, 0xFF, - 0xBB, 0xD0, - 0xFF, 0xFF, - 0xFF, 0xFF, - 0x0B, 0xE1, - 0xFF, 0xFF, - 0xFF, 0xFF, - 0xEB, 0xD0, - 0xFF, 0xFF, - 0xFE, 0x7F, - 0x70, 0x00, - 0x30, 0x00, - 0x10, 0x00, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_morse { - { 16, 16 }, bitmap_icon_morse_data -}; - -static constexpr uint8_t bitmap_icon_peripherals_details_data[] = { - 0x54, 0x01, - 0x54, 0x01, - 0xFF, 0x07, - 0xFC, 0x01, - 0x3F, 0x00, - 0xBC, 0x3F, - 0xBF, 0x60, - 0xBC, 0xEE, - 0xBF, 0x80, - 0x94, 0xBE, - 0x94, 0x80, - 0x80, 0xBE, - 0x80, 0x80, - 0x80, 0xBE, - 0x80, 0x80, - 0x80, 0xFF, -}; -static constexpr Bitmap bitmap_icon_peripherals_details { - { 16, 16 }, bitmap_icon_peripherals_details_data -}; - -static constexpr uint8_t bitmap_icon_tools_antenna_data[] = { - 0x38, 0x3E, - 0x10, 0x22, - 0x10, 0x26, - 0x10, 0x22, - 0x10, 0x2E, - 0x10, 0x22, - 0x10, 0x26, - 0x10, 0x22, - 0x38, 0x2E, - 0x38, 0x22, - 0x38, 0x26, - 0x38, 0x22, - 0x38, 0x2E, - 0x38, 0x22, - 0x38, 0x3E, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_tools_antenna { - { 16, 16 }, bitmap_icon_tools_antenna_data -}; - -static constexpr uint8_t bitmap_icon_cwgen_data[] = { - 0x18, 0x00, - 0x24, 0x00, - 0x42, 0x00, - 0x42, 0x00, - 0x42, 0x00, - 0x42, 0x00, - 0x81, 0x00, - 0xAB, 0x6A, - 0x80, 0x40, - 0x00, 0x21, - 0x00, 0x21, - 0x00, 0x21, - 0x00, 0x21, - 0x00, 0x12, - 0x00, 0x0C, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_cwgen { - { 16, 16 }, bitmap_icon_cwgen_data -}; - -static constexpr uint8_t bitmap_icon_bht_data[] = { - 0x00, 0x00, - 0xE0, 0x07, - 0xF8, 0x08, - 0x9C, 0x07, - 0x0C, 0x00, - 0x8E, 0x0A, - 0x46, 0x12, - 0x26, 0x22, - 0x06, 0x02, - 0x06, 0x00, - 0x06, 0x00, - 0x06, 0x00, - 0x06, 0x00, - 0x06, 0x00, - 0x06, 0x00, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_bht { - { 16, 16 }, bitmap_icon_bht_data -}; - -static constexpr uint8_t bitmap_icon_speaker_mute_data[] = { - 0x00, 0x00, - 0x40, 0x00, - 0x60, 0x00, - 0x70, 0x00, - 0x78, 0x00, - 0x7F, 0x22, - 0x7F, 0x36, - 0x7F, 0x1C, - 0x7F, 0x08, - 0x7F, 0x1C, - 0x7F, 0x36, - 0x7F, 0x22, - 0x78, 0x00, - 0x70, 0x00, - 0x60, 0x00, - 0x40, 0x00, -}; -static constexpr Bitmap bitmap_icon_speaker_mute { - { 16, 16 }, bitmap_icon_speaker_mute_data -}; - -static constexpr uint8_t bitmap_icon_search_data[] = { - 0xF8, 0x01, - 0xFC, 0x03, - 0x0E, 0x07, - 0x07, 0x0E, - 0x03, 0x0C, - 0x0B, 0x0C, - 0x0B, 0x0C, - 0x13, 0x0C, - 0x07, 0x0E, - 0x0E, 0x07, - 0xFC, 0x1F, - 0xF8, 0x3D, - 0x00, 0x7C, - 0x00, 0xF8, - 0x00, 0xF0, - 0x00, 0x60, -}; -static constexpr Bitmap bitmap_icon_search { - { 16, 16 }, bitmap_icon_search_data -}; - -static constexpr uint8_t bitmap_icon_adsb_data[] = { - 0x80, 0x01, - 0xC0, 0x03, - 0xC0, 0x03, - 0xC0, 0x03, - 0xC0, 0x03, - 0xE0, 0x07, - 0xF8, 0x1F, - 0xFE, 0x7F, - 0xFF, 0xFF, - 0xFF, 0xFF, - 0xC0, 0x03, - 0xC0, 0x03, - 0xC0, 0x03, - 0xE0, 0x07, - 0xF0, 0x0F, - 0xF8, 0x1F, -}; -static constexpr Bitmap bitmap_icon_adsb { - { 16, 16 }, bitmap_icon_adsb_data -}; - -static constexpr uint8_t bitmap_icon_codetx_data[] = { - 0x00, 0x00, - 0xF0, 0x07, - 0x0C, 0x18, - 0x03, 0x60, - 0xE0, 0x03, - 0x18, 0x0C, - 0x04, 0x10, - 0xC0, 0x01, - 0x20, 0x02, - 0x00, 0x00, - 0x00, 0x00, - 0xBB, 0x6D, - 0x2A, 0x49, - 0x2A, 0x49, - 0x3A, 0x49, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_codetx { - { 16, 16 }, bitmap_icon_codetx_data -}; - -static constexpr uint8_t bitmap_icon_gps_sim_data[] = { - 0xC0, 0x07, - 0xE0, 0x0F, - 0x70, 0x1F, - 0x78, 0x3E, - 0x78, 0x3C, - 0x78, 0x38, - 0x78, 0x30, - 0x78, 0x38, - 0x78, 0x3C, - 0x70, 0x1E, - 0x70, 0x1F, - 0xE0, 0x0F, - 0xC0, 0x07, - 0x80, 0x03, - 0x20, 0x09, - 0x50, 0x14, -}; -static constexpr Bitmap bitmap_icon_gps_sim { - { 16, 16 }, bitmap_icon_gps_sim_data -}; - -static constexpr uint8_t bitmap_icon_rename_numeric_data[] = { - 0x00, 0x00, - 0x00, 0x00, - 0x00, 0x0E, - 0x00, 0x04, - 0xFF, 0xF5, - 0x01, 0x84, - 0xC9, 0x85, - 0x0D, 0x85, - 0xC9, 0x85, - 0x49, 0x84, - 0xDD, 0x85, - 0x01, 0x84, - 0xFF, 0xF5, - 0x00, 0x04, - 0x00, 0x0E, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_rename_numeric { - { 16, 16 }, bitmap_icon_rename_numeric_data -}; - -static constexpr uint8_t bitmap_icon_rename_data[] = { - 0x00, 0x00, - 0x00, 0x00, - 0x00, 0x0E, - 0x00, 0x04, - 0xFF, 0xF5, - 0x01, 0x84, - 0xC9, 0x84, - 0x55, 0x85, - 0xDD, 0x84, - 0x55, 0x85, - 0xD5, 0x84, - 0x01, 0x84, - 0xFF, 0xF5, - 0x00, 0x04, - 0x00, 0x0E, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_rename { - { 16, 16 }, bitmap_icon_rename_data -}; - -static constexpr uint8_t bitmap_icon_fox_data[] = { - 0x18, 0x18, - 0x28, 0x14, - 0x68, 0x16, - 0x68, 0x16, - 0xC8, 0x13, - 0x88, 0x11, - 0x04, 0x20, - 0x24, 0x24, - 0x22, 0x44, - 0x01, 0x80, - 0x06, 0x60, - 0x98, 0x19, - 0x20, 0x04, - 0x40, 0x02, - 0x80, 0x01, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_fox { - { 16, 16 }, bitmap_icon_fox_data -}; - -static constexpr uint8_t bitmap_sd_card_ok_data[] = { - 0x00, 0x00, - 0x00, 0x00, - 0xC0, 0x1F, - 0xE0, 0x1F, - 0xF0, 0x1F, - 0xF8, 0x1F, - 0xF8, 0x1F, - 0x98, 0x15, - 0x68, 0x19, - 0x68, 0x1D, - 0x68, 0x19, - 0x98, 0x15, - 0xF8, 0x1F, - 0xF8, 0x1F, - 0x00, 0x00, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_sd_card_ok { - { 16, 16 }, bitmap_sd_card_ok_data -}; - static constexpr uint8_t bitmap_bulb_ignore_data[] = { 0x00, 0x3C, 0x00, 0x00, 0xC3, 0x00, @@ -479,682 +59,6 @@ static constexpr Bitmap bitmap_bulb_ignore { { 24, 24 }, bitmap_bulb_ignore_data }; -static constexpr uint8_t bitmap_icon_clk_ext_data[] = { - 0x00, - 0x00, - 0xDC, - 0x54, - 0x54, - 0x54, - 0x54, - 0x76, - 0x00, - 0x10, - 0x38, - 0x7C, - 0x10, - 0x10, - 0x10, - 0x00, -}; -static constexpr Bitmap bitmap_icon_clk_ext { - { 8, 16 }, bitmap_icon_clk_ext_data -}; - -static constexpr uint8_t bitmap_icon_load_data[] = { - 0x00, 0x01, - 0x80, 0x03, - 0x40, 0x05, - 0x00, 0x01, - 0x0E, 0x01, - 0x11, 0x01, - 0x7F, 0x1D, - 0x01, 0x20, - 0xF9, 0xFF, - 0xF9, 0xFF, - 0xFD, 0x7F, - 0xFD, 0x7F, - 0xFF, 0x3F, - 0xFF, 0x3F, - 0xFF, 0x1F, - 0xFF, 0x1F, -}; -static constexpr Bitmap bitmap_icon_load { - { 16, 16 }, bitmap_icon_load_data -}; - -static constexpr uint8_t bitmap_icon_hackrf_data[] = { - 0xF0, 0x0F, - 0x10, 0x08, - 0x50, 0x0A, - 0x10, 0x08, - 0x10, 0x08, - 0x10, 0x08, - 0xF8, 0x1F, - 0xF8, 0x1F, - 0xF8, 0x1F, - 0xF8, 0x1F, - 0xF8, 0x1F, - 0xF8, 0x1F, - 0xF8, 0x1F, - 0xF0, 0x0F, - 0x80, 0x01, - 0x80, 0x01, -}; -static constexpr Bitmap bitmap_icon_hackrf { - { 16, 16 }, bitmap_icon_hackrf_data -}; - -static constexpr uint8_t bitmap_icon_soundboard_data[] = { - 0xF0, 0x0F, - 0x1C, 0x18, - 0x17, 0x38, - 0x15, 0x78, - 0x15, 0xF8, - 0x15, 0x82, - 0x15, 0x8B, - 0xD5, 0x83, - 0xD5, 0xBB, - 0xD5, 0x83, - 0x15, 0x8B, - 0x15, 0x92, - 0x15, 0xA0, - 0x17, 0x80, - 0x1C, 0x80, - 0xF0, 0xFF, -}; -static constexpr Bitmap bitmap_icon_soundboard { - { 16, 16 }, bitmap_icon_soundboard_data -}; - -static constexpr uint8_t bitmap_icon_dmr_data[] = { - 0x00, 0x00, - 0xFE, 0x1F, - 0xFE, 0x3F, - 0x0E, 0x78, - 0x0E, 0x70, - 0x0E, 0x70, - 0x0E, 0x70, - 0x0E, 0x78, - 0xFE, 0x3F, - 0xFE, 0x1F, - 0x8E, 0x07, - 0x0E, 0x0F, - 0x0E, 0x1E, - 0x0E, 0x3C, - 0x0E, 0x78, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_dmr { - { 16, 16 }, bitmap_icon_dmr_data -}; - -static constexpr uint8_t bitmap_icon_burger_data[] = { - 0x00, 0x00, - 0xE0, 0x07, - 0xF8, 0x1F, - 0xFC, 0x3F, - 0xFE, 0x7F, - 0xFF, 0xFF, - 0xFF, 0xFF, - 0x00, 0x00, - 0x55, 0x55, - 0xAA, 0xAA, - 0x55, 0x55, - 0x00, 0x00, - 0xFF, 0xFF, - 0xFF, 0xFF, - 0xFE, 0x7F, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_burger { - { 16, 16 }, bitmap_icon_burger_data -}; - -static constexpr uint8_t bitmap_icon_microphone_data[] = { - 0xC0, 0x03, - 0xE0, 0x07, - 0xE0, 0x07, - 0xE0, 0x07, - 0xE8, 0x17, - 0xE8, 0x17, - 0xE8, 0x17, - 0xE8, 0x17, - 0xE8, 0x17, - 0xC8, 0x13, - 0x18, 0x18, - 0xF0, 0x0F, - 0xC0, 0x03, - 0x80, 0x01, - 0x80, 0x01, - 0xE0, 0x07, -}; -static constexpr Bitmap bitmap_icon_microphone { - { 16, 16 }, bitmap_icon_microphone_data -}; - -static constexpr uint8_t bitmap_icon_ais_data[] = { - 0x00, 0x01, - 0x80, 0x01, - 0xC0, 0x01, - 0xC0, 0x0D, - 0xE0, 0x3D, - 0xF0, 0x3D, - 0xF8, 0x7D, - 0xFC, 0x7D, - 0xFC, 0x7D, - 0xFE, 0x7D, - 0xFF, 0x7D, - 0x00, 0x00, - 0xF8, 0x7F, - 0xF8, 0x3F, - 0xF0, 0x0F, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_ais { - { 16, 16 }, bitmap_icon_ais_data -}; - -static constexpr uint8_t bitmap_icon_utilities_data[] = { - 0x30, 0x24, - 0x78, 0x66, - 0x78, 0x66, - 0x78, 0x7E, - 0x78, 0x3C, - 0x78, 0x18, - 0x78, 0x18, - 0x30, 0x3C, - 0x30, 0x3C, - 0x30, 0x3C, - 0x30, 0x3C, - 0x30, 0x3C, - 0x30, 0x3C, - 0x30, 0x3C, - 0x30, 0x18, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_utilities { - { 16, 16 }, bitmap_icon_utilities_data -}; - -static constexpr uint8_t bitmap_icon_delete_data[] = { - 0x00, 0x00, - 0x00, 0x00, - 0x0C, 0x30, - 0x1C, 0x38, - 0x38, 0x1C, - 0x70, 0x0E, - 0xE0, 0x07, - 0xC0, 0x03, - 0xC0, 0x03, - 0xE0, 0x07, - 0x70, 0x0E, - 0x38, 0x1C, - 0x1C, 0x38, - 0x0C, 0x30, - 0x00, 0x00, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_delete { - { 16, 16 }, bitmap_icon_delete_data -}; - -static constexpr uint8_t bitmap_icon_peripherals_data[] = { - 0x54, 0x01, - 0x54, 0x01, - 0xFF, 0x07, - 0x7C, 0x01, - 0xBF, 0x07, - 0xDC, 0x18, - 0x6F, 0x10, - 0x2C, 0x21, - 0xAF, 0x20, - 0x34, 0x20, - 0x54, 0x10, - 0xC0, 0x38, - 0x00, 0x77, - 0x00, 0xE0, - 0x00, 0xC0, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_peripherals { - { 16, 16 }, bitmap_icon_peripherals_data -}; - -static constexpr uint8_t bitmap_icon_file_data[] = { - 0xFC, 0x03, - 0x04, 0x06, - 0x04, 0x0E, - 0x04, 0x1E, - 0x04, 0x3E, - 0x04, 0x20, - 0x04, 0x20, - 0x04, 0x20, - 0x04, 0x20, - 0x04, 0x20, - 0x04, 0x20, - 0x04, 0x20, - 0x04, 0x20, - 0x04, 0x20, - 0x04, 0x20, - 0xFC, 0x3F, -}; -static constexpr Bitmap bitmap_icon_file { - { 16, 16 }, bitmap_icon_file_data -}; - -static constexpr uint8_t bitmap_icon_debug_data[] = { - 0xFE, 0x03, - 0x02, 0x07, - 0x2A, 0x0D, - 0x52, 0x0F, - 0x2A, 0x08, - 0x52, 0x09, - 0xAA, 0x0A, - 0x52, 0x09, - 0xAA, 0x0A, - 0x52, 0x01, - 0xAA, 0x12, - 0x02, 0x08, - 0x02, 0xFC, - 0x02, 0x08, - 0xFE, 0x13, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_debug { - { 16, 16 }, bitmap_icon_debug_data -}; - -static constexpr uint8_t bitmap_icon_previous_data[] = { - 0x00, 0x00, - 0xC0, 0x00, - 0xE0, 0x00, - 0x70, 0x00, - 0x38, 0x00, - 0x1C, 0x00, - 0x0E, 0x00, - 0xFF, 0xFF, - 0xFF, 0xFF, - 0x0E, 0x00, - 0x1C, 0x00, - 0x38, 0x00, - 0x70, 0x00, - 0xE0, 0x00, - 0xC0, 0x00, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_previous { - { 16, 16 }, bitmap_icon_previous_data -}; - -static constexpr uint8_t bitmap_icon_freqman_data[] = { - 0x00, 0x00, - 0x00, 0x00, - 0x00, 0x00, - 0x7E, 0x7E, - 0x81, 0x81, - 0xBD, 0xBD, - 0x81, 0x81, - 0xBD, 0xBD, - 0x81, 0x81, - 0xBD, 0x9D, - 0x81, 0x81, - 0xBD, 0xE1, - 0x81, 0x61, - 0x7E, 0x3E, - 0x00, 0x00, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_freqman { - { 16, 16 }, bitmap_icon_freqman_data -}; - -static constexpr uint8_t bitmap_stop_data[] = { - 0xFF, 0xFF, - 0xFF, 0xFF, - 0xFF, 0xFF, - 0xFF, 0xFF, - 0xFF, 0xFF, - 0x8B, 0xCD, - 0xDD, 0xAA, - 0xDB, 0xCA, - 0xDB, 0xEA, - 0xDD, 0xED, - 0xFF, 0xFF, - 0xFF, 0xFF, - 0xFF, 0xFF, - 0xFF, 0xFF, - 0xFF, 0xFF, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_stop { - { 16, 16 }, bitmap_stop_data -}; - -static constexpr uint8_t bitmap_icon_biast_off_data[] = { - 0x00, 0x00, - 0xFE, 0x7F, - 0x00, 0x04, - 0x00, 0x08, - 0x00, 0x10, - 0x00, 0x08, - 0x88, 0x04, - 0x50, 0x08, - 0x20, 0x10, - 0x50, 0x08, - 0x88, 0x04, - 0x00, 0x08, - 0x00, 0x10, - 0x00, 0x08, - 0x00, 0x04, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_biast_off { - { 16, 16 }, bitmap_icon_biast_off_data -}; - -static constexpr uint8_t bitmap_tab_edge_data[] = { - 0x00, - 0x01, - 0x01, - 0x03, - 0x03, - 0x03, - 0x07, - 0x07, - 0x07, - 0x0F, - 0x0F, - 0x0F, - 0x1F, - 0x1F, - 0x1F, - 0x1F, - 0x3F, - 0x3F, - 0x3F, - 0x7F, - 0x7F, - 0x7F, - 0xFF, - 0xFF, -}; -static constexpr Bitmap bitmap_tab_edge { - { 8, 24 }, bitmap_tab_edge_data -}; - -static constexpr uint8_t bitmap_sig_square_data[] = { - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0xFE, 0x83, 0xFF, 0x60, - 0xFE, 0x83, 0xFF, 0x60, - 0x06, 0x83, 0xC1, 0x60, - 0x06, 0x83, 0xC1, 0x60, - 0x06, 0x83, 0xC1, 0x60, - 0x06, 0x83, 0xC1, 0x60, - 0x06, 0x83, 0xC1, 0x60, - 0x06, 0x83, 0xC1, 0x60, - 0x06, 0x83, 0xC1, 0x60, - 0x06, 0x83, 0xC1, 0x60, - 0x06, 0x83, 0xC1, 0x60, - 0x06, 0x83, 0xC1, 0x60, - 0x06, 0x83, 0xC1, 0x60, - 0x06, 0x83, 0xC1, 0x60, - 0x06, 0xFF, 0xC1, 0x7F, - 0x06, 0xFF, 0xC1, 0x7F, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, -}; -static constexpr Bitmap bitmap_sig_square { - { 32, 32 }, bitmap_sig_square_data -}; - -static constexpr uint8_t bitmap_icon_new_category_data[] = { - 0x00, 0x18, - 0x3E, 0x18, - 0x41, 0x7E, - 0xC1, 0x7E, - 0xFF, 0x18, - 0xFF, 0xDB, - 0xFF, 0xC3, - 0xFF, 0xFF, - 0xFF, 0xFF, - 0xFF, 0xFF, - 0xAF, 0xEA, - 0x57, 0xF5, - 0xEF, 0xEF, - 0xF7, 0xF7, - 0xEE, 0x6F, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_new_category { - { 16, 16 }, bitmap_icon_new_category_data -}; - -static constexpr uint8_t bitmap_icon_lcr_data[] = { - 0x0C, 0x00, - 0xFF, 0x7F, - 0x01, 0x80, - 0xC1, 0x9B, - 0xFF, 0x7F, - 0x0C, 0x00, - 0xFF, 0x7F, - 0x01, 0x80, - 0xC1, 0x9D, - 0xFF, 0x7F, - 0x0C, 0x00, - 0x0C, 0x00, - 0x0C, 0x00, - 0x0C, 0x00, - 0x0C, 0x00, - 0x0C, 0x00, -}; -static constexpr Bitmap bitmap_icon_lcr { - { 16, 16 }, bitmap_icon_lcr_data -}; - -static constexpr uint8_t bitmap_icon_pocsag_data[] = { - 0x00, 0x00, - 0x00, 0x00, - 0x00, 0x00, - 0xFC, 0x3F, - 0xFE, 0x7F, - 0x02, 0x40, - 0xBA, 0x45, - 0x02, 0x40, - 0xFE, 0x7F, - 0xFE, 0x7F, - 0x92, 0x7C, - 0x92, 0x7C, - 0xFC, 0x3F, - 0x00, 0x00, - 0x00, 0x00, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_pocsag { - { 16, 16 }, bitmap_icon_pocsag_data -}; - -static constexpr uint8_t bitmap_icon_scanner_data[] = { - 0x03, 0x00, - 0x00, 0x00, - 0x03, 0x00, - 0x00, 0x00, - 0x0F, 0x00, - 0x00, 0x00, - 0x03, 0x01, - 0x80, 0x01, - 0xC3, 0x00, - 0xE0, 0xFF, - 0xEF, 0xFF, - 0xC0, 0x00, - 0x83, 0x01, - 0x00, 0x01, - 0x03, 0x00, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_scanner { - { 16, 16 }, bitmap_icon_scanner_data -}; - -static constexpr uint8_t bitmap_more_data[] = { - 0x10, - 0x10, - 0x10, - 0x10, - 0x54, - 0x38, - 0x10, - 0x00, -}; -static constexpr Bitmap bitmap_more { - { 8, 8 }, bitmap_more_data -}; - -static constexpr uint8_t bitmap_icon_modem_data[] = { - 0x00, 0x00, - 0x00, 0x00, - 0x00, 0x00, - 0x00, 0x00, - 0xF8, 0x1F, - 0x04, 0x20, - 0x02, 0x40, - 0xFF, 0xFF, - 0xFF, 0xFF, - 0xAB, 0xDF, - 0xAB, 0xDF, - 0xFF, 0xFF, - 0xFF, 0xFF, - 0x00, 0x00, - 0x00, 0x00, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_modem { - { 16, 16 }, bitmap_icon_modem_data -}; - -static constexpr uint8_t bitmap_icon_file_image_data[] = { - 0x00, 0x00, - 0xFF, 0xFF, - 0x01, 0x80, - 0x01, 0x80, - 0x89, 0x80, - 0xC1, 0x81, - 0xE1, 0xA3, - 0xB1, 0xB3, - 0x89, 0xDC, - 0x07, 0x8C, - 0x01, 0x90, - 0x01, 0x80, - 0xAB, 0x82, - 0xFF, 0xD5, - 0xFF, 0xFF, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_file_image { - { 16, 16 }, bitmap_icon_file_image_data -}; - -static constexpr uint8_t bitmap_icon_save_data[] = { - 0x00, 0x01, - 0x00, 0x01, - 0x00, 0x01, - 0x00, 0x01, - 0x4E, 0x05, - 0x91, 0x03, - 0x3F, 0x19, - 0x01, 0x20, - 0xF9, 0xFF, - 0xF9, 0xFF, - 0xFD, 0x7F, - 0xFD, 0x7F, - 0xFF, 0x3F, - 0xFF, 0x3F, - 0xFF, 0x1F, - 0xFF, 0x1F, -}; -static constexpr Bitmap bitmap_icon_save { - { 16, 16 }, bitmap_icon_save_data -}; - -static constexpr uint8_t bitmap_icon_stealth_data[] = { - 0x00, 0x00, - 0xC0, 0x03, - 0xE0, 0x07, - 0xE0, 0x07, - 0xF8, 0x1F, - 0x00, 0x00, - 0xE0, 0x07, - 0x60, 0x06, - 0x00, 0x00, - 0xF0, 0x0F, - 0xF0, 0x0F, - 0xF8, 0x1E, - 0xFC, 0x3F, - 0xFC, 0x3E, - 0xFC, 0x3F, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_stealth { - { 16, 16 }, bitmap_icon_stealth_data -}; - -static constexpr uint8_t bitmap_icon_controls_data[] = { - 0x8C, 0x31, - 0x5A, 0x6B, - 0xDE, 0x7B, - 0x8C, 0x31, - 0x00, 0x00, - 0x8C, 0x31, - 0x5A, 0x7B, - 0xDE, 0x7B, - 0x8C, 0x31, - 0x00, 0x00, - 0x8C, 0x31, - 0xDA, 0x7B, - 0xDE, 0x7B, - 0x8C, 0x31, - 0x00, 0x00, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_controls { - { 16, 16 }, bitmap_icon_controls_data -}; - -static constexpr uint8_t bitmap_icon_rds_data[] = { - 0x00, 0x00, - 0x00, 0x00, - 0x00, 0x00, - 0x00, 0x00, - 0x3C, 0x3C, - 0x7E, 0x7E, - 0x67, 0xE7, - 0x83, 0xC3, - 0xC7, 0xE1, - 0xFD, 0xBC, - 0x42, 0x42, - 0x3C, 0x3C, - 0x00, 0x00, - 0x00, 0x00, - 0x00, 0x00, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_rds { - { 16, 16 }, bitmap_icon_rds_data -}; - static constexpr uint8_t bitmap_bulb_off_data[] = { 0x00, 0x3C, 0x00, 0x00, 0xC3, 0x00, @@ -1185,356 +89,78 @@ static constexpr Bitmap bitmap_bulb_off { { 24, 24 }, bitmap_bulb_off_data }; -static constexpr uint8_t bitmap_icon_speaker_data[] = { - 0x00, 0x00, - 0x40, 0x10, - 0x60, 0x20, - 0x70, 0x44, - 0x78, 0x48, - 0x7F, 0x91, - 0x7F, 0x92, - 0x7F, 0x92, - 0x7F, 0x92, - 0x7F, 0x92, - 0x7F, 0x92, - 0x7F, 0x91, - 0x78, 0x48, - 0x70, 0x44, - 0x60, 0x20, - 0x40, 0x10, +static constexpr uint8_t bitmap_bulb_on_data[] = { + 0x04, 0x3C, 0x20, + 0x08, 0xFF, 0x10, + 0x90, 0xFF, 0x09, + 0xC0, 0xFF, 0x03, + 0xE0, 0xFF, 0x07, + 0xE0, 0xFF, 0x07, + 0xF0, 0xE7, 0x0F, + 0xF0, 0xBD, 0x0F, + 0xF7, 0xBD, 0xEF, + 0xF0, 0xDB, 0x0F, + 0xF0, 0xDB, 0x0F, + 0xE0, 0xDB, 0x07, + 0xE0, 0xCB, 0x07, + 0xC0, 0xD3, 0x03, + 0x90, 0xCB, 0x09, + 0x08, 0xFD, 0x10, + 0x04, 0xE3, 0x20, + 0x00, 0xBD, 0x00, + 0x00, 0xC3, 0x00, + 0x00, 0xBD, 0x00, + 0x00, 0xC3, 0x00, + 0x00, 0xBD, 0x00, + 0x00, 0x42, 0x00, + 0x00, 0x3C, 0x00, }; -static constexpr Bitmap bitmap_icon_speaker { - { 16, 16 }, bitmap_icon_speaker_data +static constexpr Bitmap bitmap_bulb_on { + { 24, 24 }, bitmap_bulb_on_data }; -static constexpr uint8_t bitmap_icon_btle_data[] = { - 0xE0, 0x03, - 0x30, 0x07, - 0x38, 0x0E, - 0x3C, 0x1C, - 0x24, 0x19, - 0x0C, 0x13, - 0x1C, 0x19, - 0x3C, 0x1C, - 0x3C, 0x1C, - 0x1C, 0x19, - 0x0C, 0x13, - 0x24, 0x19, - 0x3C, 0x1C, - 0x38, 0x0E, - 0x30, 0x07, - 0xE0, 0x03, -}; -static constexpr Bitmap bitmap_icon_btle { - { 16, 16 }, bitmap_icon_btle_data -}; - -static constexpr uint8_t bitmap_icon_biast_on_data[] = { - 0x00, 0x00, - 0xFE, 0x7F, - 0x00, 0x04, - 0x00, 0x08, - 0x20, 0x10, - 0x20, 0x08, - 0x30, 0x04, - 0x30, 0x08, - 0xF8, 0x10, - 0x60, 0x08, - 0x60, 0x04, - 0x20, 0x08, - 0x20, 0x10, - 0x00, 0x08, - 0x00, 0x04, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_biast_on { - { 16, 16 }, bitmap_icon_biast_on_data -}; - -static constexpr uint8_t bitmap_icon_transmit_data[] = { +static constexpr uint8_t bitmap_icon_adsb_data[] = { 0x80, 0x01, 0xC0, 0x03, + 0xC0, 0x03, + 0xC0, 0x03, + 0xC0, 0x03, 0xE0, 0x07, - 0xB0, 0x0D, - 0x98, 0x19, - 0x80, 0x01, - 0x80, 0x01, - 0x80, 0x01, - 0x80, 0x01, - 0x80, 0x01, - 0x80, 0x01, - 0x80, 0x01, - 0x83, 0xC1, - 0x03, 0xC0, + 0xF8, 0x1F, + 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, -}; -static constexpr Bitmap bitmap_icon_transmit { - { 16, 16 }, bitmap_icon_transmit_data -}; - -static constexpr uint8_t bitmap_sd_card_unknown_data[] = { - 0x00, 0x00, - 0x00, 0x00, - 0xC0, 0x1F, - 0xE0, 0x1F, - 0xF0, 0x1F, - 0xF8, 0x1F, - 0x38, 0x1C, - 0x98, 0x19, - 0xF8, 0x1C, - 0x78, 0x1E, - 0x78, 0x1E, - 0xF8, 0x1F, - 0x78, 0x1E, - 0xF8, 0x1F, - 0x00, 0x00, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_sd_card_unknown { - { 16, 16 }, bitmap_sd_card_unknown_data -}; - -static constexpr uint8_t bitmap_icon_notepad_data[] = { - 0x0C, 0x00, - 0x1E, 0x00, - 0x2F, 0x00, - 0x47, 0x00, - 0xE2, 0x00, - 0xD4, 0x01, - 0xB8, 0x03, - 0x70, 0x07, - 0xE0, 0x0E, - 0xC0, 0x1D, - 0x80, 0x3B, - 0x00, 0x4F, - 0x00, 0x46, - 0x00, 0x84, - 0x00, 0xD8, - 0x00, 0xE0, -}; -static constexpr Bitmap bitmap_icon_notepad { - { 16, 16 }, bitmap_icon_notepad_data -}; - -static constexpr uint8_t bitmap_icon_memory_data[] = { - 0x54, 0x15, - 0x54, 0x15, - 0xFF, 0x7F, - 0xFC, 0x1F, - 0xFF, 0x7F, - 0xCC, 0x19, - 0xAF, 0x7A, - 0x6C, 0x1B, - 0xEF, 0x7B, - 0xEC, 0x1B, - 0xFF, 0x7F, - 0xFC, 0x1F, - 0xFF, 0x7F, - 0x54, 0x15, - 0x54, 0x15, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_memory { - { 16, 16 }, bitmap_icon_memory_data -}; - -static constexpr uint8_t bitmap_icon_tpms_data[] = { 0xC0, 0x03, + 0xC0, 0x03, + 0xC0, 0x03, + 0xE0, 0x07, 0xF0, 0x0F, - 0x18, 0x18, - 0xEC, 0x37, - 0x36, 0x6C, - 0x1A, 0x58, - 0x0B, 0xD0, - 0x0B, 0xD0, - 0x0B, 0xD0, - 0x0B, 0xD0, - 0x1A, 0x58, - 0x36, 0x6C, - 0xEC, 0x37, - 0x18, 0x18, + 0xF8, 0x1F, +}; +static constexpr Bitmap bitmap_icon_adsb { + { 16, 16 }, bitmap_icon_adsb_data +}; + +static constexpr uint8_t bitmap_icon_ais_data[] = { + 0x00, 0x01, + 0x80, 0x01, + 0xC0, 0x01, + 0xC0, 0x0D, + 0xE0, 0x3D, + 0xF0, 0x3D, + 0xF8, 0x7D, + 0xFC, 0x7D, + 0xFC, 0x7D, + 0xFE, 0x7D, + 0xFF, 0x7D, + 0x00, 0x00, + 0xF8, 0x7F, + 0xF8, 0x3F, 0xF0, 0x0F, - 0xC0, 0x03, -}; -static constexpr Bitmap bitmap_icon_tpms { - { 16, 16 }, bitmap_icon_tpms_data -}; - -static constexpr uint8_t bitmap_icon_tetra_data[] = { - 0xE0, 0x0F, - 0x18, 0x38, - 0xE4, 0x67, - 0x7E, 0xCE, - 0xC7, 0xCC, - 0x00, 0x00, - 0xFF, 0x4F, - 0xBA, 0xB2, - 0x9A, 0xEE, - 0xBA, 0xB2, - 0x00, 0x00, - 0x3B, 0xE3, - 0x73, 0x7E, - 0xC6, 0x27, - 0x1C, 0x18, - 0xF0, 0x07, -}; -static constexpr Bitmap bitmap_icon_tetra { - { 16, 16 }, bitmap_icon_tetra_data -}; - -static constexpr uint8_t bitmap_icon_capture_data[] = { - 0xE0, 0x07, - 0xF8, 0x1F, - 0xFC, 0x3F, - 0xFE, 0x7F, - 0xFE, 0x7F, - 0xFF, 0xFF, - 0xFF, 0xFF, - 0xFF, 0xFF, - 0xFF, 0xFF, - 0xFF, 0xFF, - 0xFF, 0xFF, - 0xFE, 0x7F, - 0xFE, 0x7F, - 0xFC, 0x3F, - 0xF8, 0x1F, - 0xE0, 0x07, -}; -static constexpr Bitmap bitmap_icon_capture { - { 16, 16 }, bitmap_icon_capture_data -}; - -static constexpr uint8_t bitmap_icon_file_wav_data[] = { - 0xFC, 0x03, - 0x04, 0x06, - 0x04, 0x0E, - 0x04, 0x1E, - 0x04, 0x3E, - 0x84, 0x20, - 0xC4, 0x22, - 0xF4, 0x20, - 0xF4, 0x2E, - 0xF4, 0x20, - 0xC4, 0x22, - 0x84, 0x24, - 0x04, 0x28, - 0x04, 0x20, - 0x04, 0x20, - 0xFC, 0x3F, -}; -static constexpr Bitmap bitmap_icon_file_wav { - { 16, 16 }, bitmap_icon_file_wav_data -}; - -static constexpr uint8_t bitmap_icon_file_text_data[] = { - 0xFC, 0x03, - 0x04, 0x06, - 0x04, 0x0E, - 0x04, 0x1E, - 0xF4, 0x3E, - 0x04, 0x20, - 0xF4, 0x2F, - 0x04, 0x20, - 0xF4, 0x2F, - 0x04, 0x20, - 0xF4, 0x2F, - 0x04, 0x20, - 0xF4, 0x2F, - 0x04, 0x20, - 0x04, 0x20, - 0xFC, 0x3F, -}; -static constexpr Bitmap bitmap_icon_file_text { - { 16, 16 }, bitmap_icon_file_text_data -}; - -static constexpr uint8_t bitmap_icon_sd_data[] = { - 0x00, 0x00, - 0x00, 0x00, - 0xC0, 0x1F, - 0xE0, 0x1F, - 0xF0, 0x1F, - 0xF8, 0x1F, - 0x98, 0x18, - 0xE8, 0x16, - 0xC8, 0x16, - 0x98, 0x16, - 0xB8, 0x16, - 0xC8, 0x18, - 0xF8, 0x1F, - 0xF8, 0x1F, - 0x00, 0x00, 0x00, 0x00, }; -static constexpr Bitmap bitmap_icon_sd { - { 16, 16 }, bitmap_icon_sd_data -}; - -static constexpr uint8_t bitmap_icon_dir_data[] = { - 0x00, 0x00, - 0x3E, 0x00, - 0x41, 0x00, - 0xC1, 0x7F, - 0xFF, 0xFF, - 0xFF, 0xFF, - 0xFF, 0xFF, - 0xFF, 0xFF, - 0xFF, 0xFF, - 0xFF, 0xFF, - 0xAF, 0xEA, - 0x57, 0xF5, - 0xEF, 0xEF, - 0xF7, 0xF7, - 0xEE, 0x6F, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_dir { - { 16, 16 }, bitmap_icon_dir_data -}; - -static constexpr uint8_t bitmap_icon_options_touch_data[] = { - 0xC7, 0xF1, - 0x97, 0xF4, - 0x27, 0xF2, - 0x8F, 0xF8, - 0x5F, 0xFD, - 0x47, 0xFD, - 0x53, 0xC1, - 0x4B, 0x9F, - 0x43, 0xB5, - 0x6F, 0xA0, - 0x2F, 0xA0, - 0x20, 0x20, - 0x60, 0x20, - 0x40, 0x10, - 0xC0, 0x1F, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_options_touch { - { 16, 16 }, bitmap_icon_options_touch_data -}; - -static constexpr uint8_t bitmap_icon_nuoptix_data[] = { - 0x80, 0x01, - 0x80, 0x01, - 0x40, 0x02, - 0x40, 0x1A, - 0x40, 0x1A, - 0x20, 0x0C, - 0x20, 0x0F, - 0x20, 0x1E, - 0x10, 0x0E, - 0x10, 0x0B, - 0x10, 0x0B, - 0xF8, 0x1F, - 0xF8, 0x1F, - 0xF8, 0x1F, - 0xFC, 0x3F, - 0xFC, 0x3F, -}; -static constexpr Bitmap bitmap_icon_nuoptix { - { 16, 16 }, bitmap_icon_nuoptix_data +static constexpr Bitmap bitmap_icon_ais { + { 16, 16 }, bitmap_icon_ais_data }; static constexpr uint8_t bitmap_icon_aprs_data[] = { @@ -1559,62 +185,620 @@ static constexpr Bitmap bitmap_icon_aprs { { 16, 16 }, bitmap_icon_aprs_data }; -static constexpr uint8_t bitmap_stripes_data[] = { - 0xFF, 0x03, 0xC0, - 0xFF, 0x01, 0xE0, - 0xFF, 0x00, 0xF0, - 0x7F, 0x00, 0xF8, - 0x3F, 0x00, 0xFC, - 0x1F, 0x00, 0xFE, - 0x0F, 0x00, 0xFF, - 0x07, 0x80, 0xFF, +static constexpr uint8_t bitmap_icon_back_data[] = { + 0x00, 0x00, + 0x30, 0x00, + 0x38, 0x00, + 0x1C, 0x00, + 0x0E, 0x00, + 0xFF, 0x3F, + 0xFF, 0x7F, + 0x0E, 0xE0, + 0x1C, 0xC0, + 0x38, 0xC0, + 0x30, 0xC0, + 0x00, 0xE0, + 0x00, 0x7F, + 0x00, 0x3F, + 0x00, 0x00, + 0x00, 0x00, }; -static constexpr Bitmap bitmap_stripes { - { 24, 8 }, bitmap_stripes_data +static constexpr Bitmap bitmap_icon_back { + { 16, 16 }, bitmap_icon_back_data }; -static constexpr uint8_t bitmap_icon_sonde_data[] = { - 0x80, 0x03, - 0xE0, 0x0F, - 0xE0, 0x0F, - 0xF0, 0x1F, - 0xF0, 0x1F, - 0xF0, 0x1F, - 0xE0, 0x0F, - 0xE0, 0x0F, +static constexpr uint8_t bitmap_icon_bht_data[] = { 0x00, 0x00, - 0x20, 0x09, + 0xE0, 0x07, + 0xF8, 0x08, + 0x9C, 0x07, + 0x0C, 0x00, + 0x8E, 0x0A, + 0x46, 0x12, + 0x26, 0x22, + 0x06, 0x02, + 0x06, 0x00, + 0x06, 0x00, + 0x06, 0x00, + 0x06, 0x00, + 0x06, 0x00, + 0x06, 0x00, 0x00, 0x00, - 0x40, 0x05, - 0x00, 0x00, - 0xC0, 0x07, - 0xC0, 0x07, - 0xC0, 0x07, }; -static constexpr Bitmap bitmap_icon_sonde { - { 16, 16 }, bitmap_icon_sonde_data +static constexpr Bitmap bitmap_icon_bht { + { 16, 16 }, bitmap_icon_bht_data }; -static constexpr uint8_t bitmap_icon_sleep_data[] = { - 0x00, 0x00, +static constexpr uint8_t bitmap_icon_biast_off_data[] = { 0x00, 0x00, + 0xFE, 0x7F, 0x00, 0x04, 0x00, 0x08, - 0x00, 0x18, - 0x00, 0x18, - 0x00, 0x38, - 0x00, 0x3C, - 0x00, 0x3C, - 0x00, 0x3E, - 0x84, 0x1F, + 0x00, 0x10, + 0x00, 0x08, + 0x88, 0x04, + 0x50, 0x08, + 0x20, 0x10, + 0x50, 0x08, + 0x88, 0x04, + 0x00, 0x08, + 0x00, 0x10, + 0x00, 0x08, + 0x00, 0x04, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_icon_biast_off { + { 16, 16 }, bitmap_icon_biast_off_data +}; + +static constexpr uint8_t bitmap_icon_biast_on_data[] = { + 0x00, 0x00, + 0xFE, 0x7F, + 0x00, 0x04, + 0x00, 0x08, + 0x20, 0x10, + 0x20, 0x08, + 0x30, 0x04, + 0x30, 0x08, + 0xF8, 0x10, + 0x60, 0x08, + 0x60, 0x04, + 0x20, 0x08, + 0x20, 0x10, + 0x00, 0x08, + 0x00, 0x04, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_icon_biast_on { + { 16, 16 }, bitmap_icon_biast_on_data +}; + +static constexpr uint8_t bitmap_icon_btle_data[] = { + 0xE0, 0x03, + 0x30, 0x07, + 0x38, 0x0E, + 0x3C, 0x1C, + 0x24, 0x19, + 0x0C, 0x13, + 0x1C, 0x19, + 0x3C, 0x1C, + 0x3C, 0x1C, + 0x1C, 0x19, + 0x0C, 0x13, + 0x24, 0x19, + 0x3C, 0x1C, + 0x38, 0x0E, + 0x30, 0x07, + 0xE0, 0x03, +}; +static constexpr Bitmap bitmap_icon_btle { + { 16, 16 }, bitmap_icon_btle_data +}; + +static constexpr uint8_t bitmap_icon_burger_data[] = { + 0x00, 0x00, + 0xE0, 0x07, 0xF8, 0x1F, + 0xFC, 0x3F, + 0xFE, 0x7F, + 0xFF, 0xFF, + 0xFF, 0xFF, + 0x00, 0x00, + 0x55, 0x55, + 0xAA, 0xAA, + 0x55, 0x55, + 0x00, 0x00, + 0xFF, 0xFF, + 0xFF, 0xFF, + 0xFE, 0x7F, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_icon_burger { + { 16, 16 }, bitmap_icon_burger_data +}; + +static constexpr uint8_t bitmap_icon_camera_data[] = { + 0x00, 0x00, + 0x00, 0x00, + 0xE0, 0x07, 0xF0, 0x0F, - 0xC0, 0x03, + 0x3E, 0x7C, + 0xDE, 0x7B, + 0xEE, 0x77, + 0xEE, 0x77, + 0xEE, 0x77, + 0xEE, 0x77, + 0xDE, 0x7B, + 0x3E, 0x7C, + 0xFE, 0x7F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; -static constexpr Bitmap bitmap_icon_sleep { - { 16, 16 }, bitmap_icon_sleep_data +static constexpr Bitmap bitmap_icon_camera { + { 16, 16 }, bitmap_icon_camera_data +}; + +static constexpr uint8_t bitmap_icon_capture_data[] = { + 0xE0, 0x07, + 0xF8, 0x1F, + 0xFC, 0x3F, + 0xFE, 0x7F, + 0xFE, 0x7F, + 0xFF, 0xFF, + 0xFF, 0xFF, + 0xFF, 0xFF, + 0xFF, 0xFF, + 0xFF, 0xFF, + 0xFF, 0xFF, + 0xFE, 0x7F, + 0xFE, 0x7F, + 0xFC, 0x3F, + 0xF8, 0x1F, + 0xE0, 0x07, +}; +static constexpr Bitmap bitmap_icon_capture { + { 16, 16 }, bitmap_icon_capture_data +}; + +static constexpr uint8_t bitmap_icon_clk_ext_data[] = { + 0x00, + 0x00, + 0xDC, + 0x54, + 0x54, + 0x54, + 0x54, + 0x76, + 0x00, + 0x10, + 0x38, + 0x7C, + 0x10, + 0x10, + 0x10, + 0x00, +}; +static constexpr Bitmap bitmap_icon_clk_ext { + { 8, 16 }, bitmap_icon_clk_ext_data +}; + +static constexpr uint8_t bitmap_icon_clk_int_data[] = { + 0x00, + 0x00, + 0xDC, + 0x54, + 0x54, + 0x54, + 0x54, + 0x76, + 0x00, + 0x44, + 0x6C, + 0x38, + 0x38, + 0x6C, + 0x44, + 0x00, +}; +static constexpr Bitmap bitmap_icon_clk_int { + { 8, 16 }, bitmap_icon_clk_int_data +}; + +static constexpr uint8_t bitmap_icon_codetx_data[] = { + 0x00, 0x00, + 0xF0, 0x07, + 0x0C, 0x18, + 0x03, 0x60, + 0xE0, 0x03, + 0x18, 0x0C, + 0x04, 0x10, + 0xC0, 0x01, + 0x20, 0x02, + 0x00, 0x00, + 0x00, 0x00, + 0xBB, 0x6D, + 0x2A, 0x49, + 0x2A, 0x49, + 0x3A, 0x49, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_icon_codetx { + { 16, 16 }, bitmap_icon_codetx_data +}; + +static constexpr uint8_t bitmap_icon_controls_data[] = { + 0x8C, 0x31, + 0x5A, 0x6B, + 0xDE, 0x7B, + 0x8C, 0x31, + 0x00, 0x00, + 0x8C, 0x31, + 0x5A, 0x7B, + 0xDE, 0x7B, + 0x8C, 0x31, + 0x00, 0x00, + 0x8C, 0x31, + 0xDA, 0x7B, + 0xDE, 0x7B, + 0x8C, 0x31, + 0x00, 0x00, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_icon_controls { + { 16, 16 }, bitmap_icon_controls_data +}; + +static constexpr uint8_t bitmap_icon_cwgen_data[] = { + 0x18, 0x00, + 0x24, 0x00, + 0x42, 0x00, + 0x42, 0x00, + 0x42, 0x00, + 0x42, 0x00, + 0x81, 0x00, + 0xAB, 0x6A, + 0x80, 0x40, + 0x00, 0x21, + 0x00, 0x21, + 0x00, 0x21, + 0x00, 0x21, + 0x00, 0x12, + 0x00, 0x0C, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_icon_cwgen { + { 16, 16 }, bitmap_icon_cwgen_data +}; + +static constexpr uint8_t bitmap_icon_debug_data[] = { + 0xFE, 0x03, + 0x02, 0x07, + 0x2A, 0x0D, + 0x52, 0x0F, + 0x2A, 0x08, + 0x52, 0x09, + 0xAA, 0x0A, + 0x52, 0x09, + 0xAA, 0x0A, + 0x52, 0x01, + 0xAA, 0x12, + 0x02, 0x08, + 0x02, 0xFC, + 0x02, 0x08, + 0xFE, 0x13, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_icon_debug { + { 16, 16 }, bitmap_icon_debug_data +}; + +static constexpr uint8_t bitmap_icon_delete_data[] = { + 0x00, 0x00, + 0x00, 0x00, + 0x0C, 0x30, + 0x1C, 0x38, + 0x38, 0x1C, + 0x70, 0x0E, + 0xE0, 0x07, + 0xC0, 0x03, + 0xC0, 0x03, + 0xE0, 0x07, + 0x70, 0x0E, + 0x38, 0x1C, + 0x1C, 0x38, + 0x0C, 0x30, + 0x00, 0x00, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_icon_delete { + { 16, 16 }, bitmap_icon_delete_data +}; + +static constexpr uint8_t bitmap_icon_dir_data[] = { + 0x00, 0x00, + 0x3E, 0x00, + 0x41, 0x00, + 0xC1, 0x7F, + 0xFF, 0xFF, + 0xFF, 0xFF, + 0xFF, 0xFF, + 0xFF, 0xFF, + 0xFF, 0xFF, + 0xFF, 0xFF, + 0xAF, 0xEA, + 0x57, 0xF5, + 0xEF, 0xEF, + 0xF7, 0xF7, + 0xEE, 0x6F, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_icon_dir { + { 16, 16 }, bitmap_icon_dir_data +}; + +static constexpr uint8_t bitmap_icon_dmr_data[] = { + 0x00, 0x00, + 0xFE, 0x1F, + 0xFE, 0x3F, + 0x0E, 0x78, + 0x0E, 0x70, + 0x0E, 0x70, + 0x0E, 0x70, + 0x0E, 0x78, + 0xFE, 0x3F, + 0xFE, 0x1F, + 0x8E, 0x07, + 0x0E, 0x0F, + 0x0E, 0x1E, + 0x0E, 0x3C, + 0x0E, 0x78, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_icon_dmr { + { 16, 16 }, bitmap_icon_dmr_data +}; + +static constexpr uint8_t bitmap_icon_ert_data[] = { + 0x00, 0x00, + 0x00, 0x0F, + 0x80, 0x7F, + 0xC0, 0x0F, + 0xFC, 0x0F, + 0xC2, 0x0F, + 0x82, 0x7F, + 0x01, 0x0F, + 0x01, 0x00, + 0x21, 0x05, + 0x53, 0x09, + 0x56, 0x09, + 0x50, 0x05, + 0x50, 0x05, + 0x20, 0xAD, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_icon_ert { + { 16, 16 }, bitmap_icon_ert_data +}; + +static constexpr uint8_t bitmap_icon_file_data[] = { + 0xFC, 0x03, + 0x04, 0x06, + 0x04, 0x0E, + 0x04, 0x1E, + 0x04, 0x3E, + 0x04, 0x20, + 0x04, 0x20, + 0x04, 0x20, + 0x04, 0x20, + 0x04, 0x20, + 0x04, 0x20, + 0x04, 0x20, + 0x04, 0x20, + 0x04, 0x20, + 0x04, 0x20, + 0xFC, 0x3F, +}; +static constexpr Bitmap bitmap_icon_file { + { 16, 16 }, bitmap_icon_file_data +}; + +static constexpr uint8_t bitmap_icon_file_image_data[] = { + 0x00, 0x00, + 0xFF, 0xFF, + 0x01, 0x80, + 0x01, 0x80, + 0x89, 0x80, + 0xC1, 0x81, + 0xE1, 0xA3, + 0xB1, 0xB3, + 0x89, 0xDC, + 0x07, 0x8C, + 0x01, 0x90, + 0x01, 0x80, + 0xAB, 0x82, + 0xFF, 0xD5, + 0xFF, 0xFF, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_icon_file_image { + { 16, 16 }, bitmap_icon_file_image_data +}; + +static constexpr uint8_t bitmap_icon_file_iq_data[] = { + 0xFC, 0x03, + 0x04, 0x06, + 0x04, 0x0E, + 0x04, 0x1E, + 0x04, 0x3E, + 0x04, 0x20, + 0x04, 0x20, + 0x04, 0x21, + 0x44, 0x25, + 0x54, 0x25, + 0xF4, 0x2F, + 0xA4, 0x2A, + 0x84, 0x22, + 0x04, 0x22, + 0x04, 0x20, + 0xFC, 0x3F, +}; +static constexpr Bitmap bitmap_icon_file_iq { + { 16, 16 }, bitmap_icon_file_iq_data +}; + +static constexpr uint8_t bitmap_icon_file_text_data[] = { + 0xFC, 0x03, + 0x04, 0x06, + 0x04, 0x0E, + 0x04, 0x1E, + 0xF4, 0x3E, + 0x04, 0x20, + 0xF4, 0x2F, + 0x04, 0x20, + 0xF4, 0x2F, + 0x04, 0x20, + 0xF4, 0x2F, + 0x04, 0x20, + 0xF4, 0x2F, + 0x04, 0x20, + 0x04, 0x20, + 0xFC, 0x3F, +}; +static constexpr Bitmap bitmap_icon_file_text { + { 16, 16 }, bitmap_icon_file_text_data +}; + +static constexpr uint8_t bitmap_icon_file_wav_data[] = { + 0xFC, 0x03, + 0x04, 0x06, + 0x04, 0x0E, + 0x04, 0x1E, + 0x04, 0x3E, + 0x84, 0x20, + 0xC4, 0x22, + 0xF4, 0x20, + 0xF4, 0x2E, + 0xF4, 0x20, + 0xC4, 0x22, + 0x84, 0x24, + 0x04, 0x28, + 0x04, 0x20, + 0x04, 0x20, + 0xFC, 0x3F, +}; +static constexpr Bitmap bitmap_icon_file_wav { + { 16, 16 }, bitmap_icon_file_wav_data +}; + +static constexpr uint8_t bitmap_icon_fox_data[] = { + 0x18, 0x18, + 0x28, 0x14, + 0x68, 0x16, + 0x68, 0x16, + 0xC8, 0x13, + 0x88, 0x11, + 0x04, 0x20, + 0x24, 0x24, + 0x22, 0x44, + 0x01, 0x80, + 0x06, 0x60, + 0x98, 0x19, + 0x20, 0x04, + 0x40, 0x02, + 0x80, 0x01, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_icon_fox { + { 16, 16 }, bitmap_icon_fox_data +}; + +static constexpr uint8_t bitmap_icon_freqman_data[] = { + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x7E, 0x7E, + 0x81, 0x81, + 0xBD, 0xBD, + 0x81, 0x81, + 0xBD, 0xBD, + 0x81, 0x81, + 0xBD, 0x9D, + 0x81, 0x81, + 0xBD, 0xE1, + 0x81, 0x61, + 0x7E, 0x3E, + 0x00, 0x00, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_icon_freqman { + { 16, 16 }, bitmap_icon_freqman_data +}; + +static constexpr uint8_t bitmap_icon_gps_sim_data[] = { + 0xC0, 0x07, + 0xE0, 0x0F, + 0x70, 0x1F, + 0x78, 0x3E, + 0x78, 0x3C, + 0x78, 0x38, + 0x78, 0x30, + 0x78, 0x38, + 0x78, 0x3C, + 0x70, 0x1E, + 0x70, 0x1F, + 0xE0, 0x0F, + 0xC0, 0x07, + 0x80, 0x03, + 0x20, 0x09, + 0x50, 0x14, +}; +static constexpr Bitmap bitmap_icon_gps_sim { + { 16, 16 }, bitmap_icon_gps_sim_data +}; + +static constexpr uint8_t bitmap_icon_hackrf_data[] = { + 0xF0, 0x0F, + 0x10, 0x08, + 0x50, 0x0A, + 0x10, 0x08, + 0x10, 0x08, + 0x10, 0x08, + 0xF8, 0x1F, + 0xF8, 0x1F, + 0xF8, 0x1F, + 0xF8, 0x1F, + 0xF8, 0x1F, + 0xF8, 0x1F, + 0xF8, 0x1F, + 0xF0, 0x0F, + 0x80, 0x01, + 0x80, 0x01, +}; +static constexpr Bitmap bitmap_icon_hackrf { + { 16, 16 }, bitmap_icon_hackrf_data +}; + +static constexpr uint8_t bitmap_icon_jammer_data[] = { + 0xE0, 0x07, + 0xF8, 0x1F, + 0x1C, 0x38, + 0x0E, 0x78, + 0x06, 0x7C, + 0x03, 0xCE, + 0x03, 0xC7, + 0x83, 0xC3, + 0xC3, 0xC1, + 0xE3, 0xC0, + 0x73, 0xC0, + 0x3E, 0x60, + 0x1E, 0x70, + 0x1C, 0x38, + 0xF8, 0x1F, + 0xE0, 0x07, +}; +static constexpr Bitmap bitmap_icon_jammer { + { 16, 16 }, bitmap_icon_jammer_data }; static constexpr uint8_t bitmap_icon_keyfob_data[] = { @@ -1639,80 +823,290 @@ static constexpr Bitmap bitmap_icon_keyfob { { 16, 16 }, bitmap_icon_keyfob_data }; -static constexpr uint8_t bitmap_sig_cw_data[] = { - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0xFE, 0xFF, 0xFF, 0x7F, - 0xFE, 0xFF, 0xFF, 0x7F, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, +static constexpr uint8_t bitmap_icon_lcr_data[] = { + 0x0C, 0x00, + 0xFF, 0x7F, + 0x01, 0x80, + 0xC1, 0x9B, + 0xFF, 0x7F, + 0x0C, 0x00, + 0xFF, 0x7F, + 0x01, 0x80, + 0xC1, 0x9D, + 0xFF, 0x7F, + 0x0C, 0x00, + 0x0C, 0x00, + 0x0C, 0x00, + 0x0C, 0x00, + 0x0C, 0x00, + 0x0C, 0x00, }; -static constexpr Bitmap bitmap_sig_cw { - { 32, 32 }, bitmap_sig_cw_data +static constexpr Bitmap bitmap_icon_lcr { + { 16, 16 }, bitmap_icon_lcr_data }; -static constexpr uint8_t bitmap_sig_saw_up_data[] = { - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x01, 0x70, - 0x06, 0x80, 0x01, 0x78, - 0x06, 0xC0, 0x01, 0x7C, - 0x06, 0xE0, 0x01, 0x6E, - 0x06, 0xF0, 0x01, 0x67, - 0x06, 0xB8, 0x81, 0x63, - 0x06, 0x9C, 0xC1, 0x61, - 0x06, 0x8E, 0xE1, 0x60, - 0x06, 0x87, 0x71, 0x60, - 0x86, 0x83, 0x39, 0x60, - 0xC6, 0x81, 0x1D, 0x60, - 0xE6, 0x80, 0x0F, 0x60, - 0x76, 0x80, 0x07, 0x60, - 0x3E, 0x80, 0x03, 0x60, - 0x1E, 0x80, 0x01, 0x60, - 0x0E, 0x80, 0x00, 0x60, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, +static constexpr uint8_t bitmap_icon_lge_data[] = { + 0x00, 0x00, + 0x80, 0x00, + 0xA4, 0x12, + 0xA8, 0x0A, + 0xD0, 0x05, + 0xEC, 0x1B, + 0xF0, 0x07, + 0xFE, 0xFF, + 0xF0, 0x07, + 0xEC, 0x1B, + 0xD0, 0x05, + 0xA8, 0x0A, + 0xA4, 0x12, + 0x80, 0x00, + 0x00, 0x00, + 0x00, 0x00, }; -static constexpr Bitmap bitmap_sig_saw_up { - { 32, 32 }, bitmap_sig_saw_up_data +static constexpr Bitmap bitmap_icon_lge { + { 16, 16 }, bitmap_icon_lge_data +}; + +static constexpr uint8_t bitmap_icon_load_data[] = { + 0x00, 0x01, + 0x80, 0x03, + 0x40, 0x05, + 0x00, 0x01, + 0x0E, 0x01, + 0x11, 0x01, + 0x7F, 0x1D, + 0x01, 0x20, + 0xF9, 0xFF, + 0xF9, 0xFF, + 0xFD, 0x7F, + 0xFD, 0x7F, + 0xFF, 0x3F, + 0xFF, 0x3F, + 0xFF, 0x1F, + 0xFF, 0x1F, +}; +static constexpr Bitmap bitmap_icon_load { + { 16, 16 }, bitmap_icon_load_data +}; + +static constexpr uint8_t bitmap_icon_looking_data[] = { + 0xF8, 0x01, + 0xFC, 0x03, + 0x0E, 0x07, + 0x07, 0x0E, + 0xF3, 0x0C, + 0x9F, 0x0F, + 0x9F, 0x0F, + 0xF3, 0x0C, + 0x07, 0x0E, + 0x0E, 0x07, + 0xFC, 0x1F, + 0xF8, 0x3D, + 0x00, 0x7C, + 0x00, 0xF8, + 0x00, 0xF0, + 0x00, 0x60, +}; +static constexpr Bitmap bitmap_icon_looking { + { 16, 16 }, bitmap_icon_looking_data +}; + +static constexpr uint8_t bitmap_icon_lora_data[] = { + 0xC0, 0x03, + 0x30, 0x0C, + 0x00, 0x00, + 0xC0, 0x03, + 0x00, 0x00, + 0xC0, 0x03, + 0x60, 0x06, + 0x60, 0x06, + 0x60, 0x06, + 0x60, 0x06, + 0xC0, 0x03, + 0x00, 0x00, + 0xC0, 0x03, + 0x00, 0x00, + 0x30, 0x0C, + 0xC0, 0x03, +}; +static constexpr Bitmap bitmap_icon_lora { + { 16, 16 }, bitmap_icon_lora_data +}; + +static constexpr uint8_t bitmap_icon_memory_data[] = { + 0x54, 0x15, + 0x54, 0x15, + 0xFF, 0x7F, + 0xFC, 0x1F, + 0xFF, 0x7F, + 0xCC, 0x19, + 0xAF, 0x7A, + 0x6C, 0x1B, + 0xEF, 0x7B, + 0xEC, 0x1B, + 0xFF, 0x7F, + 0xFC, 0x1F, + 0xFF, 0x7F, + 0x54, 0x15, + 0x54, 0x15, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_icon_memory { + { 16, 16 }, bitmap_icon_memory_data +}; + +static constexpr uint8_t bitmap_icon_microphone_data[] = { + 0xC0, 0x03, + 0xE0, 0x07, + 0xE0, 0x07, + 0xE0, 0x07, + 0xE8, 0x17, + 0xE8, 0x17, + 0xE8, 0x17, + 0xE8, 0x17, + 0xE8, 0x17, + 0xC8, 0x13, + 0x18, 0x18, + 0xF0, 0x0F, + 0xC0, 0x03, + 0x80, 0x01, + 0x80, 0x01, + 0xE0, 0x07, +}; +static constexpr Bitmap bitmap_icon_microphone { + { 16, 16 }, bitmap_icon_microphone_data +}; + +static constexpr uint8_t bitmap_icon_modem_data[] = { + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0xF8, 0x1F, + 0x04, 0x20, + 0x02, 0x40, + 0xFF, 0xFF, + 0xFF, 0xFF, + 0xAB, 0xDF, + 0xAB, 0xDF, + 0xFF, 0xFF, + 0xFF, 0xFF, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_icon_modem { + { 16, 16 }, bitmap_icon_modem_data +}; + +static constexpr uint8_t bitmap_icon_morse_data[] = { + 0x00, 0x00, + 0xFE, 0x7F, + 0xFF, 0xFF, + 0xBB, 0xD0, + 0xFF, 0xFF, + 0xFF, 0xFF, + 0x0B, 0xE1, + 0xFF, 0xFF, + 0xFF, 0xFF, + 0xEB, 0xD0, + 0xFF, 0xFF, + 0xFE, 0x7F, + 0x70, 0x00, + 0x30, 0x00, + 0x10, 0x00, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_icon_morse { + { 16, 16 }, bitmap_icon_morse_data +}; + +static constexpr uint8_t bitmap_icon_new_category_data[] = { + 0x00, 0x18, + 0x3E, 0x18, + 0x41, 0x7E, + 0xC1, 0x7E, + 0xFF, 0x18, + 0xFF, 0xDB, + 0xFF, 0xC3, + 0xFF, 0xFF, + 0xFF, 0xFF, + 0xFF, 0xFF, + 0xAF, 0xEA, + 0x57, 0xF5, + 0xEF, 0xEF, + 0xF7, 0xF7, + 0xEE, 0x6F, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_icon_new_category { + { 16, 16 }, bitmap_icon_new_category_data +}; + +static constexpr uint8_t bitmap_icon_notepad_data[] = { + 0x0C, 0x00, + 0x1E, 0x00, + 0x2F, 0x00, + 0x47, 0x00, + 0xE2, 0x00, + 0xD4, 0x01, + 0xB8, 0x03, + 0x70, 0x07, + 0xE0, 0x0E, + 0xC0, 0x1D, + 0x80, 0x3B, + 0x00, 0x4F, + 0x00, 0x46, + 0x00, 0x84, + 0x00, 0xD8, + 0x00, 0xE0, +}; +static constexpr Bitmap bitmap_icon_notepad { + { 16, 16 }, bitmap_icon_notepad_data +}; + +static constexpr uint8_t bitmap_icon_nrf_data[] = { + 0x00, 0x01, + 0x00, 0x01, + 0x00, 0x01, + 0x00, 0x01, + 0x00, 0x01, + 0x00, 0x01, + 0x00, 0x01, + 0xF8, 0x3F, + 0xFC, 0x7F, + 0xFC, 0x7F, + 0xDC, 0x7F, + 0x8C, 0x6B, + 0xDC, 0x7F, + 0xFC, 0x7F, + 0xFC, 0x7F, + 0xF8, 0x3F, +}; +static constexpr Bitmap bitmap_icon_nrf { + { 16, 16 }, bitmap_icon_nrf_data +}; + +static constexpr uint8_t bitmap_icon_nuoptix_data[] = { + 0x80, 0x01, + 0x80, 0x01, + 0x40, 0x02, + 0x40, 0x1A, + 0x40, 0x1A, + 0x20, 0x0C, + 0x20, 0x0F, + 0x20, 0x1E, + 0x10, 0x0E, + 0x10, 0x0B, + 0x10, 0x0B, + 0xF8, 0x1F, + 0xF8, 0x1F, + 0xF8, 0x1F, + 0xFC, 0x3F, + 0xFC, 0x3F, +}; +static constexpr Bitmap bitmap_icon_nuoptix { + { 16, 16 }, bitmap_icon_nuoptix_data }; static constexpr uint8_t bitmap_icon_options_datetime_data[] = { @@ -1737,86 +1131,180 @@ static constexpr Bitmap bitmap_icon_options_datetime { { 16, 16 }, bitmap_icon_options_datetime_data }; -static constexpr uint8_t bitmap_target_calibrate_data[] = { - 0x02, 0x00, 0x00, 0x40, - 0x07, 0x00, 0x00, 0xE0, - 0x0E, 0x00, 0x00, 0x70, - 0x1C, 0x00, 0x00, 0x38, - 0x38, 0x00, 0x00, 0x1C, - 0x70, 0x00, 0x00, 0x0E, - 0xE0, 0x00, 0x00, 0x07, - 0xC0, 0x01, 0x80, 0x03, - 0x80, 0x03, 0xC0, 0x01, - 0x00, 0x07, 0xE0, 0x00, - 0x00, 0x0E, 0x70, 0x00, - 0x00, 0x1C, 0x38, 0x00, - 0x00, 0x38, 0x1C, 0x00, - 0x00, 0x70, 0x0E, 0x00, - 0x00, 0xE0, 0x07, 0x00, - 0x00, 0xC0, 0x03, 0x00, - 0x00, 0xC0, 0x03, 0x00, - 0x00, 0xE0, 0x07, 0x00, - 0x00, 0x70, 0x0E, 0x00, - 0x00, 0x38, 0x1C, 0x00, - 0x00, 0x1C, 0x38, 0x00, - 0x00, 0x0E, 0x70, 0x00, - 0x00, 0x07, 0xE0, 0x00, - 0x80, 0x03, 0xC0, 0x01, - 0xC0, 0x01, 0x80, 0x03, - 0xE0, 0x00, 0x00, 0x07, - 0x70, 0x00, 0x00, 0x0E, - 0x38, 0x00, 0x00, 0x1C, - 0x1C, 0x00, 0x00, 0x38, - 0x0E, 0x00, 0x00, 0x70, - 0x07, 0x00, 0x00, 0xE0, - 0x02, 0x00, 0x00, 0x40, +static constexpr uint8_t bitmap_icon_options_radio_data[] = { + 0x00, 0x00, + 0x00, 0x00, + 0x04, 0x20, + 0x12, 0x48, + 0x8A, 0x51, + 0xCA, 0x53, + 0xCA, 0x53, + 0x8A, 0x51, + 0x12, 0x48, + 0x84, 0x21, + 0xC0, 0x03, + 0x40, 0x02, + 0x60, 0x06, + 0x20, 0x04, + 0x30, 0x0C, + 0xF0, 0x0F, }; -static constexpr Bitmap bitmap_target_calibrate { - { 32, 32 }, bitmap_target_calibrate_data +static constexpr Bitmap bitmap_icon_options_radio { + { 16, 16 }, bitmap_icon_options_radio_data }; -static constexpr uint8_t bitmap_rssipwm_data[] = { - 0x00, 0x00, 0x00, - 0x8F, 0xE7, 0x7D, - 0x51, 0x10, 0x10, - 0x51, 0x10, 0x10, - 0x8F, 0xE3, 0x10, - 0x09, 0x04, 0x11, - 0x11, 0x04, 0x11, - 0xD1, 0xF3, 0x7C, - 0x00, 0x00, 0x00, - 0x3F, 0x1E, 0x1E, - 0x21, 0x12, 0x12, - 0x21, 0x12, 0x12, - 0x21, 0x12, 0x12, - 0x21, 0x12, 0x12, - 0x21, 0x12, 0x12, - 0xE1, 0xF3, 0x73, +static constexpr uint8_t bitmap_icon_options_touch_data[] = { + 0xC7, 0xF1, + 0x97, 0xF4, + 0x27, 0xF2, + 0x8F, 0xF8, + 0x5F, 0xFD, + 0x47, 0xFD, + 0x53, 0xC1, + 0x4B, 0x9F, + 0x43, 0xB5, + 0x6F, 0xA0, + 0x2F, 0xA0, + 0x20, 0x20, + 0x60, 0x20, + 0x40, 0x10, + 0xC0, 0x1F, + 0x00, 0x00, }; -static constexpr Bitmap bitmap_rssipwm { - { 24, 16 }, bitmap_rssipwm_data +static constexpr Bitmap bitmap_icon_options_touch { + { 16, 16 }, bitmap_icon_options_touch_data }; -static constexpr uint8_t bitmap_icon_ert_data[] = { - 0x00, 0x00, - 0x00, 0x0F, - 0x80, 0x7F, - 0xC0, 0x0F, - 0xFC, 0x0F, - 0xC2, 0x0F, - 0x82, 0x7F, - 0x01, 0x0F, - 0x01, 0x00, - 0x21, 0x05, - 0x53, 0x09, - 0x56, 0x09, - 0x50, 0x05, - 0x50, 0x05, - 0x20, 0xAD, +static constexpr uint8_t bitmap_icon_options_ui_data[] = { + 0xFF, 0x1F, + 0xFF, 0x13, + 0xFF, 0x1F, + 0x01, 0x10, + 0x01, 0x10, + 0x01, 0x10, + 0x01, 0x04, + 0x01, 0x0C, + 0x01, 0x1C, + 0x01, 0x3C, + 0xFF, 0x7D, + 0x00, 0xFC, + 0x00, 0x34, + 0x00, 0x20, + 0x00, 0x60, 0x00, 0x00, }; -static constexpr Bitmap bitmap_icon_ert { - { 16, 16 }, bitmap_icon_ert_data +static constexpr Bitmap bitmap_icon_options_ui { + { 16, 16 }, bitmap_icon_options_ui_data +}; + +static constexpr uint8_t bitmap_icon_peripherals_data[] = { + 0x54, 0x01, + 0x54, 0x01, + 0xFF, 0x07, + 0x7C, 0x01, + 0xBF, 0x07, + 0xDC, 0x18, + 0x6F, 0x10, + 0x2C, 0x21, + 0xAF, 0x20, + 0x34, 0x20, + 0x54, 0x10, + 0xC0, 0x38, + 0x00, 0x77, + 0x00, 0xE0, + 0x00, 0xC0, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_icon_peripherals { + { 16, 16 }, bitmap_icon_peripherals_data +}; + +static constexpr uint8_t bitmap_icon_peripherals_details_data[] = { + 0x54, 0x01, + 0x54, 0x01, + 0xFF, 0x07, + 0xFC, 0x01, + 0x3F, 0x00, + 0xBC, 0x3F, + 0xBF, 0x60, + 0xBC, 0xEE, + 0xBF, 0x80, + 0x94, 0xBE, + 0x94, 0x80, + 0x80, 0xBE, + 0x80, 0x80, + 0x80, 0xBE, + 0x80, 0x80, + 0x80, 0xFF, +}; +static constexpr Bitmap bitmap_icon_peripherals_details { + { 16, 16 }, bitmap_icon_peripherals_details_data +}; + +static constexpr uint8_t bitmap_icon_pocsag_data[] = { + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0xFC, 0x3F, + 0xFE, 0x7F, + 0x02, 0x40, + 0xBA, 0x45, + 0x02, 0x40, + 0xFE, 0x7F, + 0xFE, 0x7F, + 0x92, 0x7C, + 0x92, 0x7C, + 0xFC, 0x3F, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_icon_pocsag { + { 16, 16 }, bitmap_icon_pocsag_data +}; + +static constexpr uint8_t bitmap_icon_previous_data[] = { + 0x00, 0x00, + 0xC0, 0x00, + 0xE0, 0x00, + 0x70, 0x00, + 0x38, 0x00, + 0x1C, 0x00, + 0x0E, 0x00, + 0xFF, 0xFF, + 0xFF, 0xFF, + 0x0E, 0x00, + 0x1C, 0x00, + 0x38, 0x00, + 0x70, 0x00, + 0xE0, 0x00, + 0xC0, 0x00, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_icon_previous { + { 16, 16 }, bitmap_icon_previous_data +}; + +static constexpr uint8_t bitmap_icon_rds_data[] = { + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x3C, 0x3C, + 0x7E, 0x7E, + 0x67, 0xE7, + 0x83, 0xC3, + 0xC7, 0xE1, + 0xFD, 0xBC, + 0x42, 0x42, + 0x3C, 0x3C, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_icon_rds { + { 16, 16 }, bitmap_icon_rds_data }; static constexpr uint8_t bitmap_icon_receivers_data[] = { @@ -1863,70 +1351,48 @@ static constexpr Bitmap bitmap_icon_remote { { 16, 16 }, bitmap_icon_remote_data }; -static constexpr uint8_t bitmap_record_data[] = { - 0xC0, 0x07, - 0xF0, 0x1F, - 0xF8, 0x3F, - 0xFC, 0x7F, - 0xFC, 0x7F, - 0x66, 0xCC, - 0x56, 0xF7, - 0x66, 0xF6, - 0x56, 0xF7, - 0x56, 0xCC, - 0xFC, 0x7F, - 0xFC, 0x7F, - 0xF8, 0x3F, - 0xF0, 0x1F, - 0xC0, 0x07, +static constexpr uint8_t bitmap_icon_rename_data[] = { + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x0E, + 0x00, 0x04, + 0xFF, 0xF5, + 0x01, 0x84, + 0xC9, 0x84, + 0x55, 0x85, + 0xDD, 0x84, + 0x55, 0x85, + 0xD5, 0x84, + 0x01, 0x84, + 0xFF, 0xF5, + 0x00, 0x04, + 0x00, 0x0E, 0x00, 0x00, }; -static constexpr Bitmap bitmap_record { - { 16, 16 }, bitmap_record_data +static constexpr Bitmap bitmap_icon_rename { + { 16, 16 }, bitmap_icon_rename_data }; -static constexpr uint8_t bitmap_sd_card_error_data[] = { +static constexpr uint8_t bitmap_icon_rename_numeric_data[] = { 0x00, 0x00, 0x00, 0x00, - 0xC0, 0x1F, - 0xE0, 0x1F, - 0xF0, 0x1F, - 0xF8, 0x1F, - 0xC8, 0x13, - 0x98, 0x19, - 0x38, 0x1C, - 0x78, 0x1E, - 0x38, 0x1C, - 0x98, 0x19, - 0xC8, 0x13, - 0xF8, 0x1F, - 0x00, 0x00, + 0x00, 0x0E, + 0x00, 0x04, + 0xFF, 0xF5, + 0x01, 0x84, + 0xC9, 0x85, + 0x0D, 0x85, + 0xC9, 0x85, + 0x49, 0x84, + 0xDD, 0x85, + 0x01, 0x84, + 0xFF, 0xF5, + 0x00, 0x04, + 0x00, 0x0E, 0x00, 0x00, }; -static constexpr Bitmap bitmap_sd_card_error { - { 16, 16 }, bitmap_sd_card_error_data -}; - -static constexpr uint8_t bitmap_icon_script_data[] = { - 0xFC, 0x07, - 0xFA, 0x0F, - 0x19, 0x1A, - 0xF9, 0x1F, - 0x1E, 0x1D, - 0xF8, 0x1F, - 0x98, 0x1F, - 0xF8, 0x1F, - 0xF8, 0x1F, - 0x08, 0x14, - 0xF8, 0x1F, - 0x48, 0x1E, - 0xF8, 0xFF, - 0x78, 0x80, - 0x30, 0x40, - 0xE0, 0x3F, -}; -static constexpr Bitmap bitmap_icon_script { - { 16, 16 }, bitmap_icon_script_data +static constexpr Bitmap bitmap_icon_rename_numeric { + { 16, 16 }, bitmap_icon_rename_numeric_data }; static constexpr uint8_t bitmap_icon_replay_data[] = { @@ -1951,6 +1417,138 @@ static constexpr Bitmap bitmap_icon_replay { { 16, 16 }, bitmap_icon_replay_data }; +static constexpr uint8_t bitmap_icon_save_data[] = { + 0x00, 0x01, + 0x00, 0x01, + 0x00, 0x01, + 0x00, 0x01, + 0x4E, 0x05, + 0x91, 0x03, + 0x3F, 0x19, + 0x01, 0x20, + 0xF9, 0xFF, + 0xF9, 0xFF, + 0xFD, 0x7F, + 0xFD, 0x7F, + 0xFF, 0x3F, + 0xFF, 0x3F, + 0xFF, 0x1F, + 0xFF, 0x1F, +}; +static constexpr Bitmap bitmap_icon_save { + { 16, 16 }, bitmap_icon_save_data +}; + +static constexpr uint8_t bitmap_icon_scanner_data[] = { + 0x03, 0x00, + 0x00, 0x00, + 0x03, 0x00, + 0x00, 0x00, + 0x0F, 0x00, + 0x00, 0x00, + 0x03, 0x01, + 0x80, 0x01, + 0xC3, 0x00, + 0xE0, 0xFF, + 0xEF, 0xFF, + 0xC0, 0x00, + 0x83, 0x01, + 0x00, 0x01, + 0x03, 0x00, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_icon_scanner { + { 16, 16 }, bitmap_icon_scanner_data +}; + +static constexpr uint8_t bitmap_icon_script_data[] = { + 0xFC, 0x07, + 0xFA, 0x0F, + 0x19, 0x1A, + 0xF9, 0x1F, + 0x1E, 0x1D, + 0xF8, 0x1F, + 0x98, 0x1F, + 0xF8, 0x1F, + 0xF8, 0x1F, + 0x08, 0x14, + 0xF8, 0x1F, + 0x48, 0x1E, + 0xF8, 0xFF, + 0x78, 0x80, + 0x30, 0x40, + 0xE0, 0x3F, +}; +static constexpr Bitmap bitmap_icon_script { + { 16, 16 }, bitmap_icon_script_data +}; + +static constexpr uint8_t bitmap_icon_sd_data[] = { + 0x00, 0x00, + 0x00, 0x00, + 0xC0, 0x1F, + 0xE0, 0x1F, + 0xF0, 0x1F, + 0xF8, 0x1F, + 0x98, 0x18, + 0xE8, 0x16, + 0xC8, 0x16, + 0x98, 0x16, + 0xB8, 0x16, + 0xC8, 0x18, + 0xF8, 0x1F, + 0xF8, 0x1F, + 0x00, 0x00, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_icon_sd { + { 16, 16 }, bitmap_icon_sd_data +}; + +static constexpr uint8_t bitmap_icon_sdcard_data[] = { + 0xF0, 0x3F, + 0x58, 0x35, + 0x5C, 0x35, + 0xFC, 0x3F, + 0xFC, 0x3F, + 0xFC, 0x3F, + 0xFC, 0x3F, + 0xFC, 0x3F, + 0xFC, 0x3F, + 0xAC, 0x3A, + 0x5C, 0x35, + 0xAC, 0x3A, + 0x5C, 0x35, + 0xAC, 0x3A, + 0x5C, 0x35, + 0xAC, 0x3A, +}; +static constexpr Bitmap bitmap_icon_sdcard { + { 16, 16 }, bitmap_icon_sdcard_data +}; + +static constexpr uint8_t bitmap_icon_search_data[] = { + 0xF8, 0x01, + 0xFC, 0x03, + 0x0E, 0x07, + 0x07, 0x0E, + 0x03, 0x0C, + 0x0B, 0x0C, + 0x0B, 0x0C, + 0x13, 0x0C, + 0x07, 0x0E, + 0x0E, 0x07, + 0xFC, 0x1F, + 0xF8, 0x3D, + 0x00, 0x7C, + 0x00, 0xF8, + 0x00, 0xF0, + 0x00, 0x60, +}; +static constexpr Bitmap bitmap_icon_search { + { 16, 16 }, bitmap_icon_search_data +}; + static constexpr uint8_t bitmap_icon_setup_data[] = { 0xC0, 0x01, 0xC0, 0x01, @@ -1973,42 +1571,114 @@ static constexpr Bitmap bitmap_icon_setup { { 16, 16 }, bitmap_icon_setup_data }; -static constexpr uint8_t bitmap_sig_sine_data[] = { - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xC0, 0x00, - 0x80, 0x07, 0xE0, 0x01, - 0xC0, 0x0F, 0xF0, 0x03, - 0xC0, 0x0C, 0x30, 0x03, - 0x60, 0x18, 0x18, 0x06, - 0x60, 0x18, 0x18, 0x06, - 0x60, 0x18, 0x18, 0x06, - 0x60, 0x18, 0x18, 0x06, - 0x30, 0x30, 0x0C, 0x0C, - 0x30, 0x30, 0x0C, 0x0C, - 0x30, 0x30, 0x0C, 0x0C, - 0x30, 0x30, 0x0C, 0x0C, - 0x18, 0x60, 0x06, 0x18, - 0x1E, 0xE0, 0x07, 0x78, - 0x0E, 0xC0, 0x03, 0x70, - 0x06, 0x80, 0x01, 0x60, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, +static constexpr uint8_t bitmap_icon_sleep_data[] = { + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x04, + 0x00, 0x08, + 0x00, 0x18, + 0x00, 0x18, + 0x00, 0x38, + 0x00, 0x3C, + 0x00, 0x3C, + 0x00, 0x3E, + 0x84, 0x1F, + 0xF8, 0x1F, + 0xF0, 0x0F, + 0xC0, 0x03, + 0x00, 0x00, + 0x00, 0x00, }; -static constexpr Bitmap bitmap_sig_sine { - { 32, 32 }, bitmap_sig_sine_data +static constexpr Bitmap bitmap_icon_sleep { + { 16, 16 }, bitmap_icon_sleep_data +}; + +static constexpr uint8_t bitmap_icon_sonde_data[] = { + 0x80, 0x03, + 0xE0, 0x0F, + 0xE0, 0x0F, + 0xF0, 0x1F, + 0xF0, 0x1F, + 0xF0, 0x1F, + 0xE0, 0x0F, + 0xE0, 0x0F, + 0x00, 0x00, + 0x20, 0x09, + 0x00, 0x00, + 0x40, 0x05, + 0x00, 0x00, + 0xC0, 0x07, + 0xC0, 0x07, + 0xC0, 0x07, +}; +static constexpr Bitmap bitmap_icon_sonde { + { 16, 16 }, bitmap_icon_sonde_data +}; + +static constexpr uint8_t bitmap_icon_soundboard_data[] = { + 0xF0, 0x0F, + 0x1C, 0x18, + 0x17, 0x38, + 0x15, 0x78, + 0x15, 0xF8, + 0x15, 0x82, + 0x15, 0x8B, + 0xD5, 0x83, + 0xD5, 0xBB, + 0xD5, 0x83, + 0x15, 0x8B, + 0x15, 0x92, + 0x15, 0xA0, + 0x17, 0x80, + 0x1C, 0x80, + 0xF0, 0xFF, +}; +static constexpr Bitmap bitmap_icon_soundboard { + { 16, 16 }, bitmap_icon_soundboard_data +}; + +static constexpr uint8_t bitmap_icon_speaker_data[] = { + 0x00, 0x00, + 0x40, 0x10, + 0x60, 0x20, + 0x70, 0x44, + 0x78, 0x48, + 0x7F, 0x91, + 0x7F, 0x92, + 0x7F, 0x92, + 0x7F, 0x92, + 0x7F, 0x92, + 0x7F, 0x92, + 0x7F, 0x91, + 0x78, 0x48, + 0x70, 0x44, + 0x60, 0x20, + 0x40, 0x10, +}; +static constexpr Bitmap bitmap_icon_speaker { + { 16, 16 }, bitmap_icon_speaker_data +}; + +static constexpr uint8_t bitmap_icon_speaker_mute_data[] = { + 0x00, 0x00, + 0x40, 0x00, + 0x60, 0x00, + 0x70, 0x00, + 0x78, 0x00, + 0x7F, 0x22, + 0x7F, 0x36, + 0x7F, 0x1C, + 0x7F, 0x08, + 0x7F, 0x1C, + 0x7F, 0x36, + 0x7F, 0x22, + 0x78, 0x00, + 0x70, 0x00, + 0x60, 0x00, + 0x40, 0x00, +}; +static constexpr Bitmap bitmap_icon_speaker_mute { + { 16, 16 }, bitmap_icon_speaker_mute_data }; static constexpr uint8_t bitmap_icon_sstv_data[] = { @@ -2033,48 +1703,26 @@ static constexpr Bitmap bitmap_icon_sstv { { 16, 16 }, bitmap_icon_sstv_data }; -static constexpr uint8_t bitmap_titlebar_image_data[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x22, 0xC7, 0x8B, 0x9E, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xA2, 0x28, 0x48, 0xA6, 0x81, 0x31, 0x67, 0x36, 0x73, 0x63, - 0xBE, 0x2F, 0x38, 0x9E, 0x87, 0xBB, 0x6D, 0x36, 0x1B, 0x77, - 0xA2, 0x28, 0x48, 0xA6, 0x81, 0xBF, 0x6D, 0x36, 0x1B, 0x7F, - 0xA2, 0xC8, 0x8B, 0xA6, 0x81, 0xB5, 0xCF, 0xF3, 0x7B, 0x6B, - 0x00, 0x00, 0x00, 0x00, 0x80, 0xB1, 0x8D, 0x31, 0x1B, 0x63, - 0xEE, 0xEE, 0xEE, 0xEE, 0x8A, 0xB1, 0x8D, 0x31, 0x1B, 0x63, - 0xAE, 0x46, 0xEE, 0x2E, 0x86, 0xB1, 0x8D, 0x31, 0x73, 0x63, - 0xE2, 0x4A, 0x2A, 0xEA, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +static constexpr uint8_t bitmap_icon_stealth_data[] = { + 0x00, 0x00, + 0xC0, 0x03, + 0xE0, 0x07, + 0xE0, 0x07, + 0xF8, 0x1F, + 0x00, 0x00, + 0xE0, 0x07, + 0x60, 0x06, + 0x00, 0x00, + 0xF0, 0x0F, + 0xF0, 0x0F, + 0xF8, 0x1E, + 0xFC, 0x3F, + 0xFC, 0x3E, + 0xFC, 0x3F, + 0x00, 0x00, }; -static constexpr Bitmap bitmap_titlebar_image { - { 80, 16 }, bitmap_titlebar_image_data -}; - -static constexpr uint8_t bitmap_icon_lora_data[] = { - 0xC0, 0x03, - 0x30, 0x0C, - 0x00, 0x00, - 0xC0, 0x03, - 0x00, 0x00, - 0xC0, 0x03, - 0x60, 0x06, - 0x60, 0x06, - 0x60, 0x06, - 0x60, 0x06, - 0xC0, 0x03, - 0x00, 0x00, - 0xC0, 0x03, - 0x00, 0x00, - 0x30, 0x0C, - 0xC0, 0x03, -}; -static constexpr Bitmap bitmap_icon_lora { - { 16, 16 }, bitmap_icon_lora_data +static constexpr Bitmap bitmap_icon_stealth { + { 16, 16 }, bitmap_icon_stealth_data }; static constexpr uint8_t bitmap_icon_temperature_data[] = { @@ -2099,6 +1747,50 @@ static constexpr Bitmap bitmap_icon_temperature { { 16, 16 }, bitmap_icon_temperature_data }; +static constexpr uint8_t bitmap_icon_tetra_data[] = { + 0xE0, 0x0F, + 0x18, 0x38, + 0xE4, 0x67, + 0x7E, 0xCE, + 0xC7, 0xCC, + 0x00, 0x00, + 0xFF, 0x4F, + 0xBA, 0xB2, + 0x9A, 0xEE, + 0xBA, 0xB2, + 0x00, 0x00, + 0x3B, 0xE3, + 0x73, 0x7E, + 0xC6, 0x27, + 0x1C, 0x18, + 0xF0, 0x07, +}; +static constexpr Bitmap bitmap_icon_tetra { + { 16, 16 }, bitmap_icon_tetra_data +}; + +static constexpr uint8_t bitmap_icon_tools_antenna_data[] = { + 0x38, 0x3E, + 0x10, 0x22, + 0x10, 0x26, + 0x10, 0x22, + 0x10, 0x2E, + 0x10, 0x22, + 0x10, 0x26, + 0x10, 0x22, + 0x38, 0x2E, + 0x38, 0x22, + 0x38, 0x26, + 0x38, 0x22, + 0x38, 0x2E, + 0x38, 0x22, + 0x38, 0x3E, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_icon_tools_antenna { + { 16, 16 }, bitmap_icon_tools_antenna_data +}; + static constexpr uint8_t bitmap_icon_tools_wipesd_data[] = { 0xF0, 0x3F, 0x58, 0x35, @@ -2121,48 +1813,254 @@ static constexpr Bitmap bitmap_icon_tools_wipesd { { 16, 16 }, bitmap_icon_tools_wipesd_data }; -static constexpr uint8_t bitmap_icon_clk_int_data[] = { - 0x00, - 0x00, - 0xDC, - 0x54, - 0x54, - 0x54, - 0x54, - 0x76, - 0x00, - 0x44, - 0x6C, - 0x38, - 0x38, - 0x6C, - 0x44, - 0x00, +static constexpr uint8_t bitmap_icon_tpms_data[] = { + 0xC0, 0x03, + 0xF0, 0x0F, + 0x18, 0x18, + 0xEC, 0x37, + 0x36, 0x6C, + 0x1A, 0x58, + 0x0B, 0xD0, + 0x0B, 0xD0, + 0x0B, 0xD0, + 0x0B, 0xD0, + 0x1A, 0x58, + 0x36, 0x6C, + 0xEC, 0x37, + 0x18, 0x18, + 0xF0, 0x0F, + 0xC0, 0x03, }; -static constexpr Bitmap bitmap_icon_clk_int { - { 8, 16 }, bitmap_icon_clk_int_data +static constexpr Bitmap bitmap_icon_tpms { + { 16, 16 }, bitmap_icon_tpms_data }; -static constexpr uint8_t bitmap_icon_file_iq_data[] = { - 0xFC, 0x03, - 0x04, 0x06, - 0x04, 0x0E, - 0x04, 0x1E, - 0x04, 0x3E, - 0x04, 0x20, - 0x04, 0x20, - 0x04, 0x21, - 0x44, 0x25, - 0x54, 0x25, - 0xF4, 0x2F, - 0xA4, 0x2A, - 0x84, 0x22, - 0x04, 0x22, - 0x04, 0x20, - 0xFC, 0x3F, +static constexpr uint8_t bitmap_icon_transmit_data[] = { + 0x80, 0x01, + 0xC0, 0x03, + 0xE0, 0x07, + 0xB0, 0x0D, + 0x98, 0x19, + 0x80, 0x01, + 0x80, 0x01, + 0x80, 0x01, + 0x80, 0x01, + 0x80, 0x01, + 0x80, 0x01, + 0x80, 0x01, + 0x83, 0xC1, + 0x03, 0xC0, + 0xFF, 0xFF, + 0xFF, 0xFF, }; -static constexpr Bitmap bitmap_icon_file_iq { - { 16, 16 }, bitmap_icon_file_iq_data +static constexpr Bitmap bitmap_icon_transmit { + { 16, 16 }, bitmap_icon_transmit_data +}; + +static constexpr uint8_t bitmap_icon_utilities_data[] = { + 0x30, 0x24, + 0x78, 0x66, + 0x78, 0x66, + 0x78, 0x7E, + 0x78, 0x3C, + 0x78, 0x18, + 0x78, 0x18, + 0x30, 0x3C, + 0x30, 0x3C, + 0x30, 0x3C, + 0x30, 0x3C, + 0x30, 0x3C, + 0x30, 0x3C, + 0x30, 0x3C, + 0x30, 0x18, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_icon_utilities { + { 16, 16 }, bitmap_icon_utilities_data +}; + +static constexpr uint8_t bitmap_more_data[] = { + 0x10, + 0x10, + 0x10, + 0x10, + 0x54, + 0x38, + 0x10, + 0x00, +}; +static constexpr Bitmap bitmap_more { + { 8, 8 }, bitmap_more_data +}; + +static constexpr uint8_t bitmap_play_data[] = { + 0x00, 0x00, + 0x00, 0x00, + 0x0C, 0x00, + 0x3C, 0x00, + 0xFC, 0x00, + 0xFC, 0x03, + 0xFC, 0x0F, + 0xFC, 0x3F, + 0xFC, 0x3F, + 0xFC, 0x0F, + 0xFC, 0x03, + 0xFC, 0x00, + 0x3C, 0x00, + 0x0C, 0x00, + 0x00, 0x00, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_play { + { 16, 16 }, bitmap_play_data +}; + +static constexpr uint8_t bitmap_record_data[] = { + 0xC0, 0x07, + 0xF0, 0x1F, + 0xF8, 0x3F, + 0xFC, 0x7F, + 0xFC, 0x7F, + 0x66, 0xCC, + 0x56, 0xF7, + 0x66, 0xF6, + 0x56, 0xF7, + 0x56, 0xCC, + 0xFC, 0x7F, + 0xFC, 0x7F, + 0xF8, 0x3F, + 0xF0, 0x1F, + 0xC0, 0x07, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_record { + { 16, 16 }, bitmap_record_data +}; + +static constexpr uint8_t bitmap_rssipwm_data[] = { + 0x00, 0x00, 0x00, + 0x8F, 0xE7, 0x7D, + 0x51, 0x10, 0x10, + 0x51, 0x10, 0x10, + 0x8F, 0xE3, 0x10, + 0x09, 0x04, 0x11, + 0x11, 0x04, 0x11, + 0xD1, 0xF3, 0x7C, + 0x00, 0x00, 0x00, + 0x3F, 0x1E, 0x1E, + 0x21, 0x12, 0x12, + 0x21, 0x12, 0x12, + 0x21, 0x12, 0x12, + 0x21, 0x12, 0x12, + 0x21, 0x12, 0x12, + 0xE1, 0xF3, 0x73, +}; +static constexpr Bitmap bitmap_rssipwm { + { 24, 16 }, bitmap_rssipwm_data +}; + +static constexpr uint8_t bitmap_sd_card_error_data[] = { + 0x00, 0x00, + 0x00, 0x00, + 0xC0, 0x1F, + 0xE0, 0x1F, + 0xF0, 0x1F, + 0xF8, 0x1F, + 0xC8, 0x13, + 0x98, 0x19, + 0x38, 0x1C, + 0x78, 0x1E, + 0x38, 0x1C, + 0x98, 0x19, + 0xC8, 0x13, + 0xF8, 0x1F, + 0x00, 0x00, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_sd_card_error { + { 16, 16 }, bitmap_sd_card_error_data +}; + +static constexpr uint8_t bitmap_sd_card_ok_data[] = { + 0x00, 0x00, + 0x00, 0x00, + 0xC0, 0x1F, + 0xE0, 0x1F, + 0xF0, 0x1F, + 0xF8, 0x1F, + 0xF8, 0x1F, + 0x98, 0x15, + 0x68, 0x19, + 0x68, 0x1D, + 0x68, 0x19, + 0x98, 0x15, + 0xF8, 0x1F, + 0xF8, 0x1F, + 0x00, 0x00, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_sd_card_ok { + { 16, 16 }, bitmap_sd_card_ok_data +}; + +static constexpr uint8_t bitmap_sd_card_unknown_data[] = { + 0x00, 0x00, + 0x00, 0x00, + 0xC0, 0x1F, + 0xE0, 0x1F, + 0xF0, 0x1F, + 0xF8, 0x1F, + 0x38, 0x1C, + 0x98, 0x19, + 0xF8, 0x1C, + 0x78, 0x1E, + 0x78, 0x1E, + 0xF8, 0x1F, + 0x78, 0x1E, + 0xF8, 0x1F, + 0x00, 0x00, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_sd_card_unknown { + { 16, 16 }, bitmap_sd_card_unknown_data +}; + +static constexpr uint8_t bitmap_sig_cw_data[] = { + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0xFE, 0xFF, 0xFF, 0x7F, + 0xFE, 0xFF, 0xFF, 0x7F, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, +}; +static constexpr Bitmap bitmap_sig_cw { + { 32, 32 }, bitmap_sig_cw_data }; static constexpr uint8_t bitmap_sig_noise_data[] = { @@ -2203,70 +2101,156 @@ static constexpr Bitmap bitmap_sig_noise { { 32, 32 }, bitmap_sig_noise_data }; -static constexpr uint8_t bitmap_icon_back_data[] = { - 0x00, 0x00, - 0x30, 0x00, - 0x38, 0x00, - 0x1C, 0x00, - 0x0E, 0x00, - 0xFF, 0x3F, - 0xFF, 0x7F, - 0x0E, 0xE0, - 0x1C, 0xC0, - 0x38, 0xC0, - 0x30, 0xC0, - 0x00, 0xE0, - 0x00, 0x7F, - 0x00, 0x3F, - 0x00, 0x00, - 0x00, 0x00, +static constexpr uint8_t bitmap_sig_saw_down_data[] = { + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x0E, 0x80, 0x00, 0x60, + 0x1E, 0x80, 0x01, 0x60, + 0x3E, 0x80, 0x03, 0x60, + 0x76, 0x80, 0x07, 0x60, + 0xE6, 0x80, 0x0F, 0x60, + 0xC6, 0x81, 0x1D, 0x60, + 0x86, 0x83, 0x39, 0x60, + 0x06, 0x87, 0x71, 0x60, + 0x06, 0x8E, 0xE1, 0x60, + 0x06, 0x9C, 0xC1, 0x61, + 0x06, 0xB8, 0x81, 0x63, + 0x06, 0xF0, 0x01, 0x67, + 0x06, 0xE0, 0x01, 0x6E, + 0x06, 0xC0, 0x01, 0x7C, + 0x06, 0x80, 0x01, 0x78, + 0x06, 0x00, 0x01, 0x70, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, }; -static constexpr Bitmap bitmap_icon_back { - { 16, 16 }, bitmap_icon_back_data +static constexpr Bitmap bitmap_sig_saw_down { + { 32, 32 }, bitmap_sig_saw_down_data }; -static constexpr uint8_t bitmap_icon_nrf_data[] = { - 0x00, 0x01, - 0x00, 0x01, - 0x00, 0x01, - 0x00, 0x01, - 0x00, 0x01, - 0x00, 0x01, - 0x00, 0x01, - 0xF8, 0x3F, - 0xFC, 0x7F, - 0xFC, 0x7F, - 0xDC, 0x7F, - 0x8C, 0x6B, - 0xDC, 0x7F, - 0xFC, 0x7F, - 0xFC, 0x7F, - 0xF8, 0x3F, +static constexpr uint8_t bitmap_sig_saw_up_data[] = { + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x01, 0x70, + 0x06, 0x80, 0x01, 0x78, + 0x06, 0xC0, 0x01, 0x7C, + 0x06, 0xE0, 0x01, 0x6E, + 0x06, 0xF0, 0x01, 0x67, + 0x06, 0xB8, 0x81, 0x63, + 0x06, 0x9C, 0xC1, 0x61, + 0x06, 0x8E, 0xE1, 0x60, + 0x06, 0x87, 0x71, 0x60, + 0x86, 0x83, 0x39, 0x60, + 0xC6, 0x81, 0x1D, 0x60, + 0xE6, 0x80, 0x0F, 0x60, + 0x76, 0x80, 0x07, 0x60, + 0x3E, 0x80, 0x03, 0x60, + 0x1E, 0x80, 0x01, 0x60, + 0x0E, 0x80, 0x00, 0x60, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, }; -static constexpr Bitmap bitmap_icon_nrf { - { 16, 16 }, bitmap_icon_nrf_data +static constexpr Bitmap bitmap_sig_saw_up { + { 32, 32 }, bitmap_sig_saw_up_data }; -static constexpr uint8_t bitmap_icon_camera_data[] = { - 0x00, 0x00, - 0x00, 0x00, - 0xE0, 0x07, - 0xF0, 0x0F, - 0x3E, 0x7C, - 0xDE, 0x7B, - 0xEE, 0x77, - 0xEE, 0x77, - 0xEE, 0x77, - 0xEE, 0x77, - 0xDE, 0x7B, - 0x3E, 0x7C, - 0xFE, 0x7F, - 0x00, 0x00, - 0x00, 0x00, - 0x00, 0x00, +static constexpr uint8_t bitmap_sig_sine_data[] = { + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0xC0, 0x00, + 0x80, 0x07, 0xE0, 0x01, + 0xC0, 0x0F, 0xF0, 0x03, + 0xC0, 0x0C, 0x30, 0x03, + 0x60, 0x18, 0x18, 0x06, + 0x60, 0x18, 0x18, 0x06, + 0x60, 0x18, 0x18, 0x06, + 0x60, 0x18, 0x18, 0x06, + 0x30, 0x30, 0x0C, 0x0C, + 0x30, 0x30, 0x0C, 0x0C, + 0x30, 0x30, 0x0C, 0x0C, + 0x30, 0x30, 0x0C, 0x0C, + 0x18, 0x60, 0x06, 0x18, + 0x1E, 0xE0, 0x07, 0x78, + 0x0E, 0xC0, 0x03, 0x70, + 0x06, 0x80, 0x01, 0x60, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, }; -static constexpr Bitmap bitmap_icon_camera { - { 16, 16 }, bitmap_icon_camera_data +static constexpr Bitmap bitmap_sig_sine { + { 32, 32 }, bitmap_sig_sine_data +}; + +static constexpr uint8_t bitmap_sig_square_data[] = { + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0xFE, 0x83, 0xFF, 0x60, + 0xFE, 0x83, 0xFF, 0x60, + 0x06, 0x83, 0xC1, 0x60, + 0x06, 0x83, 0xC1, 0x60, + 0x06, 0x83, 0xC1, 0x60, + 0x06, 0x83, 0xC1, 0x60, + 0x06, 0x83, 0xC1, 0x60, + 0x06, 0x83, 0xC1, 0x60, + 0x06, 0x83, 0xC1, 0x60, + 0x06, 0x83, 0xC1, 0x60, + 0x06, 0x83, 0xC1, 0x60, + 0x06, 0x83, 0xC1, 0x60, + 0x06, 0x83, 0xC1, 0x60, + 0x06, 0x83, 0xC1, 0x60, + 0x06, 0xFF, 0xC1, 0x7F, + 0x06, 0xFF, 0xC1, 0x7F, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, +}; +static constexpr Bitmap bitmap_sig_square { + { 32, 32 }, bitmap_sig_square_data }; static constexpr uint8_t bitmap_sig_tri_data[] = { @@ -2307,26 +2291,130 @@ static constexpr Bitmap bitmap_sig_tri { { 32, 32 }, bitmap_sig_tri_data }; -static constexpr uint8_t bitmap_icon_options_radio_data[] = { +static constexpr uint8_t bitmap_stop_data[] = { + 0xFF, 0xFF, + 0xFF, 0xFF, + 0xFF, 0xFF, + 0xFF, 0xFF, + 0xFF, 0xFF, + 0x8B, 0xCD, + 0xDD, 0xAA, + 0xDB, 0xCA, + 0xDB, 0xEA, + 0xDD, 0xED, + 0xFF, 0xFF, + 0xFF, 0xFF, + 0xFF, 0xFF, + 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, - 0x00, 0x00, - 0x04, 0x20, - 0x12, 0x48, - 0x8A, 0x51, - 0xCA, 0x53, - 0xCA, 0x53, - 0x8A, 0x51, - 0x12, 0x48, - 0x84, 0x21, - 0xC0, 0x03, - 0x40, 0x02, - 0x60, 0x06, - 0x20, 0x04, - 0x30, 0x0C, - 0xF0, 0x0F, }; -static constexpr Bitmap bitmap_icon_options_radio { - { 16, 16 }, bitmap_icon_options_radio_data +static constexpr Bitmap bitmap_stop { + { 16, 16 }, bitmap_stop_data +}; + +static constexpr uint8_t bitmap_stripes_data[] = { + 0xFF, 0x03, 0xC0, + 0xFF, 0x01, 0xE0, + 0xFF, 0x00, 0xF0, + 0x7F, 0x00, 0xF8, + 0x3F, 0x00, 0xFC, + 0x1F, 0x00, 0xFE, + 0x0F, 0x00, 0xFF, + 0x07, 0x80, 0xFF, +}; +static constexpr Bitmap bitmap_stripes { + { 24, 8 }, bitmap_stripes_data +}; + +static constexpr uint8_t bitmap_tab_edge_data[] = { + 0x00, + 0x01, + 0x01, + 0x03, + 0x03, + 0x03, + 0x07, + 0x07, + 0x07, + 0x0F, + 0x0F, + 0x0F, + 0x1F, + 0x1F, + 0x1F, + 0x1F, + 0x3F, + 0x3F, + 0x3F, + 0x7F, + 0x7F, + 0x7F, + 0xFF, + 0xFF, +}; +static constexpr Bitmap bitmap_tab_edge { + { 8, 24 }, bitmap_tab_edge_data +}; + +static constexpr uint8_t bitmap_target_data[] = { + 0x80, 0x00, + 0x80, 0x00, + 0xE0, 0x03, + 0x90, 0x04, + 0x88, 0x08, + 0x04, 0x10, + 0x04, 0x10, + 0x1F, 0x7C, + 0x04, 0x10, + 0x04, 0x10, + 0x88, 0x08, + 0x90, 0x04, + 0xE0, 0x03, + 0x80, 0x00, + 0x80, 0x00, + 0x00, 0x00, +}; +static constexpr Bitmap bitmap_target { + { 16, 16 }, bitmap_target_data +}; + +static constexpr uint8_t bitmap_target_calibrate_data[] = { + 0x02, 0x00, 0x00, 0x40, + 0x07, 0x00, 0x00, 0xE0, + 0x0E, 0x00, 0x00, 0x70, + 0x1C, 0x00, 0x00, 0x38, + 0x38, 0x00, 0x00, 0x1C, + 0x70, 0x00, 0x00, 0x0E, + 0xE0, 0x00, 0x00, 0x07, + 0xC0, 0x01, 0x80, 0x03, + 0x80, 0x03, 0xC0, 0x01, + 0x00, 0x07, 0xE0, 0x00, + 0x00, 0x0E, 0x70, 0x00, + 0x00, 0x1C, 0x38, 0x00, + 0x00, 0x38, 0x1C, 0x00, + 0x00, 0x70, 0x0E, 0x00, + 0x00, 0xE0, 0x07, 0x00, + 0x00, 0xC0, 0x03, 0x00, + 0x00, 0xC0, 0x03, 0x00, + 0x00, 0xE0, 0x07, 0x00, + 0x00, 0x70, 0x0E, 0x00, + 0x00, 0x38, 0x1C, 0x00, + 0x00, 0x1C, 0x38, 0x00, + 0x00, 0x0E, 0x70, 0x00, + 0x00, 0x07, 0xE0, 0x00, + 0x80, 0x03, 0xC0, 0x01, + 0xC0, 0x01, 0x80, 0x03, + 0xE0, 0x00, 0x00, 0x07, + 0x70, 0x00, 0x00, 0x0E, + 0x38, 0x00, 0x00, 0x1C, + 0x1C, 0x00, 0x00, 0x38, + 0x0E, 0x00, 0x00, 0x70, + 0x07, 0x00, 0x00, 0xE0, + 0x02, 0x00, 0x00, 0x40, +}; +static constexpr Bitmap bitmap_target_calibrate { + { 32, 32 }, bitmap_target_calibrate_data }; static constexpr uint8_t bitmap_target_verify_data[] = { @@ -2367,92 +2455,26 @@ static constexpr Bitmap bitmap_target_verify { { 32, 32 }, bitmap_target_verify_data }; -static constexpr uint8_t bitmap_play_data[] = { - 0x00, 0x00, - 0x00, 0x00, - 0x0C, 0x00, - 0x3C, 0x00, - 0xFC, 0x00, - 0xFC, 0x03, - 0xFC, 0x0F, - 0xFC, 0x3F, - 0xFC, 0x3F, - 0xFC, 0x0F, - 0xFC, 0x03, - 0xFC, 0x00, - 0x3C, 0x00, - 0x0C, 0x00, - 0x00, 0x00, - 0x00, 0x00, +static constexpr uint8_t bitmap_titlebar_image_data[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x22, 0xC7, 0x8B, 0x9E, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xA2, 0x28, 0x48, 0xA6, 0x81, 0x31, 0x67, 0x36, 0x73, 0x63, + 0xBE, 0x2F, 0x38, 0x9E, 0x87, 0xBB, 0x6D, 0x36, 0x1B, 0x77, + 0xA2, 0x28, 0x48, 0xA6, 0x81, 0xBF, 0x6D, 0x36, 0x1B, 0x7F, + 0xA2, 0xC8, 0x8B, 0xA6, 0x81, 0xB5, 0xCF, 0xF3, 0x7B, 0x6B, + 0x00, 0x00, 0x00, 0x00, 0x80, 0xB1, 0x8D, 0x31, 0x1B, 0x63, + 0xEE, 0xEE, 0xEE, 0xEE, 0x8A, 0xB1, 0x8D, 0x31, 0x1B, 0x63, + 0xAE, 0x46, 0xEE, 0x2E, 0x86, 0xB1, 0x8D, 0x31, 0x73, 0x63, + 0xE2, 0x4A, 0x2A, 0xEA, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; -static constexpr Bitmap bitmap_play { - { 16, 16 }, bitmap_play_data -}; - -static constexpr uint8_t bitmap_icon_options_ui_data[] = { - 0xFF, 0x1F, - 0xFF, 0x13, - 0xFF, 0x1F, - 0x01, 0x10, - 0x01, 0x10, - 0x01, 0x10, - 0x01, 0x04, - 0x01, 0x0C, - 0x01, 0x1C, - 0x01, 0x3C, - 0xFF, 0x7D, - 0x00, 0xFC, - 0x00, 0x34, - 0x00, 0x20, - 0x00, 0x60, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_options_ui { - { 16, 16 }, bitmap_icon_options_ui_data -}; - -static constexpr uint8_t bitmap_target_data[] = { - 0x80, 0x00, - 0x80, 0x00, - 0xE0, 0x03, - 0x90, 0x04, - 0x88, 0x08, - 0x04, 0x10, - 0x04, 0x10, - 0x1F, 0x7C, - 0x04, 0x10, - 0x04, 0x10, - 0x88, 0x08, - 0x90, 0x04, - 0xE0, 0x03, - 0x80, 0x00, - 0x80, 0x00, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_target { - { 16, 16 }, bitmap_target_data -}; - -static constexpr uint8_t bitmap_icon_lge_data[] = { - 0x00, 0x00, - 0x80, 0x00, - 0xA4, 0x12, - 0xA8, 0x0A, - 0xD0, 0x05, - 0xEC, 0x1B, - 0xF0, 0x07, - 0xFE, 0xFF, - 0xF0, 0x07, - 0xEC, 0x1B, - 0xD0, 0x05, - 0xA8, 0x0A, - 0xA4, 0x12, - 0x80, 0x00, - 0x00, 0x00, - 0x00, 0x00, -}; -static constexpr Bitmap bitmap_icon_lge { - { 16, 16 }, bitmap_icon_lge_data +static constexpr Bitmap bitmap_titlebar_image { + { 80, 16 }, bitmap_titlebar_image_data }; diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp index 4cc4ebe9..59a6169b 100644 --- a/firmware/application/ui_navigation.cpp +++ b/firmware/application/ui_navigation.cpp @@ -543,12 +543,12 @@ SystemMenuView::SystemMenuView(NavigationView& nav) { { "Capture", ui::Color::red(), &bitmap_icon_capture, [&nav](){ nav.push(); } }, { "Replay", ui::Color::green(), &bitmap_icon_replay, [&nav](){ nav.push(); } }, { "Calls", ui::Color::yellow(), &bitmap_icon_search, [&nav](){ nav.push(); } }, - { "Scanner", ui::Color::green(), &bitmap_icon_scanner, [&nav](){ nav.push(); } }, + { "Scanner", ui::Color::yellow(), &bitmap_icon_scanner, [&nav](){ nav.push(); } }, { "Microphone", ui::Color::yellow(), &bitmap_icon_microphone,[&nav](){ nav.push(); } }, + { "Looking Glass", ui::Color::yellow(), &bitmap_icon_looking, [&nav](){ nav.push(); } }, { "Tools", ui::Color::cyan(), &bitmap_icon_utilities, [&nav](){ nav.push(); } }, { "Options", ui::Color::cyan(), &bitmap_icon_setup, [&nav](){ nav.push(); } }, { "Debug", ui::Color::light_grey(), &bitmap_icon_debug, [&nav](){ nav.push(); } }, - { "Lookin'Glass", ui::Color::red(), &bitmap_icon_search, [&nav](){ nav.push(); } }, { "HackRF", ui::Color::cyan(), &bitmap_icon_hackrf, [this, &nav](){ hackrf_mode(nav); } }, //{ "About", ui::Color::cyan(), nullptr, [&nav](){ nav.push(); } } }); diff --git a/firmware/graphics/icon_looking.png b/firmware/graphics/icon_looking.png new file mode 100644 index 0000000000000000000000000000000000000000..3634b5def4e13a934df43bfced3d53bfc53196e6 GIT binary patch literal 180 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Rh}-6Ar}5ygB|$}C~!#suQ%yd zn{X@g#-_8A#dKL$$!@rF_oGa;@n%`O4LmE3%brv@aD2|%E??HWt$L0^E@^tLg<(51 z9#oar{_KA+S?J21)o%OclTFqc3t0(H)e~F0X3a5e+jIBAmG}A{=<_+hB7WHiZ%u#B efRh=|IKQmS;S4&