diff --git a/main.c b/main.c index c6c5a96..40848a1 100644 --- a/main.c +++ b/main.c @@ -81,6 +81,7 @@ static int32_t frequency_offset = 5000; static uint32_t frequency = 10000000; static int8_t drive_strength = DRIVE_STRENGTH_AUTO; int8_t sweep_mode = SWEEP_ENABLE; +int8_t frequency_step_mode = FREQUENCY_STEP_LINEAR; volatile uint8_t redraw_request = 0; // contains REDRAW_XXX flags // Version text, displayed in Config->Version menu, also send by info command @@ -153,6 +154,9 @@ resume_sweep(void) sweep_mode|=SWEEP_ENABLE; } +void toggle_frequency_step_mode(void) { + frequency_step_mode ^= (FREQUENCY_STEP_LOGARITHMIC ^ FREQUENCY_STEP_LINEAR); +} void toggle_sweep(void) { @@ -611,6 +615,17 @@ static const I2SConfig i2sconfig = { 2 // i2spr }; +VNA_SHELL_FUNCTION(cmd_step_mode) { + if (argc == 0) + shell_printf("%s\r\n",(frequency_step_mode & FREQUENCY_STEP_LOGARITHMIC) ? "log" : "linear"); + else if ((argc == 1) && (0 == strcmp(argv[0],"log"))) + frequency_step_mode = FREQUENCY_STEP_LOGARITHMIC; + else if ((argc == 1) && (0 == strcmp(argv[0],"linear"))) + frequency_step_mode = FREQUENCY_STEP_LINEAR; + else + shell_printf("usage: step_mode [linear|log]\r\n"); +} + VNA_SHELL_FUNCTION(cmd_data) { int i; @@ -625,8 +640,10 @@ VNA_SHELL_FUNCTION(cmd_data) array = cal_data[sel-2]; else goto usage; - for (i = 0; i < sweep_points; i++) - shell_printf("%f %f\r\n", array[i][0], array[i][1]); + for (i = 0; i < sweep_points; i++) { + if (frequencies[i] != 0) + shell_printf("%f %f\r\n", array[i][0], array[i][1]); + } return; usage: shell_printf("usage: data [array]\r\n"); @@ -826,8 +843,8 @@ VNA_SHELL_FUNCTION(cmd_scan) uint32_t start, stop; int16_t points = sweep_points; - if (argc != 2 && argc != 3) { - shell_printf("usage: scan {start(Hz)} {stop(Hz)} [points]\r\n"); + if (argc != 2 && argc != 3 && argc != 4) { + shell_printf("usage: scan {start(Hz)} {stop(Hz)} [points [log|lin]]\r\n"); return; } @@ -888,7 +905,7 @@ update_marker_index(void) } void -set_frequencies(uint32_t start, uint32_t stop, uint16_t points) +set_lin_frequencies(uint32_t start, uint32_t stop, uint16_t points) { uint32_t i; uint32_t step = (points - 1); @@ -909,6 +926,32 @@ set_frequencies(uint32_t start, uint32_t stop, uint16_t points) frequencies[i] = 0; } +void +set_log_frequencies(uint32_t start, uint32_t stop, uint16_t points) +{ + uint16_t steps = points-1; + float logStart = logf((float)start); + float logStop = logf((float)stop); + float inc = (logStop-logStart)/((float)(steps)); + uint32_t i; + for (i = 0; i <= steps; i++) { + uint32_t f = (uint32_t)(exp((double)(logStart+inc*i))+.5); + frequencies[i] = f; + } + frequencies[steps] = stop; + // disable at out of sweep range + for (; i < sweep_points; i++) + frequencies[i] = 0; +} + +void +set_frequencies(uint32_t start, uint32_t stop, uint16_t points) { + if (frequency_step_mode & FREQUENCY_STEP_LOGARITHMIC) + set_log_frequencies(start, stop, points); + else + set_lin_frequencies(start, stop, points); +} + void update_frequencies(void) { @@ -2043,6 +2086,7 @@ static const VNAShellCommand commands[] = {"sample" , cmd_sample , 0}, // {"gamma" , cmd_gamma , 0}, {"scan" , cmd_scan , 0}, // Wait mutex hardcoded in cmd, need wait one sweep manually + {"step_mode" , cmd_step_mode , CMD_WAIT_MUTEX}, {"sweep" , cmd_sweep , 0}, {"test" , cmd_test , 0}, {"touchcal" , cmd_touchcal , CMD_WAIT_MUTEX}, diff --git a/nanovna.h b/nanovna.h index d5d14cc..5aa1ad0 100644 --- a/nanovna.h +++ b/nanovna.h @@ -84,11 +84,15 @@ uint32_t get_sweep_frequency(int type); double my_atof(const char *p); void toggle_sweep(void); +void toggle_frequency_step_mode(void); void loadDefaultProps(void); +#define FREQUENCY_STEP_LINEAR 0x00 +#define FREQUENCY_STEP_LOGARITHMIC 0x01 #define SWEEP_ENABLE 0x01 #define SWEEP_ONCE 0x02 extern int8_t sweep_mode; +extern int8_t frequency_step_mode; extern const char *info_about[]; /* diff --git a/ui.c b/ui.c index a2267da..7460ddf 100644 --- a/ui.c +++ b/ui.c @@ -678,6 +678,12 @@ menu_stimulus_cb(int item, uint8_t data) //ui_mode_normal(); draw_menu(); break; + case 6: /* PAUSE */ + toggle_frequency_step_mode(); + //menu_move_back(); + //ui_mode_normal(); + draw_menu(); + break; } } @@ -940,6 +946,7 @@ const menuitem_t menu_stimulus[] = { { MT_CALLBACK, 0, "SPAN", menu_stimulus_cb }, { MT_CALLBACK, 0, "CW FREQ", menu_stimulus_cb }, { MT_CALLBACK, 0, "\2PAUSE\0SWEEP", menu_stimulus_cb }, + { MT_CALLBACK, 0, "\2LINEAR\0LOG", menu_stimulus_cb }, { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; @@ -1113,9 +1120,10 @@ menu_invoke(int item) } } +#define MAX_MENU_SIZE 8 #define MENU_BUTTON_WIDTH 60 -#define MENU_BUTTON_HEIGHT 30 -#define NUM_INPUT_HEIGHT 30 +#define MENU_BUTTON_HEIGHT 25 +#define NUM_INPUT_HEIGHT 25 #define KP_WIDTH 48 #define KP_HEIGHT 48 @@ -1353,6 +1361,10 @@ menu_item_modify_attribute(const menuitem_t *menu, int item, *bg = DEFAULT_MENU_TEXT_COLOR; *fg = config.menu_normal_color; } + if (item == 6 /* LOG */ && (frequency_step_mode & FREQUENCY_STEP_LOGARITHMIC)) { + *bg = DEFAULT_MENU_TEXT_COLOR; + *fg = config.menu_normal_color; + } } else if (menu == menu_cal) { if (item == 3 /* CORRECTION */ && (cal_status & CALSTAT_APPLY)) { *bg = DEFAULT_MENU_TEXT_COLOR; @@ -1382,13 +1394,14 @@ static void draw_menu_buttons(const menuitem_t *menu) { int i = 0; - for (i = 0; i < 7; i++) { + for (i = 0; i < MAX_MENU_SIZE; i++) { const char *l1, *l2; if (menu[i].type == MT_NONE) break; if (menu[i].type == MT_BLANK) continue; int y = MENU_BUTTON_HEIGHT*i; + uint16_t bg = config.menu_normal_color; uint16_t fg = DEFAULT_MENU_TEXT_COLOR; // focus only in MENU mode but not in KEYPAD mode @@ -1400,12 +1413,16 @@ draw_menu_buttons(const menuitem_t *menu) setForegroundColor(fg); setBackgroundColor(bg); if (menu_is_multiline(menu[i].label, &l1, &l2)) { - ili9341_fill(320-MENU_BUTTON_WIDTH+3, y+5, MENU_BUTTON_WIDTH-6, 2+FONT_GET_HEIGHT+1+FONT_GET_HEIGHT+2, bg); - ili9341_drawstring(l1, 320-MENU_BUTTON_WIDTH+5, y+7); - ili9341_drawstring(l2, 320-MENU_BUTTON_WIDTH+5, y+7+FONT_GET_HEIGHT+1); + int fillHeight = 2+FONT_GET_HEIGHT+1+FONT_GET_HEIGHT+2; + int fillOffset = (MENU_BUTTON_HEIGHT-fillHeight)/2; + ili9341_fill(320-MENU_BUTTON_WIDTH+3, y+fillOffset, MENU_BUTTON_WIDTH-6, fillHeight, bg); + ili9341_drawstring(l1, 320-MENU_BUTTON_WIDTH+5, y+fillOffset+2); + ili9341_drawstring(l2, 320-MENU_BUTTON_WIDTH+5, y+fillOffset+2+FONT_GET_HEIGHT+1); } else { - ili9341_fill(320-MENU_BUTTON_WIDTH+3, y+8, MENU_BUTTON_WIDTH-6, 2+FONT_GET_HEIGHT+2, bg); - ili9341_drawstring(menu[i].label, 320-MENU_BUTTON_WIDTH+5, y+10); + int fillHeight = 2+FONT_GET_HEIGHT+2; + int fillOffset = (MENU_BUTTON_HEIGHT-fillHeight)/2; + ili9341_fill(320-MENU_BUTTON_WIDTH+3, y+fillOffset, MENU_BUTTON_WIDTH-6, fillHeight, bg); + ili9341_drawstring(menu[i].label, 320-MENU_BUTTON_WIDTH+5, y+fillOffset+2); } } } @@ -1428,7 +1445,7 @@ menu_apply_touch(void) int i; touch_position(&touch_x, &touch_y); - for (i = 0; i < 7; i++) { + for (i = 0; i < MAX_MENU_SIZE; i++) { if (menu[i].type == MT_NONE) break; if (menu[i].type == MT_BLANK) @@ -1453,7 +1470,7 @@ draw_menu(void) static void erase_menu_buttons(void) { - ili9341_fill(320-MENU_BUTTON_WIDTH, 0, MENU_BUTTON_WIDTH, MENU_BUTTON_HEIGHT*7, DEFAULT_BG_COLOR); + ili9341_fill(320-MENU_BUTTON_WIDTH, 0, MENU_BUTTON_WIDTH, MENU_BUTTON_HEIGHT*MAX_MENU_SIZE, DEFAULT_BG_COLOR); } static void