Measurements working

tinySA
erikkaashoek 6 years ago
parent ca687ea11b
commit 62e0120f22

@ -638,4 +638,10 @@ void SetRefpos(int);
void SetScale(int);
void SetRBW(int);
void SetRX(int);
extern int setting_measurement;
enum {
M_OFF, M_IMD, M_OIP3
};
/*EOF*/

@ -1,5 +1,4 @@
/* Copyright (c) 2014-2015, TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com
* All rights reserved.
/* All rights reserved.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -1100,7 +1099,7 @@ markmap_marker(int marker)
int t;
if (!markers[marker].enabled)
return;
for (t = TRACE_ACTUAL; t < TRACE_ACTUAL; t++) {
for (t = TRACE_ACTUAL; t <= TRACE_ACTUAL; t++) {
if (!trace[t].enabled)
continue;
index_t index = trace_index[t][markers[marker].index];
@ -1398,10 +1397,18 @@ draw_cell(int m, int n)
int x = CELL_X(index) - x0 - X_MARKER_OFFSET;
int y = CELL_Y(index) - y0 - Y_MARKER_OFFSET;
// Check marker icon on cell
#if 1
if (x + MARKER_WIDTH >= 0 && x < CELLWIDTH &&
y + MARKER_HEIGHT >= 0 && y < CELLHEIGHT)
draw_marker(x, y, marker_color[markers[i].mtype], i);
#else
if (x + MARKER_WIDTH >= 0 && x - MARKER_WIDTH < CELLWIDTH &&
y + MARKER_HEIGHT >= 0 && y - MARKER_HEIGHT < CELLHEIGHT)
draw_marker(x, y, marker_color[markers[i].mtype], i);
// draw_marker(x, y, config.trace_color[t], i);
#endif
// draw_marker(x, y, config.trace_color[t], i);
// }
}
#endif
@ -1814,6 +1821,23 @@ static void cell_draw_marker_info(int x0, int y0)
}
}
for (int i = 0; i < MARKER_COUNT; i++) {
if (i >= 2 && setting_measurement == M_OIP3 && markers[2].enabled && markers[3].enabled) {
float il = logmag(&(actual_t[markers[2].index]));
float ir = logmag(&(actual_t[markers[3].index]));
float sl = logmag(&(actual_t[markers[0].index]));
float sr = logmag(&(actual_t[markers[1].index]));
sl = (sl + sr)/2;
il = (il + ir)/2;
il = sl+ (sl - il)/2;
plot_printf(buf, sizeof buf, "OIP3: %4.1fdB", il);
j = 2;
int xpos = 1 + (j%2)*(WIDTH/2) + CELLOFFSETX - x0;
int ypos = 1 + (j/2)*(16) - y0;
cell_drawstring_7x13(buf, xpos, ypos);
break;
}
if (!markers[i].enabled)
continue;
int idx = markers[i].index;

@ -19,8 +19,11 @@ int setting_tracking = false;
int setting_modulation = MO_NONE;
int setting_step_delay = 0;
int setting_frequency_step;
int setting_decay;
int setting_noise;
float actual_rbw = 0;
float setting_vbw = 0;
int setting_measurement;
int vbwSteps = 1;
@ -48,6 +51,9 @@ void reset_settings(int m)
setting_modulation = MO_NONE;
setting_step_delay = 0;
setting_vbw = 0;
setting_decay=20;
setting_noise=20;
setting_measurement = M_OFF;
// setting_spur = 0;
switch(m) {
case M_LOW:
@ -92,6 +98,27 @@ int get_refer_output(void)
return(setting_refer);
}
void set_decay(int d)
{
if (d < 0 || d > 200)
return;
setting_decay = d;
dirty = true;
}
void set_noise(int d)
{
if (d < 5 || d > 200)
return;
setting_noise = d;
dirty = true;
}
void set_measurement(int m)
{
setting_measurement = m;
dirty = true;
}
void SetDrive(int d)
{
setting_drive = d;
@ -455,6 +482,64 @@ void update_rbw(void)
vbwSteps = 1;
dirty = true;
}
#define MAX_MAX 4
int
search_maximum(int m, int center, int span)
{
int from = center - span/2;
int found = false;
int to = center + span/2;
int cur_max = 0; // Always at least one maximum
int max_index[4];
temppeakIndex = 0;
temppeakLevel = actual_t[from];
max_index[cur_max] = from;
int downslope = true;
for (int i = from; i <= to; i++) {
if (downslope) {
if (temppeakLevel > actual_t[i]) { // Follow down
temppeakIndex = i; // Latest minimum
temppeakLevel = actual_t[i];
} else if (temppeakLevel + setting_noise < actual_t[i]) { // Local minimum found
temppeakIndex = i; // This is now the latest maximum
temppeakLevel = actual_t[i];
downslope = false;
}
} else {
if (temppeakLevel < actual_t[i]) { // Follow up
temppeakIndex = i;
temppeakLevel = actual_t[i];
} else if (temppeakLevel - setting_noise > actual_t[i]) { // Local max found
found = true;
int j = 0; // Insertion index
while (j<cur_max && actual_t[max_index[j]] >= temppeakLevel) // Find where to insert
j++;
if (j < MAX_MAX) { // Larger then one of the previous found
int k = MAX_MAX-1;
while (k > j) { // Shift to make room for max
max_index[k] = max_index[k-1];
// maxlevel_index[k] = maxlevel_index[k-1]; // Only for debugging
k--;
}
max_index[j] = temppeakIndex;
// maxlevel_index[j] = actual_t[temppeakIndex]; // Only for debugging
if (cur_max < MAX_MAX) {
cur_max++;
}
//STOP_PROFILE
}
temppeakIndex = i; // Latest minimum
temppeakLevel = actual_t[i];
downslope = true;
}
}
}
markers[m].index = max_index[0];
return found;
}
//static int spur_old_stepdelay = 0;
static const unsigned int spur_IF = 433900000;
@ -569,7 +654,6 @@ float perform(bool break_on_operation, int i, int32_t f, int tracking)
}
#define MAX_MAX 4
#define MAX_NOISE 10 // 10dB
int16_t max_index[MAX_MAX];
int16_t cur_max = 0;
@ -613,14 +697,14 @@ static bool sweep(bool break_on_operation)
actual_t[i] = RSSI;
age[i] = 0;
} else {
if (age[i] > 20)
if (age[i] > setting_decay)
actual_t[i] -= 0.5;
else
age[i] += 1;
}
break;
case AV_4: actual_t[i] = (actual_t[i] + RSSI) / 4.0; break;
case AV_16: actual_t[i] = (actual_t[i]*3 + RSSI) / 16.0; break;
case AV_4: actual_t[i] = (actual_t[i]*3 + RSSI) / 4.0; break;
case AV_16: actual_t[i] = (actual_t[i]*15 + RSSI) / 16.0; break;
}
}
#if 1
@ -629,14 +713,14 @@ static bool sweep(bool break_on_operation)
cur_max = 0; // Always at least one maximum
temppeakIndex = 0;
temppeakLevel = actual_t[i];
max_index[i] = 0;
max_index[0] = 0;
downslope = true;
}
if (downslope) {
if (temppeakLevel > actual_t[i]) { // Follow down
temppeakIndex = i; // Latest minimum
temppeakLevel = actual_t[i];
} else if (temppeakLevel + MAX_NOISE < actual_t[i]) { // Local minimum found
} else if (temppeakLevel + setting_noise < actual_t[i]) { // Local minimum found
temppeakIndex = i; // This is now the latest maximum
temppeakLevel = actual_t[i];
downslope = false;
@ -645,7 +729,7 @@ static bool sweep(bool break_on_operation)
if (temppeakLevel < actual_t[i]) { // Follow up
temppeakIndex = i;
temppeakLevel = actual_t[i];
} else if (temppeakLevel - MAX_NOISE > actual_t[i]) { // Local max found
} else if (temppeakLevel - setting_noise > actual_t[i]) { // Local max found
int j = 0; // Insertion index
while (j<cur_max && actual_t[max_index[j]] >= temppeakLevel) // Find where to insert
@ -713,6 +797,20 @@ static bool sweep(bool break_on_operation)
}
m++; // Try next marker
}
if (setting_measurement == M_IMD && markers[0].index > 10) {
markers[1].enabled = search_maximum(1, markers[0].index*2, 8);
markers[2].enabled = search_maximum(2, markers[0].index*3, 12);
markers[3].enabled = search_maximum(3, markers[0].index*4, 16);
} else if (setting_measurement == M_OIP3 && markers[0].index > 10 && markers[1].index > 10) {
int l = markers[0].index;
int r = markers[1].index;
if (r < l) {
l = markers[1].index;
r = markers[0].index;
}
markers[2].enabled = search_maximum(2, l - (r-l), 10);
markers[3].enabled = search_maximum(3, r + (r-l), 10);
}
peakIndex = max_index[0];
peakLevel = actual_t[peakIndex];
peakFreq = frequencies[peakIndex];
@ -742,7 +840,7 @@ static bool sweep(bool break_on_operation)
}
const char *averageText[] = { "OFF", "MIN", "MAX", "MAXD", "4", "16"};
const char *averageText[] = { "OFF", "MIN", "MAX", "MAXD", " A 4", "A 16"};
const char *dBText[] = { "1dB/", "2dB/", "5dB/", "10dB/", "20dB/"};
const int refMHz[] = { 30, 15, 10, 4, 3, 2, 1 };
@ -794,7 +892,7 @@ void draw_cal_status(void)
if (setting_average>0) {
ili9341_set_foreground(BRIGHT_COLOR_BLUE);
y += YSTEP*2;
ili9341_drawstring("Aver:", x, y);
ili9341_drawstring("Calc:", x, y);
y += YSTEP;
plot_printf(buf, BLEN, "%s",averageText[setting_average]);

13
ui.c

@ -1108,6 +1108,8 @@ menu_move_back(void)
return;
erase_menu_buttons();
menu_current_level--;
if (selection >= 0)
selection = 0;
ensure_selection();
draw_menu();
}
@ -1119,6 +1121,8 @@ menu_push_submenu(const menuitem_t *submenu)
if (menu_current_level < MENU_STACK_DEPTH_MAX-1)
menu_current_level++;
menu_stack[menu_current_level] = submenu;
if (selection >= 0)
selection = 0;
ensure_selection();
if (menu_is_form(submenu)) {
redraw_frame();
@ -1940,6 +1944,10 @@ ui_process_menu(void)
int status = btn_check();
if (status != 0) {
if (status & EVT_BUTTON_SINGLE_CLICK) {
if (selection == -1) {
selection = 0;
goto activate;
}
menu_invoke(selection);
} else {
do {
@ -1947,13 +1955,14 @@ ui_process_menu(void)
// close menu if next item is sentinel
if (menu_stack[menu_current_level][selection+1].type == MT_NONE)
goto menuclose;
if (!(menu_stack[menu_current_level][selection+1].type == MT_FORM | MT_NONE))
if (!(menu_stack[menu_current_level][selection+1].type == (MT_FORM | MT_NONE)))
selection++;
}
if (status & EVT_DOWN) {
if (! ( selection == 0 && menu_stack[menu_current_level][0].type & MT_FORM))
selection--;
}
activate:
ensure_selection();
draw_menu();
status = btn_wait_release();
@ -2210,7 +2219,7 @@ ui_process_keypad(void)
redraw_frame();
if (menu_is_form(menu_stack[menu_current_level])) {
ui_mode_menu(); //Reactivate menu after keypad
selection = 0;
selection = -1;
ensure_selection();
} else {
ui_mode_normal();

@ -5,6 +5,7 @@ static void menu_marker_type_cb(int item, uint8_t data);
void set_sweep_frequency(int type, uint32_t frequency);
uint32_t get_sweep_frequency(int type);
void clearDisplay(void);
void reset_settings(int);
//void ui_process_touch(void);
void SetPowerGrid(int);
void SetRefLevel(int);
@ -37,13 +38,18 @@ void ToggleLNA(void);
void ToggleAGC(void);
void redrawHisto(void);
void self_test(void);
void set_decay(int);
void set_noise(int);
extern int32_t frequencyExtra;
extern int setting_tracking;
extern int setting_drive;
extern int setting_lna;
extern int setting_agc;
extern int setting_decay;
extern int setting_noise;
void SetModulation(int);
extern int setting_modulation;
void set_measurement(int);
// extern int settingSpeed;
extern int setting_step_delay;
@ -51,7 +57,7 @@ extern int setting_step_delay;
enum {
KM_START=1, KM_STOP, KM_CENTER, KM_SPAN, KM_CW, KM_REFPOS, KM_SCALE, KM_ATTENUATION,
KM_ACTUALPOWER, KM_IF, KM_SAMPLETIME, KM_DRIVE, KM_LOWOUTLEVEL, KM_HIGHOUTLEVEL
KM_ACTUALPOWER, KM_IF, KM_SAMPLETIME, KM_DRIVE, KM_LOWOUTLEVEL, KM_DECAY, KM_NOISE
};
@ -157,7 +163,8 @@ static const keypads_t * const keypads_mode_tbl[] = {
keypads_level, // sample time
keypads_scale, // drive
keypads_level, // KM_LOWOUTLEVEL
keypads_level, // KM_HIGHOUTLEVEL
keypads_level, // KM_DECAY
keypads_level, // KM_NOISE
};
#ifdef __VNA__
@ -167,7 +174,7 @@ static const char * const keypad_mode_label[] = {
#endif
#ifdef __SA__
static const char * const keypad_mode_label[] = {
"error", "START", "STOP", "CENTER", "SPAN", "CW FREQ", "REFPOS", "SCALE", "\2ATTENUATE\0 0-31dB", "ACTUALPOWER", "IF", "SAMPLE TIME", "DRIVE", "LEVEL", "LEVEL"
"error", "START", "STOP", "CENTER", "SPAN", "CW FREQ", "REFPOS", "SCALE", "\2ATTENUATE\0 0-31dB", "ACTUALPOWER", "IF", "SAMPLE TIME", "DRIVE", "LEVEL", "LEVEL", "LEVEL"
};
#endif
@ -210,9 +217,7 @@ void menu_autosettings_cb(int item, uint8_t data)
{
(void)item;
(void)data;
int current_mode = GetMode();
SetMode(-1); // Force setmode to do something
SetMode(current_mode);
reset_settings(GetMode());
active_marker = 0;
for (int i = 1; i<MARKER_COUNT; i++ ) {
@ -346,7 +351,12 @@ static void menu_measure_cb(int item, uint8_t data)
{
(void)item;
switch(data) {
case 0: // IMD
case M_OFF: // Off
reset_settings(GetMode());
set_measurement(M_OFF);
break;
case M_IMD: // IMD
reset_settings(GetMode());
for (int i = 0; i< MARKERS_MAX; i++) {
markers[i].enabled = M_TRACKING_ENABLED;
markers[i].mtype = M_DELTA;
@ -356,8 +366,10 @@ static void menu_measure_cb(int item, uint8_t data)
ui_process_keypad();
set_sweep_frequency(ST_START, 0);
set_sweep_frequency(ST_STOP, uistat.value*5);
set_measurement(M_IMD);
break;
case 1:
case M_OIP3: // OIP3
reset_settings(GetMode());
for (int i = 0; i< MARKERS_MAX; i++) {
markers[i].enabled = M_TRACKING_ENABLED;
markers[i].mtype = M_DELTA;
@ -367,10 +379,8 @@ static void menu_measure_cb(int item, uint8_t data)
ui_process_keypad();
ui_mode_keypad(KM_SPAN);
ui_process_keypad();
break;
case 2:
break;
case 3:
set_sweep_frequency(ST_SPAN, uistat.value*4);
set_measurement(M_OIP3);
break;
}
menu_move_back();
@ -484,8 +494,8 @@ static void choose_active_marker(void)
static void menu_settings2_cb(int item, uint8_t data)
{
(void)data;
switch(item) {
(void)item;
switch(data) {
case 0:
ToggleAGC();
break;
@ -560,12 +570,12 @@ const menuitem_t menu_highoutputmode[] = {
};
static const menuitem_t menu_average[] = {
{ MT_CALLBACK, 0, " OFF", menu_average_cb},
{ MT_CALLBACK, 1, "\2 MIN\0 HOLD", menu_average_cb},
{ MT_CALLBACK, 2, "\2 MAX\0 HOLD", menu_average_cb},
{ MT_CALLBACK, 3, "\2 MAX\0 DECAY", menu_average_cb},
{ MT_CALLBACK, 4, " 4 ", menu_average_cb},
{ MT_CALLBACK, 5, " 16 ", menu_average_cb},
{ MT_CALLBACK, 0, "OFF", menu_average_cb},
{ MT_CALLBACK, 1, "\2MIN\0HOLD", menu_average_cb},
{ MT_CALLBACK, 2, "\2MAX\0HOLD", menu_average_cb},
{ MT_CALLBACK, 3, "\2MAX\0DECAY", menu_average_cb},
{ MT_CALLBACK, 4, "AVER 4", menu_average_cb},
{ MT_CALLBACK, 5, "AVER 16", menu_average_cb},
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
{ MT_NONE, 0, NULL, NULL } // sentinel
};
@ -625,7 +635,7 @@ static const menuitem_t menu_acquire[] = {
{ MT_CALLBACK, 0, "AUTO", menu_autosettings_cb},
{ MT_KEYPAD, KM_ATTENUATION, "ATTEN", NULL},
{ MT_SUBMENU,0, "RBW", menu_rbw},
{ MT_SUBMENU,0, "AVERAGE", menu_average},
{ MT_SUBMENU,0, "CALC", menu_average},
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
{ MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel
};
@ -633,7 +643,7 @@ static const menuitem_t menu_acquire[] = {
static const menuitem_t menu_acquirehigh[] = {
{ MT_CALLBACK, 0, "AUTO", menu_autosettings_cb},
{ MT_SUBMENU,0, "RBW", menu_rbw},
{ MT_SUBMENU,0, "AVERAGE", menu_average},
{ MT_SUBMENU,0, "CALC", menu_average},
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
{ MT_NONE, 0, NULL, NULL } // sentinel
};
@ -736,8 +746,10 @@ static const menuitem_t menu_dfu[] = {
static const menuitem_t menu_settings2[] =
{
{ MT_CALLBACK, 0, "AGC", menu_settings2_cb},
{ MT_CALLBACK, 0, "LNA", menu_settings2_cb},
{ MT_CALLBACK, 0, "BPF", menu_settings2_cb},
{ MT_CALLBACK, 1, "LNA", menu_settings2_cb},
{ MT_CALLBACK, 2, "BPF", menu_settings2_cb},
{ MT_KEYPAD, KM_DECAY, "\2HOLD\0TIME", NULL},
{ MT_KEYPAD, KM_NOISE, "\2NOISE\0LEVEL", NULL},
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
{ MT_NONE, 0, NULL, NULL } // sentinel
};
@ -754,8 +766,9 @@ static const menuitem_t menu_settings[] =
};
static const menuitem_t menu_measure[] = {
{ MT_CALLBACK, 0, "IMD", menu_measure_cb},
{ MT_CALLBACK, 1, "IIP3", menu_measure_cb},
{ MT_CALLBACK, M_OFF, "OFF", menu_measure_cb},
{ MT_CALLBACK, M_IMD, "IMD", menu_measure_cb},
{ MT_CALLBACK, M_OIP3, "OIP3", menu_measure_cb},
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
{ MT_NONE, 0, NULL, NULL } // sentinel
};
@ -763,7 +776,9 @@ static const menuitem_t menu_measure[] = {
static const menuitem_t menu_settingshigh2[] =
{
{ MT_CALLBACK, 0, "AGC", menu_settings2_cb},
{ MT_CALLBACK, 0, "LNA", menu_settings2_cb},
{ MT_CALLBACK, 1, "LNA", menu_settings2_cb},
{ MT_KEYPAD, KM_DECAY, "\2HOLD\0TIME", NULL},
{ MT_KEYPAD, KM_NOISE, "\2NOISE\0LEVEL", NULL},
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
{ MT_NONE, 0, NULL, NULL } // sentinel
};
@ -1025,9 +1040,13 @@ static void fetch_numeric_target(void)
uistat.value = -5 - uistat.value; // compensation for dB offset during low output mode
plot_printf(uistat.text, sizeof uistat.text, "%ddB", uistat.value);
break;
case KM_HIGHOUTLEVEL:
uistat.value = setting_drive*5 + 5;
plot_printf(uistat.text, sizeof uistat.text, "%3ddB", uistat.value);
case KM_DECAY:
uistat.value = setting_decay;
plot_printf(uistat.text, sizeof uistat.text, "%3d", uistat.value);
break;
case KM_NOISE:
uistat.value = setting_noise;
plot_printf(uistat.text, sizeof uistat.text, "%3d", uistat.value);
break;
}
@ -1089,9 +1108,11 @@ set_numeric_value(void)
uistat.value = -5 - uistat.value ; // compensation for dB offset during low output mode
SetAttenuation(uistat.value);
break;
case KM_HIGHOUTLEVEL:
uistat.value = uistat.value / 5 - 1 ; // compensation for dB offset during high output mode
SetDrive(uistat.value);
case KM_DECAY:
set_decay(uistat.value);
break;
case KM_NOISE:
set_noise(uistat.value);
break;
}
}

Loading…
Cancel
Save

Powered by TurnKey Linux.