mirror of
https://github.com/eried/portapack-mayhem.git
synced 2025-05-12 11:42:13 -04:00
Formatted code (#1007)
* Updated style * Updated files * fixed new line * Updated spacing * File fix WIP * Updated to clang 13 * updated comment style * Removed old comment code
This commit is contained in:
parent
7aca7ce74d
commit
033c4e9a5b
599 changed files with 70746 additions and 66896 deletions
|
@ -1,7 +1,14 @@
|
||||||
---
|
---
|
||||||
BasedOnStyle: Chromium
|
BasedOnStyle: Chromium
|
||||||
IndentWidth: '2'
|
IndentWidth: '4'
|
||||||
TabWidth: '2'
|
SortIncludes: 'false'
|
||||||
UseTab: Always
|
AllowAllArgumentsOnNextLine: 'true'
|
||||||
|
ColumnLimit: 0
|
||||||
|
Cpp11BracedListStyle: 'true'
|
||||||
|
AllowShortLoopsOnASingleLine: 'true'
|
||||||
|
AllowShortIfStatementsOnASingleLine: 'true'
|
||||||
|
SpacesInLineCommentPrefix:
|
||||||
|
Minimum: 1
|
||||||
|
Maximum: 1
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
11
.github/workflows/check_formatting.yml
vendored
11
.github/workflows/check_formatting.yml
vendored
|
@ -1,12 +1,17 @@
|
||||||
name: Check formatting
|
name: Check formatting
|
||||||
|
|
||||||
on: #[push, pull_request] To be enabled once formatting is fixed in repo
|
on: [push, pull_request]
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check_date:
|
check_date:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
name: Check formatting
|
name: Check formatting
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
path:
|
||||||
|
- "firmware/common"
|
||||||
|
- "firmware/application"
|
||||||
|
- "firmware/baseband"
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: print latest_commit
|
- name: print latest_commit
|
||||||
|
@ -14,5 +19,5 @@ jobs:
|
||||||
- name: clang-format Check
|
- name: clang-format Check
|
||||||
uses: jidicula/clang-format-action@v4.11.0
|
uses: jidicula/clang-format-action@v4.11.0
|
||||||
with:
|
with:
|
||||||
check-path: "firmware"
|
check-path: ${{ matrix.path }}
|
||||||
fallback-style: Chromium
|
fallback-style: Chromium
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
namespace std {
|
namespace std {
|
||||||
|
|
||||||
int app_settings::load(std::string application, AppSettings* settings) {
|
int app_settings::load(std::string application, AppSettings* settings) {
|
||||||
|
|
||||||
if (portapack::persistent_memory::load_app_settings()) {
|
if (portapack::persistent_memory::load_app_settings()) {
|
||||||
file_path = folder + "/" + application + ".ini";
|
file_path = folder + "/" + application + ".ini";
|
||||||
|
|
||||||
|
@ -59,15 +58,14 @@ int app_settings::load(std::string application, AppSettings* settings) {
|
||||||
settings->squelch = std::app_settings::read_long_long(file_content, "squelch=");
|
settings->squelch = std::app_settings::read_long_long(file_content, "squelch=");
|
||||||
|
|
||||||
rc = SETTINGS_OK;
|
rc = SETTINGS_OK;
|
||||||
}
|
} else
|
||||||
else rc = SETTINGS_UNABLE_TO_LOAD;
|
rc = SETTINGS_UNABLE_TO_LOAD;
|
||||||
}
|
} else
|
||||||
else rc = SETTINGS_DISABLED;
|
rc = SETTINGS_DISABLED;
|
||||||
return (rc);
|
return (rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
int app_settings::save(std::string application, AppSettings* settings) {
|
int app_settings::save(std::string application, AppSettings* settings) {
|
||||||
|
|
||||||
if (portapack::persistent_memory::save_app_settings()) {
|
if (portapack::persistent_memory::save_app_settings()) {
|
||||||
file_path = folder + "/" + application + ".ini";
|
file_path = folder + "/" + application + ".ini";
|
||||||
make_new_directory(folder);
|
make_new_directory(folder);
|
||||||
|
@ -94,14 +92,13 @@ int app_settings::save(std::string application, AppSettings* settings) {
|
||||||
settings_file.write_line("squelch=" + to_string_dec_uint(settings->squelch));
|
settings_file.write_line("squelch=" + to_string_dec_uint(settings->squelch));
|
||||||
|
|
||||||
rc = SETTINGS_OK;
|
rc = SETTINGS_OK;
|
||||||
}
|
} else
|
||||||
else rc = SETTINGS_UNABLE_TO_SAVE;
|
rc = SETTINGS_UNABLE_TO_SAVE;
|
||||||
}
|
} else
|
||||||
else rc = SETTINGS_DISABLED;
|
rc = SETTINGS_DISABLED;
|
||||||
return (rc);
|
return (rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
long long int app_settings::read_long_long(char* file_content, const char* setting_text) {
|
long long int app_settings::read_long_long(char* file_content, const char* setting_text) {
|
||||||
auto position = strstr(file_content, (char*)setting_text);
|
auto position = strstr(file_content, (char*)setting_text);
|
||||||
if (position) {
|
if (position) {
|
||||||
|
@ -111,5 +108,4 @@ long long int app_settings::read_long_long(char* file_content, const char* setti
|
||||||
return (setting_value);
|
return (setting_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} /* namespace std */
|
} /* namespace std */
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#ifndef __APP_SETTINGS_H__
|
#ifndef __APP_SETTINGS_H__
|
||||||
#define __APP_SETTINGS_H__
|
#define __APP_SETTINGS_H__
|
||||||
|
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -32,21 +31,14 @@
|
||||||
#include "file.hpp"
|
#include "file.hpp"
|
||||||
#include "string_format.hpp"
|
#include "string_format.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
class app_settings {
|
class app_settings {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
#define SETTINGS_OK 0 // settings found
|
#define SETTINGS_OK 0 // settings found
|
||||||
#define SETTINGS_UNABLE_TO_LOAD -1 // settings (file) not found
|
#define SETTINGS_UNABLE_TO_LOAD -1 // settings (file) not found
|
||||||
#define SETTINGS_UNABLE_TO_SAVE -2 // unable to save settings
|
#define SETTINGS_UNABLE_TO_SAVE -2 // unable to save settings
|
||||||
#define SETTINGS_DISABLED -3 // load/save settings disabled in settings
|
#define SETTINGS_DISABLED -3 // load/save settings disabled in settings
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct AppSettings {
|
struct AppSettings {
|
||||||
uint32_t baseband_bandwidth;
|
uint32_t baseband_bandwidth;
|
||||||
uint32_t channel_bandwidth;
|
uint32_t channel_bandwidth;
|
||||||
|
@ -69,9 +61,7 @@ public:
|
||||||
int load(std::string application, AppSettings* settings);
|
int load(std::string application, AppSettings* settings);
|
||||||
int save(std::string application, AppSettings* settings);
|
int save(std::string application, AppSettings* settings);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
#define MAX_FILE_CONTENT_SIZE 1000
|
#define MAX_FILE_CONTENT_SIZE 1000
|
||||||
|
|
||||||
char file_content[MAX_FILE_CONTENT_SIZE] = {};
|
char file_content[MAX_FILE_CONTENT_SIZE] = {};
|
||||||
|
@ -83,10 +73,7 @@ private:
|
||||||
|
|
||||||
long long int read_long_long(char* file_content, const char* setting_text);
|
long long int read_long_long(char* file_content, const char* setting_text);
|
||||||
|
|
||||||
|
|
||||||
}; // class app_settings
|
}; // class app_settings
|
||||||
} // namespace std
|
} // namespace std
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /*__APP_SETTINGS_H__*/
|
#endif /*__APP_SETTINGS_H__*/
|
||||||
|
|
|
@ -63,16 +63,14 @@ void ACARSAppView::update_freq(rf::Frequency f) {
|
||||||
ACARSAppView::ACARSAppView(NavigationView& nav) {
|
ACARSAppView::ACARSAppView(NavigationView& nav) {
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_acars);
|
baseband::run_image(portapack::spi_flash::image_tag_acars);
|
||||||
|
|
||||||
add_children({
|
add_children({&rssi,
|
||||||
&rssi,
|
|
||||||
&channel,
|
&channel,
|
||||||
&field_rf_amp,
|
&field_rf_amp,
|
||||||
&field_lna,
|
&field_lna,
|
||||||
&field_vga,
|
&field_vga,
|
||||||
&field_frequency,
|
&field_frequency,
|
||||||
&check_log,
|
&check_log,
|
||||||
&console
|
&console});
|
||||||
});
|
|
||||||
|
|
||||||
receiver_model.set_sampling_rate(2457600);
|
receiver_model.set_sampling_rate(2457600);
|
||||||
receiver_model.set_baseband_bandwidth(1750000);
|
receiver_model.set_baseband_bandwidth(1750000);
|
||||||
|
|
|
@ -60,14 +60,11 @@ private:
|
||||||
uint32_t packet_counter{0};
|
uint32_t packet_counter{0};
|
||||||
|
|
||||||
RFAmpField field_rf_amp{
|
RFAmpField field_rf_amp{
|
||||||
{ 13 * 8, 0 * 16 }
|
{13 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
LNAGainField field_lna{
|
LNAGainField field_lna{
|
||||||
{ 15 * 8, 0 * 16 }
|
{15 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
VGAGainField field_vga{
|
VGAGainField field_vga{
|
||||||
{ 18 * 8, 0 * 16 }
|
{18 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
RSSI rssi{
|
RSSI rssi{
|
||||||
{21 * 8, 0, 6 * 8, 4},
|
{21 * 8, 0, 6 * 8, 4},
|
||||||
};
|
};
|
||||||
|
@ -82,12 +79,10 @@ private:
|
||||||
{22 * 8, 21},
|
{22 * 8, 21},
|
||||||
3,
|
3,
|
||||||
"LOG",
|
"LOG",
|
||||||
true
|
true};
|
||||||
};
|
|
||||||
|
|
||||||
Console console{
|
Console console{
|
||||||
{ 0, 3 * 16, 240, 256 }
|
{0, 3 * 16, 240, 256}};
|
||||||
};
|
|
||||||
|
|
||||||
std::unique_ptr<ACARSLogger> logger{};
|
std::unique_ptr<ACARSLogger> logger{};
|
||||||
|
|
||||||
|
@ -106,9 +101,7 @@ private:
|
||||||
const auto message = static_cast<const ACARSPacketMessage*>(p);
|
const auto message = static_cast<const ACARSPacketMessage*>(p);
|
||||||
const acars::Packet packet{message->packet};
|
const acars::Packet packet{message->packet};
|
||||||
this->on_packet(packet);
|
this->on_packet(packet);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -58,15 +58,12 @@ static float latlon_float(const int32_t normalized) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string mmsi(
|
static std::string mmsi(
|
||||||
const ais::MMSI& mmsi
|
const ais::MMSI& mmsi) {
|
||||||
) {
|
|
||||||
return to_string_dec_uint(mmsi, 9, '0'); // MMSI is always is always 9 characters pre-padded with zeros
|
return to_string_dec_uint(mmsi, 9, '0'); // MMSI is always is always 9 characters pre-padded with zeros
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static std::string mid(
|
static std::string mid(
|
||||||
const ais::MMSI& mmsi
|
const ais::MMSI& mmsi) {
|
||||||
) {
|
|
||||||
std::database db;
|
std::database db;
|
||||||
std::string mid_code = "";
|
std::string mid_code = "";
|
||||||
std::database::MidDBRecord mid_record = {};
|
std::database::MidDBRecord mid_record = {};
|
||||||
|
@ -76,46 +73,68 @@ static std::string mid(
|
||||||
mid_code = to_string_dec_uint(mmsi, 9, ' ').substr(0, 3);
|
mid_code = to_string_dec_uint(mmsi, 9, ' ').substr(0, 3);
|
||||||
return_code = db.retrieve_mid_record(&mid_record, mid_code);
|
return_code = db.retrieve_mid_record(&mid_record, mid_code);
|
||||||
switch (return_code) {
|
switch (return_code) {
|
||||||
case DATABASE_RECORD_FOUND: return mid_record.country;
|
case DATABASE_RECORD_FOUND:
|
||||||
case DATABASE_NOT_FOUND: return "No mids.db file";
|
return mid_record.country;
|
||||||
default: return "";
|
case DATABASE_NOT_FOUND:
|
||||||
|
return "No mids.db file";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string text(const std::string& text) {
|
static std::string text(const std::string& text) {
|
||||||
size_t end = text.find_last_not_of("@");
|
size_t end = text.find_last_not_of("@");
|
||||||
return (end == std::string::npos) ? "" : text.substr(0, end + 1);
|
return (end == std::string::npos) ? "" : text.substr(0, end + 1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string navigational_status(const unsigned int value) {
|
static std::string navigational_status(const unsigned int value) {
|
||||||
switch (value) {
|
switch (value) {
|
||||||
case 0: return "under way w/engine";
|
case 0:
|
||||||
case 1: return "at anchor";
|
return "under way w/engine";
|
||||||
case 2: return "not under command";
|
case 1:
|
||||||
case 3: return "restricted maneuv";
|
return "at anchor";
|
||||||
case 4: return "constrained draught";
|
case 2:
|
||||||
case 5: return "moored";
|
return "not under command";
|
||||||
case 6: return "aground";
|
case 3:
|
||||||
case 7: return "fishing";
|
return "restricted maneuv";
|
||||||
case 8: return "sailing";
|
case 4:
|
||||||
case 9: case 10: case 13: return "reserved";
|
return "constrained draught";
|
||||||
case 11: return "towing astern";
|
case 5:
|
||||||
case 12: return "towing ahead/along";
|
return "moored";
|
||||||
case 14: return "SART/MOB/EPIRB";
|
case 6:
|
||||||
case 15: return "undefined";
|
return "aground";
|
||||||
default: return "unknown";
|
case 7:
|
||||||
|
return "fishing";
|
||||||
|
case 8:
|
||||||
|
return "sailing";
|
||||||
|
case 9:
|
||||||
|
case 10:
|
||||||
|
case 13:
|
||||||
|
return "reserved";
|
||||||
|
case 11:
|
||||||
|
return "towing astern";
|
||||||
|
case 12:
|
||||||
|
return "towing ahead/along";
|
||||||
|
case 14:
|
||||||
|
return "SART/MOB/EPIRB";
|
||||||
|
case 15:
|
||||||
|
return "undefined";
|
||||||
|
default:
|
||||||
|
return "unknown";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string rate_of_turn(const RateOfTurn value) {
|
static std::string rate_of_turn(const RateOfTurn value) {
|
||||||
switch (value) {
|
switch (value) {
|
||||||
case -128: return "not available";
|
case -128:
|
||||||
case -127: return "left >5 deg/30sec";
|
return "not available";
|
||||||
case 0: return "0 deg/min";
|
case -127:
|
||||||
case 127: return "right >5 deg/30sec";
|
return "left >5 deg/30sec";
|
||||||
default:
|
case 0:
|
||||||
{
|
return "0 deg/min";
|
||||||
|
case 127:
|
||||||
|
return "right >5 deg/30sec";
|
||||||
|
default: {
|
||||||
std::string result = (value < 0) ? "left " : "right ";
|
std::string result = (value < 0) ? "left " : "right ";
|
||||||
const float value_deg_sqrt = value / 4.733f;
|
const float value_deg_sqrt = value / 4.733f;
|
||||||
const int32_t value_deg = value_deg_sqrt * value_deg_sqrt;
|
const int32_t value_deg = value_deg_sqrt * value_deg_sqrt;
|
||||||
|
@ -218,8 +237,7 @@ void AISRecentEntry::update(const ais::Packet& packet) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 24:
|
case 24:
|
||||||
switch (packet.read(38, 2))
|
switch (packet.read(38, 2)) {
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
name = packet.text(40, 20);
|
name = packet.text(40, 20);
|
||||||
break;
|
break;
|
||||||
|
@ -246,8 +264,7 @@ void RecentEntriesTable<AISRecentEntries>::draw(
|
||||||
const Entry& entry,
|
const Entry& entry,
|
||||||
const Rect& target_rect,
|
const Rect& target_rect,
|
||||||
Painter& painter,
|
Painter& painter,
|
||||||
const Style& style
|
const Style& style) {
|
||||||
) {
|
|
||||||
std::string line = ais::format::mmsi(entry.mmsi) + " ";
|
std::string line = ais::format::mmsi(entry.mmsi) + " ";
|
||||||
if (!entry.name.empty()) {
|
if (!entry.name.empty()) {
|
||||||
line += ais::format::text(entry.name);
|
line += ais::format::text(entry.name);
|
||||||
|
@ -283,19 +300,15 @@ AISRecentEntryDetailView::AISRecentEntryDetailView(NavigationView& nav) {
|
||||||
send_updates = false;
|
send_updates = false;
|
||||||
});
|
});
|
||||||
send_updates = true;
|
send_updates = true;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AISRecentEntryDetailView::AISRecentEntryDetailView(const AISRecentEntryDetailView& Entry)
|
||||||
AISRecentEntryDetailView::AISRecentEntryDetailView(const AISRecentEntryDetailView&Entry) : View()
|
: View() {
|
||||||
{
|
|
||||||
(void)Entry;
|
(void)Entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
AISRecentEntryDetailView & AISRecentEntryDetailView::operator=(const AISRecentEntryDetailView&Entry)
|
AISRecentEntryDetailView& AISRecentEntryDetailView::operator=(const AISRecentEntryDetailView& Entry) {
|
||||||
{
|
|
||||||
(void)Entry;
|
(void)Entry;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -314,8 +327,7 @@ Rect AISRecentEntryDetailView::draw_field(
|
||||||
const Rect& draw_rect,
|
const Rect& draw_rect,
|
||||||
const Style& style,
|
const Style& style,
|
||||||
const std::string& label,
|
const std::string& label,
|
||||||
const std::string& value
|
const std::string& value) {
|
||||||
) {
|
|
||||||
const int label_length_max = 4;
|
const int label_length_max = 4;
|
||||||
|
|
||||||
painter.draw_string(Point{draw_rect.left(), draw_rect.top()}, style, label);
|
painter.draw_string(Point{draw_rect.left(), draw_rect.top()}, style, label);
|
||||||
|
@ -352,7 +364,8 @@ void AISRecentEntryDetailView::set_entry(const AISRecentEntry& entry) {
|
||||||
set_dirty();
|
set_dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
AISAppView::AISAppView(NavigationView& nav) : nav_ { nav } {
|
AISAppView::AISAppView(NavigationView& nav)
|
||||||
|
: nav_{nav} {
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_ais);
|
baseband::run_image(portapack::spi_flash::image_tag_ais);
|
||||||
|
|
||||||
add_children({
|
add_children({
|
||||||
|
@ -367,7 +380,6 @@ AISAppView::AISAppView(NavigationView& nav) : nav_ { nav } {
|
||||||
&recent_entry_detail_view,
|
&recent_entry_detail_view,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// load app settings
|
// load app settings
|
||||||
auto rc = settings.load("rx_ais", &app_settings);
|
auto rc = settings.load("rx_ais", &app_settings);
|
||||||
if (rc == SETTINGS_OK) {
|
if (rc == SETTINGS_OK) {
|
||||||
|
@ -375,8 +387,8 @@ AISAppView::AISAppView(NavigationView& nav) : nav_ { nav } {
|
||||||
field_vga.set_value(app_settings.vga);
|
field_vga.set_value(app_settings.vga);
|
||||||
field_rf_amp.set_value(app_settings.rx_amp);
|
field_rf_amp.set_value(app_settings.rx_amp);
|
||||||
target_frequency_ = app_settings.rx_frequency;
|
target_frequency_ = app_settings.rx_frequency;
|
||||||
}
|
} else
|
||||||
else target_frequency_ = initial_target_frequency;
|
target_frequency_ = initial_target_frequency;
|
||||||
|
|
||||||
recent_entry_detail_view.hidden(true);
|
recent_entry_detail_view.hidden(true);
|
||||||
|
|
||||||
|
@ -404,7 +416,6 @@ AISAppView::AISAppView(NavigationView& nav) : nav_ { nav } {
|
||||||
}
|
}
|
||||||
|
|
||||||
AISAppView::~AISAppView() {
|
AISAppView::~AISAppView() {
|
||||||
|
|
||||||
// save app settings
|
// save app settings
|
||||||
app_settings.rx_frequency = target_frequency_;
|
app_settings.rx_frequency = target_frequency_;
|
||||||
settings.save("rx_ais", &app_settings);
|
settings.save("rx_ais", &app_settings);
|
||||||
|
|
|
@ -72,21 +72,19 @@ struct AISRecentEntry {
|
||||||
size_t received_count;
|
size_t received_count;
|
||||||
int8_t navigational_status;
|
int8_t navigational_status;
|
||||||
|
|
||||||
AISRecentEntry(
|
AISRecentEntry()
|
||||||
) : AISRecentEntry { 0 }
|
: AISRecentEntry{0} {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AISRecentEntry(
|
AISRecentEntry(
|
||||||
const ais::MMSI& mmsi
|
const ais::MMSI& mmsi)
|
||||||
) : mmsi { mmsi },
|
: mmsi{mmsi},
|
||||||
name{},
|
name{},
|
||||||
call_sign{},
|
call_sign{},
|
||||||
destination{},
|
destination{},
|
||||||
last_position{},
|
last_position{},
|
||||||
received_count{0},
|
received_count{0},
|
||||||
navigational_status { -1 }
|
navigational_status{-1} {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Key key() const {
|
Key key() const {
|
||||||
|
@ -135,12 +133,10 @@ private:
|
||||||
|
|
||||||
Button button_done{
|
Button button_done{
|
||||||
{125, 224, 96, 24},
|
{125, 224, 96, 24},
|
||||||
"Done"
|
"Done"};
|
||||||
};
|
|
||||||
Button button_see_map{
|
Button button_see_map{
|
||||||
{19, 224, 96, 24},
|
{19, 224, 96, 24},
|
||||||
"See on map"
|
"See on map"};
|
||||||
};
|
|
||||||
GeoMapView* geomap_view{nullptr};
|
GeoMapView* geomap_view{nullptr};
|
||||||
bool send_updates{false};
|
bool send_updates{false};
|
||||||
|
|
||||||
|
@ -149,8 +145,7 @@ private:
|
||||||
const Rect& draw_rect,
|
const Rect& draw_rect,
|
||||||
const Style& style,
|
const Style& style,
|
||||||
const std::string& label,
|
const std::string& label,
|
||||||
const std::string& value
|
const std::string& value);
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class AISAppView : public View {
|
class AISAppView : public View {
|
||||||
|
@ -173,7 +168,6 @@ private:
|
||||||
static constexpr uint32_t sampling_rate = 2457600;
|
static constexpr uint32_t sampling_rate = 2457600;
|
||||||
static constexpr uint32_t baseband_bandwidth = 1750000;
|
static constexpr uint32_t baseband_bandwidth = 1750000;
|
||||||
|
|
||||||
|
|
||||||
// app save settings
|
// app save settings
|
||||||
std::app_settings settings{};
|
std::app_settings settings{};
|
||||||
std::app_settings::AppSettings app_settings{};
|
std::app_settings::AppSettings app_settings{};
|
||||||
|
@ -194,8 +188,7 @@ private:
|
||||||
|
|
||||||
Text label_channel{
|
Text label_channel{
|
||||||
{0 * 8, 0 * 16, 2 * 8, 1 * 16},
|
{0 * 8, 0 * 16, 2 * 8, 1 * 16},
|
||||||
"Ch"
|
"Ch"};
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField options_channel{
|
OptionsField options_channel{
|
||||||
{3 * 8, 0 * 16},
|
{3 * 8, 0 * 16},
|
||||||
|
@ -203,20 +196,16 @@ private:
|
||||||
{
|
{
|
||||||
{"87B", 161975000},
|
{"87B", 161975000},
|
||||||
{"88B", 162025000},
|
{"88B", 162025000},
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
RFAmpField field_rf_amp{
|
RFAmpField field_rf_amp{
|
||||||
{ 13 * 8, 0 * 16 }
|
{13 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
LNAGainField field_lna{
|
LNAGainField field_lna{
|
||||||
{ 15 * 8, 0 * 16 }
|
{15 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
VGAGainField field_vga{
|
VGAGainField field_vga{
|
||||||
{ 18 * 8, 0 * 16 }
|
{18 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
RSSI rssi{
|
RSSI rssi{
|
||||||
{21 * 8, 0, 6 * 8, 4},
|
{21 * 8, 0, 6 * 8, 4},
|
||||||
|
@ -234,8 +223,7 @@ private:
|
||||||
if (packet.is_valid()) {
|
if (packet.is_valid()) {
|
||||||
this->on_packet(packet);
|
this->on_packet(packet);
|
||||||
}
|
}
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
uint32_t target_frequency_ = initial_target_frequency;
|
uint32_t target_frequency_ = initial_target_frequency;
|
||||||
|
|
||||||
|
|
|
@ -43,9 +43,9 @@ namespace ui {
|
||||||
/* AMOptionsView *********************************************************/
|
/* AMOptionsView *********************************************************/
|
||||||
|
|
||||||
AMOptionsView::AMOptionsView(
|
AMOptionsView::AMOptionsView(
|
||||||
const Rect parent_rect, const Style* const style
|
const Rect parent_rect,
|
||||||
) : View { parent_rect }
|
const Style* const style)
|
||||||
{
|
: View{parent_rect} {
|
||||||
set_style(style);
|
set_style(style);
|
||||||
|
|
||||||
add_children({
|
add_children({
|
||||||
|
@ -63,17 +63,15 @@ AMOptionsView::AMOptionsView(
|
||||||
/* NBFMOptionsView *******************************************************/
|
/* NBFMOptionsView *******************************************************/
|
||||||
|
|
||||||
NBFMOptionsView::NBFMOptionsView(
|
NBFMOptionsView::NBFMOptionsView(
|
||||||
const Rect parent_rect, const Style* const style
|
const Rect parent_rect,
|
||||||
) : View { parent_rect }
|
const Style* const style)
|
||||||
{
|
: View{parent_rect} {
|
||||||
set_style(style);
|
set_style(style);
|
||||||
|
|
||||||
add_children({
|
add_children({&label_config,
|
||||||
&label_config,
|
|
||||||
&options_config,
|
&options_config,
|
||||||
&text_squelch,
|
&text_squelch,
|
||||||
&field_squelch
|
&field_squelch});
|
||||||
});
|
|
||||||
|
|
||||||
freqman_set_bandwidth_option(NFM_MODULATION, options_config); // adding the common message from freqman.cpp to the options_config
|
freqman_set_bandwidth_option(NFM_MODULATION, options_config); // adding the common message from freqman.cpp to the options_config
|
||||||
options_config.set_selected_index(receiver_model.nbfm_configuration());
|
options_config.set_selected_index(receiver_model.nbfm_configuration());
|
||||||
|
@ -90,9 +88,9 @@ NBFMOptionsView::NBFMOptionsView(
|
||||||
/* WFMOptionsView *******************************************************/
|
/* WFMOptionsView *******************************************************/
|
||||||
|
|
||||||
WFMOptionsView::WFMOptionsView(
|
WFMOptionsView::WFMOptionsView(
|
||||||
const Rect parent_rect, const Style* const style
|
const Rect parent_rect,
|
||||||
) : View { parent_rect }
|
const Style* const style)
|
||||||
{
|
: View{parent_rect} {
|
||||||
set_style(style);
|
set_style(style);
|
||||||
|
|
||||||
add_children({
|
add_children({
|
||||||
|
@ -107,21 +105,19 @@ WFMOptionsView::WFMOptionsView(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* SPECOptionsView *******************************************************/
|
/* SPECOptionsView *******************************************************/
|
||||||
|
|
||||||
SPECOptionsView::SPECOptionsView(
|
SPECOptionsView::SPECOptionsView(
|
||||||
AnalogAudioView* view, const Rect parent_rect, const Style* const style
|
AnalogAudioView* view,
|
||||||
) : View { parent_rect }
|
const Rect parent_rect,
|
||||||
{
|
const Style* const style)
|
||||||
|
: View{parent_rect} {
|
||||||
set_style(style);
|
set_style(style);
|
||||||
|
|
||||||
add_children({
|
add_children({&label_config,
|
||||||
&label_config,
|
|
||||||
&options_config,
|
&options_config,
|
||||||
&text_speed,
|
&text_speed,
|
||||||
&field_speed
|
&field_speed});
|
||||||
});
|
|
||||||
|
|
||||||
options_config.set_selected_index(view->get_spec_bw_index());
|
options_config.set_selected_index(view->get_spec_bw_index());
|
||||||
options_config.on_change = [this, view](size_t n, OptionsField::value_t bw) {
|
options_config.on_change = [this, view](size_t n, OptionsField::value_t bw) {
|
||||||
|
@ -137,11 +133,9 @@ SPECOptionsView::SPECOptionsView(
|
||||||
/* AnalogAudioView *******************************************************/
|
/* AnalogAudioView *******************************************************/
|
||||||
|
|
||||||
AnalogAudioView::AnalogAudioView(
|
AnalogAudioView::AnalogAudioView(
|
||||||
NavigationView& nav
|
NavigationView& nav)
|
||||||
) : nav_ (nav)
|
: nav_(nav) {
|
||||||
{
|
add_children({&rssi,
|
||||||
add_children({
|
|
||||||
&rssi,
|
|
||||||
&channel,
|
&channel,
|
||||||
&audio,
|
&audio,
|
||||||
&field_frequency,
|
&field_frequency,
|
||||||
|
@ -151,8 +145,7 @@ AnalogAudioView::AnalogAudioView(
|
||||||
&field_volume,
|
&field_volume,
|
||||||
&text_ctcss,
|
&text_ctcss,
|
||||||
&record_view,
|
&record_view,
|
||||||
&waterfall
|
&waterfall});
|
||||||
});
|
|
||||||
|
|
||||||
// Set on_change before initialising the field
|
// Set on_change before initialising the field
|
||||||
field_frequency.on_change = [this](rf::Frequency f) {
|
field_frequency.on_change = [this](rf::Frequency f) {
|
||||||
|
@ -248,7 +241,6 @@ void AnalogAudioView::set_spec_trigger(uint16_t trigger) {
|
||||||
}
|
}
|
||||||
|
|
||||||
AnalogAudioView::~AnalogAudioView() {
|
AnalogAudioView::~AnalogAudioView() {
|
||||||
|
|
||||||
// save app settings
|
// save app settings
|
||||||
app_settings.rx_frequency = field_frequency.value();
|
app_settings.rx_frequency = field_frequency.value();
|
||||||
app_settings.lna = receiver_model.lna();
|
app_settings.lna = receiver_model.lna();
|
||||||
|
@ -412,10 +404,18 @@ void AnalogAudioView::update_modulation(const ReceiverModel::Mode modulation) {
|
||||||
|
|
||||||
portapack::spi_flash::image_tag_t image_tag;
|
portapack::spi_flash::image_tag_t image_tag;
|
||||||
switch (modulation) {
|
switch (modulation) {
|
||||||
case ReceiverModel::Mode::AMAudio: image_tag = portapack::spi_flash::image_tag_am_audio; break;
|
case ReceiverModel::Mode::AMAudio:
|
||||||
case ReceiverModel::Mode::NarrowbandFMAudio: image_tag = portapack::spi_flash::image_tag_nfm_audio; break;
|
image_tag = portapack::spi_flash::image_tag_am_audio;
|
||||||
case ReceiverModel::Mode::WidebandFMAudio: image_tag = portapack::spi_flash::image_tag_wfm_audio; break;
|
break;
|
||||||
case ReceiverModel::Mode::SpectrumAnalysis: image_tag = portapack::spi_flash::image_tag_wideband_spectrum; break;
|
case ReceiverModel::Mode::NarrowbandFMAudio:
|
||||||
|
image_tag = portapack::spi_flash::image_tag_nfm_audio;
|
||||||
|
break;
|
||||||
|
case ReceiverModel::Mode::WidebandFMAudio:
|
||||||
|
image_tag = portapack::spi_flash::image_tag_wfm_audio;
|
||||||
|
break;
|
||||||
|
case ReceiverModel::Mode::SpectrumAnalysis:
|
||||||
|
image_tag = portapack::spi_flash::image_tag_wideband_spectrum;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -437,9 +437,15 @@ void AnalogAudioView::update_modulation(const ReceiverModel::Mode modulation) {
|
||||||
// TODO: This doesn't belong here! There's a better way.
|
// TODO: This doesn't belong here! There's a better way.
|
||||||
size_t sampling_rate = 0;
|
size_t sampling_rate = 0;
|
||||||
switch (modulation) {
|
switch (modulation) {
|
||||||
case ReceiverModel::Mode::AMAudio: sampling_rate = 12000; break;
|
case ReceiverModel::Mode::AMAudio:
|
||||||
case ReceiverModel::Mode::NarrowbandFMAudio: sampling_rate = 24000; break;
|
sampling_rate = 12000;
|
||||||
case ReceiverModel::Mode::WidebandFMAudio: sampling_rate = 48000; break;
|
break;
|
||||||
|
case ReceiverModel::Mode::NarrowbandFMAudio:
|
||||||
|
sampling_rate = 24000;
|
||||||
|
break;
|
||||||
|
case ReceiverModel::Mode::WidebandFMAudio:
|
||||||
|
sampling_rate = 48000;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -450,7 +456,6 @@ void AnalogAudioView::update_modulation(const ReceiverModel::Mode modulation) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AnalogAudioView::handle_coded_squelch(const uint32_t value) {
|
void AnalogAudioView::handle_coded_squelch(const uint32_t value) {
|
||||||
float diff, min_diff = value;
|
float diff, min_diff = value;
|
||||||
size_t min_idx{0};
|
size_t min_idx{0};
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
#include "app_settings.hpp"
|
#include "app_settings.hpp"
|
||||||
#include "tone_key.hpp"
|
#include "tone_key.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
constexpr Style style_options_group{
|
constexpr Style style_options_group{
|
||||||
|
@ -54,9 +53,9 @@ private:
|
||||||
OptionsField options_config{
|
OptionsField options_config{
|
||||||
{3 * 8, 0 * 16},
|
{3 * 8, 0 * 16},
|
||||||
5,
|
5,
|
||||||
{ // using common messages from freqman.cpp
|
{
|
||||||
}
|
// using common messages from freqman.cpp
|
||||||
};
|
}};
|
||||||
};
|
};
|
||||||
|
|
||||||
class NBFMOptionsView : public View {
|
class NBFMOptionsView : public View {
|
||||||
|
@ -71,14 +70,13 @@ private:
|
||||||
OptionsField options_config{
|
OptionsField options_config{
|
||||||
{3 * 8, 0 * 16},
|
{3 * 8, 0 * 16},
|
||||||
4,
|
4,
|
||||||
{ // using common messages from freqman.cpp
|
{
|
||||||
}
|
// using common messages from freqman.cpp
|
||||||
};
|
}};
|
||||||
|
|
||||||
Text text_squelch{
|
Text text_squelch{
|
||||||
{9 * 8, 0 * 16, 8 * 8, 1 * 16},
|
{9 * 8, 0 * 16, 8 * 8, 1 * 16},
|
||||||
"SQ /99"
|
"SQ /99"};
|
||||||
};
|
|
||||||
NumberField field_squelch{
|
NumberField field_squelch{
|
||||||
{12 * 8, 0 * 16},
|
{12 * 8, 0 * 16},
|
||||||
2,
|
2,
|
||||||
|
@ -88,7 +86,6 @@ private:
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class WFMOptionsView : public View {
|
class WFMOptionsView : public View {
|
||||||
public:
|
public:
|
||||||
WFMOptionsView(const Rect parent_rect, const Style* const style);
|
WFMOptionsView(const Rect parent_rect, const Style* const style);
|
||||||
|
@ -101,9 +98,9 @@ private:
|
||||||
OptionsField options_config{
|
OptionsField options_config{
|
||||||
{3 * 8, 0 * 16},
|
{3 * 8, 0 * 16},
|
||||||
4,
|
4,
|
||||||
{ // using common messages from freqman.cpp
|
{
|
||||||
}
|
// using common messages from freqman.cpp
|
||||||
};
|
}};
|
||||||
};
|
};
|
||||||
|
|
||||||
class AnalogAudioView;
|
class AnalogAudioView;
|
||||||
|
@ -128,13 +125,11 @@ private:
|
||||||
{" 1m ", 1000000},
|
{" 1m ", 1000000},
|
||||||
{"500k", 500000},
|
{"500k", 500000},
|
||||||
{"100k", 100000},
|
{"100k", 100000},
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_speed{
|
Text text_speed{
|
||||||
{9 * 8, 0 * 16, 8 * 8, 1 * 16},
|
{9 * 8, 0 * 16, 8 * 8, 1 * 16},
|
||||||
"SP /63"
|
"SP /63"};
|
||||||
};
|
|
||||||
NumberField field_speed{
|
NumberField field_speed{
|
||||||
{12 * 8, 0 * 16},
|
{12 * 8, 0 * 16},
|
||||||
2,
|
2,
|
||||||
|
@ -197,12 +192,10 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
LNAGainField field_lna{
|
LNAGainField field_lna{
|
||||||
{ 15 * 8, 0 * 16 }
|
{15 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
VGAGainField field_vga{
|
VGAGainField field_vga{
|
||||||
{ 18 * 8, 0 * 16 }
|
{18 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField options_modulation{
|
OptionsField options_modulation{
|
||||||
{0 * 8, 0 * 16},
|
{0 * 8, 0 * 16},
|
||||||
|
@ -212,8 +205,7 @@ private:
|
||||||
{"NFM ", toUType(ReceiverModel::Mode::NarrowbandFMAudio)},
|
{"NFM ", toUType(ReceiverModel::Mode::NarrowbandFMAudio)},
|
||||||
{"WFM ", toUType(ReceiverModel::Mode::WidebandFMAudio)},
|
{"WFM ", toUType(ReceiverModel::Mode::WidebandFMAudio)},
|
||||||
{"SPEC", toUType(ReceiverModel::Mode::SpectrumAnalysis)},
|
{"SPEC", toUType(ReceiverModel::Mode::SpectrumAnalysis)},
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_volume{
|
NumberField field_volume{
|
||||||
{28 * 8, 0 * 16},
|
{28 * 8, 0 * 16},
|
||||||
|
@ -225,18 +217,17 @@ private:
|
||||||
|
|
||||||
Text text_ctcss{
|
Text text_ctcss{
|
||||||
{19 * 8, 1 * 16, 11 * 8, 1 * 16},
|
{19 * 8, 1 * 16, 11 * 8, 1 * 16},
|
||||||
""
|
""};
|
||||||
};
|
|
||||||
|
|
||||||
std::unique_ptr<Widget> options_widget{};
|
std::unique_ptr<Widget> options_widget{};
|
||||||
|
|
||||||
RecordView record_view{
|
RecordView record_view{
|
||||||
{0 * 8, 2 * 16, 30 * 8, 1 * 16},
|
{0 * 8, 2 * 16, 30 * 8, 1 * 16},
|
||||||
u"AUD", u"AUDIO",
|
u"AUD",
|
||||||
|
u"AUDIO",
|
||||||
RecordView::FileType::WAV,
|
RecordView::FileType::WAV,
|
||||||
4096,
|
4096,
|
||||||
4
|
4};
|
||||||
};
|
|
||||||
|
|
||||||
spectrum::WaterfallWidget waterfall{true};
|
spectrum::WaterfallWidget waterfall{true};
|
||||||
|
|
||||||
|
@ -272,8 +263,7 @@ private:
|
||||||
[this](const Message* const p) {
|
[this](const Message* const p) {
|
||||||
const auto message = *reinterpret_cast<const CodedSquelchMessage*>(p);
|
const auto message = *reinterpret_cast<const CodedSquelchMessage*>(p);
|
||||||
this->handle_coded_squelch(message.value);
|
this->handle_coded_squelch(message.value);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -42,11 +42,9 @@ namespace ui {
|
||||||
/* AnalogTvView *******************************************************/
|
/* AnalogTvView *******************************************************/
|
||||||
|
|
||||||
AnalogTvView::AnalogTvView(
|
AnalogTvView::AnalogTvView(
|
||||||
NavigationView& nav
|
NavigationView& nav)
|
||||||
) : nav_ (nav)
|
: nav_(nav) {
|
||||||
{
|
add_children({&rssi,
|
||||||
add_children({
|
|
||||||
&rssi,
|
|
||||||
&channel,
|
&channel,
|
||||||
&audio,
|
&audio,
|
||||||
&field_frequency,
|
&field_frequency,
|
||||||
|
@ -54,8 +52,7 @@ AnalogTvView::AnalogTvView(
|
||||||
&field_vga,
|
&field_vga,
|
||||||
&options_modulation,
|
&options_modulation,
|
||||||
&field_volume,
|
&field_volume,
|
||||||
&tv
|
&tv});
|
||||||
});
|
|
||||||
|
|
||||||
// Set on_change before initialising the field
|
// Set on_change before initialising the field
|
||||||
field_frequency.on_change = [this](rf::Frequency f) {
|
field_frequency.on_change = [this](rf::Frequency f) {
|
||||||
|
@ -69,9 +66,8 @@ AnalogTvView::AnalogTvView(
|
||||||
field_vga.set_value(app_settings.vga);
|
field_vga.set_value(app_settings.vga);
|
||||||
receiver_model.set_rf_amp(app_settings.rx_amp);
|
receiver_model.set_rf_amp(app_settings.rx_amp);
|
||||||
field_frequency.set_value(app_settings.rx_frequency);
|
field_frequency.set_value(app_settings.rx_frequency);
|
||||||
}
|
} else
|
||||||
else field_frequency.set_value(receiver_model.tuning_frequency());
|
field_frequency.set_value(receiver_model.tuning_frequency());
|
||||||
|
|
||||||
|
|
||||||
field_frequency.set_step(receiver_model.frequency_step());
|
field_frequency.set_step(receiver_model.frequency_step());
|
||||||
field_frequency.on_edit = [this, &nav]() {
|
field_frequency.on_edit = [this, &nav]() {
|
||||||
|
@ -118,7 +114,6 @@ AnalogTvView::AnalogTvView(
|
||||||
}
|
}
|
||||||
|
|
||||||
AnalogTvView::~AnalogTvView() {
|
AnalogTvView::~AnalogTvView() {
|
||||||
|
|
||||||
// save app settings
|
// save app settings
|
||||||
app_settings.rx_frequency = field_frequency.value();
|
app_settings.rx_frequency = field_frequency.value();
|
||||||
settings.save("rx_tv", &app_settings);
|
settings.save("rx_tv", &app_settings);
|
||||||
|
|
|
@ -84,12 +84,10 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
LNAGainField field_lna{
|
LNAGainField field_lna{
|
||||||
{ 15 * 8, 0 * 16 }
|
{15 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
VGAGainField field_vga{
|
VGAGainField field_vga{
|
||||||
{ 18 * 8, 0 * 16 }
|
{18 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField options_modulation{
|
OptionsField options_modulation{
|
||||||
{0 * 8, 0 * 16},
|
{0 * 8, 0 * 16},
|
||||||
|
@ -98,8 +96,7 @@ private:
|
||||||
{"TV ", toUType(ReceiverModel::Mode::WidebandFMAudio)},
|
{"TV ", toUType(ReceiverModel::Mode::WidebandFMAudio)},
|
||||||
{"TV ", toUType(ReceiverModel::Mode::WidebandFMAudio)},
|
{"TV ", toUType(ReceiverModel::Mode::WidebandFMAudio)},
|
||||||
{"TV ", toUType(ReceiverModel::Mode::WidebandFMAudio)},
|
{"TV ", toUType(ReceiverModel::Mode::WidebandFMAudio)},
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_volume{
|
NumberField field_volume{
|
||||||
{27 * 8, 0 * 16},
|
{27 * 8, 0 * 16},
|
||||||
|
@ -128,8 +125,6 @@ private:
|
||||||
void set_options_widget(std::unique_ptr<Widget> new_widget);
|
void set_options_widget(std::unique_ptr<Widget> new_widget);
|
||||||
|
|
||||||
void update_modulation(const ReceiverModel::Mode modulation);
|
void update_modulation(const ReceiverModel::Mode modulation);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -119,7 +119,6 @@ CaptureAppView::CaptureAppView(NavigationView& nav) {
|
||||||
}
|
}
|
||||||
receiver_model.set_baseband_bandwidth(anti_alias_baseband_bandwidth_filter);
|
receiver_model.set_baseband_bandwidth(anti_alias_baseband_bandwidth_filter);
|
||||||
|
|
||||||
|
|
||||||
waterfall.on_show();
|
waterfall.on_show();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -134,7 +133,6 @@ CaptureAppView::CaptureAppView(NavigationView& nav) {
|
||||||
}
|
}
|
||||||
|
|
||||||
CaptureAppView::~CaptureAppView() {
|
CaptureAppView::~CaptureAppView() {
|
||||||
|
|
||||||
// Hack for preventing halting other apps
|
// Hack for preventing halting other apps
|
||||||
// TODO: This should be also part of something global
|
// TODO: This should be also part of something global
|
||||||
receiver_model.set_sampling_rate(3072000);
|
receiver_model.set_sampling_rate(3072000);
|
||||||
|
|
|
@ -90,29 +90,26 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
RFAmpField field_rf_amp{
|
RFAmpField field_rf_amp{
|
||||||
{ 16 * 8, 0 * 16 }
|
{16 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
LNAGainField field_lna{
|
LNAGainField field_lna{
|
||||||
{ 18 * 8, 0 * 16 }
|
{18 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
VGAGainField field_vga{
|
VGAGainField field_vga{
|
||||||
{ 21 * 8, 0 * 16 }
|
{21 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField option_bandwidth{
|
OptionsField option_bandwidth{
|
||||||
{5 * 8, 1 * 16},
|
{5 * 8, 1 * 16},
|
||||||
5,
|
5,
|
||||||
{
|
{BW_OPTIONS}};
|
||||||
BW_OPTIONS
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
RecordView record_view{
|
RecordView record_view{
|
||||||
{0 * 8, 2 * 16, 30 * 8, 1 * 16},
|
{0 * 8, 2 * 16, 30 * 8, 1 * 16},
|
||||||
u"BBD_????.*", u"CAPTURES", RecordView::FileType::RawS16, 16384, 3
|
u"BBD_????.*",
|
||||||
};
|
u"CAPTURES",
|
||||||
|
RecordView::FileType::RawS16,
|
||||||
|
16384,
|
||||||
|
3};
|
||||||
|
|
||||||
spectrum::WaterfallWidget waterfall{};
|
spectrum::WaterfallWidget waterfall{};
|
||||||
};
|
};
|
||||||
|
|
|
@ -59,7 +59,6 @@
|
||||||
#define MODES_DUMP1090_VARIANT "dump1090-unknown"
|
#define MODES_DUMP1090_VARIANT "dump1090-unknown"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define MODES_DEFAULT_FREQ 1090000000
|
#define MODES_DEFAULT_FREQ 1090000000
|
||||||
#define MODES_DEFAULT_WIDTH 1000
|
#define MODES_DEFAULT_WIDTH 1000
|
||||||
#define MODES_DEFAULT_HEIGHT 700
|
#define MODES_DEFAULT_HEIGHT 700
|
||||||
|
@ -158,11 +157,16 @@ typedef enum {
|
||||||
} airground_t;
|
} airground_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SIL_INVALID, SIL_UNKNOWN, SIL_PER_SAMPLE, SIL_PER_HOUR
|
SIL_INVALID,
|
||||||
|
SIL_UNKNOWN,
|
||||||
|
SIL_PER_SAMPLE,
|
||||||
|
SIL_PER_HOUR
|
||||||
} sil_type_t;
|
} sil_type_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CPR_SURFACE, CPR_AIRBORNE, CPR_COARSE
|
CPR_SURFACE,
|
||||||
|
CPR_AIRBORNE,
|
||||||
|
CPR_COARSE
|
||||||
} cpr_type_t;
|
} cpr_type_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -209,7 +213,11 @@ typedef enum {
|
||||||
} emergency_t;
|
} emergency_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NAV_ALT_INVALID, NAV_ALT_UNKNOWN, NAV_ALT_AIRCRAFT, NAV_ALT_MCP, NAV_ALT_FMS
|
NAV_ALT_INVALID,
|
||||||
|
NAV_ALT_UNKNOWN,
|
||||||
|
NAV_ALT_AIRCRAFT,
|
||||||
|
NAV_ALT_MCP,
|
||||||
|
NAV_ALT_FMS
|
||||||
} nav_altitude_source_t;
|
} nav_altitude_source_t;
|
||||||
|
|
||||||
#define MODES_NON_ICAO_ADDRESS (1 << 24) // Set on addresses to indicate they are not ICAO addresses
|
#define MODES_NON_ICAO_ADDRESS (1 << 24) // Set on addresses to indicate they are not ICAO addresses
|
||||||
|
@ -233,14 +241,17 @@ typedef enum {
|
||||||
|
|
||||||
#define FAUP_DEFAULT_RATE_MULTIPLIER 1.0 // FA Upload rate multiplier
|
#define FAUP_DEFAULT_RATE_MULTIPLIER 1.0 // FA Upload rate multiplier
|
||||||
|
|
||||||
|
|
||||||
//======================== structure declarations =========================
|
//======================== structure declarations =========================
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SDR_NONE, SDR_IFILE, SDR_RTLSDR, SDR_BLADERF, SDR_HACKRF, SDR_LIMESDR
|
SDR_NONE,
|
||||||
|
SDR_IFILE,
|
||||||
|
SDR_RTLSDR,
|
||||||
|
SDR_BLADERF,
|
||||||
|
SDR_HACKRF,
|
||||||
|
SDR_LIMESDR
|
||||||
} sdr_type_t;
|
} sdr_type_t;
|
||||||
|
|
||||||
|
|
||||||
// The struct we use to store information about a decoded message.
|
// The struct we use to store information about a decoded message.
|
||||||
struct modesMessage {
|
struct modesMessage {
|
||||||
// Generic fields
|
// Generic fields
|
||||||
|
@ -440,5 +451,4 @@ struct modesMessage {
|
||||||
} nav;
|
} nav;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // __DUMP1090_H
|
#endif // __DUMP1090_H
|
||||||
|
|
|
@ -38,10 +38,14 @@ namespace format {
|
||||||
std::string type(Packet::Type value) {
|
std::string type(Packet::Type value) {
|
||||||
switch (value) {
|
switch (value) {
|
||||||
default:
|
default:
|
||||||
case Packet::Type::Unknown: return "???";
|
case Packet::Type::Unknown:
|
||||||
case Packet::Type::IDM: return "IDM";
|
return "???";
|
||||||
case Packet::Type::SCM: return "SCM";
|
case Packet::Type::IDM:
|
||||||
case Packet::Type::SCMPLUS: return "SCM+";
|
return "IDM";
|
||||||
|
case Packet::Type::SCM:
|
||||||
|
return "SCM";
|
||||||
|
case Packet::Type::SCMPLUS:
|
||||||
|
return "SCM+";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,8 +86,7 @@ void RecentEntriesTable<ERTRecentEntries>::draw(
|
||||||
const Entry& entry,
|
const Entry& entry,
|
||||||
const Rect& target_rect,
|
const Rect& target_rect,
|
||||||
Painter& painter,
|
Painter& painter,
|
||||||
const Style& style
|
const Style& style) {
|
||||||
) {
|
|
||||||
std::string line = ert::format::id(entry.id) + " " + ert::format::commodity_type(entry.commodity_type) + " " + ert::format::consumption(entry.last_consumption);
|
std::string line = ert::format::id(entry.id) + " " + ert::format::commodity_type(entry.commodity_type) + " " + ert::format::consumption(entry.last_consumption);
|
||||||
|
|
||||||
if (entry.received_count > 999) {
|
if (entry.received_count > 999) {
|
||||||
|
@ -137,7 +140,6 @@ ERTAppView::ERTAppView(NavigationView&) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ERTAppView::~ERTAppView() {
|
ERTAppView::~ERTAppView() {
|
||||||
|
|
||||||
// save app settings
|
// save app settings
|
||||||
settings.save("rx_ert", &app_settings);
|
settings.save("rx_ert", &app_settings);
|
||||||
|
|
||||||
|
|
|
@ -44,10 +44,9 @@ struct ERTKey {
|
||||||
|
|
||||||
constexpr ERTKey(
|
constexpr ERTKey(
|
||||||
ert::ID id = ert::invalid_id,
|
ert::ID id = ert::invalid_id,
|
||||||
ert::CommodityType commodity_type = ert::invalid_commodity_type
|
ert::CommodityType commodity_type = ert::invalid_commodity_type)
|
||||||
) : id { id },
|
: id{id},
|
||||||
commodity_type { commodity_type }
|
commodity_type{commodity_type} {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ERTKey(const ERTKey& other) = default;
|
ERTKey(const ERTKey& other) = default;
|
||||||
|
@ -77,10 +76,9 @@ struct ERTRecentEntry {
|
||||||
ert::Consumption last_consumption{};
|
ert::Consumption last_consumption{};
|
||||||
|
|
||||||
ERTRecentEntry(
|
ERTRecentEntry(
|
||||||
const Key& key
|
const Key& key)
|
||||||
) : id { key.id },
|
: id{key.id},
|
||||||
commodity_type { key.commodity_type }
|
commodity_type{key.commodity_type} {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Key key() const {
|
Key key() const {
|
||||||
|
@ -135,7 +133,6 @@ private:
|
||||||
std::app_settings settings{};
|
std::app_settings settings{};
|
||||||
std::app_settings::AppSettings app_settings{};
|
std::app_settings::AppSettings app_settings{};
|
||||||
|
|
||||||
|
|
||||||
const RecentEntriesColumns columns{{
|
const RecentEntriesColumns columns{{
|
||||||
{"ID", 10},
|
{"ID", 10},
|
||||||
{"Tp", 2},
|
{"Tp", 2},
|
||||||
|
@ -147,16 +144,13 @@ private:
|
||||||
static constexpr auto header_height = 1 * 16;
|
static constexpr auto header_height = 1 * 16;
|
||||||
|
|
||||||
RFAmpField field_rf_amp{
|
RFAmpField field_rf_amp{
|
||||||
{ 13 * 8, 0 * 16 }
|
{13 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
LNAGainField field_lna{
|
LNAGainField field_lna{
|
||||||
{ 15 * 8, 0 * 16 }
|
{15 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
VGAGainField field_vga{
|
VGAGainField field_vga{
|
||||||
{ 18 * 8, 0 * 16 }
|
{18 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
RSSI rssi{
|
RSSI rssi{
|
||||||
{21 * 8, 0, 6 * 8, 4},
|
{21 * 8, 0, 6 * 8, 4},
|
||||||
|
@ -168,8 +162,7 @@ private:
|
||||||
const auto message = static_cast<const ERTPacketMessage*>(p);
|
const auto message = static_cast<const ERTPacketMessage*>(p);
|
||||||
const ert::Packet packet{message->type, message->packet};
|
const ert::Packet packet{message->type, message->packet};
|
||||||
this->on_packet(packet);
|
this->on_packet(packet);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
void on_packet(const ert::Packet& packet);
|
void on_packet(const ert::Packet& packet);
|
||||||
void on_show_list();
|
void on_show_list();
|
||||||
|
|
|
@ -138,21 +138,18 @@ void GpsSimAppView::start() {
|
||||||
[](uint32_t return_code) {
|
[](uint32_t return_code) {
|
||||||
ReplayThreadDoneMessage message{return_code};
|
ReplayThreadDoneMessage message{return_code};
|
||||||
EventDispatcher::send_message(message);
|
EventDispatcher::send_message(message);
|
||||||
}
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rf_amp = (transmitter_model.rf_amp()); // recover rf_amp settings applied from ui_transmiter.cpp
|
rf_amp = (transmitter_model.rf_amp()); // recover rf_amp settings applied from ui_transmiter.cpp
|
||||||
|
|
||||||
radio::enable({
|
radio::enable({receiver_model.tuning_frequency(),
|
||||||
receiver_model.tuning_frequency(),
|
|
||||||
sample_rate,
|
sample_rate,
|
||||||
baseband_bandwidth,
|
baseband_bandwidth,
|
||||||
rf::Direction::Transmit,
|
rf::Direction::Transmit,
|
||||||
rf_amp, // previous code line : "receiver_model.rf_amp()," was passing the same rf_amp of all Receiver Apps
|
rf_amp, // previous code line : "receiver_model.rf_amp()," was passing the same rf_amp of all Receiver Apps
|
||||||
static_cast<int8_t>(receiver_model.lna()),
|
static_cast<int8_t>(receiver_model.lna()),
|
||||||
static_cast<int8_t>(receiver_model.vga())
|
static_cast<int8_t>(receiver_model.vga())});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GpsSimAppView::stop(const bool do_loop) {
|
void GpsSimAppView::stop(const bool do_loop) {
|
||||||
|
@ -181,9 +178,8 @@ void GpsSimAppView::handle_replay_thread_done(const uint32_t return_code) {
|
||||||
}
|
}
|
||||||
|
|
||||||
GpsSimAppView::GpsSimAppView(
|
GpsSimAppView::GpsSimAppView(
|
||||||
NavigationView& nav
|
NavigationView& nav)
|
||||||
) : nav_ (nav)
|
: nav_(nav) {
|
||||||
{
|
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_gps);
|
baseband::run_image(portapack::spi_flash::image_tag_gps);
|
||||||
|
|
||||||
add_children({
|
add_children({
|
||||||
|
@ -254,7 +250,8 @@ void GpsSimAppView::on_target_frequency_changed(rf::Frequency f) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GpsSimAppView::set_target_frequency(const rf::Frequency new_value) {
|
void GpsSimAppView::set_target_frequency(const rf::Frequency new_value) {
|
||||||
persistent_memory::set_tuned_frequency(new_value);;
|
persistent_memory::set_tuned_frequency(new_value);
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
rf::Frequency GpsSimAppView::target_frequency() const {
|
rf::Frequency GpsSimAppView::target_frequency() const {
|
||||||
|
|
|
@ -83,31 +83,27 @@ private:
|
||||||
|
|
||||||
Button button_open{
|
Button button_open{
|
||||||
{0 * 8, 0 * 16, 10 * 8, 2 * 16},
|
{0 * 8, 0 * 16, 10 * 8, 2 * 16},
|
||||||
"Open file"
|
"Open file"};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_filename{
|
Text text_filename{
|
||||||
{11 * 8, 0 * 16, 12 * 8, 16},
|
{11 * 8, 0 * 16, 12 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
Text text_sample_rate{
|
Text text_sample_rate{
|
||||||
{24 * 8, 0 * 16, 6 * 8, 16},
|
{24 * 8, 0 * 16, 6 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_duration{
|
Text text_duration{
|
||||||
{11 * 8, 1 * 16, 6 * 8, 16},
|
{11 * 8, 1 * 16, 6 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
ProgressBar progressbar{
|
ProgressBar progressbar{
|
||||||
{ 18 * 8, 1 * 16, 12 * 8, 16 }
|
{18 * 8, 1 * 16, 12 * 8, 16}};
|
||||||
};
|
|
||||||
|
|
||||||
FrequencyField field_frequency{
|
FrequencyField field_frequency{
|
||||||
{0 * 8, 2 * 16},
|
{0 * 8, 2 * 16},
|
||||||
};
|
};
|
||||||
|
|
||||||
TransmitterView2 tx_view { // new handling of NumberField field_rfgain, NumberField field_rfamp
|
TransmitterView2 tx_view{
|
||||||
|
// new handling of NumberField field_rfgain, NumberField field_rfamp
|
||||||
74, 1 * 8, SHORT_UI // x(columns), y (line) position. (Used in Replay / GPS Simul / Playlist App)
|
74, 1 * 8, SHORT_UI // x(columns), y (line) position. (Used in Replay / GPS Simul / Playlist App)
|
||||||
// 10*8, 2*8, NORMAL_UI // x(columns), y (line) position. (Used in Mic App)
|
// 10*8, 2*8, NORMAL_UI // x(columns), y (line) position. (Used in Mic App)
|
||||||
};
|
};
|
||||||
|
@ -116,14 +112,12 @@ private:
|
||||||
{21 * 8, 2 * 16},
|
{21 * 8, 2 * 16},
|
||||||
4,
|
4,
|
||||||
"Loop",
|
"Loop",
|
||||||
true
|
true};
|
||||||
};
|
|
||||||
ImageButton button_play{
|
ImageButton button_play{
|
||||||
{28 * 8, 2 * 16, 2 * 8, 1 * 16},
|
{28 * 8, 2 * 16, 2 * 8, 1 * 16},
|
||||||
&bitmap_play,
|
&bitmap_play,
|
||||||
Color::green(),
|
Color::green(),
|
||||||
Color::black()
|
Color::black()};
|
||||||
};
|
|
||||||
|
|
||||||
spectrum::WaterfallWidget waterfall{};
|
spectrum::WaterfallWidget waterfall{};
|
||||||
|
|
||||||
|
@ -132,8 +126,7 @@ private:
|
||||||
[this](const Message* const p) {
|
[this](const Message* const p) {
|
||||||
const auto message = *reinterpret_cast<const ReplayThreadDoneMessage*>(p);
|
const auto message = *reinterpret_cast<const ReplayThreadDoneMessage*>(p);
|
||||||
this->handle_replay_thread_done(message.return_code);
|
this->handle_replay_thread_done(message.return_code);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_fifo_signal{
|
MessageHandlerRegistration message_handler_fifo_signal{
|
||||||
Message::ID::RequestSignal,
|
Message::ID::RequestSignal,
|
||||||
|
@ -142,16 +135,14 @@ private:
|
||||||
if (message->signal == RequestSignalMessage::Signal::FillRequest) {
|
if (message->signal == RequestSignalMessage::Signal::FillRequest) {
|
||||||
this->set_ready();
|
this->set_ready();
|
||||||
}
|
}
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_tx_progress{
|
MessageHandlerRegistration message_handler_tx_progress{
|
||||||
Message::ID::TXProgress,
|
Message::ID::TXProgress,
|
||||||
[this](const Message* const p) {
|
[this](const Message* const p) {
|
||||||
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
|
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
|
||||||
this->on_tx_progress(message.progress);
|
this->on_tx_progress(message.progress);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -92,8 +92,7 @@ void LGEView::generate_frame_nickname() {
|
||||||
0x1F, 0x22, 0x01, 0x07,
|
0x1F, 0x22, 0x01, 0x07,
|
||||||
0x00, 0x00, 0x01, 0x07,
|
0x00, 0x00, 0x01, 0x07,
|
||||||
0x00, 0x00, 0x63, 0x05,
|
0x00, 0x00, 0x63, 0x05,
|
||||||
0x00, 0x00
|
0x00, 0x00};
|
||||||
};
|
|
||||||
uint32_t c;
|
uint32_t c;
|
||||||
|
|
||||||
// data_header[2] = field_room.value(); // ?
|
// data_header[2] = field_room.value(); // ?
|
||||||
|
@ -180,7 +179,9 @@ void LGEView::generate_frame_broadcast_nickname() {
|
||||||
|
|
||||||
data.push_back(field_team.value());
|
data.push_back(field_team.value());
|
||||||
|
|
||||||
console.write("\n\x1B\x09" "Broadcast nickname:\x1B\x10");
|
console.write(
|
||||||
|
"\n\x1B\x09"
|
||||||
|
"Broadcast nickname:\x1B\x10");
|
||||||
|
|
||||||
generate_lge_frame(0x04, data);
|
generate_lge_frame(0x04, data);
|
||||||
}
|
}
|
||||||
|
@ -227,15 +228,16 @@ void LGEView::generate_frame_collier() {
|
||||||
(uint8_t)field_room.value(),
|
(uint8_t)field_room.value(),
|
||||||
(uint8_t)field_player.value(),
|
(uint8_t)field_player.value(),
|
||||||
(uint8_t)field_power.value(),
|
(uint8_t)field_power.value(),
|
||||||
(uint8_t)(field_duration.value() * 10)
|
(uint8_t)(field_duration.value() * 10)};
|
||||||
};
|
|
||||||
|
|
||||||
for (auto& v : data)
|
for (auto& v : data)
|
||||||
checksum += v;
|
checksum += v;
|
||||||
|
|
||||||
data.push_back(checksum - id);
|
data.push_back(checksum - id);
|
||||||
|
|
||||||
console.write("\n\x1B\x06" "Config:\x1B\x10");
|
console.write(
|
||||||
|
"\n\x1B\x06"
|
||||||
|
"Config:\x1B\x10");
|
||||||
generate_lge_frame(0x00, 0x3713, 0x3713, data);
|
generate_lge_frame(0x00, 0x3713, 0x3713, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,8 +291,7 @@ void LGEView::on_tx_progress(const uint32_t progress, const bool done) {
|
||||||
LGEView::LGEView(NavigationView& nav) {
|
LGEView::LGEView(NavigationView& nav) {
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_fsktx);
|
baseband::run_image(portapack::spi_flash::image_tag_fsktx);
|
||||||
|
|
||||||
add_children({
|
add_children({&labels,
|
||||||
&labels,
|
|
||||||
&options_frame,
|
&options_frame,
|
||||||
&field_room,
|
&field_room,
|
||||||
&button_text,
|
&button_text,
|
||||||
|
@ -303,8 +304,7 @@ LGEView::LGEView(NavigationView& nav) {
|
||||||
&checkbox_rxtick,
|
&checkbox_rxtick,
|
||||||
&checkbox_channels,
|
&checkbox_channels,
|
||||||
&console,
|
&console,
|
||||||
&tx_view
|
&tx_view});
|
||||||
});
|
|
||||||
|
|
||||||
// load app settings
|
// load app settings
|
||||||
auto rc = settings.load("tx_lge", &app_settings);
|
auto rc = settings.load("tx_lge", &app_settings);
|
||||||
|
|
|
@ -92,110 +92,93 @@ private:
|
||||||
{{0 * 8, 10 * 8}, "Vest:", Color::light_grey()},
|
{{0 * 8, 10 * 8}, "Vest:", Color::light_grey()},
|
||||||
{{4 * 8, 12 * 8}, "ID:", Color::light_grey()},
|
{{4 * 8, 12 * 8}, "ID:", Color::light_grey()},
|
||||||
{{3 * 8, 14 * 8}, "Pow: /10", Color::light_grey()},
|
{{3 * 8, 14 * 8}, "Pow: /10", Color::light_grey()},
|
||||||
{ { 2 * 8, 16 * 8 }, "Time: x100ms", Color::light_grey() }
|
{{2 * 8, 16 * 8}, "Time: x100ms", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField options_frame{
|
OptionsField options_frame{
|
||||||
{7 * 8, 1 * 8},
|
{7 * 8, 1 * 8},
|
||||||
13,
|
13,
|
||||||
{
|
{{"Key", 0},
|
||||||
{ "Key", 0 },
|
|
||||||
{"Set nickname", 1},
|
{"Set nickname", 1},
|
||||||
{"Set team", 2},
|
{"Set team", 2},
|
||||||
{"Brdcst nick", 3},
|
{"Brdcst nick", 3},
|
||||||
{"Start", 4},
|
{"Start", 4},
|
||||||
{"Game over", 5},
|
{"Game over", 5},
|
||||||
{ "Set vest", 6 }
|
{"Set vest", 6}}};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Checkbox checkbox_channels{
|
Checkbox checkbox_channels{
|
||||||
{20 * 8, 1 * 8},
|
{20 * 8, 1 * 8},
|
||||||
7,
|
7,
|
||||||
"All ch.",
|
"All ch.",
|
||||||
true
|
true};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_room{
|
NumberField field_room{
|
||||||
{7 * 8, 3 * 8},
|
{7 * 8, 3 * 8},
|
||||||
1,
|
1,
|
||||||
{1, 2},
|
{1, 2},
|
||||||
1,
|
1,
|
||||||
'0'
|
'0'};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_text{
|
Button button_text{
|
||||||
{14 * 8, 5 * 8, 16 * 8, 3 * 8},
|
{14 * 8, 5 * 8, 16 * 8, 3 * 8},
|
||||||
"ABCDEF"
|
"ABCDEF"};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_team{
|
NumberField field_team{
|
||||||
{7 * 8, 5 * 8},
|
{7 * 8, 5 * 8},
|
||||||
1,
|
1,
|
||||||
{1, 6},
|
{1, 6},
|
||||||
1,
|
1,
|
||||||
'0'
|
'0'};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_player{
|
NumberField field_player{
|
||||||
{7 * 8, 7 * 8},
|
{7 * 8, 7 * 8},
|
||||||
2,
|
2,
|
||||||
{1, 50},
|
{1, 50},
|
||||||
1,
|
1,
|
||||||
'0'
|
'0'};
|
||||||
};
|
|
||||||
|
|
||||||
Checkbox checkbox_heartbeat{
|
Checkbox checkbox_heartbeat{
|
||||||
{17 * 8, 12 * 8},
|
{17 * 8, 12 * 8},
|
||||||
9,
|
9,
|
||||||
"Heartbeat",
|
"Heartbeat",
|
||||||
true
|
true};
|
||||||
};
|
|
||||||
Checkbox checkbox_rxtick{
|
Checkbox checkbox_rxtick{
|
||||||
{17 * 8, 15 * 8},
|
{17 * 8, 15 * 8},
|
||||||
7,
|
7,
|
||||||
"RX tick",
|
"RX tick",
|
||||||
true
|
true};
|
||||||
};
|
|
||||||
NumberField field_id{
|
NumberField field_id{
|
||||||
{7 * 8, 12 * 8},
|
{7 * 8, 12 * 8},
|
||||||
1,
|
1,
|
||||||
{1, 2},
|
{1, 2},
|
||||||
1,
|
1,
|
||||||
'0'
|
'0'};
|
||||||
};
|
|
||||||
NumberField field_power{
|
NumberField field_power{
|
||||||
{7 * 8, 14 * 8},
|
{7 * 8, 14 * 8},
|
||||||
2,
|
2,
|
||||||
{1, 10},
|
{1, 10},
|
||||||
1,
|
1,
|
||||||
'0'
|
'0'};
|
||||||
};
|
|
||||||
NumberField field_duration{
|
NumberField field_duration{
|
||||||
{7 * 8, 16 * 8},
|
{7 * 8, 16 * 8},
|
||||||
2,
|
2,
|
||||||
{1, 25},
|
{1, 25},
|
||||||
1,
|
1,
|
||||||
'0'
|
'0'};
|
||||||
};
|
|
||||||
|
|
||||||
Console console{
|
Console console{
|
||||||
{ 0, 18 * 8, 30 * 8, 7 * 16 }
|
{0, 18 * 8, 30 * 8, 7 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
TransmitterView tx_view{
|
TransmitterView tx_view{
|
||||||
16 * 16,
|
16 * 16,
|
||||||
10000,
|
10000,
|
||||||
12
|
12};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_tx_progress{
|
MessageHandlerRegistration message_handler_tx_progress{
|
||||||
Message::ID::TXProgress,
|
Message::ID::TXProgress,
|
||||||
[this](const Message* const p) {
|
[this](const Message* const p) {
|
||||||
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
|
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
|
||||||
this->on_tx_progress(message.progress, message.done);
|
this->on_tx_progress(message.progress, message.done);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -46,7 +46,6 @@ void POCSAGLogger::log_raw_data(const pocsag::POCSAGPacket& packet, const uint32
|
||||||
void POCSAGLogger::log_decoded(
|
void POCSAGLogger::log_decoded(
|
||||||
const pocsag::POCSAGPacket& packet,
|
const pocsag::POCSAGPacket& packet,
|
||||||
const std::string text) {
|
const std::string text) {
|
||||||
|
|
||||||
log_file.write_entry(packet.timestamp(), text);
|
log_file.write_entry(packet.timestamp(), text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,8 +61,7 @@ POCSAGAppView::POCSAGAppView(NavigationView& nav) {
|
||||||
|
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_pocsag);
|
baseband::run_image(portapack::spi_flash::image_tag_pocsag);
|
||||||
|
|
||||||
add_children({
|
add_children({&rssi,
|
||||||
&rssi,
|
|
||||||
&channel,
|
&channel,
|
||||||
&audio,
|
&audio,
|
||||||
&field_rf_amp,
|
&field_rf_amp,
|
||||||
|
@ -74,8 +72,7 @@ POCSAGAppView::POCSAGAppView(NavigationView& nav) {
|
||||||
&field_volume,
|
&field_volume,
|
||||||
&check_ignore,
|
&check_ignore,
|
||||||
&sym_ignore,
|
&sym_ignore,
|
||||||
&console
|
&console});
|
||||||
});
|
|
||||||
|
|
||||||
// Set on_change before initialising the field
|
// Set on_change before initialising the field
|
||||||
field_frequency.on_change = [this](rf::Frequency f) {
|
field_frequency.on_change = [this](rf::Frequency f) {
|
||||||
|
@ -89,8 +86,8 @@ POCSAGAppView::POCSAGAppView(NavigationView& nav) {
|
||||||
field_vga.set_value(app_settings.vga);
|
field_vga.set_value(app_settings.vga);
|
||||||
field_rf_amp.set_value(app_settings.rx_amp);
|
field_rf_amp.set_value(app_settings.rx_amp);
|
||||||
field_frequency.set_value(app_settings.rx_frequency);
|
field_frequency.set_value(app_settings.rx_frequency);
|
||||||
}
|
} else
|
||||||
else field_frequency.set_value(receiver_model.tuning_frequency());
|
field_frequency.set_value(receiver_model.tuning_frequency());
|
||||||
|
|
||||||
receiver_model.set_modulation(ReceiverModel::Mode::NarrowbandFMAudio);
|
receiver_model.set_modulation(ReceiverModel::Mode::NarrowbandFMAudio);
|
||||||
|
|
||||||
|
@ -140,7 +137,6 @@ POCSAGAppView::POCSAGAppView(NavigationView& nav) {
|
||||||
}
|
}
|
||||||
|
|
||||||
POCSAGAppView::~POCSAGAppView() {
|
POCSAGAppView::~POCSAGAppView() {
|
||||||
|
|
||||||
// save app settings
|
// save app settings
|
||||||
app_settings.rx_frequency = field_frequency.value();
|
app_settings.rx_frequency = field_frequency.value();
|
||||||
settings.save("rx_pocsag", &app_settings);
|
settings.save("rx_pocsag", &app_settings);
|
||||||
|
@ -163,7 +159,6 @@ void POCSAGAppView::on_headphone_volume_changed(int32_t v) {
|
||||||
receiver_model.set_headphone_volume(new_volume);
|
receiver_model.set_headphone_volume(new_volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Useless ?
|
// Useless ?
|
||||||
void POCSAGAppView::set_parent_rect(const Rect new_parent_rect) {
|
void POCSAGAppView::set_parent_rect(const Rect new_parent_rect) {
|
||||||
View::set_parent_rect(new_parent_rect);
|
View::set_parent_rect(new_parent_rect);
|
||||||
|
@ -188,7 +183,6 @@ void POCSAGAppView::on_packet(const POCSAGPacketMessage * message) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string console_info;
|
std::string console_info;
|
||||||
const uint32_t roundVal = 50;
|
const uint32_t roundVal = 50;
|
||||||
const uint32_t bitrate = roundVal * ((message->packet.bitrate() + (roundVal / 2)) / roundVal);
|
const uint32_t bitrate = roundVal * ((message->packet.bitrate() + (roundVal / 2)) / roundVal);
|
||||||
|
|
|
@ -70,14 +70,11 @@ private:
|
||||||
pocsag::POCSAGState pocsag_state{};
|
pocsag::POCSAGState pocsag_state{};
|
||||||
|
|
||||||
RFAmpField field_rf_amp{
|
RFAmpField field_rf_amp{
|
||||||
{ 13 * 8, 0 * 16 }
|
{13 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
LNAGainField field_lna{
|
LNAGainField field_lna{
|
||||||
{ 15 * 8, 0 * 16 }
|
{15 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
VGAGainField field_vga{
|
VGAGainField field_vga{
|
||||||
{ 18 * 8, 0 * 16 }
|
{18 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
RSSI rssi{
|
RSSI rssi{
|
||||||
{21 * 8, 0, 6 * 8, 4},
|
{21 * 8, 0, 6 * 8, 4},
|
||||||
};
|
};
|
||||||
|
@ -103,23 +100,19 @@ private:
|
||||||
{0 * 8, 21},
|
{0 * 8, 21},
|
||||||
8,
|
8,
|
||||||
"Ign addr",
|
"Ign addr",
|
||||||
false
|
false};
|
||||||
};
|
|
||||||
SymField sym_ignore{
|
SymField sym_ignore{
|
||||||
{13 * 8, 25},
|
{13 * 8, 25},
|
||||||
7,
|
7,
|
||||||
SymField::SYMFIELD_DEC
|
SymField::SYMFIELD_DEC};
|
||||||
};
|
|
||||||
Checkbox check_log{
|
Checkbox check_log{
|
||||||
{240 - 8 * 8, 21},
|
{240 - 8 * 8, 21},
|
||||||
3,
|
3,
|
||||||
"LOG",
|
"LOG",
|
||||||
false
|
false};
|
||||||
};
|
|
||||||
|
|
||||||
Console console{
|
Console console{
|
||||||
{ 0, 3 * 16, 240, 256 }
|
{0, 3 * 16, 240, 256}};
|
||||||
};
|
|
||||||
|
|
||||||
std::unique_ptr<POCSAGLogger> logger{};
|
std::unique_ptr<POCSAGLogger> logger{};
|
||||||
|
|
||||||
|
@ -139,8 +132,7 @@ private:
|
||||||
[this](Message* const p) {
|
[this](Message* const p) {
|
||||||
const auto message = static_cast<const POCSAGPacketMessage*>(p);
|
const auto message = static_cast<const POCSAGPacketMessage*>(p);
|
||||||
this->on_packet(message);
|
this->on_packet(message);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -138,8 +138,7 @@ void ReplayAppView::start() {
|
||||||
[](uint32_t return_code) {
|
[](uint32_t return_code) {
|
||||||
ReplayThreadDoneMessage message{return_code};
|
ReplayThreadDoneMessage message{return_code};
|
||||||
EventDispatcher::send_message(message);
|
EventDispatcher::send_message(message);
|
||||||
}
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable Bias Tee if selected
|
// Enable Bias Tee if selected
|
||||||
|
@ -147,21 +146,18 @@ void ReplayAppView::start() {
|
||||||
|
|
||||||
rf_amp = (transmitter_model.rf_amp()); // recover rf_amp settings applied from ui_transmiter.cpp
|
rf_amp = (transmitter_model.rf_amp()); // recover rf_amp settings applied from ui_transmiter.cpp
|
||||||
|
|
||||||
radio::enable({
|
radio::enable({receiver_model.tuning_frequency(),
|
||||||
receiver_model.tuning_frequency(),
|
|
||||||
sample_rate * 8,
|
sample_rate * 8,
|
||||||
baseband_bandwidth,
|
baseband_bandwidth,
|
||||||
rf::Direction::Transmit,
|
rf::Direction::Transmit,
|
||||||
rf_amp, // previous code line : "receiver_model.rf_amp()," was passing the same rf_amp of all Receiver Apps
|
rf_amp, // previous code line : "receiver_model.rf_amp()," was passing the same rf_amp of all Receiver Apps
|
||||||
static_cast<int8_t>(receiver_model.lna()),
|
static_cast<int8_t>(receiver_model.lna()),
|
||||||
static_cast<int8_t>(receiver_model.vga())
|
static_cast<int8_t>(receiver_model.vga())});
|
||||||
});
|
|
||||||
|
|
||||||
if (portapack::persistent_memory::stealth_mode()) {
|
if (portapack::persistent_memory::stealth_mode()) {
|
||||||
DisplaySleepMessage message;
|
DisplaySleepMessage message;
|
||||||
EventDispatcher::send_message(message);
|
EventDispatcher::send_message(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReplayAppView::stop(const bool do_loop) {
|
void ReplayAppView::stop(const bool do_loop) {
|
||||||
|
@ -191,9 +187,8 @@ void ReplayAppView::handle_replay_thread_done(const uint32_t return_code) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ReplayAppView::ReplayAppView(
|
ReplayAppView::ReplayAppView(
|
||||||
NavigationView& nav
|
NavigationView& nav)
|
||||||
) : nav_ (nav)
|
: nav_(nav) {
|
||||||
{
|
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_replay);
|
baseband::run_image(portapack::spi_flash::image_tag_replay);
|
||||||
|
|
||||||
add_children({
|
add_children({
|
||||||
|
@ -267,7 +262,8 @@ void ReplayAppView::on_target_frequency_changed(rf::Frequency f) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReplayAppView::set_target_frequency(const rf::Frequency new_value) {
|
void ReplayAppView::set_target_frequency(const rf::Frequency new_value) {
|
||||||
persistent_memory::set_tuned_frequency(new_value);;
|
persistent_memory::set_tuned_frequency(new_value);
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
rf::Frequency ReplayAppView::target_frequency() const {
|
rf::Frequency ReplayAppView::target_frequency() const {
|
||||||
|
|
|
@ -82,31 +82,27 @@ private:
|
||||||
|
|
||||||
Button button_open{
|
Button button_open{
|
||||||
{0 * 8, 0 * 16, 10 * 8, 2 * 16},
|
{0 * 8, 0 * 16, 10 * 8, 2 * 16},
|
||||||
"Open file"
|
"Open file"};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_filename{
|
Text text_filename{
|
||||||
{11 * 8, 0 * 16, 12 * 8, 16},
|
{11 * 8, 0 * 16, 12 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
Text text_sample_rate{
|
Text text_sample_rate{
|
||||||
{24 * 8, 0 * 16, 6 * 8, 16},
|
{24 * 8, 0 * 16, 6 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_duration{
|
Text text_duration{
|
||||||
{11 * 8, 1 * 16, 6 * 8, 16},
|
{11 * 8, 1 * 16, 6 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
ProgressBar progressbar{
|
ProgressBar progressbar{
|
||||||
{ 18 * 8, 1 * 16, 12 * 8, 16 }
|
{18 * 8, 1 * 16, 12 * 8, 16}};
|
||||||
};
|
|
||||||
|
|
||||||
FrequencyField field_frequency{
|
FrequencyField field_frequency{
|
||||||
{0 * 8, 2 * 16},
|
{0 * 8, 2 * 16},
|
||||||
};
|
};
|
||||||
|
|
||||||
TransmitterView2 tx_view { // new handling of NumberField field_rfgain, NumberField field_rfamp
|
TransmitterView2 tx_view{
|
||||||
|
// new handling of NumberField field_rfgain, NumberField field_rfamp
|
||||||
74, 1 * 8, SHORT_UI // x(columns), y (line) position. (Uused in Repay / GPS Simul / Playlist App)
|
74, 1 * 8, SHORT_UI // x(columns), y (line) position. (Uused in Repay / GPS Simul / Playlist App)
|
||||||
// 10*8, 2*8, NORMAL_UI // x(columns), y (line) position. (Used in Mic App)
|
// 10*8, 2*8, NORMAL_UI // x(columns), y (line) position. (Used in Mic App)
|
||||||
};
|
};
|
||||||
|
@ -115,14 +111,12 @@ private:
|
||||||
{21 * 8, 2 * 16},
|
{21 * 8, 2 * 16},
|
||||||
4,
|
4,
|
||||||
"Loop",
|
"Loop",
|
||||||
true
|
true};
|
||||||
};
|
|
||||||
ImageButton button_play{
|
ImageButton button_play{
|
||||||
{28 * 8, 2 * 16, 2 * 8, 1 * 16},
|
{28 * 8, 2 * 16, 2 * 8, 1 * 16},
|
||||||
&bitmap_play,
|
&bitmap_play,
|
||||||
Color::green(),
|
Color::green(),
|
||||||
Color::black()
|
Color::black()};
|
||||||
};
|
|
||||||
|
|
||||||
spectrum::WaterfallWidget waterfall{};
|
spectrum::WaterfallWidget waterfall{};
|
||||||
|
|
||||||
|
@ -131,8 +125,7 @@ private:
|
||||||
[this](const Message* const p) {
|
[this](const Message* const p) {
|
||||||
const auto message = *reinterpret_cast<const ReplayThreadDoneMessage*>(p);
|
const auto message = *reinterpret_cast<const ReplayThreadDoneMessage*>(p);
|
||||||
this->handle_replay_thread_done(message.return_code);
|
this->handle_replay_thread_done(message.return_code);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_fifo_signal{
|
MessageHandlerRegistration message_handler_fifo_signal{
|
||||||
Message::ID::RequestSignal,
|
Message::ID::RequestSignal,
|
||||||
|
@ -141,16 +134,14 @@ private:
|
||||||
if (message->signal == RequestSignalMessage::Signal::FillRequest) {
|
if (message->signal == RequestSignalMessage::Signal::FillRequest) {
|
||||||
this->set_ready();
|
this->set_ready();
|
||||||
}
|
}
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_tx_progress{
|
MessageHandlerRegistration message_handler_tx_progress{
|
||||||
Message::ID::TXProgress,
|
Message::ID::TXProgress,
|
||||||
[this](const Message* const p) {
|
[this](const Message* const p) {
|
||||||
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
|
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
|
||||||
this->on_tx_progress(message.progress);
|
this->on_tx_progress(message.progress);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -104,8 +104,7 @@ void SoundBoardView::start_tx(const uint32_t id) {
|
||||||
[](uint32_t return_code) {
|
[](uint32_t return_code) {
|
||||||
ReplayThreadDoneMessage message{return_code};
|
ReplayThreadDoneMessage message{return_code};
|
||||||
EventDispatcher::send_message(message);
|
EventDispatcher::send_message(message);
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
baseband::set_audiotx_config(
|
baseband::set_audiotx_config(
|
||||||
1536000 / 20, // Update vu-meter at 20Hz
|
1536000 / 20, // Update vu-meter at 20Hz
|
||||||
|
@ -155,14 +154,12 @@ void SoundBoardView::refresh_list() {
|
||||||
for (const auto& entry : std::filesystem::directory_iterator(u"WAV", u"*")) {
|
for (const auto& entry : std::filesystem::directory_iterator(u"WAV", u"*")) {
|
||||||
if (std::filesystem::is_regular_file(entry.status())) {
|
if (std::filesystem::is_regular_file(entry.status())) {
|
||||||
if (entry.path().string().length()) {
|
if (entry.path().string().length()) {
|
||||||
|
|
||||||
auto entry_extension = entry.path().extension().string();
|
auto entry_extension = entry.path().extension().string();
|
||||||
|
|
||||||
for (auto& c : entry_extension)
|
for (auto& c : entry_extension)
|
||||||
c = toupper(c);
|
c = toupper(c);
|
||||||
|
|
||||||
if (entry_extension == ".WAV") {
|
if (entry_extension == ".WAV") {
|
||||||
|
|
||||||
if (reader->open(u"/WAV/" + entry.path().native())) {
|
if (reader->open(u"/WAV/" + entry.path().native())) {
|
||||||
if ((reader->channels() == 1) && (reader->bits_per_sample() == 8)) {
|
if ((reader->channels() == 1) && (reader->bits_per_sample() == 8)) {
|
||||||
// sounds[c].ms_duration = reader->ms_duration();
|
// sounds[c].ms_duration = reader->ms_duration();
|
||||||
|
@ -202,14 +199,12 @@ void SoundBoardView::refresh_list() {
|
||||||
menu_view.clear();
|
menu_view.clear();
|
||||||
|
|
||||||
for (size_t n = 0; n < file_list.size(); n++) {
|
for (size_t n = 0; n < file_list.size(); n++) {
|
||||||
menu_view.add_item({
|
menu_view.add_item({file_list[n].string().substr(0, 30),
|
||||||
file_list[n].string().substr(0, 30),
|
|
||||||
ui::Color::white(),
|
ui::Color::white(),
|
||||||
nullptr,
|
nullptr,
|
||||||
[this](KeyEvent) {
|
[this](KeyEvent) {
|
||||||
on_select_entry();
|
on_select_entry();
|
||||||
}
|
}});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
page_info.set("Page: " + to_string_dec_uint(c_page) + " Sounds: " + to_string_dec_uint(file_list.size()));
|
page_info.set("Page: " + to_string_dec_uint(c_page) + " Sounds: " + to_string_dec_uint(file_list.size()));
|
||||||
|
@ -222,13 +217,11 @@ void SoundBoardView::refresh_list() {
|
||||||
}
|
}
|
||||||
|
|
||||||
SoundBoardView::SoundBoardView(
|
SoundBoardView::SoundBoardView(
|
||||||
NavigationView& nav
|
NavigationView& nav)
|
||||||
) : nav_ (nav)
|
: nav_(nav) {
|
||||||
{
|
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_audio_tx);
|
baseband::run_image(portapack::spi_flash::image_tag_audio_tx);
|
||||||
|
|
||||||
add_children({
|
add_children({&labels,
|
||||||
&labels,
|
|
||||||
&menu_view,
|
&menu_view,
|
||||||
&text_empty,
|
&text_empty,
|
||||||
&options_tone_key,
|
&options_tone_key,
|
||||||
|
@ -240,8 +233,7 @@ SoundBoardView::SoundBoardView(
|
||||||
&check_random,
|
&check_random,
|
||||||
&button_prev_page,
|
&button_prev_page,
|
||||||
&button_next_page,
|
&button_next_page,
|
||||||
&tx_view
|
&tx_view});
|
||||||
});
|
|
||||||
|
|
||||||
// load app settings
|
// load app settings
|
||||||
auto rc = settings.load("tx_soundboard", &app_settings);
|
auto rc = settings.load("tx_soundboard", &app_settings);
|
||||||
|
@ -301,4 +293,4 @@ SoundBoardView::~SoundBoardView() {
|
||||||
baseband::shutdown(); // better this function at the end, not load_sram() that sometimes produces hang up.
|
baseband::shutdown(); // better this function at the end, not load_sram() that sometimes produces hang up.
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace ui
|
||||||
|
|
|
@ -88,27 +88,22 @@ private:
|
||||||
|
|
||||||
Labels labels{
|
Labels labels{
|
||||||
//{ { 0, 20 * 8 + 4 }, "Title:", Color::light_grey() },
|
//{ { 0, 20 * 8 + 4 }, "Title:", Color::light_grey() },
|
||||||
{ { 0, 180 }, "Key:", Color::light_grey() }
|
{{0, 180}, "Key:", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_next_page{
|
Button button_next_page{
|
||||||
{30 * 7, 25 * 8, 10 * 3, 2 * 14},
|
{30 * 7, 25 * 8, 10 * 3, 2 * 14},
|
||||||
"=>"
|
"=>"};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_prev_page{
|
Button button_prev_page{
|
||||||
{17 * 10, 25 * 8, 10 * 3, 2 * 14},
|
{17 * 10, 25 * 8, 10 * 3, 2 * 14},
|
||||||
"<="
|
"<="};
|
||||||
};
|
|
||||||
|
|
||||||
Text page_info{
|
Text page_info{
|
||||||
{ 0, 30 * 8 - 4, 30 * 8, 16 }
|
{0, 30 * 8 - 4, 30 * 8, 16}};
|
||||||
};
|
|
||||||
|
|
||||||
MenuView menu_view{
|
MenuView menu_view{
|
||||||
{0, 0, 240, 175},
|
{0, 0, 240, 175},
|
||||||
true
|
true};
|
||||||
};
|
|
||||||
Text text_empty{
|
Text text_empty{
|
||||||
{7 * 8, 12 * 8, 16 * 8, 16},
|
{7 * 8, 12 * 8, 16 * 8, 16},
|
||||||
"Empty directory !",
|
"Empty directory !",
|
||||||
|
@ -125,20 +120,17 @@ private:
|
||||||
OptionsField options_tone_key{
|
OptionsField options_tone_key{
|
||||||
{32, 180},
|
{32, 180},
|
||||||
18,
|
18,
|
||||||
{ }
|
{}};
|
||||||
};
|
|
||||||
|
|
||||||
Checkbox check_loop{
|
Checkbox check_loop{
|
||||||
{0, 25 * 8 + 4},
|
{0, 25 * 8 + 4},
|
||||||
4,
|
4,
|
||||||
"Loop"
|
"Loop"};
|
||||||
};
|
|
||||||
|
|
||||||
Checkbox check_random{
|
Checkbox check_random{
|
||||||
{10 * 7, 25 * 8 + 4},
|
{10 * 7, 25 * 8 + 4},
|
||||||
6,
|
6,
|
||||||
"Random"
|
"Random"};
|
||||||
};
|
|
||||||
|
|
||||||
// ProgressBar progressbar {
|
// ProgressBar progressbar {
|
||||||
// { 0 * 8, 30 * 8 - 4, 30 * 8, 16 }
|
// { 0 * 8, 30 * 8 - 4, 30 * 8, 16 }
|
||||||
|
@ -147,16 +139,14 @@ private:
|
||||||
TransmitterView tx_view{
|
TransmitterView tx_view{
|
||||||
16 * 16,
|
16 * 16,
|
||||||
5000,
|
5000,
|
||||||
12
|
12};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_replay_thread_error{
|
MessageHandlerRegistration message_handler_replay_thread_error{
|
||||||
Message::ID::ReplayThreadDone,
|
Message::ID::ReplayThreadDone,
|
||||||
[this](const Message* const p) {
|
[this](const Message* const p) {
|
||||||
const auto message = *reinterpret_cast<const ReplayThreadDoneMessage*>(p);
|
const auto message = *reinterpret_cast<const ReplayThreadDoneMessage*>(p);
|
||||||
this->handle_replay_thread_done(message.return_code);
|
this->handle_replay_thread_done(message.return_code);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_fifo_signal{
|
MessageHandlerRegistration message_handler_fifo_signal{
|
||||||
Message::ID::RequestSignal,
|
Message::ID::RequestSignal,
|
||||||
|
@ -165,16 +155,14 @@ private:
|
||||||
if (message->signal == RequestSignalMessage::Signal::FillRequest) {
|
if (message->signal == RequestSignalMessage::Signal::FillRequest) {
|
||||||
this->set_ready();
|
this->set_ready();
|
||||||
}
|
}
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_tx_progress{
|
MessageHandlerRegistration message_handler_tx_progress{
|
||||||
Message::ID::TXProgress,
|
Message::ID::TXProgress,
|
||||||
[this](const Message* const p) {
|
[this](const Message* const p) {
|
||||||
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
|
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
|
||||||
this->on_tx_progress(message.progress);
|
this->on_tx_progress(message.progress);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -34,7 +34,6 @@ namespace ui {
|
||||||
|
|
||||||
class SpectrumAnalysisView : public spectrum::WaterfallWidget {
|
class SpectrumAnalysisView : public spectrum::WaterfallWidget {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SpectrumAnalysisModel model;
|
SpectrumAnalysisModel model;
|
||||||
};
|
};
|
||||||
|
|
|
@ -59,10 +59,14 @@ std::string flags(Flags flags) {
|
||||||
|
|
||||||
static std::string signal_type(SignalType signal_type) {
|
static std::string signal_type(SignalType signal_type) {
|
||||||
switch (signal_type) {
|
switch (signal_type) {
|
||||||
case SignalType::FSK_19k2_Schrader: return "FSK 38400 19200 Schrader";
|
case SignalType::FSK_19k2_Schrader:
|
||||||
case SignalType::OOK_8k192_Schrader: return "OOK - 8192 Schrader";
|
return "FSK 38400 19200 Schrader";
|
||||||
case SignalType::OOK_8k4_Schrader: return "OOK - 8400 Schrader";
|
case SignalType::OOK_8k192_Schrader:
|
||||||
default: return "- - - -";
|
return "OOK - 8192 Schrader";
|
||||||
|
case SignalType::OOK_8k4_Schrader:
|
||||||
|
return "OOK - 8400 Schrader";
|
||||||
|
default:
|
||||||
|
return "- - - -";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,20 +107,23 @@ void RecentEntriesTable<TPMSRecentEntries>::draw(
|
||||||
const Entry& entry,
|
const Entry& entry,
|
||||||
const Rect& target_rect,
|
const Rect& target_rect,
|
||||||
Painter& painter,
|
Painter& painter,
|
||||||
const Style& style
|
const Style& style) {
|
||||||
) {
|
|
||||||
std::string line = tpms::format::type(entry.type) + " " + tpms::format::id(entry.id);
|
std::string line = tpms::format::type(entry.type) + " " + tpms::format::id(entry.id);
|
||||||
|
|
||||||
if (entry.last_pressure.is_valid()) {
|
if (entry.last_pressure.is_valid()) {
|
||||||
line += " " + tpms::format::pressure(entry.last_pressure.value());
|
line += " " + tpms::format::pressure(entry.last_pressure.value());
|
||||||
} else {
|
} else {
|
||||||
line += " " " ";
|
line +=
|
||||||
|
" "
|
||||||
|
" ";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry.last_temperature.is_valid()) {
|
if (entry.last_temperature.is_valid()) {
|
||||||
line += " " + tpms::format::temperature(entry.last_temperature.value());
|
line += " " + tpms::format::temperature(entry.last_temperature.value());
|
||||||
} else {
|
} else {
|
||||||
line += " " " ";
|
line +=
|
||||||
|
" "
|
||||||
|
" ";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry.received_count > 999) {
|
if (entry.received_count > 999) {
|
||||||
|
@ -128,7 +135,9 @@ void RecentEntriesTable<TPMSRecentEntries>::draw(
|
||||||
if (entry.last_flags.is_valid()) {
|
if (entry.last_flags.is_valid()) {
|
||||||
line += " " + tpms::format::flags(entry.last_flags.value());
|
line += " " + tpms::format::flags(entry.last_flags.value());
|
||||||
} else {
|
} else {
|
||||||
line += " " " ";
|
line +=
|
||||||
|
" "
|
||||||
|
" ";
|
||||||
}
|
}
|
||||||
|
|
||||||
line.resize(target_rect.width() / 8, ' ');
|
line.resize(target_rect.width() / 8, ' ');
|
||||||
|
@ -138,8 +147,7 @@ void RecentEntriesTable<TPMSRecentEntries>::draw(
|
||||||
TPMSAppView::TPMSAppView(NavigationView&) {
|
TPMSAppView::TPMSAppView(NavigationView&) {
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_tpms);
|
baseband::run_image(portapack::spi_flash::image_tag_tpms);
|
||||||
|
|
||||||
add_children({
|
add_children({&rssi,
|
||||||
&rssi,
|
|
||||||
&channel,
|
&channel,
|
||||||
&options_band,
|
&options_band,
|
||||||
&options_pressure,
|
&options_pressure,
|
||||||
|
@ -147,8 +155,7 @@ TPMSAppView::TPMSAppView(NavigationView&) {
|
||||||
&field_rf_amp,
|
&field_rf_amp,
|
||||||
&field_lna,
|
&field_lna,
|
||||||
&field_vga,
|
&field_vga,
|
||||||
&recent_entries_view
|
&recent_entries_view});
|
||||||
});
|
|
||||||
|
|
||||||
// load app settings
|
// load app settings
|
||||||
auto rc = settings.load("rx_tpms", &app_settings);
|
auto rc = settings.load("rx_tpms", &app_settings);
|
||||||
|
@ -157,8 +164,8 @@ TPMSAppView::TPMSAppView(NavigationView&) {
|
||||||
field_vga.set_value(app_settings.vga);
|
field_vga.set_value(app_settings.vga);
|
||||||
field_rf_amp.set_value(app_settings.rx_amp);
|
field_rf_amp.set_value(app_settings.rx_amp);
|
||||||
options_band.set_by_value(app_settings.rx_frequency);
|
options_band.set_by_value(app_settings.rx_frequency);
|
||||||
}
|
} else
|
||||||
else options_band.set_by_value(receiver_model.tuning_frequency());
|
options_band.set_by_value(receiver_model.tuning_frequency());
|
||||||
|
|
||||||
receiver_model.set_tuning_frequency(tuning_frequency());
|
receiver_model.set_tuning_frequency(tuning_frequency());
|
||||||
receiver_model.set_sampling_rate(sampling_rate);
|
receiver_model.set_sampling_rate(sampling_rate);
|
||||||
|
@ -201,8 +208,6 @@ TPMSAppView::TPMSAppView(NavigationView&) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TPMSAppView::~TPMSAppView() {
|
TPMSAppView::~TPMSAppView() {
|
||||||
|
|
||||||
|
|
||||||
// save app settings
|
// save app settings
|
||||||
app_settings.rx_frequency = target_frequency_;
|
app_settings.rx_frequency = target_frequency_;
|
||||||
settings.save("rx_tpms", &app_settings);
|
settings.save("rx_tpms", &app_settings);
|
||||||
|
|
|
@ -59,10 +59,9 @@ struct TPMSRecentEntry {
|
||||||
Optional<tpms::Flags> last_flags{};
|
Optional<tpms::Flags> last_flags{};
|
||||||
|
|
||||||
TPMSRecentEntry(
|
TPMSRecentEntry(
|
||||||
const Key& key
|
const Key& key)
|
||||||
) : type { key.first },
|
: type{key.first},
|
||||||
id { key.second }
|
id{key.second} {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Key key() const {
|
Key key() const {
|
||||||
|
@ -120,8 +119,7 @@ private:
|
||||||
const auto message = static_cast<const TPMSPacketMessage*>(p);
|
const auto message = static_cast<const TPMSPacketMessage*>(p);
|
||||||
const tpms::Packet packet{message->packet, message->signal_type};
|
const tpms::Packet packet{message->packet, message->signal_type};
|
||||||
this->on_packet(packet);
|
this->on_packet(packet);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
static constexpr ui::Dim header_height = 1 * 16;
|
static constexpr ui::Dim header_height = 1 * 16;
|
||||||
|
|
||||||
|
@ -141,38 +139,28 @@ private:
|
||||||
{
|
{
|
||||||
{"315", 315000000},
|
{"315", 315000000},
|
||||||
{"433", 433920000},
|
{"433", 433920000},
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField options_pressure{
|
OptionsField options_pressure{
|
||||||
{5 * 8, 0 * 16},
|
{5 * 8, 0 * 16},
|
||||||
3,
|
3,
|
||||||
{
|
{{"kPa", 0},
|
||||||
{ "kPa", 0 },
|
{"PSI", 1}}};
|
||||||
{ "PSI", 1 }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField options_temperature{
|
OptionsField options_temperature{
|
||||||
{9 * 8, 0 * 16},
|
{9 * 8, 0 * 16},
|
||||||
1,
|
1,
|
||||||
{
|
{{"C", 0},
|
||||||
{ "C", 0 },
|
{"F", 1}}};
|
||||||
{ "F", 1 }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
RFAmpField field_rf_amp{
|
RFAmpField field_rf_amp{
|
||||||
{ 13 * 8, 0 * 16 }
|
{13 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
LNAGainField field_lna{
|
LNAGainField field_lna{
|
||||||
{ 15 * 8, 0 * 16 }
|
{15 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
VGAGainField field_vga{
|
VGAGainField field_vga{
|
||||||
{ 18 * 8, 0 * 16 }
|
{18 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
TPMSRecentEntries recent{};
|
TPMSRecentEntries recent{};
|
||||||
std::unique_ptr<TPMSLogger> logger{};
|
std::unique_ptr<TPMSLogger> logger{};
|
||||||
|
|
|
@ -40,9 +40,8 @@ namespace ui {
|
||||||
|
|
||||||
// This is pretty much WaterfallView but in the opposite direction
|
// This is pretty much WaterfallView but in the opposite direction
|
||||||
CreditsWidget::CreditsWidget(
|
CreditsWidget::CreditsWidget(
|
||||||
Rect parent_rect
|
Rect parent_rect)
|
||||||
) : Widget { parent_rect }
|
: Widget{parent_rect} {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreditsWidget::paint(Painter&) {
|
void CreditsWidget::paint(Painter&) {
|
||||||
|
@ -60,22 +59,19 @@ void CreditsWidget::on_hide() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreditsWidget::new_row(
|
void CreditsWidget::new_row(
|
||||||
const std::array<Color, 240>& pixel_row
|
const std::array<Color, 240>& pixel_row) {
|
||||||
) {
|
|
||||||
// Glitch be here (see comment in main.cpp)
|
// Glitch be here (see comment in main.cpp)
|
||||||
const auto draw_y = display.scroll(-1);
|
const auto draw_y = display.scroll(-1);
|
||||||
|
|
||||||
display.draw_pixels(
|
display.draw_pixels(
|
||||||
{{0, draw_y - 1}, {240, 1}},
|
{{0, draw_y - 1}, {240, 1}},
|
||||||
pixel_row
|
pixel_row);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreditsWidget::clear() {
|
void CreditsWidget::clear() {
|
||||||
display.fill_rectangle(
|
display.fill_rectangle(
|
||||||
screen_rect(),
|
screen_rect(),
|
||||||
Color::black()
|
Color::black());
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AboutView::update() {
|
void AboutView::update() {
|
||||||
|
@ -126,12 +122,9 @@ void AboutView::update() {
|
||||||
}
|
}
|
||||||
|
|
||||||
AboutView::AboutView(
|
AboutView::AboutView(
|
||||||
NavigationView& nav
|
NavigationView& nav) {
|
||||||
) {
|
add_children({&credits_display,
|
||||||
add_children({
|
&button_ok});
|
||||||
&credits_display,
|
|
||||||
&button_ok
|
|
||||||
});
|
|
||||||
|
|
||||||
button_ok.on_select = [&nav](Button&) {
|
button_ok.on_select = [&nav](Button&) {
|
||||||
nav.pop();
|
nav.pop();
|
||||||
|
|
|
@ -99,25 +99,20 @@ private:
|
||||||
{1 * 8, " Windyoona Channels", 0},
|
{1 * 8, " Windyoona Channels", 0},
|
||||||
{1 * 8, " F4GEV Pyr3x", 0},
|
{1 * 8, " F4GEV Pyr3x", 0},
|
||||||
{1 * 8, " HB3YOE", 24},
|
{1 * 8, " HB3YOE", 24},
|
||||||
{ 11 * 8, "MMXVIII", -1 }
|
{11 * 8, "MMXVIII", -1}};
|
||||||
};
|
|
||||||
|
|
||||||
CreditsWidget credits_display{
|
CreditsWidget credits_display{
|
||||||
{ 0, 16, 240, 240 }
|
{0, 16, 240, 240}};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_ok{
|
Button button_ok{
|
||||||
{72, 272, 96, 24},
|
{72, 272, 96, 24},
|
||||||
"OK"
|
"OK"};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_update{
|
MessageHandlerRegistration message_handler_update{
|
||||||
Message::ID::DisplayFrameSync,
|
Message::ID::DisplayFrameSync,
|
||||||
[this](const Message* const) {
|
[this](const Message* const) {
|
||||||
this->update();
|
this->update();
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -218,7 +218,6 @@ void AboutView::render_audio() {
|
||||||
|
|
||||||
// Render 1024 music samples
|
// Render 1024 music samples
|
||||||
for (ym_render_cnt = 0; ym_render_cnt < 1024; ym_render_cnt++) {
|
for (ym_render_cnt = 0; ym_render_cnt < 1024; ym_render_cnt++) {
|
||||||
|
|
||||||
// Update registers at 48000/960 = 50Hz
|
// Update registers at 48000/960 = 50Hz
|
||||||
if (ym_sample_cnt == 0) {
|
if (ym_sample_cnt == 0) {
|
||||||
// "Decompress" on the fly and update YM registers
|
// "Decompress" on the fly and update YM registers
|
||||||
|
@ -357,9 +356,7 @@ void AboutView::ym_init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
AboutView::AboutView(
|
AboutView::AboutView(
|
||||||
NavigationView& nav
|
NavigationView& nav) {
|
||||||
)
|
|
||||||
{
|
|
||||||
uint8_t p, c;
|
uint8_t p, c;
|
||||||
|
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_audio_tx);
|
baseband::run_image(portapack::spi_flash::image_tag_audio_tx);
|
||||||
|
@ -399,7 +396,6 @@ AboutView::AboutView(
|
||||||
ym_frames = ((uint16_t)(ymdata_bin[1]) << 8) + ymdata_bin[0];
|
ym_frames = ((uint16_t)(ymdata_bin[1]) << 8) + ymdata_bin[0];
|
||||||
ym_init();
|
ym_init();
|
||||||
|
|
||||||
|
|
||||||
button_ok.on_select = [this, &nav](Button&) {
|
button_ok.on_select = [this, &nav](Button&) {
|
||||||
if (framebuffer) chHeapFree(framebuffer); // Do NOT forget this
|
if (framebuffer) chHeapFree(framebuffer); // Do NOT forget this
|
||||||
nav.pop();
|
nav.pop();
|
||||||
|
|
|
@ -121,8 +121,7 @@ private:
|
||||||
{"XYLOS DATA", "CLX", true},
|
{"XYLOS DATA", "CLX", true},
|
||||||
{"GREETS TO", "SIGMOUNTE", false},
|
{"GREETS TO", "SIGMOUNTE", false},
|
||||||
{"GREETS TO", "WINDYOONA", true},
|
{"GREETS TO", "WINDYOONA", true},
|
||||||
{"THIS MUSIC", "BIG ALEC", true}
|
{"THIS MUSIC", "BIG ALEC", true}};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_title{
|
Text text_title{
|
||||||
{100, 32, 40, 16},
|
{100, 32, 40, 16},
|
||||||
|
@ -141,20 +140,17 @@ private:
|
||||||
|
|
||||||
Text text_cpld_hackrf_status{
|
Text text_cpld_hackrf_status{
|
||||||
{240 - 3 * 8, 252, 3 * 8, 16},
|
{240 - 3 * 8, 252, 3 * 8, 16},
|
||||||
"???"
|
"???"};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_ok{
|
Button button_ok{
|
||||||
{72, 272, 96, 24},
|
{72, 272, 96, 24},
|
||||||
"OK"
|
"OK"};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_update{
|
MessageHandlerRegistration message_handler_update{
|
||||||
Message::ID::DisplayFrameSync,
|
Message::ID::DisplayFrameSync,
|
||||||
[this](const Message* const) {
|
[this](const Message* const) {
|
||||||
this->update();
|
this->update();
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_fifo_signal{
|
MessageHandlerRegistration message_handler_fifo_signal{
|
||||||
Message::ID::FIFOSignal,
|
Message::ID::FIFOSignal,
|
||||||
|
@ -164,9 +160,7 @@ private:
|
||||||
this->render_audio();
|
this->render_audio();
|
||||||
baseband::set_fifo_data(ym_buffer);
|
baseband::set_fifo_data(ym_buffer);
|
||||||
}
|
}
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
#include "ui_about_simple.hpp"
|
#include "ui_about_simple.hpp"
|
||||||
|
|
||||||
namespace ui
|
namespace ui {
|
||||||
{
|
AboutView::AboutView(NavigationView& nav) {
|
||||||
AboutView::AboutView(NavigationView &nav)
|
|
||||||
{
|
|
||||||
add_children({&console, &button_ok});
|
add_children({&console, &button_ok});
|
||||||
|
|
||||||
button_ok.on_select = [&nav](Button &)
|
button_ok.on_select = [&nav](Button&) {
|
||||||
{
|
|
||||||
nav.pop();
|
nav.pop();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -15,14 +12,11 @@ namespace ui
|
||||||
console.writeln("");
|
console.writeln("");
|
||||||
}
|
}
|
||||||
|
|
||||||
void AboutView::update()
|
void AboutView::update() {
|
||||||
{
|
if (++timer > 200) {
|
||||||
if (++timer > 200)
|
|
||||||
{
|
|
||||||
timer = 0;
|
timer = 0;
|
||||||
|
|
||||||
switch (++frame)
|
switch (++frame) {
|
||||||
{
|
|
||||||
case 1:
|
case 1:
|
||||||
// TODO: Generate this automatically from github
|
// TODO: Generate this automatically from github
|
||||||
// https://github.com/eried/portapack-mayhem/graphs/contributors?to=2022-01-01&from=2020-04-12&type=c
|
// https://github.com/eried/portapack-mayhem/graphs/contributors?to=2022-01-01&from=2020-04-12&type=c
|
||||||
|
@ -77,8 +71,7 @@ namespace ui
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AboutView::focus()
|
void AboutView::focus() {
|
||||||
{
|
|
||||||
button_ok.focus();
|
button_ok.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,10 +7,8 @@
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
namespace ui
|
namespace ui {
|
||||||
{
|
class AboutView : public View {
|
||||||
class AboutView : public View
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
AboutView(NavigationView& nav);
|
AboutView(NavigationView& nav);
|
||||||
void focus() override;
|
void focus() override;
|
||||||
|
|
|
@ -39,8 +39,7 @@ void RecentEntriesTable<AircraftRecentEntries>::draw(
|
||||||
const Entry& entry,
|
const Entry& entry,
|
||||||
const Rect& target_rect,
|
const Rect& target_rect,
|
||||||
Painter& painter,
|
Painter& painter,
|
||||||
const Style& style
|
const Style& style) {
|
||||||
) {
|
|
||||||
char aged_color;
|
char aged_color;
|
||||||
Color target_color;
|
Color target_color;
|
||||||
auto entry_age = entry.age;
|
auto entry_age = entry.age;
|
||||||
|
@ -70,8 +69,7 @@ void RecentEntriesTable<AircraftRecentEntries>::draw(
|
||||||
painter.draw_string(
|
painter.draw_string(
|
||||||
target_rect.location(),
|
target_rect.location(),
|
||||||
style,
|
style,
|
||||||
entry_string
|
entry_string);
|
||||||
);
|
|
||||||
|
|
||||||
if (entry.pos.valid)
|
if (entry.pos.valid)
|
||||||
painter.draw_bitmap(target_rect.location() + Point(8 * 8, 0), bitmap_target, target_color, style.background);
|
painter.draw_bitmap(target_rect.location() + Point(8 * 8, 0), bitmap_target, target_color, style.background);
|
||||||
|
@ -83,7 +81,6 @@ void ADSBLogger::log_str(std::string& logline) {
|
||||||
log_file.write_entry(datetime, logline);
|
log_file.write_entry(datetime, logline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Aircraft Details
|
// Aircraft Details
|
||||||
void ADSBRxAircraftDetailsView::focus() {
|
void ADSBRxAircraftDetailsView::focus() {
|
||||||
button_close.focus();
|
button_close.focus();
|
||||||
|
@ -96,13 +93,10 @@ ADSBRxAircraftDetailsView::~ADSBRxAircraftDetailsView() {
|
||||||
ADSBRxAircraftDetailsView::ADSBRxAircraftDetailsView(
|
ADSBRxAircraftDetailsView::ADSBRxAircraftDetailsView(
|
||||||
NavigationView& nav,
|
NavigationView& nav,
|
||||||
const AircraftRecentEntry& entry,
|
const AircraftRecentEntry& entry,
|
||||||
const std::function<void(void)> on_close
|
const std::function<void(void)> on_close)
|
||||||
) : entry_copy(entry),
|
: entry_copy(entry),
|
||||||
on_close_(on_close)
|
on_close_(on_close) {
|
||||||
{
|
add_children({&labels,
|
||||||
|
|
||||||
add_children({
|
|
||||||
&labels,
|
|
||||||
&text_icao_address,
|
&text_icao_address,
|
||||||
&text_registration,
|
&text_registration,
|
||||||
&text_manufacturer,
|
&text_manufacturer,
|
||||||
|
@ -112,8 +106,7 @@ ADSBRxAircraftDetailsView::ADSBRxAircraftDetailsView(
|
||||||
&text_engine_type,
|
&text_engine_type,
|
||||||
&text_owner,
|
&text_owner,
|
||||||
&text_operator,
|
&text_operator,
|
||||||
&button_close
|
&button_close});
|
||||||
});
|
|
||||||
|
|
||||||
std::unique_ptr<ADSBLogger> logger{};
|
std::unique_ptr<ADSBLogger> logger{};
|
||||||
|
|
||||||
|
@ -170,14 +163,22 @@ ADSBRxAircraftDetailsView::ADSBRxAircraftDetailsView(
|
||||||
}
|
}
|
||||||
// Check for ICAO type designator
|
// Check for ICAO type designator
|
||||||
else if (strlen(aircraft_record.icao_type) == 4) {
|
else if (strlen(aircraft_record.icao_type) == 4) {
|
||||||
if(strcmp(aircraft_record.icao_type,"SHIP") == 0) text_type.set("Airship");
|
if (strcmp(aircraft_record.icao_type, "SHIP") == 0)
|
||||||
else if(strcmp(aircraft_record.icao_type,"BALL") == 0) text_type.set("Balloon");
|
text_type.set("Airship");
|
||||||
else if(strcmp(aircraft_record.icao_type,"GLID") == 0) text_type.set("Glider / sailplane");
|
else if (strcmp(aircraft_record.icao_type, "BALL") == 0)
|
||||||
else if(strcmp(aircraft_record.icao_type,"ULAC") == 0) text_type.set("Micro/ultralight aircraft");
|
text_type.set("Balloon");
|
||||||
else if(strcmp(aircraft_record.icao_type,"GYRO") == 0) text_type.set("Micro/ultralight autogyro");
|
else if (strcmp(aircraft_record.icao_type, "GLID") == 0)
|
||||||
else if(strcmp(aircraft_record.icao_type,"UHEL") == 0) text_type.set("Micro/ultralight helicopter");
|
text_type.set("Glider / sailplane");
|
||||||
else if(strcmp(aircraft_record.icao_type,"SHIP") == 0) text_type.set("Airship");
|
else if (strcmp(aircraft_record.icao_type, "ULAC") == 0)
|
||||||
else if(strcmp(aircraft_record.icao_type,"PARA") == 0) text_type.set("Powered parachute/paraplane");
|
text_type.set("Micro/ultralight aircraft");
|
||||||
|
else if (strcmp(aircraft_record.icao_type, "GYRO") == 0)
|
||||||
|
text_type.set("Micro/ultralight autogyro");
|
||||||
|
else if (strcmp(aircraft_record.icao_type, "UHEL") == 0)
|
||||||
|
text_type.set("Micro/ultralight helicopter");
|
||||||
|
else if (strcmp(aircraft_record.icao_type, "SHIP") == 0)
|
||||||
|
text_type.set("Airship");
|
||||||
|
else if (strcmp(aircraft_record.icao_type, "PARA") == 0)
|
||||||
|
text_type.set("Powered parachute/paraplane");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DATABASE_NOT_FOUND:
|
case DATABASE_NOT_FOUND:
|
||||||
|
@ -187,7 +188,6 @@ ADSBRxAircraftDetailsView::ADSBRxAircraftDetailsView(
|
||||||
button_close.on_select = [&nav](Button&) {
|
button_close.on_select = [&nav](Button&) {
|
||||||
nav.pop();
|
nav.pop();
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// End of Aicraft details
|
// End of Aicraft details
|
||||||
|
@ -214,8 +214,7 @@ void ADSBRxDetailsView::update(const AircraftRecentEntry& entry) {
|
||||||
text_frame_pos_even.set(to_string_hex_array(entry_copy.frame_pos_even.get_raw_data(), 14));
|
text_frame_pos_even.set(to_string_hex_array(entry_copy.frame_pos_even.get_raw_data(), 14));
|
||||||
text_frame_pos_odd.set(to_string_hex_array(entry_copy.frame_pos_odd.get_raw_data(), 14));
|
text_frame_pos_odd.set(to_string_hex_array(entry_copy.frame_pos_odd.get_raw_data(), 14));
|
||||||
|
|
||||||
if (send_updates)
|
if (send_updates) {
|
||||||
{
|
|
||||||
geomap_view->update_tag(trimr(entry.callsign[0] != ' ' ? entry.callsign : to_string_hex(entry.ICAO_address, 6)));
|
geomap_view->update_tag(trimr(entry.callsign[0] != ' ' ? entry.callsign : to_string_hex(entry.ICAO_address, 6)));
|
||||||
geomap_view->update_position(entry_copy.pos.latitude, entry_copy.pos.longitude, entry_copy.velo.heading, entry_copy.pos.altitude);
|
geomap_view->update_position(entry_copy.pos.latitude, entry_copy.pos.longitude, entry_copy.velo.heading, entry_copy.pos.altitude);
|
||||||
}
|
}
|
||||||
|
@ -228,13 +227,10 @@ ADSBRxDetailsView::~ADSBRxDetailsView() {
|
||||||
ADSBRxDetailsView::ADSBRxDetailsView(
|
ADSBRxDetailsView::ADSBRxDetailsView(
|
||||||
NavigationView& nav,
|
NavigationView& nav,
|
||||||
const AircraftRecentEntry& entry,
|
const AircraftRecentEntry& entry,
|
||||||
const std::function<void(void)> on_close
|
const std::function<void(void)> on_close)
|
||||||
) : entry_copy(entry),
|
: entry_copy(entry),
|
||||||
on_close_(on_close)
|
on_close_(on_close) {
|
||||||
{
|
add_children({&labels,
|
||||||
|
|
||||||
add_children({
|
|
||||||
&labels,
|
|
||||||
&text_icao_address,
|
&text_icao_address,
|
||||||
&text_callsign,
|
&text_callsign,
|
||||||
&text_last_seen,
|
&text_last_seen,
|
||||||
|
@ -245,8 +241,7 @@ ADSBRxDetailsView::ADSBRxDetailsView(
|
||||||
&text_frame_pos_even,
|
&text_frame_pos_even,
|
||||||
&text_frame_pos_odd,
|
&text_frame_pos_odd,
|
||||||
&button_aircraft_details,
|
&button_aircraft_details,
|
||||||
&button_see_map
|
&button_see_map});
|
||||||
});
|
|
||||||
|
|
||||||
std::unique_ptr<ADSBLogger> logger{};
|
std::unique_ptr<ADSBLogger> logger{};
|
||||||
update(entry_copy);
|
update(entry_copy);
|
||||||
|
@ -265,7 +260,6 @@ ADSBRxDetailsView::ADSBRxDetailsView(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
text_callsign.set(entry_copy.callsign);
|
text_callsign.set(entry_copy.callsign);
|
||||||
text_icao_address.set(to_string_hex(entry_copy.ICAO_address, 6));
|
text_icao_address.set(to_string_hex(entry_copy.ICAO_address, 6));
|
||||||
|
|
||||||
|
@ -291,7 +285,6 @@ ADSBRxDetailsView::ADSBRxDetailsView(
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void ADSBRxView::focus() {
|
void ADSBRxView::focus() {
|
||||||
field_vga.focus();
|
field_vga.focus();
|
||||||
}
|
}
|
||||||
|
@ -320,21 +313,19 @@ AircraftRecentEntry ADSBRxView::find_or_create_entry(uint32_t ICAO_address) {
|
||||||
return *it;
|
return *it;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ADSBRxView::replace_entry(AircraftRecentEntry & entry)
|
void ADSBRxView::replace_entry(AircraftRecentEntry& entry) {
|
||||||
{
|
|
||||||
uint32_t ICAO_address = entry.ICAO_address;
|
uint32_t ICAO_address = entry.ICAO_address;
|
||||||
|
|
||||||
std::replace_if( recent.begin(), recent.end(),
|
std::replace_if(
|
||||||
|
recent.begin(), recent.end(),
|
||||||
[ICAO_address](const AircraftRecentEntry& compEntry) { return ICAO_address == compEntry.ICAO_address; },
|
[ICAO_address](const AircraftRecentEntry& compEntry) { return ICAO_address == compEntry.ICAO_address; },
|
||||||
entry);
|
entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ADSBRxView::remove_old_entries()
|
void ADSBRxView::remove_old_entries() {
|
||||||
{
|
|
||||||
auto it = recent.rbegin();
|
auto it = recent.rbegin();
|
||||||
auto end = recent.rend();
|
auto end = recent.rend();
|
||||||
while (it != end)
|
while (it != end) {
|
||||||
{
|
|
||||||
if (it->age_state >= 4) {
|
if (it->age_state >= 4) {
|
||||||
std::advance(it, 1);
|
std::advance(it, 1);
|
||||||
recent.erase(it.base());
|
recent.erase(it.base());
|
||||||
|
@ -344,8 +335,7 @@ void ADSBRxView::remove_old_entries()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ADSBRxView::sort_entries_by_state()
|
void ADSBRxView::sort_entries_by_state() {
|
||||||
{
|
|
||||||
// Sorting List pn age_state using lambda function as comparator
|
// Sorting List pn age_state using lambda function as comparator
|
||||||
recent.sort([](const AircraftRecentEntry& left, const AircraftRecentEntry& right) { return (left.age_state < right.age_state); });
|
recent.sort([](const AircraftRecentEntry& left, const AircraftRecentEntry& right) { return (left.age_state < right.age_state); });
|
||||||
}
|
}
|
||||||
|
@ -365,8 +355,7 @@ void ADSBRxView::on_frame(const ADSBFrameMessage * message) {
|
||||||
auto entry = find_or_create_entry(ICAO_address);
|
auto entry = find_or_create_entry(ICAO_address);
|
||||||
frame.set_rx_timestamp(datetime.minute() * 60 + datetime.second());
|
frame.set_rx_timestamp(datetime.minute() * 60 + datetime.second());
|
||||||
entry.reset_age();
|
entry.reset_age();
|
||||||
if (entry.hits==0)
|
if (entry.hits == 0) {
|
||||||
{
|
|
||||||
entry.amp = message->amp; // Store amplitude on first hit
|
entry.amp = message->amp; // Store amplitude on first hit
|
||||||
} else {
|
} else {
|
||||||
entry.amp = ((entry.amp * 15) + message->amp) >> 4; // Update smoothed amplitude on updates
|
entry.amp = ((entry.amp * 15) + message->amp) >> 4; // Update smoothed amplitude on updates
|
||||||
|
@ -404,7 +393,6 @@ void ADSBRxView::on_frame(const ADSBFrameMessage * message) {
|
||||||
" Lat:" + to_string_decimal(entry.pos.latitude, 2) +
|
" Lat:" + to_string_decimal(entry.pos.latitude, 2) +
|
||||||
" Lon:" + to_string_decimal(entry.pos.longitude, 2);
|
" Lon:" + to_string_decimal(entry.pos.longitude, 2);
|
||||||
|
|
||||||
|
|
||||||
entry.set_info_string(str_info);
|
entry.set_info_string(str_info);
|
||||||
|
|
||||||
if (logger) {
|
if (logger) {
|
||||||
|
@ -417,7 +405,6 @@ void ADSBRxView::on_frame(const ADSBFrameMessage * message) {
|
||||||
" Lon:" + to_string_decimal(entry.pos.longitude, 7);
|
" Lon:" + to_string_decimal(entry.pos.longitude, 7);
|
||||||
logentry += log_info + " ";
|
logentry += log_info + " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
} else if (msg_type == AIRBORNE_VEL && msg_sub >= VEL_GND_SUBSONIC && msg_sub <= VEL_AIR_SUPERSONIC) {
|
} else if (msg_type == AIRBORNE_VEL && msg_sub >= VEL_GND_SUBSONIC && msg_sub <= VEL_AIR_SUPERSONIC) {
|
||||||
entry.set_frame_velo(frame);
|
entry.set_frame_velo(frame);
|
||||||
|
@ -427,7 +414,6 @@ void ADSBRxView::on_frame(const ADSBFrameMessage * message) {
|
||||||
" Hdg:" + to_string_dec_uint(entry.velo.heading) +
|
" Hdg:" + to_string_dec_uint(entry.velo.heading) +
|
||||||
" Spd: " + to_string_dec_int(entry.velo.speed);
|
" Spd: " + to_string_dec_int(entry.velo.speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
replace_entry(entry);
|
replace_entry(entry);
|
||||||
} // frame.get_DF() == DF_ADSB
|
} // frame.get_DF() == DF_ADSB
|
||||||
|
@ -477,7 +463,9 @@ void ADSBRxView::updateDetailsAndMap(int ageStep) {
|
||||||
// Increment age, and pass updates to the details and map
|
// Increment age, and pass updates to the details and map
|
||||||
const bool otherMarkersCanBeSent = send_updates && storeNewMarkers && details_view && details_view->geomap_view; // Save retesting all of this
|
const bool otherMarkersCanBeSent = send_updates && storeNewMarkers && details_view && details_view->geomap_view; // Save retesting all of this
|
||||||
MapMarkerStored markerStored = MARKER_NOT_STORED;
|
MapMarkerStored markerStored = MARKER_NOT_STORED;
|
||||||
if (otherMarkersCanBeSent) {details_view->geomap_view->clear_markers();}
|
if (otherMarkersCanBeSent) {
|
||||||
|
details_view->geomap_view->clear_markers();
|
||||||
|
}
|
||||||
// Loop through all entries
|
// Loop through all entries
|
||||||
for (auto& entry : recent) {
|
for (auto& entry : recent) {
|
||||||
entry.inc_age(ageStep);
|
entry.inc_age(ageStep);
|
||||||
|
@ -489,8 +477,7 @@ void ADSBRxView::updateDetailsAndMap(int ageStep) {
|
||||||
details_view->update(entry);
|
details_view->update(entry);
|
||||||
}
|
}
|
||||||
// Store if the view is present and the list isn't full
|
// Store if the view is present and the list isn't full
|
||||||
else if (otherMarkersCanBeSent && (markerStored != MARKER_LIST_FULL) && entry.pos.valid && (entry.age_state<=2))
|
else if (otherMarkersCanBeSent && (markerStored != MARKER_LIST_FULL) && entry.pos.valid && (entry.age_state <= 2)) {
|
||||||
{
|
|
||||||
marker.lon = entry.pos.longitude;
|
marker.lon = entry.pos.longitude;
|
||||||
marker.lat = entry.pos.latitude;
|
marker.lat = entry.pos.latitude;
|
||||||
marker.angle = entry.velo.heading;
|
marker.angle = entry.velo.heading;
|
||||||
|
@ -510,15 +497,12 @@ void ADSBRxView::updateRecentEntries() {
|
||||||
|
|
||||||
ADSBRxView::ADSBRxView(NavigationView& nav) {
|
ADSBRxView::ADSBRxView(NavigationView& nav) {
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_adsb_rx);
|
baseband::run_image(portapack::spi_flash::image_tag_adsb_rx);
|
||||||
add_children({
|
add_children({&labels,
|
||||||
&labels,
|
|
||||||
&field_lna,
|
&field_lna,
|
||||||
&field_vga,
|
&field_vga,
|
||||||
&field_rf_amp,
|
&field_rf_amp,
|
||||||
&rssi,
|
&rssi,
|
||||||
&recent_entries_view
|
&recent_entries_view});
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// load app settings
|
// load app settings
|
||||||
auto rc = settings.load("rx_adsb", &app_settings);
|
auto rc = settings.load("rx_adsb", &app_settings);
|
||||||
|
@ -526,14 +510,11 @@ ADSBRxView::ADSBRxView(NavigationView& nav) {
|
||||||
field_lna.set_value(app_settings.lna);
|
field_lna.set_value(app_settings.lna);
|
||||||
field_vga.set_value(app_settings.vga);
|
field_vga.set_value(app_settings.vga);
|
||||||
field_rf_amp.set_value(app_settings.rx_amp);
|
field_rf_amp.set_value(app_settings.rx_amp);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
field_lna.set_value(40);
|
field_lna.set_value(40);
|
||||||
field_vga.set_value(40);
|
field_vga.set_value(40);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
recent_entries_view.set_parent_rect({0, 16, 240, 272});
|
recent_entries_view.set_parent_rect({0, 16, 240, 272});
|
||||||
recent_entries_view.on_select = [this, &nav](const AircraftRecentEntry& entry) {
|
recent_entries_view.on_select = [this, &nav](const AircraftRecentEntry& entry) {
|
||||||
detailed_entry_key = entry.key();
|
detailed_entry_key = entry.key();
|
||||||
|
|
|
@ -89,9 +89,8 @@ struct AircraftRecentEntry {
|
||||||
std::string info_string{""};
|
std::string info_string{""};
|
||||||
|
|
||||||
AircraftRecentEntry(
|
AircraftRecentEntry(
|
||||||
const uint32_t ICAO_address
|
const uint32_t ICAO_address)
|
||||||
) : ICAO_address { ICAO_address }
|
: ICAO_address{ICAO_address} {
|
||||||
{
|
|
||||||
this->icaoStr = to_string_hex(ICAO_address, 6);
|
this->icaoStr = to_string_hex(ICAO_address, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +157,6 @@ private:
|
||||||
LogFile log_file{};
|
LogFile log_file{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class ADSBRxAircraftDetailsView : public View {
|
class ADSBRxAircraftDetailsView : public View {
|
||||||
public:
|
public:
|
||||||
ADSBRxAircraftDetailsView(NavigationView&, const AircraftRecentEntry& entry, const std::function<void(void)> on_close);
|
ADSBRxAircraftDetailsView(NavigationView&, const AircraftRecentEntry& entry, const std::function<void(void)> on_close);
|
||||||
|
@ -196,60 +194,48 @@ private:
|
||||||
{{0 * 8, 8 * 16}, "Number of engines:", Color::light_grey()},
|
{{0 * 8, 8 * 16}, "Number of engines:", Color::light_grey()},
|
||||||
{{0 * 8, 9 * 16}, "Engine type:", Color::light_grey()},
|
{{0 * 8, 9 * 16}, "Engine type:", Color::light_grey()},
|
||||||
{{0 * 8, 11 * 16}, "Owner:", Color::light_grey()},
|
{{0 * 8, 11 * 16}, "Owner:", Color::light_grey()},
|
||||||
{ { 0 * 8, 13 * 16 }, "Operator:", Color::light_grey() }
|
{{0 * 8, 13 * 16}, "Operator:", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_icao_address{
|
Text text_icao_address{
|
||||||
{5 * 8, 1 * 16, 6 * 8, 16},
|
{5 * 8, 1 * 16, 6 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_registration{
|
Text text_registration{
|
||||||
{13 * 8, 2 * 16, 8 * 8, 16},
|
{13 * 8, 2 * 16, 8 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_manufacturer{
|
Text text_manufacturer{
|
||||||
{0 * 8, 4 * 16, 19 * 8, 16},
|
{0 * 8, 4 * 16, 19 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_model{
|
Text text_model{
|
||||||
{0 * 8, 6 * 16, 30 * 8, 16},
|
{0 * 8, 6 * 16, 30 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_type{
|
Text text_type{
|
||||||
{5 * 8, 7 * 16, 22 * 8, 16},
|
{5 * 8, 7 * 16, 22 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_number_of_engines{
|
Text text_number_of_engines{
|
||||||
{18 * 8, 8 * 16, 30 * 8, 16},
|
{18 * 8, 8 * 16, 30 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_engine_type{
|
Text text_engine_type{
|
||||||
{0 * 8, 10 * 16, 30 * 8, 16},
|
{0 * 8, 10 * 16, 30 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_owner{
|
Text text_owner{
|
||||||
{0 * 8, 12 * 16, 30 * 8, 16},
|
{0 * 8, 12 * 16, 30 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_operator{
|
Text text_operator{
|
||||||
{0 * 8, 14 * 16, 30 * 8, 16},
|
{0 * 8, 14 * 16, 30 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_close{
|
Button button_close{
|
||||||
{9 * 8, 16 * 16, 12 * 8, 3 * 16},
|
{9 * 8, 16 * 16, 12 * 8, 3 * 16},
|
||||||
"Back"
|
"Back"};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class ADSBRxDetailsView : public View {
|
class ADSBRxDetailsView : public View {
|
||||||
public:
|
public:
|
||||||
|
@ -269,10 +255,10 @@ public:
|
||||||
|
|
||||||
AircraftRecentEntry get_current_entry() { return entry_copy; }
|
AircraftRecentEntry get_current_entry() { return entry_copy; }
|
||||||
|
|
||||||
|
|
||||||
std::database::AirlinesDBRecord airline_record = {};
|
std::database::AirlinesDBRecord airline_record = {};
|
||||||
|
|
||||||
GeoMapView* geomap_view{nullptr};
|
GeoMapView* geomap_view{nullptr};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AircraftRecentEntry entry_copy{0};
|
AircraftRecentEntry entry_copy{0};
|
||||||
std::function<void(void)> on_close_{};
|
std::function<void(void)> on_close_{};
|
||||||
|
@ -289,64 +275,51 @@ private:
|
||||||
{{0 * 8, 3 * 16}, "Airline:", Color::light_grey()},
|
{{0 * 8, 3 * 16}, "Airline:", Color::light_grey()},
|
||||||
{{0 * 8, 5 * 16}, "Country:", Color::light_grey()},
|
{{0 * 8, 5 * 16}, "Country:", Color::light_grey()},
|
||||||
{{0 * 8, 13 * 16}, "Even position frame:", Color::light_grey()},
|
{{0 * 8, 13 * 16}, "Even position frame:", Color::light_grey()},
|
||||||
{ { 0 * 8, 15 * 16 }, "Odd position frame:", Color::light_grey() }
|
{{0 * 8, 15 * 16}, "Odd position frame:", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_icao_address{
|
Text text_icao_address{
|
||||||
{5 * 8, 1 * 16, 6 * 8, 16},
|
{5 * 8, 1 * 16, 6 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_callsign{
|
Text text_callsign{
|
||||||
{22 * 8, 1 * 16, 8 * 8, 16},
|
{22 * 8, 1 * 16, 8 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_last_seen{
|
Text text_last_seen{
|
||||||
{11 * 8, 2 * 16, 19 * 8, 16},
|
{11 * 8, 2 * 16, 19 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_airline{
|
Text text_airline{
|
||||||
{0 * 8, 4 * 16, 30 * 8, 16},
|
{0 * 8, 4 * 16, 30 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_country{
|
Text text_country{
|
||||||
{8 * 8, 5 * 16, 22 * 8, 16},
|
{8 * 8, 5 * 16, 22 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_infos{
|
Text text_infos{
|
||||||
{0 * 8, 6 * 16, 30 * 8, 16},
|
{0 * 8, 6 * 16, 30 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_info2{
|
Text text_info2{
|
||||||
{0 * 8, 7 * 16, 30 * 8, 16},
|
{0 * 8, 7 * 16, 30 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_frame_pos_even{
|
Text text_frame_pos_even{
|
||||||
{0 * 8, 14 * 16, 30 * 8, 16},
|
{0 * 8, 14 * 16, 30 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
Text text_frame_pos_odd{
|
Text text_frame_pos_odd{
|
||||||
{0 * 8, 16 * 16, 30 * 8, 16},
|
{0 * 8, 16 * 16, 30 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_aircraft_details{
|
Button button_aircraft_details{
|
||||||
{2 * 8, 9 * 16, 12 * 8, 3 * 16},
|
{2 * 8, 9 * 16, 12 * 8, 3 * 16},
|
||||||
"A/C details"
|
"A/C details"};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_see_map{
|
Button button_see_map{
|
||||||
{16 * 8, 9 * 16, 12 * 8, 3 * 16},
|
{16 * 8, 9 * 16, 12 * 8, 3 * 16},
|
||||||
"See on map"
|
"See on map"};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class ADSBRxView : public View {
|
class ADSBRxView : public View {
|
||||||
public:
|
public:
|
||||||
|
@ -382,14 +355,12 @@ private:
|
||||||
std::app_settings settings{};
|
std::app_settings settings{};
|
||||||
std::app_settings::AppSettings app_settings{};
|
std::app_settings::AppSettings app_settings{};
|
||||||
|
|
||||||
const RecentEntriesColumns columns { {
|
const RecentEntriesColumns columns{{{"ICAO/Call", 9},
|
||||||
{ "ICAO/Call", 9 },
|
|
||||||
{"Lvl", 3},
|
{"Lvl", 3},
|
||||||
{"Spd", 3},
|
{"Spd", 3},
|
||||||
{"Amp", 3},
|
{"Amp", 3},
|
||||||
{"Hit", 3},
|
{"Hit", 3},
|
||||||
{ "Age", 4 }
|
{"Age", 4}}};
|
||||||
} };
|
|
||||||
AircraftRecentEntries recent{};
|
AircraftRecentEntries recent{};
|
||||||
RecentEntriesView<RecentEntries<AircraftRecentEntry>> recent_entries_view{columns, recent};
|
RecentEntriesView<RecentEntries<AircraftRecentEntry>> recent_entries_view{columns, recent};
|
||||||
|
|
||||||
|
@ -399,20 +370,16 @@ private:
|
||||||
bool send_updates{false};
|
bool send_updates{false};
|
||||||
|
|
||||||
Labels labels{
|
Labels labels{
|
||||||
{ { 0 * 8, 0 * 8 }, "LNA: VGA: AMP:", Color::light_grey() }
|
{{0 * 8, 0 * 8}, "LNA: VGA: AMP:", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
LNAGainField field_lna{
|
LNAGainField field_lna{
|
||||||
{ 4 * 8, 0 * 16 }
|
{4 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
VGAGainField field_vga{
|
VGAGainField field_vga{
|
||||||
{ 11 * 8, 0 * 16 }
|
{11 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
RFAmpField field_rf_amp{
|
RFAmpField field_rf_amp{
|
||||||
{ 18 * 8, 0 * 16 }
|
{18 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
RSSI rssi{
|
RSSI rssi{
|
||||||
{20 * 8, 4, 10 * 8, 8},
|
{20 * 8, 4, 10 * 8, 8},
|
||||||
|
@ -423,8 +390,7 @@ private:
|
||||||
[this](Message* const p) {
|
[this](Message* const p) {
|
||||||
const auto message = static_cast<const ADSBFrameMessage*>(p);
|
const auto message = static_cast<const ADSBFrameMessage*>(p);
|
||||||
this->on_frame(message);
|
this->on_frame(message);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -38,9 +38,8 @@ using namespace portapack;
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
Compass::Compass(
|
Compass::Compass(
|
||||||
const Point parent_pos
|
const Point parent_pos)
|
||||||
) : Widget { { parent_pos, { 64, 64 } } }
|
: Widget{{parent_pos, {64, 64}}} {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Compass::set_value(uint32_t new_value) {
|
void Compass::set_value(uint32_t new_value) {
|
||||||
|
@ -51,14 +50,12 @@ void Compass::set_value(uint32_t new_value) {
|
||||||
display.draw_line(
|
display.draw_line(
|
||||||
center,
|
center,
|
||||||
center + polar_to_point(value_, 28),
|
center + polar_to_point(value_, 28),
|
||||||
Color::dark_grey()
|
Color::dark_grey());
|
||||||
);
|
|
||||||
|
|
||||||
display.draw_line(
|
display.draw_line(
|
||||||
center,
|
center,
|
||||||
center + polar_to_point(new_value, 28),
|
center + polar_to_point(new_value, 28),
|
||||||
Color::green()
|
Color::green());
|
||||||
);
|
|
||||||
|
|
||||||
value_ = new_value;
|
value_ = new_value;
|
||||||
}
|
}
|
||||||
|
@ -75,15 +72,13 @@ void Compass::paint(Painter&) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ADSBPositionView::ADSBPositionView(
|
ADSBPositionView::ADSBPositionView(
|
||||||
NavigationView& nav, Rect parent_rect
|
NavigationView& nav,
|
||||||
) : OptionTabView(parent_rect)
|
Rect parent_rect)
|
||||||
{
|
: OptionTabView(parent_rect) {
|
||||||
set_type("position");
|
set_type("position");
|
||||||
|
|
||||||
add_children({
|
add_children({&geopos,
|
||||||
&geopos,
|
&button_set_map});
|
||||||
&button_set_map
|
|
||||||
});
|
|
||||||
|
|
||||||
geopos.set_altitude(36000);
|
geopos.set_altitude(36000);
|
||||||
|
|
||||||
|
@ -118,15 +113,13 @@ void ADSBPositionView::collect_frames(const uint32_t ICAO_address, std::vector<A
|
||||||
}
|
}
|
||||||
|
|
||||||
ADSBCallsignView::ADSBCallsignView(
|
ADSBCallsignView::ADSBCallsignView(
|
||||||
NavigationView& nav, Rect parent_rect
|
NavigationView& nav,
|
||||||
) : OptionTabView(parent_rect)
|
Rect parent_rect)
|
||||||
{
|
: OptionTabView(parent_rect) {
|
||||||
set_type("callsign");
|
set_type("callsign");
|
||||||
|
|
||||||
add_children({
|
add_children({&labels_callsign,
|
||||||
&labels_callsign,
|
&button_callsign});
|
||||||
&button_callsign
|
|
||||||
});
|
|
||||||
|
|
||||||
set_enabled(true);
|
set_enabled(true);
|
||||||
|
|
||||||
|
@ -139,8 +132,7 @@ ADSBCallsignView::ADSBCallsignView(
|
||||||
8,
|
8,
|
||||||
[this](std::string& s) {
|
[this](std::string& s) {
|
||||||
button_callsign.set_text(s);
|
button_callsign.set_text(s);
|
||||||
}
|
});
|
||||||
);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,19 +147,16 @@ void ADSBCallsignView::collect_frames(const uint32_t ICAO_address, std::vector<A
|
||||||
}
|
}
|
||||||
|
|
||||||
ADSBSpeedView::ADSBSpeedView(
|
ADSBSpeedView::ADSBSpeedView(
|
||||||
Rect parent_rect
|
Rect parent_rect)
|
||||||
) : OptionTabView(parent_rect)
|
: OptionTabView(parent_rect) {
|
||||||
{
|
|
||||||
set_type("speed");
|
set_type("speed");
|
||||||
|
|
||||||
add_children({
|
add_children({&labels_speed,
|
||||||
&labels_speed,
|
|
||||||
&labels_vert_rate,
|
&labels_vert_rate,
|
||||||
&compass,
|
&compass,
|
||||||
&field_angle,
|
&field_angle,
|
||||||
&field_speed,
|
&field_speed,
|
||||||
&field_vert_rate
|
&field_vert_rate});
|
||||||
});
|
|
||||||
|
|
||||||
field_angle.set_value(0);
|
field_angle.set_value(0);
|
||||||
field_speed.set_value(400);
|
field_speed.set_value(400);
|
||||||
|
@ -190,15 +179,12 @@ void ADSBSpeedView::collect_frames(const uint32_t ICAO_address, std::vector<ADSB
|
||||||
}
|
}
|
||||||
|
|
||||||
ADSBSquawkView::ADSBSquawkView(
|
ADSBSquawkView::ADSBSquawkView(
|
||||||
Rect parent_rect
|
Rect parent_rect)
|
||||||
) : OptionTabView(parent_rect)
|
: OptionTabView(parent_rect) {
|
||||||
{
|
|
||||||
set_type("squawk");
|
set_type("squawk");
|
||||||
|
|
||||||
add_children({
|
add_children({&labels_squawk,
|
||||||
&labels_squawk,
|
&field_squawk});
|
||||||
&field_squawk
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ADSBSquawkView::collect_frames(const uint32_t ICAO_address, std::vector<ADSBFrame>& frame_list) {
|
void ADSBSquawkView::collect_frames(const uint32_t ICAO_address, std::vector<ADSBFrame>& frame_list) {
|
||||||
|
@ -213,9 +199,8 @@ void ADSBSquawkView::collect_frames(const uint32_t ICAO_address, std::vector<ADS
|
||||||
}
|
}
|
||||||
|
|
||||||
ADSBTXThread::ADSBTXThread(
|
ADSBTXThread::ADSBTXThread(
|
||||||
std::vector<ADSBFrame> frames
|
std::vector<ADSBFrame> frames)
|
||||||
) : frames_ { std::move(frames) }
|
: frames_{std::move(frames)} {
|
||||||
{
|
|
||||||
thread = chThdCreateFromHeap(NULL, 1024, NORMALPRIO + 10, ADSBTXThread::static_fn, this);
|
thread = chThdCreateFromHeap(NULL, 1024, NORMALPRIO + 10, ADSBTXThread::static_fn, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,7 +273,6 @@ void ADSBTxView::focus() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ADSBTxView::~ADSBTxView() {
|
ADSBTxView::~ADSBTxView() {
|
||||||
|
|
||||||
// save app settings
|
// save app settings
|
||||||
app_settings.tx_frequency = transmitter_model.tuning_frequency();
|
app_settings.tx_frequency = transmitter_model.tuning_frequency();
|
||||||
settings.save("tx_adsb", &app_settings);
|
settings.save("tx_adsb", &app_settings);
|
||||||
|
@ -329,13 +313,11 @@ void ADSBTxView::start_tx() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ADSBTxView::ADSBTxView(
|
ADSBTxView::ADSBTxView(
|
||||||
NavigationView& nav
|
NavigationView& nav)
|
||||||
) : nav_ { nav }
|
: nav_{nav} {
|
||||||
{
|
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_adsb_tx);
|
baseband::run_image(portapack::spi_flash::image_tag_adsb_tx);
|
||||||
|
|
||||||
add_children({
|
add_children({&tab_view,
|
||||||
&tab_view,
|
|
||||||
&labels,
|
&labels,
|
||||||
&sym_icao,
|
&sym_icao,
|
||||||
&view_position,
|
&view_position,
|
||||||
|
@ -343,8 +325,7 @@ ADSBTxView::ADSBTxView(
|
||||||
&view_speed,
|
&view_speed,
|
||||||
&view_squawk,
|
&view_squawk,
|
||||||
&text_frame,
|
&text_frame,
|
||||||
&tx_view
|
&tx_view});
|
||||||
});
|
|
||||||
|
|
||||||
// load app settings
|
// load app settings
|
||||||
auto rc = settings.load("tx_adsb", &app_settings);
|
auto rc = settings.load("tx_adsb", &app_settings);
|
||||||
|
|
|
@ -57,13 +57,11 @@ public:
|
||||||
private:
|
private:
|
||||||
GeoPos geopos{
|
GeoPos geopos{
|
||||||
{0, 2 * 16},
|
{0, 2 * 16},
|
||||||
GeoPos::FEET
|
GeoPos::FEET};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_set_map{
|
Button button_set_map{
|
||||||
{8 * 8, 6 * 16, 14 * 8, 2 * 16},
|
{8 * 8, 6 * 16, 14 * 8, 2 * 16},
|
||||||
"Set from map"
|
"Set from map"};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ADSBCallsignView : public OptionTabView {
|
class ADSBCallsignView : public OptionTabView {
|
||||||
|
@ -76,13 +74,11 @@ private:
|
||||||
std::string callsign = "TEST1234";
|
std::string callsign = "TEST1234";
|
||||||
|
|
||||||
Labels labels_callsign{
|
Labels labels_callsign{
|
||||||
{ { 2 * 8, 5 * 8 }, "Callsign:", Color::light_grey() }
|
{{2 * 8, 5 * 8}, "Callsign:", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_callsign{
|
Button button_callsign{
|
||||||
{12 * 8, 2 * 16, 10 * 8, 2 * 16},
|
{12 * 8, 2 * 16, 10 * 8, 2 * 16},
|
||||||
""
|
""};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ADSBSpeedView : public OptionTabView {
|
class ADSBSpeedView : public OptionTabView {
|
||||||
|
@ -93,27 +89,35 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Labels labels_speed{
|
Labels labels_speed{
|
||||||
{ { 1 * 8, 6 * 16 }, "Speed: kn Bearing: *", Color::light_grey() }
|
{{1 * 8, 6 * 16}, "Speed: kn Bearing: *", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
Labels labels_vert_rate{
|
Labels labels_vert_rate{
|
||||||
{ { 1 * 8, 8 * 16 }, "Vert. rate: ft/min, (+/-)", Color::light_grey() }
|
{{1 * 8, 8 * 16}, "Vert. rate: ft/min, (+/-)", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
Compass compass{
|
Compass compass{
|
||||||
{ 21 * 8, 2 * 16 }
|
{21 * 8, 2 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_angle{
|
NumberField field_angle{
|
||||||
{ 21 * 8 + 20, 6 * 16 }, 3, { 0, 359 }, 1, ' ', true
|
{21 * 8 + 20, 6 * 16},
|
||||||
};
|
3,
|
||||||
|
{0, 359},
|
||||||
|
1,
|
||||||
|
' ',
|
||||||
|
true};
|
||||||
|
|
||||||
NumberField field_speed{
|
NumberField field_speed{
|
||||||
{ 8 * 8, 6 * 16 }, 3, { 0, 999 }, 5, ' '
|
{8 * 8, 6 * 16},
|
||||||
};
|
3,
|
||||||
|
{0, 999},
|
||||||
|
5,
|
||||||
|
' '};
|
||||||
|
|
||||||
NumberField field_vert_rate{
|
NumberField field_vert_rate{
|
||||||
{ 11 * 8, 8 * 16 }, 5, { -4096, 4096 }, 64, ' ' // Let's limit to +/-5k aprox , Ex. max safe descent vertical rate aprox -1000 ft/min on an instrument approach. , std step is 64
|
{11 * 8, 8 * 16},
|
||||||
|
5,
|
||||||
|
{-4096, 4096},
|
||||||
|
64,
|
||||||
|
' ' // Let's limit to +/-5k aprox , Ex. max safe descent vertical rate aprox -1000 ft/min on an instrument approach. , std step is 64
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -125,14 +129,12 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Labels labels_squawk{
|
Labels labels_squawk{
|
||||||
{ { 2 * 8, 2 * 16 }, "Squawk:", Color::light_grey() }
|
{{2 * 8, 2 * 16}, "Squawk:", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
SymField field_squawk{
|
SymField field_squawk{
|
||||||
{10 * 8, 2 * 16},
|
{10 * 8, 2 * 16},
|
||||||
4,
|
4,
|
||||||
SymField::SYMFIELD_OCT
|
SymField::SYMFIELD_OCT};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ADSBTXThread {
|
class ADSBTXThread {
|
||||||
|
@ -221,29 +223,24 @@ private:
|
||||||
{"Position", Color::cyan(), &view_position},
|
{"Position", Color::cyan(), &view_position},
|
||||||
{"Callsign", Color::green(), &view_callsign},
|
{"Callsign", Color::green(), &view_callsign},
|
||||||
{"Speed", Color::yellow(), &view_speed},
|
{"Speed", Color::yellow(), &view_speed},
|
||||||
{ "Squawk", Color::orange(), &view_squawk }
|
{"Squawk", Color::orange(), &view_squawk}};
|
||||||
};
|
|
||||||
|
|
||||||
Labels labels{
|
Labels labels{
|
||||||
{ { 2 * 8, 4 * 8 }, "ICAO24:", Color::light_grey() }
|
{{2 * 8, 4 * 8}, "ICAO24:", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
SymField sym_icao{
|
SymField sym_icao{
|
||||||
{10 * 8, 4 * 8},
|
{10 * 8, 4 * 8},
|
||||||
6,
|
6,
|
||||||
SymField::SYMFIELD_HEX
|
SymField::SYMFIELD_HEX};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_frame{
|
Text text_frame{
|
||||||
{1 * 8, 29 * 8, 14 * 8, 16},
|
{1 * 8, 29 * 8, 14 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
|
|
||||||
TransmitterView tx_view{
|
TransmitterView tx_view{
|
||||||
16 * 16,
|
16 * 16,
|
||||||
1000000,
|
1000000,
|
||||||
0
|
0};
|
||||||
};
|
|
||||||
|
|
||||||
std::unique_ptr<ADSBTXThread> tx_thread{};
|
std::unique_ptr<ADSBTXThread> tx_thread{};
|
||||||
};
|
};
|
||||||
|
|
|
@ -53,8 +53,7 @@ void AFSKRxView::update_freq(rf::Frequency f) {
|
||||||
AFSKRxView::AFSKRxView(NavigationView& nav) {
|
AFSKRxView::AFSKRxView(NavigationView& nav) {
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_afsk_rx);
|
baseband::run_image(portapack::spi_flash::image_tag_afsk_rx);
|
||||||
|
|
||||||
add_children({
|
add_children({&rssi,
|
||||||
&rssi,
|
|
||||||
&channel,
|
&channel,
|
||||||
&field_rf_amp,
|
&field_rf_amp,
|
||||||
&field_lna,
|
&field_lna,
|
||||||
|
@ -63,8 +62,7 @@ AFSKRxView::AFSKRxView(NavigationView& nav) {
|
||||||
&check_log,
|
&check_log,
|
||||||
&text_debug,
|
&text_debug,
|
||||||
&button_modem_setup,
|
&button_modem_setup,
|
||||||
&console
|
&console});
|
||||||
});
|
|
||||||
|
|
||||||
// load app settings
|
// load app settings
|
||||||
auto rc = settings.load("rx_afsk", &app_settings);
|
auto rc = settings.load("rx_afsk", &app_settings);
|
||||||
|
@ -164,15 +162,13 @@ void AFSKRxView::on_data(uint32_t value, bool is_data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prev_value = value;
|
prev_value = value;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// Baudrate estimation
|
// Baudrate estimation
|
||||||
text_debug.set("Baudrate estimation: ~" + to_string_dec_uint(value));
|
text_debug.set("Baudrate estimation: ~" + to_string_dec_uint(value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AFSKRxView::~AFSKRxView() {
|
AFSKRxView::~AFSKRxView() {
|
||||||
|
|
||||||
// save app settings
|
// save app settings
|
||||||
app_settings.rx_frequency = field_frequency.value();
|
app_settings.rx_frequency = field_frequency.value();
|
||||||
settings.save("rx_afsk", &app_settings);
|
settings.save("rx_afsk", &app_settings);
|
||||||
|
|
|
@ -67,14 +67,11 @@ private:
|
||||||
bool logging{false};
|
bool logging{false};
|
||||||
|
|
||||||
RFAmpField field_rf_amp{
|
RFAmpField field_rf_amp{
|
||||||
{ 13 * 8, 0 * 16 }
|
{13 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
LNAGainField field_lna{
|
LNAGainField field_lna{
|
||||||
{ 15 * 8, 0 * 16 }
|
{15 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
VGAGainField field_vga{
|
VGAGainField field_vga{
|
||||||
{ 18 * 8, 0 * 16 }
|
{18 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
RSSI rssi{
|
RSSI rssi{
|
||||||
{21 * 8, 0, 6 * 8, 4},
|
{21 * 8, 0, 6 * 8, 4},
|
||||||
};
|
};
|
||||||
|
@ -90,22 +87,18 @@ private:
|
||||||
{0 * 8, 1 * 16},
|
{0 * 8, 1 * 16},
|
||||||
3,
|
3,
|
||||||
"LOG",
|
"LOG",
|
||||||
false
|
false};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_debug{
|
Text text_debug{
|
||||||
{0 * 8, 12 + 2 * 16, 240, 16},
|
{0 * 8, 12 + 2 * 16, 240, 16},
|
||||||
"DEBUG"
|
"DEBUG"};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_modem_setup{
|
Button button_modem_setup{
|
||||||
{240 - 12 * 8, 1 * 16, 96, 24},
|
{240 - 12 * 8, 1 * 16, 96, 24},
|
||||||
"Modem setup"
|
"Modem setup"};
|
||||||
};
|
|
||||||
|
|
||||||
Console console{
|
Console console{
|
||||||
{ 0, 4 * 16, 240, 240 }
|
{0, 4 * 16, 240, 240}};
|
||||||
};
|
|
||||||
|
|
||||||
void update_freq(rf::Frequency f);
|
void update_freq(rf::Frequency f);
|
||||||
void on_data_afsk(const AFSKDataMessage& message);
|
void on_data_afsk(const AFSKDataMessage& message);
|
||||||
|
@ -117,8 +110,7 @@ private:
|
||||||
[this](Message* const p) {
|
[this](Message* const p) {
|
||||||
const auto message = static_cast<const AFSKDataMessage*>(p);
|
const auto message = static_cast<const AFSKDataMessage*>(p);
|
||||||
this->on_data(message->value, message->is_data);
|
this->on_data(message->value, message->is_data);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -44,8 +44,7 @@ void RecentEntriesTable<APRSRecentEntries>::draw(
|
||||||
const Entry& entry,
|
const Entry& entry,
|
||||||
const Rect& target_rect,
|
const Rect& target_rect,
|
||||||
Painter& painter,
|
Painter& painter,
|
||||||
const Style& style
|
const Style& style) {
|
||||||
) {
|
|
||||||
char aged_color;
|
char aged_color;
|
||||||
Color target_color;
|
Color target_color;
|
||||||
// auto entry_age = entry.age;
|
// auto entry_age = entry.age;
|
||||||
|
@ -66,15 +65,13 @@ void RecentEntriesTable<APRSRecentEntries>::draw(
|
||||||
painter.draw_string(
|
painter.draw_string(
|
||||||
target_rect.location(),
|
target_rect.location(),
|
||||||
style,
|
style,
|
||||||
entry_string
|
entry_string);
|
||||||
);
|
|
||||||
|
|
||||||
if (entry.has_position) {
|
if (entry.has_position) {
|
||||||
painter.draw_bitmap(target_rect.location() + Point(12 * 8, 0), bitmap_target, target_color, style.background);
|
painter.draw_bitmap(target_rect.location() + Point(12 * 8, 0), bitmap_target, target_color, style.background);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void APRSRxView::focus() {
|
void APRSRxView::focus() {
|
||||||
options_region.focus();
|
options_region.focus();
|
||||||
}
|
}
|
||||||
|
@ -83,11 +80,11 @@ void APRSRxView::update_freq(rf::Frequency f) {
|
||||||
receiver_model.set_tuning_frequency(f);
|
receiver_model.set_tuning_frequency(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
APRSRxView::APRSRxView(NavigationView& nav, Rect parent_rect) : View(parent_rect) {
|
APRSRxView::APRSRxView(NavigationView& nav, Rect parent_rect)
|
||||||
|
: View(parent_rect) {
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_aprs_rx);
|
baseband::run_image(portapack::spi_flash::image_tag_aprs_rx);
|
||||||
|
|
||||||
add_children({
|
add_children({&rssi,
|
||||||
&rssi,
|
|
||||||
&channel,
|
&channel,
|
||||||
&field_rf_amp,
|
&field_rf_amp,
|
||||||
&field_lna,
|
&field_lna,
|
||||||
|
@ -95,8 +92,7 @@ APRSRxView::APRSRxView(NavigationView& nav, Rect parent_rect) : View(parent_rect
|
||||||
&options_region,
|
&options_region,
|
||||||
&field_frequency,
|
&field_frequency,
|
||||||
&record_view,
|
&record_view,
|
||||||
&console
|
&console});
|
||||||
});
|
|
||||||
|
|
||||||
// load app settings
|
// load app settings
|
||||||
auto rc = settings.load("rx_aprs", &app_settings);
|
auto rc = settings.load("rx_aprs", &app_settings);
|
||||||
|
@ -106,7 +102,6 @@ APRSRxView::APRSRxView(NavigationView& nav, Rect parent_rect) : View(parent_rect
|
||||||
field_rf_amp.set_value(app_settings.rx_amp);
|
field_rf_amp.set_value(app_settings.rx_amp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// DEBUG
|
// DEBUG
|
||||||
record_view.on_error = [&nav](std::string message) {
|
record_view.on_error = [&nav](std::string message) {
|
||||||
nav.display_modal("Error", message);
|
nav.display_modal("Error", message);
|
||||||
|
@ -195,8 +190,7 @@ void APRSRxView::on_data(uint32_t value, bool is_data) {
|
||||||
logger->log_raw_data(str_log);
|
logger->log_raw_data(str_log);
|
||||||
str_log = "";
|
str_log = "";
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if ((value >= 32) && (value < 127)) {
|
if ((value >= 32) && (value < 127)) {
|
||||||
str_console += (char)value; // Printable
|
str_console += (char)value; // Printable
|
||||||
str_byte += (char)value;
|
str_byte += (char)value;
|
||||||
|
@ -210,7 +204,6 @@ void APRSRxView::on_data(uint32_t value, bool is_data) {
|
||||||
if (logger) str_log += str_byte;
|
if (logger) str_log += str_byte;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,7 +213,6 @@ void APRSRxView::on_show(){
|
||||||
}
|
}
|
||||||
|
|
||||||
APRSRxView::~APRSRxView() {
|
APRSRxView::~APRSRxView() {
|
||||||
|
|
||||||
// save app settings
|
// save app settings
|
||||||
settings.save("rx_aprs", &app_settings);
|
settings.save("rx_aprs", &app_settings);
|
||||||
|
|
||||||
|
@ -246,11 +238,10 @@ void APRSTableView::on_show_detail(const APRSRecentEntry& entry) {
|
||||||
send_updates = true;
|
send_updates = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
APRSTableView::APRSTableView(NavigationView& nav, Rect parent_rec) : View(parent_rec), nav_ {nav} {
|
APRSTableView::APRSTableView(NavigationView& nav, Rect parent_rec)
|
||||||
add_children({
|
: View(parent_rec), nav_{nav} {
|
||||||
&recent_entries_view,
|
add_children({&recent_entries_view,
|
||||||
&details_view
|
&details_view});
|
||||||
});
|
|
||||||
|
|
||||||
hidden(true);
|
hidden(true);
|
||||||
|
|
||||||
|
@ -267,7 +258,6 @@ APRSTableView::APRSTableView(NavigationView& nav, Rect parent_rec) : View(parent
|
||||||
this->on_show_list();
|
this->on_show_list();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* for(size_t i = 0; i <32 ; i++){
|
/* for(size_t i = 0; i <32 ; i++){
|
||||||
std::string id = "test" + i;
|
std::string id = "test" + i;
|
||||||
auto& entry = ::on_packet(recent, i);
|
auto& entry = ::on_packet(recent, i);
|
||||||
|
@ -315,8 +305,7 @@ void APRSTableView::on_pkt(const APRSPacketMessage* message){
|
||||||
|
|
||||||
if (entry.has_position && !packet.has_position()) {
|
if (entry.has_position && !packet.has_position()) {
|
||||||
// maintain position info
|
// maintain position info
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
entry.set_has_position(packet.has_position());
|
entry.set_has_position(packet.has_position());
|
||||||
entry.set_pos(packet.get_position());
|
entry.set_pos(packet.get_position());
|
||||||
}
|
}
|
||||||
|
@ -342,7 +331,6 @@ void APRSTableView::focus(){
|
||||||
}
|
}
|
||||||
|
|
||||||
APRSTableView::~APRSTableView() {
|
APRSTableView::~APRSTableView() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void APRSDetailsView::focus() {
|
void APRSDetailsView::focus() {
|
||||||
|
@ -371,14 +359,10 @@ APRSDetailsView::~APRSDetailsView() {
|
||||||
}
|
}
|
||||||
|
|
||||||
APRSDetailsView::APRSDetailsView(
|
APRSDetailsView::APRSDetailsView(
|
||||||
NavigationView& nav
|
NavigationView& nav) {
|
||||||
)
|
add_children({&console,
|
||||||
{
|
|
||||||
add_children({
|
|
||||||
&console,
|
|
||||||
&button_done,
|
&button_done,
|
||||||
&button_see_map
|
&button_see_map});
|
||||||
});
|
|
||||||
|
|
||||||
button_done.on_select = [this, &nav](Button&) {
|
button_done.on_select = [this, &nav](Button&) {
|
||||||
console.clear(true);
|
console.clear(true);
|
||||||
|
@ -400,16 +384,14 @@ APRSDetailsView::APRSDetailsView(
|
||||||
});
|
});
|
||||||
send_updates = true;
|
send_updates = true;
|
||||||
hidden(true);
|
hidden(true);
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
APRSRXView::APRSRXView(NavigationView& nav) : nav_ {nav} {
|
APRSRXView::APRSRXView(NavigationView& nav)
|
||||||
add_children({
|
: nav_{nav} {
|
||||||
&tab_view,
|
add_children({&tab_view,
|
||||||
&view_stream,
|
&view_stream,
|
||||||
&view_table
|
&view_table});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void APRSRXView::focus() {
|
void APRSRXView::focus() {
|
||||||
|
@ -417,6 +399,5 @@ void APRSRXView::focus(){
|
||||||
}
|
}
|
||||||
|
|
||||||
APRSRXView::~APRSRXView() {
|
APRSRXView::~APRSRXView() {
|
||||||
|
|
||||||
}
|
}
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -64,8 +64,7 @@ struct APRSRecentEntry {
|
||||||
|
|
||||||
aprs::aprs_pos pos{0, 0, 0, 0};
|
aprs::aprs_pos pos{0, 0, 0, 0};
|
||||||
bool has_position = false;
|
bool has_position = false;
|
||||||
APRSRecentEntry(uint64_t src)
|
APRSRecentEntry(uint64_t src) {
|
||||||
{
|
|
||||||
source = src;
|
source = src;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,20 +130,16 @@ private:
|
||||||
GeoMapView* geomap_view{nullptr};
|
GeoMapView* geomap_view{nullptr};
|
||||||
bool send_updates{false};
|
bool send_updates{false};
|
||||||
|
|
||||||
|
|
||||||
Console console{
|
Console console{
|
||||||
{ 0, 0 * 16, 240, 224 }
|
{0, 0 * 16, 240, 224}};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_done{
|
Button button_done{
|
||||||
{160, 14 * 16, 8 * 8, 3 * 16},
|
{160, 14 * 16, 8 * 8, 3 * 16},
|
||||||
"Close"
|
"Close"};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_see_map{
|
Button button_see_map{
|
||||||
{80, 14 * 16, 8 * 8, 3 * 16},
|
{80, 14 * 16, 8 * 8, 3 * 16},
|
||||||
"Map"
|
"Map"};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using APRSRecentEntries = RecentEntries<APRSRecentEntry>;
|
using APRSRecentEntries = RecentEntries<APRSRecentEntry>;
|
||||||
|
@ -160,14 +155,13 @@ public:
|
||||||
void on_pkt(const APRSPacketMessage* message);
|
void on_pkt(const APRSPacketMessage* message);
|
||||||
|
|
||||||
std::string title() const override { return "Stations"; };
|
std::string title() const override { return "Stations"; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NavigationView& nav_;
|
NavigationView& nav_;
|
||||||
const RecentEntriesColumns columns { {
|
const RecentEntriesColumns columns{{{"Source", 9},
|
||||||
{ "Source", 9 },
|
|
||||||
{"Loc", 6},
|
{"Loc", 6},
|
||||||
{"Hits", 4},
|
{"Hits", 4},
|
||||||
{ "Time", 8 }
|
{"Time", 8}}};
|
||||||
} };
|
|
||||||
APRSRecentEntries recent{};
|
APRSRecentEntries recent{};
|
||||||
RecentEntriesView<RecentEntries<APRSRecentEntry>> recent_entries_view{columns, recent};
|
RecentEntriesView<RecentEntries<APRSRecentEntry>> recent_entries_view{columns, recent};
|
||||||
APRSDetailsView details_view{nav_};
|
APRSDetailsView details_view{nav_};
|
||||||
|
@ -197,19 +191,15 @@ private:
|
||||||
std::app_settings settings{};
|
std::app_settings settings{};
|
||||||
std::app_settings::AppSettings app_settings{};
|
std::app_settings::AppSettings app_settings{};
|
||||||
|
|
||||||
|
|
||||||
uint8_t console_color{0};
|
uint8_t console_color{0};
|
||||||
std::string str_log{""};
|
std::string str_log{""};
|
||||||
|
|
||||||
RFAmpField field_rf_amp{
|
RFAmpField field_rf_amp{
|
||||||
{ 13 * 8, 0 * 16 }
|
{13 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
LNAGainField field_lna{
|
LNAGainField field_lna{
|
||||||
{ 15 * 8, 0 * 16 }
|
{15 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
VGAGainField field_vga{
|
VGAGainField field_vga{
|
||||||
{ 18 * 8, 0 * 16 }
|
{18 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
RSSI rssi{
|
RSSI rssi{
|
||||||
{21 * 8, 0, 6 * 8, 4},
|
{21 * 8, 0, 6 * 8, 4},
|
||||||
};
|
};
|
||||||
|
@ -220,13 +210,10 @@ private:
|
||||||
OptionsField options_region{
|
OptionsField options_region{
|
||||||
{0 * 8, 0 * 8},
|
{0 * 8, 0 * 8},
|
||||||
3,
|
3,
|
||||||
{
|
{{"NA ", 0},
|
||||||
{ "NA ", 0 },
|
|
||||||
{"EUR", 1},
|
{"EUR", 1},
|
||||||
{"AUS", 2},
|
{"AUS", 2},
|
||||||
{ "NZ ", 3 }
|
{"NZ ", 3}}};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
FrequencyField field_frequency{
|
FrequencyField field_frequency{
|
||||||
{3 * 8, 0 * 16},
|
{3 * 8, 0 * 16},
|
||||||
|
@ -235,12 +222,14 @@ private:
|
||||||
// DEBUG
|
// DEBUG
|
||||||
RecordView record_view{
|
RecordView record_view{
|
||||||
{0 * 8, 1 * 16, 30 * 8, 1 * 16},
|
{0 * 8, 1 * 16, 30 * 8, 1 * 16},
|
||||||
u"AFS_????.WAV", u"APRS", RecordView::FileType::WAV, 4096, 4
|
u"AFS_????.WAV",
|
||||||
};
|
u"APRS",
|
||||||
|
RecordView::FileType::WAV,
|
||||||
|
4096,
|
||||||
|
4};
|
||||||
|
|
||||||
Console console{
|
Console console{
|
||||||
{ 0, 2 * 16, 240, 240 }
|
{0, 2 * 16, 240, 240}};
|
||||||
};
|
|
||||||
|
|
||||||
void update_freq(rf::Frequency f);
|
void update_freq(rf::Frequency f);
|
||||||
|
|
||||||
|
@ -265,8 +254,7 @@ private:
|
||||||
|
|
||||||
TabView tab_view{
|
TabView tab_view{
|
||||||
{"Stream", Color::cyan(), &view_stream},
|
{"Stream", Color::cyan(), &view_stream},
|
||||||
{ "List", Color::yellow(), &view_table }
|
{"List", Color::yellow(), &view_table}};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_packet{
|
MessageHandlerRegistration message_handler_packet{
|
||||||
Message::ID::APRSPacket,
|
Message::ID::APRSPacket,
|
||||||
|
@ -274,8 +262,7 @@ private:
|
||||||
const auto message = static_cast<const APRSPacketMessage*>(p);
|
const auto message = static_cast<const APRSPacketMessage*>(p);
|
||||||
this->view_stream.on_packet(message);
|
this->view_stream.on_packet(message);
|
||||||
this->view_table.on_pkt(message);
|
this->view_table.on_pkt(message);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -73,8 +73,7 @@ void APRSTXView::start_tx() {
|
||||||
2200,
|
2200,
|
||||||
1,
|
1,
|
||||||
10000, // APRS uses fixed 10k bandwidth
|
10000, // APRS uses fixed 10k bandwidth
|
||||||
8
|
8);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void APRSTXView::on_tx_progress(const uint32_t progress, const bool done) {
|
void APRSTXView::on_tx_progress(const uint32_t progress, const bool done) {
|
||||||
|
@ -87,20 +86,16 @@ void APRSTXView::on_tx_progress(const uint32_t progress, const bool done) {
|
||||||
}
|
}
|
||||||
|
|
||||||
APRSTXView::APRSTXView(NavigationView& nav) {
|
APRSTXView::APRSTXView(NavigationView& nav) {
|
||||||
|
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_afsk);
|
baseband::run_image(portapack::spi_flash::image_tag_afsk);
|
||||||
|
|
||||||
add_children({
|
add_children({&labels,
|
||||||
&labels,
|
|
||||||
&sym_source,
|
&sym_source,
|
||||||
&num_ssid_source,
|
&num_ssid_source,
|
||||||
&sym_dest,
|
&sym_dest,
|
||||||
&num_ssid_dest,
|
&num_ssid_dest,
|
||||||
&text_payload,
|
&text_payload,
|
||||||
&button_set,
|
&button_set,
|
||||||
&tx_view
|
&tx_view});
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// load app settings
|
// load app settings
|
||||||
auto rc = settings.load("tx_aprs", &app_settings);
|
auto rc = settings.load("tx_aprs", &app_settings);
|
||||||
|
@ -117,8 +112,7 @@ APRSTXView::APRSTXView(NavigationView& nav) {
|
||||||
30,
|
30,
|
||||||
[this](std::string& s) {
|
[this](std::string& s) {
|
||||||
text_payload.set(s);
|
text_payload.set(s);
|
||||||
}
|
});
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
tx_view.on_edit_frequency = [this, &nav]() {
|
tx_view.on_edit_frequency = [this, &nav]() {
|
||||||
|
|
|
@ -44,7 +44,6 @@ public:
|
||||||
std::string title() const override { return "APRS TX"; };
|
std::string title() const override { return "APRS TX"; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// app save settings
|
// app save settings
|
||||||
std::app_settings settings{};
|
std::app_settings settings{};
|
||||||
std::app_settings::AppSettings app_settings{};
|
std::app_settings::AppSettings app_settings{};
|
||||||
|
@ -65,38 +64,32 @@ private:
|
||||||
SymField sym_source{
|
SymField sym_source{
|
||||||
{7 * 8, 1 * 16},
|
{7 * 8, 1 * 16},
|
||||||
6,
|
6,
|
||||||
SymField::SYMFIELD_ALPHANUM
|
SymField::SYMFIELD_ALPHANUM};
|
||||||
};
|
|
||||||
NumberField num_ssid_source{
|
NumberField num_ssid_source{
|
||||||
{19 * 8, 1 * 16},
|
{19 * 8, 1 * 16},
|
||||||
2,
|
2,
|
||||||
{0, 15},
|
{0, 15},
|
||||||
1,
|
1,
|
||||||
' '
|
' '};
|
||||||
};
|
|
||||||
|
|
||||||
SymField sym_dest{
|
SymField sym_dest{
|
||||||
{7 * 8, 2 * 16},
|
{7 * 8, 2 * 16},
|
||||||
6,
|
6,
|
||||||
SymField::SYMFIELD_ALPHANUM
|
SymField::SYMFIELD_ALPHANUM};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField num_ssid_dest{
|
NumberField num_ssid_dest{
|
||||||
{19 * 8, 2 * 16},
|
{19 * 8, 2 * 16},
|
||||||
2,
|
2,
|
||||||
{0, 15},
|
{0, 15},
|
||||||
1,
|
1,
|
||||||
' '
|
' '};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_payload{
|
Text text_payload{
|
||||||
{0 * 8, 5 * 16, 30 * 8, 16},
|
{0 * 8, 5 * 16, 30 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
Button button_set{
|
Button button_set{
|
||||||
{0 * 8, 6 * 16, 80, 32},
|
{0 * 8, 6 * 16, 80, 32},
|
||||||
"Set"
|
"Set"};
|
||||||
};
|
|
||||||
|
|
||||||
TransmitterView tx_view{
|
TransmitterView tx_view{
|
||||||
16 * 16,
|
16 * 16,
|
||||||
|
@ -109,8 +102,7 @@ private:
|
||||||
[this](const Message* const p) {
|
[this](const Message* const p) {
|
||||||
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
|
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
|
||||||
this->on_tx_progress(message.progress, message.done);
|
this->on_tx_progress(message.progress, message.done);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -41,7 +41,6 @@ void BHTView::start_tx() {
|
||||||
transmitter_model.set_baseband_bandwidth(1750000);
|
transmitter_model.set_baseband_bandwidth(1750000);
|
||||||
|
|
||||||
if (target_system == XYLOS) {
|
if (target_system == XYLOS) {
|
||||||
|
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_tones);
|
baseband::run_image(portapack::spi_flash::image_tag_tones);
|
||||||
|
|
||||||
view_xylos.generate_message();
|
view_xylos.generate_message();
|
||||||
|
@ -62,7 +61,6 @@ void BHTView::start_tx() {
|
||||||
baseband::set_tones_config(transmitter_model.channel_bandwidth(), XY_SILENCE, XY_TONE_COUNT, false, false);
|
baseband::set_tones_config(transmitter_model.channel_bandwidth(), XY_SILENCE, XY_TONE_COUNT, false, false);
|
||||||
|
|
||||||
} else if (target_system == EPAR) {
|
} else if (target_system == EPAR) {
|
||||||
|
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_ook);
|
baseband::run_image(portapack::spi_flash::image_tag_ook);
|
||||||
|
|
||||||
auto bitstream_length = view_EPAR.generate_message();
|
auto bitstream_length = view_EPAR.generate_message();
|
||||||
|
@ -80,8 +78,7 @@ void BHTView::start_tx() {
|
||||||
bitstream_length,
|
bitstream_length,
|
||||||
EPAR_BIT_DURATION,
|
EPAR_BIT_DURATION,
|
||||||
EPAR_REPEAT_COUNT,
|
EPAR_REPEAT_COUNT,
|
||||||
encoder_defs[ENCODER_UM3750].pause_symbols
|
encoder_defs[ENCODER_UM3750].pause_symbols);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +111,6 @@ void BHTView::on_tx_progress(const uint32_t progress, const bool done) {
|
||||||
progressbar.set_value(progress);
|
progressbar.set_value(progress);
|
||||||
} else if (target_system == EPAR) {
|
} else if (target_system == EPAR) {
|
||||||
if (done) {
|
if (done) {
|
||||||
|
|
||||||
if (!view_EPAR.half) {
|
if (!view_EPAR.half) {
|
||||||
view_EPAR.half = true;
|
view_EPAR.half = true;
|
||||||
start_tx(); // Start second half of transmission
|
start_tx(); // Start second half of transmission
|
||||||
|
@ -151,8 +147,7 @@ BHTView::~BHTView() {
|
||||||
}
|
}
|
||||||
|
|
||||||
BHTView::BHTView(NavigationView& nav) {
|
BHTView::BHTView(NavigationView& nav) {
|
||||||
add_children({
|
add_children({&tab_view,
|
||||||
&tab_view,
|
|
||||||
&labels,
|
&labels,
|
||||||
&view_xylos,
|
&view_xylos,
|
||||||
&view_EPAR,
|
&view_EPAR,
|
||||||
|
@ -160,8 +155,7 @@ BHTView::BHTView(NavigationView& nav) {
|
||||||
&checkbox_flashing,
|
&checkbox_flashing,
|
||||||
&field_speed,
|
&field_speed,
|
||||||
&progressbar,
|
&progressbar,
|
||||||
&tx_view
|
&tx_view});
|
||||||
});
|
|
||||||
|
|
||||||
// load app settings
|
// load app settings
|
||||||
auto rc = settings.load("tx_bht", &app_settings);
|
auto rc = settings.load("tx_bht", &app_settings);
|
||||||
|
@ -229,16 +223,13 @@ size_t EPARView::generate_message() {
|
||||||
}
|
}
|
||||||
|
|
||||||
EPARView::EPARView(
|
EPARView::EPARView(
|
||||||
Rect parent_rect
|
Rect parent_rect)
|
||||||
) : View(parent_rect) {
|
: View(parent_rect) {
|
||||||
|
|
||||||
hidden(true);
|
hidden(true);
|
||||||
|
|
||||||
add_children({
|
add_children({&labels,
|
||||||
&labels,
|
|
||||||
&field_city,
|
&field_city,
|
||||||
&field_group
|
&field_group});
|
||||||
});
|
|
||||||
|
|
||||||
field_city.set_value(0);
|
field_city.set_value(0);
|
||||||
field_group.set_selected_index(2);
|
field_group.set_selected_index(2);
|
||||||
|
@ -253,11 +244,9 @@ EPARView::EPARView(
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
for (auto& relay_state : relay_states) {
|
for (auto& relay_state : relay_states) {
|
||||||
relay_state.on_change = relay_state_fn;
|
relay_state.on_change = relay_state_fn;
|
||||||
relay_state.set_parent_rect({
|
relay_state.set_parent_rect({static_cast<Coord>(90 + (n * 36)),
|
||||||
static_cast<Coord>(90 + (n * 36)),
|
|
||||||
80,
|
80,
|
||||||
24, 24
|
24, 24});
|
||||||
});
|
|
||||||
relay_state.set_options(relay_options);
|
relay_state.set_options(relay_options);
|
||||||
add_child(&relay_state);
|
add_child(&relay_state);
|
||||||
n++;
|
n++;
|
||||||
|
@ -298,9 +287,8 @@ void XylosView::generate_message() {
|
||||||
}
|
}
|
||||||
|
|
||||||
XylosView::XylosView(
|
XylosView::XylosView(
|
||||||
Rect parent_rect
|
Rect parent_rect)
|
||||||
) : View(parent_rect) {
|
: View(parent_rect) {
|
||||||
|
|
||||||
hidden(true);
|
hidden(true);
|
||||||
|
|
||||||
add_children({
|
add_children({
|
||||||
|
@ -354,11 +342,9 @@ XylosView::XylosView(
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
for (auto& relay_state : relay_states) {
|
for (auto& relay_state : relay_states) {
|
||||||
relay_state.on_change = relay_state_fn;
|
relay_state.on_change = relay_state_fn;
|
||||||
relay_state.set_parent_rect({
|
relay_state.set_parent_rect({static_cast<Coord>(54 + (n * 36)),
|
||||||
static_cast<Coord>(54 + (n * 36)),
|
|
||||||
134,
|
134,
|
||||||
24, 24
|
24, 24});
|
||||||
});
|
|
||||||
relay_state.set_options(relay_options);
|
relay_state.set_options(relay_options);
|
||||||
add_child(&relay_state);
|
add_child(&relay_state);
|
||||||
n++;
|
n++;
|
||||||
|
|
|
@ -55,74 +55,64 @@ private:
|
||||||
{{7 * 8, 5 * 8}, "Family:", Color::light_grey()},
|
{{7 * 8, 5 * 8}, "Family:", Color::light_grey()},
|
||||||
{{2 * 8, 7 * 8 + 2}, "Subfamily:", Color::light_grey()},
|
{{2 * 8, 7 * 8 + 2}, "Subfamily:", Color::light_grey()},
|
||||||
{{2 * 8, 11 * 8}, "Receiver ID:", Color::light_grey()},
|
{{2 * 8, 11 * 8}, "Receiver ID:", Color::light_grey()},
|
||||||
{ { 2 * 8, 14 * 8 }, "Relay:", Color::light_grey() }
|
{{2 * 8, 14 * 8}, "Relay:", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_header_a{
|
NumberField field_header_a{
|
||||||
{16 * 8, 1 * 8},
|
{16 * 8, 1 * 8},
|
||||||
2,
|
2,
|
||||||
{0, 99},
|
{0, 99},
|
||||||
1,
|
1,
|
||||||
'0'
|
'0'};
|
||||||
};
|
|
||||||
NumberField field_header_b{
|
NumberField field_header_b{
|
||||||
{18 * 8, 1 * 8},
|
{18 * 8, 1 * 8},
|
||||||
2,
|
2,
|
||||||
{0, 99},
|
{0, 99},
|
||||||
1,
|
1,
|
||||||
'0'
|
'0'};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_city{
|
NumberField field_city{
|
||||||
{16 * 8, 3 * 8},
|
{16 * 8, 3 * 8},
|
||||||
2,
|
2,
|
||||||
{0, XY_MAX_CITY},
|
{0, XY_MAX_CITY},
|
||||||
1,
|
1,
|
||||||
' '
|
' '};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_family{
|
NumberField field_family{
|
||||||
{16 * 8, 5 * 8},
|
{16 * 8, 5 * 8},
|
||||||
1,
|
1,
|
||||||
{0, 9},
|
{0, 9},
|
||||||
1,
|
1,
|
||||||
' '
|
' '};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_subfamily{
|
NumberField field_subfamily{
|
||||||
{16 * 8, 7 * 8 + 2},
|
{16 * 8, 7 * 8 + 2},
|
||||||
1,
|
1,
|
||||||
{0, 9},
|
{0, 9},
|
||||||
1,
|
1,
|
||||||
' '
|
' '};
|
||||||
};
|
|
||||||
|
|
||||||
Checkbox checkbox_wcsubfamily{
|
Checkbox checkbox_wcsubfamily{
|
||||||
{20 * 8, 6 * 8 + 6},
|
{20 * 8, 6 * 8 + 6},
|
||||||
3,
|
3,
|
||||||
"All"
|
"All"};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_receiver{
|
NumberField field_receiver{
|
||||||
{16 * 8, 11 * 8},
|
{16 * 8, 11 * 8},
|
||||||
2,
|
2,
|
||||||
{0, 99},
|
{0, 99},
|
||||||
1,
|
1,
|
||||||
'0'
|
'0'};
|
||||||
};
|
|
||||||
Checkbox checkbox_wcid{
|
Checkbox checkbox_wcid{
|
||||||
{20 * 8, 10 * 8 + 4},
|
{20 * 8, 10 * 8 + 4},
|
||||||
3,
|
3,
|
||||||
"All"
|
"All"};
|
||||||
};
|
|
||||||
|
|
||||||
std::array<ImageOptionsField, 4> relay_states{};
|
std::array<ImageOptionsField, 4> relay_states{};
|
||||||
|
|
||||||
ImageOptionsField::options_t relay_options = {
|
ImageOptionsField::options_t relay_options = {
|
||||||
{&bitmap_bulb_ignore, 0},
|
{&bitmap_bulb_ignore, 0},
|
||||||
{&bitmap_bulb_off, 1},
|
{&bitmap_bulb_off, 1},
|
||||||
{ &bitmap_bulb_on, 2 }
|
{&bitmap_bulb_on, 2}};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class EPARView : public View {
|
class EPARView : public View {
|
||||||
|
@ -142,34 +132,28 @@ private:
|
||||||
Labels labels{
|
Labels labels{
|
||||||
{{4 * 8, 1 * 8}, "City code:", Color::light_grey()},
|
{{4 * 8, 1 * 8}, "City code:", Color::light_grey()},
|
||||||
{{8 * 8, 3 * 8}, "Group:", Color::light_grey()},
|
{{8 * 8, 3 * 8}, "Group:", Color::light_grey()},
|
||||||
{ { 8 * 8, 7 * 8 }, "Relay:", Color::light_grey() }
|
{{8 * 8, 7 * 8}, "Relay:", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_city{
|
NumberField field_city{
|
||||||
{16 * 8, 1 * 8},
|
{16 * 8, 1 * 8},
|
||||||
3,
|
3,
|
||||||
{0, EPAR_MAX_CITY},
|
{0, EPAR_MAX_CITY},
|
||||||
1,
|
1,
|
||||||
'0'
|
'0'};
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField field_group{
|
OptionsField field_group{
|
||||||
{16 * 8, 3 * 8},
|
{16 * 8, 3 * 8},
|
||||||
2,
|
2,
|
||||||
{
|
{{"A ", 2}, // See receiver PCB
|
||||||
{ "A ", 2 }, // See receiver PCB
|
|
||||||
{"B ", 1},
|
{"B ", 1},
|
||||||
{"C ", 0},
|
{"C ", 0},
|
||||||
{ "TP", 3 }
|
{"TP", 3}}};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
std::array<ImageOptionsField, 2> relay_states{};
|
std::array<ImageOptionsField, 2> relay_states{};
|
||||||
|
|
||||||
ImageOptionsField::options_t relay_options = {
|
ImageOptionsField::options_t relay_options = {
|
||||||
{&bitmap_bulb_off, 0},
|
{&bitmap_bulb_off, 0},
|
||||||
{ &bitmap_bulb_on, 1 }
|
{&bitmap_bulb_on, 1}};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class BHTView : public View {
|
class BHTView : public View {
|
||||||
|
@ -212,31 +196,26 @@ private:
|
||||||
|
|
||||||
TabView tab_view{
|
TabView tab_view{
|
||||||
{"Xylos", Color::cyan(), &view_xylos},
|
{"Xylos", Color::cyan(), &view_xylos},
|
||||||
{ "EPAR", Color::green(), &view_EPAR }
|
{"EPAR", Color::green(), &view_EPAR}};
|
||||||
};
|
|
||||||
|
|
||||||
Labels labels{
|
Labels labels{
|
||||||
{ { 29 * 8, 14 * 16 + 4 }, "s", Color::light_grey() }
|
{{29 * 8, 14 * 16 + 4}, "s", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
Checkbox checkbox_scan{
|
Checkbox checkbox_scan{
|
||||||
{1 * 8, 25 * 8},
|
{1 * 8, 25 * 8},
|
||||||
4,
|
4,
|
||||||
"Scan"
|
"Scan"};
|
||||||
};
|
|
||||||
|
|
||||||
Checkbox checkbox_flashing{
|
Checkbox checkbox_flashing{
|
||||||
{16 * 8, 25 * 8},
|
{16 * 8, 25 * 8},
|
||||||
8,
|
8,
|
||||||
"Flashing"
|
"Flashing"};
|
||||||
};
|
|
||||||
NumberField field_speed{
|
NumberField field_speed{
|
||||||
{26 * 8, 25 * 8 + 4},
|
{26 * 8, 25 * 8 + 4},
|
||||||
2,
|
2,
|
||||||
{1, 99},
|
{1, 99},
|
||||||
1,
|
1,
|
||||||
' '
|
' '};
|
||||||
};
|
|
||||||
|
|
||||||
ProgressBar progressbar{
|
ProgressBar progressbar{
|
||||||
{0 * 8, 29 * 8, 30 * 8, 16},
|
{0 * 8, 29 * 8, 30 * 8, 16},
|
||||||
|
@ -245,16 +224,14 @@ private:
|
||||||
TransmitterView tx_view{
|
TransmitterView tx_view{
|
||||||
16 * 16,
|
16 * 16,
|
||||||
10000,
|
10000,
|
||||||
12
|
12};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_tx_progress{
|
MessageHandlerRegistration message_handler_tx_progress{
|
||||||
Message::ID::TXProgress,
|
Message::ID::TXProgress,
|
||||||
[this](const Message* const p) {
|
[this](const Message* const p) {
|
||||||
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
|
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
|
||||||
this->on_tx_progress(message.progress, message.done);
|
this->on_tx_progress(message.progress, message.done);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -47,16 +47,14 @@ void BTLERxView::update_freq(rf::Frequency f) {
|
||||||
BTLERxView::BTLERxView(NavigationView& nav) {
|
BTLERxView::BTLERxView(NavigationView& nav) {
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_btle_rx);
|
baseband::run_image(portapack::spi_flash::image_tag_btle_rx);
|
||||||
|
|
||||||
add_children({
|
add_children({&rssi,
|
||||||
&rssi,
|
|
||||||
&channel,
|
&channel,
|
||||||
&field_rf_amp,
|
&field_rf_amp,
|
||||||
&field_lna,
|
&field_lna,
|
||||||
&field_vga,
|
&field_vga,
|
||||||
&field_frequency,
|
&field_frequency,
|
||||||
&button_modem_setup,
|
&button_modem_setup,
|
||||||
&console
|
&console});
|
||||||
});
|
|
||||||
|
|
||||||
// load app settings
|
// load app settings
|
||||||
auto rc = settings.load("rx_btle", &app_settings);
|
auto rc = settings.load("rx_btle", &app_settings);
|
||||||
|
@ -129,8 +127,6 @@ void BTLERxView::on_data(uint32_t value, bool is_data) {
|
||||||
str_console += ":" + to_string_hex(value, 2);
|
str_console += ":" + to_string_hex(value, 2);
|
||||||
console.write(str_console);
|
console.write(str_console);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*if ((value != 0x7F) && (prev_value == 0x7F)) {
|
/*if ((value != 0x7F) && (prev_value == 0x7F)) {
|
||||||
// Message split
|
// Message split
|
||||||
console.writeln("");
|
console.writeln("");
|
||||||
|
@ -142,16 +138,16 @@ void BTLERxView::on_data(uint32_t value, bool is_data) {
|
||||||
} else {
|
} else {
|
||||||
// Baudrate estimation
|
// Baudrate estimation
|
||||||
// text_debug.set("~" + to_string_dec_uint(value));
|
// text_debug.set("~" + to_string_dec_uint(value));
|
||||||
if (value == 'A')
|
if (value == 'A') {
|
||||||
{console.write("mac");}
|
console.write("mac");
|
||||||
else if (value == 'B')
|
} else if (value == 'B') {
|
||||||
{console.writeln("");}
|
console.writeln("");
|
||||||
|
}
|
||||||
// console.writeln("");
|
// console.writeln("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BTLERxView::~BTLERxView() {
|
BTLERxView::~BTLERxView() {
|
||||||
|
|
||||||
// save app settings
|
// save app settings
|
||||||
app_settings.rx_frequency = field_frequency.value();
|
app_settings.rx_frequency = field_frequency.value();
|
||||||
settings.save("rx_btle", &app_settings);
|
settings.save("rx_btle", &app_settings);
|
||||||
|
|
|
@ -46,7 +46,6 @@ public:
|
||||||
private:
|
private:
|
||||||
void on_data(uint32_t value, bool is_data);
|
void on_data(uint32_t value, bool is_data);
|
||||||
|
|
||||||
|
|
||||||
// app save settings
|
// app save settings
|
||||||
std::app_settings settings{};
|
std::app_settings settings{};
|
||||||
std::app_settings::AppSettings app_settings{};
|
std::app_settings::AppSettings app_settings{};
|
||||||
|
@ -55,14 +54,11 @@ private:
|
||||||
uint32_t prev_value{0};
|
uint32_t prev_value{0};
|
||||||
|
|
||||||
RFAmpField field_rf_amp{
|
RFAmpField field_rf_amp{
|
||||||
{ 13 * 8, 0 * 16 }
|
{13 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
LNAGainField field_lna{
|
LNAGainField field_lna{
|
||||||
{ 15 * 8, 0 * 16 }
|
{15 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
VGAGainField field_vga{
|
VGAGainField field_vga{
|
||||||
{ 18 * 8, 0 * 16 }
|
{18 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
RSSI rssi{
|
RSSI rssi{
|
||||||
{21 * 8, 0, 6 * 8, 4},
|
{21 * 8, 0, 6 * 8, 4},
|
||||||
};
|
};
|
||||||
|
@ -76,12 +72,10 @@ private:
|
||||||
|
|
||||||
Button button_modem_setup{
|
Button button_modem_setup{
|
||||||
{240 - 12 * 8, 1 * 16, 96, 24},
|
{240 - 12 * 8, 1 * 16, 96, 24},
|
||||||
"Modem setup"
|
"Modem setup"};
|
||||||
};
|
|
||||||
|
|
||||||
Console console{
|
Console console{
|
||||||
{ 0, 4 * 16, 240, 240 }
|
{0, 4 * 16, 240, 240}};
|
||||||
};
|
|
||||||
|
|
||||||
void update_freq(rf::Frequency f);
|
void update_freq(rf::Frequency f);
|
||||||
// void on_data_afsk(const AFSKDataMessage& message);
|
// void on_data_afsk(const AFSKDataMessage& message);
|
||||||
|
@ -91,8 +85,7 @@ private:
|
||||||
[this](Message* const p) {
|
[this](Message* const p) {
|
||||||
const auto message = static_cast<const AFSKDataMessage*>(p);
|
const auto message = static_cast<const AFSKDataMessage*>(p);
|
||||||
this->on_data(message->value, message->is_data);
|
this->on_data(message->value, message->is_data);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -117,13 +117,11 @@ CoasterPagerView::CoasterPagerView(NavigationView& nav) {
|
||||||
|
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_fsktx);
|
baseband::run_image(portapack::spi_flash::image_tag_fsktx);
|
||||||
|
|
||||||
add_children({
|
add_children({&labels,
|
||||||
&labels,
|
|
||||||
&sym_data,
|
&sym_data,
|
||||||
&checkbox_scan,
|
&checkbox_scan,
|
||||||
&text_message,
|
&text_message,
|
||||||
&tx_view
|
&tx_view});
|
||||||
});
|
|
||||||
|
|
||||||
// load app settings
|
// load app settings
|
||||||
auto rc = settings.load("tx_coaster", &app_settings);
|
auto rc = settings.load("tx_coaster", &app_settings);
|
||||||
|
|
|
@ -61,42 +61,36 @@ private:
|
||||||
|
|
||||||
Labels labels{
|
Labels labels{
|
||||||
{{1 * 8, 3 * 8}, "Syscall pager TX beta", Color::light_grey()},
|
{{1 * 8, 3 * 8}, "Syscall pager TX beta", Color::light_grey()},
|
||||||
{ { 1 * 8, 8 * 8 }, "Data:", Color::light_grey() }
|
{{1 * 8, 8 * 8}, "Data:", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
SymField sym_data{
|
SymField sym_data{
|
||||||
{7 * 8, 8 * 8},
|
{7 * 8, 8 * 8},
|
||||||
16, // 14 ? 12 ?
|
16, // 14 ? 12 ?
|
||||||
SymField::SYMFIELD_HEX
|
SymField::SYMFIELD_HEX};
|
||||||
};
|
|
||||||
|
|
||||||
Checkbox checkbox_scan{
|
Checkbox checkbox_scan{
|
||||||
{10 * 8, 14 * 8},
|
{10 * 8, 14 * 8},
|
||||||
4,
|
4,
|
||||||
"Scan"
|
"Scan"};
|
||||||
};
|
|
||||||
|
|
||||||
/*ProgressBar progressbar {
|
/*ProgressBar progressbar {
|
||||||
{ 5 * 8, 12 * 16, 20 * 8, 16 },
|
{ 5 * 8, 12 * 16, 20 * 8, 16 },
|
||||||
};*/
|
};*/
|
||||||
Text text_message{
|
Text text_message{
|
||||||
{5 * 8, 13 * 16, 20 * 8, 16},
|
{5 * 8, 13 * 16, 20 * 8, 16},
|
||||||
""
|
""};
|
||||||
};
|
|
||||||
|
|
||||||
TransmitterView tx_view{
|
TransmitterView tx_view{
|
||||||
16 * 16,
|
16 * 16,
|
||||||
10000,
|
10000,
|
||||||
12
|
12};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_tx_progress{
|
MessageHandlerRegistration message_handler_tx_progress{
|
||||||
Message::ID::TXProgress,
|
Message::ID::TXProgress,
|
||||||
[this](const Message* const p) {
|
[this](const Message* const p) {
|
||||||
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
|
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
|
||||||
this->on_tx_progress(message.progress, message.done);
|
this->on_tx_progress(message.progress, message.done);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -41,16 +41,14 @@ namespace ui {
|
||||||
/* DebugMemoryView *******************************************************/
|
/* DebugMemoryView *******************************************************/
|
||||||
|
|
||||||
DebugMemoryView::DebugMemoryView(NavigationView& nav) {
|
DebugMemoryView::DebugMemoryView(NavigationView& nav) {
|
||||||
add_children({
|
add_children({&text_title,
|
||||||
&text_title,
|
|
||||||
&text_label_m0_core_free,
|
&text_label_m0_core_free,
|
||||||
&text_label_m0_core_free_value,
|
&text_label_m0_core_free_value,
|
||||||
&text_label_m0_heap_fragmented_free,
|
&text_label_m0_heap_fragmented_free,
|
||||||
&text_label_m0_heap_fragmented_free_value,
|
&text_label_m0_heap_fragmented_free_value,
|
||||||
&text_label_m0_heap_fragments,
|
&text_label_m0_heap_fragments,
|
||||||
&text_label_m0_heap_fragments_value,
|
&text_label_m0_heap_fragments_value,
|
||||||
&button_done
|
&button_done});
|
||||||
});
|
|
||||||
|
|
||||||
const auto m0_core_free = chCoreStatus();
|
const auto m0_core_free = chCoreStatus();
|
||||||
text_label_m0_core_free_value.set(to_string_dec_uint(m0_core_free, 5));
|
text_label_m0_core_free_value.set(to_string_dec_uint(m0_core_free, 5));
|
||||||
|
@ -80,12 +78,10 @@ void TemperatureWidget::paint(Painter& painter) {
|
||||||
const auto graph_width = static_cast<int>(logger.capacity()) * bar_width;
|
const auto graph_width = static_cast<int>(logger.capacity()) * bar_width;
|
||||||
const Rect graph_rect{
|
const Rect graph_rect{
|
||||||
rect.left() + (rect.width() - graph_width) / 2, rect.top() + 8,
|
rect.left() + (rect.width() - graph_width) / 2, rect.top() + 8,
|
||||||
graph_width, rect.height()
|
graph_width, rect.height()};
|
||||||
};
|
|
||||||
const Rect frame_rect{
|
const Rect frame_rect{
|
||||||
graph_rect.left() - 1, graph_rect.top() - 1,
|
graph_rect.left() - 1, graph_rect.top() - 1,
|
||||||
graph_rect.width() + 2, graph_rect.height() + 2
|
graph_rect.width() + 2, graph_rect.height() + 2};
|
||||||
};
|
|
||||||
painter.draw_rectangle(frame_rect, color_reticle);
|
painter.draw_rectangle(frame_rect, color_reticle);
|
||||||
painter.fill_rectangle(graph_rect, color_background);
|
painter.fill_rectangle(graph_rect, color_background);
|
||||||
|
|
||||||
|
@ -132,8 +128,7 @@ std::string TemperatureWidget::temperature_str(const temperature_t temperature)
|
||||||
|
|
||||||
Coord TemperatureWidget::screen_y(
|
Coord TemperatureWidget::screen_y(
|
||||||
const temperature_t temperature,
|
const temperature_t temperature,
|
||||||
const Rect& rect
|
const Rect& rect) const {
|
||||||
) const {
|
|
||||||
int y_raw = rect.bottom() - ((temperature - display_temp_min) * display_temp_scale);
|
int y_raw = rect.bottom() - ((temperature - display_temp_min) * display_temp_scale);
|
||||||
const auto y_limit = std::min(rect.bottom(), std::max(rect.top(), y_raw));
|
const auto y_limit = std::min(rect.bottom(), std::max(rect.top(), y_raw));
|
||||||
return y_limit;
|
return y_limit;
|
||||||
|
@ -159,11 +154,10 @@ void TemperatureView::focus() {
|
||||||
|
|
||||||
RegistersWidget::RegistersWidget(
|
RegistersWidget::RegistersWidget(
|
||||||
RegistersWidgetConfig&& config,
|
RegistersWidgetConfig&& config,
|
||||||
std::function<uint32_t(const size_t register_number)>&& reader
|
std::function<uint32_t(const size_t register_number)>&& reader)
|
||||||
) : Widget { },
|
: Widget{},
|
||||||
config(std::move(config)),
|
config(std::move(config)),
|
||||||
reader(std::move(reader))
|
reader(std::move(reader)) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegistersWidget::update() {
|
void RegistersWidget::update() {
|
||||||
|
@ -182,29 +176,25 @@ void RegistersWidget::draw_legend(const Coord left, Painter& painter) {
|
||||||
|
|
||||||
for (size_t i = 0; i < config.registers_count; i += config.registers_per_row()) {
|
for (size_t i = 0; i < config.registers_count; i += config.registers_per_row()) {
|
||||||
const Point offset{
|
const Point offset{
|
||||||
left, static_cast<int>((i / config.registers_per_row()) * row_height)
|
left, static_cast<int>((i / config.registers_per_row()) * row_height)};
|
||||||
};
|
|
||||||
|
|
||||||
const auto text = to_string_hex(i, config.legend_length());
|
const auto text = to_string_hex(i, config.legend_length());
|
||||||
painter.draw_string(
|
painter.draw_string(
|
||||||
pos + offset,
|
pos + offset,
|
||||||
style().invert(),
|
style().invert(),
|
||||||
text
|
text);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegistersWidget::draw_values(
|
void RegistersWidget::draw_values(
|
||||||
const Coord left,
|
const Coord left,
|
||||||
Painter& painter
|
Painter& painter) {
|
||||||
) {
|
|
||||||
const auto pos = screen_pos();
|
const auto pos = screen_pos();
|
||||||
|
|
||||||
for (size_t i = 0; i < config.registers_count; i++) {
|
for (size_t i = 0; i < config.registers_count; i++) {
|
||||||
const Point offset = {
|
const Point offset = {
|
||||||
static_cast<int>(left + config.legend_width() + 8 + (i % config.registers_per_row()) * (config.value_width() + 8)),
|
static_cast<int>(left + config.legend_width() + 8 + (i % config.registers_per_row()) * (config.value_width() + 8)),
|
||||||
static_cast<int>((i / config.registers_per_row()) * row_height)
|
static_cast<int>((i / config.registers_per_row()) * row_height)};
|
||||||
};
|
|
||||||
|
|
||||||
const auto value = reader(i);
|
const auto value = reader(i);
|
||||||
|
|
||||||
|
@ -212,8 +202,7 @@ void RegistersWidget::draw_values(
|
||||||
painter.draw_string(
|
painter.draw_string(
|
||||||
pos + offset,
|
pos + offset,
|
||||||
style(),
|
style(),
|
||||||
text
|
text);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,9 +212,8 @@ RegistersView::RegistersView(
|
||||||
NavigationView& nav,
|
NavigationView& nav,
|
||||||
const std::string& title,
|
const std::string& title,
|
||||||
RegistersWidgetConfig&& config,
|
RegistersWidgetConfig&& config,
|
||||||
std::function<uint32_t(const size_t register_number)>&& reader
|
std::function<uint32_t(const size_t register_number)>&& reader)
|
||||||
) : registers_widget { std::move(config), std::move(reader) }
|
: registers_widget{std::move(config), std::move(reader)} {
|
||||||
{
|
|
||||||
add_children({
|
add_children({
|
||||||
&text_title,
|
&text_title,
|
||||||
®isters_widget,
|
®isters_widget,
|
||||||
|
@ -240,10 +228,8 @@ RegistersView::RegistersView(
|
||||||
|
|
||||||
registers_widget.set_parent_rect({0, 48, 240, 192});
|
registers_widget.set_parent_rect({0, 48, 240, 192});
|
||||||
|
|
||||||
text_title.set_parent_rect({
|
text_title.set_parent_rect({(240 - static_cast<int>(title.size()) * 8) / 2, 16,
|
||||||
(240 - static_cast<int>(title.size()) * 8) / 2, 16,
|
static_cast<int>(title.size()) * 8, 16});
|
||||||
static_cast<int>(title.size()) * 8, 16
|
|
||||||
});
|
|
||||||
text_title.set(title);
|
text_title.set(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,8 +242,7 @@ void RegistersView::focus() {
|
||||||
void ControlsSwitchesWidget::on_show() {
|
void ControlsSwitchesWidget::on_show() {
|
||||||
display.fill_rectangle(
|
display.fill_rectangle(
|
||||||
screen_rect(),
|
screen_rect(),
|
||||||
Color::black()
|
Color::black());
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ControlsSwitchesWidget::on_key(const KeyEvent key) {
|
bool ControlsSwitchesWidget::on_key(const KeyEvent key) {
|
||||||
|
@ -365,20 +350,16 @@ DebugPeripheralsMenuView::DebugPeripheralsMenuView(NavigationView& nav) {
|
||||||
add_items({
|
add_items({
|
||||||
{"RFFC5072", ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [&nav]() { nav.push<RegistersView>(
|
{"RFFC5072", ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [&nav]() { nav.push<RegistersView>(
|
||||||
"RFFC5072", RegistersWidgetConfig{31, 16},
|
"RFFC5072", RegistersWidgetConfig{31, 16},
|
||||||
[](const size_t register_number) { return radio::debug::first_if::register_read(register_number); }
|
[](const size_t register_number) { return radio::debug::first_if::register_read(register_number); }); }},
|
||||||
); } },
|
|
||||||
{max283x, ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [&nav, max283x]() { nav.push<RegistersView>(
|
{max283x, ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [&nav, max283x]() { nav.push<RegistersView>(
|
||||||
max283x, RegistersWidgetConfig{32, 10},
|
max283x, RegistersWidgetConfig{32, 10},
|
||||||
[](const size_t register_number) { return radio::debug::second_if::register_read(register_number); }
|
[](const size_t register_number) { return radio::debug::second_if::register_read(register_number); }); }},
|
||||||
); } },
|
|
||||||
{si5351x, ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [&nav, si5351x]() { nav.push<RegistersView>(
|
{si5351x, ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [&nav, si5351x]() { nav.push<RegistersView>(
|
||||||
si5351x, RegistersWidgetConfig{96, 8},
|
si5351x, RegistersWidgetConfig{96, 8},
|
||||||
[](const size_t register_number) { return portapack::clock_generator.read_register(register_number); }
|
[](const size_t register_number) { return portapack::clock_generator.read_register(register_number); }); }},
|
||||||
); } },
|
|
||||||
{audio::debug::codec_name(), ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [&nav]() { nav.push<RegistersView>(
|
{audio::debug::codec_name(), ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [&nav]() { nav.push<RegistersView>(
|
||||||
audio::debug::codec_name(), RegistersWidgetConfig{audio::debug::reg_count(), audio::debug::reg_bits()},
|
audio::debug::codec_name(), RegistersWidgetConfig{audio::debug::reg_count(), audio::debug::reg_bits()},
|
||||||
[](const size_t register_number) { return audio::debug::reg_read(register_number); }
|
[](const size_t register_number) { return audio::debug::reg_read(register_number); }); }},
|
||||||
); } },
|
|
||||||
});
|
});
|
||||||
set_max_rows(2); // allow wider buttons
|
set_max_rows(2); // allow wider buttons
|
||||||
}
|
}
|
||||||
|
@ -386,8 +367,7 @@ DebugPeripheralsMenuView::DebugPeripheralsMenuView(NavigationView& nav) {
|
||||||
/* DebugMenuView *********************************************************/
|
/* DebugMenuView *********************************************************/
|
||||||
|
|
||||||
DebugMenuView::DebugMenuView(NavigationView& nav) {
|
DebugMenuView::DebugMenuView(NavigationView& nav) {
|
||||||
if( portapack::persistent_memory::show_gui_return_icon() )
|
if (portapack::persistent_memory::show_gui_return_icon()) {
|
||||||
{
|
|
||||||
add_items({{"..", ui::Color::light_grey(), &bitmap_icon_previous, [&nav]() { nav.pop(); }}});
|
add_items({{"..", ui::Color::light_grey(), &bitmap_icon_previous, [&nav]() { nav.pop(); }}});
|
||||||
}
|
}
|
||||||
add_items({
|
add_items({
|
||||||
|
|
|
@ -79,16 +79,14 @@ private:
|
||||||
|
|
||||||
Button button_done{
|
Button button_done{
|
||||||
{72, 192, 96, 24},
|
{72, 192, 96, 24},
|
||||||
"Done"
|
"Done"};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class TemperatureWidget : public Widget {
|
class TemperatureWidget : public Widget {
|
||||||
public:
|
public:
|
||||||
explicit TemperatureWidget(
|
explicit TemperatureWidget(
|
||||||
Rect parent_rect
|
Rect parent_rect)
|
||||||
) : Widget { parent_rect }
|
: Widget{parent_rect} {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void paint(Painter& painter) override;
|
void paint(Painter& painter) override;
|
||||||
|
@ -128,8 +126,7 @@ private:
|
||||||
|
|
||||||
Button button_done{
|
Button button_done{
|
||||||
{72, 264, 96, 24},
|
{72, 264, 96, 24},
|
||||||
"Done"
|
"Done"};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RegistersWidgetConfig {
|
struct RegistersWidgetConfig {
|
||||||
|
@ -177,8 +174,7 @@ class RegistersWidget : public Widget {
|
||||||
public:
|
public:
|
||||||
RegistersWidget(
|
RegistersWidget(
|
||||||
RegistersWidgetConfig&& config,
|
RegistersWidgetConfig&& config,
|
||||||
std::function<uint32_t(const size_t register_number)>&& reader
|
std::function<uint32_t(const size_t register_number)>&& reader);
|
||||||
);
|
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
|
@ -200,8 +196,7 @@ public:
|
||||||
NavigationView& nav,
|
NavigationView& nav,
|
||||||
const std::string& title,
|
const std::string& title,
|
||||||
RegistersWidgetConfig&& config,
|
RegistersWidgetConfig&& config,
|
||||||
std::function<uint32_t(const size_t register_number)>&& reader
|
std::function<uint32_t(const size_t register_number)>&& reader);
|
||||||
);
|
|
||||||
|
|
||||||
void focus();
|
void focus();
|
||||||
|
|
||||||
|
@ -212,22 +207,19 @@ private:
|
||||||
|
|
||||||
Button button_update{
|
Button button_update{
|
||||||
{16, 256, 96, 24},
|
{16, 256, 96, 24},
|
||||||
"Update"
|
"Update"};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_done{
|
Button button_done{
|
||||||
{128, 256, 96, 24},
|
{128, 256, 96, 24},
|
||||||
"Done"
|
"Done"};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ControlsSwitchesWidget : public Widget {
|
class ControlsSwitchesWidget : public Widget {
|
||||||
public:
|
public:
|
||||||
ControlsSwitchesWidget(
|
ControlsSwitchesWidget(
|
||||||
Rect parent_rect
|
Rect parent_rect)
|
||||||
) : Widget { parent_rect },
|
: Widget{parent_rect},
|
||||||
key_event_mask(0)
|
key_event_mask(0) {
|
||||||
{
|
|
||||||
set_focusable(true);
|
set_focusable(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,8 +235,7 @@ private:
|
||||||
Message::ID::DisplayFrameSync,
|
Message::ID::DisplayFrameSync,
|
||||||
[this](const Message* const) {
|
[this](const Message* const) {
|
||||||
this->on_frame_sync();
|
this->on_frame_sync();
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
void on_frame_sync();
|
void on_frame_sync();
|
||||||
};
|
};
|
||||||
|
@ -269,8 +260,7 @@ private:
|
||||||
|
|
||||||
Button button_done{
|
Button button_done{
|
||||||
{72, 264, 96, 24},
|
{72, 264, 96, 24},
|
||||||
"Done"
|
"Done"};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*class DebugLCRView : public View {
|
/*class DebugLCRView : public View {
|
||||||
|
|
|
@ -25,9 +25,9 @@
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
DfuMenu::DfuMenu(NavigationView& nav) : nav_ (nav) {
|
DfuMenu::DfuMenu(NavigationView& nav)
|
||||||
add_children({
|
: nav_(nav) {
|
||||||
&text_head,
|
add_children({&text_head,
|
||||||
&labels,
|
&labels,
|
||||||
&text_info_line_1,
|
&text_info_line_1,
|
||||||
&text_info_line_2,
|
&text_info_line_2,
|
||||||
|
@ -36,8 +36,7 @@ DfuMenu::DfuMenu(NavigationView& nav) : nav_ (nav) {
|
||||||
&text_info_line_5,
|
&text_info_line_5,
|
||||||
&text_info_line_6,
|
&text_info_line_6,
|
||||||
&text_info_line_7,
|
&text_info_line_7,
|
||||||
&text_info_line_8
|
&text_info_line_8});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DfuMenu::paint(Painter& painter) {
|
void DfuMenu::paint(Painter& painter) {
|
||||||
|
@ -56,44 +55,29 @@ void DfuMenu::paint(Painter& painter) {
|
||||||
constexpr auto lines = 8 + 2;
|
constexpr auto lines = 8 + 2;
|
||||||
|
|
||||||
painter.fill_rectangle(
|
painter.fill_rectangle(
|
||||||
{
|
{{6 * CHARACTER_WIDTH - margin, 3 * LINE_HEIGHT - margin},
|
||||||
{6 * CHARACTER_WIDTH - margin, 3 * LINE_HEIGHT - margin},
|
{15 * CHARACTER_WIDTH + margin * 2, lines * LINE_HEIGHT + margin * 2}},
|
||||||
{15 * CHARACTER_WIDTH + margin * 2, lines * LINE_HEIGHT + margin * 2}
|
ui::Color::black());
|
||||||
},
|
|
||||||
ui::Color::black()
|
|
||||||
);
|
|
||||||
|
|
||||||
painter.fill_rectangle(
|
painter.fill_rectangle(
|
||||||
{
|
{{5 * CHARACTER_WIDTH - margin, 3 * LINE_HEIGHT - margin},
|
||||||
{5 * CHARACTER_WIDTH - margin, 3 * LINE_HEIGHT - margin},
|
{CHARACTER_WIDTH, lines * LINE_HEIGHT + margin * 2}},
|
||||||
{CHARACTER_WIDTH, lines * LINE_HEIGHT + margin * 2}
|
ui::Color::dark_cyan());
|
||||||
},
|
|
||||||
ui::Color::dark_cyan()
|
|
||||||
);
|
|
||||||
|
|
||||||
painter.fill_rectangle(
|
painter.fill_rectangle(
|
||||||
{
|
{{21 * CHARACTER_WIDTH + margin, 3 * LINE_HEIGHT - margin},
|
||||||
{21 * CHARACTER_WIDTH + margin, 3 * LINE_HEIGHT - margin},
|
{CHARACTER_WIDTH, lines * LINE_HEIGHT + margin * 2}},
|
||||||
{CHARACTER_WIDTH, lines * LINE_HEIGHT + margin * 2}
|
ui::Color::dark_cyan());
|
||||||
},
|
|
||||||
ui::Color::dark_cyan()
|
|
||||||
);
|
|
||||||
|
|
||||||
painter.fill_rectangle(
|
painter.fill_rectangle(
|
||||||
{
|
{{5 * CHARACTER_WIDTH - margin, 3 * LINE_HEIGHT - margin - 8},
|
||||||
{5 * CHARACTER_WIDTH - margin, 3 * LINE_HEIGHT - margin - 8},
|
{17 * CHARACTER_WIDTH + margin * 2, 8}},
|
||||||
{17 * CHARACTER_WIDTH + margin * 2, 8}
|
ui::Color::dark_cyan());
|
||||||
},
|
|
||||||
ui::Color::dark_cyan()
|
|
||||||
);
|
|
||||||
|
|
||||||
painter.fill_rectangle(
|
painter.fill_rectangle(
|
||||||
{
|
{{5 * CHARACTER_WIDTH - margin, (lines + 3) * LINE_HEIGHT + margin},
|
||||||
{5 * CHARACTER_WIDTH - margin, (lines+3) * LINE_HEIGHT + margin},
|
{17 * CHARACTER_WIDTH + margin * 2, 8}},
|
||||||
{17 * CHARACTER_WIDTH + margin * 2, 8}
|
ui::Color::dark_cyan());
|
||||||
},
|
|
||||||
ui::Color::dark_cyan()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -55,8 +55,7 @@ private:
|
||||||
{{6 * CHARACTER_WIDTH, 9 * LINE_HEIGHT}, "M4 stack:", Color::dark_cyan()},
|
{{6 * CHARACTER_WIDTH, 9 * LINE_HEIGHT}, "M4 stack:", Color::dark_cyan()},
|
||||||
{{6 * CHARACTER_WIDTH, 10 * LINE_HEIGHT}, "M4 cpu %:", Color::dark_cyan()},
|
{{6 * CHARACTER_WIDTH, 10 * LINE_HEIGHT}, "M4 cpu %:", Color::dark_cyan()},
|
||||||
{{6 * CHARACTER_WIDTH, 11 * LINE_HEIGHT}, "M4 miss:", Color::dark_cyan()},
|
{{6 * CHARACTER_WIDTH, 11 * LINE_HEIGHT}, "M4 miss:", Color::dark_cyan()},
|
||||||
{ { 6 * CHARACTER_WIDTH,12 * LINE_HEIGHT }, "uptime:", Color::dark_cyan() }
|
{{6 * CHARACTER_WIDTH, 12 * LINE_HEIGHT}, "uptime:", Color::dark_cyan()}};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_info_line_1{{15 * CHARACTER_WIDTH, 5 * LINE_HEIGHT, 5 * CHARACTER_WIDTH, 1 * LINE_HEIGHT}, ""};
|
Text text_info_line_1{{15 * CHARACTER_WIDTH, 5 * LINE_HEIGHT, 5 * CHARACTER_WIDTH, 1 * LINE_HEIGHT}, ""};
|
||||||
Text text_info_line_2{{15 * CHARACTER_WIDTH, 6 * LINE_HEIGHT, 5 * CHARACTER_WIDTH, 1 * LINE_HEIGHT}, ""};
|
Text text_info_line_2{{15 * CHARACTER_WIDTH, 6 * LINE_HEIGHT, 5 * CHARACTER_WIDTH, 1 * LINE_HEIGHT}, ""};
|
||||||
|
|
|
@ -31,8 +31,8 @@ using namespace portapack;
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
EncodersConfigView::EncodersConfigView(
|
EncodersConfigView::EncodersConfigView(
|
||||||
NavigationView&, Rect parent_rect
|
NavigationView&,
|
||||||
) {
|
Rect parent_rect) {
|
||||||
using option_t = std::pair<std::string, int32_t>;
|
using option_t = std::pair<std::string, int32_t>;
|
||||||
std::vector<option_t> enc_options;
|
std::vector<option_t> enc_options;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
@ -43,8 +43,7 @@ EncodersConfigView::EncodersConfigView(
|
||||||
// Default encoder def
|
// Default encoder def
|
||||||
encoder_def = &encoder_defs[0];
|
encoder_def = &encoder_defs[0];
|
||||||
|
|
||||||
add_children({
|
add_children({&labels,
|
||||||
&labels,
|
|
||||||
&options_enctype,
|
&options_enctype,
|
||||||
&field_repeat_min,
|
&field_repeat_min,
|
||||||
&field_clk,
|
&field_clk,
|
||||||
|
@ -53,8 +52,7 @@ EncodersConfigView::EncodersConfigView(
|
||||||
&field_frameduration_step,
|
&field_frameduration_step,
|
||||||
&symfield_word,
|
&symfield_word,
|
||||||
&text_format,
|
&text_format,
|
||||||
&waveform
|
&waveform});
|
||||||
});
|
|
||||||
|
|
||||||
// Load encoder types in option field
|
// Load encoder types in option field
|
||||||
for (i = 0; i < ENC_TYPES_COUNT; i++)
|
for (i = 0; i < ENC_TYPES_COUNT; i++)
|
||||||
|
@ -182,17 +180,15 @@ void EncodersScanView::focus() {
|
||||||
}
|
}
|
||||||
|
|
||||||
EncodersScanView::EncodersScanView(
|
EncodersScanView::EncodersScanView(
|
||||||
NavigationView&, Rect parent_rect
|
NavigationView&,
|
||||||
) {
|
Rect parent_rect) {
|
||||||
set_parent_rect(parent_rect);
|
set_parent_rect(parent_rect);
|
||||||
hidden(true);
|
hidden(true);
|
||||||
|
|
||||||
add_children({
|
add_children({&labels,
|
||||||
&labels,
|
|
||||||
&field_length,
|
&field_length,
|
||||||
&bit_length_10,
|
&bit_length_10,
|
||||||
&bit_length
|
&bit_length});
|
||||||
});
|
|
||||||
|
|
||||||
field_length.set_value(8);
|
field_length.set_value(8);
|
||||||
bit_length_10.set_value(40);
|
bit_length_10.set_value(40);
|
||||||
|
@ -279,24 +275,20 @@ void EncodersView::start_tx(const bool scan) {
|
||||||
samples_per_bit,
|
samples_per_bit,
|
||||||
repeat_min,
|
repeat_min,
|
||||||
view_config.pause_symbols(),
|
view_config.pause_symbols(),
|
||||||
scan_width
|
scan_width);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EncodersView::EncodersView(
|
EncodersView::EncodersView(
|
||||||
NavigationView& nav
|
NavigationView& nav)
|
||||||
) : nav_ { nav }
|
: nav_{nav} {
|
||||||
{
|
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_ook);
|
baseband::run_image(portapack::spi_flash::image_tag_ook);
|
||||||
|
|
||||||
add_children({
|
add_children({&tab_view,
|
||||||
&tab_view,
|
|
||||||
&view_config,
|
&view_config,
|
||||||
&view_scan,
|
&view_scan,
|
||||||
&text_status,
|
&text_status,
|
||||||
&progressbar,
|
&progressbar,
|
||||||
&tx_view
|
&tx_view});
|
||||||
});
|
|
||||||
|
|
||||||
// load app settings
|
// load app settings
|
||||||
auto rc = settings.load("tx_ook", &app_settings);
|
auto rc = settings.load("tx_ook", &app_settings);
|
||||||
|
|
|
@ -69,71 +69,57 @@ private:
|
||||||
{{13 * 8, 4 * 8}, "us", Color::light_grey()},
|
{{13 * 8, 4 * 8}, "us", Color::light_grey()},
|
||||||
{{17 * 8, 4 * 8}, "Step:", Color::light_grey()},
|
{{17 * 8, 4 * 8}, "Step:", Color::light_grey()},
|
||||||
{{2 * 8, 7 * 8}, "Symbols:", Color::light_grey()},
|
{{2 * 8, 7 * 8}, "Symbols:", Color::light_grey()},
|
||||||
{ { 1 * 8, 14 * 8 }, "Waveform:", Color::light_grey() }
|
{{1 * 8, 14 * 8}, "Waveform:", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField options_enctype{// Options are loaded at runtime
|
OptionsField options_enctype{// Options are loaded at runtime
|
||||||
{6 * 8, 0},
|
{6 * 8, 0},
|
||||||
7,
|
7,
|
||||||
{
|
{}};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_clk{
|
NumberField field_clk{
|
||||||
{5 * 8, 2 * 8},
|
{5 * 8, 2 * 8},
|
||||||
4,
|
4,
|
||||||
{1, 1000},
|
{1, 1000},
|
||||||
1,
|
1,
|
||||||
' '
|
' '};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_repeat_min{
|
NumberField field_repeat_min{
|
||||||
{24 * 8, 0},
|
{24 * 8, 0},
|
||||||
2,
|
2,
|
||||||
{1, 99},
|
{1, 99},
|
||||||
1,
|
1,
|
||||||
' '
|
' '};
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField field_clk_step{
|
OptionsField field_clk_step{
|
||||||
{22 * 8, 2 * 8},
|
{22 * 8, 2 * 8},
|
||||||
7,
|
7,
|
||||||
{
|
{{"1", 1},
|
||||||
{ "1", 1 },
|
|
||||||
{"10", 10},
|
{"10", 10},
|
||||||
{ "100", 100 }
|
{"100", 100}}};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_frameduration{
|
NumberField field_frameduration{
|
||||||
{7 * 8, 4 * 8},
|
{7 * 8, 4 * 8},
|
||||||
5,
|
5,
|
||||||
{300, 99999},
|
{300, 99999},
|
||||||
100,
|
100,
|
||||||
' '
|
' '};
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField field_frameduration_step{
|
OptionsField field_frameduration_step{
|
||||||
{22 * 8, 4 * 8},
|
{22 * 8, 4 * 8},
|
||||||
7,
|
7,
|
||||||
{
|
{{"1", 1},
|
||||||
{ "1", 1 },
|
|
||||||
{"10", 10},
|
{"10", 10},
|
||||||
{"100", 100},
|
{"100", 100},
|
||||||
{ "1000", 1000 }
|
{"1000", 1000}}};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
SymField symfield_word{
|
SymField symfield_word{
|
||||||
{2 * 8, 9 * 8},
|
{2 * 8, 9 * 8},
|
||||||
20,
|
20,
|
||||||
SymField::SYMFIELD_DEF
|
SymField::SYMFIELD_DEF};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_format{
|
Text text_format{
|
||||||
{2 * 8, 11 * 8, 24 * 8, 16},
|
{2 * 8, 11 * 8, 24 * 8, 16},
|
||||||
""
|
""};
|
||||||
};
|
|
||||||
|
|
||||||
Waveform waveform{
|
Waveform waveform{
|
||||||
{0, 17 * 8, 240, 32},
|
{0, 17 * 8, 240, 32},
|
||||||
|
@ -141,10 +127,8 @@ private:
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
true,
|
true,
|
||||||
Color::yellow()
|
Color::yellow()};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class EncodersScanView : public View {
|
class EncodersScanView : public View {
|
||||||
public:
|
public:
|
||||||
|
@ -155,24 +139,21 @@ public:
|
||||||
2,
|
2,
|
||||||
{3, 24},
|
{3, 24},
|
||||||
1,
|
1,
|
||||||
' '
|
' '};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField bit_length_10{
|
NumberField bit_length_10{
|
||||||
{12 * 8, 2 * 8},
|
{12 * 8, 2 * 8},
|
||||||
2,
|
2,
|
||||||
{1, 88},
|
{1, 88},
|
||||||
1,
|
1,
|
||||||
' '
|
' '};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField bit_length{
|
NumberField bit_length{
|
||||||
{14 * 8, 2 * 8},
|
{14 * 8, 2 * 8},
|
||||||
1,
|
1,
|
||||||
{0, 9},
|
{0, 9},
|
||||||
1,
|
1,
|
||||||
' '
|
' '};
|
||||||
};
|
|
||||||
|
|
||||||
void focus() override;
|
void focus() override;
|
||||||
|
|
||||||
|
@ -237,26 +218,22 @@ private:
|
||||||
|
|
||||||
Text text_status{
|
Text text_status{
|
||||||
{2 * 8, 13 * 16, 128, 16},
|
{2 * 8, 13 * 16, 128, 16},
|
||||||
"Ready"
|
"Ready"};
|
||||||
};
|
|
||||||
|
|
||||||
ProgressBar progressbar{
|
ProgressBar progressbar{
|
||||||
{ 2 * 8, 13 * 16 + 20, 208, 16 }
|
{2 * 8, 13 * 16 + 20, 208, 16}};
|
||||||
};
|
|
||||||
|
|
||||||
TransmitterView tx_view{
|
TransmitterView tx_view{
|
||||||
16 * 16,
|
16 * 16,
|
||||||
50000,
|
50000,
|
||||||
9
|
9};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_tx_progress{
|
MessageHandlerRegistration message_handler_tx_progress{
|
||||||
Message::ID::TXProgress,
|
Message::ID::TXProgress,
|
||||||
[this](const Message* const p) {
|
[this](const Message* const p) {
|
||||||
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
|
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
|
||||||
this->on_tx_progress(message.progress, message.done);
|
this->on_tx_progress(message.progress, message.done);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -64,8 +64,7 @@ std::string get_pretty_size(uint32_t file_size) {
|
||||||
// Case insensitive path equality on underlying "native" string.
|
// Case insensitive path equality on underlying "native" string.
|
||||||
bool iequal(
|
bool iequal(
|
||||||
const fs::path& lhs,
|
const fs::path& lhs,
|
||||||
const fs::path& rhs
|
const fs::path& rhs) {
|
||||||
) {
|
|
||||||
const auto& lhs_str = lhs.native();
|
const auto& lhs_str = lhs.native();
|
||||||
const auto& rhs_str = rhs.native();
|
const auto& rhs_str = rhs.native();
|
||||||
|
|
||||||
|
@ -124,8 +123,7 @@ bool partner_file_prompt(
|
||||||
NavigationView& nav,
|
NavigationView& nav,
|
||||||
const fs::path& path,
|
const fs::path& path,
|
||||||
std::string action_name,
|
std::string action_name,
|
||||||
std::function<void(const fs::path&, bool)> on_partner_action
|
std::function<void(const fs::path&, bool)> on_partner_action) {
|
||||||
) {
|
|
||||||
auto partner = get_partner_file(path);
|
auto partner = get_partner_file(path);
|
||||||
|
|
||||||
if (partner.empty())
|
if (partner.empty())
|
||||||
|
@ -138,8 +136,7 @@ bool partner_file_prompt(
|
||||||
[&nav, partner, on_partner_action](bool choice) {
|
[&nav, partner, on_partner_action](bool choice) {
|
||||||
if (on_partner_action)
|
if (on_partner_action)
|
||||||
on_partner_action(partner, choice);
|
on_partner_action(partner, choice);
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -160,7 +157,7 @@ fs::path get_unique_filename(const fs::path& path, const fs::path& file) {
|
||||||
return new_path;
|
return new_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
|
@ -205,16 +202,13 @@ const fileman_entry& FileManBaseView::get_selected_entry() const {
|
||||||
|
|
||||||
FileManBaseView::FileManBaseView(
|
FileManBaseView::FileManBaseView(
|
||||||
NavigationView& nav,
|
NavigationView& nav,
|
||||||
std::string filter
|
std::string filter)
|
||||||
) : nav_{ nav },
|
: nav_{nav},
|
||||||
extension_filter{ filter }
|
extension_filter{filter} {
|
||||||
{
|
add_children({&labels,
|
||||||
add_children({
|
|
||||||
&labels,
|
|
||||||
&text_current,
|
&text_current,
|
||||||
&text_info,
|
&text_info,
|
||||||
&button_exit
|
&button_exit});
|
||||||
});
|
|
||||||
|
|
||||||
button_exit.on_select = [this, &nav](Button&) {
|
button_exit.on_select = [this, &nav](Button&) {
|
||||||
nav.pop();
|
nav.pop();
|
||||||
|
@ -278,29 +272,25 @@ void FileManBaseView::refresh_list() {
|
||||||
auto entry_name = truncate(entry.path, 20);
|
auto entry_name = truncate(entry.path, 20);
|
||||||
|
|
||||||
if (entry.is_directory) {
|
if (entry.is_directory) {
|
||||||
menu_view.add_item({
|
menu_view.add_item({entry_name,
|
||||||
entry_name,
|
|
||||||
ui::Color::yellow(),
|
ui::Color::yellow(),
|
||||||
&bitmap_icon_dir,
|
&bitmap_icon_dir,
|
||||||
[this](KeyEvent key) {
|
[this](KeyEvent key) {
|
||||||
if (on_select_entry)
|
if (on_select_entry)
|
||||||
on_select_entry(key);
|
on_select_entry(key);
|
||||||
}
|
}});
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
const auto& assoc = get_assoc(entry.path.extension());
|
const auto& assoc = get_assoc(entry.path.extension());
|
||||||
auto size_str = get_pretty_size(entry.size);
|
auto size_str = get_pretty_size(entry.size);
|
||||||
|
|
||||||
menu_view.add_item({
|
menu_view.add_item({entry_name + std::string(21 - entry_name.length(), ' ') + size_str,
|
||||||
entry_name + std::string(21 - entry_name.length(), ' ') + size_str,
|
|
||||||
assoc.color,
|
assoc.color,
|
||||||
assoc.icon,
|
assoc.icon,
|
||||||
[this](KeyEvent key) {
|
[this](KeyEvent key) {
|
||||||
if (on_select_entry)
|
if (on_select_entry)
|
||||||
on_select_entry(key);
|
on_select_entry(key);
|
||||||
}
|
}});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// HACK: Should page menu items instead of limiting the number.
|
// HACK: Should page menu items instead of limiting the number.
|
||||||
|
@ -318,8 +308,7 @@ void FileManBaseView::reload_current() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const FileManBaseView::file_assoc_t& FileManBaseView::get_assoc(
|
const FileManBaseView::file_assoc_t& FileManBaseView::get_assoc(
|
||||||
const fs::path& ext) const
|
const fs::path& ext) const {
|
||||||
{
|
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
|
|
||||||
for (; index < file_types.size() - 1; ++index)
|
for (; index < file_types.size() - 1; ++index)
|
||||||
|
@ -334,16 +323,13 @@ const FileManBaseView::file_assoc_t& FileManBaseView::get_assoc(
|
||||||
|
|
||||||
FileLoadView::FileLoadView(
|
FileLoadView::FileLoadView(
|
||||||
NavigationView& nav,
|
NavigationView& nav,
|
||||||
std::string filter
|
std::string filter)
|
||||||
) : FileManBaseView(nav, filter)
|
: FileManBaseView(nav, filter) {
|
||||||
{
|
|
||||||
on_refresh_widgets = [this](bool v) {
|
on_refresh_widgets = [this](bool v) {
|
||||||
refresh_widgets(v);
|
refresh_widgets(v);
|
||||||
};
|
};
|
||||||
|
|
||||||
add_children({
|
add_children({&menu_view});
|
||||||
&menu_view
|
|
||||||
});
|
|
||||||
|
|
||||||
// Resize menu view to fill screen
|
// Resize menu view to fill screen
|
||||||
menu_view.set_parent_rect({0, 3 * 8, 240, 29 * 8});
|
menu_view.set_parent_rect({0, 3 * 8, 240, 29 * 8});
|
||||||
|
@ -446,8 +432,7 @@ void FileManagerView::on_rename() {
|
||||||
rename_file(partner, current_path / new_name);
|
rename_file(partner, current_path / new_name);
|
||||||
}
|
}
|
||||||
reload_current();
|
reload_current();
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
if (!has_partner)
|
if (!has_partner)
|
||||||
reload_current();
|
reload_current();
|
||||||
|
@ -467,14 +452,12 @@ void FileManagerView::on_delete() {
|
||||||
if (should_delete)
|
if (should_delete)
|
||||||
delete_file(partner);
|
delete_file(partner);
|
||||||
reload_current();
|
reload_current();
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
if (!has_partner)
|
if (!has_partner)
|
||||||
reload_current();
|
reload_current();
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileManagerView::on_new_dir() {
|
void FileManagerView::on_new_dir() {
|
||||||
|
@ -531,9 +514,8 @@ void FileManagerView::refresh_widgets(const bool v) {
|
||||||
}
|
}
|
||||||
|
|
||||||
FileManagerView::FileManagerView(
|
FileManagerView::FileManagerView(
|
||||||
NavigationView& nav
|
NavigationView& nav)
|
||||||
) : FileManBaseView(nav, "")
|
: FileManBaseView(nav, "") {
|
||||||
{
|
|
||||||
// Don't bother with the UI in the case of no SDC.
|
// Don't bother with the UI in the case of no SDC.
|
||||||
if (empty_ == EmptyReason::NoSDC)
|
if (empty_ == EmptyReason::NoSDC)
|
||||||
return;
|
return;
|
||||||
|
@ -542,8 +524,7 @@ FileManagerView::FileManagerView(
|
||||||
refresh_widgets(v);
|
refresh_widgets(v);
|
||||||
};
|
};
|
||||||
|
|
||||||
add_children({
|
add_children({&menu_view,
|
||||||
&menu_view,
|
|
||||||
&labels,
|
&labels,
|
||||||
&text_date,
|
&text_date,
|
||||||
&button_rename,
|
&button_rename,
|
||||||
|
@ -552,8 +533,7 @@ FileManagerView::FileManagerView(
|
||||||
&button_copy,
|
&button_copy,
|
||||||
&button_paste,
|
&button_paste,
|
||||||
&button_new_dir,
|
&button_new_dir,
|
||||||
&button_new_file
|
&button_new_file});
|
||||||
});
|
|
||||||
|
|
||||||
menu_view.on_highlight = [this]() {
|
menu_view.on_highlight = [this]() {
|
||||||
if (selected_is_valid())
|
if (selected_is_valid())
|
||||||
|
@ -614,4 +594,4 @@ FileManagerView::FileManagerView(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace ui
|
||||||
|
|
|
@ -52,8 +52,7 @@ class FileManBaseView : public View {
|
||||||
public:
|
public:
|
||||||
FileManBaseView(
|
FileManBaseView(
|
||||||
NavigationView& nav,
|
NavigationView& nav,
|
||||||
std::string filter
|
std::string filter);
|
||||||
);
|
|
||||||
|
|
||||||
virtual ~FileManBaseView() {}
|
virtual ~FileManBaseView() {}
|
||||||
|
|
||||||
|
@ -104,8 +103,7 @@ protected:
|
||||||
std::vector<uint32_t> saved_index_stack{};
|
std::vector<uint32_t> saved_index_stack{};
|
||||||
|
|
||||||
Labels labels{
|
Labels labels{
|
||||||
{ { 0, 0 }, "Path:", Color::light_grey() }
|
{{0, 0}, "Path:", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_current{
|
Text text_current{
|
||||||
{6 * 8, 0 * 8, 24 * 8, 16},
|
{6 * 8, 0 * 8, 24 * 8, 16},
|
||||||
|
@ -114,19 +112,16 @@ protected:
|
||||||
|
|
||||||
MenuView menu_view{
|
MenuView menu_view{
|
||||||
{0, 2 * 8, 240, 26 * 8},
|
{0, 2 * 8, 240, 26 * 8},
|
||||||
true
|
true};
|
||||||
};
|
|
||||||
|
|
||||||
// HACK: for item count limit.
|
// HACK: for item count limit.
|
||||||
Text text_info{
|
Text text_info{
|
||||||
{1 * 8, 35 * 8, 15 * 8, 16},
|
{1 * 8, 35 * 8, 15 * 8, 16},
|
||||||
""
|
""};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_exit{
|
Button button_exit{
|
||||||
{21 * 8, 34 * 8, 9 * 8, 32},
|
{21 * 8, 34 * 8, 9 * 8, 32},
|
||||||
"Exit"
|
"Exit"};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class FileLoadView : public FileManBaseView {
|
class FileLoadView : public FileManBaseView {
|
||||||
|
@ -221,62 +216,53 @@ private:
|
||||||
bool selected_is_valid() const;
|
bool selected_is_valid() const;
|
||||||
|
|
||||||
Labels labels{
|
Labels labels{
|
||||||
{ { 0, 26 * 8 }, "Created ", Color::light_grey() }
|
{{0, 26 * 8}, "Created ", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_date{
|
Text text_date{
|
||||||
{8 * 8, 26 * 8, 19 * 8, 16},
|
{8 * 8, 26 * 8, 19 * 8, 16},
|
||||||
""
|
""};
|
||||||
};
|
|
||||||
|
|
||||||
NewButton button_rename{
|
NewButton button_rename{
|
||||||
{0 * 8, 29 * 8, 4 * 8, 32},
|
{0 * 8, 29 * 8, 4 * 8, 32},
|
||||||
{},
|
{},
|
||||||
&bitmap_icon_rename,
|
&bitmap_icon_rename,
|
||||||
Color::dark_blue()
|
Color::dark_blue()};
|
||||||
};
|
|
||||||
|
|
||||||
NewButton button_delete{
|
NewButton button_delete{
|
||||||
{4 * 8, 29 * 8, 4 * 8, 32},
|
{4 * 8, 29 * 8, 4 * 8, 32},
|
||||||
{},
|
{},
|
||||||
&bitmap_icon_trash,
|
&bitmap_icon_trash,
|
||||||
Color::red()
|
Color::red()};
|
||||||
};
|
|
||||||
|
|
||||||
NewButton button_cut{
|
NewButton button_cut{
|
||||||
{9 * 8, 29 * 8, 4 * 8, 32},
|
{9 * 8, 29 * 8, 4 * 8, 32},
|
||||||
{},
|
{},
|
||||||
&bitmap_icon_cut,
|
&bitmap_icon_cut,
|
||||||
Color::dark_grey()
|
Color::dark_grey()};
|
||||||
};
|
|
||||||
|
|
||||||
NewButton button_copy{
|
NewButton button_copy{
|
||||||
{13 * 8, 29 * 8, 4 * 8, 32},
|
{13 * 8, 29 * 8, 4 * 8, 32},
|
||||||
{},
|
{},
|
||||||
&bitmap_icon_copy,
|
&bitmap_icon_copy,
|
||||||
Color::dark_grey()
|
Color::dark_grey()};
|
||||||
};
|
|
||||||
|
|
||||||
NewButton button_paste{
|
NewButton button_paste{
|
||||||
{17 * 8, 29 * 8, 4 * 8, 32},
|
{17 * 8, 29 * 8, 4 * 8, 32},
|
||||||
{},
|
{},
|
||||||
&bitmap_icon_paste,
|
&bitmap_icon_paste,
|
||||||
Color::dark_grey()
|
Color::dark_grey()};
|
||||||
};
|
|
||||||
|
|
||||||
NewButton button_new_dir{
|
NewButton button_new_dir{
|
||||||
{22 * 8, 29 * 8, 4 * 8, 32},
|
{22 * 8, 29 * 8, 4 * 8, 32},
|
||||||
{},
|
{},
|
||||||
&bitmap_icon_new_dir,
|
&bitmap_icon_new_dir,
|
||||||
Color::green()
|
Color::green()};
|
||||||
};
|
|
||||||
|
|
||||||
NewButton button_new_file{
|
NewButton button_new_file{
|
||||||
{26 * 8, 29 * 8, 4 * 8, 32},
|
{26 * 8, 29 * 8, 4 * 8, 32},
|
||||||
{},
|
{},
|
||||||
&bitmap_icon_new_file,
|
&bitmap_icon_new_file,
|
||||||
Color::green()
|
Color::green()};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -28,11 +28,10 @@ namespace ui {
|
||||||
Thread* FlashUtilityView::thread{nullptr};
|
Thread* FlashUtilityView::thread{nullptr};
|
||||||
static constexpr size_t max_filename_length = 26;
|
static constexpr size_t max_filename_length = 26;
|
||||||
|
|
||||||
FlashUtilityView::FlashUtilityView(NavigationView& nav) : nav_ (nav) {
|
FlashUtilityView::FlashUtilityView(NavigationView& nav)
|
||||||
add_children({
|
: nav_(nav) {
|
||||||
&labels,
|
add_children({&labels,
|
||||||
&menu_view
|
&menu_view});
|
||||||
});
|
|
||||||
|
|
||||||
menu_view.set_parent_rect({0, 3 * 8, 240, 33 * 8});
|
menu_view.set_parent_rect({0, 3 * 8, 240, 33 * 8});
|
||||||
|
|
||||||
|
@ -40,14 +39,12 @@ FlashUtilityView::FlashUtilityView(NavigationView& nav) : nav_ (nav) {
|
||||||
auto filename = entry.path().filename();
|
auto filename = entry.path().filename();
|
||||||
auto path = entry.path().native();
|
auto path = entry.path().native();
|
||||||
|
|
||||||
menu_view.add_item({
|
menu_view.add_item({filename.string().substr(0, max_filename_length),
|
||||||
filename.string().substr(0, max_filename_length),
|
|
||||||
ui::Color::red(),
|
ui::Color::red(),
|
||||||
&bitmap_icon_temperature,
|
&bitmap_icon_temperature,
|
||||||
[this, path](KeyEvent) {
|
[this, path](KeyEvent) {
|
||||||
this->firmware_selected(path);
|
this->firmware_selected(path);
|
||||||
}
|
}});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,16 +58,14 @@ void FlashUtilityView::firmware_selected(std::filesystem::path::string_type path
|
||||||
std::u16string full_path = std::u16string(u"FIRMWARE/") + path;
|
std::u16string full_path = std::u16string(u"FIRMWARE/") + path;
|
||||||
this->flash_firmware(full_path);
|
this->flash_firmware(full_path);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlashUtilityView::flash_firmware(std::filesystem::path::string_type path) {
|
void FlashUtilityView::flash_firmware(std::filesystem::path::string_type path) {
|
||||||
ui::Painter painter;
|
ui::Painter painter;
|
||||||
painter.fill_rectangle(
|
painter.fill_rectangle(
|
||||||
{0, 0, portapack::display.width(), portapack::display.height()},
|
{0, 0, portapack::display.width(), portapack::display.height()},
|
||||||
ui::Color::black()
|
ui::Color::black());
|
||||||
);
|
|
||||||
|
|
||||||
painter.draw_string({12, 24}, this->nav_.style(), "This will take 15 seconds.");
|
painter.draw_string({12, 24}, this->nav_.style(), "This will take 15 seconds.");
|
||||||
painter.draw_string({12, 64}, this->nav_.style(), "Please wait while LEDs RX");
|
painter.draw_string({12, 64}, this->nav_.style(), "Please wait while LEDs RX");
|
||||||
|
|
|
@ -49,13 +49,11 @@ private:
|
||||||
static Thread* thread;
|
static Thread* thread;
|
||||||
|
|
||||||
Labels labels{
|
Labels labels{
|
||||||
{ { 4, 4 }, "Select firmware to flash:", Color::white() }
|
{{4, 4}, "Select firmware to flash:", Color::white()}};
|
||||||
};
|
|
||||||
|
|
||||||
MenuView menu_view{
|
MenuView menu_view{
|
||||||
{0, 2 * 8, 240, 26 * 8},
|
{0, 2 * 8, 240, 26 * 8},
|
||||||
true
|
true};
|
||||||
};
|
|
||||||
|
|
||||||
void firmware_selected(std::filesystem::path::string_type path);
|
void firmware_selected(std::filesystem::path::string_type path);
|
||||||
void flash_firmware(std::filesystem::path::string_type path);
|
void flash_firmware(std::filesystem::path::string_type path);
|
||||||
|
|
|
@ -32,15 +32,12 @@ namespace ui {
|
||||||
static int32_t last_category_id{0};
|
static int32_t last_category_id{0};
|
||||||
|
|
||||||
FreqManBaseView::FreqManBaseView(
|
FreqManBaseView::FreqManBaseView(
|
||||||
NavigationView& nav
|
NavigationView& nav)
|
||||||
) : nav_ (nav)
|
: nav_(nav) {
|
||||||
{
|
|
||||||
file_list = get_freqman_files();
|
file_list = get_freqman_files();
|
||||||
|
|
||||||
add_children({
|
add_children({&label_category,
|
||||||
&label_category,
|
&button_exit});
|
||||||
&button_exit
|
|
||||||
});
|
|
||||||
|
|
||||||
if (file_list.size()) {
|
if (file_list.size()) {
|
||||||
add_child(&options_category);
|
add_child(&options_category);
|
||||||
|
@ -94,7 +91,6 @@ void FreqManBaseView::populate_categories() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FreqManBaseView::change_category(int32_t category_id) {
|
void FreqManBaseView::change_category(int32_t category_id) {
|
||||||
|
|
||||||
if (!file_list.size()) return;
|
if (!file_list.size()) return;
|
||||||
|
|
||||||
last_category_id = current_category_id = category_id;
|
last_category_id = current_category_id = category_id;
|
||||||
|
@ -116,15 +112,13 @@ void FreqManBaseView::refresh_list() {
|
||||||
menu_view.clear();
|
menu_view.clear();
|
||||||
|
|
||||||
for (size_t n = 0; n < database.size(); n++) {
|
for (size_t n = 0; n < database.size(); n++) {
|
||||||
menu_view.add_item({
|
menu_view.add_item({freqman_item_string(database[n], 30),
|
||||||
freqman_item_string(database[n], 30),
|
|
||||||
ui::Color::white(),
|
ui::Color::white(),
|
||||||
nullptr,
|
nullptr,
|
||||||
[this](KeyEvent) {
|
[this](KeyEvent) {
|
||||||
if (on_select_frequency)
|
if (on_select_frequency)
|
||||||
on_select_frequency();
|
on_select_frequency();
|
||||||
}
|
}});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
menu_view.set_highlighted(0); // Refresh
|
menu_view.set_highlighted(0); // Refresh
|
||||||
|
@ -142,8 +136,7 @@ void FrequencySaveView::save_current_file() {
|
||||||
save_freqman_file(file_list[categories[current_category_id].second], database);
|
save_freqman_file(file_list[categories[current_category_id].second], database);
|
||||||
}
|
}
|
||||||
nav_.pop();
|
nav_.pop();
|
||||||
}
|
});
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
save_freqman_file(file_list[categories[current_category_id].second], database);
|
save_freqman_file(file_list[categories[current_category_id].second], database);
|
||||||
nav_.pop();
|
nav_.pop();
|
||||||
|
@ -164,10 +157,9 @@ void FrequencySaveView::on_save_timestamp() {
|
||||||
|
|
||||||
FrequencySaveView::FrequencySaveView(
|
FrequencySaveView::FrequencySaveView(
|
||||||
NavigationView& nav,
|
NavigationView& nav,
|
||||||
const rf::Frequency value
|
const rf::Frequency value)
|
||||||
) : FreqManBaseView(nav),
|
: FreqManBaseView(nav),
|
||||||
value_ (value)
|
value_(value) {
|
||||||
{
|
|
||||||
desc_buffer.reserve(28);
|
desc_buffer.reserve(28);
|
||||||
|
|
||||||
// Todo: add back ?
|
// Todo: add back ?
|
||||||
|
@ -178,13 +170,11 @@ FrequencySaveView::FrequencySaveView(
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
add_children({
|
add_children({&labels,
|
||||||
&labels,
|
|
||||||
&big_display,
|
&big_display,
|
||||||
&button_save_name,
|
&button_save_name,
|
||||||
&button_save_timestamp,
|
&button_save_timestamp,
|
||||||
&live_timestamp
|
&live_timestamp});
|
||||||
});
|
|
||||||
|
|
||||||
big_display.set(value);
|
big_display.set(value);
|
||||||
|
|
||||||
|
@ -204,17 +194,14 @@ void FrequencyLoadView::refresh_widgets(const bool v) {
|
||||||
}
|
}
|
||||||
|
|
||||||
FrequencyLoadView::FrequencyLoadView(
|
FrequencyLoadView::FrequencyLoadView(
|
||||||
NavigationView& nav
|
NavigationView& nav)
|
||||||
) : FreqManBaseView(nav)
|
: FreqManBaseView(nav) {
|
||||||
{
|
|
||||||
on_refresh_widgets = [this](bool v) {
|
on_refresh_widgets = [this](bool v) {
|
||||||
refresh_widgets(v);
|
refresh_widgets(v);
|
||||||
};
|
};
|
||||||
|
|
||||||
add_children({
|
add_children({&menu_view,
|
||||||
&menu_view,
|
&text_empty});
|
||||||
&text_empty
|
|
||||||
});
|
|
||||||
|
|
||||||
// Resize menu view to fill screen
|
// Resize menu view to fill screen
|
||||||
menu_view.set_parent_rect({0, 3 * 8, 240, 30 * 8});
|
menu_view.set_parent_rect({0, 3 * 8, 240, 30 * 8});
|
||||||
|
@ -291,22 +278,19 @@ FrequencyManagerView::~FrequencyManagerView() {
|
||||||
}
|
}
|
||||||
|
|
||||||
FrequencyManagerView::FrequencyManagerView(
|
FrequencyManagerView::FrequencyManagerView(
|
||||||
NavigationView& nav
|
NavigationView& nav)
|
||||||
) : FreqManBaseView(nav)
|
: FreqManBaseView(nav) {
|
||||||
{
|
|
||||||
on_refresh_widgets = [this](bool v) {
|
on_refresh_widgets = [this](bool v) {
|
||||||
refresh_widgets(v);
|
refresh_widgets(v);
|
||||||
};
|
};
|
||||||
|
|
||||||
add_children({
|
add_children({&labels,
|
||||||
&labels,
|
|
||||||
&button_new_category,
|
&button_new_category,
|
||||||
&menu_view,
|
&menu_view,
|
||||||
&text_empty,
|
&text_empty,
|
||||||
&button_edit_freq,
|
&button_edit_freq,
|
||||||
&button_edit_desc,
|
&button_edit_desc,
|
||||||
&button_delete
|
&button_delete});
|
||||||
});
|
|
||||||
|
|
||||||
// Just to allow exit on left
|
// Just to allow exit on left
|
||||||
menu_view.on_left = [&nav, this]() {
|
menu_view.on_left = [&nav, this]() {
|
||||||
|
@ -342,9 +326,8 @@ FrequencyManagerView::FrequencyManagerView(
|
||||||
[this](bool choice) {
|
[this](bool choice) {
|
||||||
if (choice)
|
if (choice)
|
||||||
on_delete();
|
on_delete();
|
||||||
}
|
});
|
||||||
);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace ui
|
||||||
|
|
|
@ -34,8 +34,7 @@ namespace ui {
|
||||||
class FreqManBaseView : public View {
|
class FreqManBaseView : public View {
|
||||||
public:
|
public:
|
||||||
FreqManBaseView(
|
FreqManBaseView(
|
||||||
NavigationView& nav
|
NavigationView& nav);
|
||||||
);
|
|
||||||
|
|
||||||
void focus() override;
|
void focus() override;
|
||||||
|
|
||||||
|
@ -59,19 +58,16 @@ protected:
|
||||||
freqman_db database{};
|
freqman_db database{};
|
||||||
|
|
||||||
Labels label_category{
|
Labels label_category{
|
||||||
{ { 0, 4 }, "Category:", Color::light_grey() }
|
{{0, 4}, "Category:", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField options_category{
|
OptionsField options_category{
|
||||||
{9 * 8, 4},
|
{9 * 8, 4},
|
||||||
14,
|
14,
|
||||||
{ }
|
{}};
|
||||||
};
|
|
||||||
|
|
||||||
MenuView menu_view{
|
MenuView menu_view{
|
||||||
{0, 3 * 8, 240, 23 * 8},
|
{0, 3 * 8, 240, 23 * 8},
|
||||||
true
|
true};
|
||||||
};
|
|
||||||
Text text_empty{
|
Text text_empty{
|
||||||
{7 * 8, 12 * 8, 16 * 8, 16},
|
{7 * 8, 12 * 8, 16 * 8, 16},
|
||||||
"Empty category !",
|
"Empty category !",
|
||||||
|
@ -79,8 +75,7 @@ protected:
|
||||||
|
|
||||||
Button button_exit{
|
Button button_exit{
|
||||||
{20 * 8, 34 * 8, 10 * 8, 4 * 8},
|
{20 * 8, 34 * 8, 10 * 8, 4 * 8},
|
||||||
"Exit"
|
"Exit"};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class FrequencySaveView : public FreqManBaseView {
|
class FrequencySaveView : public FreqManBaseView {
|
||||||
|
@ -99,24 +94,19 @@ private:
|
||||||
|
|
||||||
BigFrequency big_display{
|
BigFrequency big_display{
|
||||||
{4, 2 * 16, 28 * 8, 32},
|
{4, 2 * 16, 28 * 8, 32},
|
||||||
0
|
0};
|
||||||
};
|
|
||||||
|
|
||||||
Labels labels{
|
Labels labels{
|
||||||
{ { 1 * 8, 12 * 8 }, "Save as:", Color::white() }
|
{{1 * 8, 12 * 8}, "Save as:", Color::white()}};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_save_name{
|
Button button_save_name{
|
||||||
{1 * 8, 17 * 8, 12 * 8, 48},
|
{1 * 8, 17 * 8, 12 * 8, 48},
|
||||||
"Name (set)"
|
"Name (set)"};
|
||||||
};
|
|
||||||
Button button_save_timestamp{
|
Button button_save_timestamp{
|
||||||
{1 * 8, 25 * 8, 12 * 8, 48},
|
{1 * 8, 25 * 8, 12 * 8, 48},
|
||||||
"Timestamp:"
|
"Timestamp:"};
|
||||||
};
|
|
||||||
LiveDateTime live_timestamp{
|
LiveDateTime live_timestamp{
|
||||||
{ 14 * 8, 27 * 8, 16 * 8, 16 }
|
{14 * 8, 27 * 8, 16 * 8, 16}};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class FrequencyLoadView : public FreqManBaseView {
|
class FrequencyLoadView : public FreqManBaseView {
|
||||||
|
@ -149,27 +139,22 @@ private:
|
||||||
void on_delete();
|
void on_delete();
|
||||||
|
|
||||||
Labels labels{
|
Labels labels{
|
||||||
{ { 4 * 8 + 4, 26 * 8 }, "Edit:", Color::light_grey() }
|
{{4 * 8 + 4, 26 * 8}, "Edit:", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_new_category{
|
Button button_new_category{
|
||||||
{23 * 8, 2, 7 * 8, 20},
|
{23 * 8, 2, 7 * 8, 20},
|
||||||
"New"
|
"New"};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_edit_freq{
|
Button button_edit_freq{
|
||||||
{0 * 8, 29 * 8, 14 * 8, 32},
|
{0 * 8, 29 * 8, 14 * 8, 32},
|
||||||
"Frequency"
|
"Frequency"};
|
||||||
};
|
|
||||||
Button button_edit_desc{
|
Button button_edit_desc{
|
||||||
{0 * 8, 34 * 8, 14 * 8, 32},
|
{0 * 8, 34 * 8, 14 * 8, 32},
|
||||||
"Description"
|
"Description"};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_delete{
|
Button button_delete{
|
||||||
{18 * 8, 27 * 8, 12 * 8, 32},
|
{18 * 8, 27 * 8, 12 * 8, 32},
|
||||||
"Delete"
|
"Delete"};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -121,15 +121,13 @@ void RangeView::paint(Painter&) {
|
||||||
RangeView::RangeView(NavigationView& nav) {
|
RangeView::RangeView(NavigationView& nav) {
|
||||||
hidden(true);
|
hidden(true);
|
||||||
|
|
||||||
add_children({
|
add_children({&labels,
|
||||||
&labels,
|
|
||||||
&check_enabled,
|
&check_enabled,
|
||||||
&button_load_range,
|
&button_load_range,
|
||||||
&button_start,
|
&button_start,
|
||||||
&button_stop,
|
&button_stop,
|
||||||
&button_center,
|
&button_center,
|
||||||
&button_width
|
&button_width});
|
||||||
});
|
|
||||||
|
|
||||||
check_enabled.on_select = [this](Checkbox&, bool v) {
|
check_enabled.on_select = [this](Checkbox&, bool v) {
|
||||||
frequency_range.enabled = v;
|
frequency_range.enabled = v;
|
||||||
|
@ -220,7 +218,6 @@ void JammerView::start_tx() {
|
||||||
// Generate jamming channels with JAMMER_MAX_CH maximum width
|
// Generate jamming channels with JAMMER_MAX_CH maximum width
|
||||||
// Convert ranges min/max to center/bw
|
// Convert ranges min/max to center/bw
|
||||||
for (size_t r = 0; r < 3; r++) {
|
for (size_t r = 0; r < 3; r++) {
|
||||||
|
|
||||||
if (range_views[r]->frequency_range.enabled) {
|
if (range_views[r]->frequency_range.enabled) {
|
||||||
range_bw = abs(range_views[r]->frequency_range.max - range_views[r]->frequency_range.min);
|
range_bw = abs(range_views[r]->frequency_range.max - range_views[r]->frequency_range.min);
|
||||||
|
|
||||||
|
@ -299,19 +296,15 @@ void JammerView::stop_tx() {
|
||||||
void JammerView::on_timer() {
|
void JammerView::on_timer() {
|
||||||
if (++mscounter == 60) {
|
if (++mscounter == 60) {
|
||||||
mscounter = 0;
|
mscounter = 0;
|
||||||
if (jamming)
|
if (jamming) {
|
||||||
{
|
if (cooling) {
|
||||||
if (cooling)
|
if (++seconds >= field_timepause.value()) { // Re-start TX
|
||||||
{
|
|
||||||
if (++seconds >= field_timepause.value())
|
|
||||||
{ //Re-start TX
|
|
||||||
transmitter_model.enable();
|
transmitter_model.enable();
|
||||||
button_transmit.set_text("STOP");
|
button_transmit.set_text("STOP");
|
||||||
baseband::set_jammer(true, (JammerType)options_type.selected_index(), options_speed.selected_index_value());
|
baseband::set_jammer(true, (JammerType)options_type.selected_index(), options_speed.selected_index_value());
|
||||||
|
|
||||||
int32_t jitter_amount = field_jitter.value();
|
int32_t jitter_amount = field_jitter.value();
|
||||||
if (jitter_amount)
|
if (jitter_amount) {
|
||||||
{
|
|
||||||
lfsr_v = lfsr_iterate(lfsr_v);
|
lfsr_v = lfsr_iterate(lfsr_v);
|
||||||
jitter_amount = (jitter_amount / 2) - (lfsr_v & jitter_amount);
|
jitter_amount = (jitter_amount / 2) - (lfsr_v & jitter_amount);
|
||||||
mscounter += jitter_amount;
|
mscounter += jitter_amount;
|
||||||
|
@ -320,9 +313,7 @@ void JammerView::on_timer() {
|
||||||
cooling = false;
|
cooling = false;
|
||||||
seconds = 0;
|
seconds = 0;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
if (++seconds >= field_timetx.value()) // Start cooling period:
|
if (++seconds >= field_timetx.value()) // Start cooling period:
|
||||||
{
|
{
|
||||||
transmitter_model.disable();
|
transmitter_model.disable();
|
||||||
|
@ -330,8 +321,7 @@ void JammerView::on_timer() {
|
||||||
baseband::set_jammer(false, JammerType::TYPE_FSK, 0);
|
baseband::set_jammer(false, JammerType::TYPE_FSK, 0);
|
||||||
|
|
||||||
int32_t jitter_amount = field_jitter.value();
|
int32_t jitter_amount = field_jitter.value();
|
||||||
if (jitter_amount)
|
if (jitter_amount) {
|
||||||
{
|
|
||||||
lfsr_v = lfsr_iterate(lfsr_v);
|
lfsr_v = lfsr_iterate(lfsr_v);
|
||||||
jitter_amount = (jitter_amount / 2) - (lfsr_v & jitter_amount);
|
jitter_amount = (jitter_amount / 2) - (lfsr_v & jitter_amount);
|
||||||
mscounter += jitter_amount;
|
mscounter += jitter_amount;
|
||||||
|
@ -341,21 +331,17 @@ void JammerView::on_timer() {
|
||||||
seconds = 0;
|
seconds = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JammerView::JammerView(
|
JammerView::JammerView(
|
||||||
NavigationView& nav
|
NavigationView& nav)
|
||||||
) : nav_ { nav }
|
: nav_{nav} {
|
||||||
{
|
|
||||||
Rect view_rect = {0, 3 * 8, 240, 80};
|
Rect view_rect = {0, 3 * 8, 240, 80};
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_jammer);
|
baseband::run_image(portapack::spi_flash::image_tag_jammer);
|
||||||
|
|
||||||
add_children({
|
add_children({&tab_view,
|
||||||
&tab_view,
|
|
||||||
&view_range_a,
|
&view_range_a,
|
||||||
&view_range_b,
|
&view_range_b,
|
||||||
&view_range_c,
|
&view_range_c,
|
||||||
|
@ -370,8 +356,7 @@ JammerView::JammerView(
|
||||||
&field_jitter,
|
&field_jitter,
|
||||||
&field_gain,
|
&field_gain,
|
||||||
&field_amp,
|
&field_amp,
|
||||||
&button_transmit
|
&button_transmit});
|
||||||
});
|
|
||||||
|
|
||||||
view_range_a.set_parent_rect(view_rect);
|
view_range_a.set_parent_rect(view_rect);
|
||||||
view_range_b.set_parent_rect(view_rect);
|
view_range_b.set_parent_rect(view_rect);
|
||||||
|
|
|
@ -62,36 +62,29 @@ private:
|
||||||
{{2 * 8, 8 * 8 + 4}, "Start", Color::light_grey()},
|
{{2 * 8, 8 * 8 + 4}, "Start", Color::light_grey()},
|
||||||
{{23 * 8, 8 * 8 + 4}, "Stop", Color::light_grey()},
|
{{23 * 8, 8 * 8 + 4}, "Stop", Color::light_grey()},
|
||||||
{{12 * 8, 5 * 8 - 4}, "Center", Color::light_grey()},
|
{{12 * 8, 5 * 8 - 4}, "Center", Color::light_grey()},
|
||||||
{ { 12 * 8 + 4, 13 * 8 }, "Width", Color::light_grey() }
|
{{12 * 8 + 4, 13 * 8}, "Width", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
Checkbox check_enabled{
|
Checkbox check_enabled{
|
||||||
{1 * 8, 4},
|
{1 * 8, 4},
|
||||||
12,
|
12,
|
||||||
"Enable range"
|
"Enable range"};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_load_range{
|
Button button_load_range{
|
||||||
{18 * 8, 4, 12 * 8, 24},
|
{18 * 8, 4, 12 * 8, 24},
|
||||||
"Load range"
|
"Load range"};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_start{
|
Button button_start{
|
||||||
{0 * 8, 11 * 8, 11 * 8, 28},
|
{0 * 8, 11 * 8, 11 * 8, 28},
|
||||||
""
|
""};
|
||||||
};
|
|
||||||
Button button_stop{
|
Button button_stop{
|
||||||
{19 * 8, 11 * 8, 11 * 8, 28},
|
{19 * 8, 11 * 8, 11 * 8, 28},
|
||||||
""
|
""};
|
||||||
};
|
|
||||||
Button button_center{
|
Button button_center{
|
||||||
{76, 4 * 15 - 4, 11 * 8, 28},
|
{76, 4 * 15 - 4, 11 * 8, 28},
|
||||||
""
|
""};
|
||||||
};
|
|
||||||
Button button_width{
|
Button button_width{
|
||||||
{76, 8 * 15, 11 * 8, 28},
|
{76, 8 * 15, 11 * 8, 28},
|
||||||
""
|
""};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class JammerView : public View {
|
class JammerView : public View {
|
||||||
|
@ -158,8 +151,7 @@ private:
|
||||||
{{11 * 8, 31 * 8}, "Secs.", Color::light_grey()},
|
{{11 * 8, 31 * 8}, "Secs.", Color::light_grey()},
|
||||||
{{11 * 8, 33 * 8}, "/60", Color::light_grey()},
|
{{11 * 8, 33 * 8}, "/60", Color::light_grey()},
|
||||||
{{2 * 8, 35 * 8}, "Gain:", Color::light_grey()},
|
{{2 * 8, 35 * 8}, "Gain:", Color::light_grey()},
|
||||||
{ { 11 * 8, 35 * 8 }, "A:", Color::light_grey() }
|
{{11 * 8, 35 * 8}, "A:", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField options_type{
|
OptionsField options_type{
|
||||||
{7 * 8, 23 * 8},
|
{7 * 8, 23 * 8},
|
||||||
|
@ -169,43 +161,34 @@ private:
|
||||||
{"FM tone", 1},
|
{"FM tone", 1},
|
||||||
{"CW sweep", 2},
|
{"CW sweep", 2},
|
||||||
{"Rand CW", 3},
|
{"Rand CW", 3},
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_range_number{
|
Text text_range_number{
|
||||||
{16 * 8, 23 * 8, 2 * 8, 16},
|
{16 * 8, 23 * 8, 2 * 8, 16},
|
||||||
"--"
|
"--"};
|
||||||
};
|
|
||||||
Text text_range_total{
|
Text text_range_total{
|
||||||
{18 * 8, 23 * 8, 3 * 8, 16},
|
{18 * 8, 23 * 8, 3 * 8, 16},
|
||||||
"/--"
|
"/--"};
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField options_speed{
|
OptionsField options_speed{
|
||||||
{7 * 8, 25 * 8},
|
{7 * 8, 25 * 8},
|
||||||
6,
|
6,
|
||||||
{
|
{{"10Hz ", 10},
|
||||||
{ "10Hz ", 10 },
|
|
||||||
{"100Hz ", 100},
|
{"100Hz ", 100},
|
||||||
{"1kHz ", 1000},
|
{"1kHz ", 1000},
|
||||||
{"10kHz ", 10000},
|
{"10kHz ", 10000},
|
||||||
{ "100kHz", 100000 }
|
{"100kHz", 100000}}};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField options_hop{
|
OptionsField options_hop{
|
||||||
{7 * 8, 27 * 8},
|
{7 * 8, 27 * 8},
|
||||||
5,
|
5,
|
||||||
{
|
{{"10ms ", 1},
|
||||||
{ "10ms ", 1 },
|
|
||||||
{"50ms ", 5},
|
{"50ms ", 5},
|
||||||
{"100ms", 10},
|
{"100ms", 10},
|
||||||
{"1s ", 100},
|
{"1s ", 100},
|
||||||
{"2s ", 200},
|
{"2s ", 200},
|
||||||
{"5s ", 500},
|
{"5s ", 500},
|
||||||
{ "10s ", 1000 }
|
{"10s ", 1000}}};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_timetx{
|
NumberField field_timetx{
|
||||||
{7 * 8, 29 * 8},
|
{7 * 8, 29 * 8},
|
||||||
|
@ -249,24 +232,20 @@ private:
|
||||||
|
|
||||||
Button button_transmit{
|
Button button_transmit{
|
||||||
{148, 216, 80, 80},
|
{148, 216, 80, 80},
|
||||||
"START"
|
"START"};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_retune{
|
MessageHandlerRegistration message_handler_retune{
|
||||||
Message::ID::Retune,
|
Message::ID::Retune,
|
||||||
[this](Message* const p) {
|
[this](Message* const p) {
|
||||||
const auto message = static_cast<const RetuneMessage*>(p);
|
const auto message = static_cast<const RetuneMessage*>(p);
|
||||||
this->on_retune(message->freq, message->range);
|
this->on_retune(message->freq, message->range);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_frame_sync{
|
MessageHandlerRegistration message_handler_frame_sync{
|
||||||
Message::ID::DisplayFrameSync,
|
Message::ID::DisplayFrameSync,
|
||||||
[this](const Message* const) {
|
[this](const Message* const) {
|
||||||
this->on_timer();
|
this->on_timer();
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
||||||
|
|
|
@ -203,21 +203,18 @@ void KeyfobView::start_tx() {
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyfobView::KeyfobView(
|
KeyfobView::KeyfobView(
|
||||||
NavigationView& nav
|
NavigationView& nav)
|
||||||
) : nav_ { nav }
|
: nav_{nav} {
|
||||||
{
|
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_ook);
|
baseband::run_image(portapack::spi_flash::image_tag_ook);
|
||||||
|
|
||||||
add_children({
|
add_children({&labels,
|
||||||
&labels,
|
|
||||||
&options_make,
|
&options_make,
|
||||||
&options_command,
|
&options_command,
|
||||||
&field_payload_a,
|
&field_payload_a,
|
||||||
&field_payload_b,
|
&field_payload_b,
|
||||||
&text_status,
|
&text_status,
|
||||||
&progressbar,
|
&progressbar,
|
||||||
&tx_view
|
&tx_view});
|
||||||
});
|
|
||||||
|
|
||||||
// load app settings
|
// load app settings
|
||||||
auto rc = settings.load("tx_keyfob", &app_settings);
|
auto rc = settings.load("tx_keyfob", &app_settings);
|
||||||
|
|
|
@ -81,56 +81,44 @@ private:
|
||||||
OptionsField options_make{
|
OptionsField options_make{
|
||||||
{10 * 8, 1 * 16},
|
{10 * 8, 1 * 16},
|
||||||
8,
|
8,
|
||||||
{
|
{{"Subaru", 0}}};
|
||||||
{ "Subaru", 0 }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField options_command{
|
OptionsField options_command{
|
||||||
{10 * 8, 2 * 16},
|
{10 * 8, 2 * 16},
|
||||||
6,
|
6,
|
||||||
{
|
{{"Lock", 1},
|
||||||
{ "Lock", 1 },
|
|
||||||
{"Unlock", 2},
|
{"Unlock", 2},
|
||||||
{"Trunk", 11},
|
{"Trunk", 11},
|
||||||
{ "Panic", 10 }
|
{"Panic", 10}}};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
SymField field_payload_a{
|
SymField field_payload_a{
|
||||||
{2 * 8, 5 * 16},
|
{2 * 8, 5 * 16},
|
||||||
10,
|
10,
|
||||||
SymField::SYMFIELD_HEX
|
SymField::SYMFIELD_HEX};
|
||||||
};
|
|
||||||
SymField field_payload_b{
|
SymField field_payload_b{
|
||||||
{13 * 8, 5 * 16},
|
{13 * 8, 5 * 16},
|
||||||
10,
|
10,
|
||||||
SymField::SYMFIELD_HEX
|
SymField::SYMFIELD_HEX};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_status{
|
Text text_status{
|
||||||
{2 * 8, 13 * 16, 128, 16},
|
{2 * 8, 13 * 16, 128, 16},
|
||||||
"Ready"
|
"Ready"};
|
||||||
};
|
|
||||||
|
|
||||||
ProgressBar progressbar{
|
ProgressBar progressbar{
|
||||||
{ 2 * 8, 13 * 16 + 20, 208, 16 }
|
{2 * 8, 13 * 16 + 20, 208, 16}};
|
||||||
};
|
|
||||||
|
|
||||||
TransmitterView tx_view{
|
TransmitterView tx_view{
|
||||||
16 * 16,
|
16 * 16,
|
||||||
0,
|
0,
|
||||||
15,
|
15,
|
||||||
true
|
true};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_tx_progress{
|
MessageHandlerRegistration message_handler_tx_progress{
|
||||||
Message::ID::TXProgress,
|
Message::ID::TXProgress,
|
||||||
[this](const Message* const p) {
|
[this](const Message* const p) {
|
||||||
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
|
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
|
||||||
this->on_tx_progress(message.progress, message.done);
|
this->on_tx_progress(message.progress, message.done);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -147,8 +147,7 @@ void LCRView::start_tx(const bool scan) {
|
||||||
persistent_memory::afsk_space_freq(),
|
persistent_memory::afsk_space_freq(),
|
||||||
repeats,
|
repeats,
|
||||||
transmitter_model.channel_bandwidth(),
|
transmitter_model.channel_bandwidth(),
|
||||||
serializer::symbol_count(persistent_memory::serial_format())
|
serializer::symbol_count(persistent_memory::serial_format()));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LCRView::on_button_set_am(NavigationView& nav, int16_t button_id) {
|
void LCRView::on_button_set_am(NavigationView& nav, int16_t button_id) {
|
||||||
|
@ -166,8 +165,7 @@ LCRView::LCRView(NavigationView& nav) {
|
||||||
|
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_afsk);
|
baseband::run_image(portapack::spi_flash::image_tag_afsk);
|
||||||
|
|
||||||
add_children({
|
add_children({&labels,
|
||||||
&labels,
|
|
||||||
&options_ec,
|
&options_ec,
|
||||||
&button_set_rgsb,
|
&button_set_rgsb,
|
||||||
&button_modem_setup,
|
&button_modem_setup,
|
||||||
|
@ -176,8 +174,7 @@ LCRView::LCRView(NavigationView& nav) {
|
||||||
&options_scanlist,
|
&options_scanlist,
|
||||||
&check_scan,
|
&check_scan,
|
||||||
&button_clear,
|
&button_clear,
|
||||||
&tx_view
|
&tx_view});
|
||||||
});
|
|
||||||
|
|
||||||
// load app settings
|
// load app settings
|
||||||
auto rc = settings.load("tx_lcr", &app_settings);
|
auto rc = settings.load("tx_lcr", &app_settings);
|
||||||
|
@ -199,38 +196,30 @@ LCRView::LCRView(NavigationView& nav) {
|
||||||
button->on_select = button_set_am_fn;
|
button->on_select = button_set_am_fn;
|
||||||
button->id = n;
|
button->id = n;
|
||||||
button->set_text("AM " + to_string_dec_uint(n + 1));
|
button->set_text("AM " + to_string_dec_uint(n + 1));
|
||||||
button->set_parent_rect({
|
button->set_parent_rect({static_cast<Coord>(40),
|
||||||
static_cast<Coord>(40),
|
|
||||||
static_cast<Coord>(n * 32 + 64),
|
static_cast<Coord>(n * 32 + 64),
|
||||||
48, 24
|
48, 24});
|
||||||
});
|
|
||||||
add_child(button);
|
add_child(button);
|
||||||
|
|
||||||
Checkbox* checkbox = &checkboxes[n];
|
Checkbox* checkbox = &checkboxes[n];
|
||||||
checkbox->set_parent_rect({
|
checkbox->set_parent_rect({static_cast<Coord>(8),
|
||||||
static_cast<Coord>(8),
|
|
||||||
static_cast<Coord>(n * 32 + 64),
|
static_cast<Coord>(n * 32 + 64),
|
||||||
48, 24
|
48, 24});
|
||||||
});
|
|
||||||
checkbox->set_value(false);
|
checkbox->set_value(false);
|
||||||
add_child(checkbox);
|
add_child(checkbox);
|
||||||
|
|
||||||
Rectangle* rectangle = &rectangles[n];
|
Rectangle* rectangle = &rectangles[n];
|
||||||
rectangle->set_parent_rect({
|
rectangle->set_parent_rect({static_cast<Coord>(98),
|
||||||
static_cast<Coord>(98),
|
|
||||||
static_cast<Coord>(n * 32 + 66),
|
static_cast<Coord>(n * 32 + 66),
|
||||||
68, 20
|
68, 20});
|
||||||
});
|
|
||||||
rectangle->set_color(ui::Color::grey());
|
rectangle->set_color(ui::Color::grey());
|
||||||
rectangle->set_outline(true);
|
rectangle->set_outline(true);
|
||||||
add_child(rectangle);
|
add_child(rectangle);
|
||||||
|
|
||||||
Text* text = &texts[n];
|
Text* text = &texts[n];
|
||||||
text->set_parent_rect({
|
text->set_parent_rect({static_cast<Coord>(104),
|
||||||
static_cast<Coord>(104),
|
|
||||||
static_cast<Coord>(n * 32 + 68),
|
static_cast<Coord>(n * 32 + 68),
|
||||||
7 * 8, 16
|
7 * 8, 16});
|
||||||
});
|
|
||||||
add_child(text);
|
add_child(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,8 +50,7 @@ private:
|
||||||
|
|
||||||
const scan_list_t scan_list[2] = {
|
const scan_list_t scan_list[2] = {
|
||||||
{36, &RGSB_list_Lille[0]},
|
{36, &RGSB_list_Lille[0]},
|
||||||
{ 20, &RGSB_list_Reims[0] }
|
{20, &RGSB_list_Reims[0]}};
|
||||||
};
|
|
||||||
|
|
||||||
const std::string RGSB_list_Lille[36] = {
|
const std::string RGSB_list_Lille[36] = {
|
||||||
"AI10", "AI20", "AI30", "AI40",
|
"AI10", "AI20", "AI30", "AI40",
|
||||||
|
@ -63,8 +62,7 @@ private:
|
||||||
"EbE0", "EbF0", "EbG0", "EbH0",
|
"EbE0", "EbF0", "EbG0", "EbH0",
|
||||||
"EbI0", "EbJ0", "EbK0", "EbL0",
|
"EbI0", "EbJ0", "EbK0", "EbL0",
|
||||||
"EbM0", "EbN0", "EbO0", "EbP0",
|
"EbM0", "EbN0", "EbO0", "EbP0",
|
||||||
"EbS0"
|
"EbS0"};
|
||||||
};
|
|
||||||
|
|
||||||
const std::string RGSB_list_Reims[20] = {
|
const std::string RGSB_list_Reims[20] = {
|
||||||
"AI10", "AI20", "AI30", "AI40",
|
"AI10", "AI20", "AI30", "AI40",
|
||||||
|
@ -73,8 +71,7 @@ private:
|
||||||
"AJ50", "AJ60", "AJ70",
|
"AJ50", "AJ60", "AJ70",
|
||||||
"AK10", "AK20", "AK50", "AK60",
|
"AK10", "AK20", "AK50", "AK60",
|
||||||
"AK70",
|
"AK70",
|
||||||
"AP10"
|
"AP10"};
|
||||||
};
|
|
||||||
|
|
||||||
enum tx_modes {
|
enum tx_modes {
|
||||||
IDLE = 0,
|
IDLE = 0,
|
||||||
|
@ -101,8 +98,7 @@ private:
|
||||||
|
|
||||||
Labels labels{
|
Labels labels{
|
||||||
{{0, 8}, "EC: RGSB:", Color::light_grey()},
|
{{0, 8}, "EC: RGSB:", Color::light_grey()},
|
||||||
{ { 17 * 8, 4 * 8 }, "List:", Color::light_grey() }
|
{{17 * 8, 4 * 8}, "List:", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
std::array<Button, LCR_MAX_AM> buttons{};
|
std::array<Button, LCR_MAX_AM> buttons{};
|
||||||
std::array<Checkbox, LCR_MAX_AM> checkboxes{};
|
std::array<Checkbox, LCR_MAX_AM> checkboxes{};
|
||||||
|
@ -112,62 +108,48 @@ private:
|
||||||
OptionsField options_ec{
|
OptionsField options_ec{
|
||||||
{3 * 8, 8},
|
{3 * 8, 8},
|
||||||
4,
|
4,
|
||||||
{
|
{{"Auto", 0},
|
||||||
{ "Auto", 0 },
|
|
||||||
{"Jour", 1},
|
{"Jour", 1},
|
||||||
{"Nuit", 2},
|
{"Nuit", 2},
|
||||||
{ "S ? ", 3 }
|
{"S ? ", 3}}};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Button button_set_rgsb{
|
Button button_set_rgsb{
|
||||||
{13 * 8, 4, 8 * 8, 24},
|
{13 * 8, 4, 8 * 8, 24},
|
||||||
"RGSB"
|
"RGSB"};
|
||||||
};
|
|
||||||
Checkbox check_scan{
|
Checkbox check_scan{
|
||||||
{22 * 8, 4},
|
{22 * 8, 4},
|
||||||
4,
|
4,
|
||||||
"Scan"
|
"Scan"};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_modem_setup{
|
Button button_modem_setup{
|
||||||
{1 * 8, 4 * 8 + 2, 14 * 8, 24},
|
{1 * 8, 4 * 8 + 2, 14 * 8, 24},
|
||||||
"Modem setup"
|
"Modem setup"};
|
||||||
};
|
|
||||||
OptionsField options_scanlist{
|
OptionsField options_scanlist{
|
||||||
{22 * 8, 4 * 8},
|
{22 * 8, 4 * 8},
|
||||||
6,
|
6,
|
||||||
{
|
{{"Reims ", 1}}};
|
||||||
{ "Reims ", 1 }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Button button_clear{
|
Button button_clear{
|
||||||
{22 * 8, 8 * 8, 7 * 8, 19 * 8},
|
{22 * 8, 8 * 8, 7 * 8, 19 * 8},
|
||||||
"CLEAR"
|
"CLEAR"};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_status{
|
Text text_status{
|
||||||
{2 * 8, 27 * 8 + 4, 26 * 8, 16},
|
{2 * 8, 27 * 8 + 4, 26 * 8, 16},
|
||||||
"Ready"
|
"Ready"};
|
||||||
};
|
|
||||||
ProgressBar progress{
|
ProgressBar progress{
|
||||||
{ 2 * 8, 29 * 8 + 4, 26 * 8, 16 }
|
{2 * 8, 29 * 8 + 4, 26 * 8, 16}};
|
||||||
};
|
|
||||||
|
|
||||||
TransmitterView tx_view{
|
TransmitterView tx_view{
|
||||||
16 * 16,
|
16 * 16,
|
||||||
10000,
|
10000,
|
||||||
12
|
12};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_tx_progress{
|
MessageHandlerRegistration message_handler_tx_progress{
|
||||||
Message::ID::TXProgress,
|
Message::ID::TXProgress,
|
||||||
[this](const Message* const p) {
|
[this](const Message* const p) {
|
||||||
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
|
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
|
||||||
this->on_tx_progress(message.progress, message.done);
|
this->on_tx_progress(message.progress, message.done);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -29,8 +29,7 @@ using portapack::memory::map::backup_ram;
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
bool LevelView::check_sd_card()
|
bool LevelView::check_sd_card() {
|
||||||
{
|
|
||||||
return (sd_card::status() == sd_card::Status::Mounted) ? true : false;
|
return (sd_card::status() == sd_card::Status::Mounted) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +38,6 @@ namespace ui {
|
||||||
}
|
}
|
||||||
|
|
||||||
LevelView::~LevelView() {
|
LevelView::~LevelView() {
|
||||||
|
|
||||||
// save app settings
|
// save app settings
|
||||||
app_settings.lna = field_lna.value();
|
app_settings.lna = field_lna.value();
|
||||||
app_settings.vga = field_vga.value();
|
app_settings.vga = field_vga.value();
|
||||||
|
@ -51,10 +49,9 @@ namespace ui {
|
||||||
baseband::shutdown();
|
baseband::shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
LevelView::LevelView( NavigationView& nav) : nav_ { nav } {
|
LevelView::LevelView(NavigationView& nav)
|
||||||
|
: nav_{nav} {
|
||||||
add_children( {
|
add_children({&labels,
|
||||||
&labels,
|
|
||||||
&field_lna,
|
&field_lna,
|
||||||
&field_vga,
|
&field_vga,
|
||||||
&field_rf_amp,
|
&field_rf_amp,
|
||||||
|
@ -70,8 +67,7 @@ namespace ui {
|
||||||
&audio_mode,
|
&audio_mode,
|
||||||
&peak_mode,
|
&peak_mode,
|
||||||
&rssi,
|
&rssi,
|
||||||
&rssi_graph
|
&rssi_graph});
|
||||||
} );
|
|
||||||
|
|
||||||
rssi.set_vertical_rssi(true);
|
rssi.set_vertical_rssi(true);
|
||||||
|
|
||||||
|
@ -93,8 +89,7 @@ namespace ui {
|
||||||
button_frequency.set_text("<" + to_string_short_freq(freq) + " MHz>");
|
button_frequency.set_text("<" + to_string_short_freq(freq) + " MHz>");
|
||||||
|
|
||||||
// load auto common app settings
|
// load auto common app settings
|
||||||
if( sd_card_mounted )
|
if (sd_card_mounted) {
|
||||||
{
|
|
||||||
auto rc = settings.load("level", &app_settings);
|
auto rc = settings.load("level", &app_settings);
|
||||||
if (rc == SETTINGS_OK) {
|
if (rc == SETTINGS_OK) {
|
||||||
field_lna.set_value(app_settings.lna);
|
field_lna.set_value(app_settings.lna);
|
||||||
|
@ -116,12 +111,10 @@ namespace ui {
|
||||||
button_frequency.on_change = [this]() {
|
button_frequency.on_change = [this]() {
|
||||||
int64_t def_step = freqman_entry_get_step_value(step_mode.selected_index());
|
int64_t def_step = freqman_entry_get_step_value(step_mode.selected_index());
|
||||||
freq = freq + (button_frequency.get_encoder_delta() * def_step);
|
freq = freq + (button_frequency.get_encoder_delta() * def_step);
|
||||||
if( freq < 1 )
|
if (freq < 1) {
|
||||||
{
|
|
||||||
freq = 1;
|
freq = 1;
|
||||||
}
|
}
|
||||||
if( freq > ( MAX_UFREQ - def_step ) )
|
if (freq > (MAX_UFREQ - def_step)) {
|
||||||
{
|
|
||||||
freq = MAX_UFREQ;
|
freq = MAX_UFREQ;
|
||||||
}
|
}
|
||||||
button_frequency.set_encoder_delta(0);
|
button_frequency.set_encoder_delta(0);
|
||||||
|
@ -131,13 +124,11 @@ namespace ui {
|
||||||
};
|
};
|
||||||
|
|
||||||
field_mode.on_change = [this](size_t, OptionsField::value_t v) {
|
field_mode.on_change = [this](size_t, OptionsField::value_t v) {
|
||||||
if( v != -1 )
|
if (v != -1) {
|
||||||
{
|
|
||||||
receiver_model.disable();
|
receiver_model.disable();
|
||||||
baseband::shutdown();
|
baseband::shutdown();
|
||||||
change_mode(v);
|
change_mode(v);
|
||||||
if( audio_mode.selected_index() != 0 )
|
if (audio_mode.selected_index() != 0) {
|
||||||
{
|
|
||||||
audio::output::start();
|
audio::output::start();
|
||||||
}
|
}
|
||||||
receiver_model.enable();
|
receiver_model.enable();
|
||||||
|
@ -145,36 +136,25 @@ namespace ui {
|
||||||
};
|
};
|
||||||
|
|
||||||
rssi_resolution.on_change = [this](size_t, OptionsField::value_t v) {
|
rssi_resolution.on_change = [this](size_t, OptionsField::value_t v) {
|
||||||
if( v != -1 )
|
if (v != -1) {
|
||||||
{
|
|
||||||
rssi_graph.set_nb_columns(v);
|
rssi_graph.set_nb_columns(v);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
audio_mode.on_change = [this](size_t, OptionsField::value_t v) {
|
audio_mode.on_change = [this](size_t, OptionsField::value_t v) {
|
||||||
if( v == 0 )
|
if (v == 0) {
|
||||||
{
|
|
||||||
audio::output::stop();
|
audio::output::stop();
|
||||||
}
|
} else if (v == 1) {
|
||||||
else if( v == 1 )
|
|
||||||
{
|
|
||||||
audio::output::start();
|
audio::output::start();
|
||||||
this->on_headphone_volume_changed((receiver_model.headphone_volume() - audio::headphone::volume_range().max).decibel() + 99);
|
this->on_headphone_volume_changed((receiver_model.headphone_volume() - audio::headphone::volume_range().max).decibel() + 99);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
peak_mode.on_change = [this](size_t, OptionsField::value_t v) {
|
peak_mode.on_change = [this](size_t, OptionsField::value_t v) {
|
||||||
if( v == 0 )
|
if (v == 0) {
|
||||||
{
|
|
||||||
rssi.set_peak(false, 0);
|
rssi.set_peak(false, 0);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
rssi.set_peak(true, v);
|
rssi.set_peak(true, v);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -194,7 +174,6 @@ namespace ui {
|
||||||
receiver_model.set_headphone_volume(new_volume);
|
receiver_model.set_headphone_volume(new_volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LevelView::on_statistics_update(const ChannelStatistics& statistics) {
|
void LevelView::on_statistics_update(const ChannelStatistics& statistics) {
|
||||||
static int last_max_db = -1000;
|
static int last_max_db = -1000;
|
||||||
static int last_min_rssi = -1000;
|
static int last_min_rssi = -1000;
|
||||||
|
@ -206,21 +185,17 @@ namespace ui {
|
||||||
bool refresh_db = false;
|
bool refresh_db = false;
|
||||||
bool refresh_rssi = false;
|
bool refresh_rssi = false;
|
||||||
|
|
||||||
if( last_max_db != statistics.max_db )
|
if (last_max_db != statistics.max_db) {
|
||||||
{
|
|
||||||
refresh_db = true;
|
refresh_db = true;
|
||||||
}
|
}
|
||||||
if( last_min_rssi != rssi.get_min() || last_avg_rssi != rssi.get_avg() || last_max_rssi != rssi.get_max() )
|
if (last_min_rssi != rssi.get_min() || last_avg_rssi != rssi.get_avg() || last_max_rssi != rssi.get_max()) {
|
||||||
{
|
|
||||||
refresh_rssi = true;
|
refresh_rssi = true;
|
||||||
}
|
}
|
||||||
if( refresh_db )
|
if (refresh_db) {
|
||||||
{
|
|
||||||
last_max_db = statistics.max_db;
|
last_max_db = statistics.max_db;
|
||||||
freq_stats_db.set("Power: " + to_string_dec_int(statistics.max_db) + " db");
|
freq_stats_db.set("Power: " + to_string_dec_int(statistics.max_db) + " db");
|
||||||
}
|
}
|
||||||
if( refresh_rssi )
|
if (refresh_rssi) {
|
||||||
{
|
|
||||||
last_min_rssi = rssi.get_min();
|
last_min_rssi = rssi.get_min();
|
||||||
last_avg_rssi = rssi.get_avg();
|
last_avg_rssi = rssi.get_avg();
|
||||||
last_max_rssi = rssi.get_max();
|
last_max_rssi = rssi.get_max();
|
||||||
|
@ -229,7 +204,6 @@ namespace ui {
|
||||||
} /* on_statistic_updates */
|
} /* on_statistic_updates */
|
||||||
|
|
||||||
size_t LevelView::change_mode(freqman_index_t new_mod) {
|
size_t LevelView::change_mode(freqman_index_t new_mod) {
|
||||||
|
|
||||||
field_bw.on_change = [this](size_t n, OptionsField::value_t) { (void)n; };
|
field_bw.on_change = [this](size_t n, OptionsField::value_t) { (void)n; };
|
||||||
|
|
||||||
switch (new_mod) {
|
switch (new_mod) {
|
||||||
|
@ -241,7 +215,8 @@ namespace ui {
|
||||||
receiver_model.set_modulation(ReceiverModel::Mode::AMAudio);
|
receiver_model.set_modulation(ReceiverModel::Mode::AMAudio);
|
||||||
receiver_model.set_am_configuration(field_bw.selected_index());
|
receiver_model.set_am_configuration(field_bw.selected_index());
|
||||||
field_bw.on_change = [this](size_t n, OptionsField::value_t) { receiver_model.set_am_configuration(n); };
|
field_bw.on_change = [this](size_t n, OptionsField::value_t) { receiver_model.set_am_configuration(n); };
|
||||||
receiver_model.set_sampling_rate(3072000); receiver_model.set_baseband_bandwidth(1750000);
|
receiver_model.set_sampling_rate(3072000);
|
||||||
|
receiver_model.set_baseband_bandwidth(1750000);
|
||||||
text_ctcss.set(" ");
|
text_ctcss.set(" ");
|
||||||
break;
|
break;
|
||||||
case NFM_MODULATION:
|
case NFM_MODULATION:
|
||||||
|
@ -252,7 +227,8 @@ namespace ui {
|
||||||
receiver_model.set_modulation(ReceiverModel::Mode::NarrowbandFMAudio);
|
receiver_model.set_modulation(ReceiverModel::Mode::NarrowbandFMAudio);
|
||||||
receiver_model.set_nbfm_configuration(field_bw.selected_index());
|
receiver_model.set_nbfm_configuration(field_bw.selected_index());
|
||||||
field_bw.on_change = [this](size_t n, OptionsField::value_t) { receiver_model.set_nbfm_configuration(n); };
|
field_bw.on_change = [this](size_t n, OptionsField::value_t) { receiver_model.set_nbfm_configuration(n); };
|
||||||
receiver_model.set_sampling_rate(3072000); receiver_model.set_baseband_bandwidth(1750000);
|
receiver_model.set_sampling_rate(3072000);
|
||||||
|
receiver_model.set_baseband_bandwidth(1750000);
|
||||||
break;
|
break;
|
||||||
case WFM_MODULATION:
|
case WFM_MODULATION:
|
||||||
freqman_set_bandwidth_option(new_mod, field_bw);
|
freqman_set_bandwidth_option(new_mod, field_bw);
|
||||||
|
@ -262,7 +238,8 @@ namespace ui {
|
||||||
receiver_model.set_modulation(ReceiverModel::Mode::WidebandFMAudio);
|
receiver_model.set_modulation(ReceiverModel::Mode::WidebandFMAudio);
|
||||||
receiver_model.set_wfm_configuration(field_bw.selected_index());
|
receiver_model.set_wfm_configuration(field_bw.selected_index());
|
||||||
field_bw.on_change = [this](size_t n, OptionsField::value_t) { receiver_model.set_wfm_configuration(n); };
|
field_bw.on_change = [this](size_t n, OptionsField::value_t) { receiver_model.set_wfm_configuration(n); };
|
||||||
receiver_model.set_sampling_rate(3072000); receiver_model.set_baseband_bandwidth(1750000);
|
receiver_model.set_sampling_rate(3072000);
|
||||||
|
receiver_model.set_baseband_bandwidth(1750000);
|
||||||
text_ctcss.set(" ");
|
text_ctcss.set(" ");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -271,7 +248,6 @@ namespace ui {
|
||||||
return step_mode.selected_index();
|
return step_mode.selected_index();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LevelView::handle_coded_squelch(const uint32_t value) {
|
void LevelView::handle_coded_squelch(const uint32_t value) {
|
||||||
static int32_t last_idx = -1;
|
static int32_t last_idx = -1;
|
||||||
|
|
||||||
|
@ -279,8 +255,7 @@ namespace ui {
|
||||||
size_t min_idx{0};
|
size_t min_idx{0};
|
||||||
size_t c;
|
size_t c;
|
||||||
|
|
||||||
if( field_mode.selected_index() != NFM_MODULATION )
|
if (field_mode.selected_index() != NFM_MODULATION) {
|
||||||
{
|
|
||||||
text_ctcss.set(" ");
|
text_ctcss.set(" ");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -295,8 +270,7 @@ namespace ui {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Arbitrary confidence threshold
|
// Arbitrary confidence threshold
|
||||||
if( last_idx < 0 || (unsigned)last_idx != min_idx )
|
if (last_idx < 0 || (unsigned)last_idx != min_idx) {
|
||||||
{
|
|
||||||
last_idx = min_idx;
|
last_idx = min_idx;
|
||||||
if (min_diff < 40)
|
if (min_diff < 40)
|
||||||
text_ctcss.set("T: " + tone_keys[min_idx].first);
|
text_ctcss.set("T: " + tone_keys[min_idx].first);
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
#include "file.hpp"
|
#include "file.hpp"
|
||||||
#include "app_settings.hpp"
|
#include "app_settings.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
class LevelView : public View {
|
class LevelView : public View {
|
||||||
|
@ -48,37 +47,43 @@ namespace ui {
|
||||||
|
|
||||||
void focus() override;
|
void focus() override;
|
||||||
|
|
||||||
const Style style_grey { // level
|
const Style style_grey{
|
||||||
|
// level
|
||||||
.font = font::fixed_8x16,
|
.font = font::fixed_8x16,
|
||||||
.background = Color::black(),
|
.background = Color::black(),
|
||||||
.foreground = Color::grey(),
|
.foreground = Color::grey(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const Style style_white { // level
|
const Style style_white{
|
||||||
|
// level
|
||||||
.font = font::fixed_8x16,
|
.font = font::fixed_8x16,
|
||||||
.background = Color::black(),
|
.background = Color::black(),
|
||||||
.foreground = Color::white(),
|
.foreground = Color::white(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const Style style_yellow { //Found signal
|
const Style style_yellow{
|
||||||
|
// Found signal
|
||||||
.font = font::fixed_8x16,
|
.font = font::fixed_8x16,
|
||||||
.background = Color::black(),
|
.background = Color::black(),
|
||||||
.foreground = Color::yellow(),
|
.foreground = Color::yellow(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const Style style_green { //Found signal
|
const Style style_green{
|
||||||
|
// Found signal
|
||||||
.font = font::fixed_8x16,
|
.font = font::fixed_8x16,
|
||||||
.background = Color::black(),
|
.background = Color::black(),
|
||||||
.foreground = Color::green(),
|
.foreground = Color::green(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const Style style_red { //erasing freq
|
const Style style_red{
|
||||||
|
// erasing freq
|
||||||
.font = font::fixed_8x16,
|
.font = font::fixed_8x16,
|
||||||
.background = Color::black(),
|
.background = Color::black(),
|
||||||
.foreground = Color::red(),
|
.foreground = Color::red(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const Style style_blue { // quick level, wait == 0
|
const Style style_blue{
|
||||||
|
// quick level, wait == 0
|
||||||
.font = font::fixed_8x16,
|
.font = font::fixed_8x16,
|
||||||
.background = Color::black(),
|
.background = Color::black(),
|
||||||
.foreground = Color::blue(),
|
.foreground = Color::blue(),
|
||||||
|
@ -99,23 +104,19 @@ namespace ui {
|
||||||
bool sd_card_mounted = false;
|
bool sd_card_mounted = false;
|
||||||
rf::Frequency freq = {0};
|
rf::Frequency freq = {0};
|
||||||
|
|
||||||
Labels labels
|
Labels labels{
|
||||||
{
|
|
||||||
{{0 * 8, 0 * 16}, "LNA: VGA: AMP: VOL: ", Color::light_grey()},
|
{{0 * 8, 0 * 16}, "LNA: VGA: AMP: VOL: ", Color::light_grey()},
|
||||||
{{0 * 8, 1 * 16}, "BW: MODE: S: ", Color::light_grey()},
|
{{0 * 8, 1 * 16}, "BW: MODE: S: ", Color::light_grey()},
|
||||||
};
|
};
|
||||||
|
|
||||||
LNAGainField field_lna{
|
LNAGainField field_lna{
|
||||||
{ 4 * 8, 0 * 16 }
|
{4 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
VGAGainField field_vga{
|
VGAGainField field_vga{
|
||||||
{ 11 * 8, 0 * 16 }
|
{11 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
RFAmpField field_rf_amp{
|
RFAmpField field_rf_amp{
|
||||||
{ 18 * 8, 0 * 16 }
|
{18 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_volume{
|
NumberField field_volume{
|
||||||
{24 * 8, 0 * 16},
|
{24 * 8, 0 * 16},
|
||||||
|
@ -128,27 +129,21 @@ namespace ui {
|
||||||
OptionsField field_bw{
|
OptionsField field_bw{
|
||||||
{3 * 8, 1 * 16},
|
{3 * 8, 1 * 16},
|
||||||
6,
|
6,
|
||||||
{ }
|
{}};
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField field_mode{
|
OptionsField field_mode{
|
||||||
{15 * 8, 1 * 16},
|
{15 * 8, 1 * 16},
|
||||||
3,
|
3,
|
||||||
{
|
{}};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField step_mode{
|
OptionsField step_mode{
|
||||||
{16 * 8, 2 * 16 + 4},
|
{16 * 8, 2 * 16 + 4},
|
||||||
12,
|
12,
|
||||||
{
|
{}};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ButtonWithEncoder button_frequency{
|
ButtonWithEncoder button_frequency{
|
||||||
{0 * 8, 2 * 16 + 8, 15 * 8, 1 * 8},
|
{0 * 8, 2 * 16 + 8, 15 * 8, 1 * 8},
|
||||||
""
|
""};
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField audio_mode{
|
OptionsField audio_mode{
|
||||||
{21 * 8, 1 * 16},
|
{21 * 8, 1 * 16},
|
||||||
|
@ -158,13 +153,11 @@ namespace ui {
|
||||||
{"audio on", 1}
|
{"audio on", 1}
|
||||||
//{"tone on", 2},
|
//{"tone on", 2},
|
||||||
//{"tone off", 2},
|
//{"tone off", 2},
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_ctcss{
|
Text text_ctcss{
|
||||||
{22 * 8, 3 * 16 + 4, 14 * 8, 1 * 8},
|
{22 * 8, 3 * 16 + 4, 14 * 8, 1 * 8},
|
||||||
""
|
""};
|
||||||
};
|
|
||||||
|
|
||||||
// RSSI: XX/XX/XXX,dt: XX
|
// RSSI: XX/XX/XXX,dt: XX
|
||||||
Text freq_stats_rssi{
|
Text freq_stats_rssi{
|
||||||
|
@ -187,8 +180,7 @@ namespace ui {
|
||||||
{"peak:3s", 3000},
|
{"peak:3s", 3000},
|
||||||
{"peak:5s", 5000},
|
{"peak:5s", 5000},
|
||||||
{"peak:10s", 10000},
|
{"peak:10s", 10000},
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
OptionsField rssi_resolution{
|
OptionsField rssi_resolution{
|
||||||
{44 + 20 * 8, 4 * 16 + 4},
|
{44 + 20 * 8, 4 * 16 + 4},
|
||||||
4,
|
4,
|
||||||
|
@ -198,14 +190,15 @@ namespace ui {
|
||||||
{"64x", 64},
|
{"64x", 64},
|
||||||
{"128x", 128},
|
{"128x", 128},
|
||||||
{"240x", 240},
|
{"240x", 240},
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
RSSIGraph rssi_graph { // 240x320 =>
|
RSSIGraph rssi_graph{
|
||||||
|
// 240x320 =>
|
||||||
{0, 5 * 16 + 4, 240 - 5 * 8, 320 - (5 * 16 + 4)},
|
{0, 5 * 16 + 4, 240 - 5 * 8, 320 - (5 * 16 + 4)},
|
||||||
};
|
};
|
||||||
|
|
||||||
RSSI rssi { // 240x320 =>
|
RSSI rssi{
|
||||||
|
// 240x320 =>
|
||||||
{240 - 5 * 8, 5 * 16 + 4, 5 * 8, 320 - (5 * 16 + 4)},
|
{240 - 5 * 8, 5 * 16 + 4, 5 * 8, 320 - (5 * 16 + 4)},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -217,15 +210,13 @@ namespace ui {
|
||||||
[this](const Message* const p) {
|
[this](const Message* const p) {
|
||||||
const auto message = *reinterpret_cast<const CodedSquelchMessage*>(p);
|
const auto message = *reinterpret_cast<const CodedSquelchMessage*>(p);
|
||||||
this->handle_coded_squelch(message.value);
|
this->handle_coded_squelch(message.value);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_stats{
|
MessageHandlerRegistration message_handler_stats{
|
||||||
Message::ID::ChannelStatistics,
|
Message::ID::ChannelStatistics,
|
||||||
[this](const Message* const p) {
|
[this](const Message* const p) {
|
||||||
this->on_statistics_update(static_cast<const ChannelStatisticsMessage*>(p)->statistics);
|
this->on_statistics_update(static_cast<const ChannelStatisticsMessage*>(p)->statistics);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
// app save settings
|
// app save settings
|
||||||
std::app_settings settings{};
|
std::app_settings settings{};
|
||||||
std::app_settings::AppSettings app_settings{};
|
std::app_settings::AppSettings app_settings{};
|
||||||
|
|
|
@ -24,15 +24,12 @@
|
||||||
|
|
||||||
using namespace portapack;
|
using namespace portapack;
|
||||||
|
|
||||||
namespace ui
|
namespace ui {
|
||||||
{
|
void GlassView::focus() {
|
||||||
void GlassView::focus()
|
|
||||||
{
|
|
||||||
button_marker.focus();
|
button_marker.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
GlassView::~GlassView()
|
GlassView::~GlassView() {
|
||||||
{
|
|
||||||
receiver_model.set_sampling_rate(3072000); // Just a hack to avoid hanging other apps
|
receiver_model.set_sampling_rate(3072000); // Just a hack to avoid hanging other apps
|
||||||
receiver_model.disable();
|
receiver_model.disable();
|
||||||
baseband::shutdown();
|
baseband::shutdown();
|
||||||
|
@ -46,8 +43,7 @@ namespace ui
|
||||||
void GlassView::adjust_range(int64_t* f_min, int64_t* f_max, int64_t width) {
|
void GlassView::adjust_range(int64_t* f_min, int64_t* f_max, int64_t width) {
|
||||||
int64_t span = *f_max - *f_min;
|
int64_t span = *f_max - *f_min;
|
||||||
int64_t num_intervals = span / width;
|
int64_t num_intervals = span / width;
|
||||||
if( span % width != 0 )
|
if (span % width != 0) {
|
||||||
{
|
|
||||||
num_intervals++;
|
num_intervals++;
|
||||||
}
|
}
|
||||||
int64_t new_span = num_intervals * width;
|
int64_t new_span = num_intervals * width;
|
||||||
|
@ -56,32 +52,26 @@ namespace ui
|
||||||
*f_max += delta_span;
|
*f_max += delta_span;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlassView::on_lna_changed(int32_t v_db)
|
void GlassView::on_lna_changed(int32_t v_db) {
|
||||||
{
|
|
||||||
receiver_model.set_lna(v_db);
|
receiver_model.set_lna(v_db);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlassView::on_vga_changed(int32_t v_db)
|
void GlassView::on_vga_changed(int32_t v_db) {
|
||||||
{
|
|
||||||
receiver_model.set_vga(v_db);
|
receiver_model.set_vga(v_db);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlassView::reset_live_view( bool clear_screen )
|
void GlassView::reset_live_view(bool clear_screen) {
|
||||||
{
|
|
||||||
max_freq_hold = 0;
|
max_freq_hold = 0;
|
||||||
max_freq_power = -1000;
|
max_freq_power = -1000;
|
||||||
if( clear_screen )
|
if (clear_screen) {
|
||||||
{
|
|
||||||
// only clear screen in peak mode
|
// only clear screen in peak mode
|
||||||
if( live_frequency_view == 2 )
|
if (live_frequency_view == 2) {
|
||||||
{
|
|
||||||
display.fill_rectangle({{0, 108 + 16}, {240, 320 - (108 + 16)}}, {0, 0, 0});
|
display.fill_rectangle({{0, 108 + 16}, {240, 320 - (108 + 16)}}, {0, 0, 0});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlassView::add_spectrum_pixel( uint8_t power )
|
void GlassView::add_spectrum_pixel(uint8_t power) {
|
||||||
{
|
|
||||||
static int64_t last_max_freq = 0;
|
static int64_t last_max_freq = 0;
|
||||||
|
|
||||||
spectrum_row[pixel_index] = spectrum_rgb3_lut[power]; // row of colors
|
spectrum_row[pixel_index] = spectrum_rgb3_lut[power]; // row of colors
|
||||||
|
@ -90,8 +80,7 @@ namespace ui
|
||||||
|
|
||||||
if (pixel_index == 240) // got an entire waterfall line
|
if (pixel_index == 240) // got an entire waterfall line
|
||||||
{
|
{
|
||||||
if( live_frequency_view > 0 )
|
if (live_frequency_view > 0) {
|
||||||
{
|
|
||||||
constexpr int rssi_sample_range = 256;
|
constexpr int rssi_sample_range = 256;
|
||||||
constexpr float rssi_voltage_min = 0.4;
|
constexpr float rssi_voltage_min = 0.4;
|
||||||
constexpr float rssi_voltage_max = 2.2;
|
constexpr float rssi_voltage_max = 2.2;
|
||||||
|
@ -102,11 +91,9 @@ namespace ui
|
||||||
const range_t<int> y_max_range{0, 320 - (108 + 16)};
|
const range_t<int> y_max_range{0, 320 - (108 + 16)};
|
||||||
|
|
||||||
// drawing and keeping track of max freq
|
// drawing and keeping track of max freq
|
||||||
for( uint16_t xpos = 0 ; xpos < 240 ; xpos ++ )
|
for (uint16_t xpos = 0; xpos < 240; xpos++) {
|
||||||
{
|
|
||||||
// save max powerwull freq
|
// save max powerwull freq
|
||||||
if( spectrum_data[ xpos ] > max_freq_power )
|
if (spectrum_data[xpos] > max_freq_power) {
|
||||||
{
|
|
||||||
max_freq_power = spectrum_data[xpos];
|
max_freq_power = spectrum_data[xpos];
|
||||||
max_freq_hold = f_min + ((f_max - f_min) * xpos) / 240;
|
max_freq_hold = f_min + ((f_max - f_min) * xpos) / 240;
|
||||||
}
|
}
|
||||||
|
@ -114,21 +101,17 @@ namespace ui
|
||||||
int16_t point = y_max_range.clip(((spectrum_data[xpos] - raw_min) * (320 - (108 + 16))) / raw_delta);
|
int16_t point = y_max_range.clip(((spectrum_data[xpos] - raw_min) * (320 - (108 + 16))) / raw_delta);
|
||||||
uint8_t color_gradient = (point * 255) / 212;
|
uint8_t color_gradient = (point * 255) / 212;
|
||||||
// clear if not in peak view
|
// clear if not in peak view
|
||||||
if( live_frequency_view != 2 )
|
if (live_frequency_view != 2) {
|
||||||
{
|
|
||||||
display.fill_rectangle({{xpos, 108 + 16}, {1, 320 - point}}, {0, 0, 0});
|
display.fill_rectangle({{xpos, 108 + 16}, {1, 320 - point}}, {0, 0, 0});
|
||||||
}
|
}
|
||||||
display.fill_rectangle({{xpos, 320 - point}, {1, point}}, {color_gradient, 0, uint8_t(255 - color_gradient)});
|
display.fill_rectangle({{xpos, 320 - point}, {1, point}}, {color_gradient, 0, uint8_t(255 - color_gradient)});
|
||||||
}
|
}
|
||||||
if( last_max_freq != max_freq_hold )
|
if (last_max_freq != max_freq_hold) {
|
||||||
{
|
|
||||||
last_max_freq = max_freq_hold;
|
last_max_freq = max_freq_hold;
|
||||||
freq_stats.set("MAX HOLD: " + to_string_short_freq(max_freq_hold));
|
freq_stats.set("MAX HOLD: " + to_string_short_freq(max_freq_hold));
|
||||||
}
|
}
|
||||||
PlotMarker(marker);
|
PlotMarker(marker);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
display.draw_pixels({{0, display.scroll(1)}, {240, 1}}, spectrum_row); // new line at top, one less var, speedier
|
display.draw_pixels({{0, display.scroll(1)}, {240, 1}}, spectrum_row); // new line at top, one less var, speedier
|
||||||
}
|
}
|
||||||
pixel_index = 0; // Start New cascade line
|
pixel_index = 0; // Start New cascade line
|
||||||
|
@ -137,54 +120,40 @@ namespace ui
|
||||||
|
|
||||||
// Apparently, the spectrum object returns an array of 256 bins
|
// Apparently, the spectrum object returns an array of 256 bins
|
||||||
// Each having the radio signal power for it's corresponding frequency slot
|
// Each having the radio signal power for it's corresponding frequency slot
|
||||||
void GlassView::on_channel_spectrum(const ChannelSpectrum &spectrum)
|
void GlassView::on_channel_spectrum(const ChannelSpectrum& spectrum) {
|
||||||
{
|
|
||||||
// default fast scan offset
|
// default fast scan offset
|
||||||
uint8_t offset = 2;
|
uint8_t offset = 2;
|
||||||
baseband::spectrum_streaming_stop();
|
baseband::spectrum_streaming_stop();
|
||||||
if( fast_scan || ( LOOKING_GLASS_SLICE_WIDTH < LOOKING_GLASS_SLICE_WIDTH_MAX ) )
|
if (fast_scan || (LOOKING_GLASS_SLICE_WIDTH < LOOKING_GLASS_SLICE_WIDTH_MAX)) {
|
||||||
{
|
|
||||||
// Convert bins of this spectrum slice into a representative max_power and when enough, into pixels
|
// Convert bins of this spectrum slice into a representative max_power and when enough, into pixels
|
||||||
// Spectrum.db has 256 bins.
|
// Spectrum.db has 256 bins.
|
||||||
// All things said and done, we actually need 240 of those bins
|
// All things said and done, we actually need 240 of those bins
|
||||||
for (uint8_t bin = 0; bin < 240; bin++)
|
for (uint8_t bin = 0; bin < 240; bin++) {
|
||||||
{
|
|
||||||
// if the view is done in one pass, show it like in analog_audio_app
|
// if the view is done in one pass, show it like in analog_audio_app
|
||||||
if( ( LOOKING_GLASS_SLICE_WIDTH < LOOKING_GLASS_SLICE_WIDTH_MAX ) )
|
if ((LOOKING_GLASS_SLICE_WIDTH < LOOKING_GLASS_SLICE_WIDTH_MAX)) {
|
||||||
{
|
|
||||||
// Center 16 bins are ignored (DC spike is blanked)
|
// Center 16 bins are ignored (DC spike is blanked)
|
||||||
if (bin < 120)
|
if (bin < 120) {
|
||||||
{
|
|
||||||
if (spectrum.db[256 - 120 + bin] > max_power) // 134
|
if (spectrum.db[256 - 120 + bin] > max_power) // 134
|
||||||
max_power = spectrum.db[256 - 120 + bin];
|
max_power = spectrum.db[256 - 120 + bin];
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
if (spectrum.db[bin - 120] > max_power) // 118
|
if (spectrum.db[bin - 120] > max_power) // 118
|
||||||
max_power = spectrum.db[bin - 120];
|
max_power = spectrum.db[bin - 120];
|
||||||
}
|
}
|
||||||
}
|
} else // view is made in multiple pass, use original bin picking
|
||||||
else // view is made in multiple pass, use original bin picking
|
|
||||||
{
|
{
|
||||||
// Center 12 bins are ignored (DC spike is blanked) Leftmost and rightmost 2 bins are ignored
|
// Center 12 bins are ignored (DC spike is blanked) Leftmost and rightmost 2 bins are ignored
|
||||||
if (bin < 120)
|
if (bin < 120) {
|
||||||
{
|
|
||||||
if (spectrum.db[134 + bin] > max_power) // 134
|
if (spectrum.db[134 + bin] > max_power) // 134
|
||||||
max_power = spectrum.db[134 + bin];
|
max_power = spectrum.db[134 + bin];
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
if (spectrum.db[bin - 118] > max_power) // 118
|
if (spectrum.db[bin - 118] > max_power) // 118
|
||||||
max_power = spectrum.db[bin - 118];
|
max_power = spectrum.db[bin - 118];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( bin == 120 )
|
if (bin == 120) {
|
||||||
{
|
|
||||||
bins_Hz_size += 12 * each_bin_size; // add DC bin Hz count into the "pixel fulfilled bag of Hz"
|
bins_Hz_size += 12 * each_bin_size; // add DC bin Hz count into the "pixel fulfilled bag of Hz"
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
bins_Hz_size += each_bin_size; // add this bin Hz count into the "pixel fulfilled bag of Hz"
|
bins_Hz_size += each_bin_size; // add this bin Hz count into the "pixel fulfilled bag of Hz"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,20 +180,15 @@ namespace ui
|
||||||
}
|
}
|
||||||
f_center += (256 - (2 * offset)) * each_bin_size; // Move into the next bandwidth slice NOTE: spectrum.sampling_rate = LOOKING_GLASS_SLICE_WIDTH
|
f_center += (256 - (2 * offset)) * each_bin_size; // Move into the next bandwidth slice NOTE: spectrum.sampling_rate = LOOKING_GLASS_SLICE_WIDTH
|
||||||
// lost bins are taken in account so next slice first ignored bins overlap previous kept ones
|
// lost bins are taken in account so next slice first ignored bins overlap previous kept ones
|
||||||
}
|
} else // slow scan
|
||||||
else //slow scan
|
|
||||||
{
|
{
|
||||||
offset = 32;
|
offset = 32;
|
||||||
uint8_t bin_length = 80;
|
uint8_t bin_length = 80;
|
||||||
for (uint8_t bin = offset ; bin < bin_length + offset ; bin++)
|
for (uint8_t bin = offset; bin < bin_length + offset; bin++) {
|
||||||
{
|
if (bin < 120) {
|
||||||
if (bin < 120)
|
|
||||||
{
|
|
||||||
if (spectrum.db[134 + bin] > max_power) // 134
|
if (spectrum.db[134 + bin] > max_power) // 134
|
||||||
max_power = spectrum.db[134 + bin];
|
max_power = spectrum.db[134 + bin];
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
if (spectrum.db[bin - 118] > max_power) // 118
|
if (spectrum.db[bin - 118] > max_power) // 118
|
||||||
max_power = spectrum.db[bin - 118];
|
max_power = spectrum.db[bin - 118];
|
||||||
}
|
}
|
||||||
|
@ -259,31 +223,25 @@ namespace ui
|
||||||
baseband::spectrum_streaming_start(); // Do the RX
|
baseband::spectrum_streaming_start(); // Do the RX
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlassView::on_hide()
|
void GlassView::on_hide() {
|
||||||
{
|
|
||||||
baseband::spectrum_streaming_stop();
|
baseband::spectrum_streaming_stop();
|
||||||
display.scroll_disable();
|
display.scroll_disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlassView::on_show()
|
void GlassView::on_show() {
|
||||||
{
|
|
||||||
display.scroll_set_area(109, 319); // Restart scroll on the correct coordinates
|
display.scroll_set_area(109, 319); // Restart scroll on the correct coordinates
|
||||||
baseband::spectrum_streaming_start();
|
baseband::spectrum_streaming_start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlassView::on_range_changed()
|
void GlassView::on_range_changed() {
|
||||||
{
|
|
||||||
reset_live_view(false);
|
reset_live_view(false);
|
||||||
f_min = field_frequency_min.value();
|
f_min = field_frequency_min.value();
|
||||||
f_max = field_frequency_max.value();
|
f_max = field_frequency_max.value();
|
||||||
search_span = f_max - f_min;
|
search_span = f_max - f_min;
|
||||||
|
|
||||||
if( locked_range )
|
if (locked_range) {
|
||||||
{
|
|
||||||
button_range.set_text(">" + to_string_dec_uint(search_span) + "<");
|
button_range.set_text(">" + to_string_dec_uint(search_span) + "<");
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
button_range.set_text(" " + to_string_dec_uint(search_span) + " ");
|
button_range.set_text(" " + to_string_dec_uint(search_span) + " ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,14 +257,11 @@ namespace ui
|
||||||
pixel_index = 0; // reset pixel counter
|
pixel_index = 0; // reset pixel counter
|
||||||
max_power = 0;
|
max_power = 0;
|
||||||
bins_Hz_size = 0; // reset amount of Hz filled up by pixels
|
bins_Hz_size = 0; // reset amount of Hz filled up by pixels
|
||||||
if( (f_max - f_min) <= LOOKING_GLASS_SLICE_WIDTH_MAX )
|
if ((f_max - f_min) <= LOOKING_GLASS_SLICE_WIDTH_MAX) {
|
||||||
{
|
|
||||||
LOOKING_GLASS_SLICE_WIDTH = (f_max - f_min);
|
LOOKING_GLASS_SLICE_WIDTH = (f_max - f_min);
|
||||||
receiver_model.set_sampling_rate(LOOKING_GLASS_SLICE_WIDTH);
|
receiver_model.set_sampling_rate(LOOKING_GLASS_SLICE_WIDTH);
|
||||||
receiver_model.set_baseband_bandwidth(LOOKING_GLASS_SLICE_WIDTH / 2);
|
receiver_model.set_baseband_bandwidth(LOOKING_GLASS_SLICE_WIDTH / 2);
|
||||||
}
|
} else if (LOOKING_GLASS_SLICE_WIDTH != LOOKING_GLASS_SLICE_WIDTH_MAX) {
|
||||||
else if( LOOKING_GLASS_SLICE_WIDTH != LOOKING_GLASS_SLICE_WIDTH_MAX )
|
|
||||||
{
|
|
||||||
LOOKING_GLASS_SLICE_WIDTH = LOOKING_GLASS_SLICE_WIDTH_MAX;
|
LOOKING_GLASS_SLICE_WIDTH = LOOKING_GLASS_SLICE_WIDTH_MAX;
|
||||||
receiver_model.set_sampling_rate(LOOKING_GLASS_SLICE_WIDTH);
|
receiver_model.set_sampling_rate(LOOKING_GLASS_SLICE_WIDTH);
|
||||||
receiver_model.set_baseband_bandwidth(LOOKING_GLASS_SLICE_WIDTH);
|
receiver_model.set_baseband_bandwidth(LOOKING_GLASS_SLICE_WIDTH);
|
||||||
|
@ -324,8 +279,7 @@ namespace ui
|
||||||
receiver_model.set_tuning_frequency(f_center_ini); // tune rx for this slice
|
receiver_model.set_tuning_frequency(f_center_ini); // tune rx for this slice
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlassView::PlotMarker(rf::Frequency pos)
|
void GlassView::PlotMarker(rf::Frequency pos) {
|
||||||
{
|
|
||||||
pos -= f_min;
|
pos -= f_min;
|
||||||
pos = pos / marker_pixel_step; // Real pixel
|
pos = pos / marker_pixel_step; // Real pixel
|
||||||
|
|
||||||
|
@ -341,8 +295,8 @@ namespace ui
|
||||||
}
|
}
|
||||||
|
|
||||||
GlassView::GlassView(
|
GlassView::GlassView(
|
||||||
NavigationView &nav) : nav_(nav)
|
NavigationView& nav)
|
||||||
{
|
: nav_(nav) {
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_wideband_spectrum);
|
baseband::run_image(portapack::spi_flash::image_tag_wideband_spectrum);
|
||||||
|
|
||||||
add_children({&labels,
|
add_children({&labels,
|
||||||
|
@ -366,16 +320,14 @@ namespace ui
|
||||||
|
|
||||||
load_Presets(); // Load available presets from TXT files (or default)
|
load_Presets(); // Load available presets from TXT files (or default)
|
||||||
|
|
||||||
field_frequency_min.on_change = [this](int32_t v)
|
field_frequency_min.on_change = [this](int32_t v) {
|
||||||
{
|
|
||||||
reset_live_view(true);
|
reset_live_view(true);
|
||||||
int32_t min_size = steps;
|
int32_t min_size = steps;
|
||||||
if (locked_range)
|
if (locked_range)
|
||||||
min_size = search_span;
|
min_size = search_span;
|
||||||
if (min_size < 2)
|
if (min_size < 2)
|
||||||
min_size = 2;
|
min_size = 2;
|
||||||
if( v > 7200 - min_size )
|
if (v > 7200 - min_size) {
|
||||||
{
|
|
||||||
v = 7200 - min_size;
|
v = 7200 - min_size;
|
||||||
field_frequency_min.set_value(v);
|
field_frequency_min.set_value(v);
|
||||||
}
|
}
|
||||||
|
@ -406,16 +358,14 @@ namespace ui
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
field_frequency_max.on_change = [this](int32_t v)
|
field_frequency_max.on_change = [this](int32_t v) {
|
||||||
{
|
|
||||||
reset_live_view(true);
|
reset_live_view(true);
|
||||||
int32_t min_size = steps;
|
int32_t min_size = steps;
|
||||||
if (locked_range)
|
if (locked_range)
|
||||||
min_size = search_span;
|
min_size = search_span;
|
||||||
if (min_size < 2)
|
if (min_size < 2)
|
||||||
min_size = 2;
|
min_size = 2;
|
||||||
if( v < min_size )
|
if (v < min_size) {
|
||||||
{
|
|
||||||
v = min_size;
|
v = min_size;
|
||||||
field_frequency_max.set_value(v);
|
field_frequency_max.set_value(v);
|
||||||
}
|
}
|
||||||
|
@ -446,22 +396,19 @@ namespace ui
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
field_lna.on_change = [this](int32_t v)
|
field_lna.on_change = [this](int32_t v) {
|
||||||
{
|
|
||||||
reset_live_view(true);
|
reset_live_view(true);
|
||||||
this->on_lna_changed(v);
|
this->on_lna_changed(v);
|
||||||
};
|
};
|
||||||
field_lna.set_value(receiver_model.lna());
|
field_lna.set_value(receiver_model.lna());
|
||||||
|
|
||||||
field_vga.on_change = [this](int32_t v_db)
|
field_vga.on_change = [this](int32_t v_db) {
|
||||||
{
|
|
||||||
reset_live_view(true);
|
reset_live_view(true);
|
||||||
this->on_vga_changed(v_db);
|
this->on_vga_changed(v_db);
|
||||||
};
|
};
|
||||||
field_vga.set_value(receiver_model.vga());
|
field_vga.set_value(receiver_model.vga());
|
||||||
|
|
||||||
steps_config.on_change = [this](size_t n, OptionsField::value_t v)
|
steps_config.on_change = [this](size_t n, OptionsField::value_t v) {
|
||||||
{
|
|
||||||
(void)n;
|
(void)n;
|
||||||
field_frequency_min.set_step(v);
|
field_frequency_min.set_step(v);
|
||||||
field_frequency_max.set_step(v);
|
field_frequency_max.set_step(v);
|
||||||
|
@ -469,29 +416,24 @@ namespace ui
|
||||||
};
|
};
|
||||||
steps_config.set_selected_index(0); // default of 1 Mhz steps
|
steps_config.set_selected_index(0); // default of 1 Mhz steps
|
||||||
|
|
||||||
scan_type.on_change = [this](size_t n, OptionsField::value_t v)
|
scan_type.on_change = [this](size_t n, OptionsField::value_t v) {
|
||||||
{
|
|
||||||
(void)n;
|
(void)n;
|
||||||
fast_scan = v;
|
fast_scan = v;
|
||||||
};
|
};
|
||||||
scan_type.set_selected_index(0); // default legacy fast scan
|
scan_type.set_selected_index(0); // default legacy fast scan
|
||||||
|
|
||||||
view_config.on_change = [this](size_t n, OptionsField::value_t v)
|
view_config.on_change = [this](size_t n, OptionsField::value_t v) {
|
||||||
{
|
|
||||||
(void)n;
|
(void)n;
|
||||||
// clear between changes
|
// clear between changes
|
||||||
reset_live_view(true);
|
reset_live_view(true);
|
||||||
if( v == 0 )
|
if (v == 0) {
|
||||||
{
|
|
||||||
live_frequency_view = 0;
|
live_frequency_view = 0;
|
||||||
level_integration.hidden(true);
|
level_integration.hidden(true);
|
||||||
freq_stats.hidden(true);
|
freq_stats.hidden(true);
|
||||||
button_jump.hidden(true);
|
button_jump.hidden(true);
|
||||||
button_rst.hidden(true);
|
button_rst.hidden(true);
|
||||||
display.scroll_set_area(109, 319); // Restart scroll on the correct coordinates
|
display.scroll_set_area(109, 319); // Restart scroll on the correct coordinates
|
||||||
}
|
} else if (v == 1) {
|
||||||
else if( v == 1 )
|
|
||||||
{
|
|
||||||
display.fill_rectangle({{0, 108}, {240, 24}}, {0, 0, 0});
|
display.fill_rectangle({{0, 108}, {240, 24}}, {0, 0, 0});
|
||||||
live_frequency_view = 1;
|
live_frequency_view = 1;
|
||||||
display.scroll_disable();
|
display.scroll_disable();
|
||||||
|
@ -499,9 +441,7 @@ namespace ui
|
||||||
freq_stats.hidden(false);
|
freq_stats.hidden(false);
|
||||||
button_jump.hidden(false);
|
button_jump.hidden(false);
|
||||||
button_rst.hidden(false);
|
button_rst.hidden(false);
|
||||||
}
|
} else if (v == 2) {
|
||||||
else if( v == 2 )
|
|
||||||
{
|
|
||||||
display.fill_rectangle({{0, 108}, {240, 24}}, {0, 0, 0});
|
display.fill_rectangle({{0, 108}, {240, 24}}, {0, 0, 0});
|
||||||
live_frequency_view = 2;
|
live_frequency_view = 2;
|
||||||
display.scroll_disable();
|
display.scroll_disable();
|
||||||
|
@ -514,8 +454,7 @@ namespace ui
|
||||||
};
|
};
|
||||||
view_config.set_selected_index(0); // default spectrum
|
view_config.set_selected_index(0); // default spectrum
|
||||||
|
|
||||||
level_integration.on_change = [this](size_t n, OptionsField::value_t v)
|
level_integration.on_change = [this](size_t n, OptionsField::value_t v) {
|
||||||
{
|
|
||||||
(void)n;
|
(void)n;
|
||||||
reset_live_view(true);
|
reset_live_view(true);
|
||||||
live_frequency_integrate = v;
|
live_frequency_integrate = v;
|
||||||
|
@ -529,16 +468,14 @@ namespace ui
|
||||||
};
|
};
|
||||||
filter_config.set_selected_index(0);
|
filter_config.set_selected_index(0);
|
||||||
|
|
||||||
range_presets.on_change = [this](size_t n, OptionsField::value_t v)
|
range_presets.on_change = [this](size_t n, OptionsField::value_t v) {
|
||||||
{
|
|
||||||
(void)n;
|
(void)n;
|
||||||
field_frequency_min.set_value(presets_db[v].min, false);
|
field_frequency_min.set_value(presets_db[v].min, false);
|
||||||
field_frequency_max.set_value(presets_db[v].max, false);
|
field_frequency_max.set_value(presets_db[v].max, false);
|
||||||
this->on_range_changed();
|
this->on_range_changed();
|
||||||
};
|
};
|
||||||
|
|
||||||
button_marker.on_change = [this]()
|
button_marker.on_change = [this]() {
|
||||||
{
|
|
||||||
marker = marker + button_marker.get_encoder_delta() * marker_pixel_step;
|
marker = marker + button_marker.get_encoder_delta() * marker_pixel_step;
|
||||||
if (marker < f_min)
|
if (marker < f_min)
|
||||||
marker = f_min;
|
marker = f_min;
|
||||||
|
@ -549,29 +486,24 @@ namespace ui
|
||||||
PlotMarker(marker); // Refresh marker on screen
|
PlotMarker(marker); // Refresh marker on screen
|
||||||
};
|
};
|
||||||
|
|
||||||
button_marker.on_select = [this](ButtonWithEncoder &)
|
button_marker.on_select = [this](ButtonWithEncoder&) {
|
||||||
{
|
|
||||||
receiver_model.set_tuning_frequency(marker); // Center tune rx in marker freq.
|
receiver_model.set_tuning_frequency(marker); // Center tune rx in marker freq.
|
||||||
receiver_model.set_frequency_step(MHZ_DIV); // Preset a 1 MHz frequency step into RX -> AUDIO
|
receiver_model.set_frequency_step(MHZ_DIV); // Preset a 1 MHz frequency step into RX -> AUDIO
|
||||||
nav_.pop();
|
nav_.pop();
|
||||||
nav_.push<AnalogAudioView>(); // Jump into audio view
|
nav_.push<AnalogAudioView>(); // Jump into audio view
|
||||||
};
|
};
|
||||||
|
|
||||||
field_trigger.on_change = [this](int32_t v)
|
field_trigger.on_change = [this](int32_t v) {
|
||||||
{
|
|
||||||
baseband::set_spectrum(LOOKING_GLASS_SLICE_WIDTH, v);
|
baseband::set_spectrum(LOOKING_GLASS_SLICE_WIDTH, v);
|
||||||
};
|
};
|
||||||
field_trigger.set_value(32); // Defaults to 32, as normal triggering resolution
|
field_trigger.set_value(32); // Defaults to 32, as normal triggering resolution
|
||||||
|
|
||||||
button_range.on_select = [this](Button&) {
|
button_range.on_select = [this](Button&) {
|
||||||
if( locked_range )
|
if (locked_range) {
|
||||||
{
|
|
||||||
locked_range = false;
|
locked_range = false;
|
||||||
button_range.set_style(&style_white);
|
button_range.set_style(&style_white);
|
||||||
button_range.set_text(" " + to_string_dec_uint(search_span) + " ");
|
button_range.set_text(" " + to_string_dec_uint(search_span) + " ");
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
locked_range = true;
|
locked_range = true;
|
||||||
button_range.set_style(&style_red);
|
button_range.set_style(&style_red);
|
||||||
button_range.set_text(">" + to_string_dec_uint(search_span) + "<");
|
button_range.set_text(">" + to_string_dec_uint(search_span) + "<");
|
||||||
|
@ -604,29 +536,21 @@ namespace ui
|
||||||
receiver_model.enable();
|
receiver_model.enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlassView::load_Presets()
|
void GlassView::load_Presets() {
|
||||||
{
|
|
||||||
File presets_file; // LOAD /WHIPCALC/ANTENNAS.TXT from microSD
|
File presets_file; // LOAD /WHIPCALC/ANTENNAS.TXT from microSD
|
||||||
auto result = presets_file.open("LOOKINGGLASS/PRESETS.TXT");
|
auto result = presets_file.open("LOOKINGGLASS/PRESETS.TXT");
|
||||||
presets_db.clear(); // Start with fresh db
|
presets_db.clear(); // Start with fresh db
|
||||||
if (result.is_valid())
|
if (result.is_valid()) {
|
||||||
{
|
|
||||||
presets_Default(); // There is no txt, store a default range
|
presets_Default(); // There is no txt, store a default range
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
std::string line; // There is a txt file
|
std::string line; // There is a txt file
|
||||||
char one_char[1]; // Read it char by char
|
char one_char[1]; // Read it char by char
|
||||||
for (size_t pointer = 0; pointer < presets_file.size(); pointer++)
|
for (size_t pointer = 0; pointer < presets_file.size(); pointer++) {
|
||||||
{
|
|
||||||
presets_file.seek(pointer);
|
presets_file.seek(pointer);
|
||||||
presets_file.read(one_char, 1);
|
presets_file.read(one_char, 1);
|
||||||
if ((int)one_char[0] > 31)
|
if ((int)one_char[0] > 31) { // ascii space upwards
|
||||||
{ // ascii space upwards
|
|
||||||
line += one_char[0]; // Add it to the textline
|
line += one_char[0]; // Add it to the textline
|
||||||
}
|
} else if (one_char[0] == '\n') { // New Line
|
||||||
else if (one_char[0] == '\n')
|
|
||||||
{ // New Line
|
|
||||||
txtline_process(line); // make sense of this textline
|
txtline_process(line); // make sense of this textline
|
||||||
line.clear(); // Ready for next textline
|
line.clear(); // Ready for next textline
|
||||||
}
|
}
|
||||||
|
@ -639,8 +563,7 @@ namespace ui
|
||||||
populate_Presets();
|
populate_Presets();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlassView::txtline_process(std::string &line)
|
void GlassView::txtline_process(std::string& line) {
|
||||||
{
|
|
||||||
if (line.find("#") != std::string::npos)
|
if (line.find("#") != std::string::npos)
|
||||||
return; // Line is just a comment
|
return; // Line is just a comment
|
||||||
|
|
||||||
|
@ -671,23 +594,20 @@ namespace ui
|
||||||
presets_db.push_back(new_preset); // Add this preset.
|
presets_db.push_back(new_preset); // Add this preset.
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlassView::populate_Presets()
|
void GlassView::populate_Presets() {
|
||||||
{
|
|
||||||
using option_t = std::pair<std::string, int32_t>;
|
using option_t = std::pair<std::string, int32_t>;
|
||||||
using options_t = std::vector<option_t>;
|
using options_t = std::vector<option_t>;
|
||||||
options_t entries;
|
options_t entries;
|
||||||
|
|
||||||
for (preset_entry preset : presets_db)
|
for (preset_entry preset : presets_db) { // go thru all available presets
|
||||||
{ // go thru all available presets
|
|
||||||
entries.emplace_back(preset.label, entries.size());
|
entries.emplace_back(preset.label, entries.size());
|
||||||
}
|
}
|
||||||
range_presets.set_options(entries);
|
range_presets.set_options(entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlassView::presets_Default()
|
void GlassView::presets_Default() {
|
||||||
{
|
|
||||||
presets_db.clear();
|
presets_db.clear();
|
||||||
presets_db.push_back({2320, 2560, "DEFAULT WIFI 2.4GHz"});
|
presets_db.push_back({2320, 2560, "DEFAULT WIFI 2.4GHz"});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace ui
|
||||||
|
|
|
@ -35,16 +35,13 @@
|
||||||
#include "analog_audio_app.hpp"
|
#include "analog_audio_app.hpp"
|
||||||
#include "spectrum_color_lut.hpp"
|
#include "spectrum_color_lut.hpp"
|
||||||
|
|
||||||
namespace ui
|
namespace ui {
|
||||||
{
|
|
||||||
#define LOOKING_GLASS_SLICE_WIDTH_MAX 20000000
|
#define LOOKING_GLASS_SLICE_WIDTH_MAX 20000000
|
||||||
#define MHZ_DIV 1000000
|
#define MHZ_DIV 1000000
|
||||||
#define X2_MHZ_DIV 2000000
|
#define X2_MHZ_DIV 2000000
|
||||||
|
|
||||||
class GlassView : public View
|
class GlassView : public View {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
GlassView(NavigationView& nav);
|
GlassView(NavigationView& nav);
|
||||||
|
|
||||||
GlassView(const GlassView&);
|
GlassView(const GlassView&);
|
||||||
|
@ -60,20 +57,21 @@ namespace ui
|
||||||
private:
|
private:
|
||||||
NavigationView& nav_;
|
NavigationView& nav_;
|
||||||
|
|
||||||
struct preset_entry
|
struct preset_entry {
|
||||||
{
|
|
||||||
rf::Frequency min{};
|
rf::Frequency min{};
|
||||||
rf::Frequency max{};
|
rf::Frequency max{};
|
||||||
std::string label{};
|
std::string label{};
|
||||||
};
|
};
|
||||||
|
|
||||||
const Style style_white { // free range
|
const Style style_white{
|
||||||
|
// free range
|
||||||
.font = font::fixed_8x16,
|
.font = font::fixed_8x16,
|
||||||
.background = Color::black(),
|
.background = Color::black(),
|
||||||
.foreground = Color::white(),
|
.foreground = Color::white(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const Style style_red { // locked range
|
const Style style_red{
|
||||||
|
// locked range
|
||||||
.font = font::fixed_8x16,
|
.font = font::fixed_8x16,
|
||||||
.background = Color::black(),
|
.background = Color::black(),
|
||||||
.foreground = Color::red(),
|
.foreground = Color::red(),
|
||||||
|
@ -130,32 +128,27 @@ namespace ui
|
||||||
{{0, 1 * 16}, "RANGE: FILTER: AMP:", Color::light_grey()},
|
{{0, 1 * 16}, "RANGE: FILTER: AMP:", Color::light_grey()},
|
||||||
{{0, 2 * 16}, "PRESET:", Color::light_grey()},
|
{{0, 2 * 16}, "PRESET:", Color::light_grey()},
|
||||||
{{0, 3 * 16}, "MARKER: MHz", Color::light_grey()},
|
{{0, 3 * 16}, "MARKER: MHz", Color::light_grey()},
|
||||||
{{0, 4 * 16}, "RES: STEP:", Color::light_grey()}
|
{{0, 4 * 16}, "RES: STEP:", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_frequency_min{
|
NumberField field_frequency_min{
|
||||||
{4 * 8, 0 * 16},
|
{4 * 8, 0 * 16},
|
||||||
4,
|
4,
|
||||||
{0, 7199},
|
{0, 7199},
|
||||||
1, // number of steps by encoder delta
|
1, // number of steps by encoder delta
|
||||||
' '
|
' '};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_frequency_max{
|
NumberField field_frequency_max{
|
||||||
{13 * 8, 0 * 16},
|
{13 * 8, 0 * 16},
|
||||||
4,
|
4,
|
||||||
{1, 7200},
|
{1, 7200},
|
||||||
1, // number of steps by encoder delta
|
1, // number of steps by encoder delta
|
||||||
' '
|
' '};
|
||||||
};
|
|
||||||
|
|
||||||
LNAGainField field_lna{
|
LNAGainField field_lna{
|
||||||
{ 21 * 8, 0 * 16 }
|
{21 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
VGAGainField field_vga{
|
VGAGainField field_vga{
|
||||||
{ 27 * 8, 0 * 16 }
|
{27 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_range{
|
Button button_range{
|
||||||
{7 * 8, 1 * 16, 4 * 8, 16},
|
{7 * 8, 1 * 16, 4 * 8, 16},
|
||||||
|
@ -182,8 +175,7 @@ namespace ui
|
||||||
|
|
||||||
ButtonWithEncoder button_marker{
|
ButtonWithEncoder button_marker{
|
||||||
{7 * 8, 3 * 16, 10 * 8, 16},
|
{7 * 8, 3 * 16, 10 * 8, 16},
|
||||||
" "
|
" "};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_trigger{
|
NumberField field_trigger{
|
||||||
{4 * 8, 4 * 16},
|
{4 * 8, 4 * 16},
|
||||||
|
@ -202,8 +194,7 @@ namespace ui
|
||||||
{"100", 100},
|
{"100", 100},
|
||||||
{"250", 250},
|
{"250", 250},
|
||||||
{"500", 500},
|
{"500", 500},
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField scan_type{
|
OptionsField scan_type{
|
||||||
{17 * 8, 4 * 16},
|
{17 * 8, 4 * 16},
|
||||||
|
@ -211,8 +202,7 @@ namespace ui
|
||||||
{
|
{
|
||||||
{"F-", true},
|
{"F-", true},
|
||||||
{"S-", false},
|
{"S-", false},
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField view_config{
|
OptionsField view_config{
|
||||||
{19 * 8, 4 * 16},
|
{19 * 8, 4 * 16},
|
||||||
|
@ -221,8 +211,7 @@ namespace ui
|
||||||
{"SPCTR-V", 0},
|
{"SPCTR-V", 0},
|
||||||
{"LEVEL-V", 1},
|
{"LEVEL-V", 1},
|
||||||
{"PEAK-V", 2},
|
{"PEAK-V", 2},
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField level_integration{
|
OptionsField level_integration{
|
||||||
{27 * 8, 4 * 16},
|
{27 * 8, 4 * 16},
|
||||||
|
@ -242,26 +231,22 @@ namespace ui
|
||||||
|
|
||||||
Button button_jump{
|
Button button_jump{
|
||||||
{240 - 4 * 8, 5 * 16, 4 * 8, 16},
|
{240 - 4 * 8, 5 * 16, 4 * 8, 16},
|
||||||
"JMP"
|
"JMP"};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_rst{
|
Button button_rst{
|
||||||
{240 - 9 * 8, 5 * 16, 4 * 8, 16},
|
{240 - 9 * 8, 5 * 16, 4 * 8, 16},
|
||||||
"RST"
|
"RST"};
|
||||||
};
|
|
||||||
|
|
||||||
Text freq_stats{
|
Text freq_stats{
|
||||||
{0 * 8, 5 * 16, 240 - 10 * 8, 8},
|
{0 * 8, 5 * 16, 240 - 10 * 8, 8},
|
||||||
""
|
""};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_spectrum_config{
|
MessageHandlerRegistration message_handler_spectrum_config{
|
||||||
Message::ID::ChannelSpectrumConfig,
|
Message::ID::ChannelSpectrumConfig,
|
||||||
[this](const Message* const p) {
|
[this](const Message* const p) {
|
||||||
const auto message = *reinterpret_cast<const ChannelSpectrumConfigMessage*>(p);
|
const auto message = *reinterpret_cast<const ChannelSpectrumConfigMessage*>(p);
|
||||||
this->fifo = message.fifo;
|
this->fifo = message.fifo;
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
MessageHandlerRegistration message_handler_frame_sync{
|
MessageHandlerRegistration message_handler_frame_sync{
|
||||||
Message::ID::DisplayFrameSync,
|
Message::ID::DisplayFrameSync,
|
||||||
[this](const Message* const) {
|
[this](const Message* const) {
|
||||||
|
@ -271,8 +256,7 @@ namespace ui
|
||||||
this->on_channel_spectrum(channel_spectrum);
|
this->on_channel_spectrum(channel_spectrum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}};
|
||||||
};
|
};
|
||||||
};
|
} // namespace ui
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -39,10 +39,8 @@ using wolfson::wm8731::WM8731;
|
||||||
using namespace tonekey;
|
using namespace tonekey;
|
||||||
using namespace portapack;
|
using namespace portapack;
|
||||||
|
|
||||||
|
|
||||||
WM8731 audio_codec_wm8731{i2c0, 0x1a};
|
WM8731 audio_codec_wm8731{i2c0, 0x1a};
|
||||||
|
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
void MicTXView::focus() {
|
void MicTXView::focus() {
|
||||||
|
@ -79,9 +77,7 @@ void MicTXView::configure_baseband() {
|
||||||
enable_am,
|
enable_am,
|
||||||
enable_dsb,
|
enable_dsb,
|
||||||
enable_usb,
|
enable_usb,
|
||||||
enable_lsb
|
enable_lsb);
|
||||||
);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MicTXView::set_tx(bool enable) {
|
void MicTXView::set_tx(bool enable) {
|
||||||
|
@ -162,8 +158,7 @@ void MicTXView::rxaudio(bool is_on) {
|
||||||
receiver_model.set_modulation(ReceiverModel::Mode::AMAudio); // that AM demodulation engine is common to all Amplitude mod : AM/USB/LSB/DSB (2,3,4,5)
|
receiver_model.set_modulation(ReceiverModel::Mode::AMAudio); // that AM demodulation engine is common to all Amplitude mod : AM/USB/LSB/DSB (2,3,4,5)
|
||||||
if (options_mode.selected_index() < 5) // We will be called here with 2,3,4,5 . We treat here demod. filter 2,3,4; (excluding DSB-C case (5) it is treated more down).
|
if (options_mode.selected_index() < 5) // We will be called here with 2,3,4,5 . We treat here demod. filter 2,3,4; (excluding DSB-C case (5) it is treated more down).
|
||||||
receiver_model.set_am_configuration(options_mode.selected_index() - 1); // selecting proper filter(2,3,4). 2-1=1=>6k-AM(1) , 3-1=2=>+3k-USB(2), 4-1=3=>-3K-LSB(3),
|
receiver_model.set_am_configuration(options_mode.selected_index() - 1); // selecting proper filter(2,3,4). 2-1=1=>6k-AM(1) , 3-1=2=>+3k-USB(2), 4-1=3=>-3K-LSB(3),
|
||||||
}
|
} else { // We are in NFM/FM or WFM (NFM BW:8k5 or 11k / FM BW 16k / WFM BW:200k)
|
||||||
else { // We are in NFM/FM or WFM (NFM BW:8k5 or 11k / FM BW 16k / WFM BW:200k)
|
|
||||||
|
|
||||||
if (enable_wfm) { // WFM , BW 200Khz aprox , or the two new addional BW filters (180k, 40k)
|
if (enable_wfm) { // WFM , BW 200Khz aprox , or the two new addional BW filters (180k, 40k)
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_wfm_audio);
|
baseband::run_image(portapack::spi_flash::image_tag_wfm_audio);
|
||||||
|
@ -213,16 +208,13 @@ void MicTXView::set_ptt_visibility(bool v) {
|
||||||
}
|
}
|
||||||
|
|
||||||
MicTXView::MicTXView(
|
MicTXView::MicTXView(
|
||||||
NavigationView& nav
|
NavigationView& nav) {
|
||||||
)
|
|
||||||
{
|
|
||||||
portapack::pin_i2s0_rx_sda.mode(3); // This is already done in audio::init but gets changed by the CPLD overlay reprogramming
|
portapack::pin_i2s0_rx_sda.mode(3); // This is already done in audio::init but gets changed by the CPLD overlay reprogramming
|
||||||
|
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_mic_tx);
|
baseband::run_image(portapack::spi_flash::image_tag_mic_tx);
|
||||||
|
|
||||||
if (audio::debug::codec_name() == "WM8731") {
|
if (audio::debug::codec_name() == "WM8731") {
|
||||||
add_children({
|
add_children({&labels_WM8731, // we have audio codec WM8731, same MIC menu as original.
|
||||||
&labels_WM8731, // we have audio codec WM8731, same MIC menu as original.
|
|
||||||
&vumeter,
|
&vumeter,
|
||||||
&options_gain, // MIC GAIN float factor on the GUI.
|
&options_gain, // MIC GAIN float factor on the GUI.
|
||||||
&options_wm8731_boost_mode,
|
&options_wm8731_boost_mode,
|
||||||
|
@ -246,12 +238,10 @@ MicTXView::MicTXView(
|
||||||
&field_rxlna,
|
&field_rxlna,
|
||||||
&field_rxvga,
|
&field_rxvga,
|
||||||
&field_rxamp,
|
&field_rxamp,
|
||||||
&tx_button
|
&tx_button});
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
add_children({
|
add_children({&labels_AK4951, // we have audio codec AK4951, enable Automatic Level Control
|
||||||
&labels_AK4951, // we have audio codec AK4951, enable Automatic Level Control
|
|
||||||
&vumeter,
|
&vumeter,
|
||||||
&options_gain,
|
&options_gain,
|
||||||
&options_ak4951_alc_mode,
|
&options_ak4951_alc_mode,
|
||||||
|
@ -275,9 +265,7 @@ MicTXView::MicTXView(
|
||||||
&field_rxlna,
|
&field_rxlna,
|
||||||
&field_rxvga,
|
&field_rxvga,
|
||||||
&field_rxamp,
|
&field_rxamp,
|
||||||
&tx_button
|
&tx_button});
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tone_keys_populate(options_tone_key);
|
tone_keys_populate(options_tone_key);
|
||||||
|
@ -294,7 +282,6 @@ MicTXView::MicTXView(
|
||||||
|
|
||||||
if (audio::debug::codec_name() == "WM8731") {
|
if (audio::debug::codec_name() == "WM8731") {
|
||||||
options_wm8731_boost_mode.on_change = [this](size_t, int8_t v) {
|
options_wm8731_boost_mode.on_change = [this](size_t, int8_t v) {
|
||||||
|
|
||||||
switch (v) {
|
switch (v) {
|
||||||
case 0: // +12 dB’s respect reference level orig fw 1.5.x fw FM : when +20dB's boost ON) and shift bits (>>8),
|
case 0: // +12 dB’s respect reference level orig fw 1.5.x fw FM : when +20dB's boost ON) and shift bits (>>8),
|
||||||
shift_bits_s16 = 6; // now mic-boost on (+20dBs) and shift bits (>>6), +20+12=32 dB’s (orig fw +20 dBs+ 0dBs)=> +12dB's respect ref.
|
shift_bits_s16 = 6; // now mic-boost on (+20dBs) and shift bits (>>6), +20+12=32 dB’s (orig fw +20 dBs+ 0dBs)=> +12dB's respect ref.
|
||||||
|
@ -467,7 +454,6 @@ MicTXView::MicTXView(
|
||||||
// configure_baseband();
|
// configure_baseband();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
check_va.on_select = [this](Checkbox&, bool v) {
|
check_va.on_select = [this](Checkbox&, bool v) {
|
||||||
va_enabled = v;
|
va_enabled = v;
|
||||||
|
@ -505,7 +491,6 @@ MicTXView::MicTXView(
|
||||||
set_dirty();
|
set_dirty();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
check_rogerbeep.on_select = [this](Checkbox&, bool v) {
|
check_rogerbeep.on_select = [this](Checkbox&, bool v) {
|
||||||
rogerbeep_enabled = v;
|
rogerbeep_enabled = v;
|
||||||
};
|
};
|
||||||
|
@ -548,8 +533,7 @@ MicTXView::MicTXView(
|
||||||
if (!(enable_am || enable_usb || enable_lsb || enable_dsb || enable_wfm)) {
|
if (!(enable_am || enable_usb || enable_lsb || enable_dsb || enable_wfm)) {
|
||||||
// In Previous fw versions, that nbfm_configuration(n) was done in any mode (FM/AM/SSB/DSB)...strictly speaking only need it in (NFM/FM)
|
// In Previous fw versions, that nbfm_configuration(n) was done in any mode (FM/AM/SSB/DSB)...strictly speaking only need it in (NFM/FM)
|
||||||
receiver_model.set_nbfm_configuration(v); // we are in NFM/FM case, we need to select proper NFM/FM RX channel filter , NFM BW 8K5(0), NFM BW 11K(1) , FM BW 16K (2)
|
receiver_model.set_nbfm_configuration(v); // we are in NFM/FM case, we need to select proper NFM/FM RX channel filter , NFM BW 8K5(0), NFM BW 11K(1) , FM BW 16K (2)
|
||||||
}
|
} else { // we are not in NFM/FM mode .(we could be in any of the rest : AM /USB/LSB/DSB-SC)
|
||||||
else { // we are not in NFM/FM mode .(we could be in any of the rest : AM /USB/LSB/DSB-SC)
|
|
||||||
if (enable_am) { // we are in AM TX mode , we will allow both independent RX audio BW : AM 9K (9K00AE3 / AM 6K (6K00AE3). (In AM option v can be 0 (9k) , 1 (6k)
|
if (enable_am) { // we are in AM TX mode , we will allow both independent RX audio BW : AM 9K (9K00AE3 / AM 6K (6K00AE3). (In AM option v can be 0 (9k) , 1 (6k)
|
||||||
receiver_model.set_am_configuration(v); // we are in AM TX mode , we need to select proper AM full path config AM-9K filter. 0+0 =>AM-9K(0), 0+1=1 =>AM-6K(1),
|
receiver_model.set_am_configuration(v); // we are in AM TX mode , we need to select proper AM full path config AM-9K filter. 0+0 =>AM-9K(0), 0+1=1 =>AM-6K(1),
|
||||||
}
|
}
|
||||||
|
@ -589,7 +573,6 @@ MicTXView::MicTXView(
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
rx_lna = receiver_model.lna();
|
rx_lna = receiver_model.lna();
|
||||||
field_rxlna.on_change = [this](int32_t v) {
|
field_rxlna.on_change = [this](int32_t v) {
|
||||||
rx_lna = v;
|
rx_lna = v;
|
||||||
|
@ -652,4 +635,4 @@ MicTXView::~MicTXView() {
|
||||||
baseband::shutdown(); // better this function at the end, not load_sram() that sometimes produces hang up.
|
baseband::shutdown(); // better this function at the end, not load_sram() that sometimes produces hang up.
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace ui
|
||||||
|
|
|
@ -113,7 +113,6 @@ private:
|
||||||
bool enable_lsb{false};
|
bool enable_lsb{false};
|
||||||
bool enable_wfm{false}; // added to distinguish in the FM mode , RX BW : NFM (8K5, 11K), FM (16K), WFM(200K)
|
bool enable_wfm{false}; // added to distinguish in the FM mode , RX BW : NFM (8K5, 11K), FM (16K), WFM(200K)
|
||||||
|
|
||||||
|
|
||||||
Labels labels_WM8731{
|
Labels labels_WM8731{
|
||||||
{{3 * 8, 1 * 8}, "MIC-GAIN:", Color::light_grey()},
|
{{3 * 8, 1 * 8}, "MIC-GAIN:", Color::light_grey()},
|
||||||
{{17 * 8, 1 * 8}, "Boost", Color::light_grey()},
|
{{17 * 8, 1 * 8}, "Boost", Color::light_grey()},
|
||||||
|
@ -131,8 +130,7 @@ private:
|
||||||
{{5 * 8, 25 * 8}, "F_RX:", Color::light_grey()},
|
{{5 * 8, 25 * 8}, "F_RX:", Color::light_grey()},
|
||||||
{{5 * 8, 27 * 8}, "LNA:", Color::light_grey()},
|
{{5 * 8, 27 * 8}, "LNA:", Color::light_grey()},
|
||||||
{{12 * 8, 27 * 8}, "VGA:", Color::light_grey()},
|
{{12 * 8, 27 * 8}, "VGA:", Color::light_grey()},
|
||||||
{ {19 * 8, 27 * 8 }, "AMP:", Color::light_grey()}
|
{{19 * 8, 27 * 8}, "AMP:", Color::light_grey()}};
|
||||||
};
|
|
||||||
Labels labels_AK4951{
|
Labels labels_AK4951{
|
||||||
{{3 * 8, 1 * 8}, "MIC-GAIN:", Color::light_grey()},
|
{{3 * 8, 1 * 8}, "MIC-GAIN:", Color::light_grey()},
|
||||||
{{17 * 8, 1 * 8}, "ALC", Color::light_grey()},
|
{{17 * 8, 1 * 8}, "ALC", Color::light_grey()},
|
||||||
|
@ -150,26 +148,20 @@ private:
|
||||||
{{5 * 8, 25 * 8}, "F_RX:", Color::light_grey()},
|
{{5 * 8, 25 * 8}, "F_RX:", Color::light_grey()},
|
||||||
{{5 * 8, 27 * 8}, "LNA:", Color::light_grey()},
|
{{5 * 8, 27 * 8}, "LNA:", Color::light_grey()},
|
||||||
{{12 * 8, 27 * 8}, "VGA:", Color::light_grey()},
|
{{12 * 8, 27 * 8}, "VGA:", Color::light_grey()},
|
||||||
{ {19 * 8, 27 * 8 }, "AMP:", Color::light_grey()}
|
{{19 * 8, 27 * 8}, "AMP:", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
VuMeter vumeter{
|
VuMeter vumeter{
|
||||||
{0 * 8, 1 * 8, 2 * 8, 33 * 8},
|
{0 * 8, 1 * 8, 2 * 8, 33 * 8},
|
||||||
12,
|
12,
|
||||||
true
|
true};
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
OptionsField options_gain{
|
OptionsField options_gain{
|
||||||
{12 * 8, 1 * 8},
|
{12 * 8, 1 * 8},
|
||||||
4,
|
4,
|
||||||
{
|
{{"x0.5", 5},
|
||||||
{ "x0.5", 5 },
|
|
||||||
{"x1.0", 10},
|
{"x1.0", 10},
|
||||||
{"x1.5", 15},
|
{"x1.5", 15},
|
||||||
{ "x2.0", 20 }
|
{"x2.0", 20}}};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField options_ak4951_alc_mode{
|
OptionsField options_ak4951_alc_mode{
|
||||||
{20 * 8, 1 * 8}, // Coordinates are: int:x (px), int:y (px)
|
{20 * 8, 1 * 8}, // Coordinates are: int:x (px), int:y (px)
|
||||||
|
@ -187,8 +179,7 @@ private:
|
||||||
{"-06dB-6kHz", 9}, // ALC-> on, (-06dB's) Auto Vol max + Wind Noise cancel + LPF 6kHz + Pre-amp Mic (+21dB=original)
|
{"-06dB-6kHz", 9}, // ALC-> on, (-06dB's) Auto Vol max + Wind Noise cancel + LPF 6kHz + Pre-amp Mic (+21dB=original)
|
||||||
{"-09dB-6kHz", 10}, // ALC-> on, (-09dB's) Auto Vol max + Wind Noise cancel + LPF 6kHz - Pre-amp MIC -3dB (18dB's)
|
{"-09dB-6kHz", 10}, // ALC-> on, (-09dB's) Auto Vol max + Wind Noise cancel + LPF 6kHz - Pre-amp MIC -3dB (18dB's)
|
||||||
{"-12dB-6kHz", 11}, // ALC-> on, (-12dB's) Auto Vol max + Wind Noise cancel + LPF 6kHz - Pre-amp MIC -6dB (15dB's)
|
{"-12dB-6kHz", 11}, // ALC-> on, (-12dB's) Auto Vol max + Wind Noise cancel + LPF 6kHz - Pre-amp MIC -6dB (15dB's)
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField options_wm8731_boost_mode{
|
OptionsField options_wm8731_boost_mode{
|
||||||
{22 * 8, 1 * 8}, // Coordinates are: int:x (px), int:y (px)
|
{22 * 8, 1 * 8}, // Coordinates are: int:x (px), int:y (px)
|
||||||
|
@ -199,8 +190,7 @@ OptionsField options_wm8731_boost_mode {
|
||||||
{"OFF+04dB", 2}, // WM8731 Mic Boost OFF to avoid ADC sat in high voice ,relative G = +04 dB's (respect ref level) , always effective sampling 24khz
|
{"OFF+04dB", 2}, // WM8731 Mic Boost OFF to avoid ADC sat in high voice ,relative G = +04 dB's (respect ref level) , always effective sampling 24khz
|
||||||
{"OFF-02dB", 3}, // WM8731 Mic Boost OFF to avoid ADC sat in high voice ,relative G = -02 dB's (respect ref level)
|
{"OFF-02dB", 3}, // WM8731 Mic Boost OFF to avoid ADC sat in high voice ,relative G = -02 dB's (respect ref level)
|
||||||
{"OFF-08dB", 4}, // WM8731 Mic Boost OFF to avoid ADC sat in high voice ,relative G = -12 dB's (respect ref level)
|
{"OFF-08dB", 4}, // WM8731 Mic Boost OFF to avoid ADC sat in high voice ,relative G = -12 dB's (respect ref level)
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
FrequencyField field_frequency{
|
FrequencyField field_frequency{
|
||||||
{5 * 8, 3 * 8},
|
{5 * 8, 3 * 8},
|
||||||
|
@ -210,10 +200,10 @@ OptionsField options_wm8731_boost_mode {
|
||||||
3,
|
3,
|
||||||
{0, 150},
|
{0, 150},
|
||||||
1,
|
1,
|
||||||
' '
|
' '};
|
||||||
};
|
|
||||||
|
|
||||||
TransmitterView2 tx_view { // new handling of NumberField field_rfgain, NumberField field_rfamp
|
TransmitterView2 tx_view{
|
||||||
|
// new handling of NumberField field_rfgain, NumberField field_rfamp
|
||||||
// 3*8, 2*8, SHORT_UI // x(columns), y (line) position. (used in Replay / GPS Simul / Playlist App's)
|
// 3*8, 2*8, SHORT_UI // x(columns), y (line) position. (used in Replay / GPS Simul / Playlist App's)
|
||||||
3 * 8, 2 * 8, NORMAL_UI // x(columns), y (line) position. (used in Mic App)
|
3 * 8, 2 * 8, NORMAL_UI // x(columns), y (line) position. (used in Mic App)
|
||||||
};
|
};
|
||||||
|
@ -228,8 +218,7 @@ OptionsField options_wm8731_boost_mode {
|
||||||
{" USB ", 3},
|
{" USB ", 3},
|
||||||
{" LSB ", 4},
|
{" LSB ", 4},
|
||||||
{"DSB-SC", 5} // We are TX Double Side AM Band with suppressed carrier, and allowing in RX both indep SSB lateral band (USB/LSB).
|
{"DSB-SC", 5} // We are TX Double Side AM Band with suppressed carrier, and allowing in RX both indep SSB lateral band (USB/LSB).
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
/*
|
/*
|
||||||
Checkbox check_va {
|
Checkbox check_va {
|
||||||
{ 3 * 8, (10 * 8) - 4 },
|
{ 3 * 8, (10 * 8) - 4 },
|
||||||
|
@ -242,61 +231,51 @@ OptionsField options_wm8731_boost_mode {
|
||||||
OptionsField field_va{
|
OptionsField field_va{
|
||||||
{17 * 8, 8 * 8},
|
{17 * 8, 8 * 8},
|
||||||
3,
|
3,
|
||||||
{
|
{{" OFF", 0},
|
||||||
{" OFF", 0},
|
|
||||||
{" PTT", 1},
|
{" PTT", 1},
|
||||||
{"AUTO", 2}
|
{"AUTO", 2}}};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_va_level{
|
NumberField field_va_level{
|
||||||
{8 * 8, 10 * 8},
|
{8 * 8, 10 * 8},
|
||||||
3,
|
3,
|
||||||
{0, 255},
|
{0, 255},
|
||||||
2,
|
2,
|
||||||
' '
|
' '};
|
||||||
};
|
|
||||||
NumberField field_va_attack{
|
NumberField field_va_attack{
|
||||||
{16 * 8, 10 * 8},
|
{16 * 8, 10 * 8},
|
||||||
3,
|
3,
|
||||||
{0, 999},
|
{0, 999},
|
||||||
20,
|
20,
|
||||||
' '
|
' '};
|
||||||
};
|
|
||||||
NumberField field_va_decay{
|
NumberField field_va_decay{
|
||||||
{24 * 8, 10 * 8},
|
{24 * 8, 10 * 8},
|
||||||
4,
|
4,
|
||||||
{0, 9999},
|
{0, 9999},
|
||||||
100,
|
100,
|
||||||
' '
|
' '};
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField options_tone_key{
|
OptionsField options_tone_key{
|
||||||
{10 * 8, (15 * 8) - 2},
|
{10 * 8, (15 * 8) - 2},
|
||||||
23,
|
23,
|
||||||
{ }
|
{}};
|
||||||
};
|
|
||||||
|
|
||||||
Checkbox check_rogerbeep{
|
Checkbox check_rogerbeep{
|
||||||
{3 * 8, (16 * 8) + 7},
|
{3 * 8, (16 * 8) + 7},
|
||||||
10,
|
10,
|
||||||
"Roger beep",
|
"Roger beep",
|
||||||
false
|
false};
|
||||||
};
|
|
||||||
|
|
||||||
Checkbox check_rxactive{
|
Checkbox check_rxactive{
|
||||||
{3 * 8, (21 * 8) - 4},
|
{3 * 8, (21 * 8) - 4},
|
||||||
18, // it was 8, but if it is string size should be 18
|
18, // it was 8, but if it is string size should be 18
|
||||||
"RX audio listening",
|
"RX audio listening",
|
||||||
false
|
false};
|
||||||
};
|
|
||||||
|
|
||||||
Checkbox check_common_freq_tx_rx{
|
Checkbox check_common_freq_tx_rx{
|
||||||
{18 * 8, (16 * 8) + 7},
|
{18 * 8, (16 * 8) + 7},
|
||||||
8,
|
8,
|
||||||
"F = F_RX",
|
"F = F_RX",
|
||||||
false
|
false};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_volume{
|
NumberField field_volume{
|
||||||
{11 * 8, 23 * 8},
|
{11 * 8, 23 * 8},
|
||||||
|
@ -313,8 +292,7 @@ OptionsField options_wm8731_boost_mode {
|
||||||
{" NFM1:8k5 ", 0},
|
{" NFM1:8k5 ", 0},
|
||||||
{" NFM2:11k ", 1},
|
{" NFM2:11k ", 1},
|
||||||
{" FM :16k ", 2},
|
{" FM :16k ", 2},
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_squelch{
|
NumberField field_squelch{
|
||||||
{23 * 8, 25 * 8},
|
{23 * 8, 25 * 8},
|
||||||
|
@ -355,33 +333,28 @@ OptionsField options_wm8731_boost_mode {
|
||||||
Button tx_button{
|
Button tx_button{
|
||||||
{10 * 8, 30 * 8, 10 * 8, 5 * 8},
|
{10 * 8, 30 * 8, 10 * 8, 5 * 8},
|
||||||
"TX",
|
"TX",
|
||||||
true
|
true};
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_lcd_sync{
|
MessageHandlerRegistration message_handler_lcd_sync{
|
||||||
Message::ID::DisplayFrameSync,
|
Message::ID::DisplayFrameSync,
|
||||||
[this](const Message* const) {
|
[this](const Message* const) {
|
||||||
this->do_timing();
|
this->do_timing();
|
||||||
this->update_vumeter();
|
this->update_vumeter();
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_audio_level{
|
MessageHandlerRegistration message_handler_audio_level{
|
||||||
Message::ID::AudioLevelReport,
|
Message::ID::AudioLevelReport,
|
||||||
[this](const Message* const p) {
|
[this](const Message* const p) {
|
||||||
const auto message = static_cast<const AudioLevelReportMessage*>(p);
|
const auto message = static_cast<const AudioLevelReportMessage*>(p);
|
||||||
this->audio_level = message->value;
|
this->audio_level = message->value;
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_tx_progress{
|
MessageHandlerRegistration message_handler_tx_progress{
|
||||||
Message::ID::TXProgress,
|
Message::ID::TXProgress,
|
||||||
[this](const Message* const p) {
|
[this](const Message* const p) {
|
||||||
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
|
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
|
||||||
this->on_tx_progress(message.done);
|
this->on_tx_progress(message.done);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -36,15 +36,12 @@ void ModemSetupView::focus() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ModemSetupView::ModemSetupView(
|
ModemSetupView::ModemSetupView(
|
||||||
NavigationView& nav
|
NavigationView& nav) {
|
||||||
)
|
|
||||||
{
|
|
||||||
using option_t = std::pair<std::string, int32_t>;
|
using option_t = std::pair<std::string, int32_t>;
|
||||||
using options_t = std::vector<option_t>;
|
using options_t = std::vector<option_t>;
|
||||||
options_t modem_options;
|
options_t modem_options;
|
||||||
|
|
||||||
add_children({
|
add_children({&labels,
|
||||||
&labels,
|
|
||||||
&field_baudrate,
|
&field_baudrate,
|
||||||
&field_mark,
|
&field_mark,
|
||||||
&field_space,
|
&field_space,
|
||||||
|
@ -52,8 +49,7 @@ ModemSetupView::ModemSetupView(
|
||||||
&options_modem,
|
&options_modem,
|
||||||
&button_set_modem,
|
&button_set_modem,
|
||||||
&sym_format,
|
&sym_format,
|
||||||
&button_save
|
&button_save});
|
||||||
});
|
|
||||||
|
|
||||||
// Only list AFSK modems for now
|
// Only list AFSK modems for now
|
||||||
for (size_t i = 0; i < MODEM_DEF_COUNT; i++) {
|
for (size_t i = 0; i < MODEM_DEF_COUNT; i++) {
|
||||||
|
|
|
@ -46,63 +46,53 @@ private:
|
||||||
{{2 * 8, 15 * 8}, "Space: Hz", Color::light_grey()},
|
{{2 * 8, 15 * 8}, "Space: Hz", Color::light_grey()},
|
||||||
{{140, 15 * 8}, "Repeat:", Color::light_grey()},
|
{{140, 15 * 8}, "Repeat:", Color::light_grey()},
|
||||||
{{1 * 8, 6 * 8}, "Modem preset:", Color::light_grey()},
|
{{1 * 8, 6 * 8}, "Modem preset:", Color::light_grey()},
|
||||||
{ { 2 * 8, 22 * 8 }, "Serial format:", Color::light_grey() }
|
{{2 * 8, 22 * 8}, "Serial format:", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_baudrate{
|
NumberField field_baudrate{
|
||||||
{11 * 8, 11 * 8},
|
{11 * 8, 11 * 8},
|
||||||
5,
|
5,
|
||||||
{50, 9600},
|
{50, 9600},
|
||||||
25,
|
25,
|
||||||
' '
|
' '};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_mark{
|
NumberField field_mark{
|
||||||
{8 * 8, 13 * 8},
|
{8 * 8, 13 * 8},
|
||||||
5,
|
5,
|
||||||
{100, 15000},
|
{100, 15000},
|
||||||
25,
|
25,
|
||||||
' '
|
' '};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_space{
|
NumberField field_space{
|
||||||
{8 * 8, 15 * 8},
|
{8 * 8, 15 * 8},
|
||||||
5,
|
5,
|
||||||
{100, 15000},
|
{100, 15000},
|
||||||
25,
|
25,
|
||||||
' '
|
' '};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_repeat{
|
NumberField field_repeat{
|
||||||
{204, 15 * 8},
|
{204, 15 * 8},
|
||||||
2,
|
2,
|
||||||
{1, 99},
|
{1, 99},
|
||||||
1,
|
1,
|
||||||
' '
|
' '};
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField options_modem{
|
OptionsField options_modem{
|
||||||
{15 * 8, 6 * 8},
|
{15 * 8, 6 * 8},
|
||||||
7,
|
7,
|
||||||
{
|
{}};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
SymField sym_format{
|
SymField sym_format{
|
||||||
{16 * 8, 22 * 8},
|
{16 * 8, 22 * 8},
|
||||||
4,
|
4,
|
||||||
SymField::SYMFIELD_DEF
|
SymField::SYMFIELD_DEF};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_set_modem{
|
Button button_set_modem{
|
||||||
{23 * 8, 6 * 8 - 4, 6 * 8, 24},
|
{23 * 8, 6 * 8 - 4, 6 * 8, 24},
|
||||||
"SET"
|
"SET"};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_save{
|
Button button_save{
|
||||||
{9 * 8, 250, 96, 40},
|
{9 * 8, 250, 96, 40},
|
||||||
"Save"
|
"Save"};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -189,13 +189,11 @@ void MorseView::set_foxhunt(size_t i) {
|
||||||
}
|
}
|
||||||
|
|
||||||
MorseView::MorseView(
|
MorseView::MorseView(
|
||||||
NavigationView& nav
|
NavigationView& nav)
|
||||||
) : nav_ (nav)
|
: nav_(nav) {
|
||||||
{
|
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_tones);
|
baseband::run_image(portapack::spi_flash::image_tag_tones);
|
||||||
|
|
||||||
add_children({
|
add_children({&labels,
|
||||||
&labels,
|
|
||||||
&checkbox_foxhunt,
|
&checkbox_foxhunt,
|
||||||
&options_foxhunt,
|
&options_foxhunt,
|
||||||
&field_speed,
|
&field_speed,
|
||||||
|
@ -206,8 +204,7 @@ MorseView::MorseView(
|
||||||
&text_message,
|
&text_message,
|
||||||
&button_message,
|
&button_message,
|
||||||
&progressbar,
|
&progressbar,
|
||||||
&tx_view
|
&tx_view});
|
||||||
});
|
|
||||||
|
|
||||||
// load app settings
|
// load app settings
|
||||||
auto rc = settings.load("tx_morse", &app_settings);
|
auto rc = settings.load("tx_morse", &app_settings);
|
||||||
|
|
|
@ -61,6 +61,7 @@ public:
|
||||||
uint32_t time_unit_ms{0};
|
uint32_t time_unit_ms{0};
|
||||||
size_t symbol_count{0};
|
size_t symbol_count{0};
|
||||||
uint32_t loop{0};
|
uint32_t loop{0};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NavigationView& nav_;
|
NavigationView& nav_;
|
||||||
std::string buffer{"PORTAPACK"};
|
std::string buffer{"PORTAPACK"};
|
||||||
|
@ -92,19 +93,16 @@ private:
|
||||||
{{4 * 8, 8 * 8}, "Tone: Hz", Color::light_grey()},
|
{{4 * 8, 8 * 8}, "Tone: Hz", Color::light_grey()},
|
||||||
{{4 * 8, 10 * 8}, "Modulation:", Color::light_grey()},
|
{{4 * 8, 10 * 8}, "Modulation:", Color::light_grey()},
|
||||||
{{4 * 8, 12 * 8}, "Loop:", Color::light_grey()},
|
{{4 * 8, 12 * 8}, "Loop:", Color::light_grey()},
|
||||||
{ { 1 * 8, 25 * 8 }, "TX will last", Color::light_grey() }
|
{{1 * 8, 25 * 8}, "TX will last", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
Checkbox checkbox_foxhunt{
|
Checkbox checkbox_foxhunt{
|
||||||
{4 * 8, 16},
|
{4 * 8, 16},
|
||||||
8,
|
8,
|
||||||
"Foxhunt:"
|
"Foxhunt:"};
|
||||||
};
|
|
||||||
OptionsField options_foxhunt{
|
OptionsField options_foxhunt{
|
||||||
{17 * 8, 16 + 4},
|
{17 * 8, 16 + 4},
|
||||||
7,
|
7,
|
||||||
{
|
{{"1 (MOE)", 0},
|
||||||
{ "1 (MOE)", 0 },
|
|
||||||
{"2 (MOI)", 1},
|
{"2 (MOI)", 1},
|
||||||
{"3 (MOS)", 2},
|
{"3 (MOS)", 2},
|
||||||
{"4 (MOH)", 3},
|
{"4 (MOH)", 3},
|
||||||
|
@ -114,81 +112,65 @@ private:
|
||||||
{"8 (MOB)", 7},
|
{"8 (MOB)", 7},
|
||||||
{"9 (MO6)", 8},
|
{"9 (MO6)", 8},
|
||||||
{"X (MO) ", 9},
|
{"X (MO) ", 9},
|
||||||
{ "T (S) ", 10 }
|
{"T (S) ", 10}}};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_speed{
|
NumberField field_speed{
|
||||||
{10 * 8, 6 * 8},
|
{10 * 8, 6 * 8},
|
||||||
3,
|
3,
|
||||||
{10, 45},
|
{10, 45},
|
||||||
1,
|
1,
|
||||||
' '
|
' '};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_tone{
|
NumberField field_tone{
|
||||||
{9 * 8, 8 * 8},
|
{9 * 8, 8 * 8},
|
||||||
4,
|
4,
|
||||||
{100, 9999},
|
{100, 9999},
|
||||||
20,
|
20,
|
||||||
' '
|
' '};
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField options_modulation{
|
OptionsField options_modulation{
|
||||||
{15 * 8, 10 * 8},
|
{15 * 8, 10 * 8},
|
||||||
2,
|
2,
|
||||||
{
|
{{"CW", 0},
|
||||||
{ "CW", 0 },
|
{"FM", 1}}};
|
||||||
{ "FM", 1 }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField options_loop{
|
OptionsField options_loop{
|
||||||
{9 * 8, 12 * 8},
|
{9 * 8, 12 * 8},
|
||||||
6,
|
6,
|
||||||
{
|
{{"Off", 0},
|
||||||
{ "Off", 0 },
|
|
||||||
{"5 sec", 5},
|
{"5 sec", 5},
|
||||||
{"10 sec", 10},
|
{"10 sec", 10},
|
||||||
{"30 sec", 30},
|
{"30 sec", 30},
|
||||||
{"1 min", 60},
|
{"1 min", 60},
|
||||||
{"3 min", 180},
|
{"3 min", 180},
|
||||||
{ "5 min", 300 }
|
{"5 min", 300}}};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Text text_tx_duration{
|
Text text_tx_duration{
|
||||||
{14 * 8, 25 * 8, 4 * 8, 16},
|
{14 * 8, 25 * 8, 4 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_message{
|
Text text_message{
|
||||||
{1 * 8, 15 * 8, 28 * 8, 16},
|
{1 * 8, 15 * 8, 28 * 8, 16},
|
||||||
""
|
""};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_message{
|
Button button_message{
|
||||||
{1 * 8, 17 * 8, 12 * 8, 28},
|
{1 * 8, 17 * 8, 12 * 8, 28},
|
||||||
"Set message"
|
"Set message"};
|
||||||
};
|
|
||||||
|
|
||||||
ProgressBar progressbar{
|
ProgressBar progressbar{
|
||||||
{ 2 * 8, 28 * 8, 208, 16 }
|
{2 * 8, 28 * 8, 208, 16}};
|
||||||
};
|
|
||||||
|
|
||||||
TransmitterView tx_view{
|
TransmitterView tx_view{
|
||||||
16 * 16,
|
16 * 16,
|
||||||
10000,
|
10000,
|
||||||
12
|
12};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_tx_progress{
|
MessageHandlerRegistration message_handler_tx_progress{
|
||||||
Message::ID::TXProgress,
|
Message::ID::TXProgress,
|
||||||
[this](const Message* const p) {
|
[this](const Message* const p) {
|
||||||
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
|
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
|
||||||
this->on_tx_progress(message.progress, message.done);
|
this->on_tx_progress(message.progress, message.done);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -47,16 +47,14 @@ void NRFRxView::update_freq(rf::Frequency f) {
|
||||||
NRFRxView::NRFRxView(NavigationView& nav) {
|
NRFRxView::NRFRxView(NavigationView& nav) {
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_nrf_rx);
|
baseband::run_image(portapack::spi_flash::image_tag_nrf_rx);
|
||||||
|
|
||||||
add_children({
|
add_children({&rssi,
|
||||||
&rssi,
|
|
||||||
&channel,
|
&channel,
|
||||||
&field_rf_amp,
|
&field_rf_amp,
|
||||||
&field_lna,
|
&field_lna,
|
||||||
&field_vga,
|
&field_vga,
|
||||||
&field_frequency,
|
&field_frequency,
|
||||||
&button_modem_setup,
|
&button_modem_setup,
|
||||||
&console
|
&console});
|
||||||
});
|
|
||||||
|
|
||||||
// load app settings
|
// load app settings
|
||||||
auto rc = settings.load("rx_nrf", &app_settings);
|
auto rc = settings.load("rx_nrf", &app_settings);
|
||||||
|
@ -94,7 +92,6 @@ NRFRxView::NRFRxView(NavigationView& nav) {
|
||||||
nav.push<ModemSetupView>();
|
nav.push<ModemSetupView>();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Auto-configure modem for LCR RX (will be removed later)
|
// Auto-configure modem for LCR RX (will be removed later)
|
||||||
baseband::set_nrf(persistent_memory::modem_baudrate(), 8, 0, false);
|
baseband::set_nrf(persistent_memory::modem_baudrate(), 8, 0, false);
|
||||||
|
|
||||||
|
@ -130,8 +127,6 @@ void NRFRxView::on_data(uint32_t value, bool is_data) {
|
||||||
str_console += " " + to_string_hex(value, 2);
|
str_console += " " + to_string_hex(value, 2);
|
||||||
console.write(str_console);
|
console.write(str_console);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*if ((value != 0x7F) && (prev_value == 0x7F)) {
|
/*if ((value != 0x7F) && (prev_value == 0x7F)) {
|
||||||
// Message split
|
// Message split
|
||||||
console.writeln("");
|
console.writeln("");
|
||||||
|
@ -143,12 +138,11 @@ void NRFRxView::on_data(uint32_t value, bool is_data) {
|
||||||
} else {
|
} else {
|
||||||
// Baudrate estimation
|
// Baudrate estimation
|
||||||
// text_debug.set("~" + to_string_dec_uint(value));
|
// text_debug.set("~" + to_string_dec_uint(value));
|
||||||
if (value == 'A')
|
if (value == 'A') {
|
||||||
{console.write("addr:");}
|
console.write("addr:");
|
||||||
else if (value == 'B')
|
} else if (value == 'B') {
|
||||||
{console.write(" data:");}
|
console.write(" data:");
|
||||||
else if (value == 'C')
|
} else if (value == 'C') {
|
||||||
{
|
|
||||||
console.writeln("");
|
console.writeln("");
|
||||||
console.writeln("");
|
console.writeln("");
|
||||||
}
|
}
|
||||||
|
@ -157,7 +151,6 @@ void NRFRxView::on_data(uint32_t value, bool is_data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
NRFRxView::~NRFRxView() {
|
NRFRxView::~NRFRxView() {
|
||||||
|
|
||||||
// save app settings
|
// save app settings
|
||||||
app_settings.rx_frequency = field_frequency.value();
|
app_settings.rx_frequency = field_frequency.value();
|
||||||
settings.save("rx_nrf", &app_settings);
|
settings.save("rx_nrf", &app_settings);
|
||||||
|
|
|
@ -54,14 +54,11 @@ private:
|
||||||
uint32_t prev_value{0};
|
uint32_t prev_value{0};
|
||||||
|
|
||||||
RFAmpField field_rf_amp{
|
RFAmpField field_rf_amp{
|
||||||
{ 13 * 8, 0 * 16 }
|
{13 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
LNAGainField field_lna{
|
LNAGainField field_lna{
|
||||||
{ 15 * 8, 0 * 16 }
|
{15 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
VGAGainField field_vga{
|
VGAGainField field_vga{
|
||||||
{ 18 * 8, 0 * 16 }
|
{18 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
RSSI rssi{
|
RSSI rssi{
|
||||||
{21 * 8, 0, 6 * 8, 4},
|
{21 * 8, 0, 6 * 8, 4},
|
||||||
};
|
};
|
||||||
|
@ -75,12 +72,10 @@ private:
|
||||||
|
|
||||||
Button button_modem_setup{
|
Button button_modem_setup{
|
||||||
{240 - 12 * 8, 1 * 16, 96, 24},
|
{240 - 12 * 8, 1 * 16, 96, 24},
|
||||||
"Modem setup"
|
"Modem setup"};
|
||||||
};
|
|
||||||
|
|
||||||
Console console{
|
Console console{
|
||||||
{ 0, 4 * 16, 240, 240 }
|
{0, 4 * 16, 240, 240}};
|
||||||
};
|
|
||||||
|
|
||||||
void update_freq(rf::Frequency f);
|
void update_freq(rf::Frequency f);
|
||||||
// void on_data_afsk(const AFSKDataMessage& message);
|
// void on_data_afsk(const AFSKDataMessage& message);
|
||||||
|
@ -90,8 +85,7 @@ private:
|
||||||
[this](Message* const p) {
|
[this](Message* const p) {
|
||||||
const auto message = static_cast<const AFSKDataMessage*>(p);
|
const auto message = static_cast<const AFSKDataMessage*>(p);
|
||||||
this->on_data(message->value, message->is_data);
|
this->on_data(message->value, message->is_data);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -139,8 +139,7 @@ void NumbersStationView::start_tx() {
|
||||||
12000,
|
12000,
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
0
|
0);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NumbersStationView::on_tick_second() {
|
void NumbersStationView::on_tick_second() {
|
||||||
|
@ -178,9 +177,8 @@ bool NumbersStationView::check_wav_validity(const std::string dir, const std::st
|
||||||
}
|
}
|
||||||
|
|
||||||
NumbersStationView::NumbersStationView(
|
NumbersStationView::NumbersStationView(
|
||||||
NavigationView& nav
|
NavigationView& nav)
|
||||||
) : nav_ (nav)
|
: nav_(nav) {
|
||||||
{
|
|
||||||
std::vector<std::filesystem::path> directory_list;
|
std::vector<std::filesystem::path> directory_list;
|
||||||
using option_t = std::pair<std::string, int32_t>;
|
using option_t = std::pair<std::string, int32_t>;
|
||||||
using options_t = std::vector<option_t>;
|
using options_t = std::vector<option_t>;
|
||||||
|
@ -237,15 +235,13 @@ NumbersStationView::NumbersStationView(
|
||||||
|
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_audio_tx);
|
baseband::run_image(portapack::spi_flash::image_tag_audio_tx);
|
||||||
|
|
||||||
add_children({
|
add_children({&labels,
|
||||||
&labels,
|
|
||||||
&symfield_code,
|
&symfield_code,
|
||||||
&check_armed,
|
&check_armed,
|
||||||
&options_voices,
|
&options_voices,
|
||||||
&text_voice_flags,
|
&text_voice_flags,
|
||||||
//&button_tx_now,
|
//&button_tx_now,
|
||||||
&button_exit
|
&button_exit});
|
||||||
});
|
|
||||||
|
|
||||||
for (const auto& voice : voices)
|
for (const auto& voice : voices)
|
||||||
voice_options.emplace_back(voice.dir.substr(0, 4), 0);
|
voice_options.emplace_back(voice.dir.substr(0, 4), 0);
|
||||||
|
|
|
@ -66,8 +66,7 @@ private:
|
||||||
Style style_red{
|
Style style_red{
|
||||||
.font = font::fixed_8x16,
|
.font = font::fixed_8x16,
|
||||||
.background = Color::black(),
|
.background = Color::black(),
|
||||||
.foreground = Color::red()
|
.foreground = Color::red()};
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char code;
|
char code;
|
||||||
|
@ -102,8 +101,7 @@ private:
|
||||||
{"7", true, '7'},
|
{"7", true, '7'},
|
||||||
{"8", true, '8'},
|
{"8", true, '8'},
|
||||||
{"9", true, '9'},
|
{"9", true, '9'},
|
||||||
{ "announce", false, 'A' }
|
{"announce", false, 'A'}};
|
||||||
};
|
|
||||||
|
|
||||||
segments segment{IDLE};
|
segments segment{IDLE};
|
||||||
bool armed{false};
|
bool armed{false};
|
||||||
|
@ -131,38 +129,32 @@ private:
|
||||||
|
|
||||||
Labels labels{
|
Labels labels{
|
||||||
{{2 * 8, 5 * 8}, "Voice: Flags:", Color::light_grey()},
|
{{2 * 8, 5 * 8}, "Voice: Flags:", Color::light_grey()},
|
||||||
{ { 1 * 8, 8 * 8 }, "Code:", Color::light_grey() }
|
{{1 * 8, 8 * 8}, "Code:", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField options_voices{
|
OptionsField options_voices{
|
||||||
{8 * 8, 1 * 8},
|
{8 * 8, 1 * 8},
|
||||||
4,
|
4,
|
||||||
{ }
|
{}};
|
||||||
};
|
|
||||||
Text text_voice_flags{
|
Text text_voice_flags{
|
||||||
{19 * 8, 1 * 8, 2 * 8, 16},
|
{19 * 8, 1 * 8, 2 * 8, 16},
|
||||||
""
|
""};
|
||||||
};
|
|
||||||
|
|
||||||
SymField symfield_code{
|
SymField symfield_code{
|
||||||
{1 * 8, 10 * 8},
|
{1 * 8, 10 * 8},
|
||||||
25,
|
25,
|
||||||
SymField::SYMFIELD_DEF
|
SymField::SYMFIELD_DEF};
|
||||||
};
|
|
||||||
|
|
||||||
Checkbox check_armed{
|
Checkbox check_armed{
|
||||||
{2 * 8, 13 * 16},
|
{2 * 8, 13 * 16},
|
||||||
5,
|
5,
|
||||||
"Armed"
|
"Armed"};
|
||||||
};
|
|
||||||
/*Button button_tx_now {
|
/*Button button_tx_now {
|
||||||
{ 18 * 8, 13 * 16, 10 * 8, 32 },
|
{ 18 * 8, 13 * 16, 10 * 8, 32 },
|
||||||
"TX now"
|
"TX now"
|
||||||
};*/
|
};*/
|
||||||
Button button_exit{
|
Button button_exit{
|
||||||
{21 * 8, 16 * 16, 64, 32},
|
{21 * 8, 16 * 16, 64, 32},
|
||||||
"Exit"
|
"Exit"};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_fifo_signal{
|
MessageHandlerRegistration message_handler_fifo_signal{
|
||||||
Message::ID::RequestSignal,
|
Message::ID::RequestSignal,
|
||||||
|
@ -171,8 +163,7 @@ private:
|
||||||
if (message->signal == RequestSignalMessage::Signal::FillRequest) {
|
if (message->signal == RequestSignalMessage::Signal::FillRequest) {
|
||||||
this->prepare_audio();
|
this->prepare_audio();
|
||||||
}
|
}
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -144,18 +144,14 @@ void NuoptixView::transmit(bool setup) {
|
||||||
}
|
}
|
||||||
|
|
||||||
NuoptixView::NuoptixView(
|
NuoptixView::NuoptixView(
|
||||||
NavigationView& nav
|
NavigationView& nav) {
|
||||||
)
|
|
||||||
{
|
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_tones);
|
baseband::run_image(portapack::spi_flash::image_tag_tones);
|
||||||
|
|
||||||
add_children({
|
add_children({&number_timecode,
|
||||||
&number_timecode,
|
|
||||||
&text_timecode,
|
&text_timecode,
|
||||||
&text_mod,
|
&text_mod,
|
||||||
&progressbar,
|
&progressbar,
|
||||||
&tx_view
|
&tx_view});
|
||||||
});
|
|
||||||
|
|
||||||
number_timecode.set_value(1);
|
number_timecode.set_value(1);
|
||||||
|
|
||||||
|
@ -189,4 +185,4 @@ NuoptixView::NuoptixView(
|
||||||
};*/
|
};*/
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace ui
|
||||||
|
|
|
@ -65,25 +65,21 @@ private:
|
||||||
|
|
||||||
Text text_timecode{
|
Text text_timecode{
|
||||||
{10 * 8, 2 * 16, 9 * 8, 16},
|
{10 * 8, 2 * 16, 9 * 8, 16},
|
||||||
"Timecode:"
|
"Timecode:"};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField number_timecode{
|
NumberField number_timecode{
|
||||||
{13 * 8, 3 * 16},
|
{13 * 8, 3 * 16},
|
||||||
4,
|
4,
|
||||||
{1, 9999},
|
{1, 9999},
|
||||||
1,
|
1,
|
||||||
'0'
|
'0'};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_mod{
|
Text text_mod{
|
||||||
{10 * 8, 5 * 16, 6 * 8, 16},
|
{10 * 8, 5 * 16, 6 * 8, 16},
|
||||||
"Mod: "
|
"Mod: "};
|
||||||
};
|
|
||||||
|
|
||||||
ProgressBar progressbar{
|
ProgressBar progressbar{
|
||||||
{ 16, 14 * 16, 208, 16 }
|
{16, 14 * 16, 208, 16}};
|
||||||
};
|
|
||||||
|
|
||||||
/*Button button_impro {
|
/*Button button_impro {
|
||||||
{ 64, 184, 112, 40 },
|
{ 64, 184, 112, 40 },
|
||||||
|
@ -93,16 +89,14 @@ private:
|
||||||
TransmitterView tx_view{
|
TransmitterView tx_view{
|
||||||
16 * 16,
|
16 * 16,
|
||||||
10000,
|
10000,
|
||||||
15
|
15};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_tx_progress{
|
MessageHandlerRegistration message_handler_tx_progress{
|
||||||
Message::ID::TXProgress,
|
Message::ID::TXProgress,
|
||||||
[this](const Message* const p) {
|
[this](const Message* const p) {
|
||||||
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
|
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
|
||||||
this->on_tx_progress(message.progress, message.done);
|
this->on_tx_progress(message.progress, message.done);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -40,7 +40,6 @@ void PlaylistView::set_ready() {
|
||||||
ready_signal = true;
|
ready_signal = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PlaylistView::load_file(std::filesystem::path playlist_path) {
|
void PlaylistView::load_file(std::filesystem::path playlist_path) {
|
||||||
File playlist_file;
|
File playlist_file;
|
||||||
|
|
||||||
|
@ -66,7 +65,6 @@ void PlaylistView::set_ready() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PlaylistView::txtline_process(std::string& line) {
|
void PlaylistView::txtline_process(std::string& line) {
|
||||||
playlist_entry new_item;
|
playlist_entry new_item;
|
||||||
rf::Frequency f;
|
rf::Frequency f;
|
||||||
|
@ -139,7 +137,6 @@ void PlaylistView::toggle() {
|
||||||
if (is_active()) {
|
if (is_active()) {
|
||||||
stop(false);
|
stop(false);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
start();
|
start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,8 +175,7 @@ void PlaylistView::start() {
|
||||||
[](uint32_t return_code) {
|
[](uint32_t return_code) {
|
||||||
ReplayThreadDoneMessage message{return_code};
|
ReplayThreadDoneMessage message{return_code};
|
||||||
EventDispatcher::send_message(message);
|
EventDispatcher::send_message(message);
|
||||||
}
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable Bias Tee if selected
|
// Enable Bias Tee if selected
|
||||||
|
@ -187,15 +183,13 @@ void PlaylistView::start() {
|
||||||
|
|
||||||
rf_amp = (transmitter_model.rf_amp()); // recover rf_amp settings applied from ui_transmiter.cpp
|
rf_amp = (transmitter_model.rf_amp()); // recover rf_amp settings applied from ui_transmiter.cpp
|
||||||
|
|
||||||
radio::enable({
|
radio::enable({receiver_model.tuning_frequency(),
|
||||||
receiver_model.tuning_frequency(),
|
|
||||||
sample_rate * 8,
|
sample_rate * 8,
|
||||||
baseband_bandwidth,
|
baseband_bandwidth,
|
||||||
rf::Direction::Transmit,
|
rf::Direction::Transmit,
|
||||||
rf_amp, // previous code line : "receiver_model.rf_amp()," was passing the same rf_amp of all Receiver Apps
|
rf_amp, // previous code line : "receiver_model.rf_amp()," was passing the same rf_amp of all Receiver Apps
|
||||||
static_cast<int8_t>(receiver_model.lna()),
|
static_cast<int8_t>(receiver_model.lna()),
|
||||||
static_cast<int8_t>(receiver_model.vga())
|
static_cast<int8_t>(receiver_model.vga())});
|
||||||
});
|
|
||||||
|
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
@ -232,9 +226,8 @@ void PlaylistView::handle_replay_thread_done(const uint32_t return_code) {
|
||||||
}
|
}
|
||||||
|
|
||||||
PlaylistView::PlaylistView(
|
PlaylistView::PlaylistView(
|
||||||
NavigationView& nav
|
NavigationView& nav)
|
||||||
) : nav_ (nav)
|
: nav_(nav) {
|
||||||
{
|
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_replay);
|
baseband::run_image(portapack::spi_flash::image_tag_replay);
|
||||||
|
|
||||||
add_children({
|
add_children({
|
||||||
|
@ -303,7 +296,8 @@ void PlaylistView::on_target_frequency_changed(rf::Frequency f) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlaylistView::set_target_frequency(const rf::Frequency new_value) {
|
void PlaylistView::set_target_frequency(const rf::Frequency new_value) {
|
||||||
persistent_memory::set_tuned_frequency(new_value);;
|
persistent_memory::set_tuned_frequency(new_value);
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
rf::Frequency PlaylistView::target_frequency() const {
|
rf::Frequency PlaylistView::target_frequency() const {
|
||||||
|
|
|
@ -90,32 +90,27 @@ private:
|
||||||
|
|
||||||
Button button_open{
|
Button button_open{
|
||||||
{0 * 8, 0 * 16, 10 * 8, 2 * 16},
|
{0 * 8, 0 * 16, 10 * 8, 2 * 16},
|
||||||
"Open file"
|
"Open file"};
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
Text text_filename{
|
Text text_filename{
|
||||||
{11 * 8, 0 * 16, 12 * 8, 16},
|
{11 * 8, 0 * 16, 12 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
Text text_sample_rate{
|
Text text_sample_rate{
|
||||||
{24 * 8, 0 * 16, 6 * 8, 16},
|
{24 * 8, 0 * 16, 6 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_duration{
|
Text text_duration{
|
||||||
{11 * 8, 1 * 16, 6 * 8, 16},
|
{11 * 8, 1 * 16, 6 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
ProgressBar progressbar{
|
ProgressBar progressbar{
|
||||||
{ 18 * 8, 1 * 16, 12 * 8, 16 }
|
{18 * 8, 1 * 16, 12 * 8, 16}};
|
||||||
};
|
|
||||||
|
|
||||||
FrequencyField field_frequency{
|
FrequencyField field_frequency{
|
||||||
{0 * 8, 2 * 16},
|
{0 * 8, 2 * 16},
|
||||||
};
|
};
|
||||||
|
|
||||||
TransmitterView2 tx_view { // new handling of NumberField field_rfgain, NumberField field_rfamp
|
TransmitterView2 tx_view{
|
||||||
|
// new handling of NumberField field_rfgain, NumberField field_rfamp
|
||||||
74, 1 * 8, SHORT_UI // x(columns), y (line) position. (Used in Repay / GPS Simul / Play list App)
|
74, 1 * 8, SHORT_UI // x(columns), y (line) position. (Used in Repay / GPS Simul / Play list App)
|
||||||
// 10*8, 2*8, NORMAL_UI // x(columns), y (line) position. (Used in Mic App)
|
// 10*8, 2*8, NORMAL_UI // x(columns), y (line) position. (Used in Mic App)
|
||||||
};
|
};
|
||||||
|
@ -124,14 +119,12 @@ private:
|
||||||
{21 * 8, 2 * 16},
|
{21 * 8, 2 * 16},
|
||||||
4,
|
4,
|
||||||
"Loop",
|
"Loop",
|
||||||
true
|
true};
|
||||||
};
|
|
||||||
ImageButton button_play{
|
ImageButton button_play{
|
||||||
{28 * 8, 2 * 16, 2 * 8, 1 * 16},
|
{28 * 8, 2 * 16, 2 * 8, 1 * 16},
|
||||||
&bitmap_play,
|
&bitmap_play,
|
||||||
Color::green(),
|
Color::green(),
|
||||||
Color::black()
|
Color::black()};
|
||||||
};
|
|
||||||
|
|
||||||
spectrum::WaterfallWidget waterfall{};
|
spectrum::WaterfallWidget waterfall{};
|
||||||
|
|
||||||
|
@ -140,8 +133,7 @@ private:
|
||||||
[this](const Message* const p) {
|
[this](const Message* const p) {
|
||||||
const auto message = *reinterpret_cast<const ReplayThreadDoneMessage*>(p);
|
const auto message = *reinterpret_cast<const ReplayThreadDoneMessage*>(p);
|
||||||
this->handle_replay_thread_done(message.return_code);
|
this->handle_replay_thread_done(message.return_code);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_fifo_signal{
|
MessageHandlerRegistration message_handler_fifo_signal{
|
||||||
Message::ID::RequestSignal,
|
Message::ID::RequestSignal,
|
||||||
|
@ -150,16 +142,14 @@ private:
|
||||||
if (message->signal == RequestSignalMessage::Signal::FillRequest) {
|
if (message->signal == RequestSignalMessage::Signal::FillRequest) {
|
||||||
this->set_ready();
|
this->set_ready();
|
||||||
}
|
}
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_tx_progress{
|
MessageHandlerRegistration message_handler_tx_progress{
|
||||||
Message::ID::TXProgress,
|
Message::ID::TXProgress,
|
||||||
[this](const Message* const p) {
|
[this](const Message* const p) {
|
||||||
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
|
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
|
||||||
this->on_tx_progress(message.progress);
|
this->on_tx_progress(message.progress);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -113,8 +113,7 @@ bool POCSAGTXView::start_tx() {
|
||||||
codewords.size() * 32,
|
codewords.size() * 32,
|
||||||
2280000 / bitrate,
|
2280000 / bitrate,
|
||||||
4500,
|
4500,
|
||||||
64
|
64);
|
||||||
);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -129,13 +128,11 @@ void POCSAGTXView::on_set_text(NavigationView& nav) {
|
||||||
}
|
}
|
||||||
|
|
||||||
POCSAGTXView::POCSAGTXView(
|
POCSAGTXView::POCSAGTXView(
|
||||||
NavigationView& nav
|
NavigationView& nav)
|
||||||
) : nav_ (nav)
|
: nav_(nav) {
|
||||||
{
|
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_fsktx);
|
baseband::run_image(portapack::spi_flash::image_tag_fsktx);
|
||||||
|
|
||||||
add_children({
|
add_children({&labels,
|
||||||
&labels,
|
|
||||||
&options_bitrate,
|
&options_bitrate,
|
||||||
&field_address,
|
&field_address,
|
||||||
&options_type,
|
&options_type,
|
||||||
|
@ -144,8 +141,7 @@ POCSAGTXView::POCSAGTXView(
|
||||||
&text_message,
|
&text_message,
|
||||||
&button_message,
|
&button_message,
|
||||||
&progressbar,
|
&progressbar,
|
||||||
&tx_view
|
&tx_view});
|
||||||
});
|
|
||||||
|
|
||||||
// load app settings
|
// load app settings
|
||||||
auto rc = settings.load("tx_pocsag", &app_settings);
|
auto rc = settings.load("tx_pocsag", &app_settings);
|
||||||
|
@ -191,7 +187,6 @@ POCSAGTXView::POCSAGTXView(
|
||||||
tx_view.set_transmitting(false);
|
tx_view.set_transmitting(false);
|
||||||
transmitter_model.disable();
|
transmitter_model.disable();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -60,8 +60,10 @@ private:
|
||||||
|
|
||||||
BCHCode BCH_code{
|
BCHCode BCH_code{
|
||||||
{1, 0, 1, 0, 0, 1},
|
{1, 0, 1, 0, 0, 1},
|
||||||
5, 31, 21, 2
|
5,
|
||||||
};
|
31,
|
||||||
|
21,
|
||||||
|
2};
|
||||||
|
|
||||||
// app save settings
|
// app save settings
|
||||||
std::app_settings settings{};
|
std::app_settings settings{};
|
||||||
|
@ -77,45 +79,34 @@ private:
|
||||||
{{6 * 8, 8 * 8}, "Type:", Color::light_grey()},
|
{{6 * 8, 8 * 8}, "Type:", Color::light_grey()},
|
||||||
{{2 * 8, 10 * 8}, "Function:", Color::light_grey()},
|
{{2 * 8, 10 * 8}, "Function:", Color::light_grey()},
|
||||||
{{5 * 8, 12 * 8}, "Phase:", Color::light_grey()},
|
{{5 * 8, 12 * 8}, "Phase:", Color::light_grey()},
|
||||||
{ { 0 * 8, 14 * 8 }, "Message:", Color::light_grey() }
|
{{0 * 8, 14 * 8}, "Message:", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField options_bitrate{
|
OptionsField options_bitrate{
|
||||||
{11 * 8, 4 * 8},
|
{11 * 8, 4 * 8},
|
||||||
8,
|
8,
|
||||||
{
|
{{"512 bps ", 0},
|
||||||
{ "512 bps ", 0 },
|
|
||||||
{"1200 bps", 1},
|
{"1200 bps", 1},
|
||||||
{ "2400 bps", 2 }
|
{"2400 bps", 2}}};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
SymField field_address{
|
SymField field_address{
|
||||||
{11 * 8, 6 * 8},
|
{11 * 8, 6 * 8},
|
||||||
7,
|
7,
|
||||||
SymField::SYMFIELD_DEC
|
SymField::SYMFIELD_DEC};
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField options_type{
|
OptionsField options_type{
|
||||||
{11 * 8, 8 * 8},
|
{11 * 8, 8 * 8},
|
||||||
12,
|
12,
|
||||||
{
|
{{"Address only", MessageType::ADDRESS_ONLY},
|
||||||
{ "Address only", MessageType::ADDRESS_ONLY },
|
|
||||||
{"Numeric only", MessageType::NUMERIC_ONLY},
|
{"Numeric only", MessageType::NUMERIC_ONLY},
|
||||||
{ "Alphanumeric", MessageType::ALPHANUMERIC }
|
{"Alphanumeric", MessageType::ALPHANUMERIC}}};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField options_function{
|
OptionsField options_function{
|
||||||
{11 * 8, 10 * 8},
|
{11 * 8, 10 * 8},
|
||||||
1,
|
1,
|
||||||
{
|
{{"A", 0},
|
||||||
{ "A", 0 },
|
|
||||||
{"B", 1},
|
{"B", 1},
|
||||||
{"C", 2},
|
{"C", 2},
|
||||||
{ "D", 3 }
|
{"D", 3}}};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField options_phase{
|
OptionsField options_phase{
|
||||||
{11 * 8, 12 * 8},
|
{11 * 8, 12 * 8},
|
||||||
|
@ -123,36 +114,30 @@ private:
|
||||||
{
|
{
|
||||||
{"P", 0},
|
{"P", 0},
|
||||||
{"N", 1},
|
{"N", 1},
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_message{
|
Text text_message{
|
||||||
{0 * 8, 16 * 8, 16 * 8, 16},
|
{0 * 8, 16 * 8, 16 * 8, 16},
|
||||||
""
|
""};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_message{
|
Button button_message{
|
||||||
{0 * 8, 18 * 8, 14 * 8, 32},
|
{0 * 8, 18 * 8, 14 * 8, 32},
|
||||||
"Set message"
|
"Set message"};
|
||||||
};
|
|
||||||
|
|
||||||
ProgressBar progressbar{
|
ProgressBar progressbar{
|
||||||
{ 16, 200, 208, 16 }
|
{16, 200, 208, 16}};
|
||||||
};
|
|
||||||
|
|
||||||
TransmitterView tx_view{
|
TransmitterView tx_view{
|
||||||
16 * 16,
|
16 * 16,
|
||||||
10000,
|
10000,
|
||||||
9
|
9};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_tx_progress{
|
MessageHandlerRegistration message_handler_tx_progress{
|
||||||
Message::ID::TXProgress,
|
Message::ID::TXProgress,
|
||||||
[this](const Message* const p) {
|
[this](const Message* const p) {
|
||||||
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
|
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
|
||||||
this->on_tx_progress(message.progress, message.done);
|
this->on_tx_progress(message.progress, message.done);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -36,19 +36,16 @@ namespace ui {
|
||||||
|
|
||||||
RDSPSNView::RDSPSNView(
|
RDSPSNView::RDSPSNView(
|
||||||
NavigationView& nav,
|
NavigationView& nav,
|
||||||
Rect parent_rect
|
Rect parent_rect)
|
||||||
) : OptionTabView(parent_rect)
|
: OptionTabView(parent_rect) {
|
||||||
{
|
|
||||||
set_type("PSN");
|
set_type("PSN");
|
||||||
|
|
||||||
add_children({
|
add_children({&labels,
|
||||||
&labels,
|
|
||||||
&text_psn,
|
&text_psn,
|
||||||
&button_set,
|
&button_set,
|
||||||
&check_mono_stereo,
|
&check_mono_stereo,
|
||||||
&check_TA,
|
&check_TA,
|
||||||
&check_MS
|
&check_MS});
|
||||||
});
|
|
||||||
|
|
||||||
set_enabled(true);
|
set_enabled(true);
|
||||||
|
|
||||||
|
@ -71,23 +68,19 @@ RDSPSNView::RDSPSNView(
|
||||||
8,
|
8,
|
||||||
[this](std::string& s) {
|
[this](std::string& s) {
|
||||||
text_psn.set(s);
|
text_psn.set(s);
|
||||||
}
|
});
|
||||||
);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
RDSRadioTextView::RDSRadioTextView(
|
RDSRadioTextView::RDSRadioTextView(
|
||||||
NavigationView& nav,
|
NavigationView& nav,
|
||||||
Rect parent_rect
|
Rect parent_rect)
|
||||||
) : OptionTabView(parent_rect)
|
: OptionTabView(parent_rect) {
|
||||||
{
|
|
||||||
set_type("Radiotext");
|
set_type("Radiotext");
|
||||||
|
|
||||||
add_children({
|
add_children({&labels,
|
||||||
&labels,
|
|
||||||
&button_set,
|
&button_set,
|
||||||
&text_radiotext
|
&text_radiotext});
|
||||||
});
|
|
||||||
|
|
||||||
button_set.on_select = [this, &nav](Button&) {
|
button_set.on_select = [this, &nav](Button&) {
|
||||||
text_prompt(
|
text_prompt(
|
||||||
|
@ -96,37 +89,29 @@ RDSRadioTextView::RDSRadioTextView(
|
||||||
28,
|
28,
|
||||||
[this](std::string& s) {
|
[this](std::string& s) {
|
||||||
text_radiotext.set(s);
|
text_radiotext.set(s);
|
||||||
}
|
});
|
||||||
);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
RDSDateTimeView::RDSDateTimeView(
|
RDSDateTimeView::RDSDateTimeView(
|
||||||
Rect parent_rect
|
Rect parent_rect)
|
||||||
) : OptionTabView(parent_rect)
|
: OptionTabView(parent_rect) {
|
||||||
{
|
|
||||||
set_type("date & time");
|
set_type("date & time");
|
||||||
|
|
||||||
add_children({
|
add_children({&labels});
|
||||||
&labels
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RDSAudioView::RDSAudioView(
|
RDSAudioView::RDSAudioView(
|
||||||
Rect parent_rect
|
Rect parent_rect)
|
||||||
) : OptionTabView(parent_rect)
|
: OptionTabView(parent_rect) {
|
||||||
{
|
|
||||||
set_type("audio");
|
set_type("audio");
|
||||||
|
|
||||||
add_children({
|
add_children({&labels});
|
||||||
&labels
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RDSThread::RDSThread(
|
RDSThread::RDSThread(
|
||||||
std::vector<RDSGroup>** frames
|
std::vector<RDSGroup>** frames)
|
||||||
) : frames_ { std::move(frames) }
|
: frames_{std::move(frames)} {
|
||||||
{
|
|
||||||
thread = chThdCreateFromHeap(NULL, 1024, NORMALPRIO + 10, RDSThread::static_fn, this);
|
thread = chThdCreateFromHeap(NULL, 1024, NORMALPRIO + 10, RDSThread::static_fn, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +136,6 @@ void RDSThread::run() {
|
||||||
uint32_t frame_index = 0;
|
uint32_t frame_index = 0;
|
||||||
|
|
||||||
while (!chThdShouldTerminate()) {
|
while (!chThdShouldTerminate()) {
|
||||||
|
|
||||||
do {
|
do {
|
||||||
frame_ptr = frames_[frame_index];
|
frame_ptr = frames_[frame_index];
|
||||||
|
|
||||||
|
@ -217,9 +201,8 @@ void RDSView::start_tx() {
|
||||||
}
|
}
|
||||||
|
|
||||||
RDSView::RDSView(
|
RDSView::RDSView(
|
||||||
NavigationView& nav
|
NavigationView& nav)
|
||||||
) : nav_ { nav }
|
: nav_{nav} {
|
||||||
{
|
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_rds);
|
baseband::run_image(portapack::spi_flash::image_tag_rds);
|
||||||
|
|
||||||
add_children({
|
add_children({
|
||||||
|
|
|
@ -43,33 +43,27 @@ public:
|
||||||
private:
|
private:
|
||||||
Labels labels{
|
Labels labels{
|
||||||
{{1 * 8, 3 * 8}, "Program Service Name", Color::light_grey()},
|
{{1 * 8, 3 * 8}, "Program Service Name", Color::light_grey()},
|
||||||
{ { 2 * 8, 7 * 8 }, "PSN:", Color::light_grey() }
|
{{2 * 8, 7 * 8}, "PSN:", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_set{
|
Button button_set{
|
||||||
{18 * 8, 3 * 16, 80, 32},
|
{18 * 8, 3 * 16, 80, 32},
|
||||||
"Set"
|
"Set"};
|
||||||
};
|
|
||||||
Text text_psn{
|
Text text_psn{
|
||||||
{6 * 8, 3 * 16 + 8, 8 * 8, 16},
|
{6 * 8, 3 * 16 + 8, 8 * 8, 16},
|
||||||
""
|
""};
|
||||||
};
|
|
||||||
|
|
||||||
Checkbox check_mono_stereo{
|
Checkbox check_mono_stereo{
|
||||||
{2 * 8, 12 * 8},
|
{2 * 8, 12 * 8},
|
||||||
6,
|
6,
|
||||||
"Stereo"
|
"Stereo"};
|
||||||
};
|
|
||||||
Checkbox check_MS{
|
Checkbox check_MS{
|
||||||
{14 * 8, 12 * 8},
|
{14 * 8, 12 * 8},
|
||||||
5,
|
5,
|
||||||
"Music"
|
"Music"};
|
||||||
};
|
|
||||||
Checkbox check_TA{
|
Checkbox check_TA{
|
||||||
{2 * 8, 16 * 8},
|
{2 * 8, 16 * 8},
|
||||||
20,
|
20,
|
||||||
"Traffic announcement"
|
"Traffic announcement"};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class RDSRadioTextView : public OptionTabView {
|
class RDSRadioTextView : public OptionTabView {
|
||||||
|
@ -77,20 +71,18 @@ public:
|
||||||
RDSRadioTextView(NavigationView& nav, Rect parent_rect);
|
RDSRadioTextView(NavigationView& nav, Rect parent_rect);
|
||||||
|
|
||||||
std::string radiotext{"Radiotext test ABCD1234"};
|
std::string radiotext{"Radiotext test ABCD1234"};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Labels labels{
|
Labels labels{
|
||||||
{{2 * 8, 3 * 8}, "Radiotext", Color::light_grey()},
|
{{2 * 8, 3 * 8}, "Radiotext", Color::light_grey()},
|
||||||
{ { 1 * 8, 6 * 8 }, "Text:", Color::light_grey() }
|
{{1 * 8, 6 * 8}, "Text:", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_radiotext{
|
Text text_radiotext{
|
||||||
{1 * 8, 4 * 16, 28 * 8, 16},
|
{1 * 8, 4 * 16, 28 * 8, 16},
|
||||||
"-"
|
"-"};
|
||||||
};
|
|
||||||
Button button_set{
|
Button button_set{
|
||||||
{88, 6 * 16, 64, 32},
|
{88, 6 * 16, 64, 32},
|
||||||
"Set"
|
"Set"};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class RDSDateTimeView : public OptionTabView {
|
class RDSDateTimeView : public OptionTabView {
|
||||||
|
@ -99,8 +91,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Labels labels{
|
Labels labels{
|
||||||
{ { 44, 5 * 16 }, "Not yet implemented", Color::red() }
|
{{44, 5 * 16}, "Not yet implemented", Color::red()}};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class RDSAudioView : public OptionTabView {
|
class RDSAudioView : public OptionTabView {
|
||||||
|
@ -109,8 +100,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Labels labels{
|
Labels labels{
|
||||||
{ { 44, 5 * 16 }, "Not yet implemented", Color::red() }
|
{{44, 5 * 16}, "Not yet implemented", Color::red()}};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class RDSThread {
|
class RDSThread {
|
||||||
|
@ -154,7 +144,6 @@ private:
|
||||||
std::app_settings settings{};
|
std::app_settings settings{};
|
||||||
std::app_settings::AppSettings app_settings{};
|
std::app_settings::AppSettings app_settings{};
|
||||||
|
|
||||||
|
|
||||||
std::vector<RDSGroup> frame_psn{};
|
std::vector<RDSGroup> frame_psn{};
|
||||||
std::vector<RDSGroup> frame_radiotext{};
|
std::vector<RDSGroup> frame_radiotext{};
|
||||||
std::vector<RDSGroup> frame_datetime{};
|
std::vector<RDSGroup> frame_datetime{};
|
||||||
|
@ -177,8 +166,7 @@ private:
|
||||||
{"Name", Color::cyan(), &view_PSN},
|
{"Name", Color::cyan(), &view_PSN},
|
||||||
{"Text", Color::green(), &view_radiotext},
|
{"Text", Color::green(), &view_radiotext},
|
||||||
{"Time", Color::yellow(), &view_datetime},
|
{"Time", Color::yellow(), &view_datetime},
|
||||||
{ "Audio", Color::orange(), &view_audio }
|
{"Audio", Color::orange(), &view_audio}};
|
||||||
};
|
|
||||||
|
|
||||||
Labels labels{
|
Labels labels{
|
||||||
{{0 * 8, 28}, "Program type:", Color::light_grey()},
|
{{0 * 8, 28}, "Program type:", Color::light_grey()},
|
||||||
|
@ -190,8 +178,7 @@ private:
|
||||||
OptionsField options_pty{
|
OptionsField options_pty{
|
||||||
{13 * 8, 28},
|
{13 * 8, 28},
|
||||||
8,
|
8,
|
||||||
{
|
{{"None", 0},
|
||||||
{ "None", 0 },
|
|
||||||
{"News", 1},
|
{"News", 1},
|
||||||
{"Affairs", 2},
|
{"Affairs", 2},
|
||||||
{"Info", 3},
|
{"Info", 3},
|
||||||
|
@ -222,9 +209,7 @@ private:
|
||||||
{"Folk", 28},
|
{"Folk", 28},
|
||||||
{"Docs", 29},
|
{"Docs", 29},
|
||||||
{"AlarmTst", 30},
|
{"AlarmTst", 30},
|
||||||
{ "Alarm", 31 }
|
{"Alarm", 31}}};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*OptionsField options_countrycode {
|
/*OptionsField options_countrycode {
|
||||||
{ 17 * 8, 16 + 8 },
|
{ 17 * 8, 16 + 8 },
|
||||||
|
@ -298,8 +283,7 @@ private:
|
||||||
SymField sym_pi_code{
|
SymField sym_pi_code{
|
||||||
{13 * 8, 28 + 16},
|
{13 * 8, 28 + 16},
|
||||||
4,
|
4,
|
||||||
SymField::SYMFIELD_HEX
|
SymField::SYMFIELD_HEX};
|
||||||
};
|
|
||||||
|
|
||||||
/*OptionsField options_coverage {
|
/*OptionsField options_coverage {
|
||||||
{ 17 * 8, 32 + 8 },
|
{ 17 * 8, 32 + 8 },
|
||||||
|
@ -327,14 +311,12 @@ private:
|
||||||
Checkbox check_TP{
|
Checkbox check_TP{
|
||||||
{23 * 8, 4 * 8},
|
{23 * 8, 4 * 8},
|
||||||
2,
|
2,
|
||||||
"TP"
|
"TP"};
|
||||||
};
|
|
||||||
|
|
||||||
TransmitterView tx_view{
|
TransmitterView tx_view{
|
||||||
16 * 16,
|
16 * 16,
|
||||||
50000,
|
50000,
|
||||||
9
|
9};
|
||||||
};
|
|
||||||
|
|
||||||
std::unique_ptr<RDSThread> tx_thread{};
|
std::unique_ptr<RDSThread> tx_thread{};
|
||||||
};
|
};
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -49,37 +49,43 @@ namespace ui {
|
||||||
|
|
||||||
void focus() override;
|
void focus() override;
|
||||||
|
|
||||||
const Style style_grey { // recon
|
const Style style_grey{
|
||||||
|
// recon
|
||||||
.font = font::fixed_8x16,
|
.font = font::fixed_8x16,
|
||||||
.background = Color::black(),
|
.background = Color::black(),
|
||||||
.foreground = Color::grey(),
|
.foreground = Color::grey(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const Style style_white { // recon
|
const Style style_white{
|
||||||
|
// recon
|
||||||
.font = font::fixed_8x16,
|
.font = font::fixed_8x16,
|
||||||
.background = Color::black(),
|
.background = Color::black(),
|
||||||
.foreground = Color::white(),
|
.foreground = Color::white(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const Style style_yellow { //found signal
|
const Style style_yellow{
|
||||||
|
// found signal
|
||||||
.font = font::fixed_8x16,
|
.font = font::fixed_8x16,
|
||||||
.background = Color::black(),
|
.background = Color::black(),
|
||||||
.foreground = Color::yellow(),
|
.foreground = Color::yellow(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const Style style_green { //Found signal
|
const Style style_green{
|
||||||
|
// Found signal
|
||||||
.font = font::fixed_8x16,
|
.font = font::fixed_8x16,
|
||||||
.background = Color::black(),
|
.background = Color::black(),
|
||||||
.foreground = Color::green(),
|
.foreground = Color::green(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const Style style_red { //erasing freq
|
const Style style_red{
|
||||||
|
// erasing freq
|
||||||
.font = font::fixed_8x16,
|
.font = font::fixed_8x16,
|
||||||
.background = Color::black(),
|
.background = Color::black(),
|
||||||
.foreground = Color::red(),
|
.foreground = Color::red(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const Style style_blue { // quick recon, wait == 0
|
const Style style_blue{
|
||||||
|
// quick recon, wait == 0
|
||||||
.font = font::fixed_8x16,
|
.font = font::fixed_8x16,
|
||||||
.background = Color::black(),
|
.background = Color::black(),
|
||||||
.foreground = Color::blue(),
|
.foreground = Color::blue(),
|
||||||
|
@ -166,8 +172,7 @@ namespace ui {
|
||||||
int64_t last_freq = 0;
|
int64_t last_freq = 0;
|
||||||
std::string freq_file_path = {};
|
std::string freq_file_path = {};
|
||||||
|
|
||||||
Labels labels
|
Labels labels{
|
||||||
{
|
|
||||||
{{0 * 8, 0 * 16}, "LNA: VGA: AMP: VOL: ", Color::light_grey()},
|
{{0 * 8, 0 * 16}, "LNA: VGA: AMP: VOL: ", Color::light_grey()},
|
||||||
{{0 * 8, 1 * 16}, "BW: SQ: W,L: , ", Color::light_grey()},
|
{{0 * 8, 1 * 16}, "BW: SQ: W,L: , ", Color::light_grey()},
|
||||||
{{3 * 8, 10 * 16}, "START END MANUAL", Color::light_grey()},
|
{{3 * 8, 10 * 16}, "START END MANUAL", Color::light_grey()},
|
||||||
|
@ -176,16 +181,13 @@ namespace ui {
|
||||||
};
|
};
|
||||||
|
|
||||||
LNAGainField field_lna{
|
LNAGainField field_lna{
|
||||||
{ 4 * 8, 0 * 16 }
|
{4 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
VGAGainField field_vga{
|
VGAGainField field_vga{
|
||||||
{ 11 * 8, 0 * 16 }
|
{11 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
RFAmpField field_rf_amp{
|
RFAmpField field_rf_amp{
|
||||||
{ 18 * 8, 0 * 16 }
|
{18 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_volume{
|
NumberField field_volume{
|
||||||
{24 * 8, 0 * 16},
|
{24 * 8, 0 * 16},
|
||||||
|
@ -198,8 +200,7 @@ namespace ui {
|
||||||
OptionsField field_bw{
|
OptionsField field_bw{
|
||||||
{3 * 8, 1 * 16},
|
{3 * 8, 1 * 16},
|
||||||
6,
|
6,
|
||||||
{ }
|
{}};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_squelch{
|
NumberField field_squelch{
|
||||||
{12 * 8, 1 * 16},
|
{12 * 8, 1 * 16},
|
||||||
|
@ -231,8 +232,7 @@ namespace ui {
|
||||||
|
|
||||||
ButtonWithEncoder text_cycle{
|
ButtonWithEncoder text_cycle{
|
||||||
{0, 3 * 16, 4 * 8, 16},
|
{0, 3 * 16, 4 * 8, 16},
|
||||||
""
|
""};
|
||||||
};
|
|
||||||
|
|
||||||
Text text_max{
|
Text text_max{
|
||||||
{4 * 8, 3 * 16, SCREEN_W - 7 * 8 - 4 * 8, 16},
|
{4 * 8, 3 * 16, SCREEN_W - 7 * 8 - 4 * 8, 16},
|
||||||
|
@ -242,125 +242,107 @@ namespace ui {
|
||||||
{0, 4 * 16, SCREEN_W, 16},
|
{0, 4 * 16, SCREEN_W, 16},
|
||||||
};
|
};
|
||||||
|
|
||||||
Text big_display { //Show frequency in text mode
|
Text big_display{
|
||||||
|
// Show frequency in text mode
|
||||||
{0, 5 * 16, 23 * 8, 16},
|
{0, 5 * 16, 23 * 8, 16},
|
||||||
};
|
};
|
||||||
|
|
||||||
Text freq_stats { //Show frequency stats in text mode
|
Text freq_stats{
|
||||||
|
// Show frequency stats in text mode
|
||||||
{0, 6 * 16, 23 * 8, 16},
|
{0, 6 * 16, 23 * 8, 16},
|
||||||
};
|
};
|
||||||
|
|
||||||
// TIMER: 9999
|
// TIMER: 9999
|
||||||
Text text_timer { //Show frequency stats in text mode
|
Text text_timer{
|
||||||
|
// Show frequency stats in text mode
|
||||||
{0, 7 * 16, 11 * 8, 16},
|
{0, 7 * 16, 11 * 8, 16},
|
||||||
};
|
};
|
||||||
|
|
||||||
// T: Senn. 32.000k
|
// T: Senn. 32.000k
|
||||||
Text text_ctcss{
|
Text text_ctcss{
|
||||||
{12 * 8 + 4, 7 * 16, 14 * 8, 1 * 8},
|
{12 * 8 + 4, 7 * 16, 14 * 8, 1 * 8},
|
||||||
""
|
""};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_recon_setup{
|
Button button_recon_setup{
|
||||||
{SCREEN_W - 7 * 8, 2 * 16, 7 * 8, 28},
|
{SCREEN_W - 7 * 8, 2 * 16, 7 * 8, 28},
|
||||||
"CONFIG"
|
"CONFIG"};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_looking_glass{
|
Button button_looking_glass{
|
||||||
{SCREEN_W - 7 * 8, 5 * 16, 7 * 8, 28},
|
{SCREEN_W - 7 * 8, 5 * 16, 7 * 8, 28},
|
||||||
"GLASS"
|
"GLASS"};
|
||||||
};
|
|
||||||
|
|
||||||
// Button can be RECON or SCANNER
|
// Button can be RECON or SCANNER
|
||||||
Button button_scanner_mode{
|
Button button_scanner_mode{
|
||||||
{SCREEN_W - 7 * 8, 8 * 16, 7 * 8, 28},
|
{SCREEN_W - 7 * 8, 8 * 16, 7 * 8, 28},
|
||||||
"RECON"
|
"RECON"};
|
||||||
};
|
|
||||||
|
|
||||||
Text file_name { //show file used
|
Text file_name{
|
||||||
|
// show file used
|
||||||
{0, 8 * 16 + 6, SCREEN_W - 7 * 8, 16},
|
{0, 8 * 16 + 6, SCREEN_W - 7 * 8, 16},
|
||||||
};
|
};
|
||||||
|
|
||||||
ButtonWithEncoder button_manual_start{
|
ButtonWithEncoder button_manual_start{
|
||||||
{0 * 8, 11 * 16, 11 * 8, 28},
|
{0 * 8, 11 * 16, 11 * 8, 28},
|
||||||
""
|
""};
|
||||||
};
|
|
||||||
|
|
||||||
ButtonWithEncoder button_manual_end{
|
ButtonWithEncoder button_manual_end{
|
||||||
{12 * 8 - 6, 11 * 16, 11 * 8, 28},
|
{12 * 8 - 6, 11 * 16, 11 * 8, 28},
|
||||||
""
|
""};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_manual_recon{
|
Button button_manual_recon{
|
||||||
{23 * 8 - 3, 11 * 16, 7 * 8, 28},
|
{23 * 8 - 3, 11 * 16, 7 * 8, 28},
|
||||||
"SEARCH"
|
"SEARCH"};
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField field_mode{
|
OptionsField field_mode{
|
||||||
{5 * 8, (26 * 8) + 4},
|
{5 * 8, (26 * 8) + 4},
|
||||||
6,
|
6,
|
||||||
{
|
{}};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField step_mode{
|
OptionsField step_mode{
|
||||||
{17 * 8, (26 * 8) + 4},
|
{17 * 8, (26 * 8) + 4},
|
||||||
12,
|
12,
|
||||||
{
|
{}};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ButtonWithEncoder button_pause{
|
ButtonWithEncoder button_pause{
|
||||||
{0, (15 * 16) - 4, 72, 28},
|
{0, (15 * 16) - 4, 72, 28},
|
||||||
"PAUSE"
|
"PAUSE"};
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
Button button_audio_app{
|
Button button_audio_app{
|
||||||
{84, (15 * 16) - 4, 72, 28},
|
{84, (15 * 16) - 4, 72, 28},
|
||||||
"AUDIO"
|
"AUDIO"};
|
||||||
};
|
|
||||||
|
|
||||||
ButtonWithEncoder button_add{
|
ButtonWithEncoder button_add{
|
||||||
{168, (15 * 16) - 4, 72, 28},
|
{168, (15 * 16) - 4, 72, 28},
|
||||||
"<STORE>"
|
"<STORE>"};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_dir{
|
Button button_dir{
|
||||||
{0, (35 * 8) - 4, 34, 28},
|
{0, (35 * 8) - 4, 34, 28},
|
||||||
"FW>"
|
"FW>"};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_restart{
|
Button button_restart{
|
||||||
{38, (35 * 8) - 4, 34, 28},
|
{38, (35 * 8) - 4, 34, 28},
|
||||||
"RST"
|
"RST"};
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
Button button_mic_app{
|
Button button_mic_app{
|
||||||
{84, (35 * 8) - 4, 72, 28},
|
{84, (35 * 8) - 4, 72, 28},
|
||||||
"MIC TX"
|
"MIC TX"};
|
||||||
};
|
|
||||||
|
|
||||||
ButtonWithEncoder button_remove{
|
ButtonWithEncoder button_remove{
|
||||||
{168, (35 * 8) - 4, 72, 28},
|
{168, (35 * 8) - 4, 72, 28},
|
||||||
"<REMOVE>"
|
"<REMOVE>"};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_coded_squelch{
|
MessageHandlerRegistration message_handler_coded_squelch{
|
||||||
Message::ID::CodedSquelch,
|
Message::ID::CodedSquelch,
|
||||||
[this](const Message* const p) {
|
[this](const Message* const p) {
|
||||||
const auto message = *reinterpret_cast<const CodedSquelchMessage*>(p);
|
const auto message = *reinterpret_cast<const CodedSquelchMessage*>(p);
|
||||||
this->handle_coded_squelch(message.value);
|
this->handle_coded_squelch(message.value);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_stats{
|
MessageHandlerRegistration message_handler_stats{
|
||||||
Message::ID::ChannelStatistics,
|
Message::ID::ChannelStatistics,
|
||||||
[this](const Message* const p) {
|
[this](const Message* const p) {
|
||||||
this->on_statistics_update(static_cast<const ChannelStatisticsMessage*>(p)->statistics);
|
this->on_statistics_update(static_cast<const ChannelStatisticsMessage*>(p)->statistics);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
// app save settings
|
// app save settings
|
||||||
std::app_settings settings{};
|
std::app_settings settings{};
|
||||||
std::app_settings::AppSettings app_settings{};
|
std::app_settings::AppSettings app_settings{};
|
||||||
|
|
|
@ -34,19 +34,17 @@ using namespace portapack;
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
ReconSetupViewMain::ReconSetupViewMain( NavigationView &nav , Rect parent_rect , std::string input_file , std::string output_file ) : View( parent_rect ) , _input_file { input_file } , _output_file { output_file }
|
ReconSetupViewMain::ReconSetupViewMain(NavigationView& nav, Rect parent_rect, std::string input_file, std::string output_file)
|
||||||
{
|
: View(parent_rect), _input_file{input_file}, _output_file{output_file} {
|
||||||
hidden(true);
|
hidden(true);
|
||||||
add_children({
|
add_children({&button_load_freqs,
|
||||||
&button_load_freqs,
|
|
||||||
&text_input_file,
|
&text_input_file,
|
||||||
&button_save_freqs,
|
&button_save_freqs,
|
||||||
&button_output_file,
|
&button_output_file,
|
||||||
&checkbox_autosave_freqs,
|
&checkbox_autosave_freqs,
|
||||||
&checkbox_autostart_recon,
|
&checkbox_autostart_recon,
|
||||||
&checkbox_continuous,
|
&checkbox_continuous,
|
||||||
&checkbox_clear_output
|
&checkbox_clear_output});
|
||||||
});
|
|
||||||
|
|
||||||
checkbox_autosave_freqs.set_value(persistent_memory::recon_autosave_freqs());
|
checkbox_autosave_freqs.set_value(persistent_memory::recon_autosave_freqs());
|
||||||
checkbox_autostart_recon.set_value(persistent_memory::recon_autostart_recon());
|
checkbox_autostart_recon.set_value(persistent_memory::recon_autostart_recon());
|
||||||
|
@ -116,8 +114,8 @@ namespace ui {
|
||||||
button_load_freqs.focus();
|
button_load_freqs.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReconSetupViewMore::ReconSetupViewMore( NavigationView &nav , Rect parent_rect , uint32_t recon_lock_duration , uint32_t recon_lock_nb_match , uint32_t recon_match_mode ) : View( parent_rect ), _recon_lock_duration { recon_lock_duration } , _recon_lock_nb_match { recon_lock_nb_match } , _recon_match_mode { recon_match_mode }
|
ReconSetupViewMore::ReconSetupViewMore(NavigationView& nav, Rect parent_rect, uint32_t recon_lock_duration, uint32_t recon_lock_nb_match, uint32_t recon_match_mode)
|
||||||
{
|
: View(parent_rect), _recon_lock_duration{recon_lock_duration}, _recon_lock_nb_match{recon_lock_nb_match}, _recon_match_mode{recon_match_mode} {
|
||||||
(void)nav;
|
(void)nav;
|
||||||
hidden(true);
|
hidden(true);
|
||||||
|
|
||||||
|
@ -151,14 +149,17 @@ namespace ui {
|
||||||
}
|
}
|
||||||
|
|
||||||
ReconSetupView::ReconSetupView(
|
ReconSetupView::ReconSetupView(
|
||||||
NavigationView& nav , std::string _input_file , std::string _output_file , uint32_t _recon_lock_duration , uint32_t _recon_lock_nb_match , uint32_t _recon_match_mode ) : nav_ { nav } , input_file { _input_file } , output_file { _output_file } , recon_lock_duration { _recon_lock_duration } , recon_lock_nb_match { _recon_lock_nb_match } , recon_match_mode { _recon_match_mode }
|
NavigationView& nav,
|
||||||
{
|
std::string _input_file,
|
||||||
add_children({
|
std::string _output_file,
|
||||||
&tab_view,
|
uint32_t _recon_lock_duration,
|
||||||
|
uint32_t _recon_lock_nb_match,
|
||||||
|
uint32_t _recon_match_mode)
|
||||||
|
: nav_{nav}, input_file{_input_file}, output_file{_output_file}, recon_lock_duration{_recon_lock_duration}, recon_lock_nb_match{_recon_lock_nb_match}, recon_match_mode{_recon_match_mode} {
|
||||||
|
add_children({&tab_view,
|
||||||
&viewMain,
|
&viewMain,
|
||||||
&viewMore,
|
&viewMore,
|
||||||
&button_save
|
&button_save});
|
||||||
});
|
|
||||||
|
|
||||||
button_save.on_select = [this, &nav](Button&) {
|
button_save.on_select = [this, &nav](Button&) {
|
||||||
viewMain.Save(input_file, output_file);
|
viewMain.Save(input_file, output_file);
|
||||||
|
|
|
@ -75,44 +75,36 @@ namespace ui {
|
||||||
|
|
||||||
Button button_load_freqs{
|
Button button_load_freqs{
|
||||||
{1 * 8, 12, 18 * 8, 22},
|
{1 * 8, 12, 18 * 8, 22},
|
||||||
"select input file"
|
"select input file"};
|
||||||
};
|
|
||||||
Text text_input_file{
|
Text text_input_file{
|
||||||
{1 * 8, 4 + 2 * 16, 18 * 8, 22},
|
{1 * 8, 4 + 2 * 16, 18 * 8, 22},
|
||||||
"RECON"
|
"RECON"};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_save_freqs{
|
Button button_save_freqs{
|
||||||
{1 * 8, 4 * 16 - 8, 18 * 8, 22},
|
{1 * 8, 4 * 16 - 8, 18 * 8, 22},
|
||||||
"select output file"
|
"select output file"};
|
||||||
};
|
|
||||||
Button button_output_file{
|
Button button_output_file{
|
||||||
{1 * 8, 5 * 16 - 2, 18 * 8, 22},
|
{1 * 8, 5 * 16 - 2, 18 * 8, 22},
|
||||||
"RECON_RESULTS"
|
"RECON_RESULTS"};
|
||||||
};
|
|
||||||
|
|
||||||
Checkbox checkbox_autosave_freqs{
|
Checkbox checkbox_autosave_freqs{
|
||||||
{1 * 8, 7 * 16 - 4},
|
{1 * 8, 7 * 16 - 4},
|
||||||
3,
|
3,
|
||||||
"autosave freqs"
|
"autosave freqs"};
|
||||||
};
|
|
||||||
|
|
||||||
Checkbox checkbox_autostart_recon{
|
Checkbox checkbox_autostart_recon{
|
||||||
{1 * 8, 9 * 16 - 4},
|
{1 * 8, 9 * 16 - 4},
|
||||||
3,
|
3,
|
||||||
"autostart recon"
|
"autostart recon"};
|
||||||
};
|
|
||||||
|
|
||||||
Checkbox checkbox_continuous{
|
Checkbox checkbox_continuous{
|
||||||
{1 * 8, 11 * 16 - 4},
|
{1 * 8, 11 * 16 - 4},
|
||||||
3,
|
3,
|
||||||
"continuous"
|
"continuous"};
|
||||||
};
|
|
||||||
Checkbox checkbox_clear_output{
|
Checkbox checkbox_clear_output{
|
||||||
{1 * 8, 13 * 16 - 4},
|
{1 * 8, 13 * 16 - 4},
|
||||||
3,
|
3,
|
||||||
"clear output at start"
|
"clear output at start"};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ReconSetupViewMore : public View {
|
class ReconSetupViewMore : public View {
|
||||||
|
@ -124,7 +116,6 @@ namespace ui {
|
||||||
void focus() override;
|
void focus() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
uint32_t _recon_lock_duration = STATS_UPDATE_INTERVAL;
|
uint32_t _recon_lock_duration = STATS_UPDATE_INTERVAL;
|
||||||
uint32_t _recon_lock_nb_match = RECON_DEF_NB_MATCH;
|
uint32_t _recon_lock_nb_match = RECON_DEF_NB_MATCH;
|
||||||
uint32_t _recon_match_mode = RECON_MATCH_CONTINUOUS;
|
uint32_t _recon_match_mode = RECON_MATCH_CONTINUOUS;
|
||||||
|
@ -132,30 +123,25 @@ namespace ui {
|
||||||
Checkbox checkbox_load_freqs{
|
Checkbox checkbox_load_freqs{
|
||||||
{1 * 8, 12},
|
{1 * 8, 12},
|
||||||
3,
|
3,
|
||||||
"input: load freqs"
|
"input: load freqs"};
|
||||||
};
|
|
||||||
|
|
||||||
Checkbox checkbox_load_ranges{
|
Checkbox checkbox_load_ranges{
|
||||||
{1 * 8, 42},
|
{1 * 8, 42},
|
||||||
3,
|
3,
|
||||||
"input: load ranges"
|
"input: load ranges"};
|
||||||
};
|
|
||||||
|
|
||||||
Checkbox checkbox_load_hamradios{
|
Checkbox checkbox_load_hamradios{
|
||||||
{1 * 8, 72},
|
{1 * 8, 72},
|
||||||
3,
|
3,
|
||||||
"input: load hamradios"
|
"input: load hamradios"};
|
||||||
};
|
|
||||||
|
|
||||||
Checkbox checkbox_update_ranges_when_recon{
|
Checkbox checkbox_update_ranges_when_recon{
|
||||||
{1 * 8, 102},
|
{1 * 8, 102},
|
||||||
3,
|
3,
|
||||||
"auto update m-ranges"
|
"auto update m-ranges"};
|
||||||
};
|
|
||||||
Text text_recon_lock_duration{
|
Text text_recon_lock_duration{
|
||||||
{1 * 8, 132, 22 * 8, 22},
|
{1 * 8, 132, 22 * 8, 22},
|
||||||
" ms (lock duration)"
|
" ms (lock duration)"};
|
||||||
};
|
|
||||||
NumberField field_recon_lock_duration{
|
NumberField field_recon_lock_duration{
|
||||||
{1 * 8, 132}, // position X , Y
|
{1 * 8, 132}, // position X , Y
|
||||||
4, // number of displayed digits (even empty)
|
4, // number of displayed digits (even empty)
|
||||||
|
@ -166,26 +152,21 @@ namespace ui {
|
||||||
};
|
};
|
||||||
Text text_recon_lock_nb{
|
Text text_recon_lock_nb{
|
||||||
{1 * 8, 162, 25 * 8, 22},
|
{1 * 8, 162, 25 * 8, 22},
|
||||||
" x (nb lock to match freq)"
|
" x (nb lock to match freq)"};
|
||||||
};
|
|
||||||
NumberField field_recon_lock_nb_match{
|
NumberField field_recon_lock_nb_match{
|
||||||
{1 * 8, 162},
|
{1 * 8, 162},
|
||||||
4,
|
4,
|
||||||
{1, 99},
|
{1, 99},
|
||||||
1,
|
1,
|
||||||
' ',
|
' ',
|
||||||
false
|
false};
|
||||||
};
|
|
||||||
OptionsField field_recon_match_mode{
|
OptionsField field_recon_match_mode{
|
||||||
{1 * 8, 192},
|
{1 * 8, 192},
|
||||||
20, // CONTINUOUS MATCH MODE / SPARSE TIMED MATCH MODE
|
20, // CONTINUOUS MATCH MODE / SPARSE TIMED MATCH MODE
|
||||||
{
|
{
|
||||||
{"SQL MATCH: CONTINOUS", 0},
|
{"SQL MATCH: CONTINOUS", 0},
|
||||||
{ "SQL MATCH: SPARSE" , 1 }
|
{"SQL MATCH: SPARSE", 1}}};
|
||||||
}
|
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class ReconSetupView : public View {
|
class ReconSetupView : public View {
|
||||||
public:
|
public:
|
||||||
|
@ -198,7 +179,6 @@ namespace ui {
|
||||||
std::string title() const override { return "Recon setup"; };
|
std::string title() const override { return "Recon setup"; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
NavigationView& nav_;
|
NavigationView& nav_;
|
||||||
|
|
||||||
std::string input_file = {"RECON"};
|
std::string input_file = {"RECON"};
|
||||||
|
@ -214,12 +194,10 @@ namespace ui {
|
||||||
|
|
||||||
TabView tab_view{
|
TabView tab_view{
|
||||||
{"Main", Color::cyan(), &viewMain},
|
{"Main", Color::cyan(), &viewMain},
|
||||||
{ "More", Color::green(), &viewMore }
|
{"More", Color::green(), &viewMore}};
|
||||||
};
|
|
||||||
Button button_save{
|
Button button_save{
|
||||||
{9 * 8, 255, 14 * 8, 40},
|
{9 * 8, 255, 14 * 8, 40},
|
||||||
"SAVE"
|
"SAVE"};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -38,14 +38,10 @@ RemoteView::~RemoteView() {
|
||||||
// baseband::shutdown();
|
// baseband::shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RemoteView::RemoteView(
|
RemoteView::RemoteView(
|
||||||
NavigationView& nav
|
NavigationView& nav) {
|
||||||
) {
|
add_children({&labels,
|
||||||
add_children({
|
&button});
|
||||||
&labels,
|
|
||||||
&button
|
|
||||||
});
|
|
||||||
|
|
||||||
button.on_select = [this, &nav](Button&) {
|
button.on_select = [this, &nav](Button&) {
|
||||||
nav.pop();
|
nav.pop();
|
||||||
|
|
|
@ -52,13 +52,11 @@ private:
|
||||||
const std::array<remote_layout_t, 32> remote_layout { };*/
|
const std::array<remote_layout_t, 32> remote_layout { };*/
|
||||||
|
|
||||||
Labels labels{
|
Labels labels{
|
||||||
{ { 1 * 8, 0 }, "Work in progress...", Color::light_grey() }
|
{{1 * 8, 0}, "Work in progress...", Color::light_grey()}};
|
||||||
};
|
|
||||||
|
|
||||||
Button button{
|
Button button{
|
||||||
{60, 64, 120, 32},
|
{60, 64, 120, 32},
|
||||||
"Exit"
|
"Exit"};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
|
@ -27,14 +27,14 @@ using namespace portapack;
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
ScannerThread::ScannerThread(std::vector<rf::Frequency> frequency_list) : frequency_list_ { std::move(frequency_list) }
|
ScannerThread::ScannerThread(std::vector<rf::Frequency> frequency_list)
|
||||||
{
|
: frequency_list_{std::move(frequency_list)} {
|
||||||
_manual_search = false;
|
_manual_search = false;
|
||||||
create_thread();
|
create_thread();
|
||||||
}
|
}
|
||||||
|
|
||||||
ScannerThread::ScannerThread(const jammer::jammer_range_t& frequency_range, size_t def_step_hz) : frequency_range_(frequency_range), def_step_hz_(def_step_hz)
|
ScannerThread::ScannerThread(const jammer::jammer_range_t& frequency_range, size_t def_step_hz)
|
||||||
{
|
: frequency_range_(frequency_range), def_step_hz_(def_step_hz) {
|
||||||
_manual_search = true;
|
_manual_search = true;
|
||||||
create_thread();
|
create_thread();
|
||||||
}
|
}
|
||||||
|
@ -43,8 +43,7 @@ ScannerThread::~ScannerThread() {
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScannerThread::create_thread()
|
void ScannerThread::create_thread() {
|
||||||
{
|
|
||||||
thread = chThdCreateFromHeap(NULL, 1024, NORMALPRIO + 10, ScannerThread::static_fn, this);
|
thread = chThdCreateFromHeap(NULL, 1024, NORMALPRIO + 10, ScannerThread::static_fn, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,11 +127,9 @@ void ScannerThread::run() {
|
||||||
message.freq = frequency_list_[frequency_index];
|
message.freq = frequency_list_[frequency_index];
|
||||||
message.range = frequency_index; // Inform freq (for coloring purposes also!)
|
message.range = frequency_index; // Inform freq (for coloring purposes also!)
|
||||||
EventDispatcher::send_message(message);
|
EventDispatcher::send_message(message);
|
||||||
}
|
} else if (_freq_del != 0) { // There is a frequency to delete
|
||||||
else if (_freq_del != 0) { //There is a frequency to delete
|
|
||||||
for (int32_t i = 0; i < size; i++) { // Search for the freq to delete
|
for (int32_t i = 0; i < size; i++) { // Search for the freq to delete
|
||||||
if (frequency_list_[i] == _freq_del)
|
if (frequency_list_[i] == _freq_del) { // found: Erase it
|
||||||
{ //found: Erase it
|
|
||||||
frequency_list_.erase(frequency_list_.begin() + i);
|
frequency_list_.erase(frequency_list_.begin() + i);
|
||||||
size = frequency_list_.size();
|
size = frequency_list_.size();
|
||||||
break;
|
break;
|
||||||
|
@ -181,18 +178,26 @@ void ScannerView::bigdisplay_update(int32_t v) {
|
||||||
bigdisplay_current_color = v; // -1 means refresh display but keep current color
|
bigdisplay_current_color = v; // -1 means refresh display but keep current color
|
||||||
|
|
||||||
switch (bigdisplay_current_color) {
|
switch (bigdisplay_current_color) {
|
||||||
case BDC_GREY: big_display.set_style(&style_grey); break;
|
case BDC_GREY:
|
||||||
case BDC_YELLOW:big_display.set_style(&style_yellow); break;
|
big_display.set_style(&style_grey);
|
||||||
case BDC_GREEN: big_display.set_style(&style_green); break;
|
break;
|
||||||
case BDC_RED: big_display.set_style(&style_red); break;
|
case BDC_YELLOW:
|
||||||
default: break;
|
big_display.set_style(&style_yellow);
|
||||||
|
break;
|
||||||
|
case BDC_GREEN:
|
||||||
|
big_display.set_style(&style_green);
|
||||||
|
break;
|
||||||
|
case BDC_RED:
|
||||||
|
big_display.set_style(&style_red);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// update frequency display
|
// update frequency display
|
||||||
bigdisplay_current_frequency = current_frequency;
|
bigdisplay_current_frequency = current_frequency;
|
||||||
big_display.set(bigdisplay_current_frequency);
|
big_display.set(bigdisplay_current_frequency);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// no style change, but update frequency display if it's changed
|
// no style change, but update frequency display if it's changed
|
||||||
if (current_frequency != bigdisplay_current_frequency) {
|
if (current_frequency != bigdisplay_current_frequency) {
|
||||||
bigdisplay_current_frequency = current_frequency;
|
bigdisplay_current_frequency = current_frequency;
|
||||||
|
@ -206,8 +211,7 @@ void ScannerView::handle_retune(int64_t freq, uint32_t freq_idx) {
|
||||||
current_frequency = freq;
|
current_frequency = freq;
|
||||||
|
|
||||||
if (scan_thread) {
|
if (scan_thread) {
|
||||||
switch (scan_thread->is_freq_lock())
|
switch (scan_thread->is_freq_lock()) {
|
||||||
{
|
|
||||||
case 0: // NO FREQ LOCK, ONGOING STANDARD SCANNING
|
case 0: // NO FREQ LOCK, ONGOING STANDARD SCANNING
|
||||||
bigdisplay_update(BDC_GREY);
|
bigdisplay_update(BDC_GREY);
|
||||||
break;
|
break;
|
||||||
|
@ -252,19 +256,16 @@ void ScannerView::show_max_index() { //show total number of freqs to scan
|
||||||
if (frequency_list.size() == FREQMAN_MAX_PER_FILE) {
|
if (frequency_list.size() == FREQMAN_MAX_PER_FILE) {
|
||||||
text_max_index.set_style(&style_red);
|
text_max_index.set_style(&style_red);
|
||||||
text_max_index.set("/ " + to_string_dec_uint(FREQMAN_MAX_PER_FILE) + " (DB MAX!)");
|
text_max_index.set("/ " + to_string_dec_uint(FREQMAN_MAX_PER_FILE) + " (DB MAX!)");
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
text_max_index.set_style(&style_grey);
|
text_max_index.set_style(&style_grey);
|
||||||
text_max_index.set("/ " + to_string_dec_uint(frequency_list.size()));
|
text_max_index.set("/ " + to_string_dec_uint(frequency_list.size()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ScannerView::ScannerView(
|
ScannerView::ScannerView(
|
||||||
NavigationView& nav
|
NavigationView& nav)
|
||||||
) : nav_ { nav } , loaded_file_name { "SCANNER" }
|
: nav_{nav}, loaded_file_name{"SCANNER"} {
|
||||||
{
|
add_children({&labels,
|
||||||
add_children({
|
|
||||||
&labels,
|
|
||||||
&field_lna,
|
&field_lna,
|
||||||
&field_vga,
|
&field_vga,
|
||||||
&field_rf_amp,
|
&field_rf_amp,
|
||||||
|
@ -315,7 +316,6 @@ ScannerView::ScannerView(
|
||||||
button_load.on_select = [this, &nav](Button&) {
|
button_load.on_select = [this, &nav](Button&) {
|
||||||
auto open_view = nav.push<FileLoadView>(".TXT");
|
auto open_view = nav.push<FileLoadView>(".TXT");
|
||||||
open_view->on_changed = [this](std::filesystem::path new_file_path) {
|
open_view->on_changed = [this](std::filesystem::path new_file_path) {
|
||||||
|
|
||||||
std::string dir_filter = "FREQMAN/";
|
std::string dir_filter = "FREQMAN/";
|
||||||
std::string str_file_path = new_file_path.string();
|
std::string str_file_path = new_file_path.string();
|
||||||
|
|
||||||
|
@ -491,9 +491,7 @@ ScannerView::ScannerView(
|
||||||
auto result = scanner_file.open(freq_file_path); // First search if freq is already in txt
|
auto result = scanner_file.open(freq_file_path); // First search if freq is already in txt
|
||||||
|
|
||||||
if (!result.is_valid()) {
|
if (!result.is_valid()) {
|
||||||
const std::string frequency_to_add = "f="
|
const std::string frequency_to_add = "f=" + to_string_dec_uint(current_frequency / 1000) + to_string_dec_uint(current_frequency % 1000UL, 3, '0');
|
||||||
+ to_string_dec_uint(current_frequency / 1000)
|
|
||||||
+ to_string_dec_uint(current_frequency % 1000UL, 3, '0');
|
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
constexpr size_t buffer_size = 1024;
|
constexpr size_t buffer_size = 1024;
|
||||||
|
@ -504,8 +502,7 @@ ScannerView::ScannerView(
|
||||||
if (pointer + buffer_size >= scanner_file.size()) {
|
if (pointer + buffer_size >= scanner_file.size()) {
|
||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
adjusted_buffer_size = scanner_file.size() - pointer;
|
adjusted_buffer_size = scanner_file.size() - pointer;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
adjusted_buffer_size = buffer_size;
|
adjusted_buffer_size = buffer_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -519,8 +516,7 @@ ScannerView::ScannerView(
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
freq_str_idx = 0;
|
freq_str_idx = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -533,8 +529,7 @@ ScannerView::ScannerView(
|
||||||
if (found) {
|
if (found) {
|
||||||
nav_.display_modal("Error", "Frequency already exists");
|
nav_.display_modal("Error", "Frequency already exists");
|
||||||
bigdisplay_update(-1); // After showing an error
|
bigdisplay_update(-1); // After showing an error
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
scanner_file.append(freq_file_path); // Second: append if it is not there
|
scanner_file.append(freq_file_path); // Second: append if it is not there
|
||||||
scanner_file.write_line(frequency_to_add);
|
scanner_file.write_line(frequency_to_add);
|
||||||
|
|
||||||
|
@ -547,8 +542,7 @@ ScannerView::ScannerView(
|
||||||
show_max_index(); // Display updated frequency list size
|
show_max_index(); // Display updated frequency list size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
{
|
|
||||||
nav_.display_modal("Error", "Cannot open " + loaded_file_name + ".TXT\nfor appending freq.");
|
nav_.display_modal("Error", "Cannot open " + loaded_file_name + ".TXT\nfor appending freq.");
|
||||||
bigdisplay_update(-1); // After showing an error
|
bigdisplay_update(-1); // After showing an error
|
||||||
}
|
}
|
||||||
|
@ -573,7 +567,6 @@ ScannerView::ScannerView(
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScannerView::frequency_file_load(std::string file_name, bool stop_all_before) {
|
void ScannerView::frequency_file_load(std::string file_name, bool stop_all_before) {
|
||||||
|
|
||||||
bool found_range{false};
|
bool found_range{false};
|
||||||
bool found_single{false};
|
bool found_single{false};
|
||||||
freqman_index_t def_mod_index{-1};
|
freqman_index_t def_mod_index{-1};
|
||||||
|
@ -618,13 +611,11 @@ void ScannerView::frequency_file_load(std::string file_name, bool stop_all_befor
|
||||||
frequency_range.max = entry.frequency_b;
|
frequency_range.max = entry.frequency_b;
|
||||||
button_manual_end.set_text(to_string_short_freq(frequency_range.max));
|
button_manual_end.set_text(to_string_short_freq(frequency_range.max));
|
||||||
}
|
}
|
||||||
}
|
} else if (entry.type == SINGLE) {
|
||||||
else if ( entry.type == SINGLE ) {
|
|
||||||
found_single = true;
|
found_single = true;
|
||||||
frequency_list.push_back(entry.frequency_a);
|
frequency_list.push_back(entry.frequency_a);
|
||||||
description_list.push_back(entry.description);
|
description_list.push_back(entry.description);
|
||||||
}
|
} else if (entry.type == HAMRADIO) {
|
||||||
else if ( entry.type == HAMRADIO ) {
|
|
||||||
// For HAM repeaters, add both receive & transmit frequencies to scan list and modify description
|
// For HAM repeaters, add both receive & transmit frequencies to scan list and modify description
|
||||||
// (FUTURE fw versions might handle these differently)
|
// (FUTURE fw versions might handle these differently)
|
||||||
found_single = true;
|
found_single = true;
|
||||||
|
@ -637,15 +628,11 @@ void ScannerView::frequency_file_load(std::string file_name, bool stop_all_befor
|
||||||
description_list.push_back("T:" + entry.description);
|
description_list.push_back("T:" + entry.description);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
break; // No more space: Stop reading the txt file !
|
break; // No more space: Stop reading the txt file !
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
loaded_file_name = "SCANNER"; // back to the default frequency file
|
loaded_file_name = "SCANNER"; // back to the default frequency file
|
||||||
desc_current_index.set(" NO " + file_name + ".TXT FILE ...");
|
desc_current_index.set(" NO " + file_name + ".TXT FILE ...");
|
||||||
}
|
}
|
||||||
|
@ -693,19 +680,15 @@ void ScannerView::update_squelch_while_paused(int32_t max_db) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScannerView::on_statistics_update(const ChannelStatistics& statistics) {
|
void ScannerView::on_statistics_update(const ChannelStatistics& statistics) {
|
||||||
|
|
||||||
if (userpause) {
|
if (userpause) {
|
||||||
update_squelch_while_paused(statistics.max_db);
|
update_squelch_while_paused(statistics.max_db);
|
||||||
}
|
} else if (scan_thread) // Scanning not user-paused
|
||||||
else if ( scan_thread ) //Scanning not user-paused
|
|
||||||
{
|
{
|
||||||
// Resume regardless of signal strength if browse time reached
|
// Resume regardless of signal strength if browse time reached
|
||||||
if ((browse_wait != 0) && (browse_timer >= (browse_wait * STATISTICS_UPDATES_PER_SEC))) {
|
if ((browse_wait != 0) && (browse_timer >= (browse_wait * STATISTICS_UPDATES_PER_SEC))) {
|
||||||
browse_timer = 0;
|
browse_timer = 0;
|
||||||
scan_resume(); // Resume scanning
|
scan_resume(); // Resume scanning
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
if (statistics.max_db > squelch) { // There is something on the air...(statistics.max_db > -squelch)
|
if (statistics.max_db > squelch) { // There is something on the air...(statistics.max_db > -squelch)
|
||||||
if (scan_thread->is_freq_lock() >= MAX_FREQ_LOCK) { // Pause scanning when signal checking time reached
|
if (scan_thread->is_freq_lock() >= MAX_FREQ_LOCK) { // Pause scanning when signal checking time reached
|
||||||
if (!browse_timer) // Don't bother pausing if already paused
|
if (!browse_timer) // Don't bother pausing if already paused
|
||||||
|
@ -787,7 +770,8 @@ void ScannerView::change_mode(freqman_index_t new_mod) { //Before this, do a sca
|
||||||
field_bw.set_selected_index(0);
|
field_bw.set_selected_index(0);
|
||||||
receiver_model.set_am_configuration(field_bw.selected_index());
|
receiver_model.set_am_configuration(field_bw.selected_index());
|
||||||
field_bw.on_change = [this](size_t n, OptionsField::value_t) { receiver_model.set_am_configuration(n); };
|
field_bw.on_change = [this](size_t n, OptionsField::value_t) { receiver_model.set_am_configuration(n); };
|
||||||
receiver_model.set_sampling_rate(3072000); receiver_model.set_baseband_bandwidth(1750000);
|
receiver_model.set_sampling_rate(3072000);
|
||||||
|
receiver_model.set_baseband_bandwidth(1750000);
|
||||||
break;
|
break;
|
||||||
case NFM_MODULATION: // bw 16k (2) default
|
case NFM_MODULATION: // bw 16k (2) default
|
||||||
freqman_set_bandwidth_option(new_mod, field_bw);
|
freqman_set_bandwidth_option(new_mod, field_bw);
|
||||||
|
@ -796,7 +780,8 @@ void ScannerView::change_mode(freqman_index_t new_mod) { //Before this, do a sca
|
||||||
field_bw.set_selected_index(2);
|
field_bw.set_selected_index(2);
|
||||||
receiver_model.set_nbfm_configuration(field_bw.selected_index());
|
receiver_model.set_nbfm_configuration(field_bw.selected_index());
|
||||||
field_bw.on_change = [this](size_t n, OptionsField::value_t) { receiver_model.set_nbfm_configuration(n); };
|
field_bw.on_change = [this](size_t n, OptionsField::value_t) { receiver_model.set_nbfm_configuration(n); };
|
||||||
receiver_model.set_sampling_rate(3072000); receiver_model.set_baseband_bandwidth(1750000);
|
receiver_model.set_sampling_rate(3072000);
|
||||||
|
receiver_model.set_baseband_bandwidth(1750000);
|
||||||
break;
|
break;
|
||||||
case WFM_MODULATION:
|
case WFM_MODULATION:
|
||||||
freqman_set_bandwidth_option(new_mod, field_bw);
|
freqman_set_bandwidth_option(new_mod, field_bw);
|
||||||
|
@ -805,7 +790,8 @@ void ScannerView::change_mode(freqman_index_t new_mod) { //Before this, do a sca
|
||||||
field_bw.set_selected_index(0);
|
field_bw.set_selected_index(0);
|
||||||
receiver_model.set_wfm_configuration(field_bw.selected_index());
|
receiver_model.set_wfm_configuration(field_bw.selected_index());
|
||||||
field_bw.on_change = [this](size_t n, OptionsField::value_t) { receiver_model.set_wfm_configuration(n); };
|
field_bw.on_change = [this](size_t n, OptionsField::value_t) { receiver_model.set_wfm_configuration(n); };
|
||||||
receiver_model.set_sampling_rate(3072000); receiver_model.set_baseband_bandwidth(2000000);
|
receiver_model.set_sampling_rate(3072000);
|
||||||
|
receiver_model.set_baseband_bandwidth(2000000);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -87,25 +87,29 @@ public:
|
||||||
|
|
||||||
void focus() override;
|
void focus() override;
|
||||||
|
|
||||||
const Style style_grey { // scanning
|
const Style style_grey{
|
||||||
|
// scanning
|
||||||
.font = font::fixed_8x16,
|
.font = font::fixed_8x16,
|
||||||
.background = Color::black(),
|
.background = Color::black(),
|
||||||
.foreground = Color::grey(),
|
.foreground = Color::grey(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const Style style_yellow { //Found signal
|
const Style style_yellow{
|
||||||
|
// Found signal
|
||||||
.font = font::fixed_8x16,
|
.font = font::fixed_8x16,
|
||||||
.background = Color::black(),
|
.background = Color::black(),
|
||||||
.foreground = Color::dark_yellow(),
|
.foreground = Color::dark_yellow(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const Style style_green { //Found signal
|
const Style style_green{
|
||||||
|
// Found signal
|
||||||
.font = font::fixed_8x16,
|
.font = font::fixed_8x16,
|
||||||
.background = Color::black(),
|
.background = Color::black(),
|
||||||
.foreground = Color::green(),
|
.foreground = Color::green(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const Style style_red { //erasing freq
|
const Style style_red{
|
||||||
|
// erasing freq
|
||||||
.font = font::fixed_8x16,
|
.font = font::fixed_8x16,
|
||||||
.background = Color::black(),
|
.background = Color::black(),
|
||||||
.foreground = Color::red(),
|
.foreground = Color::red(),
|
||||||
|
@ -170,16 +174,13 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
LNAGainField field_lna{
|
LNAGainField field_lna{
|
||||||
{ 4 * 8, 0 * 16 }
|
{4 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
VGAGainField field_vga{
|
VGAGainField field_vga{
|
||||||
{ 11 * 8, 0 * 16 }
|
{11 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
RFAmpField field_rf_amp{
|
RFAmpField field_rf_amp{
|
||||||
{ 18 * 8, 0 * 16 }
|
{18 * 8, 0 * 16}};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_volume{
|
NumberField field_volume{
|
||||||
{24 * 8, 0 * 16},
|
{24 * 8, 0 * 16},
|
||||||
|
@ -192,8 +193,7 @@ private:
|
||||||
OptionsField field_bw{
|
OptionsField field_bw{
|
||||||
{3 * 8, 1 * 16},
|
{3 * 8, 1 * 16},
|
||||||
6,
|
6,
|
||||||
{ }
|
{}};
|
||||||
};
|
|
||||||
|
|
||||||
NumberField field_squelch{
|
NumberField field_squelch{
|
||||||
{13 * 8, 1 * 16},
|
{13 * 8, 1 * 16},
|
||||||
|
@ -203,7 +203,8 @@ private:
|
||||||
' ',
|
' ',
|
||||||
};
|
};
|
||||||
|
|
||||||
NumberField field_browse_wait { //Signal-Active wait timer - time to wait before moving on even when signal locked
|
NumberField field_browse_wait{
|
||||||
|
// Signal-Active wait timer - time to wait before moving on even when signal locked
|
||||||
{21 * 8, 1 * 16},
|
{21 * 8, 1 * 16},
|
||||||
2,
|
2,
|
||||||
{0, 99},
|
{0, 99},
|
||||||
|
@ -211,7 +212,8 @@ private:
|
||||||
' ',
|
' ',
|
||||||
};
|
};
|
||||||
|
|
||||||
NumberField field_lock_wait { //Signal-Lost wait timer - time to wait before moving on after losing signal lock
|
NumberField field_lock_wait{
|
||||||
|
// Signal-Lost wait timer - time to wait before moving on after losing signal lock
|
||||||
{28 * 8, 1 * 16},
|
{28 * 8, 1 * 16},
|
||||||
2,
|
2,
|
||||||
{0, 99},
|
{0, 99},
|
||||||
|
@ -237,23 +239,19 @@ private:
|
||||||
|
|
||||||
BigFrequency big_display{// Show frequency in glamour
|
BigFrequency big_display{// Show frequency in glamour
|
||||||
{4, 6 * 16, 28 * 8, 52},
|
{4, 6 * 16, 28 * 8, 52},
|
||||||
0
|
0};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_manual_start{
|
Button button_manual_start{
|
||||||
{0 * 8, 11 * 16, 11 * 8, 28},
|
{0 * 8, 11 * 16, 11 * 8, 28},
|
||||||
""
|
""};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_manual_end{
|
Button button_manual_end{
|
||||||
{12 * 8, 11 * 16, 11 * 8, 28},
|
{12 * 8, 11 * 16, 11 * 8, 28},
|
||||||
""
|
""};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_manual_search{
|
Button button_manual_search{
|
||||||
{24 * 8, 11 * 16, 6 * 8, 28},
|
{24 * 8, 11 * 16, 6 * 8, 28},
|
||||||
""
|
""};
|
||||||
};
|
|
||||||
|
|
||||||
OptionsField field_mode{
|
OptionsField field_mode{
|
||||||
{5 * 8, (26 * 8) + 4},
|
{5 * 8, (26 * 8) + 4},
|
||||||
|
@ -269,43 +267,35 @@ private:
|
||||||
|
|
||||||
ButtonWithEncoder button_pause{
|
ButtonWithEncoder button_pause{
|
||||||
{0, (15 * 16) - 4, 72, 28},
|
{0, (15 * 16) - 4, 72, 28},
|
||||||
"<PAUSE>"
|
"<PAUSE>"};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_dir{
|
Button button_dir{
|
||||||
{0, (35 * 8) - 4, 72, 28},
|
{0, (35 * 8) - 4, 72, 28},
|
||||||
"REVERSE"
|
"REVERSE"};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_audio_app{
|
Button button_audio_app{
|
||||||
{84, (15 * 16) - 4, 72, 28},
|
{84, (15 * 16) - 4, 72, 28},
|
||||||
"AUDIO"
|
"AUDIO"};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_mic_app{
|
Button button_mic_app{
|
||||||
{84, (35 * 8) - 4, 72, 28},
|
{84, (35 * 8) - 4, 72, 28},
|
||||||
"MIC TX"
|
"MIC TX"};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_add{
|
Button button_add{
|
||||||
{168, (15 * 16) - 4, 72, 28},
|
{168, (15 * 16) - 4, 72, 28},
|
||||||
"ADD FQ"
|
"ADD FQ"};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_load{
|
Button button_load{
|
||||||
{24 * 8, 3 * 16 - 10, 6 * 8, 22},
|
{24 * 8, 3 * 16 - 10, 6 * 8, 22},
|
||||||
"LOAD"
|
"LOAD"};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_clear{
|
Button button_clear{
|
||||||
{24 * 8, 4 * 16, 6 * 8, 22},
|
{24 * 8, 4 * 16, 6 * 8, 22},
|
||||||
"MCLR"
|
"MCLR"};
|
||||||
};
|
|
||||||
|
|
||||||
Button button_remove{
|
Button button_remove{
|
||||||
{168, (35 * 8) - 4, 72, 28},
|
{168, (35 * 8) - 4, 72, 28},
|
||||||
"DEL FQ"
|
"DEL FQ"};
|
||||||
};
|
|
||||||
|
|
||||||
std::unique_ptr<ScannerThread> scan_thread{};
|
std::unique_ptr<ScannerThread> scan_thread{};
|
||||||
|
|
||||||
|
@ -314,15 +304,13 @@ private:
|
||||||
[this](const Message* const p) {
|
[this](const Message* const p) {
|
||||||
const auto message = *reinterpret_cast<const RetuneMessage*>(p);
|
const auto message = *reinterpret_cast<const RetuneMessage*>(p);
|
||||||
this->handle_retune(message.freq, message.range);
|
this->handle_retune(message.freq, message.range);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
|
|
||||||
MessageHandlerRegistration message_handler_stats{
|
MessageHandlerRegistration message_handler_stats{
|
||||||
Message::ID::ChannelStatistics,
|
Message::ID::ChannelStatistics,
|
||||||
[this](const Message* const p) {
|
[this](const Message* const p) {
|
||||||
this->on_statistics_update(static_cast<const ChannelStatisticsMessage*>(p)->statistics);
|
this->on_statistics_update(static_cast<const ChannelStatisticsMessage*>(p)->statistics);
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue