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:
jLynx
2023-05-19 08:16:05 +12:00
committed by GitHub
parent 7aca7ce74d
commit 033c4e9a5b
599 changed files with 70746 additions and 66896 deletions
+10 -3
View File
@@ -1,7 +1,14 @@
---
BasedOnStyle: Chromium
IndentWidth: '2'
TabWidth: '2'
UseTab: Always
IndentWidth: '4'
SortIncludes: 'false'
AllowAllArgumentsOnNextLine: 'true'
ColumnLimit: 0
Cpp11BracedListStyle: 'true'
AllowShortLoopsOnASingleLine: 'true'
AllowShortIfStatementsOnASingleLine: 'true'
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: 1
...
+9 -4
View File
@@ -1,12 +1,17 @@
name: Check formatting
on: #[push, pull_request] To be enabled once formatting is fixed in repo
workflow_dispatch:
on: [push, pull_request]
jobs:
jobs:
check_date:
runs-on: ubuntu-latest
name: Check formatting
strategy:
matrix:
path:
- "firmware/common"
- "firmware/application"
- "firmware/baseband"
steps:
- uses: actions/checkout@v2
- name: print latest_commit
@@ -14,5 +19,5 @@ jobs:
- name: clang-format Check
uses: jidicula/clang-format-action@v4.11.0
with:
check-path: "firmware"
check-path: ${{ matrix.path }}
fallback-style: Chromium
+63 -67
View File
@@ -32,84 +32,80 @@
namespace std {
int app_settings::load(std::string application, AppSettings* settings) {
if (portapack::persistent_memory::load_app_settings()) {
file_path = folder + "/" + application + ".ini";
if (portapack::persistent_memory::load_app_settings()) {
file_path = folder+"/"+application+".ini";
auto error = settings_file.open(file_path);
if (!error.is_valid()) {
auto error = settings_file.read(file_content, std::min((int)settings_file.size(), MAX_FILE_CONTENT_SIZE));
auto error = settings_file.open(file_path);
if (!error.is_valid()) {
auto error = settings_file.read(file_content, std::min((int)settings_file.size(), MAX_FILE_CONTENT_SIZE));
settings->baseband_bandwidth = std::app_settings::read_long_long(file_content, "baseband_bandwidth=");
settings->channel_bandwidth = std::app_settings::read_long_long(file_content, "channel_bandwidth=");
settings->lna = std::app_settings::read_long_long(file_content, "lna=");
settings->modulation = std::app_settings::read_long_long(file_content, "modulation=");
settings->rx_amp = std::app_settings::read_long_long(file_content, "rx_amp=");
settings->rx_frequency = std::app_settings::read_long_long(file_content, "rx_frequency=");
settings->sampling_rate = std::app_settings::read_long_long(file_content, "sampling_rate=");
settings->vga = std::app_settings::read_long_long(file_content, "vga=");
settings->tx_amp = std::app_settings::read_long_long(file_content, "tx_amp=");
settings->tx_frequency = std::app_settings::read_long_long(file_content, "tx_frequency=");
settings->tx_gain = std::app_settings::read_long_long(file_content, "tx_gain=");
settings->step = std::app_settings::read_long_long(file_content, "step=");
settings->modulation = std::app_settings::read_long_long(file_content, "modulation=");
settings->am_config_index = std::app_settings::read_long_long(file_content, "am_config_index=");
settings->nbfm_config_index = std::app_settings::read_long_long(file_content, "nbfm_config_index=");
settings->wfm_config_index = std::app_settings::read_long_long(file_content, "wfm_config_index=");
settings->squelch = std::app_settings::read_long_long(file_content, "squelch=");
settings->baseband_bandwidth=std::app_settings::read_long_long(file_content, "baseband_bandwidth=");
settings->channel_bandwidth=std::app_settings::read_long_long(file_content, "channel_bandwidth=");
settings->lna=std::app_settings::read_long_long(file_content, "lna=");
settings->modulation=std::app_settings::read_long_long(file_content, "modulation=");
settings->rx_amp=std::app_settings::read_long_long(file_content, "rx_amp=");
settings->rx_frequency=std::app_settings::read_long_long(file_content, "rx_frequency=");
settings->sampling_rate=std::app_settings::read_long_long(file_content, "sampling_rate=");
settings->vga=std::app_settings::read_long_long(file_content, "vga=");
settings->tx_amp=std::app_settings::read_long_long(file_content, "tx_amp=");
settings->tx_frequency=std::app_settings::read_long_long(file_content, "tx_frequency=");
settings->tx_gain=std::app_settings::read_long_long(file_content, "tx_gain=");
settings->step=std::app_settings::read_long_long(file_content, "step=");
settings->modulation=std::app_settings::read_long_long(file_content, "modulation=");
settings->am_config_index=std::app_settings::read_long_long(file_content, "am_config_index=");
settings->nbfm_config_index=std::app_settings::read_long_long(file_content, "nbfm_config_index=");
settings->wfm_config_index=std::app_settings::read_long_long(file_content, "wfm_config_index=");
settings->squelch=std::app_settings::read_long_long(file_content, "squelch=");
rc = SETTINGS_OK;
}
else rc = SETTINGS_UNABLE_TO_LOAD;
}
else rc = SETTINGS_DISABLED;
return(rc);
rc = SETTINGS_OK;
} else
rc = SETTINGS_UNABLE_TO_LOAD;
} else
rc = SETTINGS_DISABLED;
return (rc);
}
int app_settings::save(std::string application, AppSettings* settings) {
if (portapack::persistent_memory::save_app_settings()) {
file_path = folder + "/" + application + ".ini";
make_new_directory(folder);
if (portapack::persistent_memory::save_app_settings()) {
file_path = folder+"/"+application+".ini";
make_new_directory(folder);
auto error = settings_file.create(file_path);
if (!error.is_valid()) {
// Save common setting
settings_file.write_line("baseband_bandwidth=" + to_string_dec_uint(portapack::receiver_model.baseband_bandwidth()));
settings_file.write_line("channel_bandwidth=" + to_string_dec_uint(portapack::transmitter_model.channel_bandwidth()));
settings_file.write_line("lna=" + to_string_dec_uint(portapack::receiver_model.lna()));
settings_file.write_line("rx_amp=" + to_string_dec_uint(portapack::receiver_model.rf_amp()));
settings_file.write_line("sampling_rate=" + to_string_dec_uint(portapack::receiver_model.sampling_rate()));
settings_file.write_line("tx_amp=" + to_string_dec_uint(portapack::transmitter_model.rf_amp()));
settings_file.write_line("tx_gain=" + to_string_dec_uint(portapack::transmitter_model.tx_gain()));
settings_file.write_line("vga=" + to_string_dec_uint(portapack::receiver_model.vga()));
// Save other settings from struct
settings_file.write_line("rx_frequency=" + to_string_dec_uint(settings->rx_frequency));
settings_file.write_line("tx_frequency=" + to_string_dec_uint(settings->tx_frequency));
settings_file.write_line("step=" + to_string_dec_uint(settings->step));
settings_file.write_line("modulation=" + to_string_dec_uint(settings->modulation));
settings_file.write_line("am_config_index=" + to_string_dec_uint(settings->am_config_index));
settings_file.write_line("nbfm_config_index=" + to_string_dec_uint(settings->nbfm_config_index));
settings_file.write_line("wfm_config_index=" + to_string_dec_uint(settings->wfm_config_index));
settings_file.write_line("squelch=" + to_string_dec_uint(settings->squelch));
auto error = settings_file.create(file_path);
if (!error.is_valid()) {
// Save common setting
settings_file.write_line("baseband_bandwidth="+to_string_dec_uint(portapack::receiver_model.baseband_bandwidth()));
settings_file.write_line("channel_bandwidth="+to_string_dec_uint(portapack::transmitter_model.channel_bandwidth()));
settings_file.write_line("lna="+to_string_dec_uint(portapack::receiver_model.lna()));
settings_file.write_line("rx_amp="+to_string_dec_uint(portapack::receiver_model.rf_amp()));
settings_file.write_line("sampling_rate="+to_string_dec_uint(portapack::receiver_model.sampling_rate()));
settings_file.write_line("tx_amp="+to_string_dec_uint(portapack::transmitter_model.rf_amp()));
settings_file.write_line("tx_gain="+to_string_dec_uint(portapack::transmitter_model.tx_gain()));
settings_file.write_line("vga="+to_string_dec_uint(portapack::receiver_model.vga()));
// Save other settings from struct
settings_file.write_line("rx_frequency="+to_string_dec_uint(settings->rx_frequency));
settings_file.write_line("tx_frequency="+to_string_dec_uint(settings->tx_frequency));
settings_file.write_line("step="+to_string_dec_uint(settings->step));
settings_file.write_line("modulation="+to_string_dec_uint(settings->modulation));
settings_file.write_line("am_config_index="+to_string_dec_uint(settings->am_config_index));
settings_file.write_line("nbfm_config_index="+to_string_dec_uint(settings->nbfm_config_index));
settings_file.write_line("wfm_config_index="+to_string_dec_uint(settings->wfm_config_index));
settings_file.write_line("squelch="+to_string_dec_uint(settings->squelch));
rc = SETTINGS_OK;
}
else rc = SETTINGS_UNABLE_TO_SAVE;
}
else rc = SETTINGS_DISABLED;
return(rc);
rc = SETTINGS_OK;
} else
rc = SETTINGS_UNABLE_TO_SAVE;
} else
rc = SETTINGS_DISABLED;
return (rc);
}
long long int app_settings::read_long_long(char* file_content, const char* setting_text) {
auto position = strstr(file_content, (char *)setting_text);
if (position) {
position += strlen((char *)setting_text);
setting_value = strtoll(position, nullptr, 10);
}
return(setting_value);
auto position = strstr(file_content, (char*)setting_text);
if (position) {
position += strlen((char*)setting_text);
setting_value = strtoll(position, nullptr, 10);
}
return (setting_value);
}
} /* namespace std */
+36 -49
View File
@@ -24,7 +24,6 @@
#ifndef __APP_SETTINGS_H__
#define __APP_SETTINGS_H__
#include <cstddef>
#include <cstdint>
#include <string>
@@ -32,61 +31,49 @@
#include "file.hpp"
#include "string_format.hpp"
namespace std {
class app_settings {
public:
#define SETTINGS_OK 0 // settings found
#define SETTINGS_UNABLE_TO_LOAD -1 // settings (file) not found
#define SETTINGS_UNABLE_TO_SAVE -2 // unable to save settings
#define SETTINGS_DISABLED -3 // load/save settings disabled in settings
struct AppSettings {
uint32_t baseband_bandwidth;
uint32_t channel_bandwidth;
uint8_t lna;
uint8_t modulation;
uint8_t rx_amp;
uint32_t rx_frequency;
uint32_t sampling_rate;
uint8_t tx_amp;
uint32_t tx_frequency;
uint8_t tx_gain;
uint8_t vga;
uint32_t step;
uint8_t am_config_index;
uint8_t nbfm_config_index;
uint8_t wfm_config_index;
uint8_t squelch;
};
int load(std::string application, AppSettings* settings);
int save(std::string application, AppSettings* settings);
public:
#define SETTINGS_OK 0 // settings found
#define SETTINGS_UNABLE_TO_LOAD -1 // settings (file) not found
#define SETTINGS_UNABLE_TO_SAVE -2 // unable to save settings
#define SETTINGS_DISABLED -3 // load/save settings disabled in settings
struct AppSettings {
uint32_t baseband_bandwidth;
uint32_t channel_bandwidth;
uint8_t lna;
uint8_t modulation;
uint8_t rx_amp;
uint32_t rx_frequency;
uint32_t sampling_rate;
uint8_t tx_amp;
uint32_t tx_frequency;
uint8_t tx_gain;
uint8_t vga;
uint32_t step;
uint8_t am_config_index;
uint8_t nbfm_config_index;
uint8_t wfm_config_index;
uint8_t squelch;
};
int load(std::string application, AppSettings* settings);
int save(std::string application, AppSettings* settings);
private:
private:
#define MAX_FILE_CONTENT_SIZE 1000
char file_content[MAX_FILE_CONTENT_SIZE] = {};
std::string file_path = "";
std::string folder = "SETTINGS";
int rc = SETTINGS_OK;
File settings_file { };
long long int setting_value {} ;
char file_content[MAX_FILE_CONTENT_SIZE] = {};
std::string file_path = "";
std::string folder = "SETTINGS";
int rc = SETTINGS_OK;
File settings_file{};
long long int setting_value{};
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
} // namespace std
}; // class app_settings
} // namespace std
#endif/*__APP_SETTINGS_H__*/
#endif /*__APP_SETTINGS_H__*/
+83 -85
View File
@@ -32,118 +32,116 @@ using namespace acars;
#include "utility.hpp"
void ACARSLogger::log_raw_data(const acars::Packet& packet, const uint32_t frequency) {
(void)frequency;
std::string entry { }; //= "Raw: F:" + to_string_dec_uint(frequency) + "Hz ";
entry.reserve(256);
// Raw hex dump of all the bytes
//for (size_t c = 0; c < packet.length(); c += 32)
// entry += to_string_hex(packet.read(c, 32), 8) + " ";
for (size_t c = 0; c < 256; c += 32)
entry += to_string_bin(packet.read(c, 32), 32);
log_file.write_entry(packet.received_at(), entry);
(void)frequency;
std::string entry{}; //= "Raw: F:" + to_string_dec_uint(frequency) + "Hz ";
entry.reserve(256);
// Raw hex dump of all the bytes
// for (size_t c = 0; c < packet.length(); c += 32)
// entry += to_string_hex(packet.read(c, 32), 8) + " ";
for (size_t c = 0; c < 256; c += 32)
entry += to_string_bin(packet.read(c, 32), 32);
log_file.write_entry(packet.received_at(), entry);
}
/*void ACARSLogger::log_decoded(
const acars::Packet& packet,
const std::string text) {
log_file.write_entry(packet.timestamp(), text);
const acars::Packet& packet,
const std::string text) {
log_file.write_entry(packet.timestamp(), text);
}*/
namespace ui {
void ACARSAppView::update_freq(rf::Frequency f) {
set_target_frequency(f);
portapack::persistent_memory::set_tuned_frequency(f); // Maybe not ?
set_target_frequency(f);
portapack::persistent_memory::set_tuned_frequency(f); // Maybe not ?
}
ACARSAppView::ACARSAppView(NavigationView& nav) {
baseband::run_image(portapack::spi_flash::image_tag_acars);
baseband::run_image(portapack::spi_flash::image_tag_acars);
add_children({
&rssi,
&channel,
&field_rf_amp,
&field_lna,
&field_vga,
&field_frequency,
&check_log,
&console
});
receiver_model.set_sampling_rate(2457600);
receiver_model.set_baseband_bandwidth(1750000);
receiver_model.enable();
field_frequency.set_value(receiver_model.tuning_frequency());
update_freq(receiver_model.tuning_frequency());
field_frequency.set_step(receiver_model.frequency_step());
field_frequency.on_change = [this](rf::Frequency f) {
update_freq(f);
};
field_frequency.on_edit = [this, &nav]() {
// TODO: Provide separate modal method/scheme?
auto new_view = nav.push<FrequencyKeypadView>(receiver_model.tuning_frequency());
new_view->on_changed = [this](rf::Frequency f) {
update_freq(f);
field_frequency.set_value(f);
};
};
check_log.set_value(logging);
check_log.on_select = [this](Checkbox&, bool v) {
logging = v;
};
logger = std::make_unique<ACARSLogger>();
if (logger)
logger->append(LOG_ROOT_DIR "/ACARS.TXT");
add_children({&rssi,
&channel,
&field_rf_amp,
&field_lna,
&field_vga,
&field_frequency,
&check_log,
&console});
receiver_model.set_sampling_rate(2457600);
receiver_model.set_baseband_bandwidth(1750000);
receiver_model.enable();
field_frequency.set_value(receiver_model.tuning_frequency());
update_freq(receiver_model.tuning_frequency());
field_frequency.set_step(receiver_model.frequency_step());
field_frequency.on_change = [this](rf::Frequency f) {
update_freq(f);
};
field_frequency.on_edit = [this, &nav]() {
// TODO: Provide separate modal method/scheme?
auto new_view = nav.push<FrequencyKeypadView>(receiver_model.tuning_frequency());
new_view->on_changed = [this](rf::Frequency f) {
update_freq(f);
field_frequency.set_value(f);
};
};
check_log.set_value(logging);
check_log.on_select = [this](Checkbox&, bool v) {
logging = v;
};
logger = std::make_unique<ACARSLogger>();
if (logger)
logger->append(LOG_ROOT_DIR "/ACARS.TXT");
}
ACARSAppView::~ACARSAppView() {
receiver_model.disable();
baseband::shutdown();
receiver_model.disable();
baseband::shutdown();
}
void ACARSAppView::focus() {
field_frequency.focus();
field_frequency.focus();
}
void ACARSAppView::on_packet(const acars::Packet& packet) {
std::string console_info;
/*if (!packet.is_valid()) {
console_info = to_string_datetime(packet.received_at(), HMS);
console_info += " INVALID";
console.writeln(console_info);
} else {
console_info = to_string_datetime(packet.received_at(), HMS);
console_info += ":" + to_string_bin(packet.read(0, 32), 32);
//console_info += " REG:" + packet.registration_number();
console.writeln(console_info);
}*/
packet_counter++;
if (packet_counter % 10 == 0)
console.writeln("Block #" + to_string_dec_uint(packet_counter));
// Log raw data whatever it contains
if (logger && logging)
logger->log_raw_data(packet, target_frequency());
std::string console_info;
/*if (!packet.is_valid()) {
console_info = to_string_datetime(packet.received_at(), HMS);
console_info += " INVALID";
console.writeln(console_info);
} else {
console_info = to_string_datetime(packet.received_at(), HMS);
console_info += ":" + to_string_bin(packet.read(0, 32), 32);
//console_info += " REG:" + packet.registration_number();
console.writeln(console_info);
}*/
packet_counter++;
if (packet_counter % 10 == 0)
console.writeln("Block #" + to_string_dec_uint(packet_counter));
// Log raw data whatever it contains
if (logger && logging)
logger->log_raw_data(packet, target_frequency());
}
void ACARSAppView::set_target_frequency(const uint32_t new_value) {
target_frequency_ = new_value;
receiver_model.set_tuning_frequency(new_value);
target_frequency_ = new_value;
receiver_model.set_tuning_frequency(new_value);
}
uint32_t ACARSAppView::target_frequency() const {
return target_frequency_;
return target_frequency_;
}
} /* namespace ui */
+55 -62
View File
@@ -32,85 +32,78 @@
#include "acars_packet.hpp"
class ACARSLogger {
public:
Optional<File::Error> append(const std::string& filename) {
return log_file.append(filename);
}
void log_raw_data(const acars::Packet& packet, const uint32_t frequency);
//void log_decoded(const acars::Packet& packet, const std::string text);
public:
Optional<File::Error> append(const std::string& filename) {
return log_file.append(filename);
}
private:
LogFile log_file { };
void log_raw_data(const acars::Packet& packet, const uint32_t frequency);
// void log_decoded(const acars::Packet& packet, const std::string text);
private:
LogFile log_file{};
};
namespace ui {
class ACARSAppView : public View {
public:
ACARSAppView(NavigationView& nav);
~ACARSAppView();
public:
ACARSAppView(NavigationView& nav);
~ACARSAppView();
void focus() override;
void focus() override;
std::string title() const override { return "ACARS (WIP)"; };
std::string title() const override { return "ACARS (WIP)"; };
private:
bool logging { false };
uint32_t packet_counter { 0 };
private:
bool logging{false};
uint32_t packet_counter{0};
RFAmpField field_rf_amp {
{ 13 * 8, 0 * 16 }
};
LNAGainField field_lna {
{ 15 * 8, 0 * 16 }
};
VGAGainField field_vga {
{ 18 * 8, 0 * 16 }
};
RSSI rssi {
{ 21 * 8, 0, 6 * 8, 4 },
};
Channel channel {
{ 21 * 8, 5, 6 * 8, 4 },
};
FrequencyField field_frequency {
{ 0 * 8, 0 * 8 },
};
Checkbox check_log {
{ 22 * 8, 21 },
3,
"LOG",
true
};
RFAmpField field_rf_amp{
{13 * 8, 0 * 16}};
LNAGainField field_lna{
{15 * 8, 0 * 16}};
VGAGainField field_vga{
{18 * 8, 0 * 16}};
RSSI rssi{
{21 * 8, 0, 6 * 8, 4},
};
Channel channel{
{21 * 8, 5, 6 * 8, 4},
};
Console console {
{ 0, 3 * 16, 240, 256 }
};
FrequencyField field_frequency{
{0 * 8, 0 * 8},
};
Checkbox check_log{
{22 * 8, 21},
3,
"LOG",
true};
std::unique_ptr<ACARSLogger> logger { };
Console console{
{0, 3 * 16, 240, 256}};
uint32_t target_frequency_ { };
void update_freq(rf::Frequency f);
std::unique_ptr<ACARSLogger> logger{};
void on_packet(const acars::Packet& packet);
uint32_t target_frequency_{};
uint32_t target_frequency() const;
void set_target_frequency(const uint32_t new_value);
MessageHandlerRegistration message_handler_packet {
Message::ID::ACARSPacket,
[this](Message* const p) {
const auto message = static_cast<const ACARSPacketMessage*>(p);
const acars::Packet packet { message->packet };
this->on_packet(packet);
}
};
void update_freq(rf::Frequency f);
void on_packet(const acars::Packet& packet);
uint32_t target_frequency() const;
void set_target_frequency(const uint32_t new_value);
MessageHandlerRegistration message_handler_packet{
Message::ID::ACARSPacket,
[this](Message* const p) {
const auto message = static_cast<const ACARSPacketMessage*>(p);
const acars::Packet packet{message->packet};
this->on_packet(packet);
}};
};
} /* namespace ui */
#endif/*__ACARS_APP_H__*/
#endif /*__ACARS_APP_H__*/
File diff suppressed because it is too large Load Diff
+133 -145
View File
@@ -50,64 +50,62 @@ using namespace lpc43xx;
#include "recent_entries.hpp"
struct AISPosition {
rtc::RTC timestamp { };
ais::Latitude latitude { };
ais::Longitude longitude { };
ais::RateOfTurn rate_of_turn { -128 };
ais::SpeedOverGround speed_over_ground { 1023 };
ais::CourseOverGround course_over_ground { 3600 };
ais::TrueHeading true_heading { 511 };
rtc::RTC timestamp{};
ais::Latitude latitude{};
ais::Longitude longitude{};
ais::RateOfTurn rate_of_turn{-128};
ais::SpeedOverGround speed_over_ground{1023};
ais::CourseOverGround course_over_ground{3600};
ais::TrueHeading true_heading{511};
};
struct AISRecentEntry {
using Key = ais::MMSI;
using Key = ais::MMSI;
static constexpr Key invalid_key = 0xffffffff;
static constexpr Key invalid_key = 0xffffffff;
ais::MMSI mmsi;
std::string name;
std::string call_sign;
std::string destination;
AISPosition last_position;
size_t received_count;
int8_t navigational_status;
ais::MMSI mmsi;
std::string name;
std::string call_sign;
std::string destination;
AISPosition last_position;
size_t received_count;
int8_t navigational_status;
AISRecentEntry(
) : AISRecentEntry { 0 }
{
}
AISRecentEntry()
: AISRecentEntry{0} {
}
AISRecentEntry(
const ais::MMSI& mmsi
) : mmsi { mmsi },
name { },
call_sign { },
destination { },
last_position { },
received_count { 0 },
navigational_status { -1 }
{
}
AISRecentEntry(
const ais::MMSI& mmsi)
: mmsi{mmsi},
name{},
call_sign{},
destination{},
last_position{},
received_count{0},
navigational_status{-1} {
}
Key key() const {
return mmsi;
}
Key key() const {
return mmsi;
}
void update(const ais::Packet& packet);
void update(const ais::Packet& packet);
};
using AISRecentEntries = RecentEntries<AISRecentEntry>;
class AISLogger {
public:
Optional<File::Error> append(const std::filesystem::path& filename) {
return log_file.append(filename);
}
void on_packet(const ais::Packet& packet);
public:
Optional<File::Error> append(const std::filesystem::path& filename) {
return log_file.append(filename);
}
private:
LogFile log_file { };
void on_packet(const ais::Packet& packet);
private:
LogFile log_file{};
};
namespace ui {
@@ -115,142 +113,132 @@ namespace ui {
using AISRecentEntriesView = RecentEntriesView<AISRecentEntries>;
class AISRecentEntryDetailView : public View {
public:
std::function<void(void)> on_close { };
public:
std::function<void(void)> on_close{};
AISRecentEntryDetailView(NavigationView& nav);
AISRecentEntryDetailView(NavigationView& nav);
void set_entry(const AISRecentEntry& new_entry);
const AISRecentEntry& entry() const { return entry_; };
void set_entry(const AISRecentEntry& new_entry);
const AISRecentEntry& entry() const { return entry_; };
void update_position();
void focus() override;
void paint(Painter&) override;
void update_position();
void focus() override;
void paint(Painter&) override;
AISRecentEntryDetailView(const AISRecentEntryDetailView&Entry);
AISRecentEntryDetailView &operator=(const AISRecentEntryDetailView&Entry);
AISRecentEntryDetailView(const AISRecentEntryDetailView& Entry);
AISRecentEntryDetailView& operator=(const AISRecentEntryDetailView& Entry);
private:
AISRecentEntry entry_ { };
private:
AISRecentEntry entry_{};
Button button_done {
{ 125, 224, 96, 24 },
"Done"
};
Button button_see_map {
{ 19, 224, 96, 24 },
"See on map"
};
GeoMapView* geomap_view { nullptr };
bool send_updates { false };
Button button_done{
{125, 224, 96, 24},
"Done"};
Button button_see_map{
{19, 224, 96, 24},
"See on map"};
GeoMapView* geomap_view{nullptr};
bool send_updates{false};
Rect draw_field(
Painter& painter,
const Rect& draw_rect,
const Style& style,
const std::string& label,
const std::string& value
);
Rect draw_field(
Painter& painter,
const Rect& draw_rect,
const Style& style,
const std::string& label,
const std::string& value);
};
class AISAppView : public View {
public:
AISAppView(NavigationView& nav);
~AISAppView();
public:
AISAppView(NavigationView& nav);
~AISAppView();
void set_parent_rect(const Rect new_parent_rect) override;
void set_parent_rect(const Rect new_parent_rect) override;
// Prevent painting of region covered entirely by a child.
// TODO: Add flag to View that specifies view does not need to be cleared before painting.
void paint(Painter&) override { };
// Prevent painting of region covered entirely by a child.
// TODO: Add flag to View that specifies view does not need to be cleared before painting.
void paint(Painter&) override{};
void focus() override;
void focus() override;
std::string title() const override { return "AIS RX"; };
std::string title() const override { return "AIS RX"; };
private:
static constexpr uint32_t initial_target_frequency = 162025000;
static constexpr uint32_t sampling_rate = 2457600;
static constexpr uint32_t baseband_bandwidth = 1750000;
private:
static constexpr uint32_t initial_target_frequency = 162025000;
static constexpr uint32_t sampling_rate = 2457600;
static constexpr uint32_t baseband_bandwidth = 1750000;
// app save settings
std::app_settings settings{};
std::app_settings::AppSettings app_settings{};
// app save settings
std::app_settings settings { };
std::app_settings::AppSettings app_settings { };
NavigationView& nav_;
NavigationView& nav_;
AISRecentEntries recent{};
std::unique_ptr<AISLogger> logger{};
AISRecentEntries recent { };
std::unique_ptr<AISLogger> logger { };
const RecentEntriesColumns columns{{
{"MMSI", 9},
{"Name/Call", 20},
}};
AISRecentEntriesView recent_entries_view{columns, recent};
AISRecentEntryDetailView recent_entry_detail_view{nav_};
const RecentEntriesColumns columns { {
{ "MMSI", 9 },
{ "Name/Call", 20 },
} };
AISRecentEntriesView recent_entries_view { columns, recent };
AISRecentEntryDetailView recent_entry_detail_view { nav_ };
static constexpr auto header_height = 1 * 16;
static constexpr auto header_height = 1 * 16;
Text label_channel{
{0 * 8, 0 * 16, 2 * 8, 1 * 16},
"Ch"};
Text label_channel {
{ 0 * 8, 0 * 16, 2 * 8, 1 * 16 },
"Ch"
};
OptionsField options_channel{
{3 * 8, 0 * 16},
3,
{
{"87B", 161975000},
{"88B", 162025000},
}};
OptionsField options_channel {
{ 3 * 8, 0 * 16 },
3,
{
{ "87B", 161975000 },
{ "88B", 162025000 },
}
};
RFAmpField field_rf_amp{
{13 * 8, 0 * 16}};
RFAmpField field_rf_amp {
{ 13 * 8, 0 * 16 }
};
LNAGainField field_lna{
{15 * 8, 0 * 16}};
LNAGainField field_lna {
{ 15 * 8, 0 * 16 }
};
VGAGainField field_vga{
{18 * 8, 0 * 16}};
VGAGainField field_vga {
{ 18 * 8, 0 * 16 }
};
RSSI rssi{
{21 * 8, 0, 6 * 8, 4},
};
RSSI rssi {
{ 21 * 8, 0, 6 * 8, 4 },
};
Channel channel{
{21 * 8, 5, 6 * 8, 4},
};
Channel channel {
{ 21 * 8, 5, 6 * 8, 4 },
};
MessageHandlerRegistration message_handler_packet{
Message::ID::AISPacket,
[this](Message* const p) {
const auto message = static_cast<const AISPacketMessage*>(p);
const ais::Packet packet{message->packet};
if (packet.is_valid()) {
this->on_packet(packet);
}
}};
MessageHandlerRegistration message_handler_packet {
Message::ID::AISPacket,
[this](Message* const p) {
const auto message = static_cast<const AISPacketMessage*>(p);
const ais::Packet packet { message->packet };
if( packet.is_valid() ) {
this->on_packet(packet);
}
}
};
uint32_t target_frequency_ = initial_target_frequency;
uint32_t target_frequency_ = initial_target_frequency;
void on_packet(const ais::Packet& packet);
void on_show_list();
void on_show_detail(const AISRecentEntry& entry);
void on_packet(const ais::Packet& packet);
void on_show_list();
void on_show_detail(const AISRecentEntry& entry);
void on_frequency_changed(const uint32_t new_target_frequency);
void on_frequency_changed(const uint32_t new_target_frequency);
uint32_t target_frequency() const;
void set_target_frequency(const uint32_t new_value);
uint32_t target_frequency() const;
void set_target_frequency(const uint32_t new_value);
uint32_t tuning_frequency() const;
uint32_t tuning_frequency() const;
};
} /* namespace ui */
#endif/*__AIS_APP_H__*/
#endif /*__AIS_APP_H__*/
File diff suppressed because it is too large Load Diff
+185 -195
View File
@@ -32,250 +32,240 @@
#include "app_settings.hpp"
#include "tone_key.hpp"
namespace ui {
constexpr Style style_options_group {
.font = font::fixed_8x16,
.background = Color::blue(),
.foreground = Color::white(),
constexpr Style style_options_group{
.font = font::fixed_8x16,
.background = Color::blue(),
.foreground = Color::white(),
};
class AMOptionsView : public View {
public:
AMOptionsView(const Rect parent_rect, const Style* const style);
public:
AMOptionsView(const Rect parent_rect, const Style* const style);
private:
Text label_config {
{ 0 * 8, 0 * 16, 2 * 8, 1 * 16 },
"BW",
};
private:
Text label_config{
{0 * 8, 0 * 16, 2 * 8, 1 * 16},
"BW",
};
OptionsField options_config {
{ 3 * 8, 0 * 16 },
5,
{ // using common messages from freqman.cpp
}
};
OptionsField options_config{
{3 * 8, 0 * 16},
5,
{
// using common messages from freqman.cpp
}};
};
class NBFMOptionsView : public View {
public:
NBFMOptionsView(const Rect parent_rect, const Style* const style);
public:
NBFMOptionsView(const Rect parent_rect, const Style* const style);
private:
Text label_config {
{ 0 * 8, 0 * 16, 2 * 8, 1 * 16 },
"BW",
};
OptionsField options_config {
{ 3 * 8, 0 * 16 },
4,
{ // using common messages from freqman.cpp
}
};
Text text_squelch {
{ 9 * 8, 0 * 16, 8 * 8, 1 * 16 },
"SQ /99"
};
NumberField field_squelch {
{ 12 * 8, 0 * 16 },
2,
{ 0, 99 },
1,
' ',
};
private:
Text label_config{
{0 * 8, 0 * 16, 2 * 8, 1 * 16},
"BW",
};
OptionsField options_config{
{3 * 8, 0 * 16},
4,
{
// using common messages from freqman.cpp
}};
Text text_squelch{
{9 * 8, 0 * 16, 8 * 8, 1 * 16},
"SQ /99"};
NumberField field_squelch{
{12 * 8, 0 * 16},
2,
{0, 99},
1,
' ',
};
};
class WFMOptionsView : public View {
public:
WFMOptionsView(const Rect parent_rect, const Style* const style);
public:
WFMOptionsView(const Rect parent_rect, const Style* const style);
private:
Text label_config {
{ 0 * 8, 0 * 16, 2 * 8, 1 * 16 },
"BW",
};
OptionsField options_config {
{ 3 * 8, 0 * 16 },
4,
{ // using common messages from freqman.cpp
}
};
private:
Text label_config{
{0 * 8, 0 * 16, 2 * 8, 1 * 16},
"BW",
};
OptionsField options_config{
{3 * 8, 0 * 16},
4,
{
// using common messages from freqman.cpp
}};
};
class AnalogAudioView;
class SPECOptionsView : public View {
public:
SPECOptionsView(AnalogAudioView* view, const Rect parent_rect, const Style* const style);
public:
SPECOptionsView(AnalogAudioView* view, const Rect parent_rect, const Style* const style);
private:
Text label_config {
{ 0 * 8, 0 * 16, 2 * 8, 1 * 16 },
"BW",
};
OptionsField options_config {
{ 3 * 8, 0 * 16 },
4,
{
{ "20m ", 20000000 },
{ "10m ", 10000000 },
{ " 5m ", 5000000 },
{ " 2m ", 2000000 },
{ " 1m ", 1000000 },
{ "500k", 500000 },
{ "100k", 100000 },
}
};
Text text_speed {
{ 9 * 8, 0 * 16, 8 * 8, 1 * 16 },
"SP /63"
};
NumberField field_speed {
{ 12 * 8, 0 * 16 },
2,
{ 0, 63 },
1,
' ',
};
private:
Text label_config{
{0 * 8, 0 * 16, 2 * 8, 1 * 16},
"BW",
};
OptionsField options_config{
{3 * 8, 0 * 16},
4,
{
{"20m ", 20000000},
{"10m ", 10000000},
{" 5m ", 5000000},
{" 2m ", 2000000},
{" 1m ", 1000000},
{"500k", 500000},
{"100k", 100000},
}};
Text text_speed{
{9 * 8, 0 * 16, 8 * 8, 1 * 16},
"SP /63"};
NumberField field_speed{
{12 * 8, 0 * 16},
2,
{0, 63},
1,
' ',
};
};
class AnalogAudioView : public View {
public:
AnalogAudioView(NavigationView& nav);
~AnalogAudioView();
public:
AnalogAudioView(NavigationView& nav);
~AnalogAudioView();
void on_hide() override;
void on_hide() override;
void set_parent_rect(const Rect new_parent_rect) override;
void set_parent_rect(const Rect new_parent_rect) override;
void focus() override;
void focus() override;
std::string title() const override { return "Audio RX"; };
std::string title() const override { return "Audio RX"; };
size_t get_spec_bw_index();
void set_spec_bw(size_t index, uint32_t bw);
size_t get_spec_bw_index();
void set_spec_bw(size_t index, uint32_t bw);
uint16_t get_spec_trigger();
void set_spec_trigger(uint16_t trigger);
uint16_t get_spec_trigger();
void set_spec_trigger(uint16_t trigger);
private:
static constexpr ui::Dim header_height = 3 * 16;
private:
static constexpr ui::Dim header_height = 3 * 16;
// app save settings
std::app_settings settings { };
std::app_settings::AppSettings app_settings { };
// app save settings
std::app_settings settings{};
std::app_settings::AppSettings app_settings{};
const Rect options_view_rect { 0 * 8, 1 * 16, 30 * 8, 1 * 16 };
const Rect nbfm_view_rect { 0 * 8, 1 * 16, 18 * 8, 1 * 16 };
const Rect options_view_rect{0 * 8, 1 * 16, 30 * 8, 1 * 16};
const Rect nbfm_view_rect{0 * 8, 1 * 16, 18 * 8, 1 * 16};
size_t spec_bw_index = 0;
uint32_t spec_bw = 20000000;
uint16_t spec_trigger = 63;
size_t spec_bw_index = 0;
uint32_t spec_bw = 20000000;
uint16_t spec_trigger = 63;
NavigationView& nav_;
//bool exit_on_squelch { false };
RSSI rssi {
{ 21 * 8, 0, 6 * 8, 4 },
};
NavigationView& nav_;
// bool exit_on_squelch { false };
Channel channel {
{ 21 * 8, 5, 6 * 8, 4 },
};
RSSI rssi{
{21 * 8, 0, 6 * 8, 4},
};
Audio audio {
{ 21 * 8, 10, 6 * 8, 4 },
};
Channel channel{
{21 * 8, 5, 6 * 8, 4},
};
FrequencyField field_frequency {
{ 5 * 8, 0 * 16 },
};
Audio audio{
{21 * 8, 10, 6 * 8, 4},
};
LNAGainField field_lna {
{ 15 * 8, 0 * 16 }
};
FrequencyField field_frequency{
{5 * 8, 0 * 16},
};
VGAGainField field_vga {
{ 18 * 8, 0 * 16 }
};
LNAGainField field_lna{
{15 * 8, 0 * 16}};
OptionsField options_modulation {
{ 0 * 8, 0 * 16 },
4,
{
{ " AM ", toUType(ReceiverModel::Mode::AMAudio) },
{ "NFM ", toUType(ReceiverModel::Mode::NarrowbandFMAudio) },
{ "WFM ", toUType(ReceiverModel::Mode::WidebandFMAudio) },
{ "SPEC", toUType(ReceiverModel::Mode::SpectrumAnalysis) },
}
};
VGAGainField field_vga{
{18 * 8, 0 * 16}};
NumberField field_volume {
{ 28 * 8, 0 * 16 },
2,
{ 0, 99 },
1,
' ',
};
Text text_ctcss {
{ 19 * 8, 1 * 16, 11 * 8, 1 * 16 },
""
};
OptionsField options_modulation{
{0 * 8, 0 * 16},
4,
{
{" AM ", toUType(ReceiverModel::Mode::AMAudio)},
{"NFM ", toUType(ReceiverModel::Mode::NarrowbandFMAudio)},
{"WFM ", toUType(ReceiverModel::Mode::WidebandFMAudio)},
{"SPEC", toUType(ReceiverModel::Mode::SpectrumAnalysis)},
}};
std::unique_ptr<Widget> options_widget { };
NumberField field_volume{
{28 * 8, 0 * 16},
2,
{0, 99},
1,
' ',
};
RecordView record_view {
{ 0 * 8, 2 * 16, 30 * 8, 1 * 16 },
u"AUD", u"AUDIO",
RecordView::FileType::WAV,
4096,
4
};
Text text_ctcss{
{19 * 8, 1 * 16, 11 * 8, 1 * 16},
""};
spectrum::WaterfallWidget waterfall { true };
std::unique_ptr<Widget> options_widget{};
void on_tuning_frequency_changed(rf::Frequency f);
void on_baseband_bandwidth_changed(uint32_t bandwidth_hz);
void on_modulation_changed(const ReceiverModel::Mode modulation);
void on_show_options_frequency();
void on_show_options_rf_gain();
void on_show_options_modulation();
void on_frequency_step_changed(rf::Frequency f);
void on_reference_ppm_correction_changed(int32_t v);
void on_headphone_volume_changed(int32_t v);
void on_edit_frequency();
RecordView record_view{
{0 * 8, 2 * 16, 30 * 8, 1 * 16},
u"AUD",
u"AUDIO",
RecordView::FileType::WAV,
4096,
4};
void remove_options_widget();
void set_options_widget(std::unique_ptr<Widget> new_widget);
spectrum::WaterfallWidget waterfall{true};
void update_modulation(const ReceiverModel::Mode modulation);
//void squelched();
void handle_coded_squelch(const uint32_t value);
/*MessageHandlerRegistration message_handler_squelch_signal {
Message::ID::RequestSignal,
[this](const Message* const p) {
(void)p;
this->squelched();
}
};*/
MessageHandlerRegistration message_handler_coded_squelch {
Message::ID::CodedSquelch,
[this](const Message* const p) {
const auto message = *reinterpret_cast<const CodedSquelchMessage*>(p);
this->handle_coded_squelch(message.value);
}
};
void on_tuning_frequency_changed(rf::Frequency f);
void on_baseband_bandwidth_changed(uint32_t bandwidth_hz);
void on_modulation_changed(const ReceiverModel::Mode modulation);
void on_show_options_frequency();
void on_show_options_rf_gain();
void on_show_options_modulation();
void on_frequency_step_changed(rf::Frequency f);
void on_reference_ppm_correction_changed(int32_t v);
void on_headphone_volume_changed(int32_t v);
void on_edit_frequency();
void remove_options_widget();
void set_options_widget(std::unique_ptr<Widget> new_widget);
void update_modulation(const ReceiverModel::Mode modulation);
// void squelched();
void handle_coded_squelch(const uint32_t value);
/*MessageHandlerRegistration message_handler_squelch_signal {
Message::ID::RequestSignal,
[this](const Message* const p) {
(void)p;
this->squelched();
}
};*/
MessageHandlerRegistration message_handler_coded_squelch{
Message::ID::CodedSquelch,
[this](const Message* const p) {
const auto message = *reinterpret_cast<const CodedSquelchMessage*>(p);
this->handle_coded_squelch(message.value);
}};
};
} /* namespace ui */
#endif/*__ANALOG_AUDIO_APP_H__*/
#endif /*__ANALOG_AUDIO_APP_H__*/
+134 -139
View File
@@ -42,213 +42,208 @@ namespace ui {
/* AnalogTvView *******************************************************/
AnalogTvView::AnalogTvView(
NavigationView& nav
) : nav_ (nav)
{
add_children({
&rssi,
&channel,
&audio,
&field_frequency,
&field_lna,
&field_vga,
&options_modulation,
&field_volume,
&tv
});
NavigationView& nav)
: nav_(nav) {
add_children({&rssi,
&channel,
&audio,
&field_frequency,
&field_lna,
&field_vga,
&options_modulation,
&field_volume,
&tv});
// Set on_change before initialising the field
field_frequency.on_change = [this](rf::Frequency f) {
this->on_tuning_frequency_changed(f);
};
// Set on_change before initialising the field
field_frequency.on_change = [this](rf::Frequency f) {
this->on_tuning_frequency_changed(f);
};
// load app settings
auto rc = settings.load("rx_tv", &app_settings);
if(rc == SETTINGS_OK) {
field_lna.set_value(app_settings.lna);
field_vga.set_value(app_settings.vga);
receiver_model.set_rf_amp(app_settings.rx_amp);
field_frequency.set_value(app_settings.rx_frequency);
}
else field_frequency.set_value(receiver_model.tuning_frequency());
// load app settings
auto rc = settings.load("rx_tv", &app_settings);
if (rc == SETTINGS_OK) {
field_lna.set_value(app_settings.lna);
field_vga.set_value(app_settings.vga);
receiver_model.set_rf_amp(app_settings.rx_amp);
field_frequency.set_value(app_settings.rx_frequency);
} else
field_frequency.set_value(receiver_model.tuning_frequency());
field_frequency.set_step(receiver_model.frequency_step());
field_frequency.on_edit = [this, &nav]() {
// TODO: Provide separate modal method/scheme?
auto new_view = nav.push<FrequencyKeypadView>(receiver_model.tuning_frequency());
new_view->on_changed = [this](rf::Frequency f) {
this->on_tuning_frequency_changed(f);
this->field_frequency.set_value(f);
};
};
field_frequency.set_step(receiver_model.frequency_step());
field_frequency.on_edit = [this, &nav]() {
// TODO: Provide separate modal method/scheme?
auto new_view = nav.push<FrequencyKeypadView>(receiver_model.tuning_frequency());
new_view->on_changed = [this](rf::Frequency f) {
this->on_tuning_frequency_changed(f);
this->field_frequency.set_value(f);
};
};
field_frequency.on_show_options = [this]() {
this->on_show_options_frequency();
};
field_frequency.on_show_options = [this]() {
this->on_show_options_frequency();
};
field_lna.on_show_options = [this]() {
this->on_show_options_rf_gain();
};
field_lna.on_show_options = [this]() {
this->on_show_options_rf_gain();
};
field_vga.on_show_options = [this]() {
this->on_show_options_rf_gain();
};
field_vga.on_show_options = [this]() {
this->on_show_options_rf_gain();
};
const auto modulation = receiver_model.modulation();
options_modulation.set_by_value(toUType(ReceiverModel::Mode::WidebandFMAudio));
options_modulation.on_change = [this](size_t, OptionsField::value_t v) {
this->on_modulation_changed(static_cast<ReceiverModel::Mode>(v));
};
options_modulation.on_show_options = [this]() {
this->on_show_options_modulation();
};
const auto modulation = receiver_model.modulation();
options_modulation.set_by_value(toUType(ReceiverModel::Mode::WidebandFMAudio));
options_modulation.on_change = [this](size_t, OptionsField::value_t v) {
this->on_modulation_changed(static_cast<ReceiverModel::Mode>(v));
};
options_modulation.on_show_options = [this]() {
this->on_show_options_modulation();
};
field_volume.set_value(0);
field_volume.on_change = [this](int32_t v) {
this->on_headphone_volume_changed(v);
};
field_volume.set_value(0);
field_volume.on_change = [this](int32_t v) {
this->on_headphone_volume_changed(v);
};
tv.on_select = [this](int32_t offset) {
field_frequency.set_value(receiver_model.tuning_frequency() + offset);
};
tv.on_select = [this](int32_t offset) {
field_frequency.set_value(receiver_model.tuning_frequency() + offset);
};
update_modulation(static_cast<ReceiverModel::Mode>(modulation));
on_modulation_changed(ReceiverModel::Mode::WidebandFMAudio);
update_modulation(static_cast<ReceiverModel::Mode>(modulation));
on_modulation_changed(ReceiverModel::Mode::WidebandFMAudio);
}
AnalogTvView::~AnalogTvView() {
// save app settings
app_settings.rx_frequency = field_frequency.value();
settings.save("rx_tv", &app_settings);
// save app settings
app_settings.rx_frequency = field_frequency.value();
settings.save("rx_tv", &app_settings);
// TODO: Manipulating audio codec here, and in ui_receiver.cpp. Good to do
// both?
audio::output::stop();
receiver_model.disable();
baseband::shutdown();
// TODO: Manipulating audio codec here, and in ui_receiver.cpp. Good to do
// both?
audio::output::stop();
receiver_model.disable();
baseband::shutdown();
}
void AnalogTvView::on_hide() {
// TODO: Terrible kludge because widget system doesn't notify Waterfall that
// it's being shown or hidden.
tv.on_hide();
View::on_hide();
// TODO: Terrible kludge because widget system doesn't notify Waterfall that
// it's being shown or hidden.
tv.on_hide();
View::on_hide();
}
void AnalogTvView::set_parent_rect(const Rect new_parent_rect) {
View::set_parent_rect(new_parent_rect);
const ui::Rect tv_rect { 0, header_height, new_parent_rect.width(), new_parent_rect.height() - header_height };
tv.set_parent_rect(tv_rect);
View::set_parent_rect(new_parent_rect);
const ui::Rect tv_rect{0, header_height, new_parent_rect.width(), new_parent_rect.height() - header_height};
tv.set_parent_rect(tv_rect);
}
void AnalogTvView::focus() {
field_frequency.focus();
field_frequency.focus();
}
void AnalogTvView::on_tuning_frequency_changed(rf::Frequency f) {
receiver_model.set_tuning_frequency(f);
receiver_model.set_tuning_frequency(f);
}
void AnalogTvView::on_baseband_bandwidth_changed(uint32_t bandwidth_hz) {
receiver_model.set_baseband_bandwidth(bandwidth_hz);
receiver_model.set_baseband_bandwidth(bandwidth_hz);
}
void AnalogTvView::on_modulation_changed(const ReceiverModel::Mode modulation) {
// TODO: Terrible kludge because widget system doesn't notify Waterfall that
// it's being shown or hidden.
tv.on_hide();
update_modulation(modulation);
on_show_options_modulation();
tv.on_show();
// TODO: Terrible kludge because widget system doesn't notify Waterfall that
// it's being shown or hidden.
tv.on_hide();
update_modulation(modulation);
on_show_options_modulation();
tv.on_show();
}
void AnalogTvView::remove_options_widget() {
if( options_widget ) {
remove_child(options_widget.get());
options_widget.reset();
}
field_lna.set_style(nullptr);
options_modulation.set_style(nullptr);
field_frequency.set_style(nullptr);
if (options_widget) {
remove_child(options_widget.get());
options_widget.reset();
}
field_lna.set_style(nullptr);
options_modulation.set_style(nullptr);
field_frequency.set_style(nullptr);
}
void AnalogTvView::set_options_widget(std::unique_ptr<Widget> new_widget) {
remove_options_widget();
remove_options_widget();
if( new_widget ) {
options_widget = std::move(new_widget);
} else {
// TODO: Lame hack to hide options view due to my bad paint/damage algorithm.
options_widget = std::make_unique<Rectangle>(options_view_rect, style_options_group_new.background);
}
add_child(options_widget.get());
if (new_widget) {
options_widget = std::move(new_widget);
} else {
// TODO: Lame hack to hide options view due to my bad paint/damage algorithm.
options_widget = std::make_unique<Rectangle>(options_view_rect, style_options_group_new.background);
}
add_child(options_widget.get());
}
void AnalogTvView::on_show_options_frequency() {
auto widget = std::make_unique<FrequencyOptionsView>(options_view_rect, &style_options_group_new);
auto widget = std::make_unique<FrequencyOptionsView>(options_view_rect, &style_options_group_new);
widget->set_step(receiver_model.frequency_step());
widget->on_change_step = [this](rf::Frequency f) {
this->on_frequency_step_changed(f);
};
widget->set_reference_ppm_correction(persistent_memory::correction_ppb() / 1000);
widget->on_change_reference_ppm_correction = [this](int32_t v) {
this->on_reference_ppm_correction_changed(v);
};
widget->set_step(receiver_model.frequency_step());
widget->on_change_step = [this](rf::Frequency f) {
this->on_frequency_step_changed(f);
};
widget->set_reference_ppm_correction(persistent_memory::correction_ppb() / 1000);
widget->on_change_reference_ppm_correction = [this](int32_t v) {
this->on_reference_ppm_correction_changed(v);
};
set_options_widget(std::move(widget));
field_frequency.set_style(&style_options_group_new);
set_options_widget(std::move(widget));
field_frequency.set_style(&style_options_group_new);
}
void AnalogTvView::on_show_options_rf_gain() {
auto widget = std::make_unique<RadioGainOptionsView>(options_view_rect, &style_options_group_new);
auto widget = std::make_unique<RadioGainOptionsView>(options_view_rect, &style_options_group_new);
set_options_widget(std::move(widget));
field_lna.set_style(&style_options_group_new);
set_options_widget(std::move(widget));
field_lna.set_style(&style_options_group_new);
}
void AnalogTvView::on_show_options_modulation() {
std::unique_ptr<Widget> widget;
std::unique_ptr<Widget> widget;
static_cast<ReceiverModel::Mode>(receiver_model.modulation());
tv.show_audio_spectrum_view(true);
set_options_widget(std::move(widget));
options_modulation.set_style(&style_options_group_new);
static_cast<ReceiverModel::Mode>(receiver_model.modulation());
tv.show_audio_spectrum_view(true);
set_options_widget(std::move(widget));
options_modulation.set_style(&style_options_group_new);
}
void AnalogTvView::on_frequency_step_changed(rf::Frequency f) {
receiver_model.set_frequency_step(f);
field_frequency.set_step(f);
receiver_model.set_frequency_step(f);
field_frequency.set_step(f);
}
void AnalogTvView::on_reference_ppm_correction_changed(int32_t v) {
persistent_memory::set_correction_ppb(v * 1000);
persistent_memory::set_correction_ppb(v * 1000);
}
void AnalogTvView::on_headphone_volume_changed(int32_t v) {
(void)v; //avoid warning
//tv::TVView::set_headphone_volume(this,v);
(void)v; // avoid warning
// tv::TVView::set_headphone_volume(this,v);
}
void AnalogTvView::update_modulation(const ReceiverModel::Mode modulation) {
audio::output::mute();
audio::output::mute();
baseband::shutdown();
baseband::shutdown();
portapack::spi_flash::image_tag_t image_tag;
image_tag = portapack::spi_flash::image_tag_am_tv;
portapack::spi_flash::image_tag_t image_tag;
image_tag = portapack::spi_flash::image_tag_am_tv;
baseband::run_image(image_tag);
baseband::run_image(image_tag);
receiver_model.set_modulation(modulation);
receiver_model.set_sampling_rate(2000000);
receiver_model.set_baseband_bandwidth(2000000);
receiver_model.enable();
receiver_model.set_modulation(modulation);
receiver_model.set_sampling_rate(2000000);
receiver_model.set_baseband_bandwidth(2000000);
receiver_model.enable();
}
} /* namespace ui */
+67 -72
View File
@@ -36,102 +36,97 @@
namespace ui {
constexpr Style style_options_group_new {
.font = font::fixed_8x16,
.background = Color::blue(),
.foreground = Color::white(),
constexpr Style style_options_group_new{
.font = font::fixed_8x16,
.background = Color::blue(),
.foreground = Color::white(),
};
class AnalogTvView : public View {
public:
AnalogTvView(NavigationView& nav);
~AnalogTvView();
public:
AnalogTvView(NavigationView& nav);
~AnalogTvView();
void on_hide() override;
void on_hide() override;
void set_parent_rect(const Rect new_parent_rect) override;
void set_parent_rect(const Rect new_parent_rect) override;
void focus() override;
void focus() override;
std::string title() const override { return "AnalogTV RX"; };
private:
static constexpr ui::Dim header_height = 3 * 16;
std::string title() const override { return "AnalogTV RX"; };
// app save settings
std::app_settings settings { };
std::app_settings::AppSettings app_settings { };
private:
static constexpr ui::Dim header_height = 3 * 16;
const Rect options_view_rect { 0 * 8, 1 * 16, 30 * 8, 1 * 16 };
const Rect nbfm_view_rect { 0 * 8, 1 * 16, 18 * 8, 1 * 16 };
// app save settings
std::app_settings settings{};
std::app_settings::AppSettings app_settings{};
NavigationView& nav_;
RSSI rssi {
{ 21 * 8, 0, 6 * 8, 4 },
};
const Rect options_view_rect{0 * 8, 1 * 16, 30 * 8, 1 * 16};
const Rect nbfm_view_rect{0 * 8, 1 * 16, 18 * 8, 1 * 16};
Channel channel {
{ 21 * 8, 5, 6 * 8, 4 },
};
NavigationView& nav_;
Audio audio {
{ 21 * 8, 10, 6 * 8, 4 },
};
RSSI rssi{
{21 * 8, 0, 6 * 8, 4},
};
FrequencyField field_frequency {
{ 5 * 8, 0 * 16 },
};
Channel channel{
{21 * 8, 5, 6 * 8, 4},
};
LNAGainField field_lna {
{ 15 * 8, 0 * 16 }
};
Audio audio{
{21 * 8, 10, 6 * 8, 4},
};
VGAGainField field_vga {
{ 18 * 8, 0 * 16 }
};
FrequencyField field_frequency{
{5 * 8, 0 * 16},
};
OptionsField options_modulation {
{ 0 * 8, 0 * 16 },
4,
{
{ "TV ", toUType(ReceiverModel::Mode::WidebandFMAudio) },
{ "TV ", toUType(ReceiverModel::Mode::WidebandFMAudio) },
{ "TV ", toUType(ReceiverModel::Mode::WidebandFMAudio) },
}
};
LNAGainField field_lna{
{15 * 8, 0 * 16}};
NumberField field_volume {
{ 27 * 8, 0 * 16 },
3,
{ 0, 255 },
1,
' ',
};
VGAGainField field_vga{
{18 * 8, 0 * 16}};
std::unique_ptr<Widget> options_widget { };
OptionsField options_modulation{
{0 * 8, 0 * 16},
4,
{
{"TV ", toUType(ReceiverModel::Mode::WidebandFMAudio)},
{"TV ", toUType(ReceiverModel::Mode::WidebandFMAudio)},
{"TV ", toUType(ReceiverModel::Mode::WidebandFMAudio)},
}};
tv::TVWidget tv { };
NumberField field_volume{
{27 * 8, 0 * 16},
3,
{0, 255},
1,
' ',
};
void on_tuning_frequency_changed(rf::Frequency f);
void on_baseband_bandwidth_changed(uint32_t bandwidth_hz);
void on_modulation_changed(const ReceiverModel::Mode modulation);
void on_show_options_frequency();
void on_show_options_rf_gain();
void on_show_options_modulation();
void on_frequency_step_changed(rf::Frequency f);
void on_reference_ppm_correction_changed(int32_t v);
void on_headphone_volume_changed(int32_t v);
void on_edit_frequency();
std::unique_ptr<Widget> options_widget{};
void remove_options_widget();
void set_options_widget(std::unique_ptr<Widget> new_widget);
tv::TVWidget tv{};
void update_modulation(const ReceiverModel::Mode modulation);
void on_tuning_frequency_changed(rf::Frequency f);
void on_baseband_bandwidth_changed(uint32_t bandwidth_hz);
void on_modulation_changed(const ReceiverModel::Mode modulation);
void on_show_options_frequency();
void on_show_options_rf_gain();
void on_show_options_modulation();
void on_frequency_step_changed(rf::Frequency f);
void on_reference_ppm_correction_changed(int32_t v);
void on_headphone_volume_changed(int32_t v);
void on_edit_frequency();
void remove_options_widget();
void set_options_widget(std::unique_ptr<Widget> new_widget);
void update_modulation(const ReceiverModel::Mode modulation);
};
} /* namespace ui */
#endif/*__ANALOG_TV_APP_H__*/
#endif /*__ANALOG_TV_APP_H__*/
+108 -110
View File
@@ -30,142 +30,140 @@ using namespace portapack;
namespace ui {
CaptureAppView::CaptureAppView(NavigationView& nav) {
baseband::run_image(portapack::spi_flash::image_tag_capture);
baseband::run_image(portapack::spi_flash::image_tag_capture);
add_children({
&labels,
&rssi,
&channel,
&field_frequency,
&field_frequency_step,
&field_rf_amp,
&field_lna,
&field_vga,
&option_bandwidth,
&record_view,
&waterfall,
});
add_children({
&labels,
&rssi,
&channel,
&field_frequency,
&field_frequency_step,
&field_rf_amp,
&field_lna,
&field_vga,
&option_bandwidth,
&record_view,
&waterfall,
});
// Hack for initialization
// TODO: This should be included in a more global section so apps dont need to do it
receiver_model.set_sampling_rate(3072000);
receiver_model.set_baseband_bandwidth(1750000);
//-------------------
// Hack for initialization
// TODO: This should be included in a more global section so apps dont need to do it
receiver_model.set_sampling_rate(3072000);
receiver_model.set_baseband_bandwidth(1750000);
//-------------------
field_frequency.set_value(receiver_model.tuning_frequency());
field_frequency.set_step(receiver_model.frequency_step());
field_frequency.on_change = [this](rf::Frequency f) {
this->on_tuning_frequency_changed(f);
};
field_frequency.on_edit = [this, &nav]() {
// TODO: Provide separate modal method/scheme?
auto new_view = nav.push<FrequencyKeypadView>(receiver_model.tuning_frequency());
new_view->on_changed = [this](rf::Frequency f) {
this->on_tuning_frequency_changed(f);
this->field_frequency.set_value(f);
};
};
field_frequency_step.set_by_value(receiver_model.frequency_step());
field_frequency_step.on_change = [this](size_t, OptionsField::value_t v) {
receiver_model.set_frequency_step(v);
this->field_frequency.set_step(v);
};
option_bandwidth.on_change = [this](size_t, uint32_t base_rate) {
sampling_rate = 8 * base_rate; // Decimation by 8 done on baseband side
/* base_rate is used for FFT calculation and display LCD, and also in recording writing SD Card rate. */
/* ex. sampling_rate values, 4Mhz, when recording 500 kHz (BW) and fs 8 Mhz , when selected 1 Mhz BW ...*/
/* ex. recording 500kHz BW to .C16 file, base_rate clock 500kHz x2(I,Q) x 2 bytes (int signed) =2MB/sec rate SD Card */
field_frequency.set_value(receiver_model.tuning_frequency());
field_frequency.set_step(receiver_model.frequency_step());
field_frequency.on_change = [this](rf::Frequency f) {
this->on_tuning_frequency_changed(f);
};
field_frequency.on_edit = [this, &nav]() {
// TODO: Provide separate modal method/scheme?
auto new_view = nav.push<FrequencyKeypadView>(receiver_model.tuning_frequency());
new_view->on_changed = [this](rf::Frequency f) {
this->on_tuning_frequency_changed(f);
this->field_frequency.set_value(f);
};
};
waterfall.on_hide();
record_view.set_sampling_rate(sampling_rate);
receiver_model.set_sampling_rate(sampling_rate);
/* Set up proper anti aliasing BPF bandwith in MAX2837 before ADC sampling according to the new added BW Options . */
switch(sampling_rate) { // we use the var fs (sampling_rate) , to set up BPF aprox < fs_max/2 by Nyquist theorem.
case 0 ... 2000000: // BW Captured range (0 <= 250kHz max ) fs = 8 x 250 kHz
anti_alias_baseband_bandwidth_filter = 1750000; // Minimum BPF MAX2837 for all those lower BW options.
break;
field_frequency_step.set_by_value(receiver_model.frequency_step());
field_frequency_step.on_change = [this](size_t, OptionsField::value_t v) {
receiver_model.set_frequency_step(v);
this->field_frequency.set_step(v);
};
case 4000000 ... 6000000: // BW capture range (500k ... 750kHz max ) fs_max = 8 x 750kHz = 6Mhz
// BW 500k ... 750kHz , ex. 500kHz (fs = 8*BW = 4Mhz) , BW 600kHz (fs = 4,8Mhz) , BW 750 kHz (fs = 6Mhz)
anti_alias_baseband_bandwidth_filter = 2500000; // in some IC MAX2837 appear 2250000 , but both works similar.
break;
option_bandwidth.on_change = [this](size_t, uint32_t base_rate) {
sampling_rate = 8 * base_rate; // Decimation by 8 done on baseband side
/* base_rate is used for FFT calculation and display LCD, and also in recording writing SD Card rate. */
/* ex. sampling_rate values, 4Mhz, when recording 500 kHz (BW) and fs 8 Mhz , when selected 1 Mhz BW ...*/
/* ex. recording 500kHz BW to .C16 file, base_rate clock 500kHz x2(I,Q) x 2 bytes (int signed) =2MB/sec rate SD Card */
case 8800000: // BW capture 1,1Mhz fs = 8 x 1,1Mhz = 8,8Mhz . (1Mhz showed slightly higher noise background).
anti_alias_baseband_bandwidth_filter = 3500000;
break;
waterfall.on_hide();
record_view.set_sampling_rate(sampling_rate);
receiver_model.set_sampling_rate(sampling_rate);
/* Set up proper anti aliasing BPF bandwith in MAX2837 before ADC sampling according to the new added BW Options . */
case 14000000: // BW capture 1,75Mhz , fs = 8 x 1,75Mhz = 14Mhz
// good BPF ,good matching, but LCD making flicker , refresh rate should be < 20 Hz , but reasonable picture
anti_alias_baseband_bandwidth_filter = 5000000;
break;
switch (sampling_rate) { // we use the var fs (sampling_rate) , to set up BPF aprox < fs_max/2 by Nyquist theorem.
case 16000000: // BW capture 2Mhz , fs = 8 x 2Mhz = 16Mhz
// good BPF ,good matching, but LCD making flicker , refresh rate should be < 20 Hz , but reasonable picture
anti_alias_baseband_bandwidth_filter = 6000000;
break;
case 20000000: // BW capture 2,5Mhz , fs= 8 x 2,5 Mhz = 20Mhz
// good BPF ,good matching, but LCD making flicker , refresh rate should be < 20 Hz , but reasonable picture
anti_alias_baseband_bandwidth_filter = 7000000;
break;
default: // BW capture 2,75Mhz, fs = 8 x 2,75Mhz= 22Mhz max ADC sampling) and others.
// We tested also 9Mhz FPB stightly too much noise floor , better 8Mhz
anti_alias_baseband_bandwidth_filter = 8000000;
}
receiver_model.set_baseband_bandwidth(anti_alias_baseband_bandwidth_filter);
waterfall.on_show();
};
option_bandwidth.set_selected_index(7); // 500k, Preselected starting default option 500kHz
receiver_model.set_modulation(ReceiverModel::Mode::Capture);
receiver_model.enable();
case 0 ... 2000000: // BW Captured range (0 <= 250kHz max ) fs = 8 x 250 kHz
anti_alias_baseband_bandwidth_filter = 1750000; // Minimum BPF MAX2837 for all those lower BW options.
break;
record_view.on_error = [&nav](std::string message) {
nav.display_modal("Error", message);
};
case 4000000 ... 6000000: // BW capture range (500k ... 750kHz max ) fs_max = 8 x 750kHz = 6Mhz
// BW 500k ... 750kHz , ex. 500kHz (fs = 8*BW = 4Mhz) , BW 600kHz (fs = 4,8Mhz) , BW 750 kHz (fs = 6Mhz)
anti_alias_baseband_bandwidth_filter = 2500000; // in some IC MAX2837 appear 2250000 , but both works similar.
break;
case 8800000: // BW capture 1,1Mhz fs = 8 x 1,1Mhz = 8,8Mhz . (1Mhz showed slightly higher noise background).
anti_alias_baseband_bandwidth_filter = 3500000;
break;
case 14000000: // BW capture 1,75Mhz , fs = 8 x 1,75Mhz = 14Mhz
// good BPF ,good matching, but LCD making flicker , refresh rate should be < 20 Hz , but reasonable picture
anti_alias_baseband_bandwidth_filter = 5000000;
break;
case 16000000: // BW capture 2Mhz , fs = 8 x 2Mhz = 16Mhz
// good BPF ,good matching, but LCD making flicker , refresh rate should be < 20 Hz , but reasonable picture
anti_alias_baseband_bandwidth_filter = 6000000;
break;
case 20000000: // BW capture 2,5Mhz , fs= 8 x 2,5 Mhz = 20Mhz
// good BPF ,good matching, but LCD making flicker , refresh rate should be < 20 Hz , but reasonable picture
anti_alias_baseband_bandwidth_filter = 7000000;
break;
default: // BW capture 2,75Mhz, fs = 8 x 2,75Mhz= 22Mhz max ADC sampling) and others.
// We tested also 9Mhz FPB stightly too much noise floor , better 8Mhz
anti_alias_baseband_bandwidth_filter = 8000000;
}
receiver_model.set_baseband_bandwidth(anti_alias_baseband_bandwidth_filter);
waterfall.on_show();
};
option_bandwidth.set_selected_index(7); // 500k, Preselected starting default option 500kHz
receiver_model.set_modulation(ReceiverModel::Mode::Capture);
receiver_model.enable();
record_view.on_error = [&nav](std::string message) {
nav.display_modal("Error", message);
};
}
CaptureAppView::~CaptureAppView() {
// Hack for preventing halting other apps
// TODO: This should be also part of something global
receiver_model.set_sampling_rate(3072000);
receiver_model.set_baseband_bandwidth(1750000);
receiver_model.set_modulation(ReceiverModel::Mode::WidebandFMAudio);
// ----------------------------
// Hack for preventing halting other apps
// TODO: This should be also part of something global
receiver_model.set_sampling_rate(3072000);
receiver_model.set_baseband_bandwidth(1750000);
receiver_model.set_modulation(ReceiverModel::Mode::WidebandFMAudio);
// ----------------------------
receiver_model.disable();
baseband::shutdown();
receiver_model.disable();
baseband::shutdown();
}
void CaptureAppView::on_hide() {
// TODO: Terrible kludge because widget system doesn't notify Waterfall that
// it's being shown or hidden.
waterfall.on_hide();
View::on_hide();
// TODO: Terrible kludge because widget system doesn't notify Waterfall that
// it's being shown or hidden.
waterfall.on_hide();
View::on_hide();
}
void CaptureAppView::set_parent_rect(const Rect new_parent_rect) {
View::set_parent_rect(new_parent_rect);
View::set_parent_rect(new_parent_rect);
const ui::Rect waterfall_rect { 0, header_height, new_parent_rect.width(), new_parent_rect.height() - header_height };
waterfall.set_parent_rect(waterfall_rect);
const ui::Rect waterfall_rect{0, header_height, new_parent_rect.width(), new_parent_rect.height() - header_height};
waterfall.set_parent_rect(waterfall_rect);
}
void CaptureAppView::focus() {
record_view.focus();
record_view.focus();
}
void CaptureAppView::on_tuning_frequency_changed(rf::Frequency f) {
receiver_model.set_tuning_frequency(f);
receiver_model.set_tuning_frequency(f);
}
} /* namespace ui */
+65 -68
View File
@@ -29,94 +29,91 @@
#include "ui_record_view.hpp"
#include "ui_spectrum.hpp"
#define BW_OPTIONS \
{ " 8k5", 8500 }, \
{ " 11k", 11000 }, \
{ " 16k", 16000 }, \
{ " 25k", 25000 }, \
{ " 50k", 50000 }, \
{ " 100k", 100000 }, \
{ " 250k", 250000 }, \
{ " 500k", 500000 }, /* Previous Limit bandwith Option with perfect micro SD write .C16 format operaton.*/ \
{ " 600k", 600000 }, /* That extended option is still possible to record with FW version Mayhem v1.41 (< 2,5MB/sec) */ \
{ " 750k", 750000 }, /* From that BW onwards, the LCD is ok, but the recorded file is auto decimated,(not real file size) */ \
{ "1100k", 1100000 }, \
{ "1750k", 1750000 }, \
{ "2000k", 2000000 }, \
{ "2500k", 2500000 }, \
{ "2750k", 2750000 } // That is our max Capture option , to keep using later / 8 decimation (22Mhz sampling ADC)
#define BW_OPTIONS \
{" 8k5", 8500}, \
{" 11k", 11000}, \
{" 16k", 16000}, \
{" 25k", 25000}, \
{" 50k", 50000}, \
{" 100k", 100000}, \
{" 250k", 250000}, \
{" 500k", 500000}, /* Previous Limit bandwith Option with perfect micro SD write .C16 format operaton.*/ \
{" 600k", 600000}, /* That extended option is still possible to record with FW version Mayhem v1.41 (< 2,5MB/sec) */ \
{" 750k", 750000}, /* From that BW onwards, the LCD is ok, but the recorded file is auto decimated,(not real file size) */ \
{"1100k", 1100000}, \
{"1750k", 1750000}, \
{"2000k", 2000000}, \
{"2500k", 2500000}, \
{ "2750k", 2750000 } // That is our max Capture option , to keep using later / 8 decimation (22Mhz sampling ADC)
namespace ui {
class CaptureAppView : public View {
public:
CaptureAppView(NavigationView& nav);
~CaptureAppView();
public:
CaptureAppView(NavigationView& nav);
~CaptureAppView();
void on_hide() override;
void on_hide() override;
void set_parent_rect(const Rect new_parent_rect) override;
void set_parent_rect(const Rect new_parent_rect) override;
void focus() override;
void focus() override;
std::string title() const override { return "Capture"; };
std::string title() const override { return "Capture"; };
private:
static constexpr ui::Dim header_height = 3 * 16;
private:
static constexpr ui::Dim header_height = 3 * 16;
uint32_t sampling_rate = 0;
uint32_t anti_alias_baseband_bandwidth_filter = 2500000; // we rename the previous var , and change type static constexpr to normal var.
uint32_t sampling_rate = 0;
uint32_t anti_alias_baseband_bandwidth_filter = 2500000; // we rename the previous var , and change type static constexpr to normal var.
void on_tuning_frequency_changed(rf::Frequency f);
void on_tuning_frequency_changed(rf::Frequency f);
Labels labels {
{ { 0 * 8, 1 * 16 }, "Rate:", Color::light_grey() },
};
RSSI rssi {
{ 24 * 8, 0, 6 * 8, 4 },
};
Labels labels{
{{0 * 8, 1 * 16}, "Rate:", Color::light_grey()},
};
Channel channel {
{ 24 * 8, 5, 6 * 8, 4 },
};
RSSI rssi{
{24 * 8, 0, 6 * 8, 4},
};
FrequencyField field_frequency {
{ 0 * 8, 0 * 16 },
};
FrequencyStepView field_frequency_step {
{ 10 * 8, 0 * 16 },
};
Channel channel{
{24 * 8, 5, 6 * 8, 4},
};
RFAmpField field_rf_amp {
{ 16 * 8, 0 * 16 }
};
FrequencyField field_frequency{
{0 * 8, 0 * 16},
};
LNAGainField field_lna {
{ 18 * 8, 0 * 16 }
};
FrequencyStepView field_frequency_step{
{10 * 8, 0 * 16},
};
VGAGainField field_vga {
{ 21 * 8, 0 * 16 }
};
RFAmpField field_rf_amp{
{16 * 8, 0 * 16}};
OptionsField option_bandwidth {
{ 5 * 8, 1 * 16 },
5,
{
BW_OPTIONS
}
};
RecordView record_view {
{ 0 * 8, 2 * 16, 30 * 8, 1 * 16 },
u"BBD_????.*", u"CAPTURES", RecordView::FileType::RawS16, 16384, 3
};
LNAGainField field_lna{
{18 * 8, 0 * 16}};
spectrum::WaterfallWidget waterfall { };
VGAGainField field_vga{
{21 * 8, 0 * 16}};
OptionsField option_bandwidth{
{5 * 8, 1 * 16},
5,
{BW_OPTIONS}};
RecordView record_view{
{0 * 8, 2 * 16, 30 * 8, 1 * 16},
u"BBD_????.*",
u"CAPTURES",
RecordView::FileType::RawS16,
16384,
3};
spectrum::WaterfallWidget waterfall{};
};
} /* namespace ui */
#endif/*__CAPTURE_APP_HPP__*/
#endif /*__CAPTURE_APP_HPP__*/
+133 -123
View File
@@ -52,54 +52,53 @@
// Default version number, if not overriden by the Makefile
#ifndef MODES_DUMP1090_VERSION
# define MODES_DUMP1090_VERSION "unknown"
#define MODES_DUMP1090_VERSION "unknown"
#endif
#ifndef MODES_DUMP1090_VARIANT
# define MODES_DUMP1090_VARIANT "dump1090-unknown"
#define MODES_DUMP1090_VARIANT "dump1090-unknown"
#endif
#define MODES_DEFAULT_FREQ 1090000000
#define MODES_DEFAULT_WIDTH 1000
#define MODES_DEFAULT_HEIGHT 700
#define MODES_RTL_BUFFERS 15 // Number of RTL buffers
#define MODES_RTL_BUF_SIZE (16 * 16384) // 256k
#define MODES_MAG_BUF_SAMPLES (MODES_RTL_BUF_SIZE / 2) // Each sample is 2 bytes
#define MODES_MAG_BUFFERS 12 // Number of magnitude buffers (should be smaller than RTL_BUFFERS for flowcontrol to work)
#define MODES_AUTO_GAIN -100 // Use automatic gain
#define MODES_MAX_GAIN 999999 // Use max available gain
#define MODES_MSG_SQUELCH_DB 4.0 // Minimum SNR, in dB
#define MODES_MSG_ENCODER_ERRS 3 // Maximum number of encoding errors
#define MODES_DEFAULT_FREQ 1090000000
#define MODES_DEFAULT_WIDTH 1000
#define MODES_DEFAULT_HEIGHT 700
#define MODES_RTL_BUFFERS 15 // Number of RTL buffers
#define MODES_RTL_BUF_SIZE (16*16384) // 256k
#define MODES_MAG_BUF_SAMPLES (MODES_RTL_BUF_SIZE / 2) // Each sample is 2 bytes
#define MODES_MAG_BUFFERS 12 // Number of magnitude buffers (should be smaller than RTL_BUFFERS for flowcontrol to work)
#define MODES_AUTO_GAIN -100 // Use automatic gain
#define MODES_MAX_GAIN 999999 // Use max available gain
#define MODES_MSG_SQUELCH_DB 4.0 // Minimum SNR, in dB
#define MODES_MSG_ENCODER_ERRS 3 // Maximum number of encoding errors
#define MODEAC_MSG_SAMPLES (25 * 2) // include up to the SPI bit
#define MODEAC_MSG_BYTES 2
#define MODEAC_MSG_SQUELCH_LEVEL 0x07FF // Average signal strength limit
#define MODEAC_MSG_SAMPLES (25 * 2) // include up to the SPI bit
#define MODEAC_MSG_BYTES 2
#define MODEAC_MSG_SQUELCH_LEVEL 0x07FF // Average signal strength limit
#define MODES_PREAMBLE_US 8 // microseconds = bits
#define MODES_PREAMBLE_SAMPLES (MODES_PREAMBLE_US * 2)
#define MODES_PREAMBLE_SIZE (MODES_PREAMBLE_SAMPLES * sizeof(uint16_t))
#define MODES_LONG_MSG_BYTES 14
#define MODES_SHORT_MSG_BYTES 7
#define MODES_LONG_MSG_BITS (MODES_LONG_MSG_BYTES * 8)
#define MODES_SHORT_MSG_BITS (MODES_SHORT_MSG_BYTES * 8)
#define MODES_LONG_MSG_SAMPLES (MODES_LONG_MSG_BITS * 2)
#define MODES_SHORT_MSG_SAMPLES (MODES_SHORT_MSG_BITS * 2)
#define MODES_LONG_MSG_SIZE (MODES_LONG_MSG_SAMPLES * sizeof(uint16_t))
#define MODES_SHORT_MSG_SIZE (MODES_SHORT_MSG_SAMPLES * sizeof(uint16_t))
#define MODES_PREAMBLE_US 8 // microseconds = bits
#define MODES_PREAMBLE_SAMPLES (MODES_PREAMBLE_US * 2)
#define MODES_PREAMBLE_SIZE (MODES_PREAMBLE_SAMPLES * sizeof(uint16_t))
#define MODES_LONG_MSG_BYTES 14
#define MODES_SHORT_MSG_BYTES 7
#define MODES_LONG_MSG_BITS (MODES_LONG_MSG_BYTES * 8)
#define MODES_SHORT_MSG_BITS (MODES_SHORT_MSG_BYTES * 8)
#define MODES_LONG_MSG_SAMPLES (MODES_LONG_MSG_BITS * 2)
#define MODES_SHORT_MSG_SAMPLES (MODES_SHORT_MSG_BITS * 2)
#define MODES_LONG_MSG_SIZE (MODES_LONG_MSG_SAMPLES * sizeof(uint16_t))
#define MODES_SHORT_MSG_SIZE (MODES_SHORT_MSG_SAMPLES * sizeof(uint16_t))
#define MODES_OS_PREAMBLE_SAMPLES (20)
#define MODES_OS_PREAMBLE_SIZE (MODES_OS_PREAMBLE_SAMPLES * sizeof(uint16_t))
#define MODES_OS_LONG_MSG_SAMPLES (268)
#define MODES_OS_PREAMBLE_SAMPLES (20)
#define MODES_OS_PREAMBLE_SIZE (MODES_OS_PREAMBLE_SAMPLES * sizeof(uint16_t))
#define MODES_OS_LONG_MSG_SAMPLES (268)
#define MODES_OS_SHORT_MSG_SAMPLES (135)
#define MODES_OS_LONG_MSG_SIZE (MODES_LONG_MSG_SAMPLES * sizeof(uint16_t))
#define MODES_OS_SHORT_MSG_SIZE (MODES_SHORT_MSG_SAMPLES * sizeof(uint16_t))
#define MODES_OS_LONG_MSG_SIZE (MODES_LONG_MSG_SAMPLES * sizeof(uint16_t))
#define MODES_OS_SHORT_MSG_SIZE (MODES_SHORT_MSG_SAMPLES * sizeof(uint16_t))
#define MODES_OUT_BUF_SIZE (1500)
#define MODES_OUT_FLUSH_SIZE (MODES_OUT_BUF_SIZE - 256)
#define MODES_OUT_FLUSH_INTERVAL (60000)
#define MODES_OUT_BUF_SIZE (1500)
#define MODES_OUT_FLUSH_SIZE (MODES_OUT_BUF_SIZE - 256)
#define MODES_OUT_FLUSH_INTERVAL (60000)
#define MODES_USER_LATLON_VALID (1<<0)
#define MODES_USER_LATLON_VALID (1 << 0)
#define INVALID_ALTITUDE (-9999)
@@ -119,19 +118,19 @@ typedef enum {
* (Earlier values are higher priority)
*/
typedef enum {
ADDR_ADSB_ICAO, /* Mode S or ADS-B, ICAO address, transponder sourced */
ADDR_ADSB_ICAO_NT, /* ADS-B, ICAO address, non-transponder */
ADDR_ADSR_ICAO, /* ADS-R, ICAO address */
ADDR_TISB_ICAO, /* TIS-B, ICAO address */
ADDR_ADSB_ICAO, /* Mode S or ADS-B, ICAO address, transponder sourced */
ADDR_ADSB_ICAO_NT, /* ADS-B, ICAO address, non-transponder */
ADDR_ADSR_ICAO, /* ADS-R, ICAO address */
ADDR_TISB_ICAO, /* TIS-B, ICAO address */
ADDR_ADSB_OTHER, /* ADS-B, other address format */
ADDR_ADSR_OTHER, /* ADS-R, other address format */
ADDR_TISB_TRACKFILE, /* TIS-B, Mode A code + track file number */
ADDR_TISB_OTHER, /* TIS-B, other address format */
ADDR_ADSB_OTHER, /* ADS-B, other address format */
ADDR_ADSR_OTHER, /* ADS-R, other address format */
ADDR_TISB_TRACKFILE, /* TIS-B, Mode A code + track file number */
ADDR_TISB_OTHER, /* TIS-B, other address format */
ADDR_MODE_A, /* Mode A */
ADDR_MODE_A, /* Mode A */
ADDR_UNKNOWN /* unknown address format */
ADDR_UNKNOWN /* unknown address format */
} addrtype_t;
typedef enum {
@@ -158,20 +157,25 @@ typedef enum {
} airground_t;
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;
typedef enum {
CPR_SURFACE, CPR_AIRBORNE, CPR_COARSE
CPR_SURFACE,
CPR_AIRBORNE,
CPR_COARSE
} cpr_type_t;
typedef enum {
HEADING_INVALID, // Not set
HEADING_GROUND_TRACK, // Direction of track over ground, degrees clockwise from true north
HEADING_TRUE, // Heading, degrees clockwise from true north
HEADING_MAGNETIC, // Heading, degrees clockwise from magnetic north
HEADING_MAGNETIC_OR_TRUE, // HEADING_MAGNETIC or HEADING_TRUE depending on the HRD bit in opstatus
HEADING_TRACK_OR_HEADING // GROUND_TRACK / MAGNETIC / TRUE depending on the TAH bit in opstatus
HEADING_INVALID, // Not set
HEADING_GROUND_TRACK, // Direction of track over ground, degrees clockwise from true north
HEADING_TRUE, // Heading, degrees clockwise from true north
HEADING_MAGNETIC, // Heading, degrees clockwise from magnetic north
HEADING_MAGNETIC_OR_TRUE, // HEADING_MAGNETIC or HEADING_TRUE depending on the HRD bit in opstatus
HEADING_TRACK_OR_HEADING // GROUND_TRACK / MAGNETIC / TRUE depending on the TAH bit in opstatus
} heading_type_t;
typedef enum {
@@ -209,61 +213,68 @@ typedef enum {
} emergency_t;
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;
#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
#define MODES_INTERACTIVE_REFRESH_TIME 250 // Milliseconds
#define MODES_INTERACTIVE_DISPLAY_TTL 60000 // Delete from display after 60 seconds
#define MODES_INTERACTIVE_REFRESH_TIME 250 // Milliseconds
#define MODES_INTERACTIVE_DISPLAY_TTL 60000 // Delete from display after 60 seconds
#define MODES_NET_HEARTBEAT_INTERVAL 60000 // milliseconds
#define MODES_NET_HEARTBEAT_INTERVAL 60000 // milliseconds
#define MODES_CLIENT_BUF_SIZE 1024
#define MODES_NET_SNDBUF_SIZE (1024*64)
#define MODES_NET_SNDBUF_MAX (7)
#define MODES_CLIENT_BUF_SIZE 1024
#define MODES_NET_SNDBUF_SIZE (1024 * 64)
#define MODES_NET_SNDBUF_MAX (7)
#define HISTORY_SIZE 120
#define HISTORY_INTERVAL 30000
#define MODES_NOTUSED(V) ((void) V)
#define MODES_NOTUSED(V) ((void)V)
#define MAX_AMPLITUDE 65535.0
#define MAX_POWER (MAX_AMPLITUDE * MAX_AMPLITUDE)
#define FAUP_DEFAULT_RATE_MULTIPLIER 1.0 // FA Upload rate multiplier
#define FAUP_DEFAULT_RATE_MULTIPLIER 1.0 // FA Upload rate multiplier
//======================== structure declarations =========================
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;
// The struct we use to store information about a decoded message.
struct modesMessage {
// Generic fields
unsigned char msg[MODES_LONG_MSG_BYTES]; // Binary message.
unsigned char verbatim[MODES_LONG_MSG_BYTES]; // Binary message, as originally received before correction
int msgbits; // Number of bits in message
int msgtype; // Downlink format #
uint32_t crc; // Message CRC
int correctedbits; // No. of bits corrected
uint32_t addr; // Address Announced
addrtype_t addrtype; // address format / source
uint64_t timestampMsg; // Timestamp of the message (12MHz clock)
uint64_t sysTimestampMsg; // Timestamp of the message (system time)
int remote; // If set this message is from a remote station
double signalLevel; // RSSI, in the range [0..1], as a fraction of full-scale power
int score; // Scoring from scoreModesMessage, if used
int reliable; // is this a "reliable" message (uncorrected DF11/DF17/DF18)?
unsigned char msg[MODES_LONG_MSG_BYTES]; // Binary message.
unsigned char verbatim[MODES_LONG_MSG_BYTES]; // Binary message, as originally received before correction
int msgbits; // Number of bits in message
int msgtype; // Downlink format #
uint32_t crc; // Message CRC
int correctedbits; // No. of bits corrected
uint32_t addr; // Address Announced
addrtype_t addrtype; // address format / source
uint64_t timestampMsg; // Timestamp of the message (12MHz clock)
uint64_t sysTimestampMsg; // Timestamp of the message (system time)
int remote; // If set this message is from a remote station
double signalLevel; // RSSI, in the range [0..1], as a fraction of full-scale power
int score; // Scoring from scoreModesMessage, if used
int reliable; // is this a "reliable" message (uncorrected DF11/DF17/DF18)?
datasource_t source; // Characterizes the overall message source
datasource_t source; // Characterizes the overall message source
// Raw data, just extracted directly from the message
// The names reflect the field names in Annex 4
unsigned IID; // extracted from CRC of DF11s
unsigned IID; // extracted from CRC of DF11s
unsigned AA;
unsigned AC;
unsigned CA;
@@ -312,25 +323,25 @@ struct modesMessage {
unsigned alert : 1;
unsigned emergency_valid : 1;
unsigned metype; // DF17/18 ME type
unsigned mesub; // DF17/18 ME subtype
unsigned metype; // DF17/18 ME type
unsigned mesub; // DF17/18 ME subtype
commb_format_t commb_format; // Inferred format of a comm-b message
commb_format_t commb_format; // Inferred format of a comm-b message
// valid if altitude_baro_valid:
int altitude_baro; // Altitude in either feet or meters
altitude_unit_t altitude_baro_unit; // the unit used for altitude
int altitude_baro; // Altitude in either feet or meters
altitude_unit_t altitude_baro_unit; // the unit used for altitude
// valid if altitude_geom_valid:
int altitude_geom; // Altitude in either feet or meters
altitude_unit_t altitude_geom_unit; // the unit used for altitude
int altitude_geom; // Altitude in either feet or meters
altitude_unit_t altitude_geom_unit; // the unit used for altitude
// following fields are valid if the corresponding _valid field is set:
int geom_delta; // Difference between geometric and baro alt
float heading; // ground track or heading, degrees (0-359). Reported directly or computed from from EW and NS velocity
heading_type_t heading_type;// how to interpret 'track_or_heading'
float track_rate; // Rate of change of track, degrees/second
float roll; // Roll, degrees, negative is left roll
int geom_delta; // Difference between geometric and baro alt
float heading; // ground track or heading, degrees (0-359). Reported directly or computed from from EW and NS velocity
heading_type_t heading_type; // how to interpret 'track_or_heading'
float track_rate; // Rate of change of track, degrees/second
float roll; // Roll, degrees, negative is left roll
struct {
// Groundspeed, kts, reported directly or computed from from EW and NS velocity
// For surface movement, this has different interpretations for v0 and v2; both
@@ -339,23 +350,23 @@ struct modesMessage {
float v2;
float selected;
} gs;
unsigned ias; // Indicated airspeed, kts
unsigned tas; // True airspeed, kts
double mach; // Mach number
int baro_rate; // Rate of change of barometric altitude, feet/minute
int geom_rate; // Rate of change of geometric (GNSS / INS) altitude, feet/minute
unsigned squawk; // 13 bits identity (Squawk), encoded as 4 hex digits
char callsign[9]; // 8 chars flight number, NUL-terminated
unsigned category; // A0 - D7 encoded as a single hex byte
emergency_t emergency; // emergency/priority status
unsigned ias; // Indicated airspeed, kts
unsigned tas; // True airspeed, kts
double mach; // Mach number
int baro_rate; // Rate of change of barometric altitude, feet/minute
int geom_rate; // Rate of change of geometric (GNSS / INS) altitude, feet/minute
unsigned squawk; // 13 bits identity (Squawk), encoded as 4 hex digits
char callsign[9]; // 8 chars flight number, NUL-terminated
unsigned category; // A0 - D7 encoded as a single hex byte
emergency_t emergency; // emergency/priority status
// valid if cpr_valid
cpr_type_t cpr_type; // The encoding type used (surface, airborne, coarse TIS-B)
unsigned cpr_lat; // Non decoded latitude.
unsigned cpr_lon; // Non decoded longitude.
unsigned cpr_nucp; // NUCp/NIC value implied by message type
cpr_type_t cpr_type; // The encoding type used (surface, airborne, coarse TIS-B)
unsigned cpr_lat; // Non decoded latitude.
unsigned cpr_lon; // Non decoded longitude.
unsigned cpr_nucp; // NUCp/NIC value implied by message type
airground_t airground; // air/ground state
airground_t airground; // air/ground state
// valid if cpr_decoded:
double decoded_lat;
@@ -374,20 +385,20 @@ struct modesMessage {
unsigned gva_valid : 1;
unsigned sda_valid : 1;
unsigned nic_a : 1; // if nic_a_valid
unsigned nic_b : 1; // if nic_b_valid
unsigned nic_c : 1; // if nic_c_valid
unsigned nic_baro : 1; // if nic_baro_valid
unsigned nic_a : 1; // if nic_a_valid
unsigned nic_b : 1; // if nic_b_valid
unsigned nic_c : 1; // if nic_c_valid
unsigned nic_baro : 1; // if nic_baro_valid
unsigned nac_p : 4; // if nac_p_valid
unsigned nac_v : 3; // if nac_v_valid
unsigned nac_p : 4; // if nac_p_valid
unsigned nac_v : 3; // if nac_v_valid
unsigned sil : 2; // if sil_type != SIL_INVALID
unsigned sil : 2; // if sil_type != SIL_INVALID
sil_type_t sil_type;
unsigned gva : 2; // if gva_valid
unsigned gva : 2; // if gva_valid
unsigned sda : 2; // if sda_valid
unsigned sda : 2; // if sda_valid
} accuracy;
// Operational Status
@@ -428,11 +439,11 @@ struct modesMessage {
unsigned qnh_valid : 1;
unsigned modes_valid : 1;
float heading; // heading, degrees (0-359) (could be magnetic or true heading; magnetic recommended)
float heading; // heading, degrees (0-359) (could be magnetic or true heading; magnetic recommended)
heading_type_t heading_type;
unsigned fms_altitude; // FMS selected altitude
unsigned mcp_altitude; // MCP/FCU selected altitude
float qnh; // altimeter setting (QFE or QNH/QNE), millibars
float qnh; // altimeter setting (QFE or QNH/QNE), millibars
nav_altitude_source_t altitude_source;
@@ -440,5 +451,4 @@ struct modesMessage {
} nav;
};
#endif // __DUMP1090_H
#endif // __DUMP1090_H
+82 -80
View File
@@ -36,25 +36,29 @@ namespace ert {
namespace format {
std::string type(Packet::Type value) {
switch(value) {
default:
case Packet::Type::Unknown: return "???";
case Packet::Type::IDM: return "IDM";
case Packet::Type::SCM: return "SCM";
case Packet::Type::SCMPLUS: return "SCM+";
}
switch (value) {
default:
case Packet::Type::Unknown:
return "???";
case Packet::Type::IDM:
return "IDM";
case Packet::Type::SCM:
return "SCM";
case Packet::Type::SCMPLUS:
return "SCM+";
}
}
std::string id(ID value) {
return to_string_dec_uint(value, 10);
return to_string_dec_uint(value, 10);
}
std::string consumption(Consumption value) {
return to_string_dec_uint(value, 10);
return to_string_dec_uint(value, 10);
}
std::string commodity_type(CommodityType value) {
return to_string_dec_uint(value, 2);
return to_string_dec_uint(value, 2);
}
} /* namespace format */
@@ -62,114 +66,112 @@ std::string commodity_type(CommodityType value) {
} /* namespace ert */
void ERTLogger::on_packet(const ert::Packet& packet) {
const auto formatted = packet.symbols_formatted();
std::string entry = ert::format::type(packet.type()) + " " + formatted.data + "/" + formatted.errors;
log_file.write_entry(packet.received_at(), entry);
const auto formatted = packet.symbols_formatted();
std::string entry = ert::format::type(packet.type()) + " " + formatted.data + "/" + formatted.errors;
log_file.write_entry(packet.received_at(), entry);
}
const ERTRecentEntry::Key ERTRecentEntry::invalid_key { };
const ERTRecentEntry::Key ERTRecentEntry::invalid_key{};
void ERTRecentEntry::update(const ert::Packet& packet) {
received_count++;
received_count++;
last_consumption = packet.consumption();
last_consumption = packet.consumption();
}
namespace ui {
template<>
template <>
void RecentEntriesTable<ERTRecentEntries>::draw(
const Entry& entry,
const Rect& target_rect,
Painter& painter,
const Style& style
) {
std::string line = ert::format::id(entry.id) + " " + ert::format::commodity_type(entry.commodity_type) + " " + ert::format::consumption(entry.last_consumption);
const Entry& entry,
const Rect& target_rect,
Painter& painter,
const Style& style) {
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 ) {
line += " +++";
} else {
line += " " + to_string_dec_uint(entry.received_count, 3);
}
if (entry.received_count > 999) {
line += " +++";
} else {
line += " " + to_string_dec_uint(entry.received_count, 3);
}
line.resize(target_rect.width() / 8, ' ');
painter.draw_string(target_rect.location(), style, line);
line.resize(target_rect.width() / 8, ' ');
painter.draw_string(target_rect.location(), style, line);
}
ERTAppView::ERTAppView(NavigationView&) {
baseband::run_image(portapack::spi_flash::image_tag_ert);
baseband::run_image(portapack::spi_flash::image_tag_ert);
add_children({
&field_rf_amp,
&field_lna,
&field_vga,
&rssi,
&recent_entries_view,
});
add_children({
&field_rf_amp,
&field_lna,
&field_vga,
&rssi,
&recent_entries_view,
});
// load app settings
auto rc = settings.load("rx_ert", &app_settings);
if(rc == SETTINGS_OK) {
field_lna.set_value(app_settings.lna);
field_vga.set_value(app_settings.vga);
field_rf_amp.set_value(app_settings.rx_amp);
}
// load app settings
auto rc = settings.load("rx_ert", &app_settings);
if (rc == SETTINGS_OK) {
field_lna.set_value(app_settings.lna);
field_vga.set_value(app_settings.vga);
field_rf_amp.set_value(app_settings.rx_amp);
}
receiver_model.set_tuning_frequency(initial_target_frequency);
receiver_model.set_sampling_rate(sampling_rate);
receiver_model.set_baseband_bandwidth(baseband_bandwidth);
receiver_model.enable(); // Before using radio::enable(), but not updating Ant.DC-Bias.
receiver_model.set_tuning_frequency(initial_target_frequency);
receiver_model.set_sampling_rate(sampling_rate);
receiver_model.set_baseband_bandwidth(baseband_bandwidth);
receiver_model.enable(); // Before using radio::enable(), but not updating Ant.DC-Bias.
/* radio::enable({
initial_target_frequency,
sampling_rate,
baseband_bandwidth,
rf::Direction::Receive,
receiver_model.rf_amp(),
static_cast<int8_t>(receiver_model.lna()),
static_cast<int8_t>(receiver_model.vga()),
}); */
/* radio::enable({
initial_target_frequency,
sampling_rate,
baseband_bandwidth,
rf::Direction::Receive,
receiver_model.rf_amp(),
static_cast<int8_t>(receiver_model.lna()),
static_cast<int8_t>(receiver_model.vga()),
}); */
logger = std::make_unique<ERTLogger>();
if( logger ) {
logger->append( LOG_ROOT_DIR "/ERT.TXT" );
}
logger = std::make_unique<ERTLogger>();
if (logger) {
logger->append(LOG_ROOT_DIR "/ERT.TXT");
}
}
ERTAppView::~ERTAppView() {
// save app settings
settings.save("rx_ert", &app_settings);
// save app settings
settings.save("rx_ert", &app_settings);
receiver_model.disable(); // to switch off all, including DC bias and change flag enabled_
receiver_model.disable(); // to switch off all, including DC bias and change flag enabled_
baseband::shutdown();
baseband::shutdown();
}
void ERTAppView::focus() {
field_vga.focus();
field_vga.focus();
}
void ERTAppView::set_parent_rect(const Rect new_parent_rect) {
View::set_parent_rect(new_parent_rect);
recent_entries_view.set_parent_rect({ 0, header_height, new_parent_rect.width(), new_parent_rect.height() - header_height });
View::set_parent_rect(new_parent_rect);
recent_entries_view.set_parent_rect({0, header_height, new_parent_rect.width(), new_parent_rect.height() - header_height});
}
void ERTAppView::on_packet(const ert::Packet& packet) {
if( logger ) {
logger->on_packet(packet);
}
if (logger) {
logger->on_packet(packet);
}
if( packet.crc_ok() ) {
auto& entry = ::on_packet(recent, ERTRecentEntry::Key { packet.id(), packet.commodity_type() });
entry.update(packet);
recent_entries_view.set_dirty();
}
if (packet.crc_ok()) {
auto& entry = ::on_packet(recent, ERTRecentEntry::Key{packet.id(), packet.commodity_type()});
entry.update(packet);
recent_entries_view.set_dirty();
}
}
void ERTAppView::on_show_list() {
recent_entries_view.hidden(false);
recent_entries_view.focus();
recent_entries_view.hidden(false);
recent_entries_view.focus();
}
} /* namespace ui */
+86 -93
View File
@@ -39,67 +39,65 @@
#include <string>
struct ERTKey {
ert::ID id;
ert::CommodityType commodity_type;
ert::ID id;
ert::CommodityType commodity_type;
constexpr ERTKey(
ert::ID id = ert::invalid_id,
ert::CommodityType commodity_type = ert::invalid_commodity_type
) : id { id },
commodity_type { commodity_type }
{
}
constexpr ERTKey(
ert::ID id = ert::invalid_id,
ert::CommodityType commodity_type = ert::invalid_commodity_type)
: id{id},
commodity_type{commodity_type} {
}
ERTKey( const ERTKey& other ) = default;
ERTKey(const ERTKey& other) = default;
ERTKey& operator=(const ERTKey& other) {
id = other.id;
commodity_type = other.commodity_type;
return *this;
}
ERTKey& operator=(const ERTKey& other) {
id = other.id;
commodity_type = other.commodity_type;
return *this;
}
bool operator==(const ERTKey& other) const {
return (id == other.id) && (commodity_type == other.commodity_type);
}
bool operator==(const ERTKey& other) const {
return (id == other.id) && (commodity_type == other.commodity_type);
}
};
struct ERTRecentEntry {
using Key = ERTKey;
using Key = ERTKey;
// TODO: Is this the right choice of invalid key value?
static const Key invalid_key;
// TODO: Is this the right choice of invalid key value?
static const Key invalid_key;
ert::ID id { ert::invalid_id };
ert::CommodityType commodity_type { ert::invalid_commodity_type };
ert::ID id{ert::invalid_id};
ert::CommodityType commodity_type{ert::invalid_commodity_type};
size_t received_count { 0 };
size_t received_count{0};
ert::Consumption last_consumption { };
ert::Consumption last_consumption{};
ERTRecentEntry(
const Key& key
) : id { key.id },
commodity_type { key.commodity_type }
{
}
ERTRecentEntry(
const Key& key)
: id{key.id},
commodity_type{key.commodity_type} {
}
Key key() const {
return { id, commodity_type };
}
Key key() const {
return {id, commodity_type};
}
void update(const ert::Packet& packet);
void update(const ert::Packet& packet);
};
class ERTLogger {
public:
Optional<File::Error> append(const std::filesystem::path& filename) {
return log_file.append(filename);
}
void on_packet(const ert::Packet& packet);
public:
Optional<File::Error> append(const std::filesystem::path& filename) {
return log_file.append(filename);
}
private:
LogFile log_file { };
void on_packet(const ert::Packet& packet);
private:
LogFile log_file{};
};
using ERTRecentEntries = RecentEntries<ERTRecentEntry>;
@@ -109,72 +107,67 @@ namespace ui {
using ERTRecentEntriesView = RecentEntriesView<ERTRecentEntries>;
class ERTAppView : public View {
public:
static constexpr uint32_t initial_target_frequency = 911600000;
static constexpr uint32_t sampling_rate = 4194304;
static constexpr uint32_t baseband_bandwidth = 2500000;
public:
static constexpr uint32_t initial_target_frequency = 911600000;
static constexpr uint32_t sampling_rate = 4194304;
static constexpr uint32_t baseband_bandwidth = 2500000;
ERTAppView(NavigationView& nav);
~ERTAppView();
ERTAppView(NavigationView& nav);
~ERTAppView();
void set_parent_rect(const Rect new_parent_rect) override;
void set_parent_rect(const Rect new_parent_rect) override;
// Prevent painting of region covered entirely by a child.
// TODO: Add flag to View that specifies view does not need to be cleared before painting.
void paint(Painter&) override { };
// Prevent painting of region covered entirely by a child.
// TODO: Add flag to View that specifies view does not need to be cleared before painting.
void paint(Painter&) override{};
void focus() override;
void focus() override;
std::string title() const override { return "ERT RX"; };
std::string title() const override { return "ERT RX"; };
private:
ERTRecentEntries recent { };
std::unique_ptr<ERTLogger> logger { };
private:
ERTRecentEntries recent{};
std::unique_ptr<ERTLogger> logger{};
// app save settings
std::app_settings settings { };
std::app_settings::AppSettings app_settings { };
// app save settings
std::app_settings settings{};
std::app_settings::AppSettings app_settings{};
const RecentEntriesColumns columns{{
{"ID", 10},
{"Tp", 2},
{"Consumpt", 10},
{"Cnt", 3},
}};
ERTRecentEntriesView recent_entries_view{columns, recent};
const RecentEntriesColumns columns { {
{ "ID", 10 },
{ "Tp", 2 },
{ "Consumpt", 10 },
{ "Cnt", 3 },
} };
ERTRecentEntriesView recent_entries_view { columns, recent };
static constexpr auto header_height = 1 * 16;
static constexpr auto header_height = 1 * 16;
RFAmpField field_rf_amp{
{13 * 8, 0 * 16}};
RFAmpField field_rf_amp {
{ 13 * 8, 0 * 16 }
};
LNAGainField field_lna{
{15 * 8, 0 * 16}};
LNAGainField field_lna {
{ 15 * 8, 0 * 16 }
};
VGAGainField field_vga{
{18 * 8, 0 * 16}};
VGAGainField field_vga {
{ 18 * 8, 0 * 16 }
};
RSSI rssi{
{21 * 8, 0, 6 * 8, 4},
};
RSSI rssi {
{ 21 * 8, 0, 6 * 8, 4 },
};
MessageHandlerRegistration message_handler_packet{
Message::ID::ERTPacket,
[this](Message* const p) {
const auto message = static_cast<const ERTPacketMessage*>(p);
const ert::Packet packet{message->type, message->packet};
this->on_packet(packet);
}};
MessageHandlerRegistration message_handler_packet {
Message::ID::ERTPacket,
[this](Message* const p) {
const auto message = static_cast<const ERTPacketMessage*>(p);
const ert::Packet packet { message->type, message->packet };
this->on_packet(packet);
}
};
void on_packet(const ert::Packet& packet);
void on_show_list();
void on_packet(const ert::Packet& packet);
void on_show_list();
};
} /* namespace ui */
#endif/*__ERT_APP_H__*/
#endif /*__ERT_APP_H__*/
+164 -167
View File
@@ -37,228 +37,225 @@ using namespace portapack;
namespace ui {
void GpsSimAppView::set_ready() {
ready_signal = true;
ready_signal = true;
}
void GpsSimAppView::on_file_changed(std::filesystem::path new_file_path) {
File data_file, info_file;
char file_data[257];
// Get file size
auto data_open_error = data_file.open("/" + new_file_path.string());
if (data_open_error.is_valid()) {
file_error();
return;
}
file_path = new_file_path;
// Get original record frequency if available
std::filesystem::path info_file_path = file_path;
info_file_path.replace_extension(u".TXT");
sample_rate = 500000;
auto info_open_error = info_file.open("/" + info_file_path.string());
if (!info_open_error.is_valid()) {
memset(file_data, 0, 257);
auto read_size = info_file.read(file_data, 256);
if (!read_size.is_error()) {
auto pos1 = strstr(file_data, "center_frequency=");
if (pos1) {
pos1 += 17;
field_frequency.set_value(strtoll(pos1, nullptr, 10));
}
auto pos2 = strstr(file_data, "sample_rate=");
if (pos2) {
pos2 += 12;
sample_rate = strtoll(pos2, nullptr, 10);
}
}
}
text_sample_rate.set(unit_auto_scale(sample_rate, 3, 1) + "Hz");
auto file_size = data_file.size();
auto duration = (file_size * 1000) / (1 * 2 * sample_rate);
progressbar.set_max(file_size / 1024);
text_filename.set(file_path.filename().string().substr(0, 12));
text_duration.set(to_string_time_ms(duration));
button_play.focus();
File data_file, info_file;
char file_data[257];
// Get file size
auto data_open_error = data_file.open("/" + new_file_path.string());
if (data_open_error.is_valid()) {
file_error();
return;
}
file_path = new_file_path;
// Get original record frequency if available
std::filesystem::path info_file_path = file_path;
info_file_path.replace_extension(u".TXT");
sample_rate = 500000;
auto info_open_error = info_file.open("/" + info_file_path.string());
if (!info_open_error.is_valid()) {
memset(file_data, 0, 257);
auto read_size = info_file.read(file_data, 256);
if (!read_size.is_error()) {
auto pos1 = strstr(file_data, "center_frequency=");
if (pos1) {
pos1 += 17;
field_frequency.set_value(strtoll(pos1, nullptr, 10));
}
auto pos2 = strstr(file_data, "sample_rate=");
if (pos2) {
pos2 += 12;
sample_rate = strtoll(pos2, nullptr, 10);
}
}
}
text_sample_rate.set(unit_auto_scale(sample_rate, 3, 1) + "Hz");
auto file_size = data_file.size();
auto duration = (file_size * 1000) / (1 * 2 * sample_rate);
progressbar.set_max(file_size / 1024);
text_filename.set(file_path.filename().string().substr(0, 12));
text_duration.set(to_string_time_ms(duration));
button_play.focus();
}
void GpsSimAppView::on_tx_progress(const uint32_t progress) {
progressbar.set_value(progress);
progressbar.set_value(progress);
}
void GpsSimAppView::focus() {
button_open.focus();
button_open.focus();
}
void GpsSimAppView::file_error() {
nav_.display_modal("Error", "File read error.");
nav_.display_modal("Error", "File read error.");
}
bool GpsSimAppView::is_active() const {
return (bool)replay_thread;
return (bool)replay_thread;
}
void GpsSimAppView::toggle() {
if( is_active() ) {
stop(false);
} else {
start();
}
if (is_active()) {
stop(false);
} else {
start();
}
}
void GpsSimAppView::start() {
stop(false);
stop(false);
std::unique_ptr<stream::Reader> reader;
auto p = std::make_unique<FileReader>();
auto open_error = p->open(file_path);
if( open_error.is_valid() ) {
file_error();
} else {
reader = std::move(p);
}
std::unique_ptr<stream::Reader> reader;
if( reader ) {
button_play.set_bitmap(&bitmap_stop);
baseband::set_sample_rate(sample_rate );
replay_thread = std::make_unique<ReplayThread>(
std::move(reader),
read_size, buffer_count,
&ready_signal,
[](uint32_t return_code) {
ReplayThreadDoneMessage message { return_code };
EventDispatcher::send_message(message);
}
);
}
auto p = std::make_unique<FileReader>();
auto open_error = p->open(file_path);
if (open_error.is_valid()) {
file_error();
} else {
reader = std::move(p);
}
rf_amp =(transmitter_model.rf_amp() ); // recover rf_amp settings applied from ui_transmiter.cpp
if (reader) {
button_play.set_bitmap(&bitmap_stop);
baseband::set_sample_rate(sample_rate);
radio::enable({
receiver_model.tuning_frequency(),
sample_rate ,
baseband_bandwidth,
rf::Direction::Transmit,
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.vga())
});
replay_thread = std::make_unique<ReplayThread>(
std::move(reader),
read_size, buffer_count,
&ready_signal,
[](uint32_t return_code) {
ReplayThreadDoneMessage message{return_code};
EventDispatcher::send_message(message);
});
}
rf_amp = (transmitter_model.rf_amp()); // recover rf_amp settings applied from ui_transmiter.cpp
radio::enable({receiver_model.tuning_frequency(),
sample_rate,
baseband_bandwidth,
rf::Direction::Transmit,
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.vga())});
}
void GpsSimAppView::stop(const bool do_loop) {
if( is_active() )
replay_thread.reset();
if (do_loop && check_loop.value()) {
start();
} else {
radio::disable();
button_play.set_bitmap(&bitmap_play);
}
ready_signal = false;
if (is_active())
replay_thread.reset();
if (do_loop && check_loop.value()) {
start();
} else {
radio::disable();
button_play.set_bitmap(&bitmap_play);
}
ready_signal = false;
}
void GpsSimAppView::handle_replay_thread_done(const uint32_t return_code) {
if (return_code == ReplayThread::END_OF_FILE) {
stop(true);
} else if (return_code == ReplayThread::READ_ERROR) {
stop(false);
file_error();
}
progressbar.set_value(0);
if (return_code == ReplayThread::END_OF_FILE) {
stop(true);
} else if (return_code == ReplayThread::READ_ERROR) {
stop(false);
file_error();
}
progressbar.set_value(0);
}
GpsSimAppView::GpsSimAppView(
NavigationView& nav
) : nav_ (nav)
{
baseband::run_image(portapack::spi_flash::image_tag_gps);
NavigationView& nav)
: nav_(nav) {
baseband::run_image(portapack::spi_flash::image_tag_gps);
add_children({
&button_open,
&text_filename,
&text_sample_rate,
&text_duration,
&progressbar,
&field_frequency,
&tx_view, // now it handles previous rfgain , rfamp.
&check_loop,
&button_play,
&waterfall,
});
field_frequency.set_value(target_frequency());
field_frequency.set_step(receiver_model.frequency_step());
field_frequency.on_change = [this](rf::Frequency f) {
this->on_target_frequency_changed(f);
};
field_frequency.on_edit = [this, &nav]() {
// TODO: Provide separate modal method/scheme?
auto new_view = nav.push<FrequencyKeypadView>(this->target_frequency());
new_view->on_changed = [this](rf::Frequency f) {
this->on_target_frequency_changed(f);
this->field_frequency.set_value(f);
};
};
add_children({
&button_open,
&text_filename,
&text_sample_rate,
&text_duration,
&progressbar,
&field_frequency,
&tx_view, // now it handles previous rfgain , rfamp.
&check_loop,
&button_play,
&waterfall,
});
field_frequency.set_step(5000);
button_play.on_select = [this](ImageButton&) {
this->toggle();
};
button_open.on_select = [this, &nav](Button&) {
auto open_view = nav.push<FileLoadView>(".C8");
open_view->on_changed = [this](std::filesystem::path new_file_path) {
on_file_changed(new_file_path);
};
};
field_frequency.set_value(target_frequency());
field_frequency.set_step(receiver_model.frequency_step());
field_frequency.on_change = [this](rf::Frequency f) {
this->on_target_frequency_changed(f);
};
field_frequency.on_edit = [this, &nav]() {
// TODO: Provide separate modal method/scheme?
auto new_view = nav.push<FrequencyKeypadView>(this->target_frequency());
new_view->on_changed = [this](rf::Frequency f) {
this->on_target_frequency_changed(f);
this->field_frequency.set_value(f);
};
};
field_frequency.set_step(5000);
button_play.on_select = [this](ImageButton&) {
this->toggle();
};
button_open.on_select = [this, &nav](Button&) {
auto open_view = nav.push<FileLoadView>(".C8");
open_view->on_changed = [this](std::filesystem::path new_file_path) {
on_file_changed(new_file_path);
};
};
}
GpsSimAppView::~GpsSimAppView() {
radio::disable();
hackrf::cpld::load_sram_no_verify(); // to leave all RX ok, without ghost signal problem at the exit .
baseband::shutdown(); // better this function at the end, not load_sram() that sometimes produces hang up.
radio::disable();
hackrf::cpld::load_sram_no_verify(); // to leave all RX ok, without ghost signal problem at the exit .
baseband::shutdown(); // better this function at the end, not load_sram() that sometimes produces hang up.
}
void GpsSimAppView::on_hide() {
// TODO: Terrible kludge because widget system doesn't notify Waterfall that
// it's being shown or hidden.
if( is_active() )
stop(false);
waterfall.on_hide();
View::on_hide();
// TODO: Terrible kludge because widget system doesn't notify Waterfall that
// it's being shown or hidden.
if (is_active())
stop(false);
waterfall.on_hide();
View::on_hide();
}
void GpsSimAppView::set_parent_rect(const Rect new_parent_rect) {
View::set_parent_rect(new_parent_rect);
View::set_parent_rect(new_parent_rect);
const ui::Rect waterfall_rect { 0, header_height, new_parent_rect.width(), new_parent_rect.height() - header_height };
waterfall.set_parent_rect(waterfall_rect);
const ui::Rect waterfall_rect{0, header_height, new_parent_rect.width(), new_parent_rect.height() - header_height};
waterfall.set_parent_rect(waterfall_rect);
}
void GpsSimAppView::on_target_frequency_changed(rf::Frequency f) {
set_target_frequency(f);
set_target_frequency(f);
}
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 {
return persistent_memory::tuned_frequency();
return persistent_memory::tuned_frequency();
}
} /* namespace ui */
+96 -105
View File
@@ -24,8 +24,8 @@
#ifndef __GPS_SIM_APP_HPP__
#define __GPS_SIM_APP_HPP__
#define SHORT_UI true
#define NORMAL_UI false
#define SHORT_UI true
#define NORMAL_UI false
#include "ui_widget.hpp"
#include "ui_navigation.hpp"
@@ -40,120 +40,111 @@
namespace ui {
class GpsSimAppView : public View {
public:
GpsSimAppView(NavigationView& nav);
~GpsSimAppView();
public:
GpsSimAppView(NavigationView& nav);
~GpsSimAppView();
void on_hide() override;
void set_parent_rect(const Rect new_parent_rect) override;
void focus() override;
void on_hide() override;
void set_parent_rect(const Rect new_parent_rect) override;
void focus() override;
std::string title() const override { return "GPS Sim TX"; };
private:
NavigationView& nav_;
static constexpr ui::Dim header_height = 3 * 16;
uint32_t sample_rate = 0;
int32_t tx_gain { 47 };
bool rf_amp { true }; // aux private var to store temporal, same as Replay App rf_amp user selection.
static constexpr uint32_t baseband_bandwidth = 3000000; //filter bandwidth
const size_t read_size { 16384 };
const size_t buffer_count { 3 };
std::string title() const override { return "GPS Sim TX"; };
void on_file_changed(std::filesystem::path new_file_path);
void on_target_frequency_changed(rf::Frequency f);
void on_tx_progress(const uint32_t progress);
void set_target_frequency(const rf::Frequency new_value);
rf::Frequency target_frequency() const;
private:
NavigationView& nav_;
void toggle();
void start();
void stop(const bool do_loop);
bool is_active() const;
void set_ready();
void handle_replay_thread_done(const uint32_t return_code);
void file_error();
static constexpr ui::Dim header_height = 3 * 16;
std::filesystem::path file_path { };
std::unique_ptr<ReplayThread> replay_thread { };
bool ready_signal { false };
uint32_t sample_rate = 0;
int32_t tx_gain{47};
bool rf_amp{true}; // aux private var to store temporal, same as Replay App rf_amp user selection.
static constexpr uint32_t baseband_bandwidth = 3000000; // filter bandwidth
const size_t read_size{16384};
const size_t buffer_count{3};
Button button_open {
{ 0 * 8, 0 * 16, 10 * 8, 2 * 16 },
"Open file"
};
Text text_filename {
{ 11 * 8, 0 * 16, 12 * 8, 16 },
"-"
};
Text text_sample_rate {
{ 24 * 8, 0 * 16, 6 * 8, 16 },
"-"
};
Text text_duration {
{ 11 * 8, 1 * 16, 6 * 8, 16 },
"-"
};
ProgressBar progressbar {
{ 18 * 8, 1 * 16, 12 * 8, 16 }
};
FrequencyField field_frequency {
{ 0 * 8, 2 * 16 },
};
void on_file_changed(std::filesystem::path new_file_path);
void on_target_frequency_changed(rf::Frequency f);
void on_tx_progress(const uint32_t progress);
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)
// 10*8, 2*8, NORMAL_UI // x(columns), y (line) position. (Used in Mic App)
};
void set_target_frequency(const rf::Frequency new_value);
rf::Frequency target_frequency() const;
Checkbox check_loop {
{ 21 * 8, 2 * 16 },
4,
"Loop",
true
};
ImageButton button_play {
{ 28 * 8, 2 * 16, 2 * 8, 1 * 16 },
&bitmap_play,
Color::green(),
Color::black()
};
void toggle();
void start();
void stop(const bool do_loop);
bool is_active() const;
void set_ready();
void handle_replay_thread_done(const uint32_t return_code);
void file_error();
spectrum::WaterfallWidget waterfall { };
std::filesystem::path file_path{};
std::unique_ptr<ReplayThread> replay_thread{};
bool ready_signal{false};
MessageHandlerRegistration message_handler_replay_thread_error {
Message::ID::ReplayThreadDone,
[this](const Message* const p) {
const auto message = *reinterpret_cast<const ReplayThreadDoneMessage*>(p);
this->handle_replay_thread_done(message.return_code);
}
};
MessageHandlerRegistration message_handler_fifo_signal {
Message::ID::RequestSignal,
[this](const Message* const p) {
const auto message = static_cast<const RequestSignalMessage*>(p);
if (message->signal == RequestSignalMessage::Signal::FillRequest) {
this->set_ready();
}
}
};
MessageHandlerRegistration message_handler_tx_progress {
Message::ID::TXProgress,
[this](const Message* const p) {
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
this->on_tx_progress(message.progress);
}
};
Button button_open{
{0 * 8, 0 * 16, 10 * 8, 2 * 16},
"Open file"};
Text text_filename{
{11 * 8, 0 * 16, 12 * 8, 16},
"-"};
Text text_sample_rate{
{24 * 8, 0 * 16, 6 * 8, 16},
"-"};
Text text_duration{
{11 * 8, 1 * 16, 6 * 8, 16},
"-"};
ProgressBar progressbar{
{18 * 8, 1 * 16, 12 * 8, 16}};
FrequencyField field_frequency{
{0 * 8, 2 * 16},
};
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)
// 10*8, 2*8, NORMAL_UI // x(columns), y (line) position. (Used in Mic App)
};
Checkbox check_loop{
{21 * 8, 2 * 16},
4,
"Loop",
true};
ImageButton button_play{
{28 * 8, 2 * 16, 2 * 8, 1 * 16},
&bitmap_play,
Color::green(),
Color::black()};
spectrum::WaterfallWidget waterfall{};
MessageHandlerRegistration message_handler_replay_thread_error{
Message::ID::ReplayThreadDone,
[this](const Message* const p) {
const auto message = *reinterpret_cast<const ReplayThreadDoneMessage*>(p);
this->handle_replay_thread_done(message.return_code);
}};
MessageHandlerRegistration message_handler_fifo_signal{
Message::ID::RequestSignal,
[this](const Message* const p) {
const auto message = static_cast<const RequestSignalMessage*>(p);
if (message->signal == RequestSignalMessage::Signal::FillRequest) {
this->set_ready();
}
}};
MessageHandlerRegistration message_handler_tx_progress{
Message::ID::TXProgress,
[this](const Message* const p) {
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
this->on_tx_progress(message.progress);
}};
};
} /* namespace ui */
#endif/*__GPS_SIM_APP_HPP__*/
#endif /*__GPS_SIM_APP_HPP__*/
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More