Merge branch 'DiSlord_tinySA-V4' of https://github.com/erikkaashoek/tinySA into DiSlord_tinySA-V4

# Conflicts:
#	nanovna.h
#	ui.c
multi_trace
DiSlord 5 years ago
commit 65893bfaf2

@ -18,7 +18,7 @@
*/ */
#include "ch.h" #include "ch.h"
//#ifdef TINYSA_F303 #ifdef TINYSA_F303
#ifdef TINYSA_F072 #ifdef TINYSA_F072
#error "Remove comment for #ifdef TINYSA_F303" #error "Remove comment for #ifdef TINYSA_F303"
#endif #endif
@ -26,7 +26,7 @@
#define TINYSA4 #define TINYSA4
#endif #endif
#define TINYSA4_PROTO #define TINYSA4_PROTO
//#endif #endif
#ifdef TINYSA_F072 #ifdef TINYSA_F072
#ifdef TINYSA_F303 #ifdef TINYSA_F303
@ -265,6 +265,7 @@ extern float level_range(void);
extern float channel_power[3]; extern float channel_power[3];
extern float channel_power_watt[3]; extern float channel_power_watt[3];
extern const char * const unit_string[]; extern const char * const unit_string[];
extern uint16_t vbwSteps;
#ifdef TINYSA4 #ifdef TINYSA4
extern freq_t ultra_threshold; extern freq_t ultra_threshold;
extern bool ultra; extern bool ultra;
@ -674,6 +675,7 @@ float get_level_offset(void);
extern uint8_t in_selftest; extern uint8_t in_selftest;
extern int display_test(void); extern int display_test(void);
extern void clear_marker_cache(void);
// //
// Shell config functions and macros // Shell config functions and macros

