diff --git a/ili9341.c b/ili9341.c index 26b6bf5..2594683 100644 --- a/ili9341.c +++ b/ili9341.c @@ -23,6 +23,7 @@ #include "si4432.h" #include "spi.h" + // Allow enable DMA for read display data #define __USE_DISPLAY_DMA_RX__ @@ -673,7 +674,7 @@ void ili9341_drawstringV(const char *str, int x, int y) ili9341_drawstring(str, ILI9341_HEIGHT-y, x); ili9341_set_rotation(DISPLAY_ROTATION_0); } - +#ifndef wFONT_GET_DATA int ili9341_drawchar_size(uint8_t ch, int x, int y, uint8_t size) { uint16_t *buf = spi_buffer; @@ -691,17 +692,19 @@ int ili9341_drawchar_size(uint8_t ch, int x, int y, uint8_t size) return w*size; } +void ili9341_drawstring_size(const char *str, int x, int y, uint8_t size) +{ + while (*str) + x += ili9341_drawchar_size(*str++, x, y, size); +} +#endif + void ili9341_drawfont(uint8_t ch, int x, int y) { blit8BitWidthBitmap(x, y, NUM_FONT_GET_WIDTH, NUM_FONT_GET_HEIGHT, NUM_FONT_GET_DATA(ch)); } -void ili9341_drawstring_size(const char *str, int x, int y, uint8_t size) -{ - while (*str) - x += ili9341_drawchar_size(*str++, x, y, size); -} #if 0 static void ili9341_pixel(int x, int y, uint16_t color) { @@ -717,21 +720,21 @@ static void ili9341_pixel(int x, int y, uint16_t color) void ili9341_line(int x0, int y0, int x1, int y1) { + SWAP(foreground_color, background_color); #if 0 - // modifed Bresenham's line algorithm, see https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm + // modified Bresenham's line algorithm, see https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm int dx = x1 - x0, sx = 1; if (dx < 0) {dx = -dx; sx = -1;} int dy = y1 - y0, sy = 1; if (dy < 0) {dy = -dy; sy = -1;} int err = (dx > dy ? dx : -dy) / 2; while (1) { - ili9341_pixel(x0, y0, DEFAULT_FG_COLOR); + ili9341_fill(x0, y0, 1, 1); if (x0 == x1 && y0 == y1) break; int e2 = err; if (e2 > -dx) { err -= dy; x0 += sx; } if (e2 < dy) { err += dx; y0 += sy; } } -#endif - SWAP(foreground_color, background_color); +#else if (x0 > x1) { SWAP(x0, x1); SWAP(y0, y1); @@ -762,6 +765,7 @@ void ili9341_line(int x0, int y0, int x1, int y1) x0 += dx; y0 += dy; } +#endif SWAP(foreground_color, background_color); } diff --git a/nanovna.h b/nanovna.h index c0f63b9..3def0ad 100644 --- a/nanovna.h +++ b/nanovna.h @@ -249,6 +249,7 @@ void set_sweep_time_us(uint32_t); #ifdef __SPUR__ //extern int setting.spur; void set_spur(int v); +void toggle_spur(void); void toggle_mirror_masking(void); #endif void set_average(int); diff --git a/plot.c b/plot.c index e74fbeb..8890943 100644 --- a/plot.c +++ b/plot.c @@ -902,7 +902,7 @@ trace_get_value_string_delta(int t, char *buf, int len, float array[POINTS_COUNT } #endif -inline void trace_get_value_string( // Only used at one place +void trace_get_value_string( // Only used at one place int t, char *buf, int len, int i, float coeff[POINTS_COUNT], int ri, int mtype, diff --git a/sa_core.c b/sa_core.c index e036f32..cd2631c 100644 --- a/sa_core.c +++ b/sa_core.c @@ -21,7 +21,7 @@ #include "stdlib.h" #pragma GCC push_options -#pragma GCC optimize ("Og") +#pragma GCC optimize ("Os") // "Os" causes problem in selftest!!!!!!!! //#define __DEBUG_AGC__ If set the AGC value will be shown in the stored trace and FAST_SWEEP rmmode will be disabled @@ -132,7 +132,11 @@ void reset_settings(int m) // setting.refer = -1; // do not reset reffer when switching modes setting.mute = true; #ifdef __SPUR__ - setting.spur_removal = 0; +#ifdef TINYSA4 + setting.spur_removal = S_AUTO_OFF; +#else + setting.spur_removal = S_OFF; +#endif setting.mirror_masking = 0; #endif switch(m) { @@ -203,10 +207,10 @@ uint32_t calc_min_sweep_time_us(void) // Estimate minimum sweep time in //#endif if (FREQ_IS_CW()) { bare_sweep_time = MINIMUM_SWEEP_TIME; // minimum sweep time in fast CW mode - if (setting.repeat != 1 || setting.sweep_time_us >= 100*ONE_MS_TIME || setting.spur_removal != 0) // if no fast CW sweep possible + if (setting.repeat != 1 || setting.sweep_time_us >= 100*ONE_MS_TIME || S_STATE(setting.spur_removal)) // if no fast CW sweep possible bare_sweep_time = 15000; // minimum CW sweep time when not in fast CW mode } - t = vbwSteps * (setting.spur_removal ? 2 : 1) * bare_sweep_time ; // factor in vbwSteps and spur impact + t = vbwSteps * (S_STATE(setting.spur_removal) ? 2 : 1) * bare_sweep_time ; // factor in vbwSteps and spur impact t += (setting.repeat - 1)* REPEAT_TIME * (sweep_points); // Add time required for repeats } return t; @@ -668,6 +672,26 @@ void set_spur(int v) // set_RBW(300); dirty = true; } + +void toggle_spur(void) +{ + if (setting.mode!=M_LOW) + return; +#ifdef TINYSA4 + if (S_IS_AUTO(setting.spur_removal )) + setting.spur_removal = false; + else if (setting.spur_removal) + setting.spur_removal = S_AUTO_OFF; + else + setting.spur_removal = true; +#else + if (S_STATE(setting.spur_removal )) + setting.spur_removal = S_OFF; + else + setting.spur_removal = S_ON; +#endif + dirty = true; +} #endif #ifdef __ULTRA__ @@ -1096,6 +1120,8 @@ void calculate_correction(void) scaled_correction_multi[i] = (int32_t) ( m / d ); } } +#pragma GCC push_options +#pragma GCC optimize ("Og") // "Os" causes problem pureRSSI_t get_frequency_correction(uint32_t f) // Frequency dependent RSSI correction to compensate for imperfect LPF { @@ -1119,6 +1145,8 @@ pureRSSI_t get_frequency_correction(uint32_t f) // Frequency dependent RSSI #endif return(cv); } +#pragma GCC pop_options + float peakLevel; @@ -1483,7 +1511,7 @@ void update_rbw(void) // calculate the actual_rbw and the vbwSteps (# actual_rbw_x10 = temp_actual_rbw_x10; // Now it fits in 16 bit #ifdef __SI4432__ - if (setting.spur_removal && actual_rbw_x10 > 3000) + if (S_STATE(setting.spur_removal) && actual_rbw_x10 > 3000) actual_rbw_x10 = 2500; // if spur suppression reduce max rbw to fit within BPF SI4432_Sel = MODE_SELECT(setting.mode); #endif @@ -1729,12 +1757,12 @@ static void calculate_static_correction(void) // Calculate the - setting.offset); } - pureRSSI_t perform(bool break_on_operation, int i, uint32_t f, int tracking) // Measure the RSSI for one frequency, used from sweep and other measurement routines. Must do all HW setup { int modulation_delay = 0; int modulation_index = 0; - if (i == 0 && dirty ) { // if first point in scan and dirty + int spur_second_pass = false; + if (i == 0 && dirty ) { // if first point in scan and dirty #ifdef __ADF4351__ ADF4351_force_refresh(); #endif @@ -1743,7 +1771,6 @@ pureRSSI_t perform(bool break_on_operation, int i, uint32_t f, int tracking) scandirty = true; // This is the first pass with new settings dirty = false; sweep_elapsed = chVTGetSystemTimeX(); // for measuring accumulated time - if (setting.spur_removal == -1) setting.spur_removal = 1; // ensure spur processing starts in right phase // Set for actual time pre calculated value (update after sweep) setting.actual_sweep_time_us = calc_min_sweep_time_us(); // Change actual sweep time as user input if it greater minimum @@ -1918,8 +1945,8 @@ modulation_again: goto skip_LO_setting; // No more LO changes required, save some time and jump over the code uint32_t local_IF; - - again: // Spur reduction jumps to here for second measurement + spur_second_pass = false; + again: // Spur reduction jumps to here for second measurement local_IF=0; // to get rid of warning if (MODE_HIGH(setting.mode)) { @@ -1940,17 +1967,17 @@ modulation_again: stored_t[i] = -60.0; // Display when to do spur shift in the stored trace #endif } - if (setting.spur_removal){ // If in low input mode and spur reduction is on - if (false && S_IS_AUTO(setting.below_IF) && lf < local_IF / 2 ) // if below 150MHz and auto_below_IF <-------------------TODO --------------------- + if (S_STATE(setting.spur_removal)){ // If in low input mode and spur reduction is on + if (false && S_IS_AUTO(setting.below_IF) && (lf < local_IF / 2 || lf > local_IF) ) // if below 150MHz and auto_below_IF <-------------------TODO --------------------- { // else low/above IF - if (setting.spur_removal == 1) - setting.below_IF = S_AUTO_ON; // use below IF in first pass + if (spur_second_pass) + setting.below_IF = S_AUTO_ON; // use below IF in second pass else - setting.below_IF = S_AUTO_OFF; // and above IF in second pass + setting.below_IF = S_AUTO_OFF; // and above IF in first pass } else { - if (setting.spur_removal == -1) // If second spur pass + if (spur_second_pass) // If second spur pass #ifdef __SI4432__ local_IF = local_IF + 500000; // apply IF spur shift #else @@ -1965,14 +1992,14 @@ modulation_again: } #ifdef __ULTRA__ } else if (setting.mode == M_ULTRA) { // No above/below IF mode in Ultra - local_IF = setting.frequency_IF + (int)(actual_rbw < 350.0 ? setting.spur_removal*300000 : 0 ); + local_IF = setting.frequency_IF + (int)(actual_rbw < 350.0 ? S_STATE(setting.spur_removal)*300000 : 0 ); #ifdef __SI4432__ set_freq (SI4432_RX , local_IF); #endif #ifdef __SI4463__ set_freq (SI4463_RX , local_IF); #endif - // local_IF = setting.frequency_IF + (int)(actual_rbw < 300.0?setting.spur_removal * 1000 * actual_rbw:0); + // local_IF = setting.frequency_IF + (int)(actual_rbw < 300.0?S_STATE(setting.spur_removal) * 1000 * actual_rbw:0); #endif } @@ -1983,7 +2010,7 @@ modulation_again: // if (lf > 3406000000 ) // setFreq (1, local_IF/5 + lf/5); // else - if (setting.spur_removal != 1) { // Left of tables + if (S_STATE(setting.spur_removal) != 1) { // Left of tables if (lf > 3250000000 ) set_freq (SI4432_LO , lf/5 - local_IF/5); if (lf > 1250000000 ) @@ -2098,14 +2125,13 @@ modulation_again: #ifdef __FAST_SWEEP__ #ifdef __SI4432__ - if (i == 0 && setting.frequency_step == 0 && setting.trigger == T_AUTO && setting.spur_removal == 0 && SI4432_step_delay == 0 && setting.repeat == 1 && setting.sweep_time_us < 100*ONE_MS_TIME) { + if (i == 0 && setting.frequency_step == 0 && setting.trigger == T_AUTO && S_STATE(setting.spur_removal) == 0 && SI4432_step_delay == 0 && setting.repeat == 1 && setting.sweep_time_us < 100*ONE_MS_TIME) { // if ultra fast scanning is needed prefill the SI4432 RSSI read buffer SI4432_Fill(MODE_SELECT(setting.mode), 0); } #endif #ifdef __SI4463__ - if (i == 0 && setting.frequency_step == 0 && setting.trigger == T_AUTO && setting.spur_removal == 0 && SI4432_step_delay == 0 && setting.repeat == 1 && setting.sweep_time_us < 100*ONE_MS_TIME) { - // if ultra fast scanning is needed prefill the SI4432 RSSI read buffer + if (i == 0 && setting.frequency_step == 0 && setting.trigger == T_AUTO && S_STATE(setting.spur_removal) == 0 && SI4432_step_delay == 0 && setting.repeat == 1 && setting.sweep_time_us < 100*ONE_MS_TIME) { SI446x_Fill(MODE_SELECT(setting.mode), 0); } #endif @@ -2161,7 +2187,7 @@ modulation_again: }while(1); #ifdef __FAST_SWEEP__ #ifdef __SI4432__ - if (setting.spur_removal == 0 && SI4432_step_delay == 0 && setting.repeat == 1 && setting.sweep_time_us < 100*ONE_MS_TIME) { + if (S_STATE(setting.spur_removal) == 0 && SI4432_step_delay == 0 && setting.repeat == 1 && setting.sweep_time_us < 100*ONE_MS_TIME) { SI4432_Fill(MODE_SELECT(setting.mode), 1); // fast mode possible to pre-fill RSSI buffer } #endif @@ -2186,13 +2212,16 @@ modulation_again: } #ifdef __SPUR__ static pureRSSI_t spur_RSSI = -1; // Initialization only to avoid warning. - if (setting.spur_removal == 1) { // If first spur pass - spur_RSSI = pureRSSI; // remember measure RSSI - setting.spur_removal = -1; - goto again; // Skip all other processing - } else if (setting.spur_removal == -1) { // If second spur pass - pureRSSI = ( pureRSSI < spur_RSSI ? pureRSSI : spur_RSSI); // Take minimum of two - setting.spur_removal = 1; // and prepare for next call of perform. + if (S_STATE(setting.spur_removal)) { + if (!spur_second_pass) { // If first spur pass + spur_RSSI = pureRSSI; // remember measure RSSI + spur_second_pass = true; + goto again; // Skip all other processing + } else { // If second spur pass + pureRSSI = ( pureRSSI < spur_RSSI ? pureRSSI : spur_RSSI); // Take minimum of two + if (S_IS_AUTO(setting.below_IF)) + setting.below_IF = S_AUTO_OFF; // make sure it is off for next pass + } } #endif @@ -3318,7 +3347,11 @@ common_silent: setting.step_delay_mode = SD_PRECISE; // set_step_delay(1); // Precise scanning speed #ifdef __SPUR__ - setting.spur_removal = 1; +#ifdef TINYSA4 + setting.spur_removal = S_AUTO_OFF; +#else + setting.spur_removal = S_OFF; +#endif #endif common: @@ -3336,7 +3369,7 @@ common_silent: dirty = true; // set_step_delay(1); // Do not set !!!!! #ifdef __SPUR__ - setting.spur_removal = 1; + setting.spur_removal = S_ON; #endif goto common; @@ -3524,7 +3557,7 @@ void self_test(int test) j = setting.test_argument; // do_again: test_prepare(TEST_RBW); - setting.spur_removal = 0; + setting.spur_removal = S_OFF; #if 1 // Disable for offset baseline scanning setting.step_delay_mode = SD_NORMAL; setting.repeat = 1; @@ -3561,7 +3594,7 @@ void self_test(int test) #if 1 // Enable for step delay tuning while (setting.step_delay > 10 && test_value != 0 && test_value > saved_peakLevel - 0.5) { test_prepare(TEST_RBW); - setting.spur_removal = 0; + setting.spur_removal = S_OFF; setting.step_delay_mode = SD_NORMAL; setting.step_delay = setting.step_delay * 4 / 5; if (setting.rbw_x10 < 1000) @@ -3588,7 +3621,7 @@ void self_test(int test) test_prepare(TEST_RBW); setting.step_delay_mode = SD_FAST; setting.offset_delay /= 2; - setting.spur_removal = 0; + setting.spur_removal = S_OFF; if (setting.rbw_x10 < 1000) set_sweep_frequency(ST_SPAN, (uint32_t)(setting.rbw_x10 * 5000)); // 50 times RBW else @@ -3736,8 +3769,8 @@ quit: reset_settings(M_LOW); #endif } -#pragma GCC pop_options +#pragma GCC pop_options #if 0 // fixed point FFT diff --git a/ui.c b/ui.c index 26b387f..610b594 100644 --- a/ui.c +++ b/ui.c @@ -25,6 +25,9 @@ #include #include +#pragma GCC push_options +#pragma GCC optimize ("Os") + uistat_t uistat = { digit: 6, current_trace: 0, @@ -76,7 +79,6 @@ enum { #endif #define NUMINPUT_LEN 10 - static uint8_t ui_mode = UI_NORMAL; static uint8_t keypad_mode; static uint8_t keypads_last_index; @@ -124,7 +126,7 @@ typedef struct { #define EVT_TOUCH_DOWN 1 #define EVT_TOUCH_PRESSED 2 #define EVT_TOUCH_RELEASED 3 - +#define EVT_TOUCH_LONGPRESS 4 static int8_t last_touch_status = EVT_TOUCH_NONE; static int16_t last_touch_x; static int16_t last_touch_y; @@ -296,7 +298,16 @@ touch_check(void) last_touch_y = y; } } +#if 0 // Long press detection + systime_t ticks = chVTGetSystemTimeX(); + + if (stat && !last_touch_status) { // new button, initialize + prev_touch_time = ticks; + } + dt = ticks - prev_touch_time; + if (stat && stat == last_touch_status && dt > BUTTON_DOWN_LONG_TICKS) {return EVT_TOUCH_LONGPRESS;} +#endif if (stat != last_touch_status) { last_touch_status = stat; return stat ? EVT_TOUCH_PRESSED : EVT_TOUCH_RELEASED; @@ -307,16 +318,24 @@ touch_check(void) void touch_wait_release(void) { - while (touch_check() != EVT_TOUCH_RELEASED) + while (touch_check() != EVT_TOUCH_NONE) chThdSleepMilliseconds(20); } - +#if 0 static inline void touch_wait_pressed(void) { while (touch_check() != EVT_TOUCH_PRESSED) ; } +#endif + +static inline void +touch_wait_released(void) +{ + while (touch_check() != EVT_TOUCH_RELEASED) + ; +} void touch_cal_exec(void) @@ -331,8 +350,8 @@ touch_cal_exec(void) ili9341_line(0, 0, 32, 0); ili9341_line(0, 0, 32, 32); ili9341_drawstring("TOUCH UPPER LEFT", 40, 40); - - touch_wait_release(); + touch_wait_released(); +// touch_wait_release(); x1 = last_touch_x; y1 = last_touch_y; @@ -342,7 +361,8 @@ touch_cal_exec(void) ili9341_line(LCD_WIDTH-1, LCD_HEIGHT-1, LCD_WIDTH-32, LCD_HEIGHT-32); ili9341_drawstring("TOUCH LOWER RIGHT", 210, 200); - touch_wait_release(); + touch_wait_released(); + // touch_wait_release(); x2 = last_touch_x; y2 = last_touch_y; @@ -917,7 +937,7 @@ menu_marker_smith_cb(int item, uint8_t data) #endif static void -active_marker_select(int item) +active_marker_select(int item) // used only to select an active marker from the modify marker selection menu { if (item == -1) { active_marker = previous_marker; @@ -926,9 +946,12 @@ active_marker_select(int item) choose_active_marker(); } } else { - if (previous_marker != active_marker) + if (previous_marker != active_marker) { previous_marker = active_marker; - active_marker = item; + active_marker = item; + } else { + active_marker = item; + } } } #ifdef __VNA__ @@ -2574,7 +2597,7 @@ static int touch_quick_menu(void) { int touch_x, touch_y; touch_position(&touch_x, &touch_y); - if (touch_x HEIGHT) { + if (touch_x < FREQUENCIES_XPOS2 -50 && uistat.lever_mode == LM_CENTER) { + touch_wait_release(); + if (setting.freq_mode & FREQ_MODE_CENTER_SPAN) + ui_mode_keypad(KM_CENTER); + else + ui_mode_keypad(KM_START); + ui_process_keypad(); + } + if (touch_x > FREQUENCIES_XPOS2 - 50 && touch_x < FREQUENCIES_XPOS2 +50) { + touch_wait_release(); + if (FREQ_IS_STARTSTOP()) + setting.freq_mode |= FREQ_MODE_CENTER_SPAN; + else if (FREQ_IS_CENTERSPAN()) + setting.freq_mode &= ~FREQ_MODE_CENTER_SPAN; + redraw_request |= REDRAW_FREQUENCY; + return true; + } + if (touch_x >= FREQUENCIES_XPOS2 +50 && uistat.lever_mode == LM_SPAN) { + touch_wait_release(); + if (setting.freq_mode & FREQ_MODE_CENTER_SPAN) + ui_mode_keypad(KM_SPAN); + else + ui_mode_keypad(KM_STOP); + ui_process_keypad(); + } select_lever_mode(touch_x < FREQUENCIES_XPOS2 ? LM_CENTER : LM_SPAN); return TRUE; } @@ -2624,6 +2672,14 @@ touch_marker_select(void) for (int i = 0; i < MARKERS_MAX; i++) { if (markers[i].enabled) { if (selected_marker == 0) { + if (active_marker == i) { + extern const menuitem_t menu_marker_modify[]; + touch_wait_release(); + selection = -1; + menu_current_level = 0; + menu_push_submenu(menu_marker_modify); + break; + } active_marker = i; redraw_marker(active_marker); break; @@ -2665,7 +2721,7 @@ void ui_process_touch(void) break; // Try select lever mode (top and bottom screen) if (touch_lever_mode_select()) { - touch_wait_release(); +// touch_wait_release(); break; } @@ -2811,3 +2867,7 @@ int check_touched(void) touch_start_watchdog(); return touched; } + + + +#pragma GCC pop_options diff --git a/ui_sa.c b/ui_sa.c index 536c5c8..38d0e41 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -16,8 +16,6 @@ * the Free Software Foundation, Inc., 51 Franklin Street, * Boston, MA 02110-1301, USA. */ -#pragma GCC push_options -#pragma GCC optimize ("Os") #define FORM_ICON_WIDTH 16 @@ -468,9 +466,7 @@ static const menuitem_t menu_tophigh[]; static const menuitem_t menu_topultra[]; #endif - -#define AUTO_ICON(s) (s >=2 ? BUTTON_ICON_CHECK_AUTO : s) // This assumes the a certin icon order !!!!!! - +#define AUTO_ICON(S) (S>=2?BUTTON_ICON_CHECK_AUTO:S) // Depends on order of ICONs!!!!! static UI_FUNCTION_ADV_CALLBACK(menu_mode_acb) { @@ -766,10 +762,7 @@ static UI_FUNCTION_ADV_CALLBACK(menu_spur_acb) return; } if (setting.mode == M_LOW) { - if (setting.spur_removal) - set_spur(0); - else - set_spur(1); // must be 0 or 1 !!!! + toggle_spur(); } else toggle_mirror_masking(); // menu_move_back(); @@ -1226,8 +1219,6 @@ static UI_FUNCTION_ADV_CALLBACK(menu_harmonic_acb) #endif -#define AUTO_ICON(S) (S>=2?BUTTON_ICON_CHECK_AUTO:S) // Depends on order of ICONs!!!!! - static UI_FUNCTION_ADV_CALLBACK(menu_settings_agc_acb){ (void)item; (void)data; @@ -1350,7 +1341,11 @@ static UI_FUNCTION_ADV_CALLBACK(menu_outputmode_acb) draw_menu(); } +#ifdef TINYSA4 +static const uint16_t points_setting[] = {51, 101, 201, 450}; +#else static const uint16_t points_setting[] = {51, 101, 145, 290}; +#endif static UI_FUNCTION_ADV_CALLBACK(menu_points_acb){ (void)item; if(b){ @@ -2518,7 +2513,10 @@ redraw_cal_status: ili9341_set_foreground(LCD_BRIGHT_COLOR_GREEN); ili9341_drawstring("Spur:", x, y); y += YSTEP; - y = add_quick_menu("ON", x, y, (menuitem_t *)menu_stimulus); + if (S_IS_AUTO(setting.spur_removal)) + y = add_quick_menu("AUTO", x, y, (menuitem_t *)menu_stimulus); + else + y = add_quick_menu("ON", x, y, (menuitem_t *)menu_stimulus); } if (setting.mirror_masking) { ili9341_set_foreground(LCD_BRIGHT_COLOR_GREEN); @@ -2720,6 +2718,3 @@ redraw_cal_status: } } - - -#pragma GCC pop_options