diff --git a/main.c b/main.c index 53117ee..fa8e69d 100644 --- a/main.c +++ b/main.c @@ -37,8 +37,8 @@ static void apply_error_term(void); static void apply_error_term_at(int i); static void cal_interpolate(int s); -static void apply_edelay_at(int i); -void sweep(void); + +bool sweep(bool break_on_operation); static MUTEX_DECL(mutex); @@ -51,12 +51,10 @@ int32_t freq = 1; int32_t step = 1; int count; int8_t drive_strength = DRIVE_STRENGTH_AUTO; -int8_t frequency_updated = FALSE; int8_t sweep_enabled = TRUE; int8_t sweep_once = FALSE; int8_t cal_auto_interpolate = TRUE; -int8_t redraw_requested = FALSE; -int8_t stop_the_world = FALSE; +uint16_t redraw_request = 0; // contains REDRAW_XXX flags int16_t vbat = 0; BaseSequentialStream *saved_chp; @@ -67,24 +65,20 @@ static THD_FUNCTION(Thread1, arg) chRegSetThreadName("sweep"); while (1) { - if (stop_the_world) { - __WFI(); - continue; - } + bool completed = false; - if (sweep_enabled) { + if (sweep_enabled || sweep_once) { chMtxLock(&mutex); - sweep(); - if (sweep_once) { - sweep_enabled = FALSE; + completed = sweep(true); sweep_once = FALSE; - } chMtxUnlock(&mutex); } else { __WFI(); - ui_process(); } + chMtxLock(&mutex); + ui_process(); + if (sweep_enabled) { if (vbat != -1) { adc_stop(ADC1); vbat = adc_vbat_read(ADC1); @@ -93,9 +87,14 @@ static THD_FUNCTION(Thread1, arg) } /* calculate trace coordinates */ + if (completed) { plot_into_index(measured); + redraw_request |= REDRAW_CELLS; + } + } /* plot trace as raster */ - draw_all_cells(); + draw_all(completed); // flush markmap only if scan completed to prevent remaining traces + chMtxUnlock(&mutex); } } @@ -190,12 +189,12 @@ transform_domain(void) tmp[i*2+1] = 0.0; } -// if (is_lowpass) { + if (is_lowpass) { for (int i = 1; i < 101; i++) { tmp[(FFT_SIZE-i)*2+0] = tmp[i*2+0]; tmp[(FFT_SIZE-i)*2+1] = -tmp[i*2+1]; } - // } + } fft256_inverse((float(*)[2])tmp); memcpy(measured[ch], tmp, sizeof(measured[0])); @@ -229,6 +228,12 @@ static void cmd_resume(BaseSequentialStream *chp, int argc, char *argv[]) (void)chp; (void)argc; (void)argv; + + // restore frequencies array and cal + update_frequencies(); + if (cal_auto_interpolate && (cal_status & CALSTAT_APPLY)) + cal_interpolate(lastsaveid); + resume_sweep(); } @@ -471,13 +476,15 @@ static void cmd_data(BaseSequentialStream *chp, int argc, char *argv[]) if (sel == 0 || sel == 1) { chMtxLock(&mutex); for (i = 0; i < sweep_points; i++) { - chprintf(chp, "%f %f\r\n", measured[sel][i][0], measured[sel][i][1]); + if (frequencies[i] != 0) + chprintf(chp, "%f %f\r\n", measured[sel][i][0], measured[sel][i][1]); } chMtxUnlock(&mutex); } else if (sel >= 2 && sel < 7) { chMtxLock(&mutex); for (i = 0; i < sweep_points; i++) { - chprintf(chp, "%f %f\r\n", cal_data[sel-2][i][0], cal_data[sel-2][i][1]); + if (frequencies[i] != 0) + chprintf(chp, "%f %f\r\n", cal_data[sel-2][i][0], cal_data[sel-2][i][1]); } chMtxUnlock(&mutex); } else { @@ -515,10 +522,7 @@ static void cmd_capture(BaseSequentialStream *chp, int argc, char *argv[]) (void)argc; (void)argv; - // pause sweep - stop_the_world = TRUE; - - chThdSleepMilliseconds(1000); + chMtxLock(&mutex); // use uint16_t spi_buffer[1024] (defined in ili9341) for read buffer uint16_t *buf = &spi_buffer[0]; @@ -541,7 +545,7 @@ static void cmd_capture(BaseSequentialStream *chp, int argc, char *argv[]) } //*/ - stop_the_world = FALSE; + chMtxUnlock(&mutex); } #if 0 @@ -642,55 +646,8 @@ ensure_edit_config(void) cal_status = 0; } - -static void cmd_scan(BaseSequentialStream *chp, int argc, char *argv[]) -{ - (void)argc; - (void)argv; - - if (argc == 3 ) { - freq = atoi(argv[0]); - step = atoi(argv[1]); - count = atoi(argv[2]); - } else { - chprintf(chp, "usage: scan start(Hz) step(Hz) points\r\n"); - return; - } - pause_sweep(); - chMtxLock(&mutex); - saved_chp = chp; - sweep_once = TRUE; - sweep_enabled = TRUE; - chMtxUnlock(&mutex); -#if 0 - float gamma[2]; - int i; - int32_t freq, step; - int delay; - (void)argc; - (void)argv; - - pause_sweep(); - chMtxLock(&mutex); - freq = frequency0; - step = (frequency1 - frequency0) / (sweep_points-1); - set_frequency(freq); - delay = 4; - for (i = 0; i < sweep_points; i++) { - freq = freq + step; - wait_dsp(delay); - delay = set_frequency(freq); - palClearPad(GPIOC, GPIOC_LED); - calculate_gamma(gamma); - palSetPad(GPIOC, GPIOC_LED); - chprintf(chp, "%d %d\r\n", gamma[0], gamma[1]); - } - chMtxUnlock(&mutex); -#endif -} - // main loop for measurement -void sweep(void) +bool sweep(bool break_on_operation) { int i; int delay; @@ -700,7 +657,6 @@ void sweep(void) if (sweep_once) chprintf(saved_chp, "start\r\n"); - rewind: frequency_updated = FALSE; //delay = 3; if (!sweep_once) { @@ -748,19 +704,46 @@ void sweep(void) if (electrical_delay != 0) apply_edelay_at(i); } - redraw_requested = FALSE; - ui_process(); - if (redraw_requested) - break; // return to redraw screen asap. - - if (frequency_updated) - goto rewind; + // back to toplevel to handle ui operation + if (operation_requested && break_on_operation) + return false; freq += step; } if (sweep_once) chprintf(saved_chp, "done\r\n"); else transform_domain(); + return true; +} + +static void cmd_scan(BaseSequentialStream *chp, int argc, char *argv[]) +{ + + if (argc != 2 && argc != 3) { + chprintf(chp, "usage: sweep {start(Hz)} {step(Hz)} [points]\r\n"); + return; + } + + freq = atoi(argv[0]); + step = atoi(argv[1]); + count = 101; + if (argc == 3 ) { + count = atoi(argv[2]); + + + + } + pause_sweep(); + chMtxLock(&mutex); + if (cal_auto_interpolate && (cal_status & CALSTAT_APPLY)) + cal_interpolate(lastsaveid); + saved_chp = chp; + sweep_once = TRUE; + chMtxUnlock(&mutex); + + // wait finishing sweep + while (sweep_once) + chThdSleepMilliseconds(10); } static void @@ -795,27 +778,36 @@ update_marker_index(void) } void -update_frequencies(void) +set_frequencies(uint32_t start, uint32_t stop, int16_t points) { int i; - int32_t span; - int32_t start; + float span = stop - start; + for (i = 0; i < points; i++) { + float offset = i * span / (float)(points - 1); + frequencies[i] = start + (uint32_t)offset; + } + // disable at out of sweep range + for (; i < sweep_points; i++) + frequencies[i] = 0; +} + +void +update_frequencies(void) +{ + uint32_t start, stop; if (frequency1 > 0) { start = frequency0; - span = (frequency1 - frequency0)/100; + stop = frequency1; } else { - int center = frequency0; - span = -frequency1; + int32_t center = frequency0; + int32_t span = -frequency1; start = center - span/2; - span /= 100; + stop = center + span/2; } - for (i = 0; i < sweep_points; i++) - frequencies[i] = start + span * i / (sweep_points - 1) * 100; - + set_frequencies(start, stop, sweep_points); update_marker_index(); - frequency_updated = TRUE; // set grid layout update_grid(); } @@ -855,7 +847,7 @@ void set_sweep_frequency(int type, float frequency) { int32_t freq = frequency; - bool cal_applied = cal_status & CALSTAT_APPLY; + int cal_applied = cal_status & CALSTAT_APPLY; switch (type) { case ST_START: freq_mode_startstop(); @@ -969,8 +961,7 @@ static void cmd_sweep(BaseSequentialStream *chp, int argc, char *argv[]) chprintf(chp, "%d %d %d\r\n", frequency0, frequency1, sweep_points); return; } else if (argc > 3) { - chprintf(chp, "usage: sweep {start(Hz)} [stop] [points]\r\n"); - return; + goto usage; } if (argc >= 2) { if (strcmp(argv[0], "start") == 0) { @@ -998,12 +989,18 @@ static void cmd_sweep(BaseSequentialStream *chp, int argc, char *argv[]) if (argc >= 1) { int32_t value = atoi(argv[0]); + if (value == 0) + goto usage; set_sweep_frequency(ST_START, value); } if (argc >= 2) { int32_t value = atoi(argv[1]); set_sweep_frequency(ST_STOP, value); } + return; +usage: + chprintf(chp, "usage: sweep {start(Hz)} [stop(Hz)]\r\n"); + chprintf(chp, "\tsweep {start|stop|center|span|cw} {freq(Hz)}\r\n"); } @@ -1119,12 +1116,8 @@ eterm_calc_et(void) int i; for (i = 0; i < sweep_points; i++) { // Et = 1/(S21mt - Ex)(1 - Es) - float esr = 1 - cal_data[ETERM_ES][i][0]; - float esi = -cal_data[ETERM_ES][i][1]; - float s21mr = cal_data[CAL_THRU][i][0] - cal_data[CAL_ISOLN][i][0]; - float s21mi = cal_data[CAL_THRU][i][1] - cal_data[CAL_ISOLN][i][1]; - float etr = esr * s21mr - esi * s21mi; - float eti = esr * s21mi + esi * s21mr; + float etr = cal_data[CAL_THRU][i][0] - cal_data[CAL_ISOLN][i][0]; + float eti = cal_data[CAL_THRU][i][1] - cal_data[CAL_ISOLN][i][1]; float sq = etr*etr + eti*eti; float invr = etr / sq; float invi = -eti / sq; @@ -1246,6 +1239,7 @@ cal_collect(int type) break; } chMtxUnlock(&mutex); + redraw_request |= REDRAW_CAL_STATUS; } void @@ -1280,6 +1274,7 @@ cal_done(void) } cal_status |= CALSTAT_APPLY; + redraw_request |= REDRAW_CAL_STATUS; } void @@ -1365,19 +1360,18 @@ static void cmd_cal(BaseSequentialStream *chp, int argc, char *argv[]) cal_collect(CAL_ISOLN); } else if (strcmp(cmd, "done") == 0) { cal_done(); - draw_cal_status(); return; } else if (strcmp(cmd, "on") == 0) { cal_status |= CALSTAT_APPLY; - draw_cal_status(); + redraw_request |= REDRAW_CAL_STATUS; return; } else if (strcmp(cmd, "off") == 0) { cal_status &= ~CALSTAT_APPLY; - draw_cal_status(); + redraw_request |= REDRAW_CAL_STATUS; return; } else if (strcmp(cmd, "reset") == 0) { cal_status = 0; - draw_cal_status(); + redraw_request |= REDRAW_CAL_STATUS; return; } else if (strcmp(cmd, "data") == 0) { chprintf(chp, "%f %f\r\n", cal_data[CAL_LOAD][0][0], cal_data[CAL_LOAD][0][1]); @@ -1391,7 +1385,7 @@ static void cmd_cal(BaseSequentialStream *chp, int argc, char *argv[]) if (argc > 1) s = atoi(argv[1]); cal_interpolate(s); - draw_cal_status(); + redraw_request |= REDRAW_CAL_STATUS; return; } else { chprintf(chp, "usage: cal [load|open|short|thru|isoln|done|reset|on|off|in]\r\n"); @@ -1410,7 +1404,7 @@ static void cmd_save(BaseSequentialStream *chp, int argc, char *argv[]) if (id < 0 || id >= SAVEAREA_MAX) goto usage; caldata_save(id); - draw_cal_status(); + redraw_request |= REDRAW_CAL_STATUS; return; usage: @@ -1432,7 +1426,7 @@ static void cmd_recall(BaseSequentialStream *chp, int argc, char *argv[]) if (caldata_recall(id) == 0) { // success update_frequencies(); - draw_cal_status(); + redraw_request |= REDRAW_CAL_STATUS; } chMtxUnlock(&mutex); resume_sweep(); @@ -1583,6 +1577,7 @@ static void cmd_trace(BaseSequentialStream *chp, int argc, char *argv[]) } return; } + if (strcmp(argv[0], "all") == 0 && argc > 1 && strcmp(argv[1], "off") == 0) { set_trace_type(0, TRC_OFF); @@ -1694,6 +1689,7 @@ static void cmd_marker(BaseSequentialStream *chp, int argc, char *argv[]) active_marker = -1; for (t = 0; t < 4; t++) markers[t].enabled = FALSE; + redraw_request |= REDRAW_MARKER; return; } @@ -1704,6 +1700,7 @@ static void cmd_marker(BaseSequentialStream *chp, int argc, char *argv[]) chprintf(chp, "%d %d %d\r\n", t+1, markers[t].index, frequency); active_marker = t; markers[t].enabled = TRUE; + redraw_request |= REDRAW_MARKER; return; } if (argc > 1) { @@ -1711,15 +1708,18 @@ static void cmd_marker(BaseSequentialStream *chp, int argc, char *argv[]) markers[t].enabled = FALSE; if (active_marker == t) active_marker = -1; + redraw_request |= REDRAW_MARKER; } else if (strcmp(argv[1], "on") == 0) { markers[t].enabled = TRUE; active_marker = t; + redraw_request |= REDRAW_MARKER; } else { markers[t].enabled = TRUE; int index = atoi(argv[1]); markers[t].index = index; markers[t].frequency = frequencies[index]; active_marker = t; + redraw_request |= REDRAW_MARKER; } } return; @@ -1767,7 +1767,8 @@ static void cmd_frequencies(BaseSequentialStream *chp, int argc, char *argv[]) (void)argc; (void)argv; for (i = 0; i < sweep_points; i++) { - chprintf(chp, "%d\r\n", frequencies[i]); + if (frequencies[i] != 0) + chprintf(chp, "%d\r\n", frequencies[i]); } } @@ -1903,7 +1904,7 @@ static void cmd_stat(BaseSequentialStream *chp, int argc, char *argv[]) #define VERSION "unknown" #endif -const char NANOVNA_VERSION[] = "edy555 0.1.1"; +const char NANOVNA_VERSION[] = "edy555 0.2.2"; static void cmd_version(BaseSequentialStream *chp, int argc, char *argv[]) { diff --git a/nanovna.h b/nanovna.h index bebad06..ef4425c 100644 --- a/nanovna.h +++ b/nanovna.h @@ -236,7 +236,7 @@ void redraw_marker(int marker, int update_info); void trace_get_info(int t, char *buf, int len); void plot_into_index(float measured[2][101][2]); void force_set_markmap(void); -void draw_all_cells(void); +void draw_all(bool flush); void draw_cal_status(void); @@ -245,7 +245,13 @@ void markmap_all_markers(void); void marker_position(int m, int t, int *x, int *y); int search_nearest_index(int x, int y, int t); -extern int8_t redraw_requested; +extern uint16_t redraw_request; + +#define REDRAW_CELLS (1<<0) +#define REDRAW_FREQUENCY (1<<1) +#define REDRAW_CAL_STATUS (1<<2) +#define REDRAW_MARKER (1<<3) + extern int16_t vbat; /* @@ -334,7 +340,6 @@ int config_recall(void); void clear_all_config_prop_data(void); - /* * ui.c */ diff --git a/plot.c b/plot.c index f8fb0c9..ad43241 100644 --- a/plot.c +++ b/plot.c @@ -89,7 +89,7 @@ void update_grid(void) grid_width = (WIDTH-1) * (fgrid / 100) / (fspan / 1000); force_set_markmap(); - draw_frequencies(); + redraw_request |= REDRAW_FREQUENCY; } int @@ -942,11 +942,15 @@ search_index_range_x(int x, uint32_t index[101], int *i0, int *i1) i = (head + tail) / 2; if (x == CELL_X0(index[i])) break; - - if (x < CELL_X0(index[i])) - tail = i+1; - else + else if (x < CELL_X0(index[i])) { + if (tail == i+1) + break; + tail = i+1; + } else { + if (head == i) + break; head = i; + } } if (x != CELL_X0(index[i])) @@ -1248,22 +1252,33 @@ draw_cell(int m, int n) } void -draw_all_cells(void) +draw_all_cells(bool flush_markmap) { int m, n; for (m = 0; m < (area_width+CELLWIDTH-1) / CELLWIDTH; m++) for (n = 0; n < (area_height+CELLHEIGHT-1) / CELLHEIGHT; n++) { if (is_mapmarked(m, n)) draw_cell(m, n); - //ui_process(); - //if (operation_requested) - // return; } - // keep current map for update - swap_markmap(); - // clear map for next plotting - clear_markmap(); + if (flush_markmap) { + // keep current map for update + swap_markmap(); + // clear map for next plotting + clear_markmap(); + } +} + +void +draw_all(bool flush) +{ + if (redraw_request & REDRAW_CELLS) + draw_all_cells(flush); + if (redraw_request & REDRAW_FREQUENCY) + draw_frequencies(); + if (redraw_request & REDRAW_CAL_STATUS) + draw_cal_status(); + redraw_request = 0; } void @@ -1276,7 +1291,7 @@ redraw_marker(int marker, int update_info) if (update_info) markmap[current_mappage][0] = 0xffff; - draw_all_cells(); + draw_all_cells(TRUE); } void @@ -1286,7 +1301,7 @@ request_to_draw_cells_behind_menu(void) for (m = 7; m <= 9; m++) for (n = 0; n < 8; n++) mark_map(m, n); - redraw_requested = TRUE; + redraw_request |= REDRAW_CELLS; } void @@ -1296,7 +1311,7 @@ request_to_draw_cells_behind_numeric_input(void) for (m = 0; m <= 9; m++) for (n = 6; n < 8; n++) mark_map(m, n); - redraw_requested = TRUE; + redraw_request |= REDRAW_CELLS; } @@ -1584,7 +1599,7 @@ void request_to_redraw_grid(void) { force_set_markmap(); - redraw_requested = TRUE; + redraw_request |= REDRAW_CELLS; } void @@ -1595,14 +1610,6 @@ redraw_frame(void) draw_cal_status(); } -/*void -redraw_all(void) -{ - redraw(); - force_set_markmap(); - draw_all_cells(); - }*/ - void plot_init(void) { diff --git a/ui.c b/ui.c index bc4acd0..8cccb6d 100644 --- a/ui.c +++ b/ui.c @@ -587,15 +587,17 @@ menu_trace_cb(int item) if (item < 0 || item >= 4) return; if (trace[item].enabled) { - trace[item].enabled = FALSE; - choose_active_trace(); + if (item == uistat.current_trace) { + // disable if active trace is selected + trace[item].enabled = FALSE; + choose_active_trace(); + } else { + // make active selected trace + uistat.current_trace = item; + } } else { trace[item].enabled = TRUE; uistat.current_trace = item; - //menu_move_back(); - //request_to_redraw_grid(); - //ui_mode_normal(); - //redraw_all(); } request_to_redraw_grid(); draw_menu(); @@ -832,15 +834,38 @@ menu_marker_op_cb(int item) //redraw_all(); } +void +active_marker_select(int item) +{ + if (item == -1) { + active_marker = previous_marker; + previous_marker = -1; + if (active_marker == -1) { + choose_active_marker(); + } + } else { + if (previous_marker != active_marker) + previous_marker = active_marker; + active_marker = item; + } +} + static void menu_marker_sel_cb(int item) { if (item >= 0 && item < 4) { - // enable specified marker - markers[item].enabled = TRUE; - if (previous_marker != active_marker) - previous_marker = active_marker; - active_marker = item; + if (markers[item].enabled) { + if (item == active_marker) { + // disable if active trace is selected + markers[item].enabled = FALSE; + active_marker_select(-1); + } else { + active_marker_select(item); + } + } else { + markers[item].enabled = TRUE; + active_marker_select(item); + } } else if (item == 4) { /* all off */ markers[0].enabled = FALSE; markers[1].enabled = FALSE; @@ -849,10 +874,8 @@ menu_marker_sel_cb(int item) previous_marker = -1; active_marker = -1; } - if (active_marker >= 0) - redraw_marker(active_marker, TRUE); + redraw_marker(active_marker, TRUE); draw_menu(); - //ui_mode_normal(); } const menuitem_t menu_calop[] = {