From 362c208078b51c53708dca515c5e74561895e651 Mon Sep 17 00:00:00 2001 From: lujji Date: Thu, 2 Feb 2023 17:54:36 +0200 Subject: [PATCH] fix ook app and 1527 encoder; add scan encoding --- firmware/application/apps/ui_encoders.cpp | 5 +- firmware/application/protocols/encoders.hpp | 34 ++--- firmware/baseband/proc_ook.cpp | 143 +++++++++++++------- firmware/baseband/proc_ook.hpp | 18 ++- 4 files changed, 129 insertions(+), 71 deletions(-) diff --git a/firmware/application/apps/ui_encoders.cpp b/firmware/application/apps/ui_encoders.cpp index c9224bc6..ffdae2c4 100644 --- a/firmware/application/apps/ui_encoders.cpp +++ b/firmware/application/apps/ui_encoders.cpp @@ -156,6 +156,8 @@ void EncodersConfigView::generate_frame() { for (auto c : encoder_def->word_format) { if (c == 'S') frame_fragments += encoder_def->sync; + else if (!c) + break; else frame_fragments += encoder_def->bit_format[symfield_word.get_sym(i++)]; } @@ -252,7 +254,8 @@ void EncodersView::start_tx(const bool scan) { scan_width = view_scan.field_length.value(); samples_per_bit = ((view_scan.bit_length_10.value() * 10 + view_scan.bit_length.value()) * OOK_SAMPLERATE) / 1000000UL; - const uint32_t seq_len = ((1 << (scan_width - 1)) * 2) * ((uint64_t) samples_per_bit) / 2048UL; + constexpr auto sym_len = 4; + const uint32_t seq_len = ((1 << (scan_width - 1)) * 2) * ((uint64_t) samples_per_bit) * sym_len / 2048UL; progressbar.set_max(seq_len); repeat_min = seq_len; } else { diff --git a/firmware/application/protocols/encoders.hpp b/firmware/application/protocols/encoders.hpp index d23b38f4..c8f11e4f 100644 --- a/firmware/application/protocols/encoders.hpp +++ b/firmware/application/protocols/encoders.hpp @@ -28,12 +28,12 @@ #define __ENCODERS_H__ namespace encoders { - + #define ENC_TYPES_COUNT 14 #define OOK_SAMPLERATE 2280000U - + #define ENCODER_UM3750 8 - + size_t make_bitstream(std::string& fragments); void bitstream_append(size_t& bitstream_length, uint32_t bit_count, uint32_t bits); @@ -65,7 +65,7 @@ namespace encoders { 150000, 2, 0 }, - + // PT2260-R4 { "2260-R4", @@ -77,7 +77,7 @@ namespace encoders { 150000, 2, 0 }, - + // PT2262 { "2262 ", @@ -89,7 +89,7 @@ namespace encoders { 20000, 4, 0 }, - + // 16-bit ? { "16-bit ", @@ -101,7 +101,7 @@ namespace encoders { 25000, 50, 0 // ? }, - + // RT1527 { "1527 ", @@ -111,9 +111,9 @@ namespace encoders { 24, "SAAAAAAAAAAAAAAAAAAAADDDD", "10000000000000000000000000000000", 100000, 4, - 10 // ? + 0 }, - + // HK526E { "526E ", @@ -125,7 +125,7 @@ namespace encoders { 20000, 4, 10 // ? }, - + // HT12E { "12E ", @@ -137,7 +137,7 @@ namespace encoders { 3000, 4, 10 // ? }, - + // VD5026 13 bits ? { "5026 ", @@ -149,7 +149,7 @@ namespace encoders { 100000, 4, 10 // ? }, - + // UM3750 { "UM3750 ", @@ -161,7 +161,7 @@ namespace encoders { 100000, 4, (3 * 12) - 6 // Compensates for pause delay bug in proc_ook }, - + // UM3758 { "UM3758 ", @@ -173,7 +173,7 @@ namespace encoders { 160000, 4, 10 // ? }, - + // BA5104 { "BA5104 ", @@ -185,7 +185,7 @@ namespace encoders { 455000, 4, 10 // ? }, - + // MC145026 { "145026 ", @@ -197,7 +197,7 @@ namespace encoders { 455000, 2, 2 }, - + // HT6*** TODO: Add individual variations { "HT6*** ", @@ -209,7 +209,7 @@ namespace encoders { 80000, 3, 10 // ? }, - + // TC9148 { "TC9148 ", diff --git a/firmware/baseband/proc_ook.cpp b/firmware/baseband/proc_ook.cpp index 6572c112..821fc7b3 100644 --- a/firmware/baseband/proc_ook.cpp +++ b/firmware/baseband/proc_ook.cpp @@ -44,57 +44,118 @@ inline void OOKProcessor::write_sample(const buffer_c8_t& buffer, uint8_t bit_va buffer.p[i] = {re, im}; } -inline void OOKProcessor::duval_algo(const buffer_c8_t& buffer) { +bool OOKProcessor::scan_init(unsigned int order) { + if (order > MAX_DE_BRUIJN_ORDER) + return false; + + scan_done = false; + scan_progress = 0; + + k = 0; + idx = 1; + + duval_symbols = 2; // 2 for binary, 3 for ternary encoders + duval_length = 0; + duval_bit = 0; + duval_sample_bit = 0; + duval_symbol = 0; + + memset(v, 0, sizeof(v)); + return true; +} + +bool OOKProcessor::scan_encode(const buffer_c8_t& buffer, size_t& buf_ptr) { + // encode data: 0 = 1000, 1 = 1110 + // @TODO: make this user-configurable + const uint8_t sym[] = { 0b0001, 0b0111 }; + constexpr auto symbol_length = 4; + + // iterate over every symbol in the sequence and convert it to bits with required bitrate + for (; duval_bit < duval_length; duval_bit++) { + auto val = v_tmp[duval_bit]; + for (; duval_symbol < symbol_length; duval_symbol++) { + auto s = sym[val] & (1 << duval_symbol); + for (; duval_sample_bit < samples_per_bit; duval_sample_bit++) { + if (buf_ptr >= buffer.count) { + // buffer is full - continue next time + txprogress_message.done = false; + txprogress_message.progress = scan_progress++; + shared_memory.application_queue.push(txprogress_message); + return false; + } + write_sample(buffer, s, buf_ptr++); + } + duval_sample_bit = 0; + } + duval_symbol = 0; + } + duval_bit = 0; + return true; +} + +inline size_t OOKProcessor::duval_algo_step() { size_t buf_ptr = 0; const unsigned int w = de_bruijn_length; // Duval's algorithm for generating de Bruijn sequence while (idx) { if (w % idx == 0) { - for (; k < idx; k++) { - size_t available_size = buffer.count - buf_ptr; - size_t len = (samples_per_bit > available_size) ? available_size : samples_per_bit; - - for (; bit_ptr < len; bit_ptr++) { - write_sample(buffer, v[k], buf_ptr); - buf_ptr++; - } - - if (buf_ptr == buffer.count) { - txprogress_message.done = false; - txprogress_message.progress = scan_progress++; - shared_memory.application_queue.push(txprogress_message); - return; - } - - bit_ptr = 0; - } - + for (unsigned int k = 0; k < idx; k++) + v_tmp[buf_ptr++] = v[k]; k = 0; } for (unsigned int j = 0; j < w - idx; j++) v[idx + j] = v[j]; - for (idx = w; idx > 0 && v[idx - 1]; idx--) ; + for (idx = w; (idx > 0) && (v[idx - 1] >= duval_symbols - 1); idx--) ; if (idx) - v[idx - 1] = 1; - } + v[idx - 1]++; - // clear the buffer in case we have any bytes left - if (buf_ptr < buffer.count) { - for (size_t i = buf_ptr; i < buffer.count; i++) { - buffer.p[i] = {0, 0}; + if (buf_ptr) { + // we fill at most de_bruijn_length number of elements + return buf_ptr; } } - if (!scan_done) { - txprogress_message.done = true; - shared_memory.application_queue.push(txprogress_message); - } + return 0; +} - scan_done = 1; +void OOKProcessor::scan_process(const buffer_c8_t& buffer) { + size_t buf_ptr = 0; + + // transmit any leftover bits from previous step + if (!scan_encode(buffer, buf_ptr)) + return; + + while (1) { + // calculate next chunk of deBruijn sequence + duval_length = duval_algo_step(); + + if (duval_length == 0) { + // last chunk - done + if (!scan_done) { + txprogress_message.done = true; + shared_memory.application_queue.push(txprogress_message); + } + scan_done = 1; + + // clear the remaining buffer in case we have any bytes left + for (size_t i = buf_ptr; i < buffer.count; i++) + buffer.p[i] = { 0, 0 }; + + break; + } + + duval_bit = 0; + duval_sample_bit = 0; + duval_symbol = 0; + + // encode the sequence into required format + if (!scan_encode(buffer, buf_ptr)) + break; + } } void OOKProcessor::execute(const buffer_c8_t& buffer) { @@ -103,7 +164,7 @@ void OOKProcessor::execute(const buffer_c8_t& buffer) { if (!configured) return; if (de_bruijn_length) { - duval_algo(buffer); + scan_process(buffer); return; } @@ -175,22 +236,8 @@ void OOKProcessor::on_message(const Message* const p) { } if (de_bruijn_length) { - if (de_bruijn_length > sizeof(v)) { + if (!scan_init(de_bruijn_length)) return; - } - - if (samples_per_bit > 2048) { - // can't handle more than dma::transfer_samples - return; - } - - k = 0; - bit_ptr = 0; - idx = 1; - scan_done = false; - scan_progress = 0; - - memset(v, 0, sizeof(v)); } else { samples_per_bit /= 10; } diff --git a/firmware/baseband/proc_ook.hpp b/firmware/baseband/proc_ook.hpp index 6ba55e23..eda493d2 100644 --- a/firmware/baseband/proc_ook.hpp +++ b/firmware/baseband/proc_ook.hpp @@ -46,9 +46,9 @@ private: uint32_t pause_counter { 0 }; uint8_t repeat_counter { 0 }; uint8_t s { 0 }; - uint16_t bit_pos { 0 }; - uint8_t cur_bit { 0 }; - uint32_t sample_count { 0 }; + uint16_t bit_pos { 0 }; + uint8_t cur_bit { 0 }; + uint32_t sample_count { 0 }; uint32_t tone_phase { 0 }, phase { 0 }, sphase { 0 }; int32_t tone_sample { 0 }, sig { 0 }, frq { 0 }; @@ -56,14 +56,22 @@ private: static constexpr auto MAX_DE_BRUIJN_ORDER = 24; uint8_t v[MAX_DE_BRUIJN_ORDER]; + uint8_t v_tmp[MAX_DE_BRUIJN_ORDER]; unsigned int idx { 0 }; unsigned int k { 0 }; - size_t bit_ptr{ 0 }; + unsigned int duval_symbols { 0 }; + unsigned int duval_length { 0 }; + unsigned int duval_bit { 0 }; + unsigned int duval_sample_bit { 0 }; + unsigned int duval_symbol { 0 }; size_t scan_progress{ 0 }; uint8_t scan_done { true }; + size_t duval_algo_step(); + void scan_process(const buffer_c8_t& buffer); + bool scan_init(unsigned int order); + bool scan_encode(const buffer_c8_t& buffer, size_t& buf_ptr); void write_sample(const buffer_c8_t& buffer, uint8_t bit_value, size_t i); - void duval_algo(const buffer_c8_t& buffer); }; #endif