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:
furrtek 2017-09-02 08:28:29 +01:00
parent 42439d1885
commit 950bc2b1d2
29 changed files with 428 additions and 206 deletions

View File

@ -117,9 +117,12 @@ void set_sstv_data(const uint8_t vis_code, const uint32_t pixel_duration) {
send_message(&message); 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 { const AFSKRxConfigureMessage message {
bitrate baudrate,
word_length,
trigger_value,
trigger_word
}; };
send_message(&message); send_message(&message);
} }

View File

@ -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, 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); const uint8_t afsk_repeat, const uint32_t afsk_bw, const uint8_t symbol_count);
void kill_afsk(); 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, void set_ook_data(const uint32_t stream_length, const uint32_t samples_per_bit, const uint8_t repeat,
const uint32_t pause_symbols); const uint32_t pause_symbols);
void set_fsk_data(const uint32_t stream_length, const uint32_t samples_per_bit, const uint32_t shift, void set_fsk_data(const uint32_t stream_length, const uint32_t samples_per_bit, const uint32_t shift,

View File

@ -32,6 +32,8 @@
//BUG: SCANNER Lock on frequency, if frequency jump, still locked on first one //BUG: SCANNER Lock on frequency, if frequency jump, still locked on first one
//BUG: SCANNER Multiple slices //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: REPLAY Convert C16 to C8 on M0 core
//TODO: Use TabView //TODO: Use TabView
//TODO: De bruijn sequence scanner for encoders //TODO: De bruijn sequence scanner for encoders

View File

@ -79,4 +79,41 @@ void generate_data(const std::string& in_message, uint16_t * out_data) {
out_data[bytes] = 0; // End marker 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 */ } /* namespace modems */

View File

@ -31,16 +31,16 @@ namespace modems {
#define MODEM_DEF_COUNT 7 #define MODEM_DEF_COUNT 7
enum modulation_enum { enum ModemModulation {
AFSK = 0, AFSK = 0,
FSK, FSK,
PSK, PSK,
SSB AM // SSB
}; };
struct modem_def_t { struct modem_def_t {
std::string name; std::string name;
modulation_enum modulation; ModemModulation modulation;
uint16_t mark_freq; uint16_t mark_freq;
uint16_t space_freq; uint16_t space_freq;
uint16_t baudrate; uint16_t baudrate;
@ -52,11 +52,12 @@ const modem_def_t modem_defs[MODEM_DEF_COUNT] = {
{ "V21", AFSK, 980, 1180, 300 }, { "V21", AFSK, 980, 1180, 300 },
{ "V23 M1", AFSK, 1300, 1700, 600 }, { "V23 M1", AFSK, 1300, 1700, 600 },
{ "V23 M2", AFSK, 1300, 2100, 1200 }, { "V23 M2", AFSK, 1300, 2100, 1200 },
{ "RTTY US", SSB, 2295, 2125, 45 }, { "RTTY US", AM, 2295, 2125, 45 },
{ "RTTY EU", SSB, 2125, 1955, 45 } { "RTTY EU", AM, 2125, 1955, 45 }
}; };
void generate_data(const std::string& in_message, uint16_t * out_data); void generate_data(const std::string& in_message, uint16_t * out_data);
uint32_t deframe_word(uint32_t raw_word);
} /* namespace modems */ } /* namespace modems */

View File

@ -23,8 +23,6 @@
#include "pocsag_app.hpp" #include "pocsag_app.hpp"
#include "baseband_api.hpp" #include "baseband_api.hpp"
#include "portapack.hpp"
#include "portapack_persistent_memory.hpp" #include "portapack_persistent_memory.hpp"
using namespace portapack; using namespace portapack;

View File

@ -39,11 +39,8 @@ namespace serializer {
* Diff M.: ... * Diff M.: ...
*/ */
uint8_t symbol_count() { size_t symbol_count(const serial_format_t& serial_format) {
serial_format_t serial_format; size_t count;
uint8_t count;
serial_format = persistent_memory::serial_format();
count = 1 + serial_format.data_bits; // Start count = 1 + serial_format.data_bits; // Start
if (serial_format.parity) count++; if (serial_format.parity) count++;

View File

@ -21,16 +21,14 @@
*/ */
#include "ui.hpp" #include "ui.hpp"
#include <cstring>
#include <string> #include "portapack_persistent_memory.hpp"
#ifndef __SERIALIZER_H__ #ifndef __SERIALIZER_H__
#define __SERIALIZER_H__ #define __SERIALIZER_H__
namespace serializer { namespace serializer {
uint8_t symbol_count();
enum parity_enum : uint8_t { enum parity_enum : uint8_t {
NONE = 0, NONE = 0,
EVEN = 1, EVEN = 1,
@ -49,6 +47,8 @@ struct serial_format_t {
order_enum bit_order; order_enum bit_order;
}; };
size_t symbol_count(const serial_format_t& serial_format);
/*{ "7-Even-1 R", "7E1", 7, EVEN, 1, false, false }, /*{ "7-Even-1 R", "7E1", 7, EVEN, 1, false, false },
{ "7E1 LUT ", "7Ea", 7, EVEN, 1, true, true }, { "7E1 LUT ", "7Ea", 7, EVEN, 1, true, true },
{ "7-Odd-1 ", "7o1", 7, ODD, 1, true, false }, { "7-Odd-1 ", "7o1", 7, ODD, 1, true, false },

View File

@ -61,7 +61,7 @@ std::string to_string_bin(
{ {
char p[33]; char p[33];
for (uint8_t c = 0; c < l; c++) { for (uint8_t c = 0; c < l; c++) {
if (n & (1 << (l - c))) if (n & (1 << (l - 1 - c)))
p[c] = '1'; p[c] = '1';
else else
p[c] = '0'; p[c] = '0';

View File

@ -25,13 +25,9 @@
#include "rtc_time.hpp" #include "rtc_time.hpp"
#include "string_format.hpp" #include "string_format.hpp"
#include "portapack.hpp"
#include "baseband_api.hpp" #include "baseband_api.hpp"
#include "portapack_persistent_memory.hpp" #include "portapack_persistent_memory.hpp"
#include <cstring>
#include <stdio.h>
using namespace portapack; using namespace portapack;
namespace ui { namespace ui {

View File

@ -21,11 +21,24 @@
*/ */
#include "ui_afsk_rx.hpp" #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 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 { namespace ui {
@ -37,10 +50,6 @@ void AFSKRxView::update_freq(rf::Frequency f) {
receiver_model.set_tuning_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) { AFSKRxView::AFSKRxView(NavigationView& nav) {
baseband::run_image(portapack::spi_flash::image_tag_afsk_rx); baseband::run_image(portapack::spi_flash::image_tag_afsk_rx);
@ -51,16 +60,24 @@ AFSKRxView::AFSKRxView(NavigationView& nav) {
&field_lna, &field_lna,
&field_vga, &field_vga,
&field_frequency, &field_frequency,
&options_bitrate, &text_debug,
&button_modem_setup,
&console &console
}); });
//receiver_model.set_sampling_rate(3072000); // Auto-configure modem for LCR RX (will be removed later)
//receiver_model.set_baseband_bandwidth(1750000); update_freq(462713300); // 162950000
//receiver_model.enable(); 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_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) { field_frequency.on_change = [this](rf::Frequency f) {
update_freq(f); update_freq(f);
}; };
@ -72,19 +89,69 @@ AFSKRxView::AFSKRxView(NavigationView& nav) {
field_frequency.set_value(f); field_frequency.set_value(f);
}; };
}; };
options_bitrate.on_change = [this](size_t, OptionsField::value_t v) { button_modem_setup.on_select = [&nav](Button&) {
on_bitrate_changed(v); 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) { void AFSKRxView::on_data(uint32_t value, bool is_data) {
std::string str_byte(1, byte); std::string str_byte = "\x1B";
console.write(str_byte);
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() { AFSKRxView::~AFSKRxView() {
audio::output::stop();
receiver_model.disable(); receiver_model.disable();
baseband::shutdown(); baseband::shutdown();
} }

View File

@ -26,9 +26,22 @@
#include "ui.hpp" #include "ui.hpp"
#include "ui_navigation.hpp" #include "ui_navigation.hpp"
#include "ui_receiver.hpp" #include "ui_receiver.hpp"
#include "ui_widget.hpp"
#include "log_file.hpp"
#include "utility.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 { namespace ui {
class AFSKRxView : public View { class AFSKRxView : public View {
@ -41,7 +54,11 @@ public:
std::string title() const override { return "AFSK RX (beta)"; }; std::string title() const override { return "AFSK RX (beta)"; };
private: 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 { RFAmpField field_rf_amp {
{ 13 * 8, 0 * 16 } { 13 * 8, 0 * 16 }
@ -60,33 +77,34 @@ private:
}; };
FrequencyField field_frequency { FrequencyField field_frequency {
{ 0 * 8, 0 * 8 }, { 0 * 8, 0 * 16 },
}; };
OptionsField options_bitrate {
{ 12 * 8, 21 }, Text text_debug {
7, { 0 * 8, 1 * 16, 10 * 8, 16 },
{ "DEBUG"
{ "600bps ", 600 }, };
{ "1200bps", 1200 },
{ "2400bps", 2400 }
} Button button_modem_setup {
{ 12 * 8, 1 * 16, 96, 24 },
"Modem setup"
}; };
Console console { Console console {
{ 0, 4 * 16, 240, 240 } { 0, 3 * 16, 240, 240 }
}; };
void update_freq(rf::Frequency f); void update_freq(rf::Frequency f);
void on_bitrate_changed(const uint32_t new_bitrate);
void on_data_afsk(const AFSKDataMessage& message); void on_data_afsk(const AFSKDataMessage& message);
std::unique_ptr<AFSKLogger> logger { };
MessageHandlerRegistration message_handler_packet { MessageHandlerRegistration message_handler_packet {
Message::ID::AFSKData, Message::ID::AFSKData,
[this](Message* const p) { [this](Message* const p) {
const auto message = static_cast<const AFSKDataMessage*>(p); const auto message = static_cast<const AFSKDataMessage*>(p);
this->on_data(message->byte); this->on_data(message->value, message->is_data);
} }
}; };
}; };

View File

@ -177,7 +177,7 @@ private:
void start_tx(const bool scan); void start_tx(const bool scan);
void on_txdone(int n, const bool txdone); void on_txdone(int n, const bool txdone);
const Style style_address { /*const Style style_address {
.font = font::fixed_8x16, .font = font::fixed_8x16,
.background = Color::black(), .background = Color::black(),
.foreground = Color::red(), .foreground = Color::red(),
@ -186,7 +186,7 @@ private:
.font = font::fixed_8x16, .font = font::fixed_8x16,
.background = Color::black(), .background = Color::black(),
.foreground = Color::blue(), .foreground = Color::blue(),
}; };*/
Rect view_rect = { 0, 4 * 8, 240, 168 }; Rect view_rect = { 0, 4 * 8, 240, 168 };

View File

@ -30,31 +30,28 @@ using namespace portapack;
namespace ui { namespace ui {
FreqManBaseView::FreqManBaseView( FreqManBaseView::FreqManBaseView(
NavigationView& nav, NavigationView& nav
Widget& default_focus_widget ) : nav_ (nav)
) : nav_ (nav),
default_focus_widget_ (default_focus_widget)
{ {
file_list = get_freqman_files(); file_list = get_freqman_files();
if (!file_list.size()) { if (!file_list.size())
error_ = ERROR_NOFILES; error_ = ERROR_NOFILES;
return;
}
add_children({ add_children({
&label_category, &label_category,
&options_category,
&button_exit &button_exit
}); });
// Populate categories OptionsField if (file_list.size()) {
populate_categories(); add_child(&options_category);
populate_categories();
}
// Default function
on_change_category = [this](int32_t category_id) { on_change_category = [this](int32_t category_id) {
change_category(category_id); change_category(category_id);
}; };
//change_category(0);
button_exit.on_select = [this, &nav](Button&) { button_exit.on_select = [this, &nav](Button&) {
nav.pop(); nav.pop();
@ -62,26 +59,21 @@ FreqManBaseView::FreqManBaseView(
}; };
void FreqManBaseView::focus() { void FreqManBaseView::focus() {
/*if (error_ == ERROR_ACCESS) { button_exit.focus();
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;
}*/
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); nav_.display_modal("Error", "No database files", ABORT, nullptr);
} else { } else {
default_focus_widget_.focus(); options_category.focus();
} }
} }
bool FreqManBaseView::populate_categories() { bool FreqManBaseView::populate_categories() {
size_t n;
categories.clear(); 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)); categories.emplace_back(std::make_pair(file_list[n], n));
options_category.set_options(categories); options_category.set_options(categories);
@ -96,10 +88,13 @@ bool FreqManBaseView::populate_categories() {
} }
void FreqManBaseView::change_category(int32_t category_id) { void FreqManBaseView::change_category(int32_t category_id) {
if (!file_list.size()) return;
current_category_id = category_id; current_category_id = category_id;
if (!load_freqman_file(file_list[current_category_id], database)) if (!load_freqman_file(file_list[current_category_id], database))
error_ = ERROR_ACCESS; // Todo error_ = ERROR_ACCESS;
else else
refresh_list(); refresh_list();
} }
@ -158,7 +153,7 @@ FrequencySaveView::~FrequencySaveView() {
FrequencySaveView::FrequencySaveView( FrequencySaveView::FrequencySaveView(
NavigationView& nav, NavigationView& nav,
const rf::Frequency value const rf::Frequency value
) : FreqManBaseView(nav, options_category), ) : FreqManBaseView(nav),
value_ (value) value_ (value)
{ {
desc_buffer.reserve(28); desc_buffer.reserve(28);
@ -204,7 +199,7 @@ void FrequencyLoadView::refresh_widgets(const bool v) {
FrequencyLoadView::FrequencyLoadView( FrequencyLoadView::FrequencyLoadView(
NavigationView& nav NavigationView& nav
) : FreqManBaseView(nav, options_category) ) : FreqManBaseView(nav)
{ {
on_refresh_widgets = [this](bool v) { on_refresh_widgets = [this](bool v) {
refresh_widgets(v); refresh_widgets(v);
@ -278,7 +273,7 @@ FrequencyManagerView::~FrequencyManagerView() {
FrequencyManagerView::FrequencyManagerView( FrequencyManagerView::FrequencyManagerView(
NavigationView& nav NavigationView& nav
) : FreqManBaseView(nav, options_category) ) : FreqManBaseView(nav)
{ {
on_refresh_widgets = [this](bool v) { on_refresh_widgets = [this](bool v) {
refresh_widgets(v); refresh_widgets(v);

View File

@ -35,7 +35,7 @@ namespace ui {
class FreqManBaseView : public View { class FreqManBaseView : public View {
public: public:
FreqManBaseView( FreqManBaseView(
NavigationView& nav, Widget& default_focus_widget NavigationView& nav
); );
void focus() override; void focus() override;
@ -48,7 +48,6 @@ protected:
NavigationView& nav_; NavigationView& nav_;
freqman_error error_ { NO_ERROR }; freqman_error error_ { NO_ERROR };
Widget& default_focus_widget_;
options_t categories { }; options_t categories { };
std::function<void(int32_t category_id)> on_change_category { nullptr }; std::function<void(int32_t category_id)> on_change_category { nullptr };
std::function<void(void)> on_select_frequency { nullptr }; std::function<void(void)> on_select_frequency { nullptr };

View File

@ -23,15 +23,12 @@
#include "ui_lcr.hpp" #include "ui_lcr.hpp"
#include "ui_modemsetup.hpp" #include "ui_modemsetup.hpp"
#include "modems.hpp"
#include "lcr.hpp" #include "lcr.hpp"
#include "modems.hpp"
#include "baseband_api.hpp" #include "baseband_api.hpp"
#include "string_format.hpp" #include "string_format.hpp"
#include "portapack_persistent_memory.hpp" #include "serializer.hpp"
#include <cstring>
#include <stdio.h>
using namespace portapack; using namespace portapack;
@ -47,7 +44,6 @@ LCRView::~LCRView() {
} }
void LCRView::paint(Painter& painter) { void LCRView::paint(Painter& painter) {
size_t i;
std::string final_str; std::string final_str;
static constexpr Style style_orange { static constexpr Style style_orange {
@ -61,7 +57,7 @@ void LCRView::paint(Painter& painter) {
static_cast<Coord>(68) static_cast<Coord>(68)
}; };
for (i = 0; i < 5; i++) { for (size_t i = 0; i < 5; i++) {
painter.draw_string( painter.draw_string(
screen_pos() + offset, screen_pos() + offset,
style_orange, style_orange,
@ -181,7 +177,7 @@ void LCRView::start_tx(const bool scan) {
persistent_memory::afsk_space_freq(), persistent_memory::afsk_space_freq(),
repeats, repeats,
persistent_memory::modem_bw(), persistent_memory::modem_bw(),
serializer::symbol_count() serializer::symbol_count(persistent_memory::serial_format())
); );
} }
@ -201,7 +197,7 @@ LCRView::LCRView(NavigationView& nav) {
&text_recap, &text_recap,
&options_ec, &options_ec,
&button_setrgsb, &button_setrgsb,
&button_txsetup, &button_modem_setup,
&text_status, &text_status,
&progress, &progress,
&button_transmit, &button_transmit,
@ -266,7 +262,7 @@ LCRView::LCRView(NavigationView& nav) {
text_prompt(nav, &rgsb, 4); text_prompt(nav, &rgsb, 4);
}; };
button_txsetup.on_select = [&nav](Button&) { button_modem_setup.on_select = [&nav](Button&) {
nav.push<ModemSetupView>(); nav.push<ModemSetupView>();
}; };
@ -294,11 +290,9 @@ LCRView::LCRView(NavigationView& nav) {
}; };
button_clear.on_select = [this, &nav](Button&) { button_clear.on_select = [this, &nav](Button&) {
size_t n;
if (tx_mode == IDLE) { if (tx_mode == IDLE) {
options_ec.set_selected_index(0); // Auto options_ec.set_selected_index(0); // Auto
for (n = 0; n < 5; n++) { for (size_t n = 0; n < 5; n++) {
litteral[n] = " "; litteral[n] = " ";
checkboxes[n].set_value(true); checkboxes[n].set_value(true);
} }

View File

@ -134,7 +134,7 @@ private:
{ 8, 24, 80, 32 }, { 8, 24, 80, 32 },
"RGSB" "RGSB"
}; };
Button button_txsetup { Button button_modem_setup {
{ 13 * 8, 24, 128, 32 }, { 13 * 8, 24, 128, 32 },
"Modem setup" "Modem setup"
}; };

View File

@ -93,10 +93,7 @@ MenuView::MenuView(
bool keep_highlight bool keep_highlight
) : keep_highlight_ { keep_highlight } ) : keep_highlight_ { keep_highlight }
{ {
View::set_parent_rect(new_parent_rect); 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_focusable(true); 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() { void MenuView::on_tick_second() {
if (more_ && blink_) if (more_ && blink_)
arrow_more.set_foreground(Color::white()); arrow_more.set_foreground(Color::white());

View File

@ -84,11 +84,11 @@ public:
size_t highlighted() const; size_t highlighted() const;
bool set_highlighted(int32_t new_value); bool set_highlighted(int32_t new_value);
void set_parent_rect(const Rect new_parent_rect) override;
void on_focus() override; void on_focus() override;
void on_blur() override; void on_blur() override;
bool on_key(const KeyEvent event) override; bool on_key(const KeyEvent event) override;
bool on_encoder(const EncoderEvent event) override; bool on_encoder(const EncoderEvent event) override;
private: private:
void update_items(); void update_items();

View File

@ -29,42 +29,36 @@
#include "portapack_shared_memory.hpp" #include "portapack_shared_memory.hpp"
#include "portapack_persistent_memory.hpp" #include "portapack_persistent_memory.hpp"
#include <cstring>
#include <stdio.h>
using namespace portapack; using namespace portapack;
using namespace modems; using namespace modems;
namespace ui { namespace ui {
void ModemSetupView::focus() { 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); persistent_memory::set_tuned_frequency(f);
button_setfreq.set_text(to_string_short_freq(f)); button_setfreq.set_text(to_string_short_freq(f));
} }*/
ModemSetupView::ModemSetupView( ModemSetupView::ModemSetupView(
NavigationView& nav NavigationView& nav
) )
{ {
using name_t = std::string; using option_t = std::pair<std::string, int32_t>;
using value_t = int32_t;
using option_t = std::pair<name_t, value_t>;
using options_t = std::vector<option_t>; using options_t = std::vector<option_t>;
options_t modem_options; options_t modem_options;
size_t i;
add_children({ add_children({
&labels, &labels,
&button_setfreq, //&button_setfreq,
&field_baudrate, &field_baudrate,
&field_mark, &field_mark,
&field_space, &field_space,
&field_bw, //&field_bw,
&field_repeat, &field_repeat,
&options_modem, &options_modem,
&button_set_modem, &button_set_modem,
@ -72,11 +66,10 @@ ModemSetupView::ModemSetupView(
&button_save &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) if (modem_defs[i].modulation == AFSK)
modem_options.emplace_back(std::make_pair(modem_defs[i].name, i)); modem_options.emplace_back(std::make_pair(modem_defs[i].name, i));
} }
options_modem.set_options(modem_options); options_modem.set_options(modem_options);
options_modem.set_selected_index(0); 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(2, persistent_memory::serial_format().stop_bits);
sym_format.set_sym(3, persistent_memory::serial_format().bit_order); 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_mark.set_value(persistent_memory::afsk_mark_freq());
field_space.set_value(persistent_memory::afsk_space_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()); 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()); auto new_view = nav.push<FrequencyKeypadView>(persistent_memory::tuned_frequency());
new_view->on_changed = [this](rf::Frequency f) { new_view->on_changed = [this](rf::Frequency f) {
update_freq(f); update_freq(f);
}; };
}; };*/
field_baudrate.set_value(persistent_memory::modem_baudrate()); 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_afsk_space(field_space.value());
persistent_memory::set_modem_baudrate(field_baudrate.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()); persistent_memory::set_modem_repeat(field_repeat.value());
serial_format.data_bits = sym_format.get_sym(0) + 6; serial_format.data_bits = sym_format.get_sym(0) + 6;

View File

@ -41,23 +41,23 @@ private:
void update_freq(rf::Frequency f); void update_freq(rf::Frequency f);
Labels labels { Labels labels {
{ { 2 * 8, 4 * 8 }, "Frequency:", Color::light_grey() }, //{ { 2 * 8, 4 * 8 }, "Frequency:", Color::light_grey() },
{ { 2 * 8, 11 * 8 }, "Speed: Bps", Color::light_grey() }, { { 2 * 8, 11 * 8 }, "Baudrate:", Color::light_grey() },
{ { 2 * 8, 13 * 8 }, "Mark: Hz", Color::light_grey() }, { { 2 * 8, 13 * 8 }, "Mark: Hz", Color::light_grey() },
{ { 2 * 8, 15 * 8 }, "Space: 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() }, { { 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() } { { 2 * 8, 22 * 8 }, "Serial format:", Color::light_grey() }
}; };
Button button_setfreq { /*Button button_setfreq {
{ 13 * 8, 3 * 8, 12 * 8, 32 }, { 13 * 8, 3 * 8, 12 * 8, 32 },
"----.----" "----.----"
}; };*/
NumberField field_baudrate { NumberField field_baudrate {
{ 64, 88 }, { 11 * 8, 11 * 8 },
5, 5,
{ 50, 9600 }, { 50, 9600 },
25, 25,
@ -65,7 +65,7 @@ private:
}; };
NumberField field_mark { NumberField field_mark {
{ 64, 104 }, { 8 * 8, 13 * 8 },
5, 5,
{ 100, 15000 }, { 100, 15000 },
25, 25,
@ -73,23 +73,23 @@ private:
}; };
NumberField field_space { NumberField field_space {
{ 64, 120 }, { 8 * 8, 15 * 8 },
5, 5,
{ 100, 15000 }, { 100, 15000 },
25, 25,
' ' ' '
}; };
NumberField field_bw { /*NumberField field_bw {
{ 172, 104 }, { 172, 104 },
2, 2,
{ 1, 50 }, { 1, 50 },
1, 1,
' ' ' '
}; };*/
NumberField field_repeat { NumberField field_repeat {
{ 204, 120 }, { 204, 15 * 8 },
2, 2,
{ 1, 99 }, { 1, 99 },
1, 1,
@ -97,7 +97,7 @@ private:
}; };
OptionsField options_modem { OptionsField options_modem {
{ 16 * 8, 19 * 8 }, { 15 * 8, 6 * 8 },
7, 7,
{ {
} }
@ -110,12 +110,12 @@ private:
}; };
Button button_set_modem { Button button_set_modem {
{ 24 * 8, 19 * 8 - 4, 5 * 8, 24 }, { 23 * 8, 6 * 8 - 4, 6 * 8, 24 },
"SET" "SET"
}; };
Button button_save { Button button_save {
{ 72, 250, 96, 40 }, { 9 * 8, 250, 96, 40 },
"Save" "Save"
}; };
}; };

View File

@ -285,7 +285,8 @@ ReceiversMenuView::ReceiversMenuView(NavigationView& nav) {
add_items({ add_items({
{ "ADS-B: Planes", ui::Color::green(), &bitmap_icon_adsb, [&nav](){ nav.push<ADSBRxView>(); }, }, { "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>(); } }, { "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); } }, { "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>(); } }, { "ERT: Utility Meters", ui::Color::green(), &bitmap_icon_ert, [&nav](){ nav.push<ERTAppView>(); } },
{ "POCSAG", ui::Color::green(), &bitmap_icon_pocsag, [&nav](){ nav.push<POCSAGAppView>(); } }, { "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>(); } }, { "TPMS: Cars", ui::Color::green(), &bitmap_icon_tpms, [&nav](){ nav.push<TPMSAppView>(); } },
}); });
on_left = [&nav](){ nav.pop(); }; on_left = [&nav](){ nav.pop(); };
//set_highlighted(3); // Default selection is "Audio" //set_highlighted(4); // Default selection is "Audio"
} }
/* TransmittersMenuView **************************************************/ /* TransmittersMenuView **************************************************/

View File

@ -25,54 +25,119 @@
#include "event_m4.hpp" #include "event_m4.hpp"
#include <cstdint>
#include <cstddef>
void AFSKRxProcessor::execute(const buffer_c8_t& buffer) { void AFSKRxProcessor::execute(const buffer_c8_t& buffer) {
// This is called at 1500Hz // This is called at 3072000 / 2048 = 1500Hz
if (!configured) return; if (!configured) return;
const auto decim_0_out = decim_0.execute(buffer, dst_buffer); // FM demodulation
const auto decim_1_out = decim_1.execute(decim_0_out, dst_buffer); const auto decim_0_out = decim_0.execute(buffer, dst_buffer); // 2048 / 8 = 256 (512 I/Q samples)
const auto channel_out = channel_filter.execute(decim_1_out, dst_buffer); 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); feed_channel_stats(channel_out);
auto audio = demod.execute(channel_out, audio_buffer); auto audio = demod.execute(channel_out, audio_buffer);
audio_output.write(audio);
// Audio signal processing
for (size_t c = 0; c < audio.count; c++) { for (size_t c = 0; c < audio.count; c++) {
const int32_t sample_int = audio.p[c] * 32768.0f; 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; current_sample /= 128;
slicer_sr |= (audio_sample < 0); // Do we need hysteresis ?
// Delay line put
// Detect transitions to adjust clock delay_line[delay_line_index & 0x3F] = current_sample;
if ((slicer_sr ^ (slicer_sr >> 1)) & 1) {
if (sphase < (0x8000u - sphase_delta_half)) // Delay line get, and LPF
sphase += sphase_delta_eighth; 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 else
sphase -= sphase_delta_eighth; phase -= 0x800;
} }
sphase += sphase_delta;*/ phase += phase_inc;
// Symbol time elapsed if (phase >= 0x10000) {
//if (sphase >= 0x10000u) { phase &= 0xFFFF;
// sphase &= 0xFFFFu;
rx_data <<= 1; if (trigger_word) {
rx_data |= 1;
// Continuous-stream value-triggered mode (AX.25) - UNTESTED
bit_count++; word_bits <<= 1;
if (bit_count == 8) { word_bits |= (sample_bits & 1);
data_message.byte = rx_data;
shared_memory.application_queue.push(data_message); bit_counter++;
bit_count = 0;
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) { 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_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_input_fs = decim_0_output_fs;
constexpr size_t decim_1_output_fs = decim_1_input_fs / decim_1.decimation_factor; 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; 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 channel_filter_output_fs = channel_filter_input_fs / 2;
const size_t demod_input_fs = channel_filter_output_fs; 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);
bitrate = message.bitrate; decim_0.configure(taps_11k0_decim_0.taps, 33554432);
sphase_delta = 0x10000u * bitrate / 24000; decim_1.configure(taps_11k0_decim_1.taps, 131072);
sphase_delta_half = sphase_delta / 2; // Just for speed channel_filter.configure(taps_11k0_channel.taps, 2);
sphase_delta_eighth = sphase_delta / 8; 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; configured = true;
} }

View File

@ -30,6 +30,8 @@
#include "dsp_decimate.hpp" #include "dsp_decimate.hpp"
#include "dsp_demodulate.hpp" #include "dsp_demodulate.hpp"
#include "audio_output.hpp"
#include "fifo.hpp" #include "fifo.hpp"
#include "message.hpp" #include "message.hpp"
@ -41,6 +43,15 @@ public:
private: private:
static constexpr size_t baseband_fs = 3072000; 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 }; BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20, baseband::Direction::Receive };
RSSIThread rssi_thread { NORMALPRIO + 10 }; RSSIThread rssi_thread { NORMALPRIO + 10 };
@ -56,27 +67,37 @@ private:
audio.size() audio.size()
}; };
// Can't use FIFO class here since it only allows power-of-two sizes // Array size ok down to 375 bauds (24000 / 375)
std::array<int32_t, 24000/1200> delay_line { 0 }; std::array<int32_t, 64> delay_line { 0 };
dsp::decimate::FIRC8xR16x24FS4Decim8 decim_0 { }; dsp::decimate::FIRC8xR16x24FS4Decim8 decim_0 { };
dsp::decimate::FIRC16xR16x32Decim8 decim_1 { }; dsp::decimate::FIRC16xR16x32Decim8 decim_1 { };
dsp::decimate::FIRAndDecimateComplex channel_filter { }; dsp::decimate::FIRAndDecimateComplex channel_filter { };
dsp::demodulate::FM demod { }; dsp::demodulate::FM demod { };
AudioOutput audio_output { };
uint32_t bitrate { }; State state { };
uint32_t sphase { 0 }; size_t delay_line_index { };
uint32_t sphase_delta { 0 }; uint32_t bit_counter { 0 };
uint32_t sphase_delta_half { 0 }; uint32_t word_bits { 0 };
uint32_t sphase_delta_eighth { 0 }; uint32_t sample_bits { 0 };
uint32_t rx_data { 0 }; uint32_t phase { }, phase_inc { };
uint32_t bit_count { 0 }; 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 configured { false };
bool wait_start { };
bool bit_value { };
bool trigger_word { };
bool triggered { };
void configure(const AFSKRxConfigureMessage& message); void configure(const AFSKRxConfigureMessage& message);
AFSKDataMessage data_message { 0 }; AFSKDataMessage data_message { false, 0 };
}; };
#endif/*__PROC_TPMS_H__*/ #endif/*__PROC_TPMS_H__*/

View File

@ -336,13 +336,16 @@ public:
class AFSKDataMessage : public Message { class AFSKDataMessage : public Message {
public: public:
constexpr AFSKDataMessage( constexpr AFSKDataMessage(
const uint_fast8_t byte const bool is_data,
const uint32_t value
) : Message { ID::AFSKData }, ) : 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 { class ShutdownMessage : public Message {
@ -615,13 +618,22 @@ public:
class AFSKRxConfigureMessage : public Message { class AFSKRxConfigureMessage : public Message {
public: public:
constexpr AFSKRxConfigureMessage( 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 }, ) : 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 { class PWMRSSIConfigureMessage : public Message {

View File

@ -26,7 +26,6 @@
#include <cstdint> #include <cstdint>
#include <cstddef> #include <cstddef>
#include "portapack_shared_memory.hpp"
#include "message_queue.hpp" #include "message_queue.hpp"
struct JammerChannel { struct JammerChannel {

View File

@ -538,7 +538,7 @@ void Console::clear() {
void Console::write(std::string message) { void Console::write(std::string message) {
bool escape = false; bool escape = false;
if (visible) { if (!hidden() && visible()) {
const Style& s = style(); const Style& s = style();
const Font& font = s.font; const Font& font = s.font;
const auto rect = screen_rect(); const auto rect = screen_rect();
@ -546,7 +546,10 @@ void Console::write(std::string message) {
for (const auto c : message) { for (const auto c : message) {
if (escape) { if (escape) {
pen_color = term_colors[c & 7]; if (c <= 15)
pen_color = term_colors[c & 15];
else
pen_color = s.foreground;
escape = false; escape = false;
} else { } else {
if (c == '\n') { if (c == '\n') {
@ -570,7 +573,7 @@ void Console::write(std::string message) {
} }
buffer = message; buffer = message;
} else { } 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_area(screen_r.top(), screen_r.bottom());
display.scroll_set_position(0); display.scroll_set_position(0);
clear(); clear();
visible = true; //visible = true;
} }
void Console::on_hide() { void Console::on_hide() {
@ -596,9 +599,12 @@ void Console::on_hide() {
* position? * position?
*/ */
display.scroll_disable(); display.scroll_disable();
//visible = false;
} }
void Console::crlf() { void Console::crlf() {
if (hidden() || !visible()) return;
const Style& s = style(); const Style& s = style();
const auto sr = screen_rect(); const auto sr = screen_rect();
const auto line_height = s.font.line_height(); const auto line_height = s.font.line_height();

View File

@ -289,7 +289,7 @@ public:
void on_hide() override; void on_hide() override;
private: private:
bool visible = false; //bool visible = false;
Point pos { 0, 0 }; Point pos { 0, 0 };
std::string buffer { }; std::string buffer { };

Binary file not shown.