@ -280,9 +280,20 @@ index_to_value(const int i)
return(value(actual_t[i])); return(value(actual_t[i]));
} }
#endif #endif
float marker_cache[MARKERS_MAX];
bool marker_cache_valid[MARKERS_MAX];
void
clear_marker_cache(void)
{
for (int i = 0; i<MARKERS_MAX; i++)
marker_cache_valid[i] = false;
}
float float
marker_to_value(const int i) marker_to_value(const int i)
{ {
if (marker_cache_valid[i])
return marker_cache[i];
float *ref_marker_levels; float *ref_marker_levels;
if (markers[i].mtype & M_STORED ) if (markers[i].mtype & M_STORED )
ref_marker_levels = stored_t; ref_marker_levels = stored_t;
@ -290,11 +301,26 @@ marker_to_value(const int i)
ref_marker_levels = actual_t; ref_marker_levels = actual_t;
float v = value(ref_marker_levels[markers[i].index]); float v = value(ref_marker_levels[markers[i].index]);
if (markers[i].mtype & M_AVER) { if (markers[i].mtype & M_AVER) {
int old_unit = setting.unit;
if (markers[i].mtype & M_NOISE)
setting.unit = U_WATT; // Noise averaging should always be done in Watts
v = 0; v = 0;
for (int i=0; i<sweep_points; i++) for (int i=0; i<sweep_points; i++)
v += value(ref_marker_levels[i]); v += value(ref_marker_levels[i]); // TODO this should be power averaging for noise markers
v /= sweep_points; v /= sweep_points;
v = to_dBm(v);
setting.unit = old_unit;
v = value(v);
}
if (markers[i].mtype & M_NOISE){
v = v - logf(actual_rbw_x10*100.0) * (10.0/logf(10.0))
#ifdef TINYSA4
+ SI4463_noise_correction_x10/10.0
#endif
;
} }
marker_cache_valid[i] = true;
marker_cache[i] = v;
return(v); return(v);
} }
@ -1444,13 +1470,6 @@ static void trace_print_value_string( // Only used at one place
// if (mtype & M_NOISE) // if (mtype & M_NOISE)
// *ptr2++ = 'N'; // *ptr2++ = 'N';
*ptr2++ = ' '; *ptr2++ = ' ';
if (mtype & M_NOISE){
v += - logf(actual_rbw_x10*100.0) * (10.0/logf(10.0))
#ifdef TINYSA4
+ SI4463_noise_correction_x10/10.0
#endif
;
}
// Not possible ??? // Not possible ???
if (v == -INFINITY){ if (v == -INFINITY){
cell_printf(xpos, ypos, FONT_b"%s-INF", buf2); cell_printf(xpos, ypos, FONT_b"%s-INF", buf2);
@ -1480,15 +1499,15 @@ static void trace_print_value_string( // Only used at one place
} }
const char *format; const char *format;
if (UNIT_IS_LINEAR(setting.unit)) if (UNIT_IS_LINEAR(setting.unit))
format = FONT_s"%s %.3F%s%s"; // 5 characters incl u, m, etc... format = FONT_s"%s %.3F%s%s%s"; // 5 characters incl u, m, etc...
else else
format = FONT_s"%s %.1f%s%s"; format = FONT_s"%s %.1f%s%s%s";
#ifdef TINYSA4 #ifdef TINYSA4
format++; // Skip small prefix for bold output format++; // Skip small prefix for bold output
#else #else
if (bold) format++; // Skip small prefix for bold output if (bold) format++; // Skip small prefix for bold output
#endif #endif
cell_printf(xpos, ypos, format, buf2, v, unit_string[unit_index], (mtype & M_NOISE?"/Hz":"")); cell_printf(xpos, ypos, format, buf2, v, unit_string[unit_index], (mtype & M_NOISE?"/Hz":""), (mtype & M_AVER?"/T":""));
} }
static void cell_draw_marker_info(int x0, int y0) static void cell_draw_marker_info(int x0, int y0)
@ -1608,21 +1627,14 @@ static void cell_draw_marker_info(int x0, int y0)
#ifdef __NOISE_FIGURE__ #ifdef __NOISE_FIGURE__
} else if (i>=2 && setting.measurement == M_NF && markers[0].enabled) { } else if (i>=2 && setting.measurement == M_NF && markers[0].enabled) {
float aNP = 0; float aNP = 0;
#if 1
for (int i =0; i < sweep_points; i++) {
aNP += actual_t[i];
}
aNP /= sweep_points;
#else
aNP = marker_to_value(0); aNP = marker_to_value(0);
#endif float mNF = aNP + 173.93 - nf_gain; // measured noise figure at 20C
float mNF = aNP - logf(actual_rbw_x10*100.0) * (10.0/logf(10.0)) + 173.93 + SI4463_noise_correction_x10/10.0; // measured noise figure at 20C
if (nf_gain != 0) { if (nf_gain != 0) {
float mnf = expf((mNF - nf_gain)/10 * logf(10)); // measure noise factor float mnf = expf(mNF/10.0 * logf(10)); // measure noise factor
float tnf = expf(config.noise_figure/10 * logf(10)); // tinySA noise factor float tnf = expf(config.noise_figure/10.0 * logf(10.0)); // tinySA noise factor
float amp_gain = expf(nf_gain/10 * logf(10)); float amp_gain = expf(nf_gain/10.0 * logf(10.0));
float anf = mnf - (tnf - 1.0)/amp_gain; float anf = mnf - (tnf - 1.0)/amp_gain;
mNF = 10*logf(anf)/logf(10); mNF = 10.0*logf(anf)/logf(10.0);
} }
// powf(10,x) = expf(x * logf(10)) // powf(10,x) = expf(x * logf(10))
// log10f(x) = logf(x)/logf(10) // log10f(x) = logf(x)/logf(10)
@ -1685,7 +1697,8 @@ static void cell_draw_marker_info(int x0, int y0)
int level = temppeakLevel - get_attenuation() + setting.external_gain; int level = temppeakLevel - get_attenuation() + setting.external_gain;
if ((!setting.subtract_stored) && // Disabled when normalized if ((!setting.subtract_stored) && // Disabled when normalized
((setting.mode == M_LOW && level > -10) || ((setting.mode == M_LOW && level > -10) ||
(setting.mode == M_HIGH && level > -29) )) (setting.mode == M_HIGH && level > -29) ||
(setting.mode == M_LOW && (markers[i].mtype & M_NOISE) && vbwSteps > 1))) //MAXPEAK increases noise marker, should reduce span.
color = LCD_BRIGHT_COLOR_RED; color = LCD_BRIGHT_COLOR_RED;
else else
color = marker_color(markers[i].mtype); color = marker_color(markers[i].mtype);

