diff --git a/sa_core.c b/sa_core.c index 5a9794f..d27f60b 100644 --- a/sa_core.c +++ b/sa_core.c @@ -156,7 +156,7 @@ void reset_settings(int m) dirty = true; } -uint32_t calc_min_sweep_time_us(void) // Calculate minimum sweep time in uS +uint32_t calc_min_sweep_time_us(void) // Calculate minimum sweep time in uS needed just because of the delays for the RSSI to become stable { float t; float a = (actualStepDelay + MEASURE_TIME); // in uS @@ -221,14 +221,14 @@ void set_level_sweep(float l) dirty = true; } -void set_sweep_time_us(uint32_t t) +void set_sweep_time_us(uint32_t t) // Set the sweep time as the user wants it to be. { if (t < MINIMUM_SWEEP_TIME) t = MINIMUM_SWEEP_TIME; if (t > MAXIMUM_SWEEP_TIME) t = MAXIMUM_SWEEP_TIME; setting.sweep_time_us = t; - uint32_t ta = calc_min_sweep_time_us(); + uint32_t ta = calc_min_sweep_time_us(); // Can not be faster than minimum sweep time if (ta < t) ta = t; setting.actual_sweep_time_us = ta; @@ -330,7 +330,7 @@ float get_attenuation(void) static const int drive_dBm [16] = {-38,-35,-33,-30,-27,-24,-21,-19,-7,-4,-2, 1, 4, 7, 10, 13}; -void set_level(float v) +void set_level(float v) // Set the drive level of the LO { if (setting.mode == M_GENHIGH) { int d = 0; @@ -346,7 +346,7 @@ void set_level(float v) dirty = true; } -void set_attenuation(float a) +void set_attenuation(float a) // Is used both in output mode and input mode { if (setting.mode == M_GENLOW) { a = a + POWER_OFFSET; @@ -439,9 +439,9 @@ void toggle_normalize(void) extern float peakLevel; -void set_actual_power(float o) +void set_actual_power(float o) // Set peak level to known value { - float new_offset = o - peakLevel + get_level_offset(); + float new_offset = o - peakLevel + get_level_offset(); // calculate offset based on difference between measured peak level and known peak level if (o == 100) new_offset = 0; if (setting.mode == M_HIGH) { config.high_level_offset = new_offset; @@ -458,7 +458,7 @@ void set_actual_power(float o) int get_level_offset(void) { if (setting.mode == M_HIGH) { - if (config.high_level_offset == 100) + if (config.high_level_offset == 100) // Offset of 100 means not calibrated return 0; return(config.high_level_offset); } @@ -513,10 +513,10 @@ void set_harmonic(int h) } #endif -void set_step_delay(int d) +void set_step_delay(int d) // override RSSI measurement delay or set to one of three auto modes { - if ((3 <= d && d < 300) || d > 30000) + if ((3 <= d && d < 300) || d > 30000) // values 0 (fast scan), 1 (precise scan) and 2(extra fast scan) have special meaning and are auto calculated return; setting.step_delay = d; dirty = true; @@ -755,7 +755,7 @@ void set_mode(int m) // dirty = true; } -void apply_settings(void) +void apply_settings(void) // Ensure all settings in the setting structure are translated to the right HW setup { set_switches(setting.mode); if (setting.mode == M_HIGH) @@ -767,12 +767,12 @@ void apply_settings(void) } SI4432_SetReference(setting.refer); update_rbw(); - if (setting.frequency_step == 0.0) { + if (setting.frequency_step == 0.0) { // zero span mode, not dependend on selected RBW if (setting.step_delay <= 2) actualStepDelay = 0; else actualStepDelay = setting.step_delay; - } else if (setting.step_delay <= 2){ + } else if (setting.step_delay <= 2){ // Frequency sweep so use RBW to calculate minimum delay when changing frequency if (actual_rbw >= 191.0) actualStepDelay = 280; else if (actual_rbw >= 142.0) actualStepDelay = 350; else if (actual_rbw >= 75.0) actualStepDelay = 450; @@ -782,7 +782,7 @@ void apply_settings(void) else if (actual_rbw >= 9.0) actualStepDelay = 1700; else if (actual_rbw >= 5.0) actualStepDelay = 3300; else actualStepDelay = 6400; - if (setting.step_delay == 1) + if (setting.step_delay == 1) // In precise mode wait twice as long for RSSI to stabalize actualStepDelay *= 2; } else actualStepDelay = setting.step_delay; @@ -799,7 +799,7 @@ static const float correction_value[CORRECTION_POINTS] = { +4.0, +2.0, +1.5, +0.5, 0.0, 0.0, +1.0, +1.0, +2.5, +5.0 }; #endif -float get_frequency_correction(uint32_t f) +float get_frequency_correction(uint32_t f) // Frequency dependent RSSI correction to compensate for imperfect LPF { if (!(setting.mode == M_LOW)) return(0.0); @@ -846,41 +846,42 @@ extern int SI4432_frequency_changed; extern int SI4432_offset_changed; static systime_t set_freq_time; -void set_freq(int V, unsigned long freq) +void set_freq(int V, unsigned long freq) // translate the requested frequency into a setting of the SI4432 { - if (old_freq[V] != freq) { + if (old_freq[V] != freq) { // Do not change HW if not needed if (V <= 1) { SI4432_Sel = V; - if (freq < 240000000 || freq > 960000000) { - real_old_freq[V] = freq + 1; + if (freq < 240000000 || freq > 960000000) { // Impossible frequency, simply ignore, should never happen. + real_old_freq[V] = freq + 1; // No idea why this is done........ return; } #if 1 - if (setting.step_delay == 2) { + if (setting.step_delay == 2) { // If in extra fast scanning mode int delta = freq - real_old_freq[V]; if (real_old_freq[V] >= 480000000) // 480MHz, high band delta = delta >> 1; - if (delta > 0 && delta < 80000) { // use frequency deviation registers + if (delta > 0 && delta < 80000) { // and requested frequency can be reached by using the offset registers +#if 0 if (0) { if (real_old_freq[V] >= 480000000) shell_printf("%d: Offs %q HW %d\r\n", SI4432_Sel, (uint32_t)(real_old_freq[V]+delta*2), real_old_freq[V]); else shell_printf("%d: Offs %q HW %d\r\n", SI4432_Sel, (uint32_t)(real_old_freq[V]+delta*1), real_old_freq[V]); } - - delta = delta * 4 / 625; // = 156.25; +#endif + delta = delta * 4 / 625; // = 156.25; // Calculate and set the offset register i.s.o programming a new frequency SI4432_Write_Byte(0x73, (uint8_t)(delta & 0xff)); SI4432_Write_Byte(0x74, (uint8_t)((delta >> 8) & 0x03)); - SI4432_offset_changed = true; + SI4432_offset_changed = true; // Signal offset changed so RSSI retrieval is delayed for frequency settling old_freq[V] = freq; return; } } #endif set_freq_time = chVTGetSystemTimeX(); - SI4432_Set_Frequency(freq); - SI4432_Write_Byte(0x73, 0); + SI4432_Set_Frequency(freq); // Impossible to use offset so set SI4432 to new frequency + SI4432_Write_Byte(0x73, 0); // set offset to zero SI4432_Write_Byte(0x74, 0); #ifdef __ULTRA_SA__ } else { @@ -928,7 +929,7 @@ case M_ULTRA: #endif SI4432_Sel = 0; SI4432_Receive(); - if (setting.atten_step) { + if (setting.atten_step) { // use switch as attenuator set_switch_transmit(); } else { set_switch_receive(); @@ -953,7 +954,7 @@ mute: SI4432_Sel = 1; SI4432_Receive(); - if (setting.atten_step) { + if (setting.atten_step) {// use switch as attenuator set_switch_transmit(); } else { set_switch_receive(); @@ -965,7 +966,7 @@ case M_GENLOW: // Mixed output from 0 if (setting.mute) goto mute; SI4432_Sel = 0; - if (setting.atten_step) { + if (setting.atten_step) { // use switch as attenuator set_switch_off(); } else { set_switch_transmit(); @@ -990,7 +991,7 @@ case M_GENHIGH: // Direct output from 1 SI4432_Sel = 1; if (setting.drive < 8) { - set_switch_off(); + set_switch_off(); // use switch as attenuator } else { set_switch_transmit(); } @@ -1004,16 +1005,16 @@ case M_GENHIGH: // Direct output from 1 } -void update_rbw(void) +void update_rbw(void) // calculate the actual_rbw and the vbwSteps (# steps in between needed if frequency step is largen than maximum rbw) { if (setting.frequency_step > 0 && MODE_INPUT(setting.mode)) { setting.vbw = (setting.frequency_step)/1000.0; } else { setting.vbw = 300; // trick to get right default rbw in zero span mode } - actual_rbw = setting.rbw; - if (actual_rbw == 0) { - actual_rbw = 2*setting.vbw; + actual_rbw = setting.rbw; // requested rbw + if (actual_rbw == 0) { // if auto rbw + actual_rbw = 2*setting.vbw; // rbw is twice the frequency step to ensure no gaps in coverage } if (actual_rbw < 2.6) actual_rbw = 2.6; @@ -1021,27 +1022,25 @@ void update_rbw(void) actual_rbw = 600; if (setting.spur && actual_rbw > 300) - actual_rbw = 250; + actual_rbw = 250; // if spur suppression reduce max rbw to fit within BPF SI4432_Sel = MODE_SELECT(setting.mode); - actual_rbw = SI4432_SET_RBW(actual_rbw); + actual_rbw = SI4432_SET_RBW(actual_rbw); // see what rbw the SI4432 can realize - if (setting.frequency_step > 0 && MODE_INPUT(setting.mode)) { - if (setting.step_delay==1) // Precise - vbwSteps = ((int)(2 * (setting.vbw + (actual_rbw/2)) / (actual_rbw / 2))); - else - vbwSteps = ((int)(2 * (setting.vbw + (actual_rbw/2)) / actual_rbw)); - - if (vbwSteps < 1) + if (setting.frequency_step > 0 && MODE_INPUT(setting.mode)) { // When doing frequency scanning in input mode + vbwSteps = ((int)(2 * (setting.vbw + (actual_rbw/2)) / actual_rbw)); // calculate # steps in between each frequency step due to rbw being less than frequency step + if (setting.step_delay==1) // if in Precise scanning + vbwSteps *= 2; // use twice as many steps + if (vbwSteps < 1) // at least one step vbwSteps = 1; - } else { + } else { // in all other modes setting.vbw = actual_rbw; - vbwSteps = 1; + vbwSteps = 1; // only one vbwSteps } dirty = true; } -int binary_search_frequency(int f) +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; @@ -1127,9 +1126,9 @@ search_maximum(int m, int center, int span) } //static int spur_old_stepdelay = 0; -static const unsigned int spur_IF = 433800000; -static const unsigned int spur_alternate_IF = 433900000; -static const int spur_table[] = +static const unsigned int spur_IF = 433800000; // The IF frequency for which the spur table is value +static const unsigned int spur_alternate_IF = 433900000; // if the frequency is found in the spur table use this IF frequency +static const int spur_table[] = // Frequencies to avoid { 580000, // 433.8 MHz table 961000, @@ -1204,7 +1203,7 @@ int binary_search(int f) } -int avoid_spur(int f) +int avoid_spur(int f) // find if this frequency should be avoided { // int window = ((int)actual_rbw ) * 1000*2; // if (window < 50000) @@ -1216,26 +1215,26 @@ int avoid_spur(int f) static int modulation_counter = 0; -static const int am_modulation[5] = { 4,0,1,5,7 }; -static const int nfm_modulation[5] = { 0, 2, 1, -1, -2}; -static const int wfm_modulation[5] = { 0, 190, 118, -118, -190 }; +static const int am_modulation[5] = { 4,0,1,5,7 }; // 5 step AM modulation +static const int nfm_modulation[5] = { 0, 2, 1, -1, -2}; // 5 step narrow FM modulation +static const int wfm_modulation[5] = { 0, 190, 118, -118, -190 }; // 5 step wide FM modulation char age[POINTS_COUNT]; static float old_a = -150; -float perform(bool break_on_operation, int i, uint32_t f, int tracking) +float 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 { - if (i == 0 && dirty ) { // SCan initiation - apply_settings(); - scandirty = true; + if (i == 0 && dirty ) { // if first point in scan and dirty + apply_settings(); // Initialize HW + scandirty = true; // This is the first pass with new settings dirty = false; - if (setting.spur) - setting.spur = 1; // resync spur in case of previous abort + if (setting.spur) // if in spur avoidance mode + setting.spur = 1; // resync spur in case of previous abort } - if (setting.mode == M_GENLOW && setting.level_sweep != 0.0) { - float ls=setting.level_sweep; + if (setting.mode == M_GENLOW && setting.level_sweep != 0.0) { // if in low output mode and level sweep is active + float ls=setting.level_sweep; // calculate and set the output level if (ls > 0) ls += 0.5; else @@ -1275,8 +1274,8 @@ float perform(bool break_on_operation, int i, uint32_t f, int tracking) } } - if (setting.mode == M_LOW && S_IS_AUTO(setting.agc) && UNIT_IS_LOG(setting.unit)) { - unsigned char v; + if (setting.mode == M_LOW && S_IS_AUTO(setting.agc) && UNIT_IS_LOG(setting.unit)) { // If in low input mode with auto AGC and log unit + unsigned char v; // Adapt the AGC setting if needed static unsigned char old_v; if (f < 500000) v = 0x50; // Disable AGC and enable LNA @@ -1287,6 +1286,9 @@ float perform(bool break_on_operation, int i, uint32_t f, int tracking) old_v = v; } } + + // ----------------------------------------------------- modulation for output modes --------------------------------------- + if (MODE_OUTPUT(setting.mode) && (setting.modulation == MO_AM_1kHz||setting.modulation == MO_AM_10Hz)) { // AM modulation int p = setting.attenuate * 2 + am_modulation[modulation_counter]; if (p>63) @@ -1325,10 +1327,10 @@ float perform(bool break_on_operation, int i, uint32_t f, int tracking) my_microsecond_delay(200); // chThdSleepMicroseconds(200); } - +// -------------------------------- Acquisition loop for one requested frequency covering spur avoidance and vbwsteps ------------------------ float RSSI = -150.0; int t = 0; - do { // ------------- Acquisition loop ---------- + do { int offs = 0,sm; uint32_t lf = (uint32_t)f; if (vbwSteps > 1) { // Calculate sub steps @@ -1351,13 +1353,13 @@ float perform(bool break_on_operation, int i, uint32_t f, int tracking) #ifdef __SPUR__ float spur_RSSI = 0; #endif + if (MODE_INPUT(setting.mode) && i > 0 && FREQ_IS_CW()) // In input mode in zero span mode after first setting of the LO's + goto skip_LO_setting; // No more LO changes required, save some time and jump over the code + long local_IF; - if (MODE_INPUT(setting.mode) && i > 0 && FREQ_IS_CW()) - goto skip_LO_setting; // No LO changes during CW loop + again: // Spur reduction jumps to here for second measurement - long local_IF; - again: if (MODE_HIGH(setting.mode)) local_IF = 0; else { @@ -1370,33 +1372,35 @@ float perform(bool break_on_operation, int i, uint32_t f, int tracking) else local_IF = setting.frequency_IF; } - if (setting.mode == M_LOW && tracking) { // Measure BPF + if (setting.mode == M_LOW && tracking) { // VERY SPECIAL CASE!!!!! Measure BPF set_freq (0, local_IF + lf - reffer_freq[setting.refer]); // Offset so fundamental of reffer is visible } else if (MODE_LOW(setting.mode)) { - if (setting.mode == M_LOW && !in_selftest && avoid_spur(f)) { + if (setting.mode == M_LOW && !in_selftest && avoid_spur(f)) { // check is alternate IF is needed to avoid spur. local_IF = spur_alternate_IF; #ifdef __SPUR__ - } else if (setting.mode== M_LOW && setting.spur){ - if (S_IS_AUTO(setting.below_IF) && lf < 150000000) // if below 150MHz and auto_below_IF swap IF + } else if (setting.mode== M_LOW && setting.spur){ // If in low input mode and spur reduction is on + if (S_IS_AUTO(setting.below_IF) && lf < 150000000) // if below 150MHz and auto_below_IF { // else low/above IF if (setting.spur == 1) - setting.below_IF = S_AUTO_ON; + setting.below_IF = S_AUTO_ON; // use below IF in first pass else - setting.below_IF = S_AUTO_OFF; + setting.below_IF = S_AUTO_OFF; // and above IF in second pass } else { - int32_t spur_offset = actual_rbw * 1000; - if (setting.spur == -1) - spur_offset = - spur_offset; - local_IF = local_IF + spur_offset; + int32_t spur_offset = actual_rbw * 1000; // Can not use below IF so calculate IF shift that hopefully will kill the spur. + if (setting.spur == -1) // If second spur pass + spur_offset = - spur_offset; // IF shift in the other direction + local_IF = local_IF + spur_offset; // apply IF spur shift } #endif - } else { -// local_IF = setting.frequency_IF ; } - if (setting.mode == M_GENLOW && setting.modulation == MO_EXTERNAL) // LO input via high port + if (setting.mode == M_GENLOW && setting.modulation == MO_EXTERNAL) // VERY SPECIAL CASE !!!!!! LO input via high port local_IF += lf; + + // --------------------- IF know, set the RX SI4432 frequency ------------------------ + set_freq (0, local_IF); + #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*300000 : 0 ); @@ -1435,12 +1439,15 @@ float perform(bool break_on_operation, int i, uint32_t f, int tracking) set_freq (3, IF_2 - 433800000); // Down from IF2 to fixed second IF in Ultra SA mode set_freq (1, 433800000); // Second IF fixe in Ultra SA mode #else - if (setting.mode == M_LOW && !setting.tracking && S_STATE(setting.below_IF)) - set_freq (1, local_IF-lf); + if (setting.mode == M_LOW && !setting.tracking && S_STATE(setting.below_IF)) // if in low input mode and below IF + set_freq (1, local_IF-lf); // set LO SI4432 to below IF frequency else - set_freq (1, local_IF+lf); + set_freq (1, local_IF+lf); // otherwise to above IF #endif } + + // ------------------------- end of processing when in output mode ------------------------------------------------ + if (MODE_OUTPUT(setting.mode)) // No substepping and no RSSI in output mode return(0); @@ -1448,9 +1455,11 @@ float perform(bool break_on_operation, int i, uint32_t f, int tracking) float signal_path_loss; - skip_LO_setting: + skip_LO_setting: // jump here if in zero span mode and all HW frequency setup is done. + #ifdef __FAST_SWEEP__ if (i == 0 && setting.frequency_step == 0 && setting.trigger == T_AUTO && setting.spur == 0 && actualStepDelay == 0 && setting.repeat == 1 && setting.sweep_time_us < ONE_SECOND_TIME) { + // if ultra fast scanning is needed prefill the SI4432 RSSI read buffer SI4432_Fill(MODE_SELECT(setting.mode), 0); } #endif @@ -1467,28 +1476,30 @@ float perform(bool break_on_operation, int i, uint32_t f, int tracking) int wait_for_trigger = false; int old_actual_step_delay = actualStepDelay; - if (i == 0 && setting.frequency_step == 0 && setting.trigger != T_AUTO) { // prepare for wait for trigger to happen - wait_for_trigger = true; - actualStepDelay = 0; // fastest possible in zero span trigger mode + if (i == 0 && setting.frequency_step == 0 && setting.trigger != T_AUTO) { // if in zero span mode and wait for trigger to happen and NOT in trigger mode + wait_for_trigger = true; // signal the wait for trigger + actualStepDelay = 0; // and ignore requested sweep time to be as fast as possible } float subRSSI; - static float correct_RSSI; + static float correct_RSSI; // This is re-used between calls if (i == 0 || setting.frequency_step != 0 ) // only cases where the value can change - correct_RSSI = get_level_offset()+ get_attenuation() - signal_path_loss - setting.offset + get_frequency_correction(f); - wait: - subRSSI = SI4432_RSSI(lf, MODE_SELECT(setting.mode)) + correct_RSSI ; + correct_RSSI = get_level_offset()+ get_attenuation() - signal_path_loss - setting.offset + get_frequency_correction(f); // calcuate the RSSI correction for later use + + wait: + subRSSI = SI4432_RSSI(lf, MODE_SELECT(setting.mode)) + correct_RSSI ; // Get RSSI, either from pre-filled buffer or by reading SI4432 RSSI // if ( i < 3) // shell_printf("%d %.3f %.3f %.1f\r\n", i, local_IF/1000000.0, lf/1000000.0, subRSSI); - if (wait_for_trigger) { // wait for trigger to happen - if ((operation_requested || shell_function) && break_on_operation) + if (wait_for_trigger) { // wait for trigger to happen + if ((operation_requested || shell_function) && break_on_operation) // allow aborting a wait for trigger break; // abort - if (subRSSI < setting.trigger_level) - goto wait; + if (subRSSI < setting.trigger_level) // trigger level not yet reached + goto wait; // get next rssi + #ifdef __FAST_SWEEP__ if (i == 0 && setting.frequency_step == 0 /* && setting.trigger == T_AUTO */&& setting.spur == 0 && old_actual_step_delay == 0 && setting.repeat == 1 && setting.sweep_time_us < ONE_SECOND_TIME) { - SI4432_Fill(MODE_SELECT(setting.mode), 1); + SI4432_Fill(MODE_SELECT(setting.mode), 1); // fast mode possible to pre-fill RSSI buffer } #endif actualStepDelay = old_actual_step_delay; // Trigger happened, restore step delay @@ -1498,21 +1509,21 @@ float perform(bool break_on_operation, int i, uint32_t f, int tracking) #ifdef __SPUR__ if (setting.spur == 1) { // If first spur pass - spur_RSSI = subRSSI; - setting.spur = -1; + spur_RSSI = subRSSI; // remember measure RSSI + setting.spur = -1; // and prepare for second pass goto again; // Skip all other processing } else if (setting.spur == -1) { // If second spur pass subRSSI = ( subRSSI < spur_RSSI ? subRSSI : spur_RSSI); // Take minimum of two - setting.spur = 1; + setting.spur = 1; // and prepare for next call of perform. } #endif if (RSSI < subRSSI) // Take max during subscanning RSSI = subRSSI; - t++; + t++; // one subscan done if ((operation_requested || shell_function ) && break_on_operation) // break subscanning if requested break; // abort - } while (t < vbwSteps); + } while (t < vbwSteps); // till all sub steps done return(RSSI); } @@ -1534,18 +1545,21 @@ static bool sweep(bool break_on_operation) // if (setting.mode== -1) // return; // START_PROFILE; -again: - downslope = true; +again: // Waiting for a trigger jumps back to here palClearPad(GPIOB, GPIOB_LED); + + downslope = true; // Initialize the peak search algoritm temppeakLevel = -150; float temp_min_level = 100; + // spur_old_stepdelay = 0; int repeats = 1; // shell_printf("\r\n"); - if (MODE_OUTPUT(setting.mode) && setting.modulation != MO_NONE) { - repeats = 1000; // to avoid interrupting the tone during UI processing - modulation_counter = 0; + if (MODE_OUTPUT(setting.mode) && setting.modulation != MO_NONE) { // If in output mode + repeats = 1000; // stay as long as possible in the sweep loop to avoid interrupting the tone during by UI processing + modulation_counter = 0; // init modulation counter } + uint32_t t = calc_min_sweep_time_us(); // Time to delay in uS if (t < setting.sweep_time_us){ t = setting.sweep_time_us - t; @@ -1553,23 +1567,34 @@ again: } else t = 0; + if (MODE_OUTPUT(setting.mode) && t < 500) // Minimum wait time to prevent LO from lockup t = 500; - set_freq_time = 0; + + set_freq_time = 0; // for predicting the weep time + while (repeats--) { - for (int i = 0; i < sweep_points; i++) { - if (start_index == -1 && start_time == 0 && set_freq_time != 0) { +// ------------------------- sweep loop ----------------------------------- + + for (int i = 0; i < sweep_points; i++) { + + if (start_index == -1 && start_time == 0 && set_freq_time != 0) { // Sweep time prediction: first real set SI4432 freq start_index = i; - start_time = set_freq_time; - set_freq_time = 0; - } else if (start_index != -1 && start_time != 0 && set_freq_time != 0 ) { - uint32_t total_time = 290*(set_freq_time - start_time)*100/(i - start_index); - if (1) shell_printf("%d T:%f\r\n", i, total_time / 1000000.0); + start_time = set_freq_time; // remember time set_freq_time = 0; + } else if (start_index != -1 && start_time != 0 && set_freq_time != 0 ) { // next real set si4432 freq + uint32_t total_time = 290*(set_freq_time - start_time)*100/(i - start_index); // use in between time to predict total sweep time + // shell_printf("%d T:%f\r\n", i, total_time / 1000000.0); + set_freq_time = 0; // retrigger detection of si4432 set freq } - RSSI = perform(break_on_operation, i, frequencies[i], setting.tracking); + // --------------------- measure ------------------------- + + RSSI = perform(break_on_operation, i, frequencies[i], setting.tracking); // Measure RSSI for one of the frequencies + + // ----------------- delay between points if needed ---------------- + if (t && (MODE_INPUT(setting.mode) || setting.modulation == MO_NONE)) { if (t < 30*ONE_MS_TIME) my_microsecond_delay(t); @@ -1578,23 +1603,26 @@ again: } // back to toplevel to handle ui operation - if ((operation_requested || shell_function) && break_on_operation) { + if ((operation_requested || shell_function) && break_on_operation) { // break loop if needed if (setting.actual_sweep_time_us > ONE_SECOND_TIME) { ili9341_fill(OFFSETX, HEIGHT_NOSCROLL+1, WIDTH, 1, 0); } - return false; } - if (MODE_OUTPUT(setting.mode)) { - continue; // Skip all other processing + + if (MODE_OUTPUT(setting.mode)) { // if in output mode + continue; // Skip all other processing in sweep loop } - if (MODE_INPUT(setting.mode)) { - if (setting.actual_sweep_time_us > ONE_SECOND_TIME && (i & 0x07) == 0) { - ili9341_fill(OFFSETX, HEIGHT_NOSCROLL+1, i, 1, BRIGHT_COLOR_GREEN); + if (MODE_INPUT(setting.mode)) { // this is always true I guess...... + + if (setting.actual_sweep_time_us > ONE_SECOND_TIME && (i & 0x07) == 0) { // if required + ili9341_fill(OFFSETX, HEIGHT_NOSCROLL+1, i, 1, BRIGHT_COLOR_GREEN); // update sweep progress bar ili9341_fill(OFFSETX+i, HEIGHT_NOSCROLL+1, WIDTH-i, 1, 0); } + // ------------------------ do all RSSI calculations frm CALC menu ------------------- + if (setting.average != AV_OFF) temp_t[i] = RSSI; if (setting.subtract_stored) { @@ -1623,7 +1651,9 @@ again: case AV_16: actual_t[i] = (actual_t[i]*15 + RSSI) / 16.0; break; } } -#if 1 + + // --------------------------- find peak and add to peak table if found ------------------------ + // START_PROFILE if (i == 0) { // Prepare peak finding @@ -1648,7 +1678,7 @@ again: temppeakLevel = actual_t[i]; } else if (actual_t[i] < temppeakLevel - setting.noise) { // Local max found - + // maintain sorted peak table int j = 0; // Insert max in sorted table while (j= temppeakLevel) // Find where to insert j++; @@ -1674,22 +1704,18 @@ again: } } } // end of peak finding -#else - if (frequencies[i] > 1000000) { - if (temppeakLevel < actual_t[i]) { - temppeakIndex = i; - temppeakLevel = actual_t[i]; - } - } -#endif + + if (temp_min_level > actual_t[i]) // Remember minimum temp_min_level = actual_t[i]; } + // --------------- check if maximum is above trigger level ----------------- + if (setting.trigger != T_AUTO && setting.frequency_step > 0) { // Trigger active if (actual_t[max_index[0]] < setting.trigger_level) { - goto again; + goto again; // not yet, sweep again } else { if (setting.trigger == T_SINGLE) pause_sweep(); // Stop scanning after completing this sweep if above trigger @@ -1697,12 +1723,16 @@ again: scandirty = true; // To show trigger happened } + // ---------------------- sweep finished, do all postprocessing --------------------- + if (scandirty) { scandirty = false; redraw_request |= REDRAW_CAL_STATUS; } - if (!in_selftest && setting.mode == M_LOW && setting.auto_attenuation && max_index[0] > 0) { // Auto attenuate + // -------------------------- auto attenuate ---------------------------------- + + if (!in_selftest && setting.mode == M_LOW && setting.auto_attenuation && max_index[0] > 0) { // calculate and apply auto attenuate setting.atten_step = false; // No step attenuate in low mode auto attenuate float old_attenuate = get_attenuation(); float actual_max_level = actual_t[max_index[0]] - old_attenuate; @@ -1725,6 +1755,9 @@ again: // dirty = true; // Must be above if(scandirty!!!!!) } } + + // ---------------------------------- auto AGC ---------------------------------- + if (!in_selftest && MODE_INPUT(setting.mode) && S_IS_AUTO(setting.agc) && UNIT_IS_LINEAR(setting.unit)) { // Auto AGC in linear mode unsigned char v; static unsigned char old_v; @@ -1739,6 +1772,9 @@ again: } } + + + // -------------------------- auto reflevel --------------------------------- if (max_index[0] > 0) temppeakLevel = actual_t[max_index[0]]; @@ -1787,7 +1823,9 @@ again: // dirty = false; // Prevent reset of SI4432 } } -#if 1 + + // --------------------- set tracking markers from maximum table ----------------- + if (MODE_INPUT(setting.mode)) { // Assign maxima found to tracking markers int i = 0; int m = 0; @@ -1810,12 +1848,16 @@ again: } m++; // Try next marker } + + // ----------------------- now follow all the special marker calculations for the measurement modes ---------------------------- + + #ifdef __MEASURE__ - if (setting.measurement == M_IMD && markers[0].index > 10) { // IMD measurement + if (setting.measurement == M_IMD && markers[0].index > 10) { // ----- IMD measurement markers[1].enabled = search_maximum(1, frequencies[markers[0].index]*2, 8); markers[2].enabled = search_maximum(2, frequencies[markers[0].index]*3, 12); markers[3].enabled = search_maximum(3, frequencies[markers[0].index]*4, 16); - } else if (setting.measurement == M_OIP3 && markers[0].index > 10 && markers[1].index > 10) { // IOP measurement + } else if (setting.measurement == M_OIP3 && markers[0].index > 10 && markers[1].index > 10) { // ----------IOP measurement int l = markers[0].index; int r = markers[1].index; if (r < l) { @@ -1828,14 +1870,14 @@ again: uint32_t rf = frequencies[r]; markers[2].enabled = search_maximum(2, lf - (rf - lf), 12); markers[3].enabled = search_maximum(3, rf + (rf - lf), 12); - } else if (setting.measurement == M_PHASE_NOISE && markers[0].index > 10) { // Phase noise measurement + } else if (setting.measurement == M_PHASE_NOISE && markers[0].index > 10) { // ------------Phase noise measurement markers[1].index = markers[0].index + (setting.mode == M_LOW ? 290/4 : -290/4); // Position phase noise marker at requested offset - } else if (setting.measurement == M_STOP_BAND && markers[0].index > 10) { // Stop band measurement + } else if (setting.measurement == M_STOP_BAND && markers[0].index > 10) { // -------------Stop band measurement markers[1].index = marker_search_left_min(markers[0].index); if (markers[1].index < 0) markers[1].index = 0; markers[2].index = marker_search_right_min(markers[0].index); if (markers[2].index < 0) markers[1].index = setting._sweep_points - 1; - } else if (setting.measurement == M_PASS_BAND && markers[0].index > 10) { // Pass band measurement + } else if (setting.measurement == M_PASS_BAND && markers[0].index > 10) { // ----------------Pass band measurement int t = markers[0].index; float v = actual_t[t]; while (t > 0 && actual_t[t] > v - 3.0) // Find left -3dB point @@ -1848,11 +1890,12 @@ again: if (t < setting._sweep_points - 1 ) markers[2].index = t; } + #endif peakIndex = max_index[0]; peakLevel = actual_t[peakIndex]; peakFreq = frequencies[peakIndex]; -#else +#if 0 int peak_marker = 0; markers[peak_marker].enabled = true; markers[peak_marker].index = peakIndex; @@ -1861,6 +1904,11 @@ again: min_level = temp_min_level; } } + + + //---------------- in Linearity measurement the attenuation has to be adapted ------------------ + + if (setting.measurement == M_LINEARITY && setting.linearity_step < setting._sweep_points) { setting.attenuate = 29.0 - setting.linearity_step * 30.0 / 290.0; dirty = true; @@ -1870,7 +1918,7 @@ again: // redraw_marker(peak_marker, FALSE); // STOP_PROFILE; - if (setting.actual_sweep_time_us > ONE_SECOND_TIME) { + if (setting.actual_sweep_time_us > ONE_SECOND_TIME) { // Clear sweep progress bar at end of sweep ili9341_fill(OFFSETX, HEIGHT_NOSCROLL+1, WIDTH, 1, 0); }