From b8c04980a9ba99f15d39f4036fe3cd9c8db7b3a2 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Sun, 6 Dec 2020 14:25:49 +0100 Subject: [PATCH 1/3] Added attack and decay --- Font10x14.c | 3 ++- ili9341.c | 4 ++++ main.c | 2 ++ nanovna.h | 14 ++++++++++++-- plot.c | 7 +++++-- sa_core.c | 54 ++++++++++++++++++++++++++++++++++++++++++++--------- ui_sa.c | 31 ++++++++++++++++++++++++++---- 7 files changed, 97 insertions(+), 18 deletions(-) diff --git a/Font10x14.c b/Font10x14.c index ee8cce3..bb0d3e1 100644 --- a/Font10x14.c +++ b/Font10x14.c @@ -23,7 +23,7 @@ #include #include "nanovna.h" - +#ifdef wFONT_GET_WIDTH /* * Check 1 byte of bitmap data for get width */ @@ -1714,3 +1714,4 @@ const uint8_t x10x14_bits[(127-wFONT_START_CHAR)*wFONT_GET_HEIGHT*2] = _BMP16(0b0000000000000000), // | | _BMP16(0b0000000000000000), // | | }; +#endif diff --git a/ili9341.c b/ili9341.c index d981ac0..7b9e3fe 100644 --- a/ili9341.c +++ b/ili9341.c @@ -643,6 +643,7 @@ void ili9341_drawstring_7x13(const char *str, int x, int y) void ili9341_drawstring_10x14(const char *str, int x, int y) { +#ifdef wFONT_GET_DATA int x_pos = x; while (*str) { uint8_t ch = *str++; @@ -654,6 +655,9 @@ void ili9341_drawstring_10x14(const char *str, int x, int y) x += w; } bit_align = 0; +#else + ili9341_drawstring_size(str, x, y, 2); +#endif } void ili9341_drawstringV(const char *str, int x, int y) diff --git a/main.c b/main.c index 36c6d47..f5ff03a 100644 --- a/main.c +++ b/main.c @@ -83,7 +83,9 @@ static volatile vna_shellcmd_t shell_function = 0; #define ENABLE_INFO_COMMAND // Enable color command, allow change config color for traces, grid, menu #define ENABLE_COLOR_COMMAND +#ifdef __USE_SERIAL_CONSOLE__ #define ENABLE_USART_COMMAND +#endif #ifdef __VNA__ static void apply_error_term_at(int i); static void apply_edelay_at(int i); diff --git a/nanovna.h b/nanovna.h index 184317b..41a4226 100644 --- a/nanovna.h +++ b/nanovna.h @@ -42,6 +42,7 @@ #define __SCROLL__ #define __ICONS__ #define __MEASURE__ +//#define __LINEARITY__ // Not available #define __SELFTEST__ #define __CALIBRATE__ #define __FAST_SWEEP__ // Pre-fill SI4432 RSSI buffer to get fastest sweep in zero span mode @@ -49,6 +50,9 @@ //#define __ULTRA__ // Add harmonics mode on low input. #define __SPUR__ // Does spur reduction by shifting IF //#define __USE_SERIAL_CONSOLE__ // Enable serial I/O connection (need enable HAL_USE_SERIAL as TRUE in halconf.h) + +#define __QUASI_PEAK__ + #ifdef TINYSA3 #define DEFAULT_IF 433800000 #define DEFAULT_SPUR_IF 434000000 @@ -162,7 +166,7 @@ void toggle_mute(void); void load_default_properties(void); enum { - AV_OFF, AV_MIN, AV_MAX_HOLD, AV_MAX_DECAY, AV_4, AV_16 + AV_OFF, AV_MIN, AV_MAX_HOLD, AV_MAX_DECAY, AV_4, AV_16, AV_QUASI }; enum { M_LOW, M_HIGH, M_GENLOW, M_GENHIGH, M_ULTRA @@ -253,6 +257,7 @@ void toggle_AGC(void); void redrawHisto(void); void self_test(int); void set_decay(int); +void set_attack(int); void set_noise(int); void toggle_tracking_output(void); extern int32_t frequencyExtra; @@ -390,16 +395,20 @@ extern const uint8_t numfont16x22[]; #define bFONT_WIDTH 7 #define bFONT_GET_HEIGHT 11 #define bFONT_STR_HEIGHT 11 - #define bFONT_GET_DATA(ch) ( &x7x11b_bits[(ch-bFONT_START_CHAR)*bFONT_GET_HEIGHT]) #define bFONT_GET_WIDTH(ch) (8-(x7x11b_bits[(ch-bFONT_START_CHAR)*bFONT_GET_HEIGHT]&7)) +#if 1 // Set to 0 to save 3kByte #define wFONT_START_CHAR 0x17 #define wFONT_MAX_WIDTH 12 #define wFONT_GET_HEIGHT 14 #define wFONT_STR_HEIGHT 16 #define wFONT_GET_DATA(ch) ( &x10x14_bits[(ch-wFONT_START_CHAR)*2*wFONT_GET_HEIGHT ]) #define wFONT_GET_WIDTH(ch) (14-(x10x14_bits[(ch-wFONT_START_CHAR)*2*wFONT_GET_HEIGHT+1]&0x7)) +#else +#define wFONT_MAX_WIDTH 12 +#define wFONT_GET_HEIGHT 14 +#endif #define NUM_FONT_GET_WIDTH 16 #define NUM_FONT_GET_HEIGHT 22 @@ -749,6 +758,7 @@ typedef struct setting int test; int harmonic; int decay; + int attack; int noise; uint32_t vbw_x10; int tracking_output; diff --git a/plot.c b/plot.c index 3b412a1..dcde65e 100644 --- a/plot.c +++ b/plot.c @@ -1852,7 +1852,6 @@ cell_drawstring(char *str, int x, int y) x += w; } } - void cell_drawstring_7x13(char *str, int x, int y) { @@ -1871,6 +1870,7 @@ cell_drawstring_7x13(char *str, int x, int y) void cell_drawstring_10x14(char *str, int x, int y) { +#ifdef wFONT_GET_DATA if (y <= -wFONT_GET_HEIGHT || y >= CELLHEIGHT) return; while (*str) { @@ -1881,9 +1881,12 @@ cell_drawstring_10x14(char *str, int x, int y) cell_blit_bitmap(x, y, w <=8 ? 9 : w, wFONT_GET_HEIGHT, wFONT_GET_DATA(ch)); x+=w; } +#else + cell_drawstring_size(str, x, y, 2); +#endif } -#if 0 +#ifndef wFONT_GET_DATA static int cell_drawchar_size(uint8_t ch, int x, int y, int size) { diff --git a/sa_core.c b/sa_core.c index 9f9ead6..f7e6f62 100644 --- a/sa_core.c +++ b/sa_core.c @@ -122,6 +122,7 @@ void reset_settings(int m) setting.vbw_x10 = 0; setting.auto_reflevel = true; // Must be after SetReflevel setting.decay=20; + setting.attack=1; setting.noise=5; setting.below_IF = S_AUTO_OFF; setting.repeat = 1; @@ -226,12 +227,28 @@ void set_refer_output(int v) void set_decay(int d) { - if (d < 0 || d > 200) + if (d < 0 || d > 1000000) return; + if (setting.frequency_step == 0) { // decay in ms + d = (float)d * 500.0 * (float)sweep_points / (float)setting.actual_sweep_time_us; + } setting.decay = d; dirty = true; } +#ifdef __QUASI_PEAK__ +void set_attack(int d) +{ + if (d < 0 || d > 20000) + return; + if (setting.frequency_step == 0 && d>0) { // decay in ms + d = (float)d * 500.0 * (float)sweep_points / (float)setting.actual_sweep_time_us; + } + setting.attack = d; + dirty = true; +} +#endif + void set_noise(int d) { if (d < 2 || d > 50) @@ -262,10 +279,10 @@ void set_10mhz(uint32_t f) update_grid(); } - void set_measurement(int m) { setting.measurement = m; +#ifdef __LINEARITY__ if (m == M_LINEARITY) { trace[TRACE_STORED].enabled = true; for (int j = 0; j < setting._sweep_points; j++) @@ -274,8 +291,10 @@ void set_measurement(int m) setting.attenuate = 29.0; setting.auto_attenuation = false; } +#endif dirty = true; } + void set_drive(int d) { setting.drive = d; @@ -669,7 +688,11 @@ void set_offset_delay(int d) // override RSSI measurement delay void set_average(int v) { setting.average = v; - trace[TRACE_TEMP].enabled = (v != 0); + trace[TRACE_TEMP].enabled = ((v != 0) +#ifdef __QUASI_PEAK__ + && (v != AV_QUASI) +#endif + ); //dirty = true; // No HW update required, only status panel refresh } @@ -2082,16 +2105,16 @@ sweep_again: // stay in sweep loop when output mo } #endif if (scandirty || setting.average == AV_OFF) { // Level calculations - actual_t[i] = RSSI; age[i] = 0; + actual_t[i] = RSSI; } else { switch(setting.average) { case AV_MIN: if (actual_t[i] > RSSI) actual_t[i] = RSSI; break; case AV_MAX_HOLD: if (actual_t[i] < RSSI) actual_t[i] = RSSI; break; case AV_MAX_DECAY: if (actual_t[i] < RSSI) { - actual_t[i] = RSSI; age[i] = 0; + actual_t[i] = RSSI; } else { if (age[i] > setting.decay) actual_t[i] -= 0.5; @@ -2101,6 +2124,20 @@ sweep_again: // stay in sweep loop when output mo break; case AV_4: actual_t[i] = (actual_t[i]*3 + RSSI) / 4.0; break; case AV_16: actual_t[i] = (actual_t[i]*15 + RSSI) / 16.0; break; +#ifdef __QUASI_PEAK__ + case AV_QUASI: + { static float old_RSSI = -150.0; + if (i == 0) old_RSSI = actual_t[sweep_points-1]; + if (RSSI > old_RSSI && setting.attack > 1) + old_RSSI += (RSSI - old_RSSI)/setting.attack; + else if (RSSI < old_RSSI && setting.decay > 1) + old_RSSI += (RSSI - old_RSSI)/setting.decay; + else + old_RSSI = RSSI; + actual_t[i] = old_RSSI; + } + break; +#endif } } @@ -2554,16 +2591,15 @@ sweep_again: // stay in sweep loop when output mo #endif +#ifdef __LINEARITY__ //---------------- in Linearity measurement the attenuation has to be adapted ------------------ - - if (setting.measurement == M_LINEARITY && setting.linearity_step < sweep_points) { setting.attenuate = 29.0 - setting.linearity_step * 30.0 / (sweep_points); dirty = true; stored_t[setting.linearity_step] = peakLevel; setting.linearity_step++; } - +#endif // redraw_marker(peak_marker, FALSE); // STOP_PROFILE; #ifdef TINYSA3 @@ -2716,7 +2752,7 @@ marker_search_right_min(int from) // -------------------------- CAL STATUS --------------------------------------------- -const char * const averageText[] = { "OFF", "MIN", "MAX", "MAXD", " A 4", "A 16"}; +const char * const averageText[] = { "OFF", "MIN", "MAX", "MAXD", " A 4", "A 16","QUASI"}; const char * const dBText[] = { "1dB/", "2dB/", "5dB/", "10dB/", "20dB/"}; const int refMHz[] = { 30, 15, 10, 4, 3, 2, 1 }; diff --git a/ui_sa.c b/ui_sa.c index a316390..35c2ba0 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -408,6 +408,7 @@ enum { 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_COR_AM,KM_COR_WFM, KM_COR_NFM, + KM_ATTACK, KM_NONE // always at enum end }; @@ -428,7 +429,7 @@ static const struct { {keypads_positive , "SAMPLE\nDELAY"}, // sample delay {keypads_positive , "DRIVE"}, // drive {keypads_plusmin , "LEVEL"}, // KM_LOWOUTLEVEL - {keypads_positive , "SCANS"}, // KM_DECAY + {keypads_positive , "DECAY"}, // KM_DECAY {keypads_positive , "NOISE\nLEVEL"}, // KM_NOISE {keypads_freq , "FREQ"}, // KM_10MHz {keypads_positive , "SAMPLE\nREPEAT"}, // KM_REPEA @@ -444,6 +445,8 @@ static const struct { {keypads_plusmin , "COR\nAM"}, // KM_COR_AM {keypads_plusmin , "COR\nWFM"}, // KM_COR_WFM {keypads_plusmin , "COR\nNFM"}, // KM_COR_NFM + {keypads_positive , "ATTACK"}, // KM_ATTACK + }; // ===[MENU CALLBACKS]========================================================= @@ -832,7 +835,7 @@ static UI_FUNCTION_ADV_CALLBACK(menu_measure_acb) // SetAverage(4); break; - case M_PASS_BAND: // Stop band measurement + case M_PASS_BAND: // pass band measurement // reset_settings(setting.mode); markers[0].enabled = M_ENABLED; markers[0].mtype = M_REFERENCE | M_TRACKING; @@ -851,9 +854,11 @@ static UI_FUNCTION_ADV_CALLBACK(menu_measure_acb) // SetAverage(4); break; +#ifdef __LINEARITY__ case M_LINEARITY: set_measurement(M_LINEARITY); break; +#endif case M_AM: // AM reset_settings(setting.mode); for (int i = 0; i< 3; i++) { @@ -1457,6 +1462,9 @@ static const menuitem_t menu_average[] = { { MT_ADV_CALLBACK, 3, "MAX\nDECAY", menu_average_acb}, { MT_ADV_CALLBACK, 4, "AVER 4", menu_average_acb}, { MT_ADV_CALLBACK, 5, "AVER 16", menu_average_acb}, +#ifdef __QUASI_PEAK__ + { MT_ADV_CALLBACK, 6, "QUASI\nPEAK", menu_average_acb}, +#endif { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; @@ -1682,8 +1690,12 @@ static const menuitem_t menu_settings2[] = { MT_ADV_CALLBACK, 0, "LNA", menu_settings_lna_acb}, { MT_ADV_CALLBACK | MT_LOW, 0, "BPF", menu_settings_bpf_acb}, { MT_ADV_CALLBACK | MT_LOW, 0, "BELOW IF", menu_settings_below_if_acb}, - { MT_KEYPAD, KM_DECAY, "HOLD\nSWEEPS", "1..1000 sweeps"}, + { MT_KEYPAD, KM_DECAY, "DECAY", "0..1000000ms or sweeps"}, +#ifdef __QUASI_PEAK__ + { MT_KEYPAD, KM_ATTACK, "ATTACK", "0..100000ms"}, +#else { MT_KEYPAD, KM_NOISE, "NOISE\nLEVEL", "2..20 dB"}, +#endif #ifdef __ULTRA__ { MT_SUBMENU,0, "HARMONIC", menu_harmonic}, #endif @@ -2019,8 +2031,14 @@ static void fetch_numeric_target(void) break; case KM_DECAY: uistat.value = setting.decay; - plot_printf(uistat.text, sizeof uistat.text, "%3d", ((int32_t)uistat.value)); + plot_printf(uistat.text, sizeof uistat.text, "%5d", ((int32_t)uistat.value)); break; +#ifdef __QUASI_PEAK__ + case KM_ATTACK: + uistat.value = setting.attack; + plot_printf(uistat.text, sizeof uistat.text, "%5d", ((int32_t)uistat.value)); + break; +#endif case KM_NOISE: uistat.value = setting.noise; plot_printf(uistat.text, sizeof uistat.text, "%3d", ((int32_t)uistat.value)); @@ -2133,6 +2151,11 @@ set_numeric_value(void) case KM_DECAY: set_decay(uistat.value); break; +#ifdef __QUASI_PEAK__ + case KM_ATTACK: + set_attack(uistat.value); + break; +#endif case KM_NOISE: set_noise(uistat.value); break; From 7664702aa91f31ace9980c62e399319e120ebb53 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Sun, 6 Dec 2020 18:40:57 +0100 Subject: [PATCH 2/3] Corrected spur removal bug --- sa_core.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sa_core.c b/sa_core.c index f7e6f62..308d9f8 100644 --- a/sa_core.c +++ b/sa_core.c @@ -1782,7 +1782,11 @@ modulation_again: else { if (setting.spur_removal == -1) // If second spur pass - local_IF = local_IF + 1000000; // apply IF spur shift +#ifdef __SI4432__ + local_IF = local_IF + 500000; // apply IF spur shift +#else + local_IF = local_IF + 1000000; // apply IF spur shift +#endif } } } From be2fb2e466aa7bf64fc01223f47ee5df43c55215 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Mon, 7 Dec 2020 10:22:50 +0100 Subject: [PATCH 3/3] Added quick menu --- nanovna.h | 7 + plot.c | 2 - releaselog.txt | 3 + sa_core.c | 371 +------------------------------------------ ui.c | 20 ++- ui_sa.c | 422 +++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 453 insertions(+), 372 deletions(-) create mode 100644 releaselog.txt diff --git a/nanovna.h b/nanovna.h index 41a4226..e920074 100644 --- a/nanovna.h +++ b/nanovna.h @@ -199,6 +199,12 @@ extern bool completed; extern const char *info_about[]; // ------------------------------- sa_core.c ---------------------------------- + +extern const char * const unit_string[]; +extern uint8_t signal_is_AM; +extern const int reffer_freq[]; + +int level_is_calibrated(void); void reset_settings(int); void update_min_max_freq(void); //void ui_process_touch(void); @@ -951,6 +957,7 @@ void menu_push_highoutput(void); void menu_move_top(void); void draw_menu(void); int check_touched(void); +int invoke_quick_menu(int); // Irq operation process set #define OP_NONE 0x00 diff --git a/plot.c b/plot.c index dcde65e..f3db3f2 100644 --- a/plot.c +++ b/plot.c @@ -902,8 +902,6 @@ trace_get_value_string_delta(int t, char *buf, int len, float array[POINTS_COUNT } #endif -extern const char *unit_string[]; - inline void trace_get_value_string( // Only used at one place int t, char *buf, int len, int i, float coeff[POINTS_COUNT], diff --git a/releaselog.txt b/releaselog.txt new file mode 100644 index 0000000..775b604 --- /dev/null +++ b/releaselog.txt @@ -0,0 +1,3 @@ +v1.1-40-g7664702: +ECHO is off. + \ No newline at end of file diff --git a/sa_core.c b/sa_core.c index 308d9f8..0838a01 100644 --- a/sa_core.c +++ b/sa_core.c @@ -43,7 +43,7 @@ uint32_t minFreq = 0; uint32_t maxFreq = 520000000; //int setting.refer = -1; // Off by default -static const int reffer_freq[] = {30000000, 15000000, 10000000, 4000000, 3000000, 2000000, 1000000}; +const int reffer_freq[] = {30000000, 15000000, 10000000, 4000000, 3000000, 2000000, 1000000}; int in_selftest = false; @@ -1553,7 +1553,7 @@ static pureRSSI_t correct_RSSI; static pureRSSI_t correct_RSSI_freq; systime_t start_of_sweep_timestamp; static systime_t sweep_elapsed = 0; // Time since first start of sweeping, used only for auto attenuate -static uint8_t signal_is_AM = false; +uint8_t signal_is_AM = false; static uint8_t check_for_AM = false; static void calculate_static_correction(void) // Calculate the static part of the RSSI correction @@ -2754,373 +2754,6 @@ marker_search_right_min(int from) - -// -------------------------- CAL STATUS --------------------------------------------- -const char * const averageText[] = { "OFF", "MIN", "MAX", "MAXD", " A 4", "A 16","QUASI"}; -const char * const dBText[] = { "1dB/", "2dB/", "5dB/", "10dB/", "20dB/"}; -const int refMHz[] = { 30, 15, 10, 4, 3, 2, 1 }; - -float my_round(float v) -{ - float m = 1; - int sign = 1; - if (v < 0) { - sign = -1; - v = -v; - } - while (v < 100) { - v = v * 10; - m = m / 10; - } - while (v > 1000) { - v = v / 10; - m = m * 10; - } - v = (int)(v+0.5); - v = v * m; - if (sign == -1) { - v = -v; - } - return v; -} - -const char * const unit_string[] = { "dBm", "dBmV", "dB"S_MICRO"V", "V", "W", "dBc", "dBc", "dBc", "Vc", "Wc" }; // unit + 5 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"}; - - - -void draw_cal_status(void) -{ -#define BLEN 7 - char buf[BLEN+1]; - buf[6]=0; -#define YSTEP 8 - int x = 0; - int y = OFFSETY; - unsigned int color; - int rounding = false; - if (!UNIT_IS_LINEAR(setting.unit)) - rounding = true; - const char * const unit = unit_string[setting.unit]; - ili9341_set_background(LCD_BG_COLOR); - ili9341_fill(0, 0, OFFSETX, CHART_BOTTOM); - if (MODE_OUTPUT(setting.mode)) { // No cal status during output - return; - } - - // if (current_menu_is_form() && !in_selftest) -// return; - - ili9341_set_background(LCD_BG_COLOR); - - float yMax = setting.reflevel; - // Top level - if (rounding) - plot_printf(buf, BLEN, "%+4d", (int)yMax); - else - plot_printf(buf, BLEN, "%+4.3F", (yMax/setting.unit_scale)); - - if (level_is_calibrated()) - color = setting.auto_reflevel ? LCD_FG_COLOR : LCD_BRIGHT_COLOR_GREEN; - else - color = LCD_BRIGHT_COLOR_RED; - ili9341_set_foreground(color); - ili9341_drawstring(buf, x, y); - - // Unit -#if 0 - color = LCD_FG_COLOR; - ili9341_set_foreground(color); - if (setting.auto_reflevel){ - y += YSTEP + YSTEP/2 ; - ili9341_drawstring("AUTO", x, y); - } -#endif - y += YSTEP + YSTEP/2 ; - plot_printf(buf, BLEN, "%s%s",unit_scale_text[setting.unit_scale_index], unit); - ili9341_drawstring(buf, x, y); - - // Scale - color = LCD_FG_COLOR; - ili9341_set_foreground(color); - y += YSTEP + YSTEP/2; -#if 1 - unsigned int i = 0; - while (i < sizeof(scale_value)/sizeof(float)) { - float t = (setting.scale/setting.unit_scale) / scale_value[i];; - if (t > 0.9 && t < 1.1){ - plot_printf(buf, BLEN, "%s%s/",scale_vtext[i],unit_scale_text[setting.unit_scale_index]); - break; - } - i++; - } -#else - plot_printf(buf, BLEN, "%.2F/",setting.scale); -#endif - ili9341_drawstring(buf, x, y); - - if (is_paused()) { - color = LCD_BRIGHT_COLOR_GREEN; - ili9341_set_foreground(color); - y += YSTEP + YSTEP/2 ; - ili9341_drawstring("PAUSED", x, y); - } - if (setting.trigger == T_SINGLE || setting.trigger == T_NORMAL ) { - color = LCD_BRIGHT_COLOR_GREEN; - ili9341_set_foreground(color); - y += YSTEP + YSTEP/2 ; - ili9341_drawstring("ARMED", x, y); - } - - if (signal_is_AM) { - color = LCD_BRIGHT_COLOR_RED; - ili9341_set_foreground(color); - y += YSTEP + YSTEP/2 ; - ili9341_drawstring("AM", x, y); - } - -// if (setting.mode == M_LOW) { - // Attenuation - if (setting.auto_attenuation) - color = LCD_FG_COLOR; - else - color = LCD_BRIGHT_COLOR_GREEN; - ili9341_set_foreground(color); - y += YSTEP + YSTEP/2 ; - ili9341_drawstring("Atten:", x, y); - y += YSTEP; - plot_printf(buf, BLEN, "%.2FdB", get_attenuation()); - ili9341_drawstring(buf, x, y); -// } - - // Average - if (setting.average>0) { - ili9341_set_foreground(LCD_BRIGHT_COLOR_GREEN); - y += YSTEP + YSTEP/2 ; - ili9341_drawstring("Calc:", x, y); - - y += YSTEP; - plot_printf(buf, BLEN, "%s",averageText[setting.average]); - ili9341_drawstring(buf, x, y); - } - // Spur -#ifdef __SPUR__ - if (setting.spur_removal) { - ili9341_set_foreground(LCD_BRIGHT_COLOR_GREEN); - y += YSTEP + YSTEP/2 ; - ili9341_drawstring("Spur:", x, y); - - y += YSTEP; - plot_printf(buf, BLEN, "ON"); - ili9341_drawstring(buf, x, y); - } - if (setting.mirror_masking) { - ili9341_set_foreground(LCD_BRIGHT_COLOR_GREEN); - y += YSTEP + YSTEP/2 ; - ili9341_drawstring("Mask:", x, y); - - y += YSTEP; - plot_printf(buf, BLEN, "ON"); - ili9341_drawstring(buf, x, y); - } -#endif - - if (setting.subtract_stored) { - ili9341_set_foreground(LCD_BRIGHT_COLOR_GREEN); - y += YSTEP + YSTEP/2 ; - ili9341_drawstring("Norm.", x, y); - } - - // RBW - if (setting.rbw_x10) - color = LCD_BRIGHT_COLOR_GREEN; - else - color = LCD_FG_COLOR; - ili9341_set_foreground(color); - - y += YSTEP + YSTEP/2 ; - ili9341_drawstring("RBW:", x, y); - - y += YSTEP; - plot_printf(buf, BLEN, "%.1FkHz", actual_rbw_x10/10.0); - ili9341_drawstring(buf, x, y); - -#if 0 - // VBW - if (setting.frequency_step > 0) { - ili9341_set_foreground(LCD_FG_COLOR); - y += YSTEP + YSTEP/2 ; - ili9341_drawstring("VBW:", x, y); - - y += YSTEP; - plot_printf(buf, BLEN, "%dkHz",(int)setting.vbw_x10/10.0); - buf[6]=0; - ili9341_drawstring(buf, x, y); - } -#endif - // Sweep time - if (setting.step_delay != 0) - color = LCD_BRIGHT_COLOR_GREEN; - else - color = LCD_FG_COLOR; - - ili9341_set_foreground(color); - - y += YSTEP + YSTEP/2 ; - - buf[0] = ' '; - strcpy(&buf[1],"Scan:"); - if (setting.step_delay_mode == SD_PRECISE) - buf[0] = 'P'; - else if (setting.step_delay_mode == SD_FAST) - buf[0] = 'F'; - else - strcpy(&buf[0],"Scan:"); - ili9341_drawstring(buf, x, y); - -#if 0 // Activate for sweep time debugging - y += YSTEP; - plot_printf(buf, BLEN, "%5.3Fs", (float)setting.sweep_time_us/ONE_SECOND_TIME); - ili9341_drawstring(buf, x, y); -#endif - y += YSTEP; - plot_printf(buf, BLEN, "%5.3Fs", (float)setting.actual_sweep_time_us/ONE_SECOND_TIME); - ili9341_drawstring(buf, x, y); -#if 0 // Activate for sweep time debugging - y += YSTEP; - update_rbw(); // To ensure the calc_min_sweep time shown takes the latest delay into account - calculate_step_delay(); - uint32_t t = calc_min_sweep_time_us(); - plot_printf(buf, BLEN, "%5.3Fs", (float)t/ONE_SECOND_TIME); - ili9341_drawstring(buf, x, y); - - y += YSTEP; - plot_printf(buf, BLEN, "%5.3Fs", (float)setting.additional_step_delay_us/ONE_SECOND_TIME); - ili9341_drawstring(buf, x, y); -#endif - - // Cal output - if (setting.refer >= 0) { - ili9341_set_foreground(LCD_BRIGHT_COLOR_GREEN); - y += YSTEP + YSTEP/2 ; - ili9341_drawstring("Ref:", x, y); - - y += YSTEP; - plot_printf(buf, BLEN, "%dMHz",reffer_freq[setting.refer]/1000000); - buf[6]=0; - ili9341_drawstring(buf, x, y); - } - - // Offset - if (setting.offset != 0.0) { - ili9341_set_foreground(LCD_BRIGHT_COLOR_GREEN); - y += YSTEP + YSTEP/2 ; - ili9341_drawstring("Amp:", x, y); - - y += YSTEP; - plot_printf(buf, BLEN, "%.1fdB",setting.offset); - ili9341_drawstring(buf, x, y); - } - - // Repeat - if (setting.repeat != 1) { - ili9341_set_foreground(LCD_BRIGHT_COLOR_GREEN); - y += YSTEP + YSTEP/2 ; - ili9341_drawstring("Repeat:", x, y); - - y += YSTEP; - plot_printf(buf, BLEN, "%d",setting.repeat); - buf[6]=0; - ili9341_drawstring(buf, x, y); - } - - // Trigger - if (setting.trigger != T_AUTO) { - if (is_paused() || setting.trigger == T_NORMAL) { - ili9341_set_foreground(LCD_BRIGHT_COLOR_GREEN); - } else { - ili9341_set_foreground(LCD_BRIGHT_COLOR_RED); - } - y += YSTEP + YSTEP/2 ; - ili9341_drawstring("TRIG:", x, y); - - y += YSTEP; - if (rounding) - plot_printf(buf, BLEN, "%4f", value(setting.trigger_level)); - else - plot_printf(buf, BLEN, "%.4F", value(setting.trigger_level)); -// plot_printf(buf, BLEN, "%4f", value(setting.trigger_level)/setting.unit_scale); - ili9341_drawstring(buf, x, y); - } - - // Mode - if (level_is_calibrated()) - color = LCD_BRIGHT_COLOR_GREEN; - else - color = LCD_BRIGHT_COLOR_RED; - ili9341_set_foreground(color); - y += YSTEP + YSTEP/2 ; - ili9341_drawstring_7x13(MODE_LOW(setting.mode) ? "LOW" : "HIGH", x, y); - - // Compact status string -// ili9341_set_background(LCD_FG_COLOR); - ili9341_set_foreground(LCD_FG_COLOR); - y += YSTEP + YSTEP/2 ; - strncpy(buf," ",BLEN-1); - if (setting.auto_attenuation) - buf[0] = 'a'; - else - buf[0] = 'A'; - if (setting.auto_IF) - buf[1] = 'f'; - else - buf[1] = 'F'; - if (setting.auto_reflevel) - buf[2] = 'r'; - else - buf[2] = 'R'; - if (S_IS_AUTO(setting.agc)) - buf[3] = 'g'; - else if (S_STATE(setting.agc)) - buf[3] = 'G'; - if (S_IS_AUTO(setting.lna)) - buf[4] = 'n'; - else if (S_STATE(setting.lna)) - buf[4] = 'N'; - if (S_IS_AUTO(setting.below_IF)) - buf[5] = 'b'; - else if (S_STATE(setting.below_IF)) - buf[5] = 'B'; - ili9341_drawstring(buf, x, y); - - // Version - y += YSTEP + YSTEP/2 ; - strncpy(buf,&VERSION[8], BLEN-1); - ili9341_drawstring(buf, x, y); - -// ili9341_set_background(LCD_BG_COLOR); - if (!get_waterfall()) { // Do not draw bottom level if in waterfall mode - // Bottom level - y = area_height - 8 + OFFSETY; - if (rounding) - plot_printf(buf, BLEN, "%4d", (int)(yMax - setting.scale * NGRIDY)); - else - plot_printf(buf, BLEN, "%+4.3F", ((yMax - setting.scale * NGRIDY)/setting.unit_scale)); - // buf[5]=0; - if (level_is_calibrated()) - if (setting.auto_reflevel) - color = LCD_FG_COLOR; - else - color = LCD_BRIGHT_COLOR_GREEN; - else - color = LCD_BRIGHT_COLOR_RED; - ili9341_set_foreground(color); - ili9341_drawstring(buf, x, y); - } -} - // -------------------- Self testing ------------------------------------------------- enum { diff --git a/ui.c b/ui.c index ccb95fa..6a4cded 100644 --- a/ui.c +++ b/ui.c @@ -2539,6 +2539,18 @@ touch_pickup_marker(void) return FALSE; } +static int touch_quick_menu(void) +{ + int touch_x, touch_y; + touch_position(&touch_x, &touch_y); + if (touch_x 1000) { + v = v / 10; + m = m * 10; + } + v = (int)(v+0.5); + v = v * m; + if (sign == -1) { + v = -v; + } + return v; +} + +const char * const unit_string[] = { "dBm", "dBmV", "dB"S_MICRO"V", "V", "W", "dBc", "dBc", "dBc", "Vc", "Wc" }; // unit + 5 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"}; + +#define MAX_QUICK_MENU 20 +uint8_t quick_menu_y[MAX_QUICK_MENU]; +menuitem_t *quick_menu[MAX_QUICK_MENU]; +int max_quick_menu = 0; + +int invoke_quick_menu(int y) +{ + int i=0; + while (i < max_quick_menu) { + if (y < quick_menu_y[i] && quick_menu[i] != NULL) { + if ((uint32_t)quick_menu[i] < KM_NONE) { + ui_mode_keypad((int)quick_menu[i]); + ui_process_keypad(); + } else { + selection = -1; + menu_current_level = 0; + menu_push_submenu(quick_menu[i]); + } + return TRUE; + } + i++; + } + return FALSE; +} + + + +void draw_cal_status(void) +{ +#define BLEN 7 + char buf[BLEN+1]; + buf[6]=0; +#define YSTEP 8 + int x = 0; + int y = OFFSETY; + unsigned int color; + int rounding = false; + if (!UNIT_IS_LINEAR(setting.unit)) + rounding = true; + const char * const unit = unit_string[setting.unit]; + ili9341_set_background(LCD_BG_COLOR); + ili9341_fill(0, 0, OFFSETX, CHART_BOTTOM); + max_quick_menu = 0; + if (MODE_OUTPUT(setting.mode)) { // No cal status during output + return; + } + + // if (current_menu_is_form() && !in_selftest) +// return; + + ili9341_set_background(LCD_BG_COLOR); + + float yMax = setting.reflevel; + // Ref level + if (rounding) + plot_printf(buf, BLEN, "%+4d", (int)yMax); + else + plot_printf(buf, BLEN, "%+4.3F", (yMax/setting.unit_scale)); + + if (level_is_calibrated()) + color = setting.auto_reflevel ? LCD_FG_COLOR : LCD_BRIGHT_COLOR_GREEN; + else + color = LCD_BRIGHT_COLOR_RED; + ili9341_set_foreground(color); + ili9341_drawstring(buf, x, y); + y += YSTEP + YSTEP/2 ; + quick_menu_y[max_quick_menu] = y; + quick_menu[max_quick_menu++] = (menuitem_t *)menu_reflevel; + + // Unit +#if 0 + color = LCD_FG_COLOR; + ili9341_set_foreground(color); + if (setting.auto_reflevel){ + y += YSTEP + YSTEP/2 ; + ili9341_drawstring("AUTO", x, y); + } +#endif + plot_printf(buf, BLEN, "%s%s",unit_scale_text[setting.unit_scale_index], unit); + ili9341_drawstring(buf, x, y); + + y += YSTEP + YSTEP/2; + quick_menu_y[max_quick_menu] = y; + quick_menu[max_quick_menu++] = (menuitem_t *)menu_unit; + + // Scale + color = LCD_FG_COLOR; + ili9341_set_foreground(color); +#if 1 + unsigned int i = 0; + while (i < sizeof(scale_value)/sizeof(float)) { + float t = (setting.scale/setting.unit_scale) / scale_value[i];; + if (t > 0.9 && t < 1.1){ + plot_printf(buf, BLEN, "%s%s/",scale_vtext[i],unit_scale_text[setting.unit_scale_index]); + break; + } + i++; + } +#else + plot_printf(buf, BLEN, "%.2F/",setting.scale); +#endif + ili9341_drawstring(buf, x, y); + y += YSTEP + YSTEP/2 ; + quick_menu_y[max_quick_menu] = y; + quick_menu[max_quick_menu++] = (menuitem_t *)KM_SCALE; + + // Trigger status + if (is_paused()) { + color = LCD_BRIGHT_COLOR_GREEN; + ili9341_set_foreground(color); + ili9341_drawstring("PAUSED", x, y); + y += YSTEP + YSTEP/2 ; + } + if (setting.trigger == T_SINGLE || setting.trigger == T_NORMAL ) { + color = LCD_BRIGHT_COLOR_GREEN; + ili9341_set_foreground(color); + ili9341_drawstring("ARMED", x, y); + y += YSTEP + YSTEP/2 ; + } + // AM warning + if (signal_is_AM) { + color = LCD_BRIGHT_COLOR_RED; + ili9341_set_foreground(color); + ili9341_drawstring("AM", x, y); + y += YSTEP + YSTEP/2 ; + } + quick_menu_y[max_quick_menu] = y; + quick_menu[max_quick_menu++] = (menuitem_t *)NULL; + +// if (setting.mode == M_LOW) { + // Attenuation + if (setting.auto_attenuation) + color = LCD_FG_COLOR; + else + color = LCD_BRIGHT_COLOR_GREEN; + ili9341_set_foreground(color); + ili9341_drawstring("Atten:", x, y); + y += YSTEP; + plot_printf(buf, BLEN, "%.2FdB", get_attenuation()); + ili9341_drawstring(buf, x, y); + y += YSTEP + YSTEP/2 ; + quick_menu_y[max_quick_menu] = y; + quick_menu[max_quick_menu++] = (menuitem_t *)menu_atten; +// } + + // Calc + if (setting.average>0) { + ili9341_set_foreground(LCD_BRIGHT_COLOR_GREEN); + ili9341_drawstring("Calc:", x, y); + y += YSTEP; + plot_printf(buf, BLEN, "%s",averageText[setting.average]); + ili9341_drawstring(buf, x, y); + y += YSTEP + YSTEP/2 ; + quick_menu_y[max_quick_menu] = y; + quick_menu[max_quick_menu++] = (menuitem_t *)menu_average; + } + // Spur +#ifdef __SPUR__ + if (setting.spur_removal) { + ili9341_set_foreground(LCD_BRIGHT_COLOR_GREEN); + ili9341_drawstring("Spur:", x, y); + y += YSTEP; + plot_printf(buf, BLEN, "ON"); + ili9341_drawstring(buf, x, y); + y += YSTEP + YSTEP/2 ; + quick_menu_y[max_quick_menu] = y; + quick_menu[max_quick_menu++] = (menuitem_t *)menu_stimulus; + } + if (setting.mirror_masking) { + ili9341_set_foreground(LCD_BRIGHT_COLOR_GREEN); + ili9341_drawstring("Mask:", x, y); + + y += YSTEP; + plot_printf(buf, BLEN, "ON"); + ili9341_drawstring(buf, x, y); + y += YSTEP + YSTEP/2 ; + quick_menu_y[max_quick_menu] = y; + quick_menu[max_quick_menu++] = (menuitem_t *)menu_stimulus; + } +#endif + + if (setting.subtract_stored) { + ili9341_set_foreground(LCD_BRIGHT_COLOR_GREEN); + ili9341_drawstring("Norm.", x, y); + y += YSTEP + YSTEP/2 ; + quick_menu_y[max_quick_menu] = y; + quick_menu[max_quick_menu++] = (menuitem_t *)menu_storage; + } + + // RBW + if (setting.rbw_x10) + color = LCD_BRIGHT_COLOR_GREEN; + else + color = LCD_FG_COLOR; + ili9341_set_foreground(color); + + ili9341_drawstring("RBW:", x, y); + y += YSTEP; + plot_printf(buf, BLEN, "%.1FkHz", actual_rbw_x10/10.0); + ili9341_drawstring(buf, x, y); + y += YSTEP + YSTEP/2 ; + quick_menu_y[max_quick_menu] = y; + quick_menu[max_quick_menu++] = (menuitem_t *)menu_rbw; + +#if 0 + // VBW + if (setting.frequency_step > 0) { + ili9341_set_foreground(LCD_FG_COLOR); + y += YSTEP + YSTEP/2 ; + ili9341_drawstring("VBW:", x, y); + + y += YSTEP; + plot_printf(buf, BLEN, "%dkHz",(int)setting.vbw_x10/10.0); + buf[6]=0; + ili9341_drawstring(buf, x, y); + } +#endif + // Sweep time + if (setting.step_delay != 0) + color = LCD_BRIGHT_COLOR_GREEN; + else + color = LCD_FG_COLOR; + ili9341_set_foreground(color); + buf[0] = ' '; + strcpy(&buf[1],"Scan:"); + if (setting.step_delay_mode == SD_PRECISE) + buf[0] = 'P'; + else if (setting.step_delay_mode == SD_FAST) + buf[0] = 'F'; + else + strcpy(&buf[0],"Scan:"); + ili9341_drawstring(buf, x, y); + +#if 0 // Activate for sweep time debugging + y += YSTEP; + plot_printf(buf, BLEN, "%5.3Fs", (float)setting.sweep_time_us/ONE_SECOND_TIME); + ili9341_drawstring(buf, x, y); +#endif + y += YSTEP; + plot_printf(buf, BLEN, "%5.3Fs", (float)setting.actual_sweep_time_us/ONE_SECOND_TIME); + ili9341_drawstring(buf, x, y); + y += YSTEP + YSTEP/2 ; + quick_menu_y[max_quick_menu] = y; + quick_menu[max_quick_menu++] = (menuitem_t *)menu_sweep_speed; + + + #if 0 // Activate for sweep time debugging + y += YSTEP; + update_rbw(); // To ensure the calc_min_sweep time shown takes the latest delay into account + calculate_step_delay(); + uint32_t t = calc_min_sweep_time_us(); + plot_printf(buf, BLEN, "%5.3Fs", (float)t/ONE_SECOND_TIME); + ili9341_drawstring(buf, x, y); + y += YSTEP; + plot_printf(buf, BLEN, "%5.3Fs", (float)setting.additional_step_delay_us/ONE_SECOND_TIME); + ili9341_drawstring(buf, x, y); + y += YSTEP + YSTEP/2 ; +#endif + + // Cal output + if (setting.refer >= 0) { + ili9341_set_foreground(LCD_BRIGHT_COLOR_GREEN); + ili9341_drawstring("Ref:", x, y); + y += YSTEP; + plot_printf(buf, BLEN, "%dMHz",reffer_freq[setting.refer]/1000000); + buf[6]=0; + ili9341_drawstring(buf, x, y); + y += YSTEP + YSTEP/2 ; + quick_menu_y[max_quick_menu] = y; + quick_menu[max_quick_menu++] = (menuitem_t *)menu_reffer; + } + + // Offset + if (setting.offset != 0.0) { + ili9341_set_foreground(LCD_BRIGHT_COLOR_GREEN); + ili9341_drawstring("Amp:", x, y); + y += YSTEP; + plot_printf(buf, BLEN, "%.1fdB",setting.offset); + ili9341_drawstring(buf, x, y); + y += YSTEP + YSTEP/2 ; + quick_menu_y[max_quick_menu] = y; + quick_menu[max_quick_menu++] = (menuitem_t *)KM_OFFSET; + } + + // Repeat + if (setting.repeat != 1) { + ili9341_set_foreground(LCD_BRIGHT_COLOR_GREEN); + ili9341_drawstring("Repeat:", x, y); + y += YSTEP; + plot_printf(buf, BLEN, "%d",setting.repeat); + buf[6]=0; + ili9341_drawstring(buf, x, y); + y += YSTEP + YSTEP/2 ; + quick_menu_y[max_quick_menu] = y; + quick_menu[max_quick_menu++] = (menuitem_t *)KM_REPEAT; + } + + // Trigger + if (setting.trigger != T_AUTO) { + if (is_paused() || setting.trigger == T_NORMAL) { + ili9341_set_foreground(LCD_BRIGHT_COLOR_GREEN); + } else { + ili9341_set_foreground(LCD_BRIGHT_COLOR_RED); + } + ili9341_drawstring("TRIG:", x, y); + + y += YSTEP; + if (rounding) + plot_printf(buf, BLEN, "%4f", value(setting.trigger_level)); + else + plot_printf(buf, BLEN, "%.4F", value(setting.trigger_level)); +// plot_printf(buf, BLEN, "%4f", value(setting.trigger_level)/setting.unit_scale); + ili9341_drawstring(buf, x, y); + y += YSTEP + YSTEP/2 ; + quick_menu_y[max_quick_menu] = y; + quick_menu[max_quick_menu++] = (menuitem_t *)menu_trigger; + } + + // Mode + if (level_is_calibrated()) + color = LCD_BRIGHT_COLOR_GREEN; + else + color = LCD_BRIGHT_COLOR_RED; + ili9341_set_foreground(color); + y += YSTEP + YSTEP/2 ; + ili9341_drawstring_7x13(MODE_LOW(setting.mode) ? "LOW" : "HIGH", x, y); + + // Compact status string +// ili9341_set_background(LCD_FG_COLOR); + ili9341_set_foreground(LCD_FG_COLOR); + y += YSTEP + YSTEP/2 ; + strncpy(buf," ",BLEN-1); + if (setting.auto_attenuation) + buf[0] = 'a'; + else + buf[0] = 'A'; + if (setting.auto_IF) + buf[1] = 'f'; + else + buf[1] = 'F'; + if (setting.auto_reflevel) + buf[2] = 'r'; + else + buf[2] = 'R'; + if (S_IS_AUTO(setting.agc)) + buf[3] = 'g'; + else if (S_STATE(setting.agc)) + buf[3] = 'G'; + if (S_IS_AUTO(setting.lna)) + buf[4] = 'n'; + else if (S_STATE(setting.lna)) + buf[4] = 'N'; + if (S_IS_AUTO(setting.below_IF)) + buf[5] = 'b'; + else if (S_STATE(setting.below_IF)) + buf[5] = 'B'; + ili9341_drawstring(buf, x, y); + + // Version + y += YSTEP + YSTEP/2 ; + strncpy(buf,&VERSION[8], BLEN-1); + ili9341_drawstring(buf, x, y); + +// ili9341_set_background(LCD_BG_COLOR); + if (!get_waterfall()) { // Do not draw bottom level if in waterfall mode + // Bottom level + y = area_height - 8 + OFFSETY; + if (rounding) + plot_printf(buf, BLEN, "%4d", (int)(yMax - setting.scale * NGRIDY)); + else + plot_printf(buf, BLEN, "%+4.3F", ((yMax - setting.scale * NGRIDY)/setting.unit_scale)); + // buf[5]=0; + if (level_is_calibrated()) + if (setting.auto_reflevel) + color = LCD_FG_COLOR; + else + color = LCD_BRIGHT_COLOR_GREEN; + else + color = LCD_BRIGHT_COLOR_RED; + ili9341_set_foreground(color); + ili9341_drawstring(buf, x, y); + } +} + + + #pragma GCC pop_options