From 7032e739771ed7bb0b7806956dea0872c61ee1b3 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Mon, 13 Oct 2025 10:08:35 +0300 Subject: [PATCH] Make SD card icon configurable It's now possible to save capture, traces, or both by clicking SD card icon Disabling both options hides SD card icon Config submenu was added to Storage menu, and all settings were moved there Existing config remains valid, and default behavior with saving a capture is kept --- flash.c | 7 +++++++ main.c | 3 +++ nanovna.h | 15 +++++++++++++++ plot.c | 2 +- ui.c | 49 +++++++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 71 insertions(+), 5 deletions(-) diff --git a/flash.c b/flash.c index 81e9a78..e5caf7b 100644 --- a/flash.c +++ b/flash.c @@ -121,6 +121,13 @@ config_recall(void) /* duplicated saved data onto sram to be able to modify marker/trace */ memcpy(dst, src, sizeof(config_t)); + +#ifdef __USE_SD_CARD__ + // Migrate from old config without sd_icon_save member + if (config.sd_icon_save == 0) + config.sd_icon_save = SDIS_DEFAULT; +#endif // __USE_SD_CARD__ + return 0; } diff --git a/main.c b/main.c index 622da6e..dd30911 100644 --- a/main.c +++ b/main.c @@ -1237,6 +1237,9 @@ config_t config = { .overclock = 0, .hide_21MHz = false, #endif +#ifdef __USE_SD_CARD__ + .sd_icon_save = SDIS_DEFAULT, +#endif // __USE_SD_CARD__ }; diff --git a/nanovna.h b/nanovna.h index fb47599..ebdf308 100644 --- a/nanovna.h +++ b/nanovna.h @@ -801,6 +801,18 @@ float marker_to_value(const int i); #define _MODE_AUTO_FILENAME 0x10 #define _MODE_MHZ_CSV 0x20 +#ifdef __USE_SD_CARD__ +// SD Icon Save (SDIS) configuration +#define SDIS_CAPTURE (1 << 0) +#define SDIS_TRACES (1 << 1) +// Validity mask is needed to distinguish disabled SD card icon saving +// from the case with old config that does not have sd_icon_save member +// (the corresponding padding byte was always equal to zero) +#define SDIS_VALID_MASK (1 << 7) +#define SDIS_DEFAULT (SDIS_CAPTURE | SDIS_VALID_MASK) +#define SDIS_IS_ENABLED ((config.sd_icon_save & ~SDIS_VALID_MASK) != 0) +#endif // __USE_SD_CARD__ + #pragma pack(push, 4) typedef struct config { int32_t magic; @@ -882,6 +894,9 @@ typedef struct config { uint8_t hide_21MHz; uint8_t no_audio_agc; #endif +#ifdef __USE_SD_CARD__ + uint8_t sd_icon_save; // enum +#endif // __USE_SD_CARD__ float sweep_voltage; float switch_offset; int16_t ext_zero_level; diff --git a/plot.c b/plot.c index b4bd0ab..b6033bf 100644 --- a/plot.c +++ b/plot.c @@ -1995,7 +1995,7 @@ static const uint8_t sd_icon [] = { _BMP16(0b0101010101011000), //14 _BMP16(0b0111111111111000) // }; - if (SD_Inserted()){ + if (SD_Inserted() && SDIS_IS_ENABLED) { ili9341_set_foreground(LCD_BRIGHT_COLOR_GREEN); ili9341_blitBitmap(4, SD_CARD_START, 16, 16, sd_icon); // ili9341_drawstring("-SD-", x, SD_CARD_START); diff --git a/ui.c b/ui.c index 3371825..dd564cc 100644 --- a/ui.c +++ b/ui.c @@ -4368,6 +4368,32 @@ static UI_FUNCTION_ADV_CALLBACK(menu_mhz_csv_acb) config_save(); } +static UI_FUNCTION_ADV_CALLBACK(menu_sd_icon_save_capture_acb) +{ + (void)item; + (void)data; + + if (b) { + b->icon = config.sd_icon_save & SDIS_CAPTURE ? BUTTON_ICON_CHECK : BUTTON_ICON_NOCHECK; + return; + } + config.sd_icon_save ^= SDIS_CAPTURE; + config_save(); +} + +static UI_FUNCTION_ADV_CALLBACK(menu_sd_icon_save_traces_acb) +{ + (void)item; + (void)data; + + if (b) { + b->icon = config.sd_icon_save & SDIS_TRACES ? BUTTON_ICON_CHECK : BUTTON_ICON_NOCHECK; + return; + } + config.sd_icon_save ^= SDIS_TRACES; + config_save(); +} + #ifdef __SD_FILE_BROWSER__ #include "vna_browser.c" #endif @@ -5331,6 +5357,19 @@ static const menuitem_t menu_stimulus[] = { }; #ifdef __USE_SD_CARD__ +static const menuitem_t menu_storage_sd_icon[] = { + { MT_ADV_CALLBACK, 0, "SAVE\nCAPTURE", menu_sd_icon_save_capture_acb }, + { MT_ADV_CALLBACK, 0, "SAVE\nTRACES", menu_sd_icon_save_traces_acb }, + { MT_NONE, 0, NULL, menu_back } +}; + +static const menuitem_t menu_storage_config[] = { + { MT_ADV_CALLBACK, 0, "AUTO NAME", menu_autoname_acb }, + { MT_ADV_CALLBACK, 0, "MHz\nCSV", menu_mhz_csv_acb }, + { MT_SUBMENU, 0, "SD CARD\nICON", menu_storage_sd_icon }, + { MT_NONE, 0, NULL, menu_back } +}; + static const menuitem_t menu_storage[] = { #ifdef __SD_FILE_BROWSER__ { MT_CALLBACK, FMT_BMP_FILE, "LOAD\nCAPTURE", menu_sdcard_browse_cb }, @@ -5338,12 +5377,11 @@ static const menuitem_t menu_storage[] = { { MT_CALLBACK, FMT_CMD_FILE, "LOAD\nCMD", menu_sdcard_browse_cb }, { MT_CALLBACK, FMT_CFG_FILE, "LOAD\nCONFIG", menu_sdcard_browse_cb }, #endif - { MT_ADV_CALLBACK, 0, "AUTO NAME", menu_autoname_acb }, { MT_CALLBACK, FMT_BMP_FILE, "SAVE\nCAPTURE", menu_sdcard_cb}, { MT_CALLBACK, FMT_PRS_FILE, "SAVE\nSETTINGS", menu_sdcard_cb}, { MT_CALLBACK, FMT_CFG_FILE, "SAVE\nCONFIG", menu_sdcard_cb}, - { MT_ADV_CALLBACK, 0, "MHz\nCSV", menu_mhz_csv_acb }, { MT_CALLBACK, FMT_CSV_FILE, "SAVE\nTRACES", menu_save_traces_cb}, + { MT_SUBMENU, 0, "CONFIG", menu_storage_config }, // { MT_KEYPAD, KM_INTERVAL, "INTERVAL\n\b%s", NULL }, { MT_NONE, 0, NULL, menu_back} // next-> menu_back }; @@ -8073,7 +8111,10 @@ made_screenshot(int touch_x, int touch_y) { ili9341_set_background(LCD_BG_COLOR); ili9341_fill(4, SD_CARD_START, 16, 16); touch_wait_release(); - menu_sdcard_cb(0, FMT_BMP_FILE); + if (config.sd_icon_save & SDIS_CAPTURE) + menu_sdcard_cb(0, FMT_BMP_FILE); + if (config.sd_icon_save & SDIS_TRACES) + menu_save_traces_cb(0, 0); return TRUE; } #endif @@ -8193,7 +8234,7 @@ void ui_process_touch(void) switch (ui_mode) { case UI_NORMAL: #ifdef __USE_SD_CARD__ - if (made_screenshot(touch_x, touch_y)) + if (SDIS_IS_ENABLED && made_screenshot(touch_x, touch_y)) break; #endif if (touch_quick_menu(touch_x, touch_y))