diff --git a/firmware/application/apps/ui_encoders.cpp b/firmware/application/apps/ui_encoders.cpp index 5292e383..f811a3d6 100644 --- a/firmware/application/apps/ui_encoders.cpp +++ b/firmware/application/apps/ui_encoders.cpp @@ -36,16 +36,17 @@ EncodersConfigView::EncodersConfigView( using option_t = std::pair; std::vector 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, + &field_repeat_min, &field_clk, &field_clk_step, &field_frameduration, @@ -58,18 +59,18 @@ EncodersConfigView::EncodersConfigView( // 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 field_clk.on_change = [this](int32_t value) { // value is in kHz, new_value is in us @@ -81,7 +82,7 @@ EncodersConfigView::EncodersConfigView( field_clk_step.on_change = [this](size_t, int32_t value) { field_clk.set_step(value); }; - + // Selecting word duration changes input clock and symbol duration field_frameduration.on_change = [this](int32_t value) { // value is in us, new_value is in kHz @@ -107,7 +108,8 @@ void EncodersConfigView::on_type_change(size_t index) { encoder_def = &encoder_defs[index]; field_clk.set_value(encoder_def->default_speed / 1000); - + field_repeat_min.set_value(encoder_def->repeat_min); + // SymField setup word_length = encoder_def->word_length; symfield_word.set_length(word_length); @@ -122,10 +124,10 @@ void EncodersConfigView::on_type_change(size_t index) { format_string += 'D'; } } - + // Ugly :( Pad to erase format_string.append(24 - format_string.size(), ' '); - + text_format.set(format_string); generate_frame(); @@ -141,28 +143,28 @@ void EncodersConfigView::draw_waveform() { for (size_t n = 0; n < length; n++) waveform_buffer[n] = (frame_fragments[n] == '0') ? 0 : 1; - + waveform.set_length(length); waveform.set_dirty(); } void EncodersConfigView::generate_frame() { size_t i = 0; - + frame_fragments.clear(); - + for (auto c : encoder_def->word_format) { if (c == 'S') frame_fragments += encoder_def->sync; else frame_fragments += encoder_def->bit_format[symfield_word.get_sym(i++)]; } - + draw_waveform(); } uint8_t EncodersConfigView::repeat_min() { - return encoder_def->repeat_min; + return field_repeat_min.value(); } uint32_t EncodersConfigView::samples_per_bit() { @@ -174,7 +176,7 @@ uint32_t EncodersConfigView::pause_symbols() { } void EncodersScanView::focus() { - field_debug.focus(); + field_length.focus(); } EncodersScanView::EncodersScanView( @@ -182,31 +184,17 @@ EncodersScanView::EncodersScanView( ) { set_parent_rect(parent_rect); hidden(true); - + add_children({ &labels, - &field_debug, - &text_debug, - &text_length + &field_length, + &bit_length_10, + &bit_length }); - - // DEBUG - field_debug.on_change = [this](int32_t value) { - uint32_t l; - size_t length; - - de_bruijn debruijn_seq; - length = 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)); - - text_length.set(to_string_dec_uint(length)); - }; + + field_length.set_value(8); + bit_length_10.set_value(40); + bit_length.set_value(0); } void EncodersView::focus() { @@ -215,7 +203,7 @@ void EncodersView::focus() { EncodersView::~EncodersView() { // save app settings - app_settings.tx_frequency = transmitter_model.tuning_frequency(); + app_settings.tx_frequency = transmitter_model.tuning_frequency(); settings.save("tx_ook", &app_settings); transmitter_model.disable(); @@ -225,24 +213,11 @@ EncodersView::~EncodersView() { void EncodersView::update_progress() { std::string str_buffer; - - // text_status.set(" "); - - if (tx_mode == SINGLE) { + + if (tx_mode == SINGLE || tx_mode == SCAN) { str_buffer = to_string_dec_uint(repeat_index) + "/" + to_string_dec_uint(repeat_min); text_status.set(str_buffer); progressbar.set_value(repeat_index); - - /*} else if (tx_mode == SCAN) { - strcpy(str, to_string_dec_uint(repeat_index).c_str()); - strcat(str, "/"); - strcat(str, to_string_dec_uint(portapack::persistent_memory::afsk_repeats()).c_str()); - strcat(str, " "); - strcat(str, to_string_dec_uint(scan_index + 1).c_str()); - strcat(str, "/"); - strcat(str, to_string_dec_uint(scan_count).c_str()); - text_status.set(str); - progress.set_value(scan_progress);*/ } else { text_status.set("Ready"); progressbar.set_value(0); @@ -250,89 +225,58 @@ void EncodersView::update_progress() { } void EncodersView::on_tx_progress(const uint32_t progress, const bool done) { - //char str[16]; - if (!done) { // Repeating... repeat_index = progress + 1; - - /*if (tx_mode == SCAN) { - scan_progress++; - update_progress(); - } else {*/ - update_progress(); - //} + update_progress(); } else { + // make sure all samples are transmitted before disabling radio + chThdSleepMilliseconds(10); + // Done transmitting - /*if ((tx_mode == SCAN) && (scan_index < (scan_count - 1))) { - transmitter_model.disable(); - if (abort_scan) { - // Kill scan process - strcpy(str, "Abort @"); - strcat(str, rgsb); - text_status.set(str); - progress.set_value(0); - tx_mode = IDLE; - abort_scan = false; - button_scan.set_style(&style_val); - button_scan.set_text("SCAN"); - } else { - // Next address - scan_index++; - strcpy(rgsb, &scan_list[options_scanlist.selected_index()].addresses[scan_index * 5]); - scan_progress++; - repeat_index = 1; - update_progress(); - start_tx(true); - } - } else {*/ - transmitter_model.disable(); - tx_mode = IDLE; - text_status.set("Done"); - progressbar.set_value(0); - tx_view.set_transmitting(false); - //} + transmitter_model.disable(); + tx_mode = IDLE; + text_status.set("Done"); + progressbar.set_value(0); + tx_view.set_transmitting(false); } } void EncodersView::start_tx(const bool scan) { - (void)scan; size_t bitstream_length = 0; - - repeat_min = view_config.repeat_min(); - - /*if (scan) { - if (tx_mode != SCAN) { - scan_index = 0; - scan_count = scan_list[options_scanlist.selected_index()].count; - scan_progress = 1; - repeat_index = 1; - tx_mode = SCAN; - strcpy(rgsb, &scan_list[options_scanlist.selected_index()].addresses[0]); - progress.set_max(scan_count * afsk_repeats); - update_progress(); - } - } else {*/ + int scan_width = 0; + uint32_t samples_per_bit; + + if (scan) { + tx_mode = 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) * samples_per_bit / 2048; + progressbar.set_max(seq_len); + repeat_min = seq_len; + } else { tx_mode = SINGLE; - repeat_index = 1; + samples_per_bit = view_config.samples_per_bit(); + view_config.generate_frame(); + bitstream_length = make_bitstream(view_config.frame_fragments); progressbar.set_max(repeat_min); - update_progress(); - //} - - view_config.generate_frame(); - - bitstream_length = make_bitstream(view_config.frame_fragments); + repeat_min = view_config.repeat_min(); + } + + repeat_index = 1; + update_progress(); transmitter_model.set_sampling_rate(OOK_SAMPLERATE); - transmitter_model.set_rf_amp(true); transmitter_model.set_baseband_bandwidth(1750000); transmitter_model.enable(); - + baseband::set_ook_data( bitstream_length, - view_config.samples_per_bit(), + samples_per_bit, repeat_min, - view_config.pause_symbols() + view_config.pause_symbols(), + scan_width ); } @@ -350,14 +294,14 @@ EncodersView::EncodersView( &progressbar, &tx_view }); - + // load app settings auto rc = settings.load("tx_ook", &app_settings); - if(rc == SETTINGS_OK) { + if (rc == SETTINGS_OK) { transmitter_model.set_rf_amp(app_settings.tx_amp); transmitter_model.set_channel_bandwidth(app_settings.channel_bandwidth); transmitter_model.set_tuning_frequency(app_settings.tx_frequency); - transmitter_model.set_tx_gain(app_settings.tx_gain); + transmitter_model.set_tx_gain(app_settings.tx_gain); } tx_view.on_edit_frequency = [this, &nav]() { @@ -366,14 +310,16 @@ EncodersView::EncodersView( transmitter_model.set_tuning_frequency(f); }; }; - + tx_view.on_start = [this]() { tx_view.set_transmitting(true); - start_tx(false); + start_tx(tab_view.selected()); }; - + tx_view.on_stop = [this]() { tx_view.set_transmitting(false); + baseband::kill_ook(); + transmitter_model.disable(); }; } diff --git a/firmware/application/apps/ui_encoders.hpp b/firmware/application/apps/ui_encoders.hpp index 883a6b92..f8afc02a 100644 --- a/firmware/application/apps/ui_encoders.hpp +++ b/firmware/application/apps/ui_encoders.hpp @@ -35,43 +35,39 @@ 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_fragments = "0"; private: - //bool abort_scan = false; - //uint8_t scan_count; - //double scan_progress; - //unsigned int scan_index; int16_t waveform_buffer[550]; 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() }, + { { 17 * 8, 0 }, "Repeat:", Color::light_grey() }, { { 1 * 8, 2 * 8 }, "Clk:", Color::light_grey() }, { { 10 * 8, 2 * 8 }, "kHz", Color::light_grey() }, - { { 17 * 8, 2 * 8 }, "Step:", Color::light_grey() }, + { { 17 * 8, 2 * 8 }, "Step:", Color::light_grey() }, { { 1 * 8, 4 * 8 }, "Frame:", Color::light_grey() }, - { { 13 * 8, 4 * 8 }, "us", Color::light_grey() }, - { { 17 * 8, 4 * 8 }, "Step", Color::light_grey() }, + { { 13 * 8, 4 * 8 }, "us", Color::light_grey() }, + { { 17 * 8, 4 * 8 }, "Step:", Color::light_grey() }, { { 2 * 8, 7 * 8 }, "Symbols:", Color::light_grey() }, { { 1 * 8, 14 * 8 }, "Waveform:", Color::light_grey() } }; @@ -91,6 +87,14 @@ private: ' ' }; + NumberField field_repeat_min { + { 24 * 8, 0 }, + 2, + { 1, 99 }, + 1, + ' ' + }; + OptionsField field_clk_step { { 22 * 8, 2 * 8 }, 7, @@ -119,18 +123,18 @@ private: { "1000", 1000 } } }; - + SymField symfield_word { { 2 * 8, 9 * 8 }, 20, SymField::SYMFIELD_DEF }; - + Text text_format { { 2 * 8, 11 * 8, 24 * 8, 16 }, "" }; - + Waveform waveform { { 0, 17 * 8, 240, 32 }, waveform_buffer, @@ -145,33 +149,38 @@ private: class EncodersScanView : public View { public: EncodersScanView(NavigationView& nav, Rect parent_rect); - + + NumberField field_length { + { 8 * 8, 0 }, + 2, + { 3, 24 }, + 1, + ' ' + }; + + NumberField bit_length_10 { + { 12 * 8, 2 * 8 }, + 2, + { 1, 88 }, + 1, + ' ' + }; + + NumberField bit_length { + { 14 * 8, 2 * 8 }, + 1, + { 0, 9 }, + 1, + ' ' + }; + void focus() override; private: Labels labels { - { { 1 * 8, 1 * 8 }, "Coming soon...", 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 }, - "" - }; - - // DEBUG - Text text_length { - { 1 * 8, 10 * 8, 24 * 8, 16 }, - "" + { { 1 * 8, 0 * 8 }, "Length:", Color::light_grey() }, + { { 1 * 8, 2 * 8 }, "Bit length:", Color::light_grey() }, + { { 16 * 8, 2 * 8 }, "us", Color::light_grey() }, }; }; @@ -179,9 +188,9 @@ class EncodersView : public View { public: EncodersView(NavigationView& nav); ~EncodersView(); - + void focus() override; - + std::string title() const override { return "OOK TX"; }; private: @@ -192,19 +201,19 @@ private: SINGLE, SCAN }; - + // app save settings - std::app_settings settings { }; + std::app_settings settings { }; std::app_settings::AppSettings app_settings { }; tx_modes tx_mode = IDLE; - uint8_t repeat_index { 0 }; - uint8_t repeat_min { 0 }; - + uint32_t repeat_index { 0 }; + uint32_t repeat_min { 0 }; + void update_progress(); void start_tx(const bool scan); void on_tx_progress(const uint32_t progress, const bool done); - + /*const Style style_address { .font = font::fixed_8x16, .background = Color::black(), @@ -215,32 +224,32 @@ private: .background = Color::black(), .foreground = Color::blue(), };*/ - + Rect view_rect = { 0, 4 * 8, 240, 168 }; - + EncodersConfigView view_config { nav_, view_rect }; EncodersScanView view_scan { nav_, view_rect }; - + TabView tab_view { { "Config", Color::cyan(), &view_config }, - { "Scan", Color::green(), &view_scan }, + { "de Bruijn", Color::green(), &view_scan }, }; Text text_status { { 2 * 8, 13 * 16, 128, 16 }, "Ready" }; - + ProgressBar progressbar { { 2 * 8, 13 * 16 + 20, 208, 16 } }; - + TransmitterView tx_view { 16 * 16, 50000, 9 }; - + MessageHandlerRegistration message_handler_tx_progress { Message::ID::TXProgress, [this](const Message* const p) { diff --git a/firmware/application/baseband_api.cpp b/firmware/application/baseband_api.cpp index 3f7fe12d..b4321577 100644 --- a/firmware/application/baseband_api.cpp +++ b/firmware/application/baseband_api.cpp @@ -146,7 +146,7 @@ void set_btle(const uint32_t baudrate, const uint32_t word_length, const uint32_ }; send_message(&message); } - + void set_nrf(const uint32_t baudrate, const uint32_t word_length, const uint32_t trigger_value, const bool trigger_word) { const NRFRxConfigureMessage message { baudrate, @@ -156,7 +156,7 @@ void set_nrf(const uint32_t baudrate, const uint32_t word_length, const uint32_t }; send_message(&message); } - + void set_afsk_data(const uint32_t afsk_samples_per_bit, const uint32_t afsk_phase_inc_mark, const uint32_t afsk_phase_inc_space, const uint8_t afsk_repeat, const uint32_t afsk_bw, const uint8_t symbol_count) { const AFSKTxConfigureMessage message { @@ -183,7 +183,7 @@ void kill_afsk() { } void set_audiotx_config(const uint32_t divider, const float deviation_hz, const float audio_gain, - uint8_t audio_shift_bits_s16, const uint32_t tone_key_delta, const bool am_enabled, + uint8_t audio_shift_bits_s16, const uint32_t tone_key_delta, const bool am_enabled, const bool dsb_enabled, const bool usb_enabled, const bool lsb_enabled) { const AudioTXConfigMessage message { divider, @@ -212,16 +212,28 @@ void set_pitch_rssi(int32_t avg, bool enabled) { enabled, avg }; - send_message(&message); + send_message(&message); } void set_ook_data(const uint32_t stream_length, const uint32_t samples_per_bit, const uint8_t repeat, - const uint32_t pause_symbols) { + const uint32_t pause_symbols, const uint8_t de_bruijn_length) { const OOKConfigureMessage message { stream_length, samples_per_bit, repeat, - pause_symbols + pause_symbols, + de_bruijn_length + }; + send_message(&message); +} + +void kill_ook() { + const OOKConfigureMessage message { + 0, + 0, + 0, + 0, + 0 }; send_message(&message); } @@ -251,7 +263,7 @@ void set_adsb() { void set_jammer(const bool run, const jammer::JammerType type, const uint32_t speed) { const JammerConfigureMessage message { - run, + run, type, speed }; @@ -312,7 +324,7 @@ void shutdown() { send_message(&message); shared_memory.application_queue.reset(); - + baseband_image_running = false; } diff --git a/firmware/application/baseband_api.hpp b/firmware/application/baseband_api.hpp index e28a49e7..974d4923 100644 --- a/firmware/application/baseband_api.hpp +++ b/firmware/application/baseband_api.hpp @@ -62,7 +62,7 @@ void set_tones_config(const uint32_t bw, const uint32_t pre_silence, const uint1 void kill_tone(); void set_sstv_data(const uint8_t vis_code, const uint32_t pixel_duration); void set_audiotx_config(const uint32_t divider, const float deviation_hz, const float audio_gain, - uint8_t audio_shift_bits_s16, const uint32_t tone_key_delta, const bool am_enabled, + uint8_t audio_shift_bits_s16, const uint32_t tone_key_delta, const bool am_enabled, const bool dsb_enabled, const bool usb_enabled, const bool lsb_enabled); void set_fifo_data(const int8_t * data); void set_pitch_rssi(int32_t avg, bool enabled); @@ -77,7 +77,8 @@ void set_btle(const uint32_t baudrate, const uint32_t word_length, const uint32_ void set_nrf(const uint32_t baudrate, const uint32_t word_length, const uint32_t trigger_value, const bool trigger_word); void set_ook_data(const uint32_t stream_length, const uint32_t samples_per_bit, const uint8_t repeat, - const uint32_t pause_symbols); + const uint32_t pause_symbols, const uint8_t de_bruijn_length = 0); +void kill_ook(); void set_fsk_data(const uint32_t stream_length, const uint32_t samples_per_bit, const uint32_t shift, const uint32_t progress_notice); void set_pocsag(); diff --git a/firmware/baseband/proc_ook.cpp b/firmware/baseband/proc_ook.cpp index 0bf8dfb6..420ca957 100644 --- a/firmware/baseband/proc_ook.cpp +++ b/firmware/baseband/proc_ook.cpp @@ -27,15 +27,88 @@ #include -void OOKProcessor::execute(const buffer_c8_t& buffer) { +inline void OOKProcessor::write_sample(const buffer_c8_t& buffer, uint8_t bit_value, size_t i) { int8_t re, im; - + + if (bit_value) { + phase = (phase + 200); // What ? + sphase = phase + (64 << 18); + + re = (sine_table_i8[(sphase & 0x03FC0000) >> 18]); + im = (sine_table_i8[(phase & 0x03FC0000) >> 18]); + } else { + re = 0; + im = 0; + } + + buffer.p[i] = {re, im}; +} + +inline void OOKProcessor::duval_algo(const buffer_c8_t& buffer) { + 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; + } + + 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--) ; + + if (idx) + v[idx - 1] = 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 (!scan_done) { + txprogress_message.done = true; + shared_memory.application_queue.push(txprogress_message); + } + + scan_done = 1; +} + +void OOKProcessor::execute(const buffer_c8_t& buffer) { // This is called at 2.28M/2048 = 1113Hz - + if (!configured) return; - + + if (de_bruijn_length) { + duval_algo(buffer); + return; + } + for (size_t i = 0; i < buffer.count; i++) { - + // Synthesis at 2.28M/10 = 228kHz if (!s) { s = 10 - 1; @@ -71,7 +144,7 @@ void OOKProcessor::execute(const buffer_c8_t& buffer) { bit_pos++; } } - + sample_count = 0; } else { sample_count++; @@ -79,31 +152,49 @@ void OOKProcessor::execute(const buffer_c8_t& buffer) { } else { s--; } - - if (cur_bit) { - phase = (phase + 200); // What ? - sphase = phase + (64 << 18); - re = (sine_table_i8[(sphase & 0x03FC0000) >> 18]); - im = (sine_table_i8[(phase & 0x03FC0000) >> 18]); - } else { - re = 0; - im = 0; - } - - buffer.p[i] = {re, im}; + write_sample(buffer, cur_bit, i); } } void OOKProcessor::on_message(const Message* const p) { const auto message = *reinterpret_cast(p); - + if (message.id == Message::ID::OOKConfigure) { - samples_per_bit = message.samples_per_bit / 10; + configured = false; + repeat = message.repeat - 1; length = message.stream_length; pause = message.pause_symbols + 1; - + de_bruijn_length = message.de_bruijn_length; + samples_per_bit = message.samples_per_bit; + + if (!length && !samples_per_bit) { + // shutdown + return; + } + + if (de_bruijn_length) { + if (de_bruijn_length > sizeof(v)) { + 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; + } + pause_counter = 0; s = 0; sample_count = samples_per_bit; diff --git a/firmware/baseband/proc_ook.hpp b/firmware/baseband/proc_ook.hpp index e678b45c..6ba55e23 100644 --- a/firmware/baseband/proc_ook.hpp +++ b/firmware/baseband/proc_ook.hpp @@ -29,19 +29,20 @@ class OOKProcessor : public BasebandProcessor { public: void execute(const buffer_c8_t& buffer) override; - + void on_message(const Message* const p) override; private: bool configured = false; - + BasebandThread baseband_thread { 2280000, this, NORMALPRIO + 20, baseband::Direction::Transmit }; - + uint32_t samples_per_bit { 0 }; uint8_t repeat { 0 }; uint32_t length { 0 }; uint32_t pause { 0 }; - + uint8_t de_bruijn_length { 0 }; + uint32_t pause_counter { 0 }; uint8_t repeat_counter { 0 }; uint8_t s { 0 }; @@ -50,8 +51,19 @@ private: uint32_t sample_count { 0 }; uint32_t tone_phase { 0 }, phase { 0 }, sphase { 0 }; int32_t tone_sample { 0 }, sig { 0 }, frq { 0 }; - + TXProgressMessage txprogress_message { }; + + static constexpr auto MAX_DE_BRUIJN_ORDER = 24; + uint8_t v[MAX_DE_BRUIJN_ORDER]; + unsigned int idx { 0 }; + unsigned int k { 0 }; + size_t bit_ptr{ 0 }; + size_t scan_progress{ 0 }; + uint8_t scan_done { true }; + + void write_sample(const buffer_c8_t& buffer, uint8_t bit_value, size_t i); + void duval_algo(const buffer_c8_t& buffer); }; #endif diff --git a/firmware/common/message.hpp b/firmware/common/message.hpp index 38bc1217..a7a0784b 100644 --- a/firmware/common/message.hpp +++ b/firmware/common/message.hpp @@ -306,7 +306,7 @@ using ChannelSpectrumFIFO = FIFO; class ChannelSpectrumConfigMessage : public Message { public: static constexpr size_t fifo_k = 2; - + constexpr ChannelSpectrumConfigMessage( ChannelSpectrumFIFO* fifo ) : Message { ID::ChannelSpectrumConfig }, @@ -352,7 +352,7 @@ public: packet { packet } { } - + pocsag::POCSAGPacket packet; }; @@ -378,7 +378,7 @@ public: amp(amp) { } - + adsb::ADSBFrame frame; uint32_t amp; }; @@ -393,7 +393,7 @@ public: value { value } { } - + bool is_data; uint32_t value; }; @@ -406,7 +406,7 @@ public: value { value } { } - + uint32_t value; }; @@ -584,7 +584,7 @@ public: used_ += copy_size; return copy_size; } - + size_t read(void* p, const size_t count) { const auto copy_size = std::min(used_, count); memcpy(p, &data_[capacity_ - used_], copy_size); @@ -595,7 +595,7 @@ public: bool is_full() const { return used_ >= capacity_; } - + bool is_empty() const { return used_ == 0; } @@ -607,7 +607,7 @@ public: size_t size() const { return used_; } - + size_t capacity() const { return capacity_; } @@ -700,7 +700,7 @@ public: ) : Message { ID::TXProgress } { } - + uint32_t progress = 0; bool done = false; }; @@ -719,7 +719,7 @@ public: trigger_word(trigger_word) { } - + const uint32_t baudrate; const uint32_t word_length; const uint32_t trigger_value; @@ -734,7 +734,7 @@ public: baudrate(baudrate) { } - + const uint32_t baudrate; }; @@ -788,7 +788,7 @@ public: rssi(rssi) { } - + const bool enabled; const int32_t rssi; }; @@ -825,7 +825,7 @@ public: length(length) { } - + const uint16_t length = 0; }; @@ -835,7 +835,7 @@ public: ) : Message { ID::Retune } { } - + int64_t freq = 0; uint32_t range = 0; }; @@ -848,7 +848,7 @@ public: sample_rate(sample_rate) { } - + const uint32_t sample_rate = 0; }; @@ -858,7 +858,7 @@ public: ) : Message { ID::AudioLevelReport } { } - + uint32_t value = 0; }; @@ -964,12 +964,14 @@ public: const uint32_t stream_length, const uint32_t samples_per_bit, const uint8_t repeat, - const uint32_t pause_symbols + const uint32_t pause_symbols, + const uint8_t de_bruijn_length ) : Message { ID::OOKConfigure }, stream_length(stream_length), samples_per_bit(samples_per_bit), repeat(repeat), - pause_symbols(pause_symbols) + pause_symbols(pause_symbols), + de_bruijn_length(de_bruijn_length) { } @@ -977,6 +979,7 @@ public: const uint32_t samples_per_bit; const uint8_t repeat; const uint32_t pause_symbols; + const uint8_t de_bruijn_length; }; class SSTVConfigureMessage : public Message { @@ -1017,7 +1020,7 @@ public: class POCSAGConfigureMessage : public Message { public: - constexpr POCSAGConfigureMessage() + constexpr POCSAGConfigureMessage() : Message { ID::POCSAGConfigure } { } @@ -1031,7 +1034,7 @@ public: packet { packet } { } - + aprs::APRSPacket packet; };