diff --git a/flash.c b/flash.c index e5caf7b..6d11baf 100644 --- a/flash.c +++ b/flash.c @@ -233,6 +233,9 @@ caldata_recall(uint16_t id) /* duplicated saved data onto sram to be able to modify marker/trace */ memcpy(dst, src, sizeof(setting_t)); +#ifdef __SD_FILE_BROWSER__ + sd_preset_path[0] = 0; // this preset came from flash, not from SD +#endif #if 0 // Restore stored trace src = &(src[1]); diff --git a/main.c b/main.c index 36f9d43..a7b085a 100644 --- a/main.c +++ b/main.c @@ -1986,10 +1986,10 @@ show_one: do_one = true; goto show_one; } -#if MAX_UNIT_TYPE != 7 +#if MAX_UNIT_TYPE != 8 #error "Unit type enum possibly changed, check cmd_trace function" #endif - static const char cmd_type_list[] = "dBm|dBmV|dBuV|RAW|V|Vpp|W"; + static const char cmd_type_list[] = "dBm|dBmV|dBuV|RAW|V|Vpp|W|dBV"; if (argc == 1) { int type = get_str_index(argv[0], cmd_type_list); if (type >= 0) { diff --git a/nanovna.h b/nanovna.h index 1068946..f323edd 100644 --- a/nanovna.h +++ b/nanovna.h @@ -775,13 +775,15 @@ enum trace_type { // Electrical Delay // Phase -#define MAX_UNIT_TYPE 7 // Index of U_DBC +#define MAX_UNIT_TYPE 8 // Index of U_DBC +// New units must be appended before U_DBC, the values below U_DBC are stored in +// setting.unit (flash presets and .prs files) and may not be renumbered enum unit_type { - U_DBM=0, U_DBMV, U_DBUV, U_RAW, U_VOLT, U_VPP, U_WATT, U_DBC // dBc only for displaying delta marker info + U_DBM=0, U_DBMV, U_DBUV, U_RAW, U_VOLT, U_VPP, U_WATT, U_DBV, U_DBC // dBc only for displaying delta marker info }; -#define UNIT_IS_LINEAR(T) ( T >= U_VOLT ? true : false) -#define UNIT_IS_LOG(T) ( T >= U_VOLT ? false : true) +#define UNIT_IS_LINEAR(T) ((T) >= U_VOLT && (T) <= U_WATT) +#define UNIT_IS_LOG(T) (!UNIT_IS_LINEAR(T)) float value(float); float index_to_value(const int i); @@ -1759,6 +1761,11 @@ void testLog(void); // debug log void sd_card_load_config(char *filename); extern systime_t last_auto_save; void save_csv(uint8_t mask); +#ifdef __SD_FILE_BROWSER__ +// Full path of the preset last loaded from SD, empty when the active preset did +// not come from SD. Used to default the name when storing a preset back to SD. +extern char sd_preset_path[FF_LFN_BUF]; +#endif #endif /* diff --git a/plot.c b/plot.c index e9c1992..9bbf119 100644 --- a/plot.c +++ b/plot.c @@ -394,6 +394,8 @@ value(const float v) return v + (30.0 + 20.0*log10f(sqrtf(50.0))); case U_DBUV: return v + (90.0 + 20.0*log10f(sqrtf(50.0))); + case U_DBV: + return v + (-30.0 + 20.0*log10f(sqrtf(50.0))); case U_VOLT: // return powf(10.0, (v-30.0)/20.0) * sqrtf(50.0); // powf(10.0, v /20.0) * powf(10, -30.0/20.0) * sqrtf(50) return expf(v*(logf(10.0)/20.0)) * (powf(10, -30.0/20.0)*sqrtf(50));// expf(v*logf(10.0)/20.0) * powf(10, -30.0/20.0) * sqrtf(50) @@ -418,6 +420,8 @@ to_dBm(const float v) return v - (30.0 + 20.0*log10f(sqrtf(50.0))); case U_DBUV: return v - (90.0 + 20.0*log10f(sqrtf(50.0))); + case U_DBV: + return v - (-30.0 + 20.0*log10f(sqrtf(50.0))); case U_VOLT: // return log10f(v/(sqrtf(50.0)))* 20.0 + 30.0; return logf(v/(sqrtf(50.0)))*(20.0/logf(10.0)) + 30.0; @@ -485,6 +489,7 @@ trace_into_index_y_array(index_y_t *y, float *array, int points) #endif case U_DBMV: ref_shift = 30.0 + 20.0*log10f(sqrtf(50.0));break; case U_DBUV: ref_shift = 90.0 + 20.0*log10f(sqrtf(50.0));break; + case U_DBV: ref_shift = -30.0 + 20.0*log10f(sqrtf(50.0));break; case U_VOLT: vmult = powf(10, -30.0/20.0) * sqrtf(50.0); mult = logf(10.0)/20.0;break; case U_VPP: vmult = 2.828* powf(10, -30.0/20.0) * sqrtf(50.0); mult = logf(10.0)/20.0;break; case U_WATT: vmult = 1.0/1000.0; mult = logf(10.0)/10.0;break; diff --git a/sa_core.c b/sa_core.c index e72625d..4046a20 100644 --- a/sa_core.c +++ b/sa_core.c @@ -592,6 +592,9 @@ void update_min_max_freq(void) void reset_settings(int m) { // strcpy((char *)spi_buffer, dummy); +#ifdef __SD_FILE_BROWSER__ + sd_preset_path[0] = 0; // active preset no longer comes from SD +#endif setting.mode = m; setting.sweep = false; disable_waterfall(); diff --git a/ui.c b/ui.c index 7c7e237..7bd3cac 100644 --- a/ui.c +++ b/ui.c @@ -102,6 +102,22 @@ void ui_set_keypad_text(const char *text) plot_printf(kp_buf, sizeof(kp_buf), "%s", text); } +// Set when kp_buf holds a default that the next keypad must start with instead +// of an empty buffer, so a single ENTER accepts it unchanged +static bool keypad_text_preset = false; + +#ifdef __SD_FILE_BROWSER__ +// Preset the keypad input with the first len characters of text +static void ui_preset_keypad_text(const char *text, int len) +{ + if (len > (int)sizeof(kp_buf) - 1) + len = sizeof(kp_buf) - 1; + memcpy(kp_buf, text, len); + kp_buf[len] = 0; + keypad_text_preset = true; +} +#endif + static uint8_t ui_mode = UI_NORMAL; static uint8_t keypad_mode; static char *kp_help_text = NULL; @@ -4351,6 +4367,12 @@ static const char *file_ext[] = { [FMT_BND_FILE] = "bnd", }; +#ifdef __SD_FILE_BROWSER__ +// Full path of the preset last loaded from SD, empty when the active preset did +// not come from SD (startup preset, stored slot or factory defaults). +char sd_preset_path[FF_LFN_BUF] = {0}; +#endif + static void sa_save_file(uint8_t format); static UI_FUNCTION_CALLBACK(menu_sdcard_cb) { @@ -5304,6 +5326,7 @@ static const menuitem_t menu_display[] = { static const menuitem_t menu_unit[] = { { MT_ADV_CALLBACK,U_DBM, "dBm", menu_unit_acb}, + { MT_ADV_CALLBACK,U_DBV, "dBV", menu_unit_acb}, { MT_ADV_CALLBACK,U_DBMV, "dBmV", menu_unit_acb}, { MT_ADV_CALLBACK,U_DBUV, "dB"S_MICRO"V", menu_unit_acb}, { MT_ADV_CALLBACK,U_VOLT, "Vrms", menu_unit_acb}, @@ -6190,7 +6213,8 @@ float my_round(float v) } return v; } -const char * const unit_string[MAX_UNIT_TYPE*2] = { "dBm", "dBmV", "dB"S_MICRO"V", "RAW", "Vrms", "Vpp", "W", "dB", "dB", "dB", "RAW", "Vrms", "Vpp", "W" }; // unit + 6 is delta unit +const char * const unit_string[MAX_UNIT_TYPE*2] = { "dBm", "dBmV", "dB"S_MICRO"V", "RAW", "Vrms", "Vpp", "W", "dBV", + "dB", "dB", "dB", "RAW", "Vrms", "Vpp", "W", "dB" }; // unit + MAX_UNIT_TYPE is delta unit //static const float scale_value[]={50000, 20000, 10000, 5000, 2000, 1000, 500, 200, 100, 50, 20,10,5,2,1,0.5,0.2,0.1,0.05,0.02,0.01,0.005,0.002, 0.001,0.0005,0.0002, 0.0001}; //static const char * const scale_vtext[]= {"50000", "20000", "10000", "5000", "2000", "1000", "500", "200", "100", "50", "20","10","5","2","1","0.5","0.2","0.1","0.05","0.02","0.01", "0.005","0.002","0.001", "0.0005","0.0002","0.0001"}; @@ -7846,8 +7870,19 @@ ui_process_keypad(void) { int status; int keypads_last_index = keypads[0].pos - 1; - kp_buf[0] = 0; + // Keep a preset default only when the keypad is really shown, a remote menu + // invoke must not silently accept it + bool preset_text = keypad_text_preset && !in_menu_command; + keypad_text_preset = false; + if (!preset_text) + kp_buf[0] = 0; if (in_menu_command) return; + if (preset_text) { // show the default, ENTER accepts it as is + if (keypads[0].c == NUM_KEYBOARD) + draw_numeric_input(kp_buf); + else + draw_text_input(kp_buf); + } while (TRUE) { status = btn_check(); if (status & (EVT_UP|EVT_DOWN)) { @@ -8025,6 +8060,17 @@ static void sa_save_file(uint8_t format) { #endif } else { +#ifdef __SD_FILE_BROWSER__ + // Storing a preset: offer the SD preset it was loaded from as default name, + // so a single ENTER writes back to that same file + if (format == FMT_PRS_FILE && sd_preset_path[0]) { + int len = strlen(sd_preset_path); + int ext = strlen(file_ext[format]) + 1; // ".prs" + if (len > ext && sd_preset_path[len - ext] == '.') // keypad adds the extension back + len -= ext; + ui_preset_keypad_text(sd_preset_path, len); + } +#endif ui_mode_keypad(KM_FILENAME); if (kp_buf[0] == 0) return; plot_printf(fs_filename, FF_LFN_BUF, "%s.%s", kp_buf, file_ext[format]); diff --git a/vna_browser.c b/vna_browser.c index 33f7312..0773ea8 100644 --- a/vna_browser.c +++ b/vna_browser.c @@ -322,6 +322,8 @@ static char cmd_buffer[256+128]; set_scale(setting.scale); set_reflevel(setting.reflevel); set_level_meter_or_waterfall(); + // Remember where this preset came from so storing it back can default to it + plot_printf(sd_preset_path, sizeof(sd_preset_path), "%s", fno.fname); } else error = "Format err"; }