From 894a149025fadadb36c77f847fc0a3b49c9f9bd8 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Sun, 10 Jan 2021 09:00:50 +0100 Subject: [PATCH] Spur reduce updates and much more --- main.c | 1 + nanovna.h | 5 ++-- radio_config_Si4468_850kHz.h | 22 +++++++-------- sa_core.c | 55 +++++++++++++++++++++--------------- si4432.c | 16 ++++++++--- ui_sa.c | 8 ++++-- 6 files changed, 64 insertions(+), 43 deletions(-) diff --git a/main.c b/main.c index 9fdee20..acd3513 100644 --- a/main.c +++ b/main.c @@ -886,6 +886,7 @@ config_t config = { .vbat_offset = 500, #ifdef TINYSA4 .frequency_IF2 = 0, + .lpf_switch = 600000000, #endif .low_level_offset = 100, // Uncalibrated .high_level_offset = 100, // Uncalibrated diff --git a/nanovna.h b/nanovna.h index a369c60..61f22ef 100644 --- a/nanovna.h +++ b/nanovna.h @@ -377,9 +377,9 @@ extern uint16_t graph_bottom; // Menu Button // Maximum menu buttons count -#define MENU_BUTTON_MAX 8 +#define MENU_BUTTON_MAX 9 #define MENU_BUTTON_WIDTH 80 -#define MENU_BUTTON_HEIGHT (LCD_HEIGHT/8-1) +#define MENU_BUTTON_HEIGHT (LCD_HEIGHT/9-1) #define MENU_BUTTON_BORDER 1 #define KEYBOARD_BUTTON_BORDER 2 #define FORM_BUTTON_BORDER 2 @@ -531,6 +531,7 @@ typedef struct config { uint16_t hambands; #ifdef TINYSA4 uint32_t frequency_IF2; + uint32_t lpf_switch; #endif int8_t _mode; int8_t cor_am; diff --git a/radio_config_Si4468_850kHz.h b/radio_config_Si4468_850kHz.h index 7cd4f70..b4ba52e 100644 --- a/radio_config_Si4468_850kHz.h +++ b/radio_config_Si4468_850kHz.h @@ -20,14 +20,14 @@ // INPUT DATA /* // Crys_freq(Hz): 30000000 Crys_tol(ppm): 0 IF_mode: 2 High_perf_Ch_Fil: 1 OSRtune: 0 Ch_Fil_Bw_AFC: 0 ANT_DIV: 0 PM_pattern: 0 -// MOD_type: 2 Rsymb(sps): 400000 Fdev(Hz): 200000 RXBW(Hz): 850000 Manchester: 0 AFC_en: 0 Rsymb_error: 0.0 Chip-Version: 2 +// MOD_type: 2 Rsymb(sps): 500000 Fdev(Hz): 300000 RXBW(Hz): 850000 Manchester: 0 AFC_en: 0 Rsymb_error: 0.0 Chip-Version: 2 // RF Freq.(MHz): 977 API_TC: 29 fhst: 250000 inputBW: 1 BERT: 1 RAW_dout: 0 D_source: 1 Hi_pfm_div: 1 // API_ARR_Det_en: 0 Fdev_error: 0 API_ETSI: 2 // // # RX IF frequency is -468750 Hz // # WB filter 1 (BW = 915.70 kHz); NB-filter 1 (BW = 915.70 kHz) // -// Modulation index: 1 +// Modulation index: 1.2 */ @@ -507,7 +507,7 @@ // MODEM_FREQ_DEV_2 - 17-bit unsigned TX frequency deviation word. // MODEM_FREQ_DEV_1 - 17-bit unsigned TX frequency deviation word. */ -#define RF_MODEM_MOD_TYPE_12_1 0x11, 0x20, 0x0C, 0x00, 0x0A, 0x00, 0x07, 0x3D, 0x09, 0x00, 0x01, 0xC9, 0xC3, 0x80, 0x00, 0x1B +#define RF_MODEM_MOD_TYPE_12_1 0x11, 0x20, 0x0C, 0x00, 0x0A, 0x00, 0x07, 0x4C, 0x4B, 0x40, 0x01, 0xC9, 0xC3, 0x80, 0x00, 0x28 /* // Set properties: RF_MODEM_FREQ_DEV_0_1_1 @@ -518,7 +518,7 @@ // Descriptions: // MODEM_FREQ_DEV_0 - 17-bit unsigned TX frequency deviation word. */ -#define RF_MODEM_FREQ_DEV_0_1_1 0x11, 0x20, 0x01, 0x0C, 0x4F +#define RF_MODEM_FREQ_DEV_0_1_1 0x11, 0x20, 0x01, 0x0C, 0xF6 /* // Set properties: RF_MODEM_TX_RAMP_DELAY_12_1 @@ -540,7 +540,7 @@ // MODEM_BCR_OSR_1 - RX BCR/Slicer oversampling rate (12-bit unsigned number). // MODEM_BCR_OSR_0 - RX BCR/Slicer oversampling rate (12-bit unsigned number). */ -#define RF_MODEM_TX_RAMP_DELAY_12_1 0x11, 0x20, 0x0C, 0x18, 0x01, 0x00, 0x0A, 0x03, 0xC0, 0x00, 0x00, 0x30, 0x00, 0xF9, 0x00, 0x4B +#define RF_MODEM_TX_RAMP_DELAY_12_1 0x11, 0x20, 0x0C, 0x18, 0x01, 0x00, 0x0A, 0x03, 0xC0, 0x00, 0x00, 0x30, 0x00, 0xF9, 0x00, 0x3C /* // Set properties: RF_MODEM_BCR_NCO_OFFSET_2_12_1 @@ -562,7 +562,7 @@ // MODEM_AFC_GAIN_1 - Sets the gain of the PLL-based AFC acquisition loop, and provides miscellaneous control bits for AFC functionality. // MODEM_AFC_GAIN_0 - Sets the gain of the PLL-based AFC acquisition loop, and provides miscellaneous control bits for AFC functionality. */ -#define RF_MODEM_BCR_NCO_OFFSET_2_12_1 0x11, 0x20, 0x0C, 0x24, 0x06, 0xD3, 0xA0, 0x06, 0xD4, 0x02, 0xC0, 0x08, 0x00, 0x23, 0x0D, 0xA7 +#define RF_MODEM_BCR_NCO_OFFSET_2_12_1 0x11, 0x20, 0x0C, 0x24, 0x08, 0x88, 0x89, 0x07, 0x1C, 0x02, 0xC0, 0x08, 0x00, 0x23, 0x08, 0x89 /* // Set properties: RF_MODEM_AFC_LIMITER_1_3_1 @@ -575,7 +575,7 @@ // MODEM_AFC_LIMITER_0 - Set the AFC limiter value. // MODEM_AFC_MISC - Specifies miscellaneous AFC control bits. */ -#define RF_MODEM_AFC_LIMITER_1_3_1 0x11, 0x20, 0x03, 0x30, 0x00, 0xEA, 0xA0 +#define RF_MODEM_AFC_LIMITER_1_3_1 0x11, 0x20, 0x03, 0x30, 0x01, 0x77, 0xA0 /* // Set properties: RF_MODEM_AGC_CONTROL_1_1 @@ -608,7 +608,7 @@ // MODEM_OOK_CNT1 - OOK control. // MODEM_OOK_MISC - Selects the detector(s) used for demodulation of an OOK signal, or for demodulation of a (G)FSK signal when using the asynchronous demodulator. */ -#define RF_MODEM_AGC_WINDOW_SIZE_12_1 0x11, 0x20, 0x0C, 0x38, 0x22, 0x08, 0x08, 0x80, 0x02, 0x40, 0x00, 0x00, 0x28, 0x0C, 0xA4, 0x23 +#define RF_MODEM_AGC_WINDOW_SIZE_12_1 0x11, 0x20, 0x0C, 0x38, 0x22, 0x07, 0x07, 0x80, 0x02, 0x4C, 0xCD, 0x00, 0x27, 0x0C, 0xA4, 0x23 /* // Set properties: RF_MODEM_RAW_CONTROL_10 @@ -628,7 +628,7 @@ // MODEM_RSSI_CONTROL2 - RSSI Jump Detection control. // MODEM_RSSI_COMP - RSSI compensation value. */ -#define RF_MODEM_RAW_CONTROL_10 0x11, 0x20, 0x0A, 0x45, 0x03, 0x01, 0xAA, 0x01, 0x00, 0xFF, 0x08, 0x00, 0x10, 0x40 +#define RF_MODEM_RAW_CONTROL_10 0x11, 0x20, 0x0A, 0x45, 0x03, 0x02, 0x7F, 0x01, 0x00, 0xFF, 0x08, 0x00, 0x10, 0x40 /* // Set properties: RF_MODEM_RAW_SEARCH2_2_1 @@ -652,7 +652,7 @@ // MODEM_SPIKE_DET - Configures the threshold for (G)FSK Spike Detection. // MODEM_ONE_SHOT_AFC - Configures parameters for th e One Shot AFC function and for BCR timing/acquisition. */ -#define RF_MODEM_SPIKE_DET_2_1 0x11, 0x20, 0x02, 0x54, 0x05, 0x07 +#define RF_MODEM_SPIKE_DET_2_1 0x11, 0x20, 0x02, 0x54, 0x08, 0x07 /* // Set properties: RF_MODEM_RSSI_MUTE_1_1 @@ -678,7 +678,7 @@ // MODEM_DSA_RSSI - Signal Arrival Detect RSSI Qualifier Config // MODEM_DSA_MISC - Miscellaneous detection of signal arrival bits. */ -#define RF_MODEM_DSA_CTRL1_5_1 0x11, 0x20, 0x05, 0x5B, 0x40, 0x04, 0x0C, 0x78, 0x20 +#define RF_MODEM_DSA_CTRL1_5_1 0x11, 0x20, 0x05, 0x5B, 0x40, 0x04, 0x13, 0x78, 0x20 /* // Set properties: RF_MODEM_CHFLT_RX1_CHFLT_COE13_7_0_12_1 diff --git a/sa_core.c b/sa_core.c index c4a6e66..308a1c7 100644 --- a/sa_core.c +++ b/sa_core.c @@ -40,7 +40,7 @@ uint16_t actual_rbw_x10 = 0; uint16_t vbwSteps = 1; uint32_t minFreq = 0; uint32_t maxFreq = 520000000; -uint32_t lpf_switch = 800000000; +int spur_gate = 100; uint32_t old_CFGR; uint32_t orig_CFGR; @@ -168,6 +168,7 @@ void reset_settings(int m) setting.auto_attenuation = true; setting.sweep_time_us = 0; setting.lo_drive=1; + setting.extra_lna = false; break; #ifdef __ULTRA__ case M_ULTRA: @@ -184,11 +185,13 @@ void reset_settings(int m) set_sweep_frequency(ST_SPAN, 0); setting.sweep_time_us = 10*ONE_SECOND_TIME; setting.step_delay_mode = SD_FAST; + setting.extra_lna = false; break; case M_HIGH: set_sweep_frequency(ST_START, minFreq); set_sweep_frequency(ST_STOP, maxFreq); setting.sweep_time_us = 0; + setting.extra_lna = false; break; case M_GENHIGH: setting.lo_drive=1; @@ -196,6 +199,7 @@ void reset_settings(int m) set_sweep_frequency(ST_SPAN, 0); setting.sweep_time_us = 10*ONE_SECOND_TIME; setting.step_delay_mode = SD_FAST; + setting.extra_lna = false; break; } for (uint8_t i = 0; i< MARKERS_MAX; i++) { @@ -474,7 +478,7 @@ void set_modulo(uint32_t f) } #endif -#define POWER_STEP 0 // Should be 5 dB but appearently it is lower +#define POWER_STEP 0 // Should be 5 dB but apparently it is lower #define POWER_OFFSET 15 #define SWITCH_ATTENUATION 30 #define RECEIVE_SWITCH_ATTENUATION 21 @@ -1080,14 +1084,14 @@ void calculate_step_delay(void) #endif #endif #ifdef __SI4463__ - if (actual_rbw_x10 >= 8500) { SI4432_step_delay = 350; SI4432_offset_delay = 100; } - else if (actual_rbw_x10 >= 3000) { SI4432_step_delay = 350; SI4432_offset_delay = 100; } - else if (actual_rbw_x10 >= 1000) { SI4432_step_delay = 350; SI4432_offset_delay = 100; } - else if (actual_rbw_x10 >= 300) { SI4432_step_delay = 1000; SI4432_offset_delay = 30; } - else if (actual_rbw_x10 >= 100) { SI4432_step_delay = 1400; SI4432_offset_delay = 500; } - else if (actual_rbw_x10 >= 30) { SI4432_step_delay = 2500; SI4432_offset_delay = 800; } - else if (actual_rbw_x10 >= 10) { SI4432_step_delay = 7000; SI4432_offset_delay = 2500; } - else { SI4432_step_delay = 15000; SI4432_offset_delay =5000; } + if (actual_rbw_x10 >= 8500) { SI4432_step_delay = 400; SI4432_offset_delay = 100; spur_gate = 50; } + else if (actual_rbw_x10 >= 3000) { SI4432_step_delay = 400; SI4432_offset_delay = 100; spur_gate = 50; } + else if (actual_rbw_x10 >= 1000) { SI4432_step_delay = 400; SI4432_offset_delay = 100; spur_gate = 70; } + else if (actual_rbw_x10 >= 300) { SI4432_step_delay = 1000; SI4432_offset_delay = 30; spur_gate = 80; } + else if (actual_rbw_x10 >= 100) { SI4432_step_delay = 1400; SI4432_offset_delay = 500; spur_gate = 80; } + else if (actual_rbw_x10 >= 30) { SI4432_step_delay = 2500; SI4432_offset_delay = 800; spur_gate = 80; } + else if (actual_rbw_x10 >= 10) { SI4432_step_delay = 7000; SI4432_offset_delay = 2500; spur_gate = 80; } + else { SI4432_step_delay = 15000; SI4432_offset_delay =5000; spur_gate = 80; } #endif if (setting.step_delay_mode == SD_PRECISE) // In precise mode wait twice as long for RSSI to stabalize SI4432_step_delay += (SI4432_step_delay>>2) ; @@ -1633,12 +1637,14 @@ void update_rbw(void) // calculate the actual_rbw and the vbwSteps (# } } +#define frequency_seatch_gate 60 // 120% of the RBW + int binary_search_frequency(int f) // Search which index in the frequency tabled matches with frequency f using actual_rbw { int L = 0; int R = (sizeof frequencies)/sizeof(int) - 1; - int fmin = f - actual_rbw_x10 * 100; - int fplus = f + actual_rbw_x10 * 100; + int fmin = f - actual_rbw_x10 * frequency_seatch_gate; + int fplus = f + actual_rbw_x10 * frequency_seatch_gate; while (L <= R) { int m = (L + R) / 2; if ((int)frequencies[m] < fmin) @@ -1744,9 +1750,9 @@ static const int spur_table[] = // Frequencies t 243781200, 244250000, 325666667, - 487542300, // This is linked to the MODULO of the ADF4350 - 487993000, - 488020700, + 487541650, // This is linked to the MODULO of the ADF4350 +// 487993000, +// 488020700, // 487551700, // 487578000, // 488500000, @@ -1806,8 +1812,8 @@ int binary_search(int f) { int L = 0; int R = (sizeof spur_table)/sizeof(int) - 1; - int fmin = f - actual_rbw_x10 * (100); - int fplus = f + actual_rbw_x10 * (100); + int fmin = f - actual_rbw_x10 * spur_gate; + int fplus = f + actual_rbw_x10 * spur_gate; while (L <= R) { int m = (L + R) / 2; if (spur_table[m] < fmin) @@ -2040,16 +2046,17 @@ modulation_again: } // -------------- set ultra --------------------------------- if (setting.mode == M_LOW && config.ultra) { - if ((S_IS_AUTO(setting.ultra)&& f > lpf_switch) || S_STATE(setting.ultra) ) { + if ((S_IS_AUTO(setting.ultra)&& f > config.lpf_switch) || S_STATE(setting.ultra) ) { enable_ultra(true); } else enable_ultra(false); } // -------------------------------- Acquisition loop for one requested frequency covering spur avoidance and vbwsteps ------------------------ pureRSSI_t RSSI = float_TO_PURE_RSSI(-150); -//#define __DEBUG_SPUR__ +#define __DEBUG_SPUR__ #ifdef __DEBUG_SPUR__ // For debugging the spur avoidance control - stored_t[i] = -90.0; // Display when to do spur shift in the stored trace + if (!setting.auto_IF) + stored_t[i] = -90.0; // Display when to do spur shift in the stored trace #endif int t = 0; do { @@ -2095,14 +2102,16 @@ modulation_again: #endif } else { if(!in_selftest && avoid_spur(lf)) { // check if alternate IF is needed to avoid spur. - local_IF = spur_alternate_IF; + if (setting.auto_IF) + local_IF = spur_alternate_IF; #ifdef __DEBUG_SPUR__ // For debugging the spur avoidance control - stored_t[i] = -60.0; // Display when to do spur shift in the stored trace + else + stored_t[i] = -60.0; // Display when to do spur shift in the stored trace #endif } #ifdef __SI4468__ if (S_IS_AUTO(setting.spur_removal)) { - if (lf >= lpf_switch) { + if (lf >= config.lpf_switch) { setting.spur_removal= S_AUTO_ON; } else { setting.spur_removal= S_AUTO_OFF; diff --git a/si4432.c b/si4432.c index 88d2f91..5912cd7 100644 --- a/si4432.c +++ b/si4432.c @@ -996,7 +996,7 @@ int ADF4351_frequency_changed = false; #define DEBUGLN(X) #ifdef TINYSA4_PROTO -#define XTAL 30000000 +#define XTAL 29999960 #else #define XTAL 26000000 #endif @@ -2375,7 +2375,7 @@ void SI4463_set_freq(uint32_t freq) if (SI4463_band == -1) return; //#ifdef TINYSA4_PROTO -#define freq_xco 30000000 +#define freq_xco 29999960 //#else //#define freq_xco 26000000 //#endif @@ -2384,7 +2384,7 @@ void SI4463_set_freq(uint32_t freq) SI4463_offset_active = false; } int32_t R = (freq * SI4463_outdiv) / (Npresc ? 2*freq_xco : 4*freq_xco) - 1; // R between 0x00 and 0x7f (127) - int64_t MOD = 524288; + int64_t MOD = 524288; // = 2^19 int32_t F = ((freq * SI4463_outdiv*MOD) / (Npresc ? 2*freq_xco : 4*freq_xco)) - R*MOD; uint32_t actual_freq = (R*MOD + F) * (Npresc ? 2*freq_xco : 4*freq_xco)/ SI4463_outdiv/MOD; int delta = freq - actual_freq; @@ -2429,6 +2429,14 @@ void SI4463_set_freq(uint32_t freq) // SI4463_set_gpio(3,GPIO_LOW); return; } +#if 0 + static int old_R = -1; // What about TX/RX switching? + static int old_F = -1; + if (old_R == R || old_F == F) + return; + old_R = R; + old_F = f; +#endif refresh_count=0; SI4463_set_state(SI446X_STATE_READY); my_deleted_delay(100); @@ -2476,7 +2484,7 @@ void SI4463_set_freq(uint32_t freq) // #define RF_MODEM_CLKGEN_BAND_1 0x11, 0x20, 0x01, 0x51, 0x0A uint8_t data2[] = { 0x11, 0x20, 0x01, 0x51, - /* 0x10 + */ (uint8_t)(SI4463_band + (Npresc ? 0x08 : 0)) // 0x08 for high performance mode, 0x10 to skip recal + 0x10 + (uint8_t)(SI4463_band + (Npresc ? 0x08 : 0)) // 0x08 for high performance mode, 0x10 to skip recal }; SI4463_do_api(data2, sizeof(data2), NULL, 0); // my_microsecond_delay(30000); diff --git a/ui_sa.c b/ui_sa.c index fa322e4..77c502f 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -1143,7 +1143,7 @@ static UI_FUNCTION_CALLBACK(menu_marker_delete_cb) } } -static const uint16_t rbwsel_x10[]={0,3,10,30,100,300,1000,3000}; +static const uint16_t rbwsel_x10[]={0,3,10,30,100,300,1000,3000,9000}; static UI_FUNCTION_ADV_CALLBACK(menu_rbw_acb) { (void)item; @@ -1588,6 +1588,7 @@ static const menuitem_t menu_rbw[] = { { MT_ADV_CALLBACK, 5, "%4.1qHz", menu_rbw_acb}, { MT_ADV_CALLBACK, 6, "%4.1qHz", menu_rbw_acb}, { MT_ADV_CALLBACK, 7, "%3.1qHz", menu_rbw_acb}, + { MT_ADV_CALLBACK, 8, "%3.1qHz", menu_rbw_acb}, { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; @@ -2178,7 +2179,7 @@ static void fetch_numeric_target(void) break; #endif case KM_LPF: - uistat.value = lpf_switch; + uistat.value = config.lpf_switch; plot_printf(uistat.text, sizeof uistat.text, "%3.6fMHz", uistat.value / 1000000.0); break; case KM_NOISE: @@ -2314,7 +2315,8 @@ set_numeric_value(void) break; #endif case KM_LPF: - lpf_switch = uistat.value; + config.lpf_switch = uistat.value; + config_save(); break; case KM_NOISE: set_noise(uistat.value);