portapack-mayhem/firmware/application/apps/ui_scanner.hpp
euquiq 27f566be8f scanner-enhanced-version
New ui_scanner, inspired on AlainD's (alain00091) PR: https://github.com/eried/portapack-mayhem/pull/80

It includes the following:

1) A big frequency numbers display.

2) A Manual scan section (you can input a frequency range (START / END), choose a STEP value from an available of standard frequency intervals, and press SCAN button.

3) An AM / WFM / NFM scan mode selector, changing "on the fly".

4) A PAUSE / RESUME button, which will make the scanner to stop upon you listening something of interest

5) AUDIO APP button, a quick shortcut into the analog audio visualizing / recording app, with the mode, frequency, amp, LNA, VGA settings already in tune with the scanner.

6) Two enums are added to freqman.hpp, reserved for compatibility with AlainD's proposed freqman's app and / or further enhancement. More on this topic:

ORIGINAL scanner just used one frequency step, when creating scanning frequency ranges, which was unacceptable.  AlainD enhanced freqman in order to pass different steppings along with ranges.  This seems an excellent idea, and I preserved that aspect on my current implementation of thisscanner, while adding those enums into the freqman just to keep the door open for AlainD's freqman in the future.

7) I did eliminate the extra blank spaces added by function to_string_short_freq() which created unnecessary spacing in every app where there is need for a SHORT string, from a frequency number. (SHORT!, no extra spaces!!)

8) I also maintained AlainD idea of capping the number of frequencies which are dynamically created for each range and stored inside a memory based db. While AlainD capped the number into 400 frequencies, I was able to up that value a bit more, into 500.

Cheers!
2020-07-20 16:43:24 -03:00

259 lines
5.5 KiB
C++

/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2018 Furrtek
*
* 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 "receiver_model.hpp"
#include "ui_receiver.hpp"
#include "ui_font_fixed_8x16.hpp"
#include "ui_spectrum.hpp"
#include "freqman.hpp"
#include "log_file.hpp"
#include "analog_audio_app.hpp"
#define MAX_DB_ENTRY 500
namespace ui {
enum modulation_type { AM = 0,WFM,NFM };
string const mod_name[3] = {"AM", "WFM", "NFM"};
size_t const mod_step[3] = {9000, 100000, 12500 };
class ScannerThread {
public:
ScannerThread(std::vector<rf::Frequency> frequency_list);
~ScannerThread();
void set_scanning(const bool v);
bool is_scanning();
void set_userpause(const bool v);
bool is_userpause();
void stop();
ScannerThread(const ScannerThread&) = delete;
ScannerThread(ScannerThread&&) = delete;
ScannerThread& operator=(const ScannerThread&) = delete;
ScannerThread& operator=(ScannerThread&&) = delete;
private:
std::vector<rf::Frequency> frequency_list_ { };
Thread* thread { nullptr };
bool _scanning { true };
bool _userpause { false };
static msg_t static_fn(void* arg);
void run();
};
class ScannerView : public View {
public:
ScannerView(NavigationView& nav);
~ScannerView();
void focus() override;
void big_display_freq(rf::Frequency f);
const Style style_grey { // scanning
.font = font::fixed_8x16,
.background = Color::black(),
.foreground = Color::grey(),
};
const Style style_green { //Found signal
.font = font::fixed_8x16,
.background = Color::black(),
.foreground = Color::green(),
};
std::string title() const override { return "SCANNER"; };
std::vector<rf::Frequency> frequency_list{ };
std::vector<string> description_list { };
//void set_parent_rect(const Rect new_parent_rect) override;
private:
NavigationView& nav_;
void start_scan_thread();
size_t change_mode(uint8_t mod_type);
void show_max();
void scan_pause();
void scan_resume();
void on_statistics_update(const ChannelStatistics& statistics);
void on_headphone_volume_changed(int32_t v);
void handle_retune(uint32_t i);
jammer::jammer_range_t frequency_range { false, 0, 0 }; //perfect for manual scan task too...
int32_t squelch { 0 };
uint32_t timer { 0 };
uint32_t wait { 0 };
size_t def_step { 0 };
freqman_db database { };
Labels labels {
{ { 0 * 8, 0 * 16 }, "LNA: VGA: AMP: VOL:", Color::light_grey() },
{ { 0 * 8, 1* 16 }, "BW: SQUELCH: /99 WAIT:", Color::light_grey() },
{ { 3 * 8, 10 * 16 }, "START END MANUAL", Color::light_grey() },
{ { 0 * 8, 14 * 16 }, "MODE:", Color::light_grey() },
{ { 11 * 8, 14 * 16 }, "STEP:", Color::light_grey() },
};
LNAGainField field_lna {
{ 4 * 8, 0 * 16 }
};
VGAGainField field_vga {
{ 11 * 8, 0 * 16 }
};
RFAmpField field_rf_amp {
{ 18 * 8, 0 * 16 }
};
NumberField field_volume {
{ 24 * 8, 0 * 16 },
2,
{ 0, 99 },
1,
' ',
};
OptionsField field_bw {
{ 3 * 8, 1 * 16 },
4,
{ }
};
NumberField field_squelch {
{ 15 * 8, 1 * 16 },
2,
{ 0, 99 },
1,
' ',
};
NumberField field_wait {
{ 26 * 8, 1 * 16 },
2,
{ 0, 99 },
1,
' ',
};
RSSI rssi {
{ 0 * 16, 2 * 16, 15 * 16, 8 },
};
Text text_cycle {
{ 0, 3 * 16, 3 * 8, 16 },
};
Text text_max {
{ 4 * 8, 3 * 16, 18 * 8, 16 },
};
Text desc_cycle {
{0, 4 * 16, 240, 16 },
};
BigFrequency big_display { //Show frequency in glamour
{ 4, 6 * 16, 28 * 8, 52 },
0
};
Button button_manual_start {
{ 0 * 8, 11 * 16, 11 * 8, 28 },
""
};
Button button_manual_end {
{ 12 * 8, 11 * 16, 11 * 8, 28 },
""
};
Button button_manual_scan {
{ 24 * 8, 11 * 16, 6 * 8, 28 },
"SCAN"
};
OptionsField field_mode {
{ 5 * 8, 14 * 16 },
6,
{
{ " AM ", 0 },
{ " WFM ", 1 },
{ " NFM ", 2 },
}
};
OptionsField step_mode {
{ 17 * 8, 14 * 16 },
12,
{
{ "5Khz (SA AM)", 5000 },
{ "9Khz (EU AM)", 9000 },
{ "10Khz(US AM)", 10000 },
{ "50Khz (FM1)", 50000 },
{ "100Khz(FM2)", 100000 },
{ "6.25khz(NFM)", 6250 },
{ "12.5khz(NFM)", 12500 },
{ "25khz (N1)", 25000 },
{ "250khz (N2)", 250000 },
{ "8.33khz(AIR)", 8330 }
}
};
Button button_pause {
{ 12, 17 * 16, 96, 24 },
"PAUSE"
};
Button button_audio_app {
{ 124, 17 * 16, 96, 24 },
"AUDIO APP"
};
std::unique_ptr<ScannerThread> scan_thread { };
MessageHandlerRegistration message_handler_retune {
Message::ID::Retune,
[this](const Message* const p) {
const auto message = *reinterpret_cast<const RetuneMessage*>(p);
this->handle_retune(message.range);
}
};
MessageHandlerRegistration message_handler_stats {
Message::ID::ChannelStatistics,
[this](const Message* const p) {
this->on_statistics_update(static_cast<const ChannelStatisticsMessage*>(p)->statistics);
}
};
};
} /* namespace ui */