Added remaining buttons for TouchTunes remote

LCR transmit UI cleanup
CC1101 data whitening function
Uniformized tx progress message handling
This commit is contained in:
furrtek 2017-09-24 20:05:42 +01:00
parent 26949773bb
commit 73d47cd77d
48 changed files with 504 additions and 486 deletions

View File

@ -24,4 +24,23 @@
namespace cc1101 {
void CC1101Emu::whitening_init() {
whitening_pn = 0x1FF;
}
// See TI app note DN509
uint8_t CC1101Emu::whiten_byte(uint8_t byte) {
uint_fast8_t new_bit;
byte ^= (whitening_pn & 0xFF);
for (size_t step = 0; step < 8; step++) {
new_bit = (whitening_pn & 1) ^ ((whitening_pn >> 5) & 1);
whitening_pn >>= 1;
whitening_pn |= (new_bit << 8);
}
return byte;
}
} /* namespace cc1101 */

View File

@ -30,20 +30,21 @@ using namespace portapack;
namespace modems {
void generate_data(const std::string& in_message, uint16_t * out_data) {
serial_format_t serial_format;
uint8_t parity_init, parity, data_bits, bits, bit, cur_byte;
uint16_t ordered_word, bytes;
uint8_t parity_init, parity, bits, bit, cur_byte;
uint16_t ordered_word;
size_t bytes;
serial_format = persistent_memory::serial_format();
serial_format_t serial_format = persistent_memory::serial_format();
size_t message_length = in_message.length();
if (serial_format.parity == ODD)
parity_init = 1;
else
parity_init = 0;
data_bits = serial_format.data_bits;
uint8_t data_bits = serial_format.data_bits;
for (bytes = 0; bytes < in_message.length(); bytes++) {
for (bytes = 0; bytes < message_length; bytes++) {
parity = parity_init;
cur_byte = in_message[bytes];
bit = 0;
@ -81,18 +82,17 @@ void generate_data(const std::string& in_message, uint16_t * out_data) {
// 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;
uint32_t cur_bit, deframed_word { 0 };
size_t bit;
serial_format = persistent_memory::serial_format();
serial_format_t serial_format = persistent_memory::serial_format();
/*if (serial_format.parity == ODD)
parity = 1;
else
parity = 0;*/
bits = serial_format.data_bits;
size_t data_bits = serial_format.data_bits;
// Ignore parity for now
if (serial_format.parity)
@ -100,7 +100,7 @@ uint32_t deframe_word(uint32_t raw_word) {
if (serial_format.bit_order == LSB_FIRST) {
// Reverse data bits
for (bit = 0; bit < bits; bit++) {
for (bit = 0; bit < data_bits; bit++) {
cur_bit = raw_word & 1;
deframed_word <<= 1;

View File

@ -30,6 +30,7 @@
namespace modems {
#define MODEM_DEF_COUNT 7
#define AFSK_TX_SAMPLERATE 1536000U
enum ModemModulation {
AFSK = 0,

View File

@ -38,7 +38,7 @@ namespace encoders {
struct encoder_def_t {
std::string name; // Encoder chip ref/name
std::string address_symbols; // "01", "01F"...
std::string address_symbols; // List of possible symbols like "01", "01F"...
std::string data_symbols; // Same
uint16_t clk_per_symbol; // Oscillator periods per symbol
uint16_t clk_per_fragment; // Oscillator periods per symbol fragment (state)
@ -51,7 +51,7 @@ namespace encoders {
uint16_t pause_symbols; // Length of pause between repeats in symbols
};
// Warning ! If this is changed, make sure that the UM3750 index is still good in ui_bht_tx.cpp !
// Warning ! If this is changed, make sure that ENCODER_UM3750 is still valid !
const encoder_def_t encoder_defs[ENC_TYPES_COUNT] = {
// PT2260-R2
{

View File

@ -30,21 +30,20 @@ namespace serializer {
/* Raw: 00110110100111
* NRZ-L: 00110110100111
* NRZ-M: 00100100111010
* NRZ-S: 10001110010000
* RZ: 00 00 10 10 00 10 10 00 10 00 00 10 10 10
* Bi-L: 01 01 10 10 01 10 10 01 10 01 01 10 10 10
* Bi-M: 00 11 01 01 00 10 10 11 01 00 11 01 01 01
* Bi-S: 01 01 00 11 01 00 11 01 00 10 10 11 00 11
* NRZ-M: 00100100111010 (1 = transition)
* NRZ-S: ?0001110010000 (0 = transition)
* RZ: 00 00 10 10 00 10 10 00 10 00 00 10 10 10 (half bits)
* Bi-L: 01 01 10 10 01 10 10 01 10 01 01 10 10 10 (1 = high to low, 0 = low to high)
* Bi-M: 00 11 01 01 00 10 10 11 01 00 11 01 01 01 (1 = mid-bit transition, 0 = invert last level)
* Bi-S: 01 01 00 11 01 00 11 01 00 10 10 11 00 11 (the opposite)
* Diff M.: ...
*/
size_t symbol_count(const serial_format_t& serial_format) {
size_t count;
count = 1 + serial_format.data_bits; // Start
count = 1 + serial_format.data_bits + serial_format.stop_bits; // Start + data + stop
if (serial_format.parity) count++;
count += serial_format.stop_bits;
return count;
};

View File

@ -63,8 +63,10 @@ void APRSTXView::start_tx() {
transmitter_model.enable();*/
}
void APRSTXView::on_txdone(const bool v) {
if (v) {
void APRSTXView::on_tx_progress(const uint32_t progress, const bool done) {
(void)progress;
if (done) {
transmitter_model.disable();
tx_view.set_transmitting(false);
//progress.set_value(0);

View File

@ -56,7 +56,7 @@ private:
void start_tx();
void generate_frame();
void generate_frame_pos();
void on_txdone(const bool v);
void on_tx_progress(const uint32_t progress, const bool done);
Labels labels {
{ { 2 * 8, 2 * 8 }, "Work in progress...", Color::light_grey() }
@ -74,11 +74,11 @@ private:
true
};
MessageHandlerRegistration message_handler_tx_done {
Message::ID::TXDone,
MessageHandlerRegistration message_handler_tx_progress {
Message::ID::TXProgress,
[this](const Message* const p) {
const auto message = *reinterpret_cast<const TXDoneMessage*>(p);
this->on_txdone(message.done);
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
this->on_tx_progress(message.progress, message.done);
}
};
};

View File

@ -81,7 +81,7 @@ void BHTView::start_tx() {
}
}
void BHTView::on_tx_progress(const int progress, const bool done) {
void BHTView::on_tx_progress(const uint32_t progress, const bool done) {
//if (view_xylos.tx_mode == XylosView::tx_modes::SINGLE) {
if (done) {

View File

@ -221,7 +221,7 @@ public:
std::string title() const override { return "BHT transmit"; };
private:
void on_tx_progress(const int progress, const bool done);
void on_tx_progress(const uint32_t progress, const bool done);
void start_tx();
enum tx_type_t {
@ -272,10 +272,10 @@ private:
12
};
MessageHandlerRegistration message_handler_tx_done {
Message::ID::TXDone,
MessageHandlerRegistration message_handler_tx_progress {
Message::ID::TXProgress,
[this](const Message* const p) {
const auto message = *reinterpret_cast<const TXDoneMessage*>(p);
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
this->on_tx_progress(message.progress, message.done);
}
};

View File

@ -75,8 +75,9 @@ void CoasterPagerView::start_tx() {
baseband::set_fsk_data(19 * 8, 2280000 / 1000, 5000, 32);
}
void CoasterPagerView::on_tx_progress(const int progress, const bool done) {
void CoasterPagerView::on_tx_progress(const uint32_t progress, const bool done) {
(void)progress;
uint16_t address = 0;
uint32_t c;

View File

@ -52,7 +52,7 @@ private:
void start_tx();
void generate_frame();
void on_tx_progress(const int progress, const bool done);
void on_tx_progress(const uint32_t progress, const bool done);
Labels labels {
{ { 1 * 8, 3 * 8 }, "Syscall pager TX beta", Color::light_grey() },
@ -85,10 +85,10 @@ private:
12
};
MessageHandlerRegistration message_handler_tx_done {
Message::ID::TXDone,
MessageHandlerRegistration message_handler_tx_progress {
Message::ID::TXProgress,
[this](const Message* const p) {
const auto message = *reinterpret_cast<const TXDoneMessage*>(p);
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
this->on_tx_progress(message.progress, message.done);
}
};

View File

@ -219,7 +219,7 @@ void EncodersView::update_progress() {
if (tx_mode == SINGLE) {
str_buffer = to_string_dec_uint(repeat_index) + "/" + to_string_dec_uint(repeat_min);
text_status.set(str_buffer);
progress.set_value(repeat_index);
progressbar.set_value(repeat_index);
/*} else if (tx_mode == SCAN) {
strcpy(str, to_string_dec_uint(repeat_index).c_str());
@ -233,16 +233,16 @@ void EncodersView::update_progress() {
progress.set_value(scan_progress);*/
} else {
text_status.set("Ready");
progress.set_value(0);
progressbar.set_value(0);
}
}
void EncodersView::on_txdone(int n, const bool txdone) {
void EncodersView::on_tx_progress(const uint32_t progress, const bool done) {
//char str[16];
if (!txdone) {
if (!done) {
// Repeating...
repeat_index = n + 1;
repeat_index = progress + 1;
/*if (tx_mode == SCAN) {
scan_progress++;
@ -277,7 +277,7 @@ void EncodersView::on_txdone(int n, const bool txdone) {
transmitter_model.disable();
tx_mode = IDLE;
text_status.set("Done");
progress.set_value(0);
progressbar.set_value(0);
tx_view.set_transmitting(false);
//}
}
@ -303,7 +303,7 @@ void EncodersView::start_tx(const bool scan) {
} else {*/
tx_mode = SINGLE;
repeat_index = 1;
progress.set_max(repeat_min);
progressbar.set_max(repeat_min);
update_progress();
//}
@ -335,7 +335,7 @@ EncodersView::EncodersView(
&view_config,
&view_scan,
&text_status,
&progress,
&progressbar,
&tx_view
});

View File

@ -175,7 +175,7 @@ private:
void update_progress();
void start_tx(const bool scan);
void on_txdone(int n, const bool txdone);
void on_tx_progress(const uint32_t progress, const bool done);
/*const Style style_address {
.font = font::fixed_8x16,
@ -203,7 +203,7 @@ private:
"Ready"
};
ProgressBar progress {
ProgressBar progressbar {
{ 2 * 8, 13 * 16 + 20, 208, 16 }
};
@ -213,11 +213,11 @@ private:
9
};
MessageHandlerRegistration message_handler_tx_done {
Message::ID::TXDone,
MessageHandlerRegistration message_handler_tx_progress {
Message::ID::TXProgress,
[this](const Message* const p) {
const auto message = *reinterpret_cast<const TXDoneMessage*>(p);
this->on_txdone(message.progress, message.done);
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
this->on_tx_progress(message.progress, message.done);
}
};
};

View File

@ -35,7 +35,7 @@ using namespace portapack;
namespace ui {
void LCRView::focus() {
button_setrgsb.focus();
button_set_rgsb.focus();
}
LCRView::~LCRView() {
@ -43,92 +43,52 @@ LCRView::~LCRView() {
baseband::shutdown();
}
void LCRView::paint(Painter& painter) {
std::string final_str;
static constexpr Style style_orange {
.font = font::fixed_8x16,
.background = Color::black(),
.foreground = Color::orange(),
};
Point offset = {
static_cast<Coord>(104),
static_cast<Coord>(68)
};
for (size_t i = 0; i < 5; i++) {
painter.draw_string(
screen_pos() + offset,
style_orange,
litteral[i]
);
offset += { 0, 32 };
}
button_setrgsb.set_text(rgsb);
// Recap: frequency @ baudrate
final_str = to_string_short_freq(persistent_memory::tuned_frequency());
final_str += '@';
final_str += to_string_dec_int(persistent_memory::modem_baudrate(), 4);
final_str += "bps ";
//final_str += modem_defs[persistent_memory::modem_def_index()].name;
text_recap.set(final_str);
}
std::vector<std::string> LCRView::parse_litterals() {
std::vector<std::string> litterals;
for (size_t i = 0; i < 5; i++) {
if (checkboxes[i].value())
litterals.push_back(litteral[i]);
}
return litterals;
}
/*
// Recap: frequency @ baudrate
final_str = to_string_short_freq(persistent_memory::tuned_frequency());
final_str += '@';
final_str += to_string_dec_int(persistent_memory::modem_baudrate(), 4);
final_str += "bps ";
//final_str += modem_defs[persistent_memory::modem_def_index()].name;
text_recap.set(final_str);*/
void LCRView::update_progress() {
std::string progress_str;
text_status.set(" "); // Clear
progress_str = to_string_dec_uint(repeat_index) + "/" + to_string_dec_uint(persistent_memory::modem_repeat());
progress_str += " " + to_string_dec_uint(scan_index + 1) + "/" + to_string_dec_uint(scan_count);
if (tx_mode == SINGLE) {
text_status.set(progress_str);
progress.set_value(repeat_index);
} else if (tx_mode == SCAN) {
text_status.set(progress_str);
progress.set_value(scan_progress);
} else {
if (tx_mode == IDLE) {
text_status.set("Ready");
progress.set_value(0);
} else {
std::string progress_str = to_string_dec_uint(repeat_index) + "/" + to_string_dec_uint(persistent_memory::modem_repeat()) +
" " + to_string_dec_uint(scan_index + 1) + "/" + to_string_dec_uint(scan_count);
text_status.set(progress_str);
if (tx_mode == SINGLE)
progress.set_value(repeat_index);
else if (tx_mode == SCAN)
progress.set_value(scan_progress);
}
}
void LCRView::on_txdone(int n) {
if (n) {
void LCRView::on_tx_progress(const uint32_t progress, const bool done) {
if (!done) {
// Repeating...
repeat_index = n + 1;
repeat_index = progress + 1;
if (tx_mode == SCAN)
scan_progress++;
} else {
// Done transmitting
tx_view.set_transmitting(false);
transmitter_model.disable();
if ((tx_mode == SCAN) && (scan_index < (scan_count - 1))) {
transmitter_model.disable();
// Next address
scan_index++;
scan_progress++;
repeat_index = 1;
start_tx(true);
} else {
transmitter_model.disable();
tx_mode = IDLE;
button_scan.set_style(&style_val);
button_scan.set_text("SCAN");
}
}
@ -136,9 +96,7 @@ void LCRView::on_txdone(int n) {
}
void LCRView::start_tx(const bool scan) {
uint8_t repeats;
repeats = persistent_memory::modem_repeat();
uint32_t repeats = persistent_memory::modem_repeat();
if (scan) {
if (tx_mode != SCAN) {
@ -151,6 +109,7 @@ void LCRView::start_tx(const bool scan) {
update_progress();
}
rgsb = scan_list[options_scanlist.selected_index()].addresses[scan_index];
button_set_rgsb.set_text(rgsb);
} else {
tx_mode = SINGLE;
repeat_index = 1;
@ -160,11 +119,17 @@ void LCRView::start_tx(const bool scan) {
update_progress();
}
button_setrgsb.set_text(rgsb);
modems::generate_data(lcr::generate_message(rgsb, parse_litterals(), options_ec.selected_index()), lcr_message_data);
std::vector<std::string> litterals_list;
for (size_t i = 0; i < LCR_MAX_AM; i++) {
if (checkboxes[i].value())
litterals_list.push_back(litteral[i]);
}
modems::generate_data(lcr::generate_message(rgsb, litterals_list, options_ec.selected_index()), lcr_message_data);
transmitter_model.set_tuning_frequency(persistent_memory::tuned_frequency());
transmitter_model.set_sampling_rate(1536000U);
transmitter_model.set_sampling_rate(AFSK_TX_SAMPLERATE);
transmitter_model.set_rf_amp(true);
transmitter_model.set_baseband_bandwidth(1750000);
transmitter_model.enable();
@ -172,17 +137,23 @@ void LCRView::start_tx(const bool scan) {
memcpy(shared_memory.bb_data.data, lcr_message_data, sizeof(lcr_message_data));
baseband::set_afsk_data(
1536000 / persistent_memory::modem_baudrate(),
AFSK_TX_SAMPLERATE / persistent_memory::modem_baudrate(),
persistent_memory::afsk_mark_freq(),
persistent_memory::afsk_space_freq(),
repeats,
persistent_memory::modem_bw(),
transmitter_model.channel_bandwidth(),
serializer::symbol_count(persistent_memory::serial_format())
);
}
void LCRView::on_button_setam(NavigationView& nav, Button& button) {
text_prompt(nav, &litteral[button.id], 7);
void LCRView::on_button_set_am(NavigationView& nav, int16_t button_id) {
text_prompt(
nav,
&litteral[button_id],
7,
[this, button_id](std::string* buffer) {
texts[button_id].set(*buffer);
});
}
LCRView::LCRView(NavigationView& nav) {
@ -190,116 +161,126 @@ LCRView::LCRView(NavigationView& nav) {
baseband::run_image(portapack::spi_flash::image_tag_afsk);
rgsb = scan_list[0].addresses[0];
add_children({
&labels,
&text_recap,
&options_ec,
&button_setrgsb,
&button_set_rgsb,
&button_modem_setup,
&text_status,
&progress,
&button_transmit,
&options_scanlist,
&button_scan,
&button_clear
&check_scan,
&button_clear,
&tx_view
});
options_scanlist.set_selected_index(0);
const auto button_setam_fn = [this, &nav](Button& button) {
this->on_button_setam(nav, button);
const auto button_set_am_fn = [this, &nav](Button& button) {
on_button_set_am(nav, button.id);
};
size_t n = 0;
for (auto& button : buttons) {
button.on_select = button_setam_fn;
button.id = n;
button.set_text("AM " + to_string_dec_uint(n + 1, 1));
button.set_parent_rect({
for (size_t n = 0; n < LCR_MAX_AM; n++) {
Button* button = &buttons[n];
button->on_select = button_set_am_fn;
button->id = n;
button->set_text("AM " + to_string_dec_uint(n + 1));
button->set_parent_rect({
static_cast<Coord>(40),
static_cast<Coord>(n * 32 + 64),
48, 24
});
add_child(&button);
n++;
}
n = 0;
for (auto& checkbox : checkboxes) {
checkbox.set_parent_rect({
add_child(button);
Checkbox* checkbox = &checkboxes[n];
checkbox->set_parent_rect({
static_cast<Coord>(8),
static_cast<Coord>(n * 32 + 64),
48, 24
});
checkbox.set_value(false);
add_child(&checkbox);
n++;
}
n = 0;
for (auto& rectangle : rectangles) {
rectangle.set_parent_rect({
checkbox->set_value(false);
add_child(checkbox);
Rectangle* rectangle = &rectangles[n];
rectangle->set_parent_rect({
static_cast<Coord>(98),
static_cast<Coord>(n * 32 + 68 - 2),
static_cast<Coord>(n * 32 + 66),
68, 20
});
rectangle.set_color(ui::Color::grey());
rectangle.set_outline(true);
add_child(&rectangle);
n++;
rectangle->set_color(ui::Color::grey());
rectangle->set_outline(true);
add_child(rectangle);
Text* text = &texts[n];
text->set_parent_rect({
static_cast<Coord>(104),
static_cast<Coord>(n * 32 + 68),
7 * 8, 16
});
add_child(text);
}
button_setrgsb.set_text(rgsb);
button_set_rgsb.set_text(rgsb);
options_ec.set_selected_index(0); // Auto
checkboxes[0].set_value(true);
button_transmit.set_style(&style_val);
button_scan.set_style(&style_val);
button_setrgsb.on_select = [this,&nav](Button&) {
text_prompt(nav, &rgsb, 4);
button_set_rgsb.on_select = [this, &nav](Button&) {
text_prompt(
nav,
&rgsb,
4,
[this](std::string* buffer) {
button_set_rgsb.set_text(*buffer);
});
};
button_modem_setup.on_select = [&nav](Button&) {
nav.push<ModemSetupView>();
};
button_transmit.on_select = [this](Button&) {
button_modem_setup.on_select = [this, &nav](Button&) {
if (tx_mode == IDLE)
start_tx(false);
};
button_scan.on_select = [this](Button&) {
std::string str_temp;
if (tx_mode == IDLE) {
button_scan.set_style(&style_cancel);
button_scan.set_text("ABORT");
start_tx(true);
} else {
// Kill scan process
baseband::kill_afsk();
text_status.set("Abort @" + rgsb);
progress.set_value(0);
tx_mode = IDLE;
button_scan.set_style(&style_val);
button_scan.set_text("SCAN");
}
nav.push<ModemSetupView>();
};
button_clear.on_select = [this, &nav](Button&) {
if (tx_mode == IDLE) {
options_ec.set_selected_index(0); // Auto
for (size_t n = 0; n < 5; n++) {
litteral[n] = " ";
checkboxes[n].set_value(true);
}
set_dirty();
start_tx(false);
options_ec.set_selected_index(0); // Auto
for (size_t n = 0; n < LCR_MAX_AM; n++) {
litteral[n] = " ";
checkboxes[n].set_value(true);
}
};
tx_view.on_edit_frequency = [this, &nav]() {
auto new_view = nav.push<FrequencyKeypadView>(transmitter_model.tuning_frequency());
new_view->on_changed = [this](rf::Frequency f) {
transmitter_model.set_tuning_frequency(f);
};
};
tx_view.on_start = [this]() {
if (check_scan.value()) {
if (tx_mode == IDLE) {
start_tx(true);
tx_view.set_transmitting(true);
} else {
// Kill scan process
baseband::kill_afsk();
tx_view.set_transmitting(false);
transmitter_model.disable();
text_status.set("Abort @" + rgsb);
progress.set_value(0);
tx_mode = IDLE;
}
} else {
if (tx_mode == IDLE) {
start_tx(false);
tx_view.set_transmitting(true);
}
}
};
tx_view.on_stop = [this]() {
tx_view.set_transmitting(false);
transmitter_model.disable();
tx_mode = IDLE;
};
}
} /* namespace ui */

View File

@ -23,10 +23,14 @@
#include "ui.hpp"
#include "ui_widget.hpp"
#include "ui_textentry.hpp"
#include "ui_transmitter.hpp"
#include "message.hpp"
#include "transmitter_model.hpp"
namespace ui {
#define LCR_MAX_AM 5
class LCRView : public View {
public:
@ -34,7 +38,6 @@ public:
~LCRView();
void focus() override;
void paint(Painter& painter) override;
std::string title() const override { return "LCR transmit"; };
@ -48,7 +51,7 @@ private:
{ 36, &RGSB_list_Lille[0] },
{ 20, &RGSB_list_Reims[0] }
};
const std::string RGSB_list_Lille[36] = {
"AI10", "AI20", "AI30", "AI40",
"AI50", "AI60", "AI70", "AJ10",
@ -81,46 +84,28 @@ private:
tx_modes tx_mode = IDLE;
uint8_t scan_count { 0 }, scan_index { 0 };
uint32_t scan_progress { 0 };
std::string litteral[5] { { " " } };
std::string rgsb { " " };
char lcr_message[512];
std::array<std::string, LCR_MAX_AM> litteral { { " " } };
std::string rgsb { "AI10" };
uint16_t lcr_message_data[256];
rf::Frequency f { 0 };
uint8_t repeat_index { 0 };
std::vector<std::string> parse_litterals();
void update_progress();
void start_tx(const bool scan);
void on_txdone(int n);
void on_button_setam(NavigationView& nav, Button& button);
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(),
};
void on_tx_progress(const uint32_t progress, const bool done);
void on_button_set_am(NavigationView& nav, int16_t button_id);
Labels labels {
{ { 2 * 8, 4 }, "EC:", Color::light_grey() },
{ { 84, 268 }, "Scan list:", Color::light_grey() }
{ { 0, 8 }, "EC: RGSB:", Color::light_grey() },
{ { 17 * 8, 4 * 8 }, "List:", Color::light_grey() }
};
std::array<Button, 5> buttons { };
std::array<Checkbox, 5> checkboxes { };
std::array<Rectangle, 5> rectangles { };
Text text_recap {
{ 12 * 8, 4, 18 * 8, 16 },
"-"
};
std::array<Button, LCR_MAX_AM> buttons { };
std::array<Checkbox, LCR_MAX_AM> checkboxes { };
std::array<Rectangle, LCR_MAX_AM> rectangles { };
std::array<Text, LCR_MAX_AM> texts { };
OptionsField options_ec {
{ 40, 4 },
{ 3 * 8, 8 },
4,
{
{ "Auto", 0 },
@ -130,51 +115,52 @@ private:
}
};
Button button_setrgsb {
{ 8, 24, 80, 32 },
Button button_set_rgsb {
{ 13 * 8, 4, 8 * 8, 24 },
"RGSB"
};
Checkbox check_scan {
{ 22 * 8, 4 },
4,
"Scan"
};
Button button_modem_setup {
{ 13 * 8, 24, 128, 32 },
{ 1 * 8, 4 * 8 + 2, 14 * 8, 24 },
"Modem setup"
};
Button button_clear {
{ 174, 64, 58, 19 * 8 },
"CLEAR"
};
Text text_status {
{ 16, 222, 128, 16 },
"Ready"
};
ProgressBar progress {
{ 16, 242, 208, 16 }
};
Button button_transmit {
{ 8, 270, 64, 32 },
"TX"
};
OptionsField options_scanlist {
{ 84, 284 },
{ 22 * 8, 4 * 8 },
6,
{
{ "Reims ", 1 }
}
};
Button button_scan {
{ 166, 270, 64, 32 },
"SCAN"
Button button_clear {
{ 22 * 8, 8 * 8, 7 * 8, 19 * 8 },
"CLEAR"
};
MessageHandlerRegistration message_handler_tx_done {
Message::ID::TXDone,
Text text_status {
{ 2 * 8, 27 * 8 + 4, 26 * 8, 16 },
"Ready"
};
ProgressBar progress {
{ 2 * 8, 29 * 8 + 4, 26 * 8, 16 }
};
TransmitterView tx_view {
16 * 16,
10000,
12
};
MessageHandlerRegistration message_handler_tx_progress {
Message::ID::TXProgress,
[this](const Message* const p) {
const auto message = *reinterpret_cast<const TXDoneMessage*>(p);
this->on_txdone(message.progress);
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
this->on_tx_progress(message.progress, message.done);
}
};
};

View File

@ -47,7 +47,10 @@ void MicTXView::update_vumeter() {
vumeter.set_value(audio_level);
}
void MicTXView::on_tx_done() {
void MicTXView::on_tx_progress(const uint32_t progress, const bool done) {
(void)progress;
(void)done;
// Roger beep transmitted, stop transmitting
set_tx(false);
}

View File

@ -64,7 +64,7 @@ private:
void set_tx(bool enable);
void on_tuning_frequency_changed(rf::Frequency f);
void on_ctcss_changed(uint32_t v);
void on_tx_done();
void on_tx_progress(const uint32_t progress, const bool done);
bool transmitting { false };
bool va_enabled { };
@ -184,11 +184,11 @@ private:
}
};
MessageHandlerRegistration message_handler_tx_done {
Message::ID::TXDone,
MessageHandlerRegistration message_handler_tx_progress {
Message::ID::TXProgress,
[this](const Message* const p) {
const auto message = *reinterpret_cast<const TXDoneMessage*>(p);
if (message.done) this->on_tx_done();
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
this->on_tx_progress(message.progress, message.done);
}
};
};

View File

@ -21,12 +21,9 @@
*/
#include "ui_modemsetup.hpp"
#include "ui_receiver.hpp"
#include "portapack.hpp"
#include "string_format.hpp"
#include "portapack_shared_memory.hpp"
#include "portapack_persistent_memory.hpp"
using namespace portapack;
@ -38,12 +35,6 @@ void ModemSetupView::focus() {
field_baudrate.focus();
}
/*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
)
@ -54,11 +45,9 @@ ModemSetupView::ModemSetupView(
add_children({
&labels,
//&button_setfreq,
&field_baudrate,
&field_mark,
&field_space,
//&field_bw,
&field_repeat,
&options_modem,
&button_set_modem,
@ -66,6 +55,7 @@ ModemSetupView::ModemSetupView(
&button_save
});
// Only list AFSK modems for now
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));
@ -83,20 +73,10 @@ 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());
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_repeat.set_value(persistent_memory::modem_repeat());
/*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());
button_set_modem.on_select = [this, &nav](Button&) {
@ -114,7 +94,6 @@ 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_repeat(field_repeat.value());
serial_format.data_bits = sym_format.get_sym(0) + 6;

View File

@ -41,20 +41,13 @@ private:
void update_freq(rf::Frequency f);
Labels labels {
//{ { 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, 15 * 8 }, "Repeat:", Color::light_grey() },
{ { 1 * 8, 6 * 8 }, "Modem preset:", Color::light_grey() },
{ { 2 * 8, 22 * 8 }, "Serial format:", Color::light_grey() }
};
/*Button button_setfreq {
{ 13 * 8, 3 * 8, 12 * 8, 32 },
"----.----"
};*/
NumberField field_baudrate {
{ 11 * 8, 11 * 8 },
@ -80,14 +73,6 @@ private:
' '
};
/*NumberField field_bw {
{ 172, 104 },
2,
{ 1, 50 },
1,
' '
};*/
NumberField field_repeat {
{ 204, 15 * 8 },
2,

View File

@ -42,14 +42,13 @@ static WORKING_AREA(ookthread_wa, 256);
static msg_t ookthread_fn(void * arg) {
uint32_t v = 0, delay = 0;
size_t i = 0;
uint8_t * message_symbols = shared_memory.bb_data.tones_data.message;
uint8_t symbol;
MorseView * arg_c = (MorseView*)arg;
chRegSetThreadName("ookthread");
for (i = 0; i < arg_c->symbol_count; i++) {
for (uint32_t i = 0; i < arg_c->symbol_count; i++) {
if (chThdShouldTerminate()) break;
symbol = message_symbols[i];
@ -128,7 +127,7 @@ void MorseView::update_tx_duration() {
}
}
void MorseView::on_tx_progress(const int progress, const bool done) {
void MorseView::on_tx_progress(const uint32_t progress, const bool done) {
if (done) {
transmitter_model.disable();
progressbar.set_value(0);

View File

@ -52,8 +52,8 @@ public:
void focus() override;
void paint(Painter& painter) override;
void on_tx_progress(const int progress, const bool done);
void on_tx_progress(const uint32_t progress, const bool done);
std::string title() const override { return "Morse TX"; };
@ -159,10 +159,10 @@ private:
12
};
MessageHandlerRegistration message_handler_tx_done {
Message::ID::TXDone,
MessageHandlerRegistration message_handler_tx_progress {
Message::ID::TXProgress,
[this](const Message* const p) {
const auto message = *reinterpret_cast<const TXDoneMessage*>(p);
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
this->on_tx_progress(message.progress, message.done);
}
};

View File

@ -298,7 +298,8 @@ ReceiversMenuView::ReceiversMenuView(NavigationView& nav) {
{ "TPMS: Cars", ui::Color::green(), &bitmap_icon_tpms, [&nav](){ nav.push<TPMSAppView>(); } },
});
on_left = [&nav](){ nav.pop(); };
//set_highlighted(4); // Default selection is "Audio"
set_highlighted(4); // Default selection is "Audio"
}
/* TransmittersMenuView **************************************************/
@ -312,7 +313,6 @@ TransmittersMenuView::TransmittersMenuView(NavigationView& nav) {
{ "Microphone", ui::Color::green(), &bitmap_icon_microphone, [&nav](){ nav.push<MicTXView>(); } },
{ "Morse code", ui::Color::green(), &bitmap_icon_morse, [&nav](){ nav.push<MorseView>(); } },
{ "NTTWorks burger pager", ui::Color::yellow(), &bitmap_icon_burger, [&nav](){ nav.push<CoasterPagerView>(); } },
{ "TouchTunes remote", ui::Color::orange(), nullptr, [&nav](){ nav.push<TouchTunesView>(); } },
{ "Nuoptix DTMF timecode", ui::Color::green(), &bitmap_icon_nuoptix, [&nav](){ nav.push<NuoptixView>(); } },
{ "OOK remote encoders", ui::Color::yellow(), &bitmap_icon_remote, [&nav](){ nav.push<EncodersView>(); } },
{ "POCSAG", ui::Color::green(), &bitmap_icon_pocsag, [&nav](){ nav.push<POCSAGTXView>(); } },
@ -321,6 +321,7 @@ TransmittersMenuView::TransmittersMenuView(NavigationView& nav) {
{ "Soundboard", ui::Color::green(), &bitmap_icon_soundboard, [&nav](){ nav.push<SoundBoardView>(); } },
{ "SSTV", ui::Color::green(), &bitmap_icon_sstv, [&nav](){ nav.push<SSTVTXView>(); } },
{ "TEDI/LCR AFSK", ui::Color::yellow(), &bitmap_icon_lcr, [&nav](){ nav.push<LCRView>(); } },
{ "TouchTunes remote", ui::Color::orange(), nullptr, [&nav](){ nav.push<TouchTunesView>(); } },
});
on_left = [&nav](){ nav.pop(); };
}

View File

@ -45,6 +45,13 @@ NuoptixView::~NuoptixView() {
baseband::shutdown();
}
void NuoptixView::on_tx_progress(const uint32_t progress, const bool done) {
if (done)
transmit(false);
else
progressbar.set_value(progress);
}
void NuoptixView::transmit(bool setup) {
uint8_t mod, tone_code;
uint8_t c;

View File

@ -59,6 +59,7 @@ private:
void on_tuning_frequency_changed(rf::Frequency f);
void transmit(bool setup);
void on_tx_progress(const uint32_t progress, const bool done);
uint32_t timecode { 0 };
@ -95,14 +96,11 @@ private:
15
};
MessageHandlerRegistration message_handler_tx_done {
Message::ID::TXDone,
MessageHandlerRegistration message_handler_tx_progress {
Message::ID::TXProgress,
[this](const Message* const p) {
const auto message = *reinterpret_cast<const TXDoneMessage*>(p);
if (message.done)
transmit(false);
else
progressbar.set_value(message.progress);
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
this->on_tx_progress(message.progress, message.done);
}
};
};

View File

@ -42,7 +42,7 @@ POCSAGTXView::~POCSAGTXView() {
baseband::shutdown();
}
void POCSAGTXView::on_tx_progress(const int progress, const bool done) {
void POCSAGTXView::on_tx_progress(const uint32_t progress, const bool done) {
if (done) {
transmitter_model.disable();
progressbar.set_value(0);

View File

@ -63,7 +63,7 @@ private:
};
void on_set_text(NavigationView& nav);
void on_tx_progress(const int progress, const bool done);
void on_tx_progress(const uint32_t progress, const bool done);
bool start_tx();
Labels labels {
@ -131,10 +131,10 @@ private:
9
};
MessageHandlerRegistration message_handler_tx_done {
Message::ID::TXDone,
MessageHandlerRegistration message_handler_tx_progress {
Message::ID::TXProgress,
[this](const Message* const p) {
const auto message = *reinterpret_cast<const TXDoneMessage*>(p);
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
this->on_tx_progress(message.progress, message.done);
}
};

View File

@ -60,7 +60,9 @@ void SigGenView::update_tone() {
baseband::set_siggen_tone(symfield_tone.value_dec_u32());
}
void SigGenView::on_tx_progress(const bool done) {
void SigGenView::on_tx_progress(const uint32_t progress, const bool done) {
(void) progress;
if (done)
tx_view.set_transmitting(false);
}

View File

@ -45,7 +45,7 @@ public:
private:
void start_tx();
void update_tone();
void on_tx_progress(const bool done);
void on_tx_progress(const uint32_t progress, const bool done);
const std::string shape_strings[7] = {
"CW",
@ -123,11 +123,11 @@ private:
12
};
MessageHandlerRegistration message_handler_tx_done {
Message::ID::TXDone,
MessageHandlerRegistration message_handler_tx_progress {
Message::ID::TXProgress,
[this](const Message* const p) {
const auto message = *reinterpret_cast<const TXDoneMessage*>(p);
this->on_tx_progress(message.done);
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
this->on_tx_progress(message.progress, message.done);
}
};
};

View File

@ -40,27 +40,29 @@ TouchTunesView::~TouchTunesView() {
baseband::shutdown();
}
void TouchTunesView::on_tx_progress(const int progress, const bool done) {
void TouchTunesView::stop_tx() {
transmitter_model.disable();
tx_mode = IDLE;
progressbar.set_value(0);
text_status.set("Ready");
}
void TouchTunesView::on_tx_progress(const uint32_t progress, const bool done) {
if (!done) {
// Repeating
if (tx_mode == SINGLE) {
// Progress
if (tx_mode == SINGLE)
progressbar.set_value(progress);
} else if (tx_mode == SCAN) {
progressbar.set_value((pin * 4) + progress);
}
else if (tx_mode == SCAN)
progressbar.set_value((pin * TOUCHTUNES_REPEATS) + progress);
} else {
// Done transmitting
if (tx_mode == SINGLE) {
transmitter_model.disable();
tx_mode = IDLE;
progressbar.set_value(0);
stop_tx();
} else if (tx_mode == SCAN) {
pin++;
if (pin == 256) {
transmitter_model.disable();
tx_mode = IDLE;
progressbar.set_value(0);
if (pin == TOUCHTUNES_MAX_PIN) {
stop_tx();
} else {
pin++;
field_pin.set_value(pin);
start_tx(scan_button_index);
}
@ -76,28 +78,36 @@ void TouchTunesView::start_tx(const uint32_t button_index) {
if (check_scan.value()) {
scan_button_index = button_index;
tx_mode = SCAN;
progressbar.set_max(256 * 4);
progressbar.set_max(TOUCHTUNES_MAX_PIN * TOUCHTUNES_REPEATS);
text_status.set("Scanning...");
} else {
tx_mode = SINGLE;
progressbar.set_max(4);
progressbar.set_max(TOUCHTUNES_REPEATS);
text_status.set("Transmitting...");
}
frame_data = 0x5D; // Sync word
frame_data = TOUCHTUNES_SYNC_WORD; // Sync word
// Insert pin value (LSB first)
for (bit = 0; bit < 8; bit++) {
frame_data <<= 1;
if (pin & (1 << bit))
frame_data |= 1;
}
// Insert button code (and its complement)
frame_data <<= 16;
frame_data |= button_codes[button_index];
frame_data |= (button_codes[button_index] << 8);
frame_data |= (button_codes[button_index] ^ 0xFF);
// Convert to OOK symbols
for (bit = 0; bit < (8 + 8 + 16); bit++) {
fragments += (frame_data & 0x80000000UL) ? "1000" : "10";
frame_data <<= 1;
}
fragments = "111111111111111100000000" + fragments + "1000"; // End pulse
// Sync and end pulse
fragments = "111111111111111100000000" + fragments + "1000";
size_t bitstream_length = make_bitstream(fragments);
@ -109,28 +119,20 @@ void TouchTunesView::start_tx(const uint32_t button_index) {
baseband::set_ook_data(
bitstream_length,
OOK_SAMPLERATE / 1766, // 1766 baud, 566us/bit
4, // Repeats
100
OOK_SAMPLERATE / 1786, // 560us
TOUCHTUNES_REPEATS,
100 // Pause
);
}
TouchTunesView::TouchTunesView(
NavigationView&
)
{
) {
baseband::run_image(portapack::spi_flash::image_tag_ook);
add_children({
&labels,
&field_pin,
&button_on_off,
&button_pause,
&button_p1,
&button_ok,
&button_vol_inc1,
&button_vol_inc2,
&button_vol_inc3,
&check_scan,
&text_status,
&progressbar
@ -142,28 +144,22 @@ TouchTunesView::TouchTunesView(
pin = v;
};
button_on_off.on_select = [this](Button&) {
start_tx(0);
const auto button_fn = [this](Button& button) {
start_tx(button.id);
};
button_pause.on_select = [this](Button&) {
start_tx(1);
};
button_p1.on_select = [this](Button&) {
start_tx(2);
};
button_ok.on_select = [this](Button&) {
start_tx(3);
};
button_vol_inc1.on_select = [this](Button&) {
start_tx(4);
};
button_vol_inc2.on_select = [this](Button&) {
start_tx(5);
};
button_vol_inc3.on_select = [this](Button&) {
start_tx(6);
};
size_t n = 0;
for (auto& entry : remote_layout) {
buttons[n].on_select = button_fn;
buttons[n].id = n;
buttons[n].set_text(entry.text);
buttons[n].set_parent_rect({
entry.position + Point(8, 0),
{ (Dim)(entry.text.length() + 2) * 8, 4 * 8 }
});
add_child(&buttons[n]);
n++;
}
}
} /* namespace ui */

View File

@ -25,7 +25,9 @@
#include "transmitter_model.hpp"
// The coding in notpike's script is quite complex, using multiple LUTs to form the data sent to the YSO.
// The format is actually very simple if it is rather seen as short and long gaps between pulses (as seen in many OOK remotes):
// The format is actually very simple if it is rather seen as short and long gaps between pulses (as seen in many OOK remotes).
// The frames and data rate suspiciously match the NEC infrared protocol (http://www.sbprojects.com/knowledge/ir/nec.php) without
// the address complement. The exact data rate would be 1786 baud (560us/fragment).
// Pin 0 - On/Off
// ffff00 a2888a2aaaa8888aa2aa2220
@ -57,14 +59,44 @@
// The hex data only seems scrambled because of the shift induced by the short or long gaps (10 or 1000)
// The radio frame's duration depends on the value of the bits
const uint16_t button_codes[7] = {
0x7887, // On/Off
0xB34C, // Pause
0xF10E, // P1
0xDD22, // OK
0xF40B, // Zone 1 Vol+
0xF609, // Zone 2 Vol+
0xFC03 // Zone 3 Vol+
#define TOUCHTUNES_MAX_PIN 255
#define TOUCHTUNES_REPEATS 4
#define TOUCHTUNES_SYNC_WORD 0x5D
// Each 16bit button code is actually 8bit followed by its complement
const uint8_t button_codes[32] = {
0xB3, // Pause
0x78, // On/Off
0xF1, // P1
0x60, // P2
0xCA, // P3
0x20, // F1
0xF2, // Up
0xA0, // F2
0x84, // Left
0xDD, // OK
0xC4, // Right
0x30, // F3
0x80, // Down
0xB0, // F4
0xF0, // 1
0x08, // 2
0x88, // 3
0x48, // 4
0xC8, // 5
0x28, // 6
0xA8, // 7
0x68, // 8
0xE8, // 9
0x18, // Music_Karaoke
0x98, // 0
0x58, // Lock_Queue
0xF4, // Zone 1 Vol+
0xF6, // Zone 2 Vol+
0xFC, // Zone 3 Vol+
0x50, // Zone 1 Vol-
0x10, // Zone 2 Vol-
0x40, // Zone 3 Vol-
};
namespace ui {
@ -79,10 +111,6 @@ public:
std::string title() const override { return "TouchTunes TX"; };
private:
Labels labels {
{ { 2 * 8, 2 * 8 }, "PIN:", Color::light_grey() }
};
uint32_t scan_button_index { };
uint32_t pin { 0 };
@ -95,66 +123,90 @@ private:
tx_modes tx_mode = IDLE;
void start_tx(const uint32_t button_index);
void on_tx_progress(const int progress, const bool done);
void stop_tx();
void on_tx_progress(const uint32_t progress, const bool done);
struct remote_layout_t {
Point position;
std::string text;
};
const std::array<remote_layout_t, 32> remote_layout { {
{ { 12 * 8, 0 }, "PAUSE" },
{ { 21 * 8, 0 }, "POWER" },
{ { 14 * 8, 5 * 8 }, "P1" },
{ { 18 * 8, 5 * 8 }, "P2" },
{ { 22 * 8, 5 * 8 }, "P3" },
{ { 14 * 8, 10 * 8 }, "F1" },
{ { 18 * 8 + 4, 10 * 8 }, "^" },
{ { 22 * 8, 10 * 8 }, "F2" },
{ { 14 * 8, 14 * 8 }, "<" },
{ { 18 * 8, 14 * 8 }, "OK" },
{ { 23 * 8, 14 * 8 }, ">" },
{ { 14 * 8, 18 * 8 }, "F3" },
{ { 18 * 8 + 4, 18 * 8 }, "V" },
{ { 22 * 8, 18 * 8 }, "F4" },
{ { 0 * 8, 5 * 8 }, "1" },
{ { 4 * 8, 5 * 8 }, "2" },
{ { 8 * 8, 5 * 8 }, "3" },
{ { 0 * 8, 10 * 8 }, "4" },
{ { 4 * 8, 10 * 8 }, "5" },
{ { 8 * 8, 10 * 8 }, "6" },
{ { 0 * 8, 15 * 8 }, "7" },
{ { 4 * 8, 15 * 8 }, "8" },
{ { 8 * 8, 15 * 8 }, "9" },
{ { 0 * 8, 20 * 8 }, "*" },
{ { 4 * 8, 20 * 8 }, "0" },
{ { 8 * 8, 20 * 8 }, "#" },
{ { 13 * 8, 23 * 8 }, "+" },
{ { 18 * 8, 23 * 8 }, "+" },
{ { 23 * 8, 23 * 8 }, "+" },
{ { 13 * 8, 29 * 8 }, "-" },
{ { 18 * 8, 29 * 8 }, "-" },
{ { 23 * 8, 29 * 8 }, "-" }
} };
Labels labels {
{ { 2 * 8, 1 * 8 }, "PIN:", Color::light_grey() },
{ { 13 * 8 + 4, 27 * 8 }, "VOL1 VOL2 VOL3", Color::light_grey() }
};
std::array<Button, 32> buttons { };
NumberField field_pin {
{ 6 * 8, 1 * 16 },
{ 6 * 8, 1 * 8 },
3,
{ 0, 255 },
1,
' '
};
Button button_on_off {
{ 2 * 8, 3 * 16, 8 * 8, 2 * 16 },
"ON/OFF"
};
Button button_pause {
{ 2 * 8, 6 * 16, 8 * 8, 2 * 16 },
"PAUSE"
};
Button button_p1 {
{ 11 * 8, 6 * 16, 8 * 8, 2 * 16 },
"P1"
};
Button button_ok {
{ 20 * 8, 6 * 16, 8 * 8, 2 * 16 },
"OK"
};
Button button_vol_inc1 {
{ 2 * 8, 9 * 16, 8 * 8, 2 * 16 },
"VOL+ 1"
};
Button button_vol_inc2 {
{ 11 * 8, 9 * 16, 8 * 8, 2 * 16 },
"VOL+ 2"
};
Button button_vol_inc3 {
{ 20 * 8, 9 * 16, 8 * 8, 2 * 16 },
"VOL+ 3"
'0'
};
Checkbox check_scan {
{ 2 * 8, 13 * 16 },
{ 2 * 8, 27 * 8 },
4,
"Scan"
};
Text text_status {
{ 2 * 8, 15 * 16, 128, 16 },
{ 2 * 8, 33 * 8, 128, 16 },
"Ready"
};
ProgressBar progressbar {
{ 2 * 8, 15 * 16 + 20, 208, 16 }
{ 2 * 8, 35 * 8, 208, 16 }
};
MessageHandlerRegistration message_handler_tx_done {
Message::ID::TXDone,
MessageHandlerRegistration message_handler_tx_progress {
Message::ID::TXProgress,
[this](const Message* const p) {
const auto message = *reinterpret_cast<const TXDoneMessage*>(p);
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
this->on_tx_progress(message.progress, message.done);
}
};

View File

@ -48,7 +48,7 @@ private:
uint32_t cur_bit { 0 };
uint32_t phase { 0 };
TXDoneMessage message { };
TXProgressMessage txprogress_message { };
};
#endif

View File

@ -46,14 +46,15 @@ void AFSKProcessor::execute(const buffer_c8_t& buffer) {
bit_pos = 0;
word_ptr = (uint16_t*)shared_memory.bb_data.data;
cur_word = *word_ptr;
message.progress = repeat_counter + 1;
shared_memory.application_queue.push(message);
txprogress_message.done = false;
txprogress_message.progress = repeat_counter + 1;
shared_memory.application_queue.push(txprogress_message);
repeat_counter++;
} else {
// Stop
cur_word = 0;
message.progress = 0;
shared_memory.application_queue.push(message);
txprogress_message.done = true;
shared_memory.application_queue.push(txprogress_message);
configured = false;
}
}
@ -101,7 +102,7 @@ void AFSKProcessor::on_message(const Message* const msg) {
afsk_phase_inc_mark = message.phase_inc_mark * AFSK_DELTA_COEF;
afsk_phase_inc_space = message.phase_inc_space * AFSK_DELTA_COEF;
afsk_repeat = message.repeat - 1;
fm_delta = message.fm_delta * (0xFFFFFFULL / 1536000);
fm_delta = message.fm_delta * (0xFFFFFFULL / AFSK_SAMPLERATE);
symbol_count = message.symbol_count - 1;
sample_count = afsk_samples_per_bit;

View File

@ -38,7 +38,7 @@ public:
private:
bool configured = false;
BasebandThread baseband_thread { 1536000, this, NORMALPRIO + 20, baseband::Direction::Transmit };
BasebandThread baseband_thread { AFSK_SAMPLERATE, this, NORMALPRIO + 20, baseband::Direction::Transmit };
uint32_t afsk_samples_per_bit { 0 };
uint32_t afsk_phase_inc_mark { 0 };
@ -58,7 +58,7 @@ private:
int8_t re { 0 }, im { 0 };
TXDoneMessage message { };
TXProgressMessage txprogress_message { };
};
#endif

View File

@ -40,16 +40,17 @@ void FSKProcessor::execute(const buffer_c8_t& buffer) {
if (bit_pos > length) {
// End of data
cur_bit = 0;
txdone_message.done = true;
shared_memory.application_queue.push(txdone_message);
txprogress_message.done = true;
shared_memory.application_queue.push(txprogress_message);
configured = false;
} else {
cur_bit = (shared_memory.bb_data.data[bit_pos >> 3] << (bit_pos & 7)) & 0x80;
bit_pos++;
if (progress_count >= progress_notice) {
progress_count = 0;
txdone_message.progress++;
shared_memory.application_queue.push(txdone_message);
txprogress_message.progress++;
txprogress_message.done = false;
shared_memory.application_queue.push(txprogress_message);
} else {
progress_count++;
}
@ -95,8 +96,8 @@ void FSKProcessor::on_message(const Message* const p) {
bit_pos = 0;
cur_bit = 0;
txdone_message.progress = 0;
txdone_message.done = false;
txprogress_message.progress = 0;
txprogress_message.done = false;
configured = true;
}
}

View File

@ -47,7 +47,7 @@ private:
uint32_t sample_count { 0 };
uint32_t phase { 0 }, sphase { 0 };
TXDoneMessage txdone_message { };
TXProgressMessage txprogress_message { };
};
#endif

View File

@ -60,7 +60,7 @@ void MicTXProcessor::execute(const buffer_c8_t& buffer){
if (beep_index == BEEP_TONES_NB) {
configured = false;
fm_delta = 0; // Zero-out the IQ output for the rest of the buffer
shared_memory.application_queue.push(txdone_message);
shared_memory.application_queue.push(txprogress_message);
} else {
beep_phase_inc = beep_deltas[beep_index];
beep_index++;
@ -108,7 +108,7 @@ void MicTXProcessor::on_message(const Message* const msg) {
ctcss_enabled = config_message.ctcss_enabled;
ctcss_phase_inc = config_message.ctcss_phase_inc;
txdone_message.done = true;
txprogress_message.done = true;
play_beep = false;
configured = true;

View File

@ -60,7 +60,7 @@ private:
int8_t re { 0 }, im { 0 };
AudioLevelReportMessage level_message { };
TXDoneMessage txdone_message { };
TXProgressMessage txprogress_message { };
};
#endif

View File

@ -51,14 +51,15 @@ void OOKProcessor::execute(const buffer_c8_t& buffer) {
// Repeat
bit_pos = 0;
cur_bit = shared_memory.bb_data.data[0] & 0x80;
txdone_message.progress = repeat_counter + 1;
shared_memory.application_queue.push(txdone_message);
txprogress_message.progress = repeat_counter + 1;
txprogress_message.done = false;
shared_memory.application_queue.push(txprogress_message);
repeat_counter++;
} else {
// Stop
cur_bit = 0;
txdone_message.done = true;
shared_memory.application_queue.push(txdone_message);
txprogress_message.done = true;
shared_memory.application_queue.push(txprogress_message);
configured = false;
}
pause_counter = 0;
@ -109,8 +110,8 @@ void OOKProcessor::on_message(const Message* const p) {
repeat_counter = 0;
bit_pos = 0;
cur_bit = 0;
txdone_message.progress = 0;
txdone_message.done = false;
txprogress_message.progress = 0;
txprogress_message.done = false;
configured = true;
}
}

View File

@ -51,7 +51,7 @@ private:
uint32_t tone_phase { 0 }, phase { 0 }, sphase { 0 };
int32_t tone_sample { 0 }, sig { 0 }, frq { 0 };
TXDoneMessage txdone_message { };
TXProgressMessage txprogress_message { };
};
#endif

View File

@ -33,8 +33,8 @@ void SigGenProcessor::execute(const buffer_c8_t& buffer) {
for (size_t i = 0; i < buffer.count; i++) {
if (!sample_count && auto_off) {
message.done = true;
shared_memory.application_queue.push(message);
txprogress_message.done = true;
shared_memory.application_queue.push(txprogress_message);
} else
sample_count--;

View File

@ -46,7 +46,7 @@ private:
int8_t sample { 0 };
int8_t re { 0 }, im { 0 };
TXDoneMessage message { };
TXProgressMessage txprogress_message { };
};
#endif

View File

@ -52,12 +52,13 @@ void TonesProcessor::execute(const buffer_c8_t& buffer) {
digit = shared_memory.bb_data.tones_data.message[digit_pos];
if (digit_pos >= message_length) {
configured = false;
txdone_message.done = true;
shared_memory.application_queue.push(txdone_message);
txprogress_message.done = true;
shared_memory.application_queue.push(txprogress_message);
return;
} else {
txdone_message.progress = digit_pos; // Inform UI about progress
shared_memory.application_queue.push(txdone_message);
txprogress_message.progress = digit_pos; // Inform UI about progress
txprogress_message.done = false;
shared_memory.application_queue.push(txprogress_message);
}
digit_pos++;
@ -136,8 +137,8 @@ void TonesProcessor::on_message(const Message* const p) {
if (audio_out) audio_output.configure(false);
txdone_message.done = false;
txdone_message.progress = 0;
txprogress_message.done = false;
txprogress_message.progress = 0;
digit_pos = 0;
sample_count = 0;
@ -148,8 +149,8 @@ void TonesProcessor::on_message(const Message* const p) {
configured = true;
} else {
configured = false;
txdone_message.done = true;
shared_memory.application_queue.push(txdone_message);
txprogress_message.done = true;
shared_memory.application_queue.push(txprogress_message);
}
}
}

View File

@ -62,7 +62,7 @@ private:
int8_t re { 0 }, im { 0 };
uint8_t as { 0 }, ai { 0 };
TXDoneMessage txdone_message { };
TXProgressMessage txprogress_message { };
AudioOutput audio_output { };
};

View File

@ -32,7 +32,6 @@ namespace cc1101 {
// Data rate (Bauds)
// Whitening: Everything except preamble and sync word, init value = 111111111
// See datasheet page 38 for logic schematic
// Packet format: preamble, sync word, (opt) length, (opt) address, payload, (opt) CRC
// Preamble: 8*n bits of 10101010
// Sync word: 2 bytes (can be repeated twice)
@ -100,6 +99,12 @@ private:
modulation_t modulation_ { TWO_FSK };
uint8_t num_preamble_ { 4 };
size_t deviation_ { 4000 };
uint16_t whitening_pn { 0x1FF };
void whitening_init();
uint8_t whiten_byte(uint8_t byte);
};
} /* namespace cc1101 */

View File

@ -73,7 +73,7 @@ public:
ReplayThreadDone = 20,
AFSKRxConfigure = 21,
TXDone = 30,
TXProgress = 30,
Retune = 31,
TonesConfigure = 32,
@ -604,10 +604,10 @@ public:
ReplayConfig* const config;
};
class TXDoneMessage : public Message {
class TXProgressMessage : public Message {
public:
constexpr TXDoneMessage(
) : Message { ID::TXDone }
constexpr TXProgressMessage(
) : Message { ID::TXProgress }
{
}

View File

@ -51,9 +51,9 @@ using modem_baudrate_range_t = range_t<int32_t>;
constexpr modem_baudrate_range_t modem_baudrate_range { 50, 9600 };
constexpr int32_t modem_baudrate_reset_value { 1200 };
using modem_bw_range_t = range_t<int32_t>;
/*using modem_bw_range_t = range_t<int32_t>;
constexpr modem_bw_range_t modem_bw_range { 1000, 50000 };
constexpr int32_t modem_bw_reset_value { 15000 };
constexpr int32_t modem_bw_reset_value { 15000 };*/
using modem_repeat_range_t = range_t<int32_t>;
constexpr modem_repeat_range_t modem_repeat_range { 1, 99 };
@ -151,14 +151,14 @@ void set_modem_baudrate(const int32_t new_value) {
data->modem_baudrate = modem_baudrate_range.clip(new_value);
}
int32_t modem_bw() {
/*int32_t modem_bw() {
modem_bw_range.reset_if_outside(data->modem_bw, modem_bw_reset_value);
return data->modem_bw;
}
void set_modem_bw(const int32_t new_value) {
data->modem_bw = modem_bw_range.clip(new_value);
}
}*/
uint8_t modem_repeat() {
modem_repeat_range.reset_if_outside(data->modem_repeat, modem_repeat_reset_value);

View File

@ -61,8 +61,6 @@ void set_modem_baudrate(const int32_t new_value);
uint8_t modem_repeat();
void set_modem_repeat(const uint32_t new_value);
int32_t modem_bw();
void set_modem_bw(const int32_t new_value);
uint32_t playing_dead();
void set_playing_dead(const uint32_t new_value);

Binary file not shown.