From e32c48ca84e5704e61ee4e35b18352cf2c9c90ea Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Thu, 25 Mar 2021 13:53:24 +0100 Subject: [PATCH] Vaals update --- sa_core.c | 98 ++++++++++++++++++++++++++++++++++++++----------------- si4468.c | 49 ++++++++++++++++++++-------- ui_sa.c | 32 +++++++++++++++++- 3 files changed, 134 insertions(+), 45 deletions(-) diff --git a/sa_core.c b/sa_core.c index 21c1ed1..fd93174 100644 --- a/sa_core.c +++ b/sa_core.c @@ -46,9 +46,10 @@ uint16_t vbwSteps = 1; freq_t minFreq = 0; freq_t maxFreq = 520000000; static float old_a = -150; // cached value to reduce writes to level registers +int spur_gate = 100; #ifdef TINYSA4 -int spur_gate = 100; +int noise_level; uint32_t old_CFGR; uint32_t orig_CFGR; @@ -498,6 +499,13 @@ void toggle_tracking_output(void) void toggle_debug_avoid(void) { debug_avoid = !debug_avoid; + if (debug_avoid) { + setting.show_stored = true; + trace[TRACE_STORED].enabled = true; + } else { + setting.show_stored = false; + trace[TRACE_STORED].enabled = false; + } dirty = true; } @@ -1318,16 +1326,17 @@ static const struct { uint16_t step_delay; uint16_t offset_delay; uint16_t spur_div_1000; + int16_t noise_level; } step_delay_table[]={ // RBWx10 step_delay offset_delay spur_gate (value divided by 1000) - { 6000, 50, 50, 400}, - { 3000, 100, 50, 200}, - { 1000, 400, 100, 100}, - { 300, 400, 120, 100}, - { 100, 700, 120, 100}, - { 30, 900, 300, 100}, - { 10, 4000, 600, 100}, - { 0, 9000, 3000, 100} + { 6000, 200, 50, 400, -85}, + { 3000, 200, 50, 200, -95}, + { 1000, 400, 100, 100, -100}, + { 300, 400, 120, 100, -105}, + { 100, 700, 120, 100, -110}, + { 30, 900, 300, 100, -115}, + { 10, 4000, 600, 100, -120}, + { 0, 9000, 3000, 100, -125} }; #endif @@ -1352,11 +1361,13 @@ static void calculate_step_delay(void) #ifdef __SI4432__ SI4432_step_delay = step_delay_table[i].step_delay; SI4432_offset_delay = step_delay_table[i].offset_delay; + spur_gate = actual_rbw_x10 * (100 / 2); #endif #ifdef __SI4463__ SI4432_step_delay = step_delay_table[i].step_delay; SI4432_offset_delay = step_delay_table[i].offset_delay; spur_gate = step_delay_table[i].spur_div_1000 * 1000; + noise_level = step_delay_table[i].noise_level; #endif if (setting.step_delay_mode == SD_PRECISE) // In precise mode wait twice as long for RSSI to stabilize SI4432_step_delay += (SI4432_step_delay>>2) ; @@ -1427,6 +1438,7 @@ pureRSSI_t get_frequency_correction(freq_t f) // Frequency dependent RSSI c if (setting.mode == M_GENHIGH) return(0.0); #ifdef TINYSA4 +#if 0 if (setting.extra_lna) { if (f > 2100000000U) { cv += float_TO_PURE_RSSI(+13); @@ -1438,6 +1450,7 @@ pureRSSI_t get_frequency_correction(freq_t f) // Frequency dependent RSSI c if (f > ULTRA_MAX_FREQ) { cv += float_TO_PURE_RSSI(+4); // 4dB loss in harmonic mode } +#endif #endif int i = 0; while (f > setting.correction_frequency[i] && i < CORRECTION_POINTS) @@ -2098,10 +2111,9 @@ int binary_search(freq_t f) { int L = 0; int R = (sizeof spur_table)/sizeof(int) - 1; -#ifdef TINYSA4 freq_t fmin = f - spur_gate; freq_t fplus = f + spur_gate; -#else +#if 0 freq_t fmin = f - actual_rbw_x10 * (100 / 2); freq_t fplus = f + actual_rbw_x10 * (100 / 2); #endif @@ -2345,6 +2357,8 @@ pureRSSI_t perform(bool break_on_operation, int i, freq_t f, int tracking) / } } + // --------------------------------- Pulse at start of low output sweep -------------------------- + #ifdef __SI4432__ if (setting.mode == M_GENLOW && ( setting.frequency_step != 0 || setting.level_sweep != 0.0)) {// pulse high out SI4432_Sel = SI4432_LO ; @@ -2357,6 +2371,9 @@ pureRSSI_t perform(bool break_on_operation, int i, freq_t f, int tracking) / } } #endif + + // ------------------------------------- Set the output level ---------------------------------- + if (( setting.frequency_step != 0 || setting.level_sweep != 0.0 || i == 0)) { // Initialize or adapt output levels if (setting.mode == M_GENLOW) {// if in low output mode and level sweep or frequency weep is active or at start of sweep float ls=setting.level_sweep; // calculate and set the output level @@ -2469,6 +2486,9 @@ pureRSSI_t perform(bool break_on_operation, int i, freq_t f, int tracking) / if (setting.frequency_step != 0) correct_RSSI_freq = get_frequency_correction(f); } + + // ----------------------------- Initiate modulation --------------------------- + int *current_fm_modulation = 0; if (MODE_OUTPUT(setting.mode)) { if (setting.modulation != MO_NONE && setting.modulation != MO_EXTERNAL && setting.modulation_frequency != 0) { @@ -2503,7 +2523,7 @@ pureRSSI_t perform(bool break_on_operation, int i, freq_t f, int tracking) / } } modulation_again: - // ----------------------------------------------------- modulation for output modes --------------------------------------- + // ----------------------------------------------------- apply modulation for output modes --------------------------------------- if (MODE_OUTPUT(setting.mode)){ if (setting.modulation == MO_AM) { // AM modulation int p = setting.attenuate_x2 + am_modulation[modulation_counter]; @@ -2525,7 +2545,7 @@ modulation_again: #endif } modulation_counter++; - if (modulation_counter == MODULATION_STEPS) // 3dB modulation depth + if (modulation_counter == MODULATION_STEPS) modulation_counter = 0; if (setting.modulation != MO_NONE && setting.modulation != MO_EXTERNAL) { my_microsecond_delay(modulation_delay); @@ -2579,7 +2599,7 @@ modulation_again: freq_t local_IF; #ifdef __SPUR__ spur_second_pass = false; - again: // Spur reduction jumps to here for second measurement +again: // Spur reduction jumps to here for second measurement #endif local_IF=0; // to get rid of warning @@ -2650,7 +2670,7 @@ modulation_again: ) { // below/above IF #ifdef TINYSA4 - local_IF = local_IF + DEFAULT_SPUR_OFFSET/2; // center IF + local_IF = local_IF; // + DEFAULT_SPUR_OFFSET/2; // center IF #endif if (spur_second_pass) setting.below_IF = S_AUTO_ON; @@ -2686,7 +2706,7 @@ modulation_again: } else { - local_IF = local_IF + DEFAULT_SPUR_OFFSET/2; // No spure removal and no spur, center in IF + local_IF = local_IF; // + DEFAULT_SPUR_OFFSET/2; // No spure removal and no spur, center in IF } #endif } @@ -2734,9 +2754,12 @@ modulation_again: #define TXCO_DIV3 10000000 if (setting.R == 0) { - if (actual_rbw_x10 >= 3000) + if (actual_rbw_x10 >= 3000) { + if (ADF4350_modulo == 0) ADF4351_modulo(1000); ADF4351_R_counter(1); - else if (lf < LOW_MAX_FREQ && lf >= TXCO_DIV3 && MODE_INPUT(setting.mode)) { + + } else if (lf < LOW_MAX_FREQ && lf >= TXCO_DIV3 && MODE_INPUT(setting.mode)) { + if (ADF4350_modulo == 0) ADF4351_modulo(60); freq_t tf = ((lf + actual_rbw_x10*1000) / TCXO) * TCXO; if (tf + actual_rbw_x10*100 >= lf && tf < lf + actual_rbw_x10*100) { // 30MHz ADF4351_R_counter(6); @@ -2750,15 +2773,17 @@ modulation_again: } else ADF4351_R_counter(1); } - } else + } else { + if (ADF4350_modulo == 0) ADF4351_modulo(60); if (setting.frequency_step < 100000) ADF4351_R_counter(3); else ADF4351_R_counter(1); + } } - else + else { ADF4351_R_counter(setting.R); - + } #endif // __ADF4351__ #if 0 freq_t target_f; @@ -2776,9 +2801,11 @@ modulation_again: } set_freq(ADF4351_LO, target_f); #if 1 // Compensate frequency ADF4350 error with SI4468 + if (actual_rbw_x10 < 3000 || setting.frequency_step < 100000) { int32_t error_f = 0; if (real_old_freq[ADF4351_LO] > target_f) { error_f = real_old_freq[ADF4351_LO] - target_f; + if (inverted_f) { error_f = -error_f; goto correct_min; @@ -2802,6 +2829,7 @@ modulation_again: // if ( error_f < - actual_rbw_x10 * 5) //RBW / 4 local_IF += error_f; } + } #endif } else if (setting.mode == M_HIGH) { set_freq (SI4463_RX, lf); // sweep RX, local_IF = 0 in high mode @@ -3026,7 +3054,7 @@ modulation_again: int my_step_delay = SI4432_step_delay; if (f < 2000000 && actual_rbw_x10 == 3) my_step_delay = my_step_delay * 2; - if (SI4463_offset_changed) + if (LO_shifted) // || SI4463_offset_changed) my_step_delay = my_step_delay * 2; my_microsecond_delay(my_step_delay * ((setting.R == 0 && old_R > 5 ) ? 8 : 1)); ADF4351_frequency_changed = false; @@ -3182,7 +3210,7 @@ sweep_again: // stay in sweep loop when output mo if (refreshing) scandirty = false; if (break_on_operation && operation_requested) { // break loop if needed - if (setting.actual_sweep_time_us > ONE_SECOND_TIME && MODE_INPUT(setting.mode)) { + if (setting.actual_sweep_time_us > ONE_SECOND_TIME /* && MODE_INPUT(setting.mode) */) { ili9341_set_background(LCD_BG_COLOR); ili9341_fill(OFFSETX, CHART_BOTTOM+1, WIDTH, 1); // Erase progress bar } @@ -3224,7 +3252,8 @@ sweep_again: // stay in sweep loop when output mo } } - if (MODE_INPUT(setting.mode)) { + //if (MODE_INPUT(setting.mode)) + { #ifdef TINYSA4 if ((i & 0x07) == 0 && (setting.actual_sweep_time_us > ONE_SECOND_TIME || (chVTGetSystemTimeX() - start_of_sweep_timestamp) > ONE_SECOND_TIME / 100)) { // if required #else @@ -3369,7 +3398,7 @@ sweep_again: // stay in sweep loop when output mo } // scandirty = true; // To show trigger happened } - if (setting.actual_sweep_time_us > ONE_SECOND_TIME && MODE_INPUT(setting.mode)) { + if (setting.actual_sweep_time_us > ONE_SECOND_TIME /* && MODE_INPUT(setting.mode) */) { // ili9341_fill(OFFSETX, CHART_BOTTOM+1, WIDTH, 1, 0); // Erase progress bar before updating actual_sweep_time ili9341_set_background(LCD_BG_COLOR); ili9341_fill(OFFSETX, CHART_BOTTOM+1, WIDTH, 1); @@ -3458,6 +3487,7 @@ sweep_again: // stay in sweep loop when output mo // -------------------------- auto attenuate ---------------------------------- #ifdef TINYSA4 #define AUTO_TARGET_LEVEL (actual_rbw_x10 >= 10 ? -30 : -40) +#define LNA_AUTO_TARGET_LEVEL -45 #else #define AUTO_TARGET_LEVEL -25 #endif @@ -3467,11 +3497,16 @@ sweep_again: // stay in sweep loop when output mo setting.atten_step = false; // No step attenuate in low mode auto attenuate int changed = false; int delta = 0; + int target_level = AUTO_TARGET_LEVEL; +#ifdef TINYSA4 + if (setting.extra_lna) + target_level = LNA_AUTO_TARGET_LEVEL; +#endif int actual_max_level = (max_index[0] == 0 ? -100 :(int) (actual_t[max_index[0]] - get_attenuation()) ) + setting.external_gain; // If no max found reduce attenuation - if (actual_max_level < AUTO_TARGET_LEVEL && setting.attenuate_x2 > 0) { - delta = - (AUTO_TARGET_LEVEL - actual_max_level); - } else if (actual_max_level > AUTO_TARGET_LEVEL && setting.attenuate_x2 < 60) { - delta = actual_max_level - AUTO_TARGET_LEVEL; + if (actual_max_level < target_level && setting.attenuate_x2 > 0) { + delta = - (target_level - actual_max_level); + } else if (actual_max_level > target_level && setting.attenuate_x2 < 60) { + delta = actual_max_level - target_level; } if ((chVTGetSystemTimeX() - sweep_elapsed > 10000 && delta != 0) || delta > 5 ) { setting.attenuate_x2 += delta + delta; @@ -3572,6 +3607,9 @@ sweep_again: // stay in sweep loop when output mo } else { #define MAX_FIT (NGRIDY-1.2) float s_min = value(temp_min_level)/setting.scale; + float noise = (noise_level - setting.external_gain - (setting.extra_lna ? 25 : 0))/setting.scale; + if (s_min < noise) + s_min = noise; float s_ref = setting.reflevel/setting.scale; if (s_max < s_ref - NGRIDY || s_min > s_ref) { //Completely outside if (s_max - s_min < NGRIDY - 2) @@ -4569,7 +4607,7 @@ void self_test(int test) quit: sweep_mode = SWEEP_ENABLE; test_wait = false; - ili9341_clear_screen(); + if (setting.test_argument == 0) ili9341_clear_screen(); #ifdef TINYSA4 config_recall(); config.cor_am = 0; diff --git a/si4468.c b/si4468.c index bb64e12..80bcc39 100644 --- a/si4468.c +++ b/si4468.c @@ -955,11 +955,11 @@ uint64_t PFDRFout[6] = {XTAL,XTAL,XTAL,10000000,10000000,10000000}; //Reference //double FRACF; // Temp volatile int64_t - INTA, // Temp - ADF4350_modulo = 60, // Linked to spur table!!!!! - MOD, - target_freq, - FRAC; //Temp +// INTA, // Temp + ADF4350_modulo = 0, // Linked to spur table!!!!! +// MOD, +// FRAC, //Temp + target_freq; uint8_t OutputDivider; // Temp uint8_t lock=2; //Not used @@ -1207,8 +1207,26 @@ uint64_t ADF4351_prepare_frequency(int channel, uint64_t freq) // freq / 10Hz } +#if 1 + volatile uint32_t PFDR = (uint32_t)PFDRFout[channel]; + uint32_t MOD = ADF4350_modulo; + if (MOD == 0) + MOD = 60; + uint32_t MOD_X2 = MOD<<1; + uint32_t INTA_F = ((freq * (uint64_t)OutputDivider) * (uint64_t)MOD_X2/ PFDR) + 1; + uint32_t INTA = INTA_F / MOD_X2; + uint32_t FRAC = (INTA_F - INTA * MOD_X2)>>1; + if (FRAC >= MOD) { + FRAC -= MOD; + INTA++; + } + + +#else volatile uint64_t PFDR = PFDRFout[channel]; - MOD = ADF4350_modulo; + uint16_t MOD = ADF4350_modulo; + if (MOD == 0) + MOD = 60; uint64_t half_spacing = PFDR / MOD / 2 / OutputDivider; INTA = (((uint64_t)freq + half_spacing) * OutputDivider) / PFDR; uint64_t f_int = INTA *(uint64_t) MOD; @@ -1218,6 +1236,7 @@ uint64_t ADF4351_prepare_frequency(int channel, uint64_t freq) // freq / 10Hz FRAC -= MOD; INTA++; } +#endif #if 0 while (FRAC > 4095 || MOD > 4095) { FRAC = FRAC >> 1; @@ -1234,7 +1253,7 @@ uint64_t ADF4351_prepare_frequency(int channel, uint64_t freq) // freq / 10Hz MOD=2; } #endif - uint64_t actual_freq = (PFDR *(INTA * MOD +FRAC))/OutputDivider / MOD; + uint64_t actual_freq = ((uint64_t)PFDR *(INTA * MOD +FRAC))/OutputDivider / MOD; #if 0 volatile int max_delta = PFDRFout[channel]/OutputDivider/MOD/100; if (actual_freq < freq - max_delta || actual_freq > freq + max_delta ){ @@ -1247,10 +1266,10 @@ uint64_t ADF4351_prepare_frequency(int channel, uint64_t freq) // freq / 10Hz my_microsecond_delay(10); } #endif - if (FRAC >= MOD ){ - while(1) - my_microsecond_delay(10); - } +// if (FRAC >= MOD ){ +// while(1) +// my_microsecond_delay(10); +// } registers[0] = 0; registers[0] = INTA << 15; // OK @@ -2441,10 +2460,11 @@ freq_t SI4463_set_freq(freq_t freq) si_set_offset(0); SI4463_offset_active = false; } - int32_t R = (freq * SI4463_outdiv) / (Npresc ? 2*config.setting_frequency_30mhz : 4*config.setting_frequency_30mhz) - 1; // R between 0x00 and 0x7f (127) - int64_t MOD = 524288; // = 2^19 - int32_t F = ((freq * SI4463_outdiv*MOD) / (Npresc ? 2*config.setting_frequency_30mhz : 4*config.setting_frequency_30mhz)) - R*MOD; + uint32_t R = (freq * SI4463_outdiv) / (Npresc ? 2*config.setting_frequency_30mhz : 4*config.setting_frequency_30mhz) - 1; // R between 0x00 and 0x7f (127) + uint64_t MOD = 524288; // = 2^19 + uint32_t F = ((freq * SI4463_outdiv*MOD) / (Npresc ? 2*config.setting_frequency_30mhz : 4*config.setting_frequency_30mhz)) - R*MOD; freq_t actual_freq = (R*MOD + F) * (Npresc ? 2*config.setting_frequency_30mhz : 4*config.setting_frequency_30mhz)/ SI4463_outdiv/MOD; +#if 0 int delta = freq - actual_freq; if (delta < -100 || delta > 100 ){ while(1) @@ -2454,6 +2474,7 @@ freq_t SI4463_set_freq(freq_t freq) while(1) my_microsecond_delay(10); } +#endif if (false && (SI4463_band == prev_band)) { int vco = 2091 + ((((freq / 4 ) * SI4463_outdiv - 850000000)/1000) * 492) / 200000; diff --git a/ui_sa.c b/ui_sa.c index d74c66b..89633c9 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -881,6 +881,34 @@ static UI_FUNCTION_ADV_CALLBACK(menu_adf_out_acb) ui_mode_normal(); } +static UI_FUNCTION_ADV_CALLBACK(menu_ultra_acb) +{ + (void)data; + (void)item; + if (b){ + b->icon = config.ultra == 0 ? BUTTON_ICON_NOCHECK : BUTTON_ICON_CHECK; + return; + } + if (!config.ultra) { + kp_help_text = "Ultra unlock code"; + ui_mode_keypad(KM_CENTER); + if (uistat.value != 4321) + return; + set_sweep_frequency(ST_START, 0); + set_sweep_frequency(ST_STOP, 3000000000ULL); + + } + config.ultra = !config.ultra; + update_min_max_freq(); + if (config.ultra){ + set_sweep_frequency(ST_START, 0); + set_sweep_frequency(ST_STOP, 3000000000ULL); + } + // menu_move_back(false); + ui_mode_normal(); +} + + static UI_FUNCTION_ADV_CALLBACK(menu_debug_freq_acb) { @@ -1969,6 +1997,7 @@ static const menuitem_t menu_settings3[] = #ifdef TINYSA4 // { MT_KEYPAD, KM_GRIDLINES, "MINIMUM\nGRIDLINES", "Enter minimum horizontal grid divisions"}, { MT_ADV_CALLBACK, 0, "ADF OUT", menu_adf_out_acb}, + { MT_ADV_CALLBACK, 0, "ENABLE\nULTRA", menu_ultra_acb}, { MT_KEYPAD, KM_LPF, "ULTRA\nSTART", "Enter ULTRA mode start freq"}, // { MT_KEYPAD | MT_LOW, KM_IF2, "IF2 FREQ", "Set to zero for no IF2"}, { MT_KEYPAD, KM_R, "R", "Set R"}, @@ -2822,9 +2851,10 @@ redraw_cal_status: #ifdef __SPUR__ if (setting.spur_removal != S_OFF) { if (setting.spur_removal == S_ON) - ili9341_set_foreground(LCD_BRIGHT_COLOR_GREEN); + color = LCD_BRIGHT_COLOR_GREEN; else color = LCD_FG_COLOR; + ili9341_set_foreground(color); ili9341_drawstring("Spur:", x, y); y += YSTEP;