From 13d1e65576b5e913698ac6d6df46ea0f3f8f471e Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Mon, 6 Mar 2023 17:28:32 +0100 Subject: [PATCH] IMD multi band --- main.c | 89 ++++++++++++++++++++++++++++++------------------------- nanovna.h | 1 + sa_core.c | 39 +++++++++++++++++++----- ui.c | 35 +++++++++++++++++----- 4 files changed, 109 insertions(+), 55 deletions(-) diff --git a/main.c b/main.c index c1d834b..590b7e5 100644 --- a/main.c +++ b/main.c @@ -1341,42 +1341,60 @@ static freq_t _f_delta; static freq_t _f_error; static uint16_t _f_count; + +#ifdef __BANDS__ +int getBand(uint16_t idx) { + if (setting.multi_band && !setting.multi_trace) + return _f_band_index[idx]; + return 0; +} + +void update_bands(void) +{ + if (!setting.multi_band) + return; + freq_t span = 0; + for (int i=0; i= sweep_points) + return; + } + else { + b++; + break; + } + } + } while (b < BANDS_MAX); + update_rbw(); + dirty = true; +} +#endif + + static void set_frequencies(freq_t start, freq_t stop, uint16_t points) { #ifdef __BANDS__ if (setting.multi_band && !setting.multi_trace) { - - freq_t span = 0; - for (int i=0; i= points) - return; - } - else { - b++; - break; - } - } - } while (b < BANDS_MAX); + update_bands(); return; - } + } #endif freq_t span = stop - start; _f_start = start; @@ -1393,22 +1411,13 @@ freq_t getFrequency(uint16_t idx) { idx = POINTS_COUNT-1; int b = _f_band_index[idx]; band_t *bp = &setting.bands[b]; - freq_t f = bp->start + ((bp->end- bp->start) * (idx - bp->start_index)) / (bp->stop_index - bp->start_index) ; + volatile freq_t f = bp->start + ((bp->end- bp->start) * (idx - bp->start_index)) / (bp->stop_index - bp->start_index) ; return f; } else #endif return _f_start + _f_delta * idx + (_f_count / 2 + _f_error * idx) / _f_count;} #endif -#ifdef __BANDS__ -int getBand(uint16_t idx) { - if (setting.multi_band && !setting.multi_trace) - return _f_band_index[idx]; - return 0; -} -#endif - - void update_frequencies(void) { diff --git a/nanovna.h b/nanovna.h index afa2924..dd3fbff 100644 --- a/nanovna.h +++ b/nanovna.h @@ -255,6 +255,7 @@ enum stimulus_type { void set_sweep_points(uint16_t points); void update_frequencies(void); +void update_bands(void); void set_sweep_frequency(int type, freq_t frequency); freq_t get_sweep_frequency(int type); void my_microsecond_delay(int t); diff --git a/sa_core.c b/sa_core.c index abf8182..22cebfe 100644 --- a/sa_core.c +++ b/sa_core.c @@ -558,6 +558,16 @@ void reset_settings(int m) disable_waterfall(); setting.level_meter = false; setting.pulse = false; +#ifdef __BANDS__ + setting.multi_band = false; + setting.multi_trace = false; + for (int i = 0; ienabled && b->start <= f && f end) { + freq_t f_step = (b->end - b->start)/(b->stop_index - b->start_index); + int i = ((f - b->start ) + (f_step >> 1)) / f_step + b->start_index; + return i; + } + } + return 0; + } +#endif freq_t f_step = getFrequency(1) - getFrequency(0); if (f_step == 0) return 0; @@ -3308,7 +3331,7 @@ static int modulation_steps = 8; #define MAX_MODULATION_STEPS 128 // Max = 10000 / 28.8 -static const int sinus[MAX_MODULATION_STEPS/4+1] = {0, 17, 34, 51, 68, 84, 101, 117, 133, 148, 164, 179, 193, 207, 220, 233, 246, 257, 268, 279, 289, 298, 306, 314, 321, 327, 332, 337, 341, 343, 346, 347, 347 }; +static const int sine_wave[MAX_MODULATION_STEPS/4+1] = {0, 17, 34, 51, 68, 84, 101, 117, 133, 148, 164, 179, 193, 207, 220, 233, 246, 257, 268, 279, 289, 298, 306, 314, 321, 327, 332, 337, 341, 343, 346, 347, 347 }; // // Offset is 14.4Hz when below 600MHz and 28.8 when above. // @@ -3532,18 +3555,18 @@ pureRSSI_t perform(bool break_on_operation, int i, freq_t f, int tracking) / #ifdef TINYSA4 // Calculate AM/FM modulation if (setting.modulation == MO_AM) { - int sinus_index = 1; + int sine_wave_index = 1; config.cor_am = INITIAL_MODULATION_CORRECTION; // Initialize with some spare modulation_steps = MAX_MODULATION_STEPS; // Search modulation steps that fit frequency while ( (modulation_delay = (8000000/ modulation_steps ) / setting.modulation_frequency + config.cor_am) < 20 && modulation_steps > 4) { - sinus_index <<= 1; + sine_wave_index <<= 1; modulation_steps >>= 1; } int offset347 = (setting.modulation_depth_x100 < 100 ? setting.modulation_depth_x100 - 6: setting.modulation_depth_x100) * 347 / 100; for (int i = 0; i < modulation_steps/4+1; i++) { - fm_modulation[i] = offset347 * sinus[i*sinus_index]/347; + fm_modulation[i] = offset347 * sine_wave[i*sine_wave_index]/347; fm_modulation[modulation_steps/2 - i] = fm_modulation[i]; - fm_modulation[modulation_steps/2 + i] = - offset347 * sinus[i*sinus_index]/347; + fm_modulation[modulation_steps/2 + i] = - offset347 * sine_wave[i*sine_wave_index]/347; fm_modulation[modulation_steps - i] = fm_modulation[modulation_steps/2 + i]; } for (int i=0; i < modulation_steps; i++) { @@ -3555,17 +3578,17 @@ pureRSSI_t perform(bool break_on_operation, int i, freq_t f, int tracking) / } } if (setting.modulation == MO_WFM) { - int sinus_index = 1; + int sine_wave_index = 1; config.cor_am = INITIAL_MODULATION_CORRECTION; // Initialize with some spare modulation_steps = MAX_MODULATION_STEPS; // Search modulation steps that fit frequency //modulation_steps = 8; // <-----------------TEMP!!!!! while ( ((modulation_delay = (8000000/ modulation_steps ) / setting.modulation_frequency + config.cor_am)) < 100 && modulation_steps > 4) { - sinus_index <<= 1; + sine_wave_index <<= 1; modulation_steps >>= 1; } if (modulation_steps > 8) { for (int i = 0; i < modulation_steps/4+1; i++) { - fm_modulation[i] = setting.modulation_deviation_div100 * sinus[i*sinus_index]/100; + fm_modulation[i] = setting.modulation_deviation_div100 * sine_wave[i*sine_wave_index]/100; fm_modulation[modulation_steps/2 - i] = fm_modulation[i]; fm_modulation[modulation_steps/2 + i] = -fm_modulation[i]; fm_modulation[modulation_steps - i] = -fm_modulation[i]; diff --git a/ui.c b/ui.c index 4a929f3..0bd033d 100644 --- a/ui.c +++ b/ui.c @@ -1067,7 +1067,7 @@ const uint8_t right_icons [] = _BMP16(0b0111111111111111), _BMP16(0b0000000000000000), -#define I_SINUS 3 +#define I_SINE 3 _BMP16(0b0000000000000000), _BMP16(0b0111111111111111), // 1 _BMP16(0b0100000000000001), // 2 @@ -2208,7 +2208,7 @@ static UI_FUNCTION_ADV_CALLBACK(menu_lowoutput_settings_acb) if (data == 255) { plot_printf(mode_string, sizeof mode_string, "%s %s %s %s", (!force_signal_path ? "" : path_text[test_path]), - (get_sweep_frequency(ST_START) < MINIMUM_DIRECT_FREQ ? "SINUS" : "" ), + (get_sweep_frequency(ST_START) < MINIMUM_DIRECT_FREQ ? "SINE" : "" ), (get_sweep_frequency(ST_STOP) >= MINIMUM_DIRECT_FREQ ? "SQUARE WAVE" : ""), (get_sweep_frequency(ST_STOP) > MAX_LOW_OUTPUT_FREQ && setting.mixer_output ? "MIXER" : "")); b->param_1.text = mode_string; @@ -2647,8 +2647,29 @@ static UI_FUNCTION_ADV_CALLBACK(menu_measure_acb) } kp_help_text = "Frequency of fundamental"; ui_mode_keypad(KM_CENTER); - set_sweep_frequency(ST_START, 0); - set_sweep_frequency(ST_STOP, uistat.value*(MARKERS_MAX+1)); + freq_t fundamental = uistat.value; +#ifdef __BANDS__ + kp_help_text = "Span (0=full span)"; + ui_mode_keypad(KM_CENTER); + freq_t half_span = uistat.value/2; + if (half_span > fundamental/2) + half_span = fundamental/2; + if (half_span != 0) { + for (int i = 0; i< BANDS_MAX; i++) { + setting.bands[i].start = fundamental*(i+1) - half_span; + setting.bands[i].end = fundamental*(i+1) + half_span; + setting.bands[i].enabled = true; + } + setting.multi_band = true; + setting.multi_trace = false; + update_bands(); + } + else +#endif + { + set_sweep_frequency(ST_START, 0); + set_sweep_frequency(ST_STOP, fundamental*(MARKERS_MAX+1)); + } set_average(0,AV_4); // set_measurement(M_IMD); break; @@ -4201,7 +4222,7 @@ static const menuitem_t menu_band_modify[] = static const menuitem_t menu_band_select[] = { { MT_ADV_CALLBACK | MT_REPEATS, DATA_STARTS_REPEATS(0,BANDS_MAX), MT_CUSTOM_LABEL, menu_band_select_acb }, - { MT_ADV_CALLBACK, 0 , "MULTI\nTRACE", menu_multi_trace_acb }, + { MT_ADV_CALLBACK, 0 , "ALTERNATE", menu_multi_trace_acb }, #ifdef __USE_SD_CARD__ { MT_CALLBACK, FMT_BND_FILE, "BANDS"S_RARROW"\nSD", menu_sdcard_cb}, #ifdef __SD_FILE_BROWSER__ @@ -4836,7 +4857,7 @@ static const menuitem_t menu_storage[] = { const menuitem_t menu_mode[] = { // { MT_FORM | MT_TITLE, 0, "tinySA MODE", NULL}, { MT_FORM | MT_ADV_CALLBACK | MT_ICON, I_LOW_INPUT+I_SA, "Spectrum Analyzer", menu_mode_acb}, - { MT_FORM | MT_ADV_CALLBACK | MT_ICON, I_LOW_OUTPUT+I_SINUS, "Signal Generator", menu_mode_acb}, + { MT_FORM | MT_ADV_CALLBACK | MT_ICON, I_LOW_OUTPUT+I_SINE, "Signal Generator", menu_mode_acb}, // { MT_FORM | MT_ADV_CALLBACK | MT_ICON, I_HIGH_OUTPUT+I_GEN, "%s to HIGH out", menu_mode_acb}, { MT_FORM | MT_ADV_CALLBACK | MT_ICON, I_CONNECT+I_GEN, "Calibration Output: %s", menu_sreffer_acb}, { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel @@ -4846,7 +4867,7 @@ const menuitem_t menu_mode[] = { // { MT_FORM | MT_TITLE, 0, "tinySA MODE", NULL}, { MT_FORM | MT_ADV_CALLBACK | MT_ICON, I_LOW_INPUT+I_SA, "%s to LOW in", menu_mode_acb}, { MT_FORM | MT_ADV_CALLBACK | MT_ICON, I_HIGH_INPUT+I_SA, "%s to HIGH in", menu_mode_acb}, - { MT_FORM | MT_ADV_CALLBACK | MT_ICON, I_LOW_OUTPUT+I_SINUS, "%s to LOW out", menu_mode_acb}, + { MT_FORM | MT_ADV_CALLBACK | MT_ICON, I_LOW_OUTPUT+I_SINE, "%s to LOW out", menu_mode_acb}, { MT_FORM | MT_ADV_CALLBACK | MT_ICON, I_HIGH_OUTPUT+I_GEN, "%s to HIGH out", menu_mode_acb}, { MT_FORM | MT_ADV_CALLBACK | MT_ICON, I_CONNECT+I_GEN, "Cal. output: %s", menu_sreffer_acb}, // { MT_SUBMENU, 0, "EXPERT\nCONFIG", menu_settings3},