diff --git a/plot.c b/plot.c index e0c47ea..774e110 100644 --- a/plot.c +++ b/plot.c @@ -519,6 +519,13 @@ draw_on_strut(int v0, int d, int color) * calculate log10f(abs(gamma)) */ + +float +index_to_value(const int i) +{ + return(value(actual_t[i])); +} + float value(const float v) { @@ -2084,31 +2091,51 @@ static void cell_draw_marker_info(int x0, int y0) if (setting.measurement == M_THD && active >= 1) active = 2; for (int i = 0; i < MARKER_COUNT; i++) { - if (i == 3 && setting.measurement == M_PASS_BAND) { + if (i == 3) { + if (setting.measurement == M_PASS_BAND) { uint32_t f; if (markers[2].frequency>markers[1].frequency) f = markers[2].frequency-markers[1].frequency; else f = markers[1].frequency-markers[2].frequency; plot_printf(buf, sizeof buf, "WIDTH: %8.3qHz", f); + show_computed: j = 3; int xpos = 1 + (j%2)*(WIDTH/2) + CELLOFFSETX - x0; int ypos = 1 + (j/2)*(16) - y0; cell_drawstring_7x13(buf, xpos, ypos); -// cell_drawstring(buf, xpos, ypos); - break; - } else + // cell_drawstring(buf, xpos, ypos); + } else if (setting.measurement == M_AM){ +#ifdef AM_IN_VOLT + int old_unit = setting.unit; + setting.unit = U_VOLT; + float level = (index_to_value(markers[1].index) + index_to_value(markers[2].index))/2 / index_to_value(markers[0].index); + setting.unit = old_unit; + int depth = (int)( level * 2.0 * 80.0) + 20; +#else + float delta = actual_t[markers[1].index] - actual_t[markers[2].index]; + if (delta < -5 || delta > 5) + break; + float level = (actual_t[markers[1].index] + actual_t[markers[2].index])/2.0 - actual_t[markers[0].index]; + if (level < -40 || level > 0) + break; + int depth =(int) (pow((float)10.0, 2.0 + (level + 6.02) /20.0)); +#endif + plot_printf(buf, sizeof buf, "DEPTH: %3d%%", depth); + goto show_computed; + } + } if (i >= 2 && setting.measurement == M_THD) { if (i == 2 && (markers[0].index << 5) > sweep_points ) { int old_unit = setting.unit; setting.unit = U_WATT; - float p = value((actual_t[markers[0].index])); + float p = index_to_value(markers[0].index); int j = 2; uint32_t f = markers[0].frequency; float h = 0.0; while (f * j < frequencies[sweep_points-1]) { if (search_maximum(1, f*j, 4*j) ) // use marker 1 for searching harmonics - h += value((actual_t[markers[1].index])); + h += index_to_value(markers[1].index); j++; } float thd = 100.0 * sqrt(h/p); @@ -2125,10 +2152,10 @@ static void cell_draw_marker_info(int x0, int y0) break; } else if (i >= 2 && setting.measurement == M_OIP3 && markers[2].enabled && markers[3].enabled) { - float il = value((actual_t[markers[2].index])); - float ir = value((actual_t[markers[3].index])); - float sl = value((actual_t[markers[0].index])); - float sr = value((actual_t[markers[1].index])); + float il = index_to_value(markers[2].index); + float ir = index_to_value(markers[3].index); + float sl = index_to_value(markers[0].index); + float sr = index_to_value(markers[1].index); float ip = sl+ (sr - il)/2; plot_printf(buf, sizeof buf, "OIP3: %4.1fdB", ip); diff --git a/sa_core.c b/sa_core.c index e1e358e..a72169f 100644 --- a/sa_core.c +++ b/sa_core.c @@ -1120,8 +1120,8 @@ void set_freq(int V, unsigned long freq) // translate the requested frequency shell_printf("%d: Offs %q HW %d\r\n", SI4432_Sel, (uint32_t)(real_old_freq[V]+delta*1), real_old_freq[V]); #endif delta = delta * 4 / 625; // = 156.25; // Calculate and set the offset register i.s.o programming a new frequency - SI4432_Write_Byte(SI4432_FREQ_OFFSET1, (uint8_t)(delta & 0xff)); - SI4432_Write_Byte(SI4432_FREQ_OFFSET2, (uint8_t)((delta >> 8) & 0x03)); + SI4432_Write_2_Byte(SI4432_FREQ_OFFSET1, (uint8_t)(delta & 0xff), (uint8_t)((delta >> 8) & 0x03)); + // SI4432_Write_Byte(SI4432_FREQ_OFFSET2, (uint8_t)((delta >> 8) & 0x03)); SI4432_offset_changed = true; // Signal offset changed so RSSI retrieval is delayed for frequency settling old_freq[V] = freq; } else { @@ -1134,8 +1134,8 @@ void set_freq(int V, unsigned long freq) // translate the requested frequency target_f = freq - 80000; } SI4432_Set_Frequency(target_f); - SI4432_Write_Byte(SI4432_FREQ_OFFSET1, 0xff); // set offset to most positive - SI4432_Write_Byte(SI4432_FREQ_OFFSET2, 0x01); + SI4432_Write_2_Byte(SI4432_FREQ_OFFSET1, 0xff, 0x01); // set offset to most positive + // SI4432_Write_Byte(SI4432_FREQ_OFFSET2, 0x01); real_old_freq[V] = target_f; } else { // sweeping up if (freq + 80000 >= 480000000) { @@ -1144,14 +1144,14 @@ void set_freq(int V, unsigned long freq) // translate the requested frequency target_f = freq + 80000; } SI4432_Set_Frequency(target_f); - SI4432_Write_Byte(SI4432_FREQ_OFFSET1, 0); // set offset to most negative - SI4432_Write_Byte(SI4432_FREQ_OFFSET2, 0x02); + SI4432_Write_2_Byte(SI4432_FREQ_OFFSET1, 0, 0x02); // set offset to most negative +// SI4432_Write_Byte(SI4432_FREQ_OFFSET2, 0x02); real_old_freq[V] = target_f; } #else SI4432_Set_Frequency(freq); // Impossible to use offset so set SI4432 to new frequency - SI4432_Write_Byte(SI4432_FREQ_OFFSET1, 0); // set offset to zero - SI4432_Write_Byte(SI4432_FREQ_OFFSET2, 0); + SI4432_Write_2_Byte(SI4432_FREQ_OFFSET1, 0, 0); // set offset to zero +// SI4432_Write_Byte(SI4432_FREQ_OFFSET2, 0); real_old_freq[V] = freq; #endif } @@ -2150,7 +2150,7 @@ sweep_again: // stay in sweep loop when output mo if (setting.subtract_stored) { RSSI = RSSI - stored_t[i] + setting.normalize_level; } -// #define __DEBUG_AGC__ +//#define __DEBUG_AGC__ #ifdef __DEBUG_AGC__ // For debugging the AGC control stored_t[i] = (SI4432_Read_Byte(0x69) & 0x01f) * 3.0 - 90.0; // Display the AGC value in the stored trace #endif @@ -2448,6 +2448,27 @@ sweep_again: // stay in sweep loop when output mo if (markers[m].enabled && markers[m].mtype & M_TRACKING) { // Available marker found markers[m].index = max_index[i]; markers[m].frequency = frequencies[markers[m].index]; +#if 0 + float v = actual_t[markers[m].index] - 10.0; // -10dB points + int index = markers[m].index; + uint32_t f = markers[m].frequency; + uint32_t s = actual_rbw_x10 * 200; // twice the selected RBW + int left = index, right = index; + while (t > 0 && actual_t[t+1] > v && markers[t].frequency > f - s) // Find left point + t--; + if (t > 0) { + left = t; + } + t = setting._sweep_points-1;; + while (t > setting._sweep_points-1 && actual_t[t+1] > v) // find right -3dB point + t++; + if (t > index) { + right = t; + markers[2].frequency = frequencies[t]; + } + +#endif + #if 1 // Hyperbolic interpolation, can be removed to save memory const int idx = markers[m].index; if (idx > 0 && idx < sweep_points-1) @@ -2511,18 +2532,18 @@ sweep_again: // stay in sweep loop when output mo if (markers[2].index < 0) markers[1].index = setting._sweep_points - 1; markers[2].frequency = frequencies[markers[2].index]; } 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 - 4.0) // Find left -3dB point - t --; - if (t > 0) { + int t = 0; + float v = actual_t[markers[0].index] - 3.0; + while (t < markers[0].index && actual_t[t+1] < v) // Find left -3dB point + t++; + if (t< markers[0].index) { markers[1].index = t; markers[1].frequency = frequencies[t]; } - t = markers[0].index; - while (t < setting._sweep_points - 1 && actual_t[t] > v - 4.0) // find right -3dB point - t ++; - if (t < setting._sweep_points - 1 ) { + t = setting._sweep_points-1;; + while (t > markers[0].index && actual_t[t-1] < v) // find right -3dB point + t--; + if (t > markers[0].index) { markers[2].index = t; markers[2].frequency = frequencies[t]; } @@ -3148,6 +3169,7 @@ static const struct { {TC_BELOW, TP_30MHZ, 430, 60, -75, 0, -75}, // 9 LPF cutoff {TC_SIGNAL, TP_10MHZ_SWITCH,20, 7, -39, 10, -60 }, // 10 Switch isolation using high attenuation {TC_ATTEN, TP_30MHZ, 30, 0, -25, 145, -60 }, // 11 Measure atten step accuracy +#define TEST_END 11 {TC_END, 0, 0, 0, 0, 0, 0}, #define TEST_POWER 12 {TC_MEASURE, TP_30MHZ, 30, 7, -25, 10, -55 }, // 12 Measure power level and noise @@ -3528,6 +3550,16 @@ void self_test(int test) test_prepare(test_step); test_acquire(test_step); // Acquire test test_status[test_step] = test_validate(test_step); // Validate test + if (test_step == 2) { + if (peakLevel < -60) { + test_step = TEST_END; + ili9341_set_foreground(BRIGHT_COLOR_RED); + ili9341_drawstring_7x13("Signal level too low", 30, 140); + ili9341_drawstring_7x13("Check cable between High and Low connectors", 30, 160); + goto resume2; + } + + } if (test_status[test_step] != TS_PASS) { resume: test_wait = true; @@ -3715,7 +3747,9 @@ void self_test(int test) reset_settings(M_LOW); setting.step_delay_mode = SD_NORMAL; setting.step_delay = 0; - } else if (test == 5) { + } +#ifdef DOESNOTFIT + else if (test == 5) { // reset_settings(M_LOW); // Make sure we are in a defined state in_selftest = true; switch (setting.test_argument) { @@ -3753,6 +3787,7 @@ void self_test(int test) } in_selftest = false; } +#endif show_test_info = FALSE; in_selftest = false; test_wait = false; @@ -3785,10 +3820,16 @@ void calibrate(void) setting.lna = S_OFF; test_acquire(TEST_POWER); // Acquire test local_test_status = test_validate(TEST_POWER); // Validate test + if (peakLevel < -50) { + ili9341_set_foreground(BRIGHT_COLOR_RED); + ili9341_drawstring_7x13("Signal level too low", 30, 140); + ili9341_drawstring_7x13("Check cable between High and Low connectors", 30, 160); + goto quit; + } // chThdSleepMilliseconds(1000); if (local_test_status != TS_PASS) { ili9341_set_foreground(BRIGHT_COLOR_RED); - ili9341_drawstring_7x13("Calibration failed", 30, 120); + ili9341_drawstring_7x13("Calibration failed", 30, 140); goto quit; } else { set_actual_power(-25.0); // Should be -23.5dBm (V0.2) OR 25 (V0.3) @@ -3824,9 +3865,9 @@ void calibrate(void) config_save(); ili9341_set_foreground(BRIGHT_COLOR_GREEN); - ili9341_drawstring_7x13("Calibration complete", 30, 120); + ili9341_drawstring_7x13("Calibration complete", 30, 140); quit: - ili9341_drawstring_7x13("Touch screen to continue", 30, 140); + ili9341_drawstring_7x13("Touch screen to continue", 30, 200); wait_user(); ili9341_clear_screen(); set_sweep_points(old_sweep_points); diff --git a/ui_sa.c b/ui_sa.c index f59bd05..e8d7c1e 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -858,20 +858,31 @@ static UI_FUNCTION_ADV_CALLBACK(menu_measure_acb) case M_LINEARITY: set_measurement(M_LINEARITY); break; - case M_AM: // OIP3 + case M_AM: // AM reset_settings(setting.mode); for (int i = 0; i< 3; i++) { markers[i].enabled = M_ENABLED; - markers[i].mtype = M_DELTA | M_TRACKING; + markers[i].mtype = M_DELTA;// | M_TRACKING; } - markers[0].mtype = M_REFERENCE | M_TRACKING; + uint32_t center, span; + markers[0].mtype = M_REFERENCE;// | M_TRACKING; kp_help_text = "Frequency of signal"; ui_mode_keypad(KM_CENTER); ui_process_keypad(); + center = uistat.value; + kp_help_text = "Modulation frequency, 2 .. 10 kHz"; + ui_mode_keypad(KM_SPAN); + ui_process_keypad(); + if (uistat.value < 2000) + break; + span = uistat.value + 1500; // Enlarge span for RBW width set_sweep_frequency(ST_SPAN, 100000); // 100kHz set_measurement(M_AM); + set_marker_frequency(0, center); + set_marker_frequency(1, center-span); + set_marker_frequency(2, center+span); break; - case M_FM: // OIP3 + case M_FM: // FM reset_settings(setting.mode); for (int i = 0; i< 3; i++) { markers[i].enabled = M_ENABLED;