diff --git a/nanovna.h b/nanovna.h index d634b4a..5de000c 100644 --- a/nanovna.h +++ b/nanovna.h @@ -75,7 +75,7 @@ #define MARKER_COUNT 4 #define TRACES_MAX 3 -#define TRACE_AGE 3 +//#define TRACE_AGE 3 #define TRACE_ACTUAL 2 #define TRACE_STORED 1 #define TRACE_TEMP 0 @@ -216,6 +216,7 @@ void toggle_below_IF(void); int get_refer_output(void); void set_attenuation(float); float get_attenuation(void); +float get_level(void); void set_harmonic(int); //extern int setting.harmonic; int search_is_greater(void); diff --git a/sa_core.c b/sa_core.c index 4550762..ef6b218 100644 --- a/sa_core.c +++ b/sa_core.c @@ -115,7 +115,8 @@ void reset_settings(int m) setting.measurement = M_OFF; setting.frequency_IF = DEFAULT_IF; setting.auto_IF = true; - setting.offset = 0.0; + set_offset(0.0); // This also updates the help text!!!!! + //setting.offset = 0.0; setting.trigger = T_AUTO; setting.trigger_direction = T_UP; setting.trigger_mode = T_MID; @@ -480,7 +481,7 @@ void set_level(float v) // Set the output level in dB in high/low output { if (setting.mode == M_GENHIGH) { int d = 0; - while (drive_dBm[d] < v - 1 && d < 16) + while (drive_dBm[d] < v - 1 && d < 15) // Do not exceed array size d++; if (d == 8 && v < -12) // Round towards closest level d = 7; @@ -492,6 +493,14 @@ void set_level(float v) // Set the output level in dB in high/low output dirty = true; } +float get_level(void) +{ + if (setting.mode == M_GENHIGH) { + return drive_dBm[setting.lo_drive]; + } else { + return get_attenuation(); + } +} void set_attenuation(float a) // Is used both in low output mode and high/low input mode { if (setting.mode == M_GENLOW) { @@ -914,7 +923,13 @@ extern char low_level_help_text[12]; void set_offset(float offset) { setting.offset = offset; - plot_printf(low_level_help_text, sizeof low_level_help_text, "%+d..%+d", -76 + (int)offset, -6 + (int)offset); + int min,max; + if (setting.mode == M_GENLOW) { + min = -76; max = -6; + } else { + min = -38; max = +13; + } + plot_printf(low_level_help_text, sizeof low_level_help_text, "%+d..%+d", min + (int)offset, max + (int)offset); force_set_markmap(); dirty = true; // No HW update required, only status panel refresh but need to ensure the cached value is updated in the calculation of the RSSI } diff --git a/ui.c b/ui.c index 7a864e0..54455d1 100644 --- a/ui.c +++ b/ui.c @@ -90,7 +90,6 @@ static int selection = 0; static const uint8_t slider_bitmap[]= { - _BMP8(0b11111110), _BMP8(0b11111110), _BMP8(0b11111110), _BMP8(0b01111100), @@ -1756,6 +1755,7 @@ static const uint8_t check_box[] = { _BMP16(0b0000100001000000), _BMP16(0b0000011110000000), }; +static const char *step_text[5] = {"-10dB", "-1dB", "set", "+1dB", "+10dB"}; static void draw_menu_buttons(const menuitem_t *menu) @@ -1820,7 +1820,7 @@ draw_menu_buttons(const menuitem_t *menu) text_offs = button_start+6+ICON_WIDTH+1; } // ili9341_drawstring_size(button.text, text_offs, y+(button_height-2*FONT_GET_HEIGHT)/2, 2); - ili9341_drawstring_10x14(button.text, text_offs, y+(button_height-wFONT_GET_HEIGHT)/2); + ili9341_drawstring_10x14(button.text, text_offs, y+(button_height-wFONT_GET_HEIGHT)/2 - 2); #ifdef __ICONS__ if (menu[i].type & MT_ICON) { blit8BitWidthBitmap(button_start+MENU_FORM_WIDTH-2*FORM_ICON_WIDTH-8,y+(button_height-FORM_ICON_HEIGHT)/2,FORM_ICON_WIDTH,FORM_ICON_HEIGHT,& left_icons[((menu[i].data >>4)&0xf)*2*FORM_ICON_HEIGHT]); @@ -1831,17 +1831,26 @@ draw_menu_buttons(const menuitem_t *menu) if (MT_MASK(menu[i].type) == MT_KEYPAD) { if (menu[i].data == KM_CENTER) { local_slider_positions = LCD_WIDTH/2+setting.slider_position; - goto draw_slider; + draw_slider: + blit8BitWidthBitmap(local_slider_positions - 4, y, 7, 5, slider_bitmap); } else if (menu[i].data == KM_LOWOUTLEVEL) { local_slider_positions = ((get_attenuation() + 76 ) * (MENU_FORM_WIDTH-8)) / 70 + OFFSETX+4; + for (int i=0; i <= 4; i++) + ili9341_drawstring(step_text[i], button_start+12 + i * MENU_FORM_WIDTH/5, y+button_height-9); + for (int i = 1; i <= 4; i++) + ili9341_line(button_start + i * MENU_FORM_WIDTH/5, y+button_height-9, button_start + i * MENU_FORM_WIDTH/5, y+button_height); + goto draw_slider; + } else if (menu[i].data == KM_HIGHOUTLEVEL) { + local_slider_positions = ((menu_drive_value[setting.lo_drive] + 38 ) * (MENU_FORM_WIDTH-8)) / 51 + OFFSETX+4; goto draw_slider; } } +#if 0 if (MT_MASK(menu[i].type) == MT_ADV_CALLBACK && menu[i].reference == menu_sdrive_acb) { local_slider_positions = ((menu_drive_value[setting.lo_drive] + 38 ) * (MENU_FORM_WIDTH-8)) / 51 + OFFSETX+4; - draw_slider: - blit8BitWidthBitmap(local_slider_positions - 4, y, 7, 6, slider_bitmap); + goto draw_slider; } +#endif } else { int button_width = MENU_BUTTON_WIDTH; int button_start = LCD_WIDTH - MENU_BUTTON_WIDTH; @@ -1897,12 +1906,15 @@ void check_frequency_slider(uint32_t slider_freq) } static void -menu_select_touch(int i) +menu_select_touch(int i, int pos) { + int step = 0; + int do_exit = false; selection = i; draw_menu(); #if 1 // drag values const menuitem_t *menu = menu_stack[menu_current_level]; + int old_keypad_mode = keypad_mode; int keypad = menu[i].data; prev_touch_time = chVTGetSystemTimeX(); @@ -1918,7 +1930,6 @@ menu_select_touch(int i) if (dt > BUTTON_DOWN_LONG_TICKS) { touch_position(&touch_x, &touch_y); if (touch_x != prev_touch_x /* - 1 || prev_touch_x + 1 < touch_x */ ) { - int old_keypad_mode = keypad_mode; keypad_mode = keypad; fetch_numeric_target(); int new_slider = touch_x - LCD_WIDTH/2; @@ -1997,12 +2008,14 @@ menu_select_touch(int i) } } else if (menu_is_form(menu) && MT_MASK(menu[i].type) == MT_KEYPAD && keypad == KM_LOWOUTLEVEL) { uistat.value = setting.offset + (touch_x - OFFSETX+4) *( -6 - -76) / (MENU_FORM_WIDTH-8) + -76; + apply_step: set_keypad_value(keypad); apply: perform(false, 0, get_sweep_frequency(ST_CENTER), false); draw_menu(); // } - } else if (MT_MASK(menu[i].type) == MT_ADV_CALLBACK && menu[i].reference == menu_sdrive_acb) { +// } else if (MT_MASK(menu[i].type) == MT_ADV_CALLBACK && menu[i].reference == menu_sdrive_acb) { + } else if (menu_is_form(menu) && MT_MASK(menu[i].type) == MT_KEYPAD && keypad == KM_HIGHOUTLEVEL) { set_level( (touch_x - OFFSETX+4) *( 13 - -38) / (MENU_FORM_WIDTH-8) + -38 ); goto apply; } @@ -2011,11 +2024,33 @@ menu_select_touch(int i) } prev_touch_x = touch_x; } - if (dt > BUTTON_DOWN_LONG_TICKS) { + if (dt > BUTTON_DOWN_LONG_TICKS || do_exit) { selection = -1; draw_menu(); return; } + if (menu_is_form(menu) && MT_MASK(menu[i].type) == MT_KEYPAD && keypad == KM_LOWOUTLEVEL) { + switch (pos) { + case 0: + step = -10; + break; + case 1: + step = -1; + break; + case 2: + goto nogo; + case 3: + step = +1; + break; + case 4: + step = +10; + break; + } + uistat.value = get_level() + step; + do_exit = true; + goto apply_step; + } +nogo: setting.slider_position = 0; // Reset slider when entering frequency prev_touch_button = -1; #endif @@ -2054,7 +2089,7 @@ menu_apply_touch(void) } if (y < touch_y && touch_y < y+MENU_BUTTON_HEIGHT) { if (touch_x > active_button_start) { - menu_select_touch(i); + menu_select_touch(i, (( touch_x - active_button_start) * 5 ) / MENU_FORM_WIDTH); return; } } diff --git a/ui_sa.c b/ui_sa.c index cd5ddc5..269b722 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -406,7 +406,7 @@ enum { KM_REFLEVEL, KM_SCALE, KM_ATTENUATION, KM_ACTUALPOWER, KM_IF, KM_SAMPLETIME, KM_DRIVE, KM_LOWOUTLEVEL, KM_DECAY, KM_NOISE, KM_10MHZ, KM_REPEAT, KM_OFFSET, KM_TRIGGER, KM_LEVELSWEEP, KM_SWEEP_TIME, KM_OFFSET_DELAY, - KM_FAST_SPEEDUP, KM_GRIDLINES, KM_MARKER, KM_MODULATION, + KM_FAST_SPEEDUP, KM_GRIDLINES, KM_MARKER, KM_MODULATION, KM_HIGHOUTLEVEL, #if 0 KM_COR_AM,KM_COR_WFM, KM_COR_NFM, #endif @@ -444,6 +444,7 @@ static const struct { {keypads_positive , "MINIMUM\nGRIDLINES"}, // KM_GRIDLINES {keypads_freq , "MARKER\nFREQ"}, // KM_MARKER {keypads_freq , "MODULATION\nFREQ"}, // KM_MODULATION + {keypads_plusmin , "LEVEL"}, // KM_HIGHOUTLEVEL #if 0 {keypads_plusmin , "COR\nAM"}, // KM_COR_AM {keypads_plusmin , "COR\nWFM"}, // KM_COR_WFM @@ -458,6 +459,7 @@ ui_slider_t ui_sliders [] = { KM_CENTER, true, 0, 1000000, 0, 350000000, M_GENLOW}, { KM_CENTER, true, 0, 1000000, 240000000, 960000000, M_GENHIGH}, { KM_LOWOUTLEVEL, false,0, 1, -76, -6, M_GENLOW}, + { KM_HIGHOUTLEVEL, false,0, 1, -38, +6, M_GENHIGH}, }; #endif @@ -747,6 +749,7 @@ static UI_FUNCTION_ADV_CALLBACK(menu_lo_drive_acb) // draw_cal_status(); } +#if 0 static UI_FUNCTION_ADV_CALLBACK(menu_sdrive_acb){ (void)item; (void)data; @@ -756,6 +759,7 @@ static UI_FUNCTION_ADV_CALLBACK(menu_sdrive_acb){ } menu_push_submenu(menu_drive_wide); } +#endif #ifdef __SPUR__ static UI_FUNCTION_ADV_CALLBACK(menu_spur_acb) @@ -1438,6 +1442,7 @@ static const menuitem_t menu_lo_drive[] = { { MT_NONE, 0, NULL, NULL } // sentinel }; +#if 0 static const menuitem_t menu_drive_wide3[] = { { MT_FORM | MT_ADV_CALLBACK, 5, "%+ddBm", menu_lo_drive_acb}, { MT_FORM | MT_ADV_CALLBACK, 4, "%+ddBm", menu_lo_drive_acb}, @@ -1470,6 +1475,7 @@ static const menuitem_t menu_drive_wide[] = { { MT_FORM | MT_CANCEL, 255, S_LARROW" BACK", NULL }, { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; +#endif static const menuitem_t menu_modulation[] = { { MT_FORM | MT_TITLE, 0, "MODULATION",NULL}, @@ -1511,7 +1517,8 @@ static const menuitem_t menu_lowoutputmode[] = { static const menuitem_t menu_highoutputmode[] = { { MT_FORM | MT_ADV_CALLBACK, 0, "HIGH OUTPUT %s", menu_outputmode_acb}, { MT_FORM | MT_KEYPAD, KM_CENTER, center_text, "240MHz..960MHz"}, - { MT_FORM | MT_ADV_CALLBACK, 0, "LEVEL: %+ddBm", menu_sdrive_acb}, +// { MT_FORM | MT_ADV_CALLBACK, 0, "LEVEL: %+ddBm", menu_sdrive_acb}, + { MT_FORM | MT_KEYPAD, KM_HIGHOUTLEVEL, "LEVEL: %s", low_level_help_text /* "-76..-6" */}, { MT_FORM | MT_ADV_CALLBACK, 0, "MOD: %s", menu_smodulation_acb}, { MT_FORM | MT_KEYPAD, KM_SPAN, "SPAN: %s", NULL}, { MT_FORM | MT_KEYPAD, KM_SWEEP_TIME,"SWEEP TIME: %s", "0..600 seconds"}, @@ -2089,7 +2096,7 @@ static void fetch_numeric_target(void) plot_printf(uistat.text, sizeof uistat.text, "%3ddB", ((int32_t)uistat.value)); break; case KM_LOWOUTLEVEL: - uistat.value = get_attenuation(); // compensation for dB offset during low output mode + uistat.value = get_level(); // compensation for dB offset during low output mode int end_level = ((int32_t)uistat.value)+setting.level_sweep; if (end_level < -76) end_level = -76; @@ -2102,6 +2109,11 @@ static void fetch_numeric_target(void) else plot_printf(uistat.text, sizeof uistat.text, "%ddBm", ((int32_t)uistat.value)); break; + case KM_HIGHOUTLEVEL: + uistat.value = get_level(); // compensation for dB offset during low output mode + uistat.value += setting.offset; + plot_printf(uistat.text, sizeof uistat.text, "%ddBm", ((int32_t)uistat.value)); + break; case KM_DECAY: uistat.value = setting.decay; plot_printf(uistat.text, sizeof uistat.text, "%5d", ((int32_t)uistat.value)); @@ -2221,6 +2233,9 @@ set_numeric_value(void) case KM_LOWOUTLEVEL: set_level(uistat.value - setting.offset); break; + case KM_HIGHOUTLEVEL: + set_level(uistat.value - setting.offset); + break; case KM_DECAY: set_decay(uistat.value); break;