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;