From 91539cbd61f43f89562424fc209244ea81433987 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Wed, 9 Oct 2024 20:22:14 +0300 Subject: [PATCH] Rewrite trigger render Allow drag triggers Fix Trigger level value on menu (if selected different unit format) Fixed triggers lines in multi band mode if used different point count Small fixes --- main.c | 1 + nanovna.h | 9 ++- plot.c | 198 +++++++++++++++++++++++++++++++++++++----------------- sa_core.c | 3 +- ui.c | 43 +++++++++++- 5 files changed, 187 insertions(+), 67 deletions(-) diff --git a/main.c b/main.c index db49bba..986b65f 100644 --- a/main.c +++ b/main.c @@ -2640,6 +2640,7 @@ static void shell_init_connection(void) { * Set I/O stream (SDU1 or SD1) for shell */ PREPARE_STREAM; + shell_reset_console(); } #else diff --git a/nanovna.h b/nanovna.h index b707ae0..3f5341b 100644 --- a/nanovna.h +++ b/nanovna.h @@ -624,6 +624,8 @@ extern uint16_t graph_bottom; // Marker start drag distance (can be bigger for various display resolution) #define MARKER_PICKUP_DISTANCE 20 +// Trigger line start drag distance (can be bigger for various display resolution) +#define DRAG_TRIGGER_DISTANCE 10 // Smith/polar chart //#define P_CENTER_X (CELLOFFSETX + WIDTH/2) @@ -968,6 +970,7 @@ void redraw_frame(void); void request_to_draw_cells_behind_menu(void); void request_to_draw_cells_behind_numeric_input(void); void redraw_marker(int marker); +void redraw_trigger(int band); void markmap_all_markers(void); void plot_into_index(measurement_t measured); void draw_frequencies(void); @@ -979,6 +982,10 @@ void draw_cal_status(void); int distance_to_index(int8_t t, uint16_t idx, int16_t x, int16_t y); int search_nearest_index(int x, int y, int t); +int search_nearest_trigger(int x, int y); + +float pos_to_trigger_value(int y); +bool is_multiband_trigger(void); int marker_search_max(int m); int marker_search_left_max(int m); @@ -1604,7 +1611,7 @@ extern volatile uint8_t abort_enabled; // lever_mode enum lever_mode { - LM_MARKER, LM_SEARCH, LM_CENTER, LM_SPAN, LM_EDELAY + LM_MARKER, LM_SEARCH, LM_CENTER, LM_SPAN, LM_TRIGGER }; // marker smith value format diff --git a/plot.c b/plot.c index 76ce72f..7c806e1 100644 --- a/plot.c +++ b/plot.c @@ -423,7 +423,7 @@ to_dBm(const float v) return logf(v/(sqrtf(50.0)))*(20.0/logf(10.0)) + 30.0; case U_VPP: // return log10f(v/(sqrtf(50.0)))* 20.0 + 30.0; - return logf((v/2.828)/(sqrtf(50.0)))*(20.0/logf(10.0)) + 30.0; + return logf(v/(2.828*sqrtf(50.0)))*(20.0/logf(10.0)) + 30.0; case U_WATT: // return log10f(v*1000.0)* 10.0; return logf(v*1000.0)*(10.0/logf(10.0)); @@ -503,13 +503,19 @@ trace_into_index_y_array(index_y_t *y, float *array, int points) if (mult) value = fast_expf(value*mult); value = ref - value * scale; int v = value; - if (v < 0) v = 0; - else if (v > max) v = max; + if (v < 0) v = 0; + else if (v >= max) v = max-1; y[i] = v; } return; } +static index_y_t trace_into_index_y(float level) { + index_y_t tp; + trace_into_index_y_array(&tp, &level, 1); + return tp; +} + static inline void swap_markmap(void) { @@ -583,43 +589,50 @@ markmap_upperarea(void) #endif } -static uint16_t get_trigger_level( #ifdef __BANDS__ - int x -#else - void -#endif - ){ - index_y_t trigger; -#ifdef TINYSA4 - if (setting.trigger_trace != 255) - setting.trigger_level = measured[setting.trigger_trace][x]; -#endif -#ifdef __BANDS__ - else if (!setting.draw_line && setting.multi_band && !setting.multi_trace) { - int b = getBand(x); - setting.trigger_level = setting.bands[b].level; - } +// Triggers draw in multiband mode +bool is_multiband_trigger(void) { + if (setting.multi_band && !setting.multi_trace + #ifdef __DRAW_LINE__ + && !setting.draw_line + #endif + ) return true; + return false; +} + +// Mark band trigger area for redraw +static void markmap_band_trigger(int band) { + band_t *b = &setting.bands[band]; + if (!b->enabled) return; + int tp = trace_into_index_y(b->level); + int x1 = trace_index_x[b->start_index == 0 ? b->start_index : b->start_index - 1]; + int x2 = trace_index_x[b->stop_index]; + invalidate_rect(x1, tp, x2, tp); +} #endif - trace_into_index_y_array(&trigger, &setting.trigger_level, 1); - return trigger; + +// Mark trigger area or line for redraw +static void markmap_trigger(void) { + int tp = trace_into_index_y(setting.trigger_level); + markmap[current_mappage][tp/CELLWIDTH] = (map_t)0xFFFFFFFF; } -static inline void -markmap_trigger_area(void){ +// Mark all trigger lines area for redraw +static void markmap_trigger_area(void) { #ifdef __BANDS__ - uint16_t tp = get_trigger_level(0); -#else - uint16_t tp = get_trigger_level(); + if (is_multiband_trigger()) { + for (int band = 0; band < BANDS_MAX; band++) + markmap_band_trigger(band); + } else #endif - markmap[current_mappage][tp/CELLWIDTH] = (map_t)0xFFFFFFFF; + markmap_trigger(); } // // in most cases _compute_outcode clip calculation not give render line speedup // static inline void -cell_drawline(int x0, int y0, int x1, int y1, int c) +cell_drawline(int x0, int y0, int x1, int y1, pixel_t c) { if (x0 < 0 && x1 < 0) return; if (y0 < 0 && y1 < 0) return; @@ -654,6 +667,24 @@ cell_drawline(int x0, int y0, int x1, int y1, int c) } } +static void +cell_draw_hline(int x0, int x1, int y, pixel_t c) { + if ((uint32_t)y >= CELLHEIGHT) return; +// if (x1 < x0) SWAP(x0, x1); + if (x0 < 0) x0 = 0; + if (x1 > CELLWIDTH) x1 = CELLWIDTH; + for (;x0 < x1; x0++) cell_buffer[y * CELLWIDTH + x0] = c; +} + +static void +cell_draw_vline(int y0, int y1, int x, pixel_t c) { + if ((uint32_t)x >= CELLWIDTH) return; +// if (y1 < y0) SWAP(y0, y1); + if (y0 < 0) y0 = 0; + if (y1 > CELLHEIGHT) y1 = CELLHEIGHT; + for (;y0 < y1; y0++) cell_buffer[y0 * CELLWIDTH + x] = c; +} + // Give a little speedup then draw rectangular plot (50 systick on all calls, all render req 700 systick) // Write more difficult algoritm for seach indexes not give speedup static int @@ -1150,50 +1181,42 @@ draw_cell(int m, int n) #ifdef __CHANNEL_POWER__ if (setting.measurement == M_CP||setting.measurement == M_SNR) { c = GET_PALTETTE_COLOR(LCD_TRIGGER_COLOR); - for (x = 0; x < w; x++) - if (x+x0 == WIDTH/3 || x+x0 == 2*WIDTH/3 ) { - for (y = 0; y < h; y++) cell_buffer[y * CELLWIDTH + x] = c; - } - } -#endif -#ifdef __BANDS__ - if (setting.multi_band && !setting.multi_trace) { - c = GET_PALTETTE_COLOR(LCD_TRIGGER_COLOR); - for (x = 0; x < w; x++) { - int idx1 = ((x+x0) * sweep_points) / WIDTH; - int idx2 = ((x+x0+1) * sweep_points) / WIDTH; - if (getBand(idx1) != getBand(idx2) && idx2 < WIDTH-2) { - for (y = 0; y < h; y++) cell_buffer[y * CELLWIDTH + x] = c; - } - } + cell_draw_vline(0, h, 1*WIDTH/3 - x0, c); + cell_draw_vline(0, h, 2*WIDTH/3 - x0, c); } #endif // PULSE; #endif -// Draw trigger line - if ((setting.trigger != T_AUTO + + // Draw trigger and band splitter lines + bool draw_trigger = (setting.trigger != T_AUTO #ifdef __TRIGGER_TRACE__ && setting.trigger_trace == 255 #endif - ) + ); + c = GET_PALTETTE_COLOR(LCD_TRIGGER_COLOR); +#ifdef __BANDS__ + if (setting.multi_band && !setting.multi_trace) { + for (int band = 0; band < BANDS_MAX; band++) { + band_t *b = &setting.bands[band]; + if (!b->enabled) continue; + // Get start and stop band display position + int x1 = trace_index_x[b->start_index == 0 ? 0 : b->start_index - 1] - x0; + int x2 = trace_index_x[b->stop_index ] - x0; + cell_draw_vline(0, h, x2, c); // Draw vertical band splitter + if (draw_trigger) // Draw trigger line + cell_draw_hline(x1, x2, trace_into_index_y(b->level) - y0, c); + } + draw_trigger = false; // triggers draw in multi-band mode + } +#endif + // Draw line or single trigger line + if (draw_trigger #ifdef __DRAW_LINE__ || setting.draw_line #endif - ) { - c = GET_PALTETTE_COLOR(LCD_TRIGGER_COLOR); -#ifndef __BANDS__ - int tp = get_trigger_level() - y0; - if (tp>=0 && tp < h) -#endif - for (x = 0; x < w; x++) { -#ifdef __BANDS__ - int tp = get_trigger_level(x + x0 - CELLOFFSETX) - y0; - if (tp>=0 && tp < h) -#endif - if ((uint32_t)(x + x0 - CELLOFFSETX) <= WIDTH + CELLOFFSETX) - cell_buffer[tp * CELLWIDTH + x] = c; - } - } + ) cell_draw_hline(0, w, trace_into_index_y(setting.trigger_level) - y0, c); + #if 1 // Only right cells if (m >= (GRID_X_TEXT)/CELLWIDTH) @@ -1369,6 +1392,57 @@ draw_all(bool flush) redraw_request = 0; } +// +// Call this function then need fast draw trigger line +// Used in ui.c for leveler move trigger (not added yet), drag trigger and etc. +void redraw_trigger(int band) { + (void)band; +#ifdef __BANDS__ + if (is_multiband_trigger()) + markmap_band_trigger(band); + else +#endif + markmap_trigger(); + draw_all_cells(TRUE); + redraw_request|= REDRAW_CAL_STATUS | REDRAW_AREA; // Force redraw cal after +} + +// Convert y display position to value in dBm +float pos_to_trigger_value(int y) { + if (y < 0) y = 0; + if (y > area_height) y = area_height; + return to_dBm(get_trace_refpos() - get_trace_scale() * (float)(y * NGRIDY) / area_height); +} + +// Search nearest trigger line on screen +int search_nearest_trigger(int x, int y) { + if ((setting.trigger == T_AUTO // Not in auto mode + #ifdef __TRIGGER_TRACE__ + || setting.trigger_trace != 255 // Not in Trigger trace mode + #endif + ) + #ifdef __DRAW_LINE__ + && !setting.draw_line // Allow in draw line mode + #endif + ) return -1; +#ifdef __BANDS__ + if (is_multiband_trigger()) { + for (int band = 0; band < BANDS_MAX; band++) { + band_t *b = &setting.bands[band]; + if (!b->enabled) continue; + int x1 = trace_index_x[b->start_index]; + int x2 = trace_index_x[b->stop_index ]; + if (x < x1 || x > x2) continue; + int tl = trace_into_index_y(b->level) + DRAG_TRIGGER_DISTANCE - y; + if ((uint32_t)tl < 2 * DRAG_TRIGGER_DISTANCE) return band; + } + return -1; + } +#endif + int tl = trace_into_index_y(setting.trigger_level) + DRAG_TRIGGER_DISTANCE - y; + if ((uint32_t)tl < 2 * DRAG_TRIGGER_DISTANCE) return 0; + return -1; +} // // Call this function then need fast draw marker and marker info diff --git a/sa_core.c b/sa_core.c index ed07505..52cbd9e 100644 --- a/sa_core.c +++ b/sa_core.c @@ -2046,7 +2046,7 @@ void set_trigger_level(float trigger_level) #ifdef __TRIGGER_TRACE__ setting.trigger_trace = 255; #endif - redraw_request |= REDRAW_TRIGGER | REDRAW_CAL_STATUS | REDRAW_AREA; + redraw_request |= REDRAW_TRIGGER | REDRAW_CAL_STATUS; //dirty = true; // No HW update required, only status panel refresh } @@ -2058,7 +2058,6 @@ void set_trigger(int trigger) setting.trigger_direction = trigger; } else if (trigger == T_DONE) { pause_sweep(); // Trigger once so pause after this sweep has completed!!!!!!! - redraw_request |= REDRAW_CAL_STATUS; // Show status change setting.trigger = trigger; setting.trigger = trigger; } else { sweep_mode = SWEEP_ENABLE; diff --git a/ui.c b/ui.c index 11a9217..225447f 100644 --- a/ui.c +++ b/ui.c @@ -264,7 +264,7 @@ static int btn_wait_release(void) #ifdef SOFTWARE_TOUCH // ADC read count for measure X and Y (2^N count) #define TOUCH_X_N 3 -#define TOUCH_Y_N 3 +#define TOUCH_Y_N 4 static int touch_measure_y(void) { @@ -3197,7 +3197,7 @@ static UI_FUNCTION_ADV_CALLBACK(menu_trigger_level_acb) format = "LEVEL\n\b%.3F%s"; // 5 characters incl u, m, etc... else format = "LEVEL\n\b%.1f%s"; - plot_printf(b->text, sizeof(b->text), format, setting.trigger_level,unit_string[setting.unit]); + plot_printf(b->text, sizeof(b->text), format, value(setting.trigger_level),unit_string[setting.unit]); } else { plot_printf(b->text, sizeof(b->text), "LEVEL\n\bTRACE %d", setting.trigger_trace+1); } @@ -7347,6 +7347,23 @@ lever_search_marker(int status) } while (status != 0); } +#if 0 +void lever_trigger(int status) { + static uint16_t lever_band = 0; + float *level = &setting.trigger_level; +#ifdef __BANDS__ + if (is_multiband_trigger()) level = &setting.bands[lever_band].level; +#endif + do { + if (status & EVT_DOWN) *level+= 0.5f; + if (status & EVT_UP ) *level-= 0.5f; + redraw_trigger(lever_band); + lcd_printf(180, 312, "%02x %.2f %.2f", lever_band, setting.bands[lever_band].level, setting.trigger_level); + status = btn_wait_release(); + } while (status != 0); +} +#endif + // ex. 10942 -> 10000 // 6791 -> 5000 // 341 -> 200 @@ -7438,6 +7455,7 @@ ui_process_normal_lever(void) else lever_move(status, FREQ_IS_STARTSTOP() ? ST_STOP : ST_SPAN); break; +// case LM_TRIGGER: lever_trigger(status); break; } } } @@ -7766,6 +7784,24 @@ touch_pickup_marker(int touch_x, int touch_y) return TRUE; } +static int touch_pickup_trigger(int touch_x, int touch_y) { + touch_x -= OFFSETX; + touch_y -= OFFSETY; + + int band = search_nearest_trigger(touch_x, touch_y); + if (band < 0) return FALSE; + float *level = &setting.trigger_level; +#ifdef __BANDS__ + if (is_multiband_trigger()) level = &setting.bands[band].level; +#endif + do { // wait touch release + touch_position(&touch_x, &touch_y); + *level = pos_to_trigger_value(touch_y - OFFSETY); + redraw_trigger(band); + } while (touch_check()!= EVT_TOUCH_RELEASED); + return TRUE; +} + static int touch_quick_menu(int touch_x, int touch_y) { if (touch_x