mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-12-25 07:19:28 -05:00
Added tabs in OOK encoders app
Simplified credits scrolling
This commit is contained in:
parent
6fcb2efdcf
commit
cd6a1a7f3f
@ -29,6 +29,7 @@
|
|||||||
namespace encoders {
|
namespace encoders {
|
||||||
|
|
||||||
#define ENC_TYPES_COUNT 14
|
#define ENC_TYPES_COUNT 14
|
||||||
|
#define OOK_SAMPLERATE 2280000U
|
||||||
|
|
||||||
struct encoder_def_t {
|
struct encoder_def_t {
|
||||||
std::string name; // Encoder chip ref/name
|
std::string name; // Encoder chip ref/name
|
||||||
|
@ -38,111 +38,100 @@ using namespace portapack;
|
|||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
void AboutView::update() {
|
// This is pretty much WaterfallView but in the opposite direction
|
||||||
size_t c;
|
CreditsWidget::CreditsWidget(
|
||||||
int32_t n;
|
Rect parent_rect
|
||||||
std::string text;
|
) : Widget { parent_rect }
|
||||||
Coord y_val, x_pos = 0;
|
{
|
||||||
uint32_t flag;
|
}
|
||||||
|
|
||||||
if (scroll & 1) {
|
|
||||||
if (!((scroll >> 1) & 15)) {
|
|
||||||
if (line_feed) {
|
|
||||||
line_feed = false;
|
|
||||||
} else {
|
|
||||||
// Find a free text widget
|
|
||||||
for (c = 0; c < 10; c++)
|
|
||||||
if (text_line[c].screen_pos().y() >= 200) break;
|
|
||||||
|
|
||||||
if (c < 10) {
|
|
||||||
flag = credits[credits_index].flag & 0x3F;
|
|
||||||
line_feed = (credits[credits_index].flag & 0x40) ? true : false;
|
|
||||||
|
|
||||||
if (flag == SECTION) {
|
|
||||||
if (!second) {
|
|
||||||
text = credits[credits_index].role;
|
|
||||||
if (credits[credits_index].name != "")
|
|
||||||
second = true;
|
|
||||||
else {
|
|
||||||
credits_index++;
|
|
||||||
line_feed = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
text = credits[credits_index].name;
|
|
||||||
second = false;
|
|
||||||
line_feed = true;
|
|
||||||
credits_index++;
|
|
||||||
}
|
|
||||||
x_pos = (240 - (text.size() * 8)) / 2;
|
|
||||||
} else if (flag == TITLE) {
|
|
||||||
text = credits[credits_index].role;
|
|
||||||
x_pos = 120 - (text.size() * 8);
|
|
||||||
if (credits[credits_index].name != "")
|
|
||||||
text += " " + credits[credits_index].name;
|
|
||||||
credits_index++;
|
|
||||||
} else if (flag == MEMBER) {
|
|
||||||
if (!second) {
|
|
||||||
text = credits[credits_index].role;
|
|
||||||
if (credits[credits_index].name != "")
|
|
||||||
second = true;
|
|
||||||
else
|
|
||||||
credits_index++;
|
|
||||||
} else {
|
|
||||||
text = credits[credits_index].name;
|
|
||||||
second = false;
|
|
||||||
credits_index++;
|
|
||||||
}
|
|
||||||
x_pos = 136;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(flag & 0x80)) {
|
|
||||||
text_line[c].set_parent_rect({{ x_pos, 200 - 16 }, { (Dim)text.size() * 8, 17 }});
|
|
||||||
text_line[c].set(text);
|
|
||||||
text_line[c].hidden(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scroll text lines
|
void CreditsWidget::paint(Painter&) {
|
||||||
for (c = 0; c < 10; c++) {
|
}
|
||||||
y_val = text_line[c].screen_pos().y() - 16;
|
|
||||||
if (y_val < 32) {
|
void CreditsWidget::on_show() {
|
||||||
text_line[c].set_parent_rect({{ text_line[c].screen_pos().x(), 200 }, { text_line[c].size() }});
|
clear();
|
||||||
text_line[c].hidden(true);
|
|
||||||
} else {
|
const auto screen_r = screen_rect();
|
||||||
if (y_val < 200) {
|
display.scroll_set_area(screen_r.top(), screen_r.bottom());
|
||||||
text_line[c].set_parent_rect({{ text_line[c].screen_pos().x(), y_val - 1 }, { text_line[c].size() }});
|
}
|
||||||
n = (y_val - 32) >> 2;
|
|
||||||
if (n > 19)
|
void CreditsWidget::on_hide() {
|
||||||
n = (38 - n);
|
display.scroll_disable();
|
||||||
else
|
}
|
||||||
n -= 3;
|
|
||||||
if (n > 3) n = 3;
|
void CreditsWidget::new_row(
|
||||||
if (n < 0) n = 0;
|
const std::array<Color, 240>& pixel_row
|
||||||
text_line[c].set_style(&styles[n]);
|
) {
|
||||||
}
|
const auto draw_y = display.scroll(-1);
|
||||||
}
|
|
||||||
|
display.draw_pixels(
|
||||||
|
{ { 0, draw_y }, { 240, 1 } },
|
||||||
|
pixel_row
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreditsWidget::clear() {
|
||||||
|
display.fill_rectangle(
|
||||||
|
screen_rect(),
|
||||||
|
Color::black()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AboutView::update() {
|
||||||
|
size_t i = 0;
|
||||||
|
std::array<Color, 240> pixel_row;
|
||||||
|
|
||||||
|
slow_down++;
|
||||||
|
if (slow_down & 1) return;
|
||||||
|
|
||||||
|
if (!timer) {
|
||||||
|
if (loop) {
|
||||||
|
credits_index = 0;
|
||||||
|
loop = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
text = credits[credits_index].text;
|
||||||
|
timer = credits[credits_index].delay;
|
||||||
|
start_pos = credits[credits_index].start_pos;
|
||||||
|
|
||||||
|
if (timer < 0) {
|
||||||
|
timer = 240;
|
||||||
|
loop = true;
|
||||||
|
} else {
|
||||||
|
timer += 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
render_line = 0;
|
||||||
|
credits_index++;
|
||||||
|
} else
|
||||||
|
timer--;
|
||||||
|
|
||||||
|
if (render_line < 16) {
|
||||||
|
for (const auto c : text) {
|
||||||
|
const auto glyph = style().font.glyph(c);
|
||||||
|
|
||||||
|
const size_t start = (glyph.size().width() / 8) * render_line;
|
||||||
|
for(Dim c=0; c<glyph.size().width(); c++) {
|
||||||
|
const auto pixel = glyph.pixels()[start + (c >> 3)] & (1U << (c & 0x7));
|
||||||
|
pixel_row[start_pos + i + c] = pixel ? Color::white() : Color::black();
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto advance = glyph.advance();
|
||||||
|
i += advance.x();
|
||||||
|
}
|
||||||
|
render_line++;
|
||||||
}
|
}
|
||||||
scroll++;
|
|
||||||
|
credits_display.new_row(pixel_row);
|
||||||
}
|
}
|
||||||
|
|
||||||
AboutView::AboutView(
|
AboutView::AboutView(
|
||||||
NavigationView& nav
|
NavigationView& nav
|
||||||
)
|
) {
|
||||||
{
|
add_children({
|
||||||
add_child(&button_ok);
|
&credits_display,
|
||||||
|
&button_ok
|
||||||
for (auto& text : text_line) {
|
});
|
||||||
text.set("");
|
|
||||||
text.set_parent_rect({
|
|
||||||
static_cast<Coord>(0),
|
|
||||||
static_cast<Coord>(200),
|
|
||||||
0, 0
|
|
||||||
});
|
|
||||||
add_child(&text);
|
|
||||||
}
|
|
||||||
|
|
||||||
button_ok.on_select = [&nav](Button&){
|
button_ok.on_select = [&nav](Button&){
|
||||||
nav.pop();
|
nav.pop();
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
#define __UI_ABOUT_H__
|
#define __UI_ABOUT_H__
|
||||||
|
|
||||||
#include "ui_widget.hpp"
|
#include "ui_widget.hpp"
|
||||||
#include "ui_menu.hpp"
|
|
||||||
#include "ui_navigation.hpp"
|
#include "ui_navigation.hpp"
|
||||||
#include "ui_font_fixed_8x16.hpp"
|
#include "ui_font_fixed_8x16.hpp"
|
||||||
|
|
||||||
@ -32,6 +31,21 @@
|
|||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
|
class CreditsWidget : public Widget {
|
||||||
|
public:
|
||||||
|
CreditsWidget(Rect parent_rect);
|
||||||
|
|
||||||
|
void on_show() override;
|
||||||
|
void on_hide() override;
|
||||||
|
|
||||||
|
void paint(Painter&) override;
|
||||||
|
|
||||||
|
void new_row(const std::array<Color, 240>& pixel_row);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void clear();
|
||||||
|
};
|
||||||
|
|
||||||
class AboutView : public View {
|
class AboutView : public View {
|
||||||
public:
|
public:
|
||||||
AboutView(NavigationView& nav);
|
AboutView(NavigationView& nav);
|
||||||
@ -43,33 +57,14 @@ public:
|
|||||||
private:
|
private:
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
uint8_t credits_index = 0;
|
uint8_t credits_index { 0 };
|
||||||
uint32_t scroll = 0;
|
uint8_t render_line { 0 };
|
||||||
bool second = false;
|
Coord start_pos { 0 };
|
||||||
bool line_feed = false;
|
uint8_t slow_down { 0 };
|
||||||
|
int32_t timer { 0 };
|
||||||
|
bool loop { false };
|
||||||
|
|
||||||
Style styles[4] = { style_black, style_dark_grey, style_light_grey, style_white };
|
std::string text { };
|
||||||
|
|
||||||
static constexpr Style style_white {
|
|
||||||
.font = font::fixed_8x16,
|
|
||||||
.background = Color::black(),
|
|
||||||
.foreground = Color(255, 255, 255)
|
|
||||||
};
|
|
||||||
static constexpr Style style_light_grey {
|
|
||||||
.font = font::fixed_8x16,
|
|
||||||
.background = Color::black(),
|
|
||||||
.foreground = Color(170, 170, 170)
|
|
||||||
};
|
|
||||||
static constexpr Style style_dark_grey {
|
|
||||||
.font = font::fixed_8x16,
|
|
||||||
.background = Color::black(),
|
|
||||||
.foreground = Color(85, 85, 85)
|
|
||||||
};
|
|
||||||
static constexpr Style style_black {
|
|
||||||
.font = font::fixed_8x16,
|
|
||||||
.background = Color::black(),
|
|
||||||
.foreground = Color(0, 0, 0)
|
|
||||||
};
|
|
||||||
|
|
||||||
enum flags {
|
enum flags {
|
||||||
SECTION = 0,
|
SECTION = 0,
|
||||||
@ -81,30 +76,35 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
typedef struct credits_t {
|
typedef struct credits_t {
|
||||||
std::string role;
|
size_t start_pos;
|
||||||
std::string name;
|
std::string text;
|
||||||
flags flag;
|
int32_t delay;
|
||||||
} credits_t;
|
} credits_t;
|
||||||
|
|
||||||
const credits_t credits[16] = { {"Portapack|HAVOC", "Git hash " GIT_REVISION, SECTION},
|
const credits_t credits[19] = {
|
||||||
{"Gurus", "J. Boone", TITLE},
|
{ 60, "PortaPack|HAVOC", 0 },
|
||||||
{"M. Ossmann", "", MEMBER_LF},
|
{ 7 * 8, "Git hash " GIT_REVISION, 16 },
|
||||||
{"HAVOC", "Furrtek", TITLE_LF},
|
{ 9 * 8, "Gurus J. Boone", 0 },
|
||||||
{"POCSAG rx", "T. Sailer", TITLE},
|
{ 16 * 8, "M. Ossmann", 16 },
|
||||||
{"E. Oenal", "", MEMBER_LF},
|
{ 9 * 8, "HAVOC Furrtek", 16 },
|
||||||
{"RDS waveform", "C. Jacquet", TITLE_LF},
|
{ 5 * 8, "POCSAG rx T. Sailer", 0 },
|
||||||
{"Xy. infos", "cLx", TITLE_LF},
|
{ 16 * 8, "E. Oenal", 16 },
|
||||||
{"World map", "NASA", TITLE_LF},
|
{ 2 * 8, "RDS waveform C. Jacquet", 16 },
|
||||||
{"Thanks", "", SECTION},
|
{ 5 * 8, "Xy. infos cLx", 16 },
|
||||||
{"Rainer Matla", "Keld Norman", TITLE},
|
{ 0, "OOK scan trick Samy Kamkar", 16 },
|
||||||
{"Giorgio C.", "DC1RDB", TITLE},
|
{ 5 * 8, "World map NASA", 24 },
|
||||||
{"Sigmounte", "Waax", TITLE},
|
{ 12 * 8, "Thanks", 16 },
|
||||||
{"Windyoona", "Channels", TITLE},
|
{ 1 * 8, "Rainer Matla Keld Norman", 0 },
|
||||||
{"F4GEV", "", TITLE_LF},
|
{ 1 * 8, " Giorgio C. DC1RDB", 0 },
|
||||||
{"", "MMXVII", END}
|
{ 1 * 8, " Sigmounte Waax", 0 },
|
||||||
};
|
{ 1 * 8, " Windyoona Channels", 0 },
|
||||||
|
{ 1 * 8, " F4GEV", 24 },
|
||||||
std::array<Text, 10> text_line { };
|
{ 12 * 8, "MMXVII", -1 }
|
||||||
|
};
|
||||||
|
|
||||||
|
CreditsWidget credits_display {
|
||||||
|
{ 0, 16, 240, 240 }
|
||||||
|
};
|
||||||
|
|
||||||
Button button_ok {
|
Button button_ok {
|
||||||
{ 72, 272, 96, 24 },
|
{ 72, 272, 96, 24 },
|
||||||
|
@ -25,47 +25,131 @@
|
|||||||
#include "baseband_api.hpp"
|
#include "baseband_api.hpp"
|
||||||
#include "string_format.hpp"
|
#include "string_format.hpp"
|
||||||
|
|
||||||
#include "portapack_persistent_memory.hpp"
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
using namespace portapack;
|
using namespace portapack;
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
void EncodersView::focus() {
|
EncodersConfigView::EncodersConfigView(
|
||||||
|
NavigationView& nav, Rect parent_rect
|
||||||
|
) {
|
||||||
|
using name_t = std::string;
|
||||||
|
using value_t = int32_t;
|
||||||
|
using option_t = std::pair<name_t, value_t>;
|
||||||
|
std::vector<option_t> enc_options;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
set_parent_rect(parent_rect);
|
||||||
|
hidden(true);
|
||||||
|
|
||||||
|
// Default encoder def
|
||||||
|
encoder_def = &encoder_defs[0];
|
||||||
|
|
||||||
|
add_children({
|
||||||
|
&labels,
|
||||||
|
&options_enctype,
|
||||||
|
&numberfield_clk,
|
||||||
|
&numberfield_bitduration,
|
||||||
|
&numberfield_wordduration,
|
||||||
|
&symfield_word,
|
||||||
|
&text_format,
|
||||||
|
&waveform
|
||||||
|
});
|
||||||
|
|
||||||
|
// Load encoder types in option field
|
||||||
|
for (i = 0; i < ENC_TYPES_COUNT; i++)
|
||||||
|
enc_options.emplace_back(std::make_pair(encoder_defs[i].name, i));
|
||||||
|
|
||||||
|
options_enctype.on_change = [this](size_t index, int32_t) {
|
||||||
|
on_type_change(index);
|
||||||
|
};
|
||||||
|
|
||||||
|
options_enctype.set_options(enc_options);
|
||||||
|
options_enctype.set_selected_index(0);
|
||||||
|
|
||||||
|
symfield_word.on_change = [this]() {
|
||||||
|
generate_frame();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Selecting input clock changes symbol and word duration
|
||||||
|
numberfield_clk.on_change = [this](int32_t value) {
|
||||||
|
// value is in kHz, new_value is in us
|
||||||
|
int32_t new_value = 1000000 / ((value * 1000) / encoder_def->clk_per_symbol);
|
||||||
|
if (new_value != numberfield_bitduration.value()) {
|
||||||
|
numberfield_bitduration.set_value(new_value, false);
|
||||||
|
numberfield_wordduration.set_value(new_value * encoder_def->word_length, false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Selecting symbol duration changes input clock and word duration
|
||||||
|
numberfield_bitduration.on_change = [this](int32_t value) {
|
||||||
|
int32_t new_value = 1000000 / (((float)value * 1000) / encoder_def->clk_per_symbol);
|
||||||
|
if (new_value != numberfield_clk.value()) {
|
||||||
|
numberfield_clk.set_value(new_value, false);
|
||||||
|
numberfield_wordduration.set_value(value * encoder_def->word_length, false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Selecting word duration changes input clock and symbol duration
|
||||||
|
numberfield_wordduration.on_change = [this](int32_t value) {
|
||||||
|
int32_t new_value = value / encoder_def->word_length;
|
||||||
|
if (new_value != numberfield_bitduration.value()) {
|
||||||
|
numberfield_bitduration.set_value(new_value, false);
|
||||||
|
numberfield_clk.set_value(1000000 / (((float)new_value * 1000) / encoder_def->clk_per_symbol), false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void EncodersConfigView::focus() {
|
||||||
options_enctype.focus();
|
options_enctype.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
EncodersView::~EncodersView() {
|
void EncodersConfigView::on_type_change(size_t index) {
|
||||||
transmitter_model.disable();
|
std::string word_format, format_string = "";
|
||||||
baseband::shutdown();
|
size_t word_length;
|
||||||
}
|
char symbol_type;
|
||||||
|
//size_t address_length;
|
||||||
|
|
||||||
|
//enc_type = index;
|
||||||
|
|
||||||
void EncodersView::generate_frame() {
|
encoder_def = &encoder_defs[index];
|
||||||
size_t i;
|
|
||||||
|
numberfield_clk.set_value(encoder_def->default_speed / 1000);
|
||||||
|
|
||||||
debug_text.clear();
|
// SymField setup
|
||||||
|
word_length = encoder_def->word_length;
|
||||||
i = 0;
|
symfield_word.set_length(word_length);
|
||||||
for (auto c : encoder_def->word_format) {
|
size_t n = 0, i = 0;
|
||||||
if (c == 'S')
|
while (n < word_length) {
|
||||||
debug_text += encoder_def->sync;
|
symbol_type = encoder_def->word_format.at(i++);
|
||||||
else
|
if (symbol_type == 'A') {
|
||||||
debug_text += encoder_def->bit_format[symfield_word.get_sym(i++)];
|
symfield_word.set_symbol_list(n++, encoder_def->address_symbols);
|
||||||
|
format_string += 'A';
|
||||||
|
} else if (symbol_type == 'D') {
|
||||||
|
symfield_word.set_symbol_list(n++, encoder_def->data_symbols);
|
||||||
|
format_string += 'D';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
draw_waveform();
|
// Ugly :( Pad to erase
|
||||||
|
format_string.append(24 - format_string.size(), ' ');
|
||||||
|
|
||||||
|
text_format.set(format_string);
|
||||||
|
|
||||||
|
generate_frame();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EncodersView::draw_waveform() {
|
void EncodersConfigView::on_show() {
|
||||||
uint32_t n, length;
|
// TODO: Remove ?
|
||||||
|
//options_enctype.set_selected_index(enc_type);
|
||||||
|
//on_type_change(enc_type);
|
||||||
|
}
|
||||||
|
|
||||||
length = debug_text.length();
|
void EncodersConfigView::draw_waveform() {
|
||||||
|
size_t length = frame_symbols.length();
|
||||||
|
size_t n;
|
||||||
|
|
||||||
for (n = 0; n < length; n++) {
|
for (n = 0; n < length; n++) {
|
||||||
if (debug_text[n] == '0')
|
if (frame_symbols[n] == '0')
|
||||||
waveform_buffer[n] = 0;
|
waveform_buffer[n] = 0;
|
||||||
else
|
else
|
||||||
waveform_buffer[n] = 1;
|
waveform_buffer[n] = 1;
|
||||||
@ -75,17 +159,82 @@ void EncodersView::draw_waveform() {
|
|||||||
waveform.set_dirty();
|
waveform.set_dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EncodersConfigView::generate_frame() {
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
frame_symbols.clear();
|
||||||
|
|
||||||
|
for (auto c : encoder_def->word_format) {
|
||||||
|
if (c == 'S')
|
||||||
|
frame_symbols += encoder_def->sync;
|
||||||
|
else
|
||||||
|
frame_symbols += encoder_def->bit_format[symfield_word.get_sym(i++)];
|
||||||
|
}
|
||||||
|
|
||||||
|
draw_waveform();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t EncodersConfigView::repeat_min() {
|
||||||
|
return encoder_def->repeat_min;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t EncodersConfigView::samples_per_bit() {
|
||||||
|
return OOK_SAMPLERATE / ((numberfield_clk.value() * 1000) / encoder_def->clk_per_fragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t EncodersConfigView::pause_symbols() {
|
||||||
|
return encoder_def->pause_symbols;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EncodersScanView::focus() {
|
||||||
|
field_debug.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
EncodersScanView::EncodersScanView(
|
||||||
|
NavigationView& nav, Rect parent_rect
|
||||||
|
) {
|
||||||
|
set_parent_rect(parent_rect);
|
||||||
|
hidden(true);
|
||||||
|
|
||||||
|
add_children({
|
||||||
|
&labels,
|
||||||
|
&field_debug,
|
||||||
|
&text_debug
|
||||||
|
});
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
field_debug.on_change = [this](int32_t value) {
|
||||||
|
uint32_t l;
|
||||||
|
de_bruijn debruijn_seq;
|
||||||
|
debruijn_seq.init(value);
|
||||||
|
l = 1;
|
||||||
|
l <<= value;
|
||||||
|
l--;
|
||||||
|
if (l > 25)
|
||||||
|
l = 25;
|
||||||
|
text_debug.set(to_string_bin(debruijn_seq.compute(l), 25));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void EncodersView::focus() {
|
||||||
|
tab_view.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
EncodersView::~EncodersView() {
|
||||||
|
transmitter_model.disable();
|
||||||
|
baseband::shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
void EncodersView::update_progress() {
|
void EncodersView::update_progress() {
|
||||||
char str[16];
|
std::string str_buffer;
|
||||||
|
|
||||||
// text_status.set(" ");
|
// text_status.set(" ");
|
||||||
|
|
||||||
if (tx_mode == SINGLE) {
|
if (tx_mode == SINGLE) {
|
||||||
strcpy(str, to_string_dec_uint(repeat_index).c_str());
|
str_buffer = to_string_dec_uint(repeat_index) + "/" + to_string_dec_uint(repeat_min);
|
||||||
strcat(str, "/");
|
text_status.set(str_buffer);
|
||||||
strcat(str, to_string_dec_uint(encoder_def->repeat_min).c_str());
|
|
||||||
text_status.set(str);
|
|
||||||
progress.set_value(repeat_index);
|
progress.set_value(repeat_index);
|
||||||
|
|
||||||
/*} else if (tx_mode == SCAN) {
|
/*} else if (tx_mode == SCAN) {
|
||||||
strcpy(str, to_string_dec_uint(repeat_index).c_str());
|
strcpy(str, to_string_dec_uint(repeat_index).c_str());
|
||||||
strcat(str, "/");
|
strcat(str, "/");
|
||||||
@ -107,7 +256,8 @@ void EncodersView::on_txdone(int n, const bool txdone) {
|
|||||||
|
|
||||||
if (!txdone) {
|
if (!txdone) {
|
||||||
// Repeating...
|
// Repeating...
|
||||||
repeat_index = n + 1;
|
//repeat_index = n + 1;
|
||||||
|
|
||||||
/*if (tx_mode == SCAN) {
|
/*if (tx_mode == SCAN) {
|
||||||
scan_progress++;
|
scan_progress++;
|
||||||
update_progress();
|
update_progress();
|
||||||
@ -147,14 +297,12 @@ void EncodersView::on_txdone(int n, const bool txdone) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EncodersView::on_tuning_frequency_changed(rf::Frequency f) {
|
|
||||||
transmitter_model.set_tuning_frequency(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EncodersView::start_tx(const bool scan) {
|
void EncodersView::start_tx(const bool scan) {
|
||||||
char ook_bitstream[256];
|
|
||||||
uint32_t ook_bitstream_length;
|
|
||||||
(void)scan;
|
(void)scan;
|
||||||
|
uint8_t* ook_bitstream = shared_memory.bb_data.data;
|
||||||
|
uint32_t ook_bitstream_length;
|
||||||
|
|
||||||
|
repeat_min = view_config.repeat_min();
|
||||||
|
|
||||||
/*if (scan) {
|
/*if (scan) {
|
||||||
if (tx_mode != SCAN) {
|
if (tx_mode != SCAN) {
|
||||||
@ -170,17 +318,17 @@ void EncodersView::start_tx(const bool scan) {
|
|||||||
} else {*/
|
} else {*/
|
||||||
tx_mode = SINGLE;
|
tx_mode = SINGLE;
|
||||||
repeat_index = 1;
|
repeat_index = 1;
|
||||||
progress.set_max(encoder_def->repeat_min);
|
progress.set_max(repeat_min);
|
||||||
update_progress();
|
update_progress();
|
||||||
//}
|
//}
|
||||||
|
|
||||||
generate_frame();
|
view_config.generate_frame();
|
||||||
|
|
||||||
// Clear bitstream
|
// Clear bitstream
|
||||||
memset(ook_bitstream, 0, 256);
|
memset(ook_bitstream, 0, 256);
|
||||||
|
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
for (auto c : debug_text) {
|
for (auto c : view_config.frame_symbols) {
|
||||||
if (c != '0')
|
if (c != '0')
|
||||||
ook_bitstream[n >> 3] |= (1 << (7 - (n & 7)));
|
ook_bitstream[n >> 3] |= (1 << (7 - (n & 7)));
|
||||||
n++;
|
n++;
|
||||||
@ -188,158 +336,41 @@ void EncodersView::start_tx(const bool scan) {
|
|||||||
|
|
||||||
ook_bitstream_length = n;
|
ook_bitstream_length = n;
|
||||||
|
|
||||||
transmitter_model.set_sampling_rate(2280000U);
|
transmitter_model.set_sampling_rate(OOK_SAMPLERATE);
|
||||||
transmitter_model.set_rf_amp(true);
|
transmitter_model.set_rf_amp(true);
|
||||||
transmitter_model.set_baseband_bandwidth(1750000);
|
transmitter_model.set_baseband_bandwidth(1750000);
|
||||||
transmitter_model.enable();
|
transmitter_model.enable();
|
||||||
|
|
||||||
memcpy(shared_memory.bb_data.data, ook_bitstream, 256);
|
|
||||||
|
|
||||||
baseband::set_ook_data(
|
baseband::set_ook_data(
|
||||||
ook_bitstream_length,
|
ook_bitstream_length,
|
||||||
// 2280000/2 = 1140000Hz = 0,877192982us
|
// 2280000/2 = 1140000Hz = 0,877192982us
|
||||||
// numberfield_clk.value() / encoder_def->clk_per_fragment
|
// numberfield_clk.value() / encoder_def->clk_per_fragment
|
||||||
// 455000 / 12 = 37917Hz = 26,37339452us
|
// 455000 / 12 = 37917Hz = 26,37339452us
|
||||||
228000 / ((numberfield_clk.value() * 1000) / encoder_def->clk_per_fragment),
|
view_config.samples_per_bit(),
|
||||||
encoder_def->repeat_min,
|
repeat_min,
|
||||||
encoder_def->pause_symbols
|
view_config.pause_symbols()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EncodersView::on_type_change(size_t index) {
|
EncodersView::EncodersView(
|
||||||
std::string word_format, format_string = "";
|
NavigationView& nav
|
||||||
size_t word_length;
|
) : nav_ { nav }
|
||||||
char symbol_type;
|
{
|
||||||
//size_t address_length;
|
|
||||||
|
|
||||||
enc_type = index;
|
|
||||||
|
|
||||||
encoder_def = &encoder_defs[enc_type];
|
|
||||||
|
|
||||||
numberfield_clk.set_value(encoder_def->default_speed / 1000);
|
|
||||||
|
|
||||||
// SymField setup
|
|
||||||
word_length = encoder_def->word_length;
|
|
||||||
symfield_word.set_length(word_length);
|
|
||||||
size_t n = 0, i = 0;
|
|
||||||
while (n < word_length) {
|
|
||||||
symbol_type = encoder_def->word_format.at(i++);
|
|
||||||
if (symbol_type == 'A') {
|
|
||||||
symfield_word.set_symbol_list(n++, encoder_def->address_symbols);
|
|
||||||
format_string += 'A';
|
|
||||||
} else if (symbol_type == 'D') {
|
|
||||||
symfield_word.set_symbol_list(n++, encoder_def->data_symbols);
|
|
||||||
format_string += 'D';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ugly :( Pad to erase
|
|
||||||
while (format_string.length() < 24)
|
|
||||||
format_string += ' ';
|
|
||||||
|
|
||||||
text_format.set(format_string);
|
|
||||||
|
|
||||||
generate_frame();
|
|
||||||
}
|
|
||||||
|
|
||||||
void EncodersView::on_show() {
|
|
||||||
// TODO: Remove ?
|
|
||||||
options_enctype.set_selected_index(enc_type);
|
|
||||||
on_type_change(enc_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
EncodersView::EncodersView(NavigationView& nav) {
|
|
||||||
using name_t = std::string;
|
|
||||||
using value_t = int32_t;
|
|
||||||
using option_t = std::pair<name_t, value_t>;
|
|
||||||
using options_t = std::vector<option_t>;
|
|
||||||
options_t enc_options;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
baseband::run_image(portapack::spi_flash::image_tag_ook);
|
baseband::run_image(portapack::spi_flash::image_tag_ook);
|
||||||
|
|
||||||
// Default encoder def
|
|
||||||
encoder_def = &encoder_defs[0];
|
|
||||||
|
|
||||||
add_children({
|
add_children({
|
||||||
&labels,
|
&tab_view,
|
||||||
&options_enctype,
|
&view_config,
|
||||||
&numberfield_clk,
|
&view_scan,
|
||||||
&numberfield_bitduration,
|
|
||||||
&numberfield_wordduration,
|
|
||||||
//&field_debug,
|
|
||||||
&symfield_word,
|
|
||||||
&text_format,
|
|
||||||
//&text_format_a, // DEBUG
|
|
||||||
//&text_format_d, // DEBUG
|
|
||||||
&waveform,
|
|
||||||
&text_status,
|
&text_status,
|
||||||
&progress,
|
&progress,
|
||||||
&tx_view
|
&tx_view
|
||||||
});
|
});
|
||||||
|
|
||||||
// Load encoder types
|
|
||||||
for (i = 0; i < ENC_TYPES_COUNT; i++)
|
|
||||||
enc_options.emplace_back(std::make_pair(encoder_defs[i].name, i));
|
|
||||||
|
|
||||||
options_enctype.on_change = [this](size_t index, int32_t value) {
|
|
||||||
(void)value;
|
|
||||||
this->on_type_change(index);
|
|
||||||
};
|
|
||||||
|
|
||||||
options_enctype.set_options(enc_options);
|
|
||||||
options_enctype.set_selected_index(0);
|
|
||||||
|
|
||||||
symfield_word.on_change = [this]() {
|
|
||||||
this->generate_frame();
|
|
||||||
};
|
|
||||||
|
|
||||||
// DEBUG
|
|
||||||
/*field_debug.on_change = [this](int32_t value) {
|
|
||||||
uint32_t l;
|
|
||||||
de_bruijn debruijn_seq;
|
|
||||||
debruijn_seq.init(value);
|
|
||||||
l = 1;
|
|
||||||
l <<= value;
|
|
||||||
l--;
|
|
||||||
if (l > 25)
|
|
||||||
l = 25;
|
|
||||||
text_format.set(to_string_bin(debruijn_seq.compute(l), 25));
|
|
||||||
};*/
|
|
||||||
|
|
||||||
// Selecting input clock changes symbol and word duration
|
|
||||||
numberfield_clk.on_change = [this](int32_t value) {
|
|
||||||
//int32_t new_value = 1000000 / (((float)value * 1000) / encoder_def->clk_per_symbol);
|
|
||||||
// value is in kHz, new_value is in us
|
|
||||||
int32_t new_value = 1000000 / ((value * 1000) / encoder_def->clk_per_symbol);
|
|
||||||
if (new_value != numberfield_bitduration.value()) {
|
|
||||||
numberfield_bitduration.set_value(new_value, false);
|
|
||||||
numberfield_wordduration.set_value(new_value * encoder_def->word_length, false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Selecting symbol duration changes input clock and word duration
|
|
||||||
numberfield_bitduration.on_change = [this](int32_t value) {
|
|
||||||
int32_t new_value = 1000000 / (((float)value * 1000) / encoder_def->clk_per_symbol);
|
|
||||||
if (new_value != numberfield_clk.value()) {
|
|
||||||
numberfield_clk.set_value(new_value, false);
|
|
||||||
numberfield_wordduration.set_value(value * encoder_def->word_length, false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Selecting word duration changes input clock and symbol duration
|
|
||||||
numberfield_wordduration.on_change = [this](int32_t value) {
|
|
||||||
int32_t new_value = value / encoder_def->word_length;
|
|
||||||
if (new_value != numberfield_bitduration.value()) {
|
|
||||||
numberfield_bitduration.set_value(new_value, false);
|
|
||||||
numberfield_clk.set_value(1000000 / (((float)new_value * 1000) / encoder_def->clk_per_symbol), false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
tx_view.on_edit_frequency = [this, &nav]() {
|
tx_view.on_edit_frequency = [this, &nav]() {
|
||||||
auto new_view = nav.push<FrequencyKeypadView>(receiver_model.tuning_frequency());
|
auto new_view = nav.push<FrequencyKeypadView>(transmitter_model.tuning_frequency());
|
||||||
new_view->on_changed = [this](rf::Frequency f) {
|
new_view->on_changed = [this](rf::Frequency f) {
|
||||||
receiver_model.set_tuning_frequency(f);
|
transmitter_model.set_tuning_frequency(f);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -21,37 +21,151 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ui.hpp"
|
#include "ui.hpp"
|
||||||
#include "ui_widget.hpp"
|
#include "ui_tabview.hpp"
|
||||||
#include "ui_navigation.hpp"
|
|
||||||
#include "ui_font_fixed_8x16.hpp"
|
|
||||||
#include "ui_receiver.hpp"
|
|
||||||
#include "ui_transmitter.hpp"
|
#include "ui_transmitter.hpp"
|
||||||
|
#include "transmitter_model.hpp"
|
||||||
#include "encoders.hpp"
|
#include "encoders.hpp"
|
||||||
#include "de_bruijn.hpp"
|
#include "de_bruijn.hpp"
|
||||||
#include "message.hpp"
|
|
||||||
#include "transmitter_model.hpp"
|
|
||||||
|
|
||||||
using namespace encoders;
|
using namespace encoders;
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
|
class EncodersConfigView : public View {
|
||||||
|
public:
|
||||||
|
EncodersConfigView(NavigationView& nav, Rect parent_rect);
|
||||||
|
|
||||||
|
EncodersConfigView(const EncodersConfigView&) = delete;
|
||||||
|
EncodersConfigView(EncodersConfigView&&) = delete;
|
||||||
|
EncodersConfigView& operator=(const EncodersConfigView&) = delete;
|
||||||
|
EncodersConfigView& operator=(EncodersConfigView&&) = delete;
|
||||||
|
|
||||||
|
void focus() override;
|
||||||
|
void on_show() override;
|
||||||
|
|
||||||
|
uint8_t repeat_min();
|
||||||
|
uint32_t samples_per_bit();
|
||||||
|
uint32_t pause_symbols();
|
||||||
|
void generate_frame();
|
||||||
|
|
||||||
|
std::string frame_symbols = "0";
|
||||||
|
|
||||||
|
private:
|
||||||
|
//bool abort_scan = false;
|
||||||
|
//uint8_t scan_count;
|
||||||
|
//double scan_progress;
|
||||||
|
//unsigned int scan_index;
|
||||||
|
int8_t waveform_buffer[512];
|
||||||
|
const encoder_def_t * encoder_def { };
|
||||||
|
//uint8_t enc_type = 0;
|
||||||
|
|
||||||
|
void draw_waveform();
|
||||||
|
void on_bitfield();
|
||||||
|
void on_type_change(size_t index);
|
||||||
|
|
||||||
|
Labels labels {
|
||||||
|
{ { 1 * 8, 0 }, "Type:", Color::light_grey() },
|
||||||
|
{ { 16 * 8, 0 }, "Clk:", Color::light_grey() },
|
||||||
|
{ { 24 * 8, 0 }, "kHz", Color::light_grey() },
|
||||||
|
{ { 16 * 8, 2 * 8 }, "Bit:", Color::light_grey() },
|
||||||
|
{ { 25 * 8, 2 * 8 }, "us", Color::light_grey() },
|
||||||
|
{ { 15 * 8, 4 * 8 }, "Word:", Color::light_grey() },
|
||||||
|
{ { 26 * 8, 4 * 8 }, "us", Color::light_grey() },
|
||||||
|
{ { 2 * 8, 6 * 8 }, "Word:", Color::light_grey() },
|
||||||
|
{ { 1 * 8, 13 * 8 }, "Waveform:", Color::light_grey() }
|
||||||
|
};
|
||||||
|
|
||||||
|
OptionsField options_enctype { // Options are loaded at runtime
|
||||||
|
{ 6 * 8, 0 },
|
||||||
|
7,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
NumberField numberfield_clk {
|
||||||
|
{ 21 * 8, 0 },
|
||||||
|
3,
|
||||||
|
{ 1, 500 },
|
||||||
|
1,
|
||||||
|
' '
|
||||||
|
};
|
||||||
|
|
||||||
|
NumberField numberfield_bitduration {
|
||||||
|
{ 21 * 8, 2 * 8 },
|
||||||
|
4,
|
||||||
|
{ 50, 9999 },
|
||||||
|
1,
|
||||||
|
' '
|
||||||
|
};
|
||||||
|
|
||||||
|
NumberField numberfield_wordduration {
|
||||||
|
{ 21 * 8, 4 * 8 },
|
||||||
|
5,
|
||||||
|
{ 300, 99999 },
|
||||||
|
100,
|
||||||
|
' '
|
||||||
|
};
|
||||||
|
|
||||||
|
SymField symfield_word {
|
||||||
|
{ 2 * 8, 8 * 8 },
|
||||||
|
20,
|
||||||
|
SymField::SYMFIELD_DEF
|
||||||
|
};
|
||||||
|
|
||||||
|
Text text_format {
|
||||||
|
{ 2 * 8, 10 * 8, 24 * 8, 16 },
|
||||||
|
""
|
||||||
|
};
|
||||||
|
|
||||||
|
Waveform waveform {
|
||||||
|
{ 0, 16 * 8, 240, 32 },
|
||||||
|
waveform_buffer,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
true,
|
||||||
|
Color::yellow()
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class EncodersScanView : public View {
|
||||||
|
public:
|
||||||
|
EncodersScanView(NavigationView& nav, Rect parent_rect);
|
||||||
|
|
||||||
|
void focus() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Labels labels {
|
||||||
|
{ { 1 * 8, 1 * 8 }, "Test", Color::light_grey() }
|
||||||
|
};
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
NumberField field_debug {
|
||||||
|
{ 1 * 8, 6 * 8 },
|
||||||
|
2,
|
||||||
|
{ 3, 16 },
|
||||||
|
1,
|
||||||
|
' '
|
||||||
|
};
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
Text text_debug {
|
||||||
|
{ 1 * 8, 8 * 8, 24 * 8, 16 },
|
||||||
|
""
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
class EncodersView : public View {
|
class EncodersView : public View {
|
||||||
public:
|
public:
|
||||||
EncodersView(NavigationView& nav);
|
EncodersView(NavigationView& nav);
|
||||||
~EncodersView();
|
~EncodersView();
|
||||||
|
|
||||||
EncodersView(const EncodersView&) = delete;
|
|
||||||
EncodersView(EncodersView&&) = delete;
|
|
||||||
EncodersView& operator=(const EncodersView&) = delete;
|
|
||||||
EncodersView& operator=(EncodersView&&) = delete;
|
|
||||||
|
|
||||||
void focus() override;
|
void focus() override;
|
||||||
void on_show() override;
|
|
||||||
|
|
||||||
std::string title() const override { return "Encoders TX"; };
|
std::string title() const override { return "OOK transmit"; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void on_tuning_frequency_changed(rf::Frequency f);
|
NavigationView& nav_;
|
||||||
|
|
||||||
enum tx_modes {
|
enum tx_modes {
|
||||||
IDLE = 0,
|
IDLE = 0,
|
||||||
@ -59,36 +173,14 @@ private:
|
|||||||
SCAN
|
SCAN
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t enc_type = 0;
|
|
||||||
const encoder_def_t * encoder_def { };
|
|
||||||
tx_modes tx_mode = IDLE;
|
tx_modes tx_mode = IDLE;
|
||||||
//bool abort_scan = false;
|
|
||||||
//uint8_t scan_count;
|
|
||||||
//double scan_progress;
|
|
||||||
//unsigned int scan_index;
|
|
||||||
std::string debug_text = "0";
|
|
||||||
uint8_t repeat_index { 0 };
|
uint8_t repeat_index { 0 };
|
||||||
int8_t waveform_buffer[512];
|
uint8_t repeat_min { 0 };
|
||||||
|
|
||||||
void draw_waveform();
|
|
||||||
void on_bitfield();
|
|
||||||
void on_type_change(size_t index);
|
|
||||||
void generate_frame();
|
|
||||||
void update_progress();
|
void update_progress();
|
||||||
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_val {
|
|
||||||
.font = font::fixed_8x16,
|
|
||||||
.background = Color::black(),
|
|
||||||
.foreground = Color::green(),
|
|
||||||
};
|
|
||||||
const Style style_cancel {
|
|
||||||
.font = font::fixed_8x16,
|
|
||||||
.background = Color::black(),
|
|
||||||
.foreground = Color::red(),
|
|
||||||
};
|
|
||||||
|
|
||||||
const Style style_address {
|
const Style style_address {
|
||||||
.font = font::fixed_8x16,
|
.font = font::fixed_8x16,
|
||||||
.background = Color::black(),
|
.background = Color::black(),
|
||||||
@ -100,85 +192,21 @@ private:
|
|||||||
.foreground = Color::blue(),
|
.foreground = Color::blue(),
|
||||||
};
|
};
|
||||||
|
|
||||||
Labels labels {
|
Rect view_rect = { 0, 5 * 8, 240, 168 };
|
||||||
{ { 1 * 8, 4 * 8 }, "Type:", Color::light_grey() },
|
|
||||||
{ { 16 * 8, 4 * 8 }, "Clk:", Color::light_grey() },
|
EncodersConfigView view_config { nav_, view_rect };
|
||||||
{ { 24 * 8, 4 * 8 }, "kHz", Color::light_grey() },
|
EncodersScanView view_scan { nav_, view_rect };
|
||||||
{ { 16 * 8, 6 * 8 }, "Bit:", Color::light_grey() },
|
|
||||||
{ { 25 * 8, 6 * 8 }, "us", Color::light_grey() },
|
TabView tab_view {
|
||||||
{ { 15 * 8, 8 * 8 }, "Word:", Color::light_grey() },
|
{ "Config", Color::cyan(), &view_config },
|
||||||
{ { 26 * 8, 8 * 8 }, "us", Color::light_grey() },
|
{ "Scan", Color::green(), &view_scan },
|
||||||
{ { 2 * 8, 10 * 8 }, "Word:", Color::light_grey() },
|
|
||||||
{ { 1 * 8, 17 * 8 }, "Waveform:", Color::light_grey() }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
OptionsField options_enctype { // Options are loaded at runtime
|
|
||||||
{ 6 * 8, 32 },
|
|
||||||
7,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
NumberField numberfield_clk {
|
|
||||||
{ 21 * 8, 4 * 8 },
|
|
||||||
3,
|
|
||||||
{ 1, 500 },
|
|
||||||
1,
|
|
||||||
' '
|
|
||||||
};
|
|
||||||
|
|
||||||
NumberField numberfield_bitduration {
|
|
||||||
{ 21 * 8, 6 * 8 },
|
|
||||||
4,
|
|
||||||
{ 50, 9999 },
|
|
||||||
1,
|
|
||||||
' '
|
|
||||||
};
|
|
||||||
|
|
||||||
NumberField numberfield_wordduration {
|
|
||||||
{ 21 * 8, 8 * 8 },
|
|
||||||
5,
|
|
||||||
{ 300, 99999 },
|
|
||||||
100,
|
|
||||||
' '
|
|
||||||
};
|
|
||||||
|
|
||||||
// DEBUG
|
|
||||||
/*NumberField field_debug {
|
|
||||||
{ 21 * 8, 10 * 8 },
|
|
||||||
2,
|
|
||||||
{ 3, 16 },
|
|
||||||
1,
|
|
||||||
' '
|
|
||||||
};*/
|
|
||||||
|
|
||||||
SymField symfield_word {
|
|
||||||
{ 2 * 8, 12 * 8 },
|
|
||||||
20,
|
|
||||||
SymField::SYMFIELD_DEF
|
|
||||||
};
|
|
||||||
Text text_format {
|
|
||||||
{ 2 * 8, 14 * 8, 24 * 8, 16 },
|
|
||||||
""
|
|
||||||
};
|
|
||||||
|
|
||||||
//Text text_format_a; // DEBUG
|
|
||||||
//Text text_format_d; // DEBUG
|
|
||||||
|
|
||||||
Waveform waveform {
|
|
||||||
{ 0, 160, 240, 32 },
|
|
||||||
waveform_buffer,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
true,
|
|
||||||
Color::yellow()
|
|
||||||
};
|
|
||||||
|
|
||||||
Text text_status {
|
Text text_status {
|
||||||
{ 2 * 8, 13 * 16, 128, 16 },
|
{ 2 * 8, 13 * 16, 128, 16 },
|
||||||
"Ready"
|
"Ready"
|
||||||
};
|
};
|
||||||
|
|
||||||
ProgressBar progress {
|
ProgressBar progress {
|
||||||
{ 2 * 8, 13 * 16 + 20, 208, 16 }
|
{ 2 * 8, 13 * 16 + 20, 208, 16 }
|
||||||
};
|
};
|
||||||
|
@ -219,6 +219,8 @@ void GeoMapView::focus() {
|
|||||||
void GeoMapView::update_position(float lat, float lon) {
|
void GeoMapView::update_position(float lat, float lon) {
|
||||||
lat_ = lat;
|
lat_ = lat;
|
||||||
lon_ = lon;
|
lon_ = lon;
|
||||||
|
geopos.set_lat(lat_);
|
||||||
|
geopos.set_lon(lon_);
|
||||||
geomap.move(lon_, lat_);
|
geomap.move(lon_, lat_);
|
||||||
geomap.set_dirty();
|
geomap.set_dirty();
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ void OOKProcessor::on_message(const Message* const p) {
|
|||||||
const auto message = *reinterpret_cast<const OOKConfigureMessage*>(p);
|
const auto message = *reinterpret_cast<const OOKConfigureMessage*>(p);
|
||||||
|
|
||||||
if (message.id == Message::ID::OOKConfigure) {
|
if (message.id == Message::ID::OOKConfigure) {
|
||||||
samples_per_bit = message.samples_per_bit;
|
samples_per_bit = message.samples_per_bit / 10;
|
||||||
repeat = message.repeat - 1;
|
repeat = message.repeat - 1;
|
||||||
length = message.stream_length - 1;
|
length = message.stream_length - 1;
|
||||||
pause = message.pause_symbols + 1;
|
pause = message.pause_symbols + 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user