@ -3320,7 +3320,7 @@ again: // Spur redu
} }
set_freq(ADF4351_LO, target_f); set_freq(ADF4351_LO, target_f);
#if 1 // Compensate frequency ADF4350 error with SI4468 #if 1 // Compensate frequency ADF4350 error with SI4468
if (actual_rbw_x10 < 3000 || setting.frequency_step < 100000) { if (actual_rbw_x10 < 10000 || setting.frequency_step < 100000) { //TODO always compensate for the moment as this eliminates artifacts at larger RBW
int32_t error_f = 0; int32_t error_f = 0;
if (real_old_freq[ADF4351_LO] > target_f) { if (real_old_freq[ADF4351_LO] > target_f) {
error_f = real_old_freq[ADF4351_LO] - target_f; error_f = real_old_freq[ADF4351_LO] - target_f;
@ -3588,11 +3588,13 @@ again: // Spur redu
my_step_delay = my_step_delay * 2; my_step_delay = my_step_delay * 2;
// if (LO_shifted) // || SI4463_offset_changed) // if (LO_shifted) // || SI4463_offset_changed)
// my_step_delay = my_step_delay * 2; // my_step_delay = my_step_delay * 2;
#if 0 // Always have some delay before measuring RSSI
if (old_R < 4 && actual_rbw_x10 >= 1000 && SI4463_frequency_changed && ADF4351_frequency_changed) { if (old_R < 4 && actual_rbw_x10 >= 1000 && SI4463_frequency_changed && ADF4351_frequency_changed) {
my_step_delay -= 200; // compensate for additional delay of setting SI4463 my_step_delay -= 200; // compensate for additional delay of setting SI4463
if (my_step_delay < 0) if (my_step_delay < 0)
my_step_delay = 0; my_step_delay = 0;
} }
#endif
my_microsecond_delay(my_step_delay * (old_R > 5 ? 8 : (old_R > 3 ? 2 : 1))); my_microsecond_delay(my_step_delay * (old_R > 5 ? 8 : (old_R > 3 ? 2 : 1)));
ADF4351_frequency_changed = false; ADF4351_frequency_changed = false;
SI4463_frequency_changed = false; SI4463_frequency_changed = false;
@ -3738,7 +3740,7 @@ static bool sweep(bool break_on_operation)
float vbw_rssi; float vbw_rssi;
#endif #endif
#endif #endif
clear_marker_cache();
again: // Waiting for a trigger jumps back to here again: // Waiting for a trigger jumps back to here
setting.measure_sweep_time_us = 0; // start measure sweep time setting.measure_sweep_time_us = 0; // start measure sweep time
// start_of_sweep_timestamp = chVTGetSystemTimeX(); // Will be set in perform // start_of_sweep_timestamp = chVTGetSystemTimeX(); // Will be set in perform
@ -4103,6 +4105,11 @@ static volatile int dummy;
temppeakLevel = actual_t[0]; temppeakLevel = actual_t[0];
max_index[0] = 0; max_index[0] = 0;
downslope = true; downslope = true;
peakLevel = temppeakLevel;
}
if (cur_max == 0 && peakLevel < actual_t[i]) {
peakIndex = i;
peakLevel = actual_t[i];
} }
if (downslope) { // If in down slope peak finding if (downslope) { // If in down slope peak finding
if (temppeakLevel > actual_t[i]) { // Follow down if (temppeakLevel > actual_t[i]) { // Follow down
@ -4403,6 +4410,10 @@ static volatile int dummy;
// --------------------- set tracking markers from maximum table ----------------- // --------------------- set tracking markers from maximum table -----------------
if (cur_max == 0) {
max_index[0] = peakIndex;
cur_max = 1;
}
if (MODE_INPUT(setting.mode)) { // Assign maxima found to tracking markers if (MODE_INPUT(setting.mode)) { // Assign maxima found to tracking markers
int i = 0; int i = 0;
int m = 0; int m = 0;
@ -4525,8 +4536,11 @@ static volatile int dummy;
} }
#endif #endif
peakIndex = max_index[0]; if (cur_max > 0) {
peakLevel = actual_t[peakIndex]; peakIndex = max_index[0];
peakLevel = actual_t[peakIndex];
cur_max = 1;
}
peakFreq = frequencies[peakIndex]; peakFreq = frequencies[peakIndex];
min_level = temp_min_level; min_level = temp_min_level;
} }
@ -4590,6 +4604,11 @@ static volatile int dummy;
// palSetLine(LINE_LED); // palSetLine(LINE_LED);
#endif #endif
// Enable traces at sweep complete for redraw
if (enable_after_complete){
TRACE_ENABLE(enable_after_complete);
enable_after_complete = 0;
}
return true; return true;
} }
@ -5732,9 +5751,11 @@ quit:
shell_printf("%6.2f ", (first_level - peakLevel)*10.0 ); shell_printf("%6.2f ", (first_level - peakLevel)*10.0 );
if (setting.test_argument != 0) if (setting.test_argument != 0)
break; break;
if (operation_requested) goto abort;
} }
} }
#endif #endif
abort:
shell_printf("\n\r"); shell_printf("\n\r");
setting.R = 0; setting.R = 0;
switch_SI4463_RSSI_correction(true); switch_SI4463_RSSI_correction(true);
@ -5752,6 +5773,7 @@ quit:
if (setting.test_argument != 0) if (setting.test_argument != 0)
j = setting.test_argument; j = setting.test_argument;
test_prepare(TEST_NOISE); test_prepare(TEST_NOISE);
markers[0].mtype = M_NOISE | M_AVER;
setting.rbw_x10 = force_rbw(j); setting.rbw_x10 = force_rbw(j);
setting.extra_lna = true; setting.extra_lna = true;
osalThreadSleepMilliseconds(200); osalThreadSleepMilliseconds(200);
@ -5786,7 +5808,7 @@ quit:
setting.rbw_x10 = force_rbw(j); setting.rbw_x10 = force_rbw(j);
setting.extra_lna = true; setting.extra_lna = true;
osalThreadSleepMilliseconds(200); osalThreadSleepMilliseconds(200);
markers[0].mtype = M_NOISE | M_AVER;
set_sweep_frequency(ST_SPAN, (freq_t)(setting.rbw_x10 * (1000 << k))); set_sweep_frequency(ST_SPAN, (freq_t)(setting.rbw_x10 * (1000 << k)));
set_average(AV_100); set_average(AV_100);
test_acquire(TC_LEVEL); // Acquire test test_acquire(TC_LEVEL); // Acquire test
@ -5806,6 +5828,7 @@ quit:
shell_printf("%6.2f ", (first_level - peakLevel)*10.0 ); shell_printf("%6.2f ", (first_level - peakLevel)*10.0 );
if (setting.test_argument != 0) if (setting.test_argument != 0)
break; break;
if (operation_requested) goto abort;
} }
} }
#endif #endif
@ -5887,7 +5910,9 @@ again:
set_refer_output(0); set_refer_output(0);
set_sweep_frequency(ST_STOP, 60000000); set_sweep_frequency(ST_STOP, 60000000);
int test_case = TEST_POWER; int test_case = TEST_POWER;
#ifdef TINYSA4
set_extra_lna(calibrate_lna); set_extra_lna(calibrate_lna);
#endif
set_average(AV_100); set_average(AV_100);
for (int m=1; m<20; m++) { for (int m=1; m<20; m++) {
test_acquire(test_case); // Acquire test test_acquire(test_case); // Acquire test
@ -5996,7 +6021,9 @@ quit:
sweep_mode = SWEEP_ENABLE; sweep_mode = SWEEP_ENABLE;
// set_refer_output(-1); // set_refer_output(-1);
// reset_settings(M_LOW); // reset_settings(M_LOW);
#ifdef TINYSA4
set_extra_lna(false); set_extra_lna(false);
#endif
set_average(AV_OFF); set_average(AV_OFF);
} }

