mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-10-01 01:26:06 -04:00
AFSK RX works (only Bell202 for now)
AFSK RX always logs to file Removed frequency and bw settings from modem setup view Updated binary Bugfix: Binary display shifted one bit Bugfix: Frequency manager views freezing if SD card not present Bugfix: Menuview blinking arrow not showing up at the right position Bugfix: Freeze if console written to while it's hidden Broken: LCR TX, needs UI update
This commit is contained in:
parent
42439d1885
commit
950bc2b1d2
@ -117,9 +117,12 @@ void set_sstv_data(const uint8_t vis_code, const uint32_t pixel_duration) {
|
||||
send_message(&message);
|
||||
}
|
||||
|
||||
void set_afsk(const uint32_t bitrate) {
|
||||
void set_afsk(const uint32_t baudrate, const uint32_t word_length, const uint32_t trigger_value, const bool trigger_word) {
|
||||
const AFSKRxConfigureMessage message {
|
||||
bitrate
|
||||
baudrate,
|
||||
word_length,
|
||||
trigger_value,
|
||||
trigger_word
|
||||
};
|
||||
send_message(&message);
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ void set_pwmrssi(int32_t avg, bool enabled);
|
||||
void set_afsk_data(const uint32_t afsk_samples_per_bit, const uint32_t afsk_phase_inc_mark, const uint32_t afsk_phase_inc_space,
|
||||
const uint8_t afsk_repeat, const uint32_t afsk_bw, const uint8_t symbol_count);
|
||||
void kill_afsk();
|
||||
void set_afsk(const uint32_t bitrate);
|
||||
void set_afsk(const uint32_t baudrate, const uint32_t word_length, const uint32_t trigger_value, const bool trigger_word);
|
||||
void set_ook_data(const uint32_t stream_length, const uint32_t samples_per_bit, const uint8_t repeat,
|
||||
const uint32_t pause_symbols);
|
||||
void set_fsk_data(const uint32_t stream_length, const uint32_t samples_per_bit, const uint32_t shift,
|
||||
|
@ -32,6 +32,8 @@
|
||||
//BUG: SCANNER Lock on frequency, if frequency jump, still locked on first one
|
||||
//BUG: SCANNER Multiple slices
|
||||
|
||||
//TODO: Frequency and bw settings were removed from modemsetup, put those back in LCR TX
|
||||
//TODO: Use separate thread for scanning in LCR TX
|
||||
//TODO: REPLAY Convert C16 to C8 on M0 core
|
||||
//TODO: Use TabView
|
||||
//TODO: De bruijn sequence scanner for encoders
|
||||
|
@ -79,4 +79,41 @@ void generate_data(const std::string& in_message, uint16_t * out_data) {
|
||||
out_data[bytes] = 0; // End marker
|
||||
}
|
||||
|
||||
// This accepts a word with start and stop bits removed !
|
||||
uint32_t deframe_word(uint32_t raw_word) {
|
||||
serial_format_t serial_format;
|
||||
uint32_t parity, cur_bit, deframed_word { 0 };
|
||||
size_t bit, bits;
|
||||
|
||||
serial_format = persistent_memory::serial_format();
|
||||
|
||||
/*if (serial_format.parity == ODD)
|
||||
parity = 1;
|
||||
else
|
||||
parity = 0;*/
|
||||
|
||||
bits = serial_format.data_bits;
|
||||
|
||||
// Ignore parity for now
|
||||
if (serial_format.parity)
|
||||
raw_word >>= 1;
|
||||
|
||||
if (serial_format.bit_order == LSB_FIRST) {
|
||||
// Reverse data bits
|
||||
for (bit = 0; bit < bits; bit++) {
|
||||
cur_bit = raw_word & 1;
|
||||
|
||||
deframed_word <<= 1;
|
||||
deframed_word |= cur_bit;
|
||||
|
||||
//parity += cur_bit;
|
||||
|
||||
raw_word >>= 1;
|
||||
}
|
||||
|
||||
return deframed_word;
|
||||
} else
|
||||
return raw_word;
|
||||
}
|
||||
|
||||
} /* namespace modems */
|
||||
|
@ -31,16 +31,16 @@ namespace modems {
|
||||
|
||||
#define MODEM_DEF_COUNT 7
|
||||
|
||||
enum modulation_enum {
|
||||
enum ModemModulation {
|
||||
AFSK = 0,
|
||||
FSK,
|
||||
PSK,
|
||||
SSB
|
||||
AM // SSB
|
||||
};
|
||||
|
||||
struct modem_def_t {
|
||||
std::string name;
|
||||
modulation_enum modulation;
|
||||
ModemModulation modulation;
|
||||
uint16_t mark_freq;
|
||||
uint16_t space_freq;
|
||||
uint16_t baudrate;
|
||||
@ -52,11 +52,12 @@ const modem_def_t modem_defs[MODEM_DEF_COUNT] = {
|
||||
{ "V21", AFSK, 980, 1180, 300 },
|
||||
{ "V23 M1", AFSK, 1300, 1700, 600 },
|
||||
{ "V23 M2", AFSK, 1300, 2100, 1200 },
|
||||
{ "RTTY US", SSB, 2295, 2125, 45 },
|
||||
{ "RTTY EU", SSB, 2125, 1955, 45 }
|
||||
{ "RTTY US", AM, 2295, 2125, 45 },
|
||||
{ "RTTY EU", AM, 2125, 1955, 45 }
|
||||
};
|
||||
|
||||
void generate_data(const std::string& in_message, uint16_t * out_data);
|
||||
uint32_t deframe_word(uint32_t raw_word);
|
||||
|
||||
} /* namespace modems */
|
||||
|
||||
|
@ -23,8 +23,6 @@
|
||||
#include "pocsag_app.hpp"
|
||||
|
||||
#include "baseband_api.hpp"
|
||||
|
||||
#include "portapack.hpp"
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
|
||||
using namespace portapack;
|
||||
|
@ -39,11 +39,8 @@ namespace serializer {
|
||||
* Diff M.: ...
|
||||
*/
|
||||
|
||||
uint8_t symbol_count() {
|
||||
serial_format_t serial_format;
|
||||
uint8_t count;
|
||||
|
||||
serial_format = persistent_memory::serial_format();
|
||||
size_t symbol_count(const serial_format_t& serial_format) {
|
||||
size_t count;
|
||||
|
||||
count = 1 + serial_format.data_bits; // Start
|
||||
if (serial_format.parity) count++;
|
||||
|
@ -21,16 +21,14 @@
|
||||
*/
|
||||
|
||||
#include "ui.hpp"
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
|
||||
#ifndef __SERIALIZER_H__
|
||||
#define __SERIALIZER_H__
|
||||
|
||||
namespace serializer {
|
||||
|
||||
uint8_t symbol_count();
|
||||
|
||||
enum parity_enum : uint8_t {
|
||||
NONE = 0,
|
||||
EVEN = 1,
|
||||
@ -49,6 +47,8 @@ struct serial_format_t {
|
||||
order_enum bit_order;
|
||||
};
|
||||
|
||||
size_t symbol_count(const serial_format_t& serial_format);
|
||||
|
||||
/*{ "7-Even-1 R", "7E1", 7, EVEN, 1, false, false },
|
||||
{ "7E1 LUT ", "7Ea", 7, EVEN, 1, true, true },
|
||||
{ "7-Odd-1 ", "7o1", 7, ODD, 1, true, false },
|
||||
|
@ -61,7 +61,7 @@ std::string to_string_bin(
|
||||
{
|
||||
char p[33];
|
||||
for (uint8_t c = 0; c < l; c++) {
|
||||
if (n & (1 << (l - c)))
|
||||
if (n & (1 << (l - 1 - c)))
|
||||
p[c] = '1';
|
||||
else
|
||||
p[c] = '0';
|
||||
|
@ -25,13 +25,9 @@
|
||||
|
||||
#include "rtc_time.hpp"
|
||||
#include "string_format.hpp"
|
||||
#include "portapack.hpp"
|
||||
#include "baseband_api.hpp"
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
|
||||
#include <cstring>
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace portapack;
|
||||
|
||||
namespace ui {
|
||||
|
@ -21,11 +21,24 @@
|
||||
*/
|
||||
|
||||
#include "ui_afsk_rx.hpp"
|
||||
#include "baseband_api.hpp"
|
||||
#include "ui_modemsetup.hpp"
|
||||
|
||||
//#include "string_format.hpp"
|
||||
#include "modems.hpp"
|
||||
#include "audio.hpp"
|
||||
#include "rtc_time.hpp"
|
||||
#include "baseband_api.hpp"
|
||||
#include "string_format.hpp"
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
|
||||
using namespace portapack;
|
||||
using namespace modems;
|
||||
|
||||
void AFSKLogger::log_raw_data(const std::string& data) {
|
||||
rtc::RTC datetime;
|
||||
rtcGetTime(&RTCD1, &datetime);
|
||||
|
||||
log_file.write_entry(datetime, data);
|
||||
}
|
||||
|
||||
namespace ui {
|
||||
|
||||
@ -37,10 +50,6 @@ void AFSKRxView::update_freq(rf::Frequency f) {
|
||||
receiver_model.set_tuning_frequency(f);
|
||||
}
|
||||
|
||||
void AFSKRxView::on_bitrate_changed(const uint32_t new_bitrate) {
|
||||
baseband::set_afsk(new_bitrate);
|
||||
}
|
||||
|
||||
AFSKRxView::AFSKRxView(NavigationView& nav) {
|
||||
baseband::run_image(portapack::spi_flash::image_tag_afsk_rx);
|
||||
|
||||
@ -51,16 +60,24 @@ AFSKRxView::AFSKRxView(NavigationView& nav) {
|
||||
&field_lna,
|
||||
&field_vga,
|
||||
&field_frequency,
|
||||
&options_bitrate,
|
||||
&text_debug,
|
||||
&button_modem_setup,
|
||||
&console
|
||||
});
|
||||
|
||||
//receiver_model.set_sampling_rate(3072000);
|
||||
//receiver_model.set_baseband_bandwidth(1750000);
|
||||
//receiver_model.enable();
|
||||
// Auto-configure modem for LCR RX (will be removed later)
|
||||
update_freq(462713300); // 162950000
|
||||
auto def_bell202 = &modem_defs[0];
|
||||
persistent_memory::set_modem_baudrate(def_bell202->baudrate);
|
||||
serial_format_t serial_format;
|
||||
serial_format.data_bits = 7;
|
||||
serial_format.parity = EVEN;
|
||||
serial_format.stop_bits = 1;
|
||||
serial_format.bit_order = LSB_FIRST;
|
||||
persistent_memory::set_serial_format(serial_format);
|
||||
|
||||
field_frequency.set_value(receiver_model.tuning_frequency());
|
||||
field_frequency.set_step(receiver_model.frequency_step());
|
||||
field_frequency.set_step(100);
|
||||
field_frequency.on_change = [this](rf::Frequency f) {
|
||||
update_freq(f);
|
||||
};
|
||||
@ -72,19 +89,69 @@ AFSKRxView::AFSKRxView(NavigationView& nav) {
|
||||
field_frequency.set_value(f);
|
||||
};
|
||||
};
|
||||
|
||||
options_bitrate.on_change = [this](size_t, OptionsField::value_t v) {
|
||||
on_bitrate_changed(v);
|
||||
|
||||
button_modem_setup.on_select = [&nav](Button&) {
|
||||
nav.push<ModemSetupView>();
|
||||
};
|
||||
options_bitrate.set_selected_index(1); // 1200bps
|
||||
|
||||
logger = std::make_unique<AFSKLogger>();
|
||||
if (logger)
|
||||
logger->append("AFSK_LOG.TXT");
|
||||
|
||||
// Auto-configure modem for LCR RX (will be removed later)
|
||||
baseband::set_afsk(persistent_memory::modem_baudrate(), 8, 0, false);
|
||||
|
||||
audio::set_rate(audio::Rate::Hz_24000);
|
||||
audio::output::start();
|
||||
|
||||
receiver_model.set_sampling_rate(3072000);
|
||||
receiver_model.set_baseband_bandwidth(1750000);
|
||||
receiver_model.enable();
|
||||
}
|
||||
|
||||
void AFSKRxView::on_data(uint_fast8_t byte) {
|
||||
std::string str_byte(1, byte);
|
||||
console.write(str_byte);
|
||||
void AFSKRxView::on_data(uint32_t value, bool is_data) {
|
||||
std::string str_byte = "\x1B";
|
||||
|
||||
str_byte += (char)((console_color & 3) + 9);
|
||||
|
||||
if (is_data) {
|
||||
//value = deframe_word(value);
|
||||
|
||||
value &= 0xFF; // ABCDEFGH
|
||||
value = ((value & 0xF0) >> 4) | ((value & 0x0F) << 4); // EFGHABCD
|
||||
value = ((value & 0xCC) >> 2) | ((value & 0x33) << 2); // GHEFCDAB
|
||||
value = ((value & 0xAA) >> 1) | ((value & 0x55) << 1); // HGFEDCBA
|
||||
value &= 0x7F;
|
||||
|
||||
if ((value >= 32) && (value < 127))
|
||||
str_byte += (char)value ; // Printable
|
||||
else
|
||||
str_byte += "[" + to_string_hex(value, 2) + "]"; // Not printable
|
||||
|
||||
//str_byte = to_string_bin(value & 0xFF, 8) + " ";
|
||||
|
||||
console.write(str_byte);
|
||||
|
||||
if (logger) str_log += str_byte;
|
||||
|
||||
if ((value != 0x7F) && (prev_value == 0x7F)) {
|
||||
console.writeln("");
|
||||
console_color++;
|
||||
|
||||
if (logger) {
|
||||
logger->log_raw_data(str_log);
|
||||
str_log = "";
|
||||
}
|
||||
}
|
||||
prev_value = value;
|
||||
} else {
|
||||
// Baudrate estimation
|
||||
text_debug.set("~" + to_string_dec_uint(value));
|
||||
}
|
||||
}
|
||||
|
||||
AFSKRxView::~AFSKRxView() {
|
||||
audio::output::stop();
|
||||
receiver_model.disable();
|
||||
baseband::shutdown();
|
||||
}
|
||||
|
@ -26,9 +26,22 @@
|
||||
#include "ui.hpp"
|
||||
#include "ui_navigation.hpp"
|
||||
#include "ui_receiver.hpp"
|
||||
#include "ui_widget.hpp"
|
||||
|
||||
#include "log_file.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
class AFSKLogger {
|
||||
public:
|
||||
Optional<File::Error> append(const std::string& filename) {
|
||||
return log_file.append(filename);
|
||||
}
|
||||
|
||||
void log_raw_data(const std::string& data);
|
||||
|
||||
private:
|
||||
LogFile log_file { };
|
||||
};
|
||||
|
||||
namespace ui {
|
||||
|
||||
class AFSKRxView : public View {
|
||||
@ -41,7 +54,11 @@ public:
|
||||
std::string title() const override { return "AFSK RX (beta)"; };
|
||||
|
||||
private:
|
||||
void on_data(uint_fast8_t byte);
|
||||
void on_data(uint32_t value, bool is_data);
|
||||
|
||||
uint8_t console_color { 0 };
|
||||
uint32_t prev_value { 0 };
|
||||
std::string str_log { "" };
|
||||
|
||||
RFAmpField field_rf_amp {
|
||||
{ 13 * 8, 0 * 16 }
|
||||
@ -60,33 +77,34 @@ private:
|
||||
};
|
||||
|
||||
FrequencyField field_frequency {
|
||||
{ 0 * 8, 0 * 8 },
|
||||
{ 0 * 8, 0 * 16 },
|
||||
};
|
||||
OptionsField options_bitrate {
|
||||
{ 12 * 8, 21 },
|
||||
7,
|
||||
{
|
||||
{ "600bps ", 600 },
|
||||
{ "1200bps", 1200 },
|
||||
{ "2400bps", 2400 }
|
||||
}
|
||||
|
||||
Text text_debug {
|
||||
{ 0 * 8, 1 * 16, 10 * 8, 16 },
|
||||
"DEBUG"
|
||||
};
|
||||
|
||||
|
||||
Button button_modem_setup {
|
||||
{ 12 * 8, 1 * 16, 96, 24 },
|
||||
"Modem setup"
|
||||
};
|
||||
|
||||
Console console {
|
||||
{ 0, 4 * 16, 240, 240 }
|
||||
{ 0, 3 * 16, 240, 240 }
|
||||
};
|
||||
|
||||
void update_freq(rf::Frequency f);
|
||||
|
||||
void on_bitrate_changed(const uint32_t new_bitrate);
|
||||
|
||||
void on_data_afsk(const AFSKDataMessage& message);
|
||||
|
||||
std::unique_ptr<AFSKLogger> logger { };
|
||||
|
||||
MessageHandlerRegistration message_handler_packet {
|
||||
Message::ID::AFSKData,
|
||||
[this](Message* const p) {
|
||||
const auto message = static_cast<const AFSKDataMessage*>(p);
|
||||
this->on_data(message->byte);
|
||||
this->on_data(message->value, message->is_data);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -177,7 +177,7 @@ private:
|
||||
void start_tx(const bool scan);
|
||||
void on_txdone(int n, const bool txdone);
|
||||
|
||||
const Style style_address {
|
||||
/*const Style style_address {
|
||||
.font = font::fixed_8x16,
|
||||
.background = Color::black(),
|
||||
.foreground = Color::red(),
|
||||
@ -186,7 +186,7 @@ private:
|
||||
.font = font::fixed_8x16,
|
||||
.background = Color::black(),
|
||||
.foreground = Color::blue(),
|
||||
};
|
||||
};*/
|
||||
|
||||
Rect view_rect = { 0, 4 * 8, 240, 168 };
|
||||
|
||||
|
@ -30,31 +30,28 @@ using namespace portapack;
|
||||
namespace ui {
|
||||
|
||||
FreqManBaseView::FreqManBaseView(
|
||||
NavigationView& nav,
|
||||
Widget& default_focus_widget
|
||||
) : nav_ (nav),
|
||||
default_focus_widget_ (default_focus_widget)
|
||||
NavigationView& nav
|
||||
) : nav_ (nav)
|
||||
{
|
||||
file_list = get_freqman_files();
|
||||
|
||||
if (!file_list.size()) {
|
||||
if (!file_list.size())
|
||||
error_ = ERROR_NOFILES;
|
||||
return;
|
||||
}
|
||||
|
||||
add_children({
|
||||
&label_category,
|
||||
&options_category,
|
||||
&button_exit
|
||||
});
|
||||
|
||||
// Populate categories OptionsField
|
||||
populate_categories();
|
||||
if (file_list.size()) {
|
||||
add_child(&options_category);
|
||||
populate_categories();
|
||||
}
|
||||
|
||||
// Default function
|
||||
on_change_category = [this](int32_t category_id) {
|
||||
change_category(category_id);
|
||||
};
|
||||
//change_category(0);
|
||||
|
||||
button_exit.on_select = [this, &nav](Button&) {
|
||||
nav.pop();
|
||||
@ -62,26 +59,21 @@ FreqManBaseView::FreqManBaseView(
|
||||
};
|
||||
|
||||
void FreqManBaseView::focus() {
|
||||
/*if (error_ == ERROR_ACCESS) {
|
||||
nav_.display_modal("Error", "File acces error", ABORT, nullptr);
|
||||
} else if (error_ == ERROR_DUPLICATE) {
|
||||
nav_.display_modal("Error", "Frequency already saved", INFO, nullptr);
|
||||
error_ = NO_ERROR;
|
||||
}*/
|
||||
button_exit.focus();
|
||||
|
||||
if (error_ == ERROR_NOFILES) {
|
||||
if (error_ == ERROR_ACCESS) {
|
||||
nav_.display_modal("Error", "File acces error", ABORT, nullptr);
|
||||
} else if (error_ == ERROR_NOFILES) {
|
||||
nav_.display_modal("Error", "No database files", ABORT, nullptr);
|
||||
} else {
|
||||
default_focus_widget_.focus();
|
||||
options_category.focus();
|
||||
}
|
||||
}
|
||||
|
||||
bool FreqManBaseView::populate_categories() {
|
||||
size_t n;
|
||||
|
||||
categories.clear();
|
||||
|
||||
for (n = 0; n < file_list.size(); n++)
|
||||
for (size_t n = 0; n < file_list.size(); n++)
|
||||
categories.emplace_back(std::make_pair(file_list[n], n));
|
||||
|
||||
options_category.set_options(categories);
|
||||
@ -96,10 +88,13 @@ bool FreqManBaseView::populate_categories() {
|
||||
}
|
||||
|
||||
void FreqManBaseView::change_category(int32_t category_id) {
|
||||
|
||||
if (!file_list.size()) return;
|
||||
|
||||
current_category_id = category_id;
|
||||
|
||||
if (!load_freqman_file(file_list[current_category_id], database))
|
||||
error_ = ERROR_ACCESS; // Todo
|
||||
error_ = ERROR_ACCESS;
|
||||
else
|
||||
refresh_list();
|
||||
}
|
||||
@ -158,7 +153,7 @@ FrequencySaveView::~FrequencySaveView() {
|
||||
FrequencySaveView::FrequencySaveView(
|
||||
NavigationView& nav,
|
||||
const rf::Frequency value
|
||||
) : FreqManBaseView(nav, options_category),
|
||||
) : FreqManBaseView(nav),
|
||||
value_ (value)
|
||||
{
|
||||
desc_buffer.reserve(28);
|
||||
@ -204,7 +199,7 @@ void FrequencyLoadView::refresh_widgets(const bool v) {
|
||||
|
||||
FrequencyLoadView::FrequencyLoadView(
|
||||
NavigationView& nav
|
||||
) : FreqManBaseView(nav, options_category)
|
||||
) : FreqManBaseView(nav)
|
||||
{
|
||||
on_refresh_widgets = [this](bool v) {
|
||||
refresh_widgets(v);
|
||||
@ -278,7 +273,7 @@ FrequencyManagerView::~FrequencyManagerView() {
|
||||
|
||||
FrequencyManagerView::FrequencyManagerView(
|
||||
NavigationView& nav
|
||||
) : FreqManBaseView(nav, options_category)
|
||||
) : FreqManBaseView(nav)
|
||||
{
|
||||
on_refresh_widgets = [this](bool v) {
|
||||
refresh_widgets(v);
|
||||
|
@ -35,7 +35,7 @@ namespace ui {
|
||||
class FreqManBaseView : public View {
|
||||
public:
|
||||
FreqManBaseView(
|
||||
NavigationView& nav, Widget& default_focus_widget
|
||||
NavigationView& nav
|
||||
);
|
||||
|
||||
void focus() override;
|
||||
@ -48,7 +48,6 @@ protected:
|
||||
|
||||
NavigationView& nav_;
|
||||
freqman_error error_ { NO_ERROR };
|
||||
Widget& default_focus_widget_;
|
||||
options_t categories { };
|
||||
std::function<void(int32_t category_id)> on_change_category { nullptr };
|
||||
std::function<void(void)> on_select_frequency { nullptr };
|
||||
|
@ -23,15 +23,12 @@
|
||||
#include "ui_lcr.hpp"
|
||||
#include "ui_modemsetup.hpp"
|
||||
|
||||
#include "modems.hpp"
|
||||
#include "lcr.hpp"
|
||||
#include "modems.hpp"
|
||||
#include "baseband_api.hpp"
|
||||
#include "string_format.hpp"
|
||||
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
|
||||
#include <cstring>
|
||||
#include <stdio.h>
|
||||
#include "serializer.hpp"
|
||||
|
||||
using namespace portapack;
|
||||
|
||||
@ -47,7 +44,6 @@ LCRView::~LCRView() {
|
||||
}
|
||||
|
||||
void LCRView::paint(Painter& painter) {
|
||||
size_t i;
|
||||
std::string final_str;
|
||||
|
||||
static constexpr Style style_orange {
|
||||
@ -61,7 +57,7 @@ void LCRView::paint(Painter& painter) {
|
||||
static_cast<Coord>(68)
|
||||
};
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
for (size_t i = 0; i < 5; i++) {
|
||||
painter.draw_string(
|
||||
screen_pos() + offset,
|
||||
style_orange,
|
||||
@ -181,7 +177,7 @@ void LCRView::start_tx(const bool scan) {
|
||||
persistent_memory::afsk_space_freq(),
|
||||
repeats,
|
||||
persistent_memory::modem_bw(),
|
||||
serializer::symbol_count()
|
||||
serializer::symbol_count(persistent_memory::serial_format())
|
||||
);
|
||||
}
|
||||
|
||||
@ -201,7 +197,7 @@ LCRView::LCRView(NavigationView& nav) {
|
||||
&text_recap,
|
||||
&options_ec,
|
||||
&button_setrgsb,
|
||||
&button_txsetup,
|
||||
&button_modem_setup,
|
||||
&text_status,
|
||||
&progress,
|
||||
&button_transmit,
|
||||
@ -266,7 +262,7 @@ LCRView::LCRView(NavigationView& nav) {
|
||||
text_prompt(nav, &rgsb, 4);
|
||||
};
|
||||
|
||||
button_txsetup.on_select = [&nav](Button&) {
|
||||
button_modem_setup.on_select = [&nav](Button&) {
|
||||
nav.push<ModemSetupView>();
|
||||
};
|
||||
|
||||
@ -294,11 +290,9 @@ LCRView::LCRView(NavigationView& nav) {
|
||||
};
|
||||
|
||||
button_clear.on_select = [this, &nav](Button&) {
|
||||
size_t n;
|
||||
|
||||
if (tx_mode == IDLE) {
|
||||
options_ec.set_selected_index(0); // Auto
|
||||
for (n = 0; n < 5; n++) {
|
||||
for (size_t n = 0; n < 5; n++) {
|
||||
litteral[n] = " ";
|
||||
checkboxes[n].set_value(true);
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ private:
|
||||
{ 8, 24, 80, 32 },
|
||||
"RGSB"
|
||||
};
|
||||
Button button_txsetup {
|
||||
Button button_modem_setup {
|
||||
{ 13 * 8, 24, 128, 32 },
|
||||
"Modem setup"
|
||||
};
|
||||
|
@ -93,10 +93,7 @@ MenuView::MenuView(
|
||||
bool keep_highlight
|
||||
) : keep_highlight_ { keep_highlight }
|
||||
{
|
||||
View::set_parent_rect(new_parent_rect);
|
||||
|
||||
displayed_max_ = (parent_rect().size().height() / 24);
|
||||
arrow_more.set_parent_rect( { 228, (Coord)(displayed_max_ * item_height), 8, 8 } );
|
||||
set_parent_rect(new_parent_rect);
|
||||
|
||||
set_focusable(true);
|
||||
|
||||
@ -116,6 +113,14 @@ MenuView::~MenuView() {
|
||||
}
|
||||
}
|
||||
|
||||
void MenuView::set_parent_rect(const Rect new_parent_rect) {
|
||||
|
||||
View::set_parent_rect(new_parent_rect);
|
||||
|
||||
displayed_max_ = (parent_rect().size().height() / 24);
|
||||
arrow_more.set_parent_rect( { 228, (Coord)(displayed_max_ * item_height), 8, 8 } );
|
||||
}
|
||||
|
||||
void MenuView::on_tick_second() {
|
||||
if (more_ && blink_)
|
||||
arrow_more.set_foreground(Color::white());
|
||||
|
@ -84,11 +84,11 @@ public:
|
||||
size_t highlighted() const;
|
||||
bool set_highlighted(int32_t new_value);
|
||||
|
||||
void set_parent_rect(const Rect new_parent_rect) override;
|
||||
void on_focus() override;
|
||||
void on_blur() override;
|
||||
bool on_key(const KeyEvent event) override;
|
||||
bool on_encoder(const EncoderEvent event) override;
|
||||
|
||||
|
||||
private:
|
||||
void update_items();
|
||||
|
@ -29,42 +29,36 @@
|
||||
#include "portapack_shared_memory.hpp"
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
|
||||
#include <cstring>
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace portapack;
|
||||
using namespace modems;
|
||||
|
||||
namespace ui {
|
||||
|
||||
void ModemSetupView::focus() {
|
||||
button_setfreq.focus();
|
||||
field_baudrate.focus();
|
||||
}
|
||||
|
||||
void ModemSetupView::update_freq(rf::Frequency f) {
|
||||
/*void ModemSetupView::update_freq(rf::Frequency f) {
|
||||
persistent_memory::set_tuned_frequency(f);
|
||||
|
||||
button_setfreq.set_text(to_string_short_freq(f));
|
||||
}
|
||||
}*/
|
||||
|
||||
ModemSetupView::ModemSetupView(
|
||||
NavigationView& nav
|
||||
)
|
||||
{
|
||||
using name_t = std::string;
|
||||
using value_t = int32_t;
|
||||
using option_t = std::pair<name_t, value_t>;
|
||||
using option_t = std::pair<std::string, int32_t>;
|
||||
using options_t = std::vector<option_t>;
|
||||
options_t modem_options;
|
||||
size_t i;
|
||||
|
||||
add_children({
|
||||
&labels,
|
||||
&button_setfreq,
|
||||
//&button_setfreq,
|
||||
&field_baudrate,
|
||||
&field_mark,
|
||||
&field_space,
|
||||
&field_bw,
|
||||
//&field_bw,
|
||||
&field_repeat,
|
||||
&options_modem,
|
||||
&button_set_modem,
|
||||
@ -72,11 +66,10 @@ ModemSetupView::ModemSetupView(
|
||||
&button_save
|
||||
});
|
||||
|
||||
for (i = 0; i < MODEM_DEF_COUNT; i++) {
|
||||
for (size_t i = 0; i < MODEM_DEF_COUNT; i++) {
|
||||
if (modem_defs[i].modulation == AFSK)
|
||||
modem_options.emplace_back(std::make_pair(modem_defs[i].name, i));
|
||||
}
|
||||
|
||||
options_modem.set_options(modem_options);
|
||||
options_modem.set_selected_index(0);
|
||||
|
||||
@ -90,19 +83,19 @@ ModemSetupView::ModemSetupView(
|
||||
sym_format.set_sym(2, persistent_memory::serial_format().stop_bits);
|
||||
sym_format.set_sym(3, persistent_memory::serial_format().bit_order);
|
||||
|
||||
update_freq(persistent_memory::tuned_frequency());
|
||||
//update_freq(persistent_memory::tuned_frequency());
|
||||
|
||||
field_mark.set_value(persistent_memory::afsk_mark_freq());
|
||||
field_space.set_value(persistent_memory::afsk_space_freq());
|
||||
field_bw.set_value(persistent_memory::modem_bw() / 1000);
|
||||
//field_bw.set_value(persistent_memory::modem_bw() / 1000);
|
||||
field_repeat.set_value(persistent_memory::modem_repeat());
|
||||
|
||||
button_setfreq.on_select = [this, &nav](Button&) {
|
||||
/*button_setfreq.on_select = [this, &nav](Button&) {
|
||||
auto new_view = nav.push<FrequencyKeypadView>(persistent_memory::tuned_frequency());
|
||||
new_view->on_changed = [this](rf::Frequency f) {
|
||||
update_freq(f);
|
||||
};
|
||||
};
|
||||
};*/
|
||||
|
||||
field_baudrate.set_value(persistent_memory::modem_baudrate());
|
||||
|
||||
@ -121,7 +114,7 @@ ModemSetupView::ModemSetupView(
|
||||
persistent_memory::set_afsk_space(field_space.value());
|
||||
|
||||
persistent_memory::set_modem_baudrate(field_baudrate.value());
|
||||
persistent_memory::set_modem_bw(field_bw.value() * 1000);
|
||||
//persistent_memory::set_modem_bw(field_bw.value() * 1000);
|
||||
persistent_memory::set_modem_repeat(field_repeat.value());
|
||||
|
||||
serial_format.data_bits = sym_format.get_sym(0) + 6;
|
||||
|
@ -41,23 +41,23 @@ private:
|
||||
void update_freq(rf::Frequency f);
|
||||
|
||||
Labels labels {
|
||||
{ { 2 * 8, 4 * 8 }, "Frequency:", Color::light_grey() },
|
||||
{ { 2 * 8, 11 * 8 }, "Speed: Bps", Color::light_grey() },
|
||||
//{ { 2 * 8, 4 * 8 }, "Frequency:", Color::light_grey() },
|
||||
{ { 2 * 8, 11 * 8 }, "Baudrate:", Color::light_grey() },
|
||||
{ { 2 * 8, 13 * 8 }, "Mark: Hz", Color::light_grey() },
|
||||
{ { 2 * 8, 15 * 8 }, "Space: Hz", Color::light_grey() },
|
||||
{ { 140, 13 * 8 }, "BW: kHz", Color::light_grey() },
|
||||
//{ { 140, 13 * 8 }, "BW: kHz", Color::light_grey() },
|
||||
{ { 140, 15 * 8 }, "Repeat:", Color::light_grey() },
|
||||
{ { 2 * 8, 19 * 8 }, "Modem preset:", Color::light_grey() },
|
||||
{ { 1 * 8, 6 * 8 }, "Modem preset:", Color::light_grey() },
|
||||
{ { 2 * 8, 22 * 8 }, "Serial format:", Color::light_grey() }
|
||||
};
|
||||
|
||||
Button button_setfreq {
|
||||
/*Button button_setfreq {
|
||||
{ 13 * 8, 3 * 8, 12 * 8, 32 },
|
||||
"----.----"
|
||||
};
|
||||
};*/
|
||||
|
||||
NumberField field_baudrate {
|
||||
{ 64, 88 },
|
||||
{ 11 * 8, 11 * 8 },
|
||||
5,
|
||||
{ 50, 9600 },
|
||||
25,
|
||||
@ -65,7 +65,7 @@ private:
|
||||
};
|
||||
|
||||
NumberField field_mark {
|
||||
{ 64, 104 },
|
||||
{ 8 * 8, 13 * 8 },
|
||||
5,
|
||||
{ 100, 15000 },
|
||||
25,
|
||||
@ -73,23 +73,23 @@ private:
|
||||
};
|
||||
|
||||
NumberField field_space {
|
||||
{ 64, 120 },
|
||||
{ 8 * 8, 15 * 8 },
|
||||
5,
|
||||
{ 100, 15000 },
|
||||
25,
|
||||
' '
|
||||
};
|
||||
|
||||
NumberField field_bw {
|
||||
/*NumberField field_bw {
|
||||
{ 172, 104 },
|
||||
2,
|
||||
{ 1, 50 },
|
||||
1,
|
||||
' '
|
||||
};
|
||||
};*/
|
||||
|
||||
NumberField field_repeat {
|
||||
{ 204, 120 },
|
||||
{ 204, 15 * 8 },
|
||||
2,
|
||||
{ 1, 99 },
|
||||
1,
|
||||
@ -97,7 +97,7 @@ private:
|
||||
};
|
||||
|
||||
OptionsField options_modem {
|
||||
{ 16 * 8, 19 * 8 },
|
||||
{ 15 * 8, 6 * 8 },
|
||||
7,
|
||||
{
|
||||
}
|
||||
@ -110,12 +110,12 @@ private:
|
||||
};
|
||||
|
||||
Button button_set_modem {
|
||||
{ 24 * 8, 19 * 8 - 4, 5 * 8, 24 },
|
||||
{ 23 * 8, 6 * 8 - 4, 6 * 8, 24 },
|
||||
"SET"
|
||||
};
|
||||
|
||||
Button button_save {
|
||||
{ 72, 250, 96, 40 },
|
||||
{ 9 * 8, 250, 96, 40 },
|
||||
"Save"
|
||||
};
|
||||
};
|
||||
|
@ -285,7 +285,8 @@ ReceiversMenuView::ReceiversMenuView(NavigationView& nav) {
|
||||
add_items({
|
||||
{ "ADS-B: Planes", ui::Color::green(), &bitmap_icon_adsb, [&nav](){ nav.push<ADSBRxView>(); }, },
|
||||
{ "AIS: Boats", ui::Color::green(), &bitmap_icon_ais, [&nav](){ nav.push<AISAppView>(); } },
|
||||
{ "APRS", ui::Color::orange(),&bitmap_icon_aprs, [&nav](){ nav.push<AFSKRxView>(); } },
|
||||
{ "AFSK", ui::Color::yellow(),&bitmap_icon_receivers, [&nav](){ nav.push<AFSKRxView>(); } },
|
||||
{ "APRS", ui::Color::grey(), &bitmap_icon_aprs, [&nav](){ nav.push<NotImplementedView>(); } },
|
||||
{ "Audio", ui::Color::green(), &bitmap_icon_speaker, [&nav](){ nav.push<AnalogAudioView>(false); } },
|
||||
{ "ERT: Utility Meters", ui::Color::green(), &bitmap_icon_ert, [&nav](){ nav.push<ERTAppView>(); } },
|
||||
{ "POCSAG", ui::Color::green(), &bitmap_icon_pocsag, [&nav](){ nav.push<POCSAGAppView>(); } },
|
||||
@ -295,7 +296,7 @@ ReceiversMenuView::ReceiversMenuView(NavigationView& nav) {
|
||||
{ "TPMS: Cars", ui::Color::green(), &bitmap_icon_tpms, [&nav](){ nav.push<TPMSAppView>(); } },
|
||||
});
|
||||
on_left = [&nav](){ nav.pop(); };
|
||||
//set_highlighted(3); // Default selection is "Audio"
|
||||
//set_highlighted(4); // Default selection is "Audio"
|
||||
}
|
||||
|
||||
/* TransmittersMenuView **************************************************/
|
||||
|
@ -25,54 +25,119 @@
|
||||
|
||||
#include "event_m4.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
void AFSKRxProcessor::execute(const buffer_c8_t& buffer) {
|
||||
// This is called at 1500Hz
|
||||
// This is called at 3072000 / 2048 = 1500Hz
|
||||
|
||||
if (!configured) return;
|
||||
|
||||
const auto decim_0_out = decim_0.execute(buffer, dst_buffer);
|
||||
const auto decim_1_out = decim_1.execute(decim_0_out, dst_buffer);
|
||||
const auto channel_out = channel_filter.execute(decim_1_out, dst_buffer);
|
||||
// FM demodulation
|
||||
const auto decim_0_out = decim_0.execute(buffer, dst_buffer); // 2048 / 8 = 256 (512 I/Q samples)
|
||||
const auto decim_1_out = decim_1.execute(decim_0_out, dst_buffer); // 256 / 8 = 32 (64 I/Q samples)
|
||||
const auto channel_out = channel_filter.execute(decim_1_out, dst_buffer); // 32 / 2 = 16 (32 I/Q samples)
|
||||
|
||||
feed_channel_stats(channel_out);
|
||||
|
||||
auto audio = demod.execute(channel_out, audio_buffer);
|
||||
|
||||
audio_output.write(audio);
|
||||
|
||||
// Audio signal processing
|
||||
for (size_t c = 0; c < audio.count; c++) {
|
||||
|
||||
const int32_t sample_int = audio.p[c] * 32768.0f;
|
||||
const int32_t audio_sample = __SSAT(sample_int, 16);
|
||||
int32_t current_sample = __SSAT(sample_int, 16);
|
||||
|
||||
/*slicer_sr <<= 1;
|
||||
slicer_sr |= (audio_sample < 0); // Do we need hysteresis ?
|
||||
|
||||
// Detect transitions to adjust clock
|
||||
if ((slicer_sr ^ (slicer_sr >> 1)) & 1) {
|
||||
if (sphase < (0x8000u - sphase_delta_half))
|
||||
sphase += sphase_delta_eighth;
|
||||
current_sample /= 128;
|
||||
|
||||
// Delay line put
|
||||
delay_line[delay_line_index & 0x3F] = current_sample;
|
||||
|
||||
// Delay line get, and LPF
|
||||
sample_mixed = (delay_line[(delay_line_index - (samples_per_bit/2)) & 0x3F] * current_sample) / 4;
|
||||
sample_filtered = prev_mixed + sample_mixed + (prev_filtered / 2);
|
||||
|
||||
delay_line_index++;
|
||||
|
||||
prev_filtered = sample_filtered;
|
||||
prev_mixed = sample_mixed;
|
||||
|
||||
// Slice
|
||||
sample_bits <<= 1;
|
||||
sample_bits |= (sample_filtered < -20) ? 1 : 0;
|
||||
|
||||
// Check for "clean" transition: either 0011 or 1100
|
||||
if ((((sample_bits >> 2) ^ sample_bits) & 3) == 3) {
|
||||
// Adjust phase
|
||||
if (phase < 0x8000)
|
||||
phase += 0x800; // Is this a proper value ?
|
||||
else
|
||||
sphase -= sphase_delta_eighth;
|
||||
phase -= 0x800;
|
||||
}
|
||||
|
||||
sphase += sphase_delta;*/
|
||||
phase += phase_inc;
|
||||
|
||||
// Symbol time elapsed
|
||||
//if (sphase >= 0x10000u) {
|
||||
// sphase &= 0xFFFFu;
|
||||
if (phase >= 0x10000) {
|
||||
phase &= 0xFFFF;
|
||||
|
||||
rx_data <<= 1;
|
||||
rx_data |= 1;
|
||||
|
||||
bit_count++;
|
||||
if (bit_count == 8) {
|
||||
data_message.byte = rx_data;
|
||||
shared_memory.application_queue.push(data_message);
|
||||
bit_count = 0;
|
||||
if (trigger_word) {
|
||||
|
||||
// Continuous-stream value-triggered mode (AX.25) - UNTESTED
|
||||
word_bits <<= 1;
|
||||
word_bits |= (sample_bits & 1);
|
||||
|
||||
bit_counter++;
|
||||
|
||||
if (triggered) {
|
||||
if (bit_counter == word_length) {
|
||||
bit_counter = 0;
|
||||
|
||||
data_message.is_data = true;
|
||||
data_message.value = word_bits & word_mask;
|
||||
shared_memory.application_queue.push(data_message);
|
||||
}
|
||||
} else {
|
||||
if ((word_bits & word_mask) == trigger_value) {
|
||||
triggered = !triggered;
|
||||
bit_counter = 0;
|
||||
|
||||
data_message.is_data = true;
|
||||
data_message.value = trigger_value;
|
||||
shared_memory.application_queue.push(data_message);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// RS232-like modem mode
|
||||
if (state == WAIT_START) {
|
||||
if (!(sample_bits & 1)) {
|
||||
// Got start bit
|
||||
state = RECEIVE;
|
||||
bit_counter = 0;
|
||||
}
|
||||
} else if (state == WAIT_STOP) {
|
||||
if (sample_bits & 1) {
|
||||
// Got stop bit
|
||||
state = WAIT_START;
|
||||
}
|
||||
} else {
|
||||
word_bits <<= 1;
|
||||
word_bits |= (sample_bits & 1);
|
||||
|
||||
bit_counter++;
|
||||
}
|
||||
|
||||
if (bit_counter == word_length) {
|
||||
bit_counter = 0;
|
||||
state = WAIT_STOP;
|
||||
|
||||
data_message.is_data = true;
|
||||
data_message.value = word_bits;
|
||||
shared_memory.application_queue.push(data_message);
|
||||
}
|
||||
|
||||
}
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,26 +147,39 @@ void AFSKRxProcessor::on_message(const Message* const message) {
|
||||
}
|
||||
|
||||
void AFSKRxProcessor::configure(const AFSKRxConfigureMessage& message) {
|
||||
constexpr size_t decim_0_input_fs = baseband_fs;
|
||||
/*constexpr size_t decim_0_input_fs = baseband_fs;
|
||||
constexpr size_t decim_0_output_fs = decim_0_input_fs / decim_0.decimation_factor;
|
||||
|
||||
constexpr size_t decim_1_input_fs = decim_0_output_fs;
|
||||
constexpr size_t decim_1_output_fs = decim_1_input_fs / decim_1.decimation_factor;
|
||||
|
||||
|
||||
constexpr size_t channel_filter_input_fs = decim_1_output_fs;
|
||||
const size_t channel_filter_output_fs = channel_filter_input_fs / 2;
|
||||
|
||||
const size_t demod_input_fs = channel_filter_output_fs;
|
||||
|
||||
decim_0.configure(taps_16k0_decim_0.taps, 33554432);
|
||||
decim_1.configure(taps_16k0_decim_1.taps, 131072);
|
||||
channel_filter.configure(taps_16k0_channel.taps, 2);
|
||||
demod.configure(demod_input_fs, 5000);
|
||||
const size_t demod_input_fs = channel_filter_output_fs;*/
|
||||
|
||||
bitrate = message.bitrate;
|
||||
sphase_delta = 0x10000u * bitrate / 24000;
|
||||
sphase_delta_half = sphase_delta / 2; // Just for speed
|
||||
sphase_delta_eighth = sphase_delta / 8;
|
||||
decim_0.configure(taps_11k0_decim_0.taps, 33554432);
|
||||
decim_1.configure(taps_11k0_decim_1.taps, 131072);
|
||||
channel_filter.configure(taps_11k0_channel.taps, 2);
|
||||
demod.configure(audio_fs, 5000);
|
||||
|
||||
audio_output.configure(audio_24k_hpf_300hz_config, audio_24k_deemph_300_6_config, 0);
|
||||
|
||||
samples_per_bit = audio_fs / message.baudrate;
|
||||
|
||||
phase_inc = (0x10000 * message.baudrate) / audio_fs;
|
||||
phase = 0;
|
||||
|
||||
trigger_word = message.trigger_word;
|
||||
word_length = message.word_length;
|
||||
trigger_value = message.trigger_value;
|
||||
word_mask = (1 << word_length) - 1;
|
||||
|
||||
// Delay line
|
||||
delay_line_index = 0;
|
||||
|
||||
triggered = false;
|
||||
state = WAIT_START;
|
||||
|
||||
configured = true;
|
||||
}
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "dsp_decimate.hpp"
|
||||
#include "dsp_demodulate.hpp"
|
||||
|
||||
#include "audio_output.hpp"
|
||||
|
||||
#include "fifo.hpp"
|
||||
#include "message.hpp"
|
||||
|
||||
@ -41,6 +43,15 @@ public:
|
||||
|
||||
private:
|
||||
static constexpr size_t baseband_fs = 3072000;
|
||||
static constexpr size_t audio_fs = baseband_fs / 8 / 8 / 2;
|
||||
|
||||
size_t samples_per_bit { };
|
||||
|
||||
enum State {
|
||||
WAIT_START = 0,
|
||||
WAIT_STOP,
|
||||
RECEIVE
|
||||
};
|
||||
|
||||
BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20, baseband::Direction::Receive };
|
||||
RSSIThread rssi_thread { NORMALPRIO + 10 };
|
||||
@ -56,27 +67,37 @@ private:
|
||||
audio.size()
|
||||
};
|
||||
|
||||
// Can't use FIFO class here since it only allows power-of-two sizes
|
||||
std::array<int32_t, 24000/1200> delay_line { 0 };
|
||||
// Array size ok down to 375 bauds (24000 / 375)
|
||||
std::array<int32_t, 64> delay_line { 0 };
|
||||
|
||||
dsp::decimate::FIRC8xR16x24FS4Decim8 decim_0 { };
|
||||
dsp::decimate::FIRC16xR16x32Decim8 decim_1 { };
|
||||
dsp::decimate::FIRAndDecimateComplex channel_filter { };
|
||||
|
||||
dsp::demodulate::FM demod { };
|
||||
|
||||
AudioOutput audio_output { };
|
||||
|
||||
uint32_t bitrate { };
|
||||
uint32_t sphase { 0 };
|
||||
uint32_t sphase_delta { 0 };
|
||||
uint32_t sphase_delta_half { 0 };
|
||||
uint32_t sphase_delta_eighth { 0 };
|
||||
uint32_t rx_data { 0 };
|
||||
uint32_t bit_count { 0 };
|
||||
State state { };
|
||||
size_t delay_line_index { };
|
||||
uint32_t bit_counter { 0 };
|
||||
uint32_t word_bits { 0 };
|
||||
uint32_t sample_bits { 0 };
|
||||
uint32_t phase { }, phase_inc { };
|
||||
int32_t sample_mixed { }, prev_mixed { }, sample_filtered { }, prev_filtered { };
|
||||
uint32_t word_length { };
|
||||
uint32_t word_mask { };
|
||||
uint32_t trigger_value { };
|
||||
|
||||
bool configured { false };
|
||||
bool wait_start { };
|
||||
bool bit_value { };
|
||||
bool trigger_word { };
|
||||
bool triggered { };
|
||||
|
||||
void configure(const AFSKRxConfigureMessage& message);
|
||||
|
||||
AFSKDataMessage data_message { 0 };
|
||||
AFSKDataMessage data_message { false, 0 };
|
||||
};
|
||||
|
||||
#endif/*__PROC_TPMS_H__*/
|
||||
|
@ -336,13 +336,16 @@ public:
|
||||
class AFSKDataMessage : public Message {
|
||||
public:
|
||||
constexpr AFSKDataMessage(
|
||||
const uint_fast8_t byte
|
||||
const bool is_data,
|
||||
const uint32_t value
|
||||
) : Message { ID::AFSKData },
|
||||
byte { byte }
|
||||
is_data { is_data },
|
||||
value { value }
|
||||
{
|
||||
}
|
||||
|
||||
uint_fast8_t byte;
|
||||
bool is_data;
|
||||
uint32_t value;
|
||||
};
|
||||
|
||||
class ShutdownMessage : public Message {
|
||||
@ -615,13 +618,22 @@ public:
|
||||
class AFSKRxConfigureMessage : public Message {
|
||||
public:
|
||||
constexpr AFSKRxConfigureMessage(
|
||||
const uint32_t bitrate
|
||||
const uint32_t baudrate,
|
||||
const uint32_t word_length,
|
||||
const uint32_t trigger_value,
|
||||
const bool trigger_word
|
||||
) : Message { ID::AFSKRxConfigure },
|
||||
bitrate(bitrate)
|
||||
baudrate(baudrate),
|
||||
word_length(word_length),
|
||||
trigger_value(trigger_value),
|
||||
trigger_word(trigger_word)
|
||||
{
|
||||
}
|
||||
|
||||
const uint32_t bitrate;
|
||||
const uint32_t baudrate;
|
||||
const uint32_t word_length;
|
||||
const uint32_t trigger_value;
|
||||
const bool trigger_word;
|
||||
};
|
||||
|
||||
class PWMRSSIConfigureMessage : public Message {
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
#include "portapack_shared_memory.hpp"
|
||||
#include "message_queue.hpp"
|
||||
|
||||
struct JammerChannel {
|
||||
|
@ -538,7 +538,7 @@ void Console::clear() {
|
||||
void Console::write(std::string message) {
|
||||
bool escape = false;
|
||||
|
||||
if (visible) {
|
||||
if (!hidden() && visible()) {
|
||||
const Style& s = style();
|
||||
const Font& font = s.font;
|
||||
const auto rect = screen_rect();
|
||||
@ -546,7 +546,10 @@ void Console::write(std::string message) {
|
||||
|
||||
for (const auto c : message) {
|
||||
if (escape) {
|
||||
pen_color = term_colors[c & 7];
|
||||
if (c <= 15)
|
||||
pen_color = term_colors[c & 15];
|
||||
else
|
||||
pen_color = s.foreground;
|
||||
escape = false;
|
||||
} else {
|
||||
if (c == '\n') {
|
||||
@ -570,7 +573,7 @@ void Console::write(std::string message) {
|
||||
}
|
||||
buffer = message;
|
||||
} else {
|
||||
buffer += message;
|
||||
if (buffer.size() < 256) buffer += message;
|
||||
}
|
||||
}
|
||||
|
||||
@ -588,7 +591,7 @@ void Console::on_show() {
|
||||
display.scroll_set_area(screen_r.top(), screen_r.bottom());
|
||||
display.scroll_set_position(0);
|
||||
clear();
|
||||
visible = true;
|
||||
//visible = true;
|
||||
}
|
||||
|
||||
void Console::on_hide() {
|
||||
@ -596,9 +599,12 @@ void Console::on_hide() {
|
||||
* position?
|
||||
*/
|
||||
display.scroll_disable();
|
||||
//visible = false;
|
||||
}
|
||||
|
||||
void Console::crlf() {
|
||||
if (hidden() || !visible()) return;
|
||||
|
||||
const Style& s = style();
|
||||
const auto sr = screen_rect();
|
||||
const auto line_height = s.font.line_height();
|
||||
|
@ -289,7 +289,7 @@ public:
|
||||
void on_hide() override;
|
||||
|
||||
private:
|
||||
bool visible = false;
|
||||
//bool visible = false;
|
||||
Point pos { 0, 0 };
|
||||
std::string buffer { };
|
||||
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user