diff --git a/nanovna.h b/nanovna.h index 18fd053..0fa6496 100644 --- a/nanovna.h +++ b/nanovna.h @@ -984,6 +984,7 @@ extern int8_t marker_tracking; void plot_init(void); void update_grid(void); +void update_grid_if_changed(void); void request_to_redraw_grid(void); void redraw_frame(void); //void redraw_all(void); diff --git a/plot.c b/plot.c index 4514719..bdce5d7 100644 --- a/plot.c +++ b/plot.c @@ -110,19 +110,24 @@ float2int(float v) } #endif -void update_grid(void) +static void calculate_grid(int16_t *offset, int16_t *width, freq_t *span) { freq_t gdigit = 1000000000; freq_t fstart = get_sweep_frequency(ST_START) + (setting.frequency_offset - FREQUENCY_SHIFT); freq_t fspan = get_sweep_frequency(ST_SPAN); freq_t grid; + bool time_domain = fspan == 0; - if (fspan == 0) { + if (time_domain) { fspan = setting.actual_sweep_time_us; // Time in uS fstart = 0; } + if (fspan == 0) + fspan = 1; if (config.gridlines == 0) { grid = fspan/10; + if (grid == 0) + grid = 1; } else { if (config.gridlines < 3) config.gridlines = 6; @@ -139,21 +144,54 @@ void update_grid(void) gdigit /= 10; } } - grid_span = grid; - if (grid > 1000) { - grid_offset = (WIDTH) * ((fstart % grid) / 100) / (fspan / 100); - grid_width = (WIDTH) * (grid / 100) / (fspan / 1000); + *span = grid; + if (time_domain) { + // The zero-span x axis is measured in microseconds. Keep the full ratio + // until the final division so 5-20 ms sweeps do not shift by whole pixels. + *offset = (int16_t)((uint64_t)WIDTH * (fstart % grid) / fspan); + *width = (int16_t)((uint64_t)WIDTH * 10U * grid / fspan); + } else if (grid > 1000) { + *offset = (WIDTH) * ((fstart % grid) / 100) / (fspan / 100); + *width = (WIDTH) * (grid / 100) / (fspan / 1000); } else { - grid_offset = (WIDTH) * ((fstart % grid)) / (fspan); - grid_width = (WIDTH) * (grid) / (fspan/10); + *offset = (WIDTH) * ((fstart % grid)) / (fspan); + *width = (WIDTH) * (grid) / (fspan/10); } + if (*width < 1) + *width = 1; if (config.gridlines == 0) - grid_offset = 0; + *offset = 0; +} + +static void apply_grid(int16_t offset, int16_t width, freq_t span) +{ + grid_offset = offset; + grid_width = width; + grid_span = span; // if (setting.waterfall) set_level_meter_or_waterfall(); redraw_request |= REDRAW_FREQUENCY | REDRAW_AREA; } +void update_grid(void) +{ + int16_t offset; + int16_t width; + freq_t span; + calculate_grid(&offset, &width, &span); + apply_grid(offset, width, span); +} + +void update_grid_if_changed(void) +{ + int16_t offset; + int16_t width; + freq_t span; + calculate_grid(&offset, &width, &span); + if (offset != grid_offset || width != grid_width || span != grid_span) + apply_grid(offset, width, span); +} + #if 0 static int rectangular_grid(int x, int y) diff --git a/sa_core.c b/sa_core.c index 1ffdf3c..b9d6ecf 100644 --- a/sa_core.c +++ b/sa_core.c @@ -5700,6 +5700,11 @@ static volatile int dummy; redraw_request|=REDRAW_CAL_STATUS | REDRAW_FREQUENCY; } setting.actual_sweep_time_us = setting.measure_sweep_time_us; + // The zero-span x axis represents the sweep that just completed. Recompute + // its tuple every time; update_grid_if_changed() suppresses redraws while + // the exact grid geometry remains unchanged. + if (FREQ_IS_CW()) + update_grid_if_changed(); // Not possible reduce sweep time, it minimum! if (setting.sweep_time_us < setting.actual_sweep_time_us && setting.additional_step_delay_us == 0){ // Warning!! not correct set sweep time here, you get error!!