@ -1523,15 +1523,15 @@ typedef struct {
static const RBW_t RBW_choices[] = static const RBW_t RBW_choices[] =
{ {
// BW register corr freq // BW register corr freq
{SI4463_RBW_02kHz, 14,3,22}, {SI4463_RBW_02kHz, 21,3, 26},
{SI4463_RBW_1kHz, 18,10,9}, {SI4463_RBW_1kHz, 26,10, 10},
{SI4463_RBW_3kHz, 14,30,8}, {SI4463_RBW_3kHz, 22,30, 8},
{SI4463_RBW_10kHz, 6,100,6}, {SI4463_RBW_10kHz, 12,100, 9},
{SI4463_RBW_30kHz, 11,300,2}, {SI4463_RBW_30kHz, 12,300, 12},
{SI4463_RBW_100kHz, 6,1000,-1}, {SI4463_RBW_100kHz, 7,1000, 10},
{SI4463_RBW_300kHz, 6,3000,-15}, {SI4463_RBW_300kHz, 8,3000, 7},
{SI4463_RBW_600kHz, 6,6000,-21}, {SI4463_RBW_600kHz, 8,6000, 15},
{SI4463_RBW_850kHz,16,8500,-29}, {SI4463_RBW_850kHz,18,8500, 15},
}; };
const uint8_t SI4432_RBW_count = ((int)(sizeof(RBW_choices)/sizeof(RBW_t))); const uint8_t SI4432_RBW_count = ((int)(sizeof(RBW_choices)/sizeof(RBW_t)));

@ -1347,7 +1347,7 @@ static UI_FUNCTION_ADV_CALLBACK(menu_measure_acb)
case M_NF: // noise figure case M_NF: // noise figure
// reset_settings(setting.mode); // reset_settings(setting.mode);
markers[0].enabled = M_ENABLED; markers[0].enabled = M_ENABLED;
markers[0].mtype = M_NOISE; // Not tracking markers[0].mtype = M_NOISE | M_AVER; // Not tracking
set_extra_lna(true); set_extra_lna(true);
kp_help_text = "Amplifier Gain "; kp_help_text = "Amplifier Gain ";
float old_gain = setting.external_gain; float old_gain = setting.external_gain;

Loading…
Cancel
Save

Powered by TurnKey Linux.