di 1 incre

This commit is contained in:
awe
2026-04-24 18:01:45 +03:00
parent 70b5557be9
commit 8175d1cba0

View File

@ -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<double, 2> noise_ring_sum {};
std::array<double, 2> step_sum {};
std::array<uint32_t, 2> 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<double>(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);
}