From 8175d1cba03d7dcf9f821146d0594f13388d01dc Mon Sep 17 00:00:00 2001 From: awe Date: Fri, 24 Apr 2026 18:01:45 +0300 Subject: [PATCH] di 1 incre --- main.cpp | 59 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/main.cpp b/main.cpp index 4685665..1b727b3 100644 --- a/main.cpp +++ b/main.cpp @@ -511,8 +511,9 @@ void print_help(const char* exe_name) { << " do1_toggle_per_frame -> hardware cyclic DO1 pattern in module memory:\n" << " DO1 outputs 00110011... continuously (toggle every 2 ADC ticks)\n" << " without per-tick DOUT updates from PC\n" - << " do1_noise_subtract -> with tty + do1_toggle_per_frame, use programmed DO1 phase (0011...)\n" - << " to average recent noise steps and subtract it from useful steps before tty output\n" + << " do1_noise_subtract -> with tty + do1_toggle_per_frame, use DI1 state from synchronous DIN\n" + << " (expected DO1->DI1 loopback) to average recent noise steps and subtract it\n" + << " from useful steps before tty output\n" << " (only corrected DO1=LOW steps are sent to tty)\n" << " noise_avg_steps:N -> number of recent DO1=HIGH noise steps per channel used as subtraction baseline\n" << " (required when do1_noise_subtract is enabled)\n" @@ -543,8 +544,8 @@ void print_help(const char* exe_name) { << "The live HTML supports X/Y zoom buttons, mouse-wheel zoom, and reset.\n" << "For tty output, use di1_group_avg together with di1:trace to emit one averaged 4-word step\n" << "per constant DI1 run while keeping the current ring-buffered binary frame format.\n" - << "For DO1-phase subtraction, use do1_toggle_per_frame + do1_noise_subtract + noise_avg_steps:N;\n" - << "the first ADC sample in each packet is treated as DO1 LOW in the 0011... sequence.\n" + << "For DO1 subtraction with loopback, use do1_toggle_per_frame + do1_noise_subtract + noise_avg_steps:N;\n" + << "DI1 from synchronous DIN is used as the actual DO1 state marker.\n" << "Amplitude mode keeps the raw AD8317 voltage as captured on X1; no inversion is applied.\n" << "\n" << "Phase profile example:\n" @@ -1238,8 +1239,8 @@ struct Do1NoiseSubtractState { std::array noise_ring_sum {}; std::array step_sum {}; std::array step_count {}; - uint32_t ticks_in_step = 0; - bool step_do1_high = false; + bool step_level_initialized = false; + bool step_di1_high = false; uint16_t next_index = 1; void configure(uint32_t history_steps) { @@ -1253,18 +1254,24 @@ struct Do1NoiseSubtractState { void clear_step() { step_sum = {}; step_count = {}; - ticks_in_step = 0; } void reset_packet() { clear_step(); - step_do1_high = false; + step_level_initialized = false; + step_di1_high = false; next_index = 1; noise_ring_head = {}; noise_ring_size = {}; noise_ring_sum = {}; } + void start_new_step(bool di1_high) { + clear_step(); + step_di1_high = di1_high; + step_level_initialized = true; + } + void add_sample(uint32_t lch, double raw_code) { if (lch >= step_sum.size()) { return; @@ -1273,15 +1280,6 @@ struct Do1NoiseSubtractState { ++step_count[lch]; } - bool advance_tick() { - ++ticks_in_step; - if (ticks_in_step < kDo1TogglePeriodTicks) { - return false; - } - ticks_in_step = 0; - return true; - } - bool has_complete_step(uint32_t channel_count) const { return (step_count[0] != 0U) && ((channel_count <= 1U) || (step_count[1] != 0U)); } @@ -1327,11 +1325,7 @@ struct Do1NoiseSubtractState { return noise_ring_sum[lch] / static_cast(size); } - void finish_step() { - step_do1_high = !step_do1_high; - step_sum = {}; - step_count = {}; - } + void finish_step() { clear_step(); } }; int16_t pack_raw_code_to_int16(double avg_raw_code) { @@ -1650,6 +1644,8 @@ int run(const Config& cfg) { << " input buffer words: " << cfg.input_buffer_words << "\n" << " tty di1_group_avg: " << (tty_di1_group_average ? "enabled" : "disabled") << "\n" << " tty do1_noise_subtract: " << (tty_do1_noise_subtract ? "enabled" : "disabled") << "\n" + << " do1_noise_subtract marker: " + << (tty_do1_noise_subtract ? "DI1 from DIN (DO1->DI1 loopback expected)" : "n/a") << "\n" << " noise_avg_steps: " << (tty_do1_noise_subtract ? std::to_string(*cfg.noise_avg_steps) : std::string("n/a")) << "\n" << " stream-only note: ignoring csv/svg/live_html/live_json/live_update_period_ms/svg_history_packets\n"; @@ -1876,6 +1872,10 @@ int run(const Config& cfg) { return; } + if (!tty_do1_noise_state.step_level_initialized) { + return; + } + if (!tty_do1_noise_state.has_complete_step(cfg.channel_count)) { tty_do1_noise_state.finish_step(); return; @@ -1884,7 +1884,7 @@ int run(const Config& cfg) { const double ch1_avg = tty_do1_noise_state.step_average(0U); const double ch2_avg = (cfg.channel_count <= 1U) ? 0.0 : tty_do1_noise_state.step_average(1U); - if (tty_do1_noise_state.step_do1_high) { + if (tty_do1_noise_state.step_di1_high) { tty_do1_noise_state.push_noise_average(0U, ch1_avg); if (cfg.channel_count > 1U) { tty_do1_noise_state.push_noise_average(1U, ch2_avg); @@ -1960,7 +1960,8 @@ int run(const Config& cfg) { append_tty_group_step(); tty_group_state.clear_step(); } else if (tty_do1_noise_subtract) { - // Keep only complete programmed DO1 steps. Partial steps are dropped on packet close. + // Finalize the last DI1 run in packet, drop only incomplete channel tuples. + append_tty_do1_subtracted_step(); tty_do1_noise_state.clear_step(); } @@ -2343,6 +2344,13 @@ int run(const Config& cfg) { if (tty_di1_group_average && di1_changed) { append_tty_group_step(); tty_group_state.clear_step(); + } else if (tty_do1_noise_subtract) { + if (!tty_do1_noise_state.step_level_initialized) { + tty_do1_noise_state.start_new_step(di1_level); + } else if (di1_changed) { + append_tty_do1_subtracted_step(); + tty_do1_noise_state.start_new_step(di1_level); + } } if (!fast_tty_avg_stream_mode && @@ -2356,9 +2364,6 @@ int run(const Config& cfg) { if (fast_packet_frames < target_frames) { if (tty_do1_noise_subtract) { tty_do1_noise_state.add_sample(lch, adc_raw_value); - if (tty_do1_noise_state.advance_tick()) { - append_tty_do1_subtracted_step(); - } } else { tty_group_state.add_sample(lch, adc_raw_value); }