Merge branch 'tinySA' into tinySA-v0.2

tinySA-v0.2
erikkaashoek 6 years ago
commit a595a256d0

@ -309,9 +309,9 @@ static const uint8_t ili9341_init_seq[] = {
// gamma set for curve 01/2/04/08
ILI9341_GAMMA_SET, 1, 0x01,
// positive gamma correction
//ILI9341_POSITIVE_GAMMA_CORRECTION, 15, 0x1F, 0x1A, 0x18, 0x0A, 0x0F, 0x06, 0x45, 0x87, 0x32, 0x0A, 0x07, 0x02, 0x07, 0x05, 0x00,
ILI9341_POSITIVE_GAMMA_CORRECTION, 15, 0x1F, 0x1A, 0x18, 0x0A, 0x0F, 0x06, 0x45, 0x87, 0x32, 0x0A, 0x07, 0x02, 0x07, 0x05, 0x00,
// negativ gamma correction
//ILI9341_NEGATIVE_GAMMA_CORRECTION, 15, 0x00, 0x25, 0x27, 0x05, 0x10, 0x09, 0x3A, 0x78, 0x4D, 0x05, 0x18, 0x0D, 0x38, 0x3A, 0x1F,
ILI9341_NEGATIVE_GAMMA_CORRECTION, 15, 0x00, 0x25, 0x27, 0x05, 0x10, 0x09, 0x3A, 0x78, 0x4D, 0x05, 0x18, 0x0D, 0x38, 0x3A, 0x1F,
// Column Address Set
//ILI9341_COLUMN_ADDRESS_SET, 4, 0x00, 0x00, 0x01, 0x3f, // width 320
// Page Address Set
@ -609,7 +609,7 @@ void ili9341_drawstring_7x13(const char *str, int x, int y)
while (*str) {
uint8_t ch = *str++;
const uint16_t *char_buf = &x7x13b_bits[(ch * 13)]; // All chars start at row 2
blit16BitWidthBitmap(x, y, 7, 12, char_buf); // Only 'Q' has 12 rows
blit16BitWidthBitmap(x, y, 7, 13, char_buf); // Only 'Q' has 12 rows, 'g' requires 13 rows
x += 7;
}
}

@ -201,7 +201,7 @@
/*
* UART driver system settings.
*/
#define STM32_UART_USE_USART1 FALSE
#define STM32_UART_USE_USART1 TRUE
#define STM32_UART_USE_USART2 FALSE
#define STM32_UART_USART1_IRQ_PRIORITY 3
#define STM32_UART_USART2_IRQ_PRIORITY 3

@ -365,6 +365,10 @@ void set_marker_search(int mode);
int marker_search(void);
int marker_search_left(int from);
int marker_search_right(int from);
int marker_search_left_max(int from);
int marker_search_right_max(int from);
int marker_search_left_min(int from);
int marker_search_right_min(int from);
// _request flag for update screen
#define REDRAW_CELLS (1<<0)
@ -380,7 +384,10 @@ extern volatile uint8_t redraw_request;
*/
// SPI bus revert byte order
//gggBBBbb RRRrrGGG
#define RGB565(r,g,b) ( (((g)&0x1c)<<11) | (((b)&0xf8)<<5) | ((r)&0xf8) | (((g)&0xe0)>>5) )
#define byteReverse16(x) (uint16_t)(((x) << 8) & 0xff00) | (((x) >> 8) & 0xff)
#define RGB565(r,g,b) byteReverse16( ((((uint16_t)r)<<8)&0b1111100000000000) | ((((uint16_t)g)<<3)&0b0000011111100000) | ((((uint16_t)b)>>3)&0b0000000000011111) )
//#define RGB565(r,g,b) ( (((g)&0x1c)<<11) | (((b)&0xf8)<<5) | ((r)&0xf8) | (((g)&0xe0)>>5) )
#define RGBHEX(hex) ( (((hex)&0x001c00)<<3) | (((hex)&0x0000f8)<<5) | (((hex)&0xf80000)>>16) | (((hex)&0x00e000)>>13) )
// Define size of screen buffer in pixels (one pixel 16bit size)
@ -651,7 +658,7 @@ void wait_user(void);
void calibrate(void);
enum {
M_OFF, M_IMD, M_OIP3, M_PHASE_NOISE
M_OFF, M_IMD, M_OIP3, M_PHASE_NOISE, M_STOP_BAND, M_PASS_BAND
};
/*EOF*/

@ -1141,10 +1141,10 @@ marker_position(int m, int t, int *x, int *y)
*y = CELL_Y(index);
}
static int greater(int x, int y) { return x > y; }
static int lesser(int x, int y) { return x < y; }
static int greater(int x, int y, int d) { return x - d > y; }
static int lesser(int x, int y, int d) { return x - d < y; }
static int (*compare)(int x, int y) = greater;
static int (*compare)(int x, int y, int d) = greater;
int
marker_search(void)
@ -1158,7 +1158,7 @@ marker_search(void)
int value = CELL_Y(trace_index[TRACE_ACTUAL][0]);
for (i = 0; i < sweep_points; i++) {
int new_value = CELL_Y(trace_index[TRACE_ACTUAL][i]);
if ((*compare)(value, new_value)) {
if ((*compare)(value, new_value, 0)) {
value = new_value;
found = i;
}
@ -1179,30 +1179,32 @@ search_is_greater(void)
return(compare == greater);
}
#define MINMAX_DELTA 10
int
marker_search_left(int from)
{
int i;
int found = -1;
#define MINMAX_DELTA -5
if (uistat.current_trace == -1)
return -1;
int value = CELL_Y(trace_index[TRACE_ACTUAL][from]);
for (i = from - 1; i >= 0; i--) {
int new_value = CELL_Y(trace_index[TRACE_ACTUAL][i]);
if ((*compare)(value + MINMAX_DELTA, new_value))
if ((*compare)(value, new_value, MINMAX_DELTA))
break;
value = new_value;
}
for (; i >= 0; i--) {
int new_value = CELL_Y(trace_index[TRACE_ACTUAL][i]);
if ((*compare)(new_value, value - MINMAX_DELTA)) {
if ((*compare)(new_value, value, -MINMAX_DELTA)) {
break;
}
found = i;
value = new_value;
if ((*compare)(value, new_value, 0)) {
found = i;
value = new_value;
}
}
return found;
}
@ -1218,18 +1220,19 @@ marker_search_right(int from)
int value = CELL_Y(trace_index[TRACE_ACTUAL][from]);
for (i = from + 1; i < sweep_points; i++) {
int new_value = CELL_Y(trace_index[TRACE_ACTUAL][i]);
if ((*compare)(value+MINMAX_DELTA, new_value))
if ((*compare)(value, new_value, MINMAX_DELTA))
break;
value = new_value;
}
for (; i < sweep_points; i++) {
int new_value = CELL_Y(trace_index[TRACE_ACTUAL][i]);
if ((*compare)(new_value, value-MINMAX_DELTA)) {
if ((*compare)(new_value, value, -MINMAX_DELTA)) {
break;
}
found = i;
value = new_value;
if ((*compare)(value, new_value, 0)) {
found = i;
value = new_value;
}
}
return found;
}
@ -1467,6 +1470,12 @@ draw_cell(int m, int n)
ili9341_bulk(OFFSETX + x0, OFFSETY + y0, w, h);
}
extern float peakLevel;
extern float min_level;
int w_max = -130;
int w_min = 0;
static void
draw_all_cells(bool flush_markmap)
{
@ -1512,6 +1521,35 @@ draw_all_cells(bool flush_markmap)
b = (k-128)*4;
}
#else
if (w_min > (int)min_level)
w_min = (int)min_level;
if (w_max < (int)peakLevel)
w_max = (int)peakLevel;
/*
def rgb(minimum, maximum, value):
minimum, maximum = float(minimum), float(maximum)
ratio = 2 * (value-minimum) / (maximum - minimum)
b = int(max(0, 255*(1 - ratio)))
r = int(max(0, 255*(ratio - 1)))
g = 255 - b - r
return r, g, b
*/
int r,g,b;
float ratio = (int)(510.0 * (actual_t[i] - w_min) / (w_max - w_min));
// float ratio = (i*2); // Uncomment for testing the waterfall colors
b = 255 - ratio;
if (b > 255) b = 255;
if (b < 0) b = 0;
r = ratio - 255;
if (r > 255) r = 255;
if (r < 0) r = 0;
// g = 255 - b; // if red is too weak to be seen.....
g = 255 - b - r;
#define gamma_correct(X,L) X = (L + X * (255 - L)/255 )
gamma_correct(r,128);
gamma_correct(g,128);
gamma_correct(b,128);
#if 0
int k = (actual_t[i]+120)* 2 * 8;
k &= 255;
unsigned int r=0,g=0,b=0;
@ -1529,6 +1567,7 @@ draw_all_cells(bool flush_markmap)
g = 255 - (k-192)*2;
r = 255;
}
#endif
#endif
spi_buffer[i] = RGB565(r,g,b);
}
@ -2079,6 +2118,7 @@ redraw_frame(void)
draw_cal_status();
}
int get_waterfall(void)
{
return(waterfall);
@ -2092,6 +2132,11 @@ toggle_waterfall(void)
ili9341_fill(5*5, HEIGHT, 320 - 5*5, 236-HEIGHT, 0);
waterfall = true;
fullscreen = false;
w_min = (int)min_level;
w_max = (int)peakLevel;
if (w_max < w_min + 20)
w_max = w_min + 20;
} else {
_height = HEIGHT_NOSCROLL;
waterfall = false;

@ -99,6 +99,13 @@ void reset_settings(int m)
set_sweep_frequency(ST_SPAN, 0);
break;
}
for (int i = 0; i< MARKERS_MAX; i++) {
markers[i].enabled = M_DISABLED;
markers[i].mtype = M_NORMAL;
}
markers[0].mtype = M_REFERENCE | M_TRACKING;
markers[0].enabled = M_ENABLED;
dirty = true;
}
@ -965,7 +972,7 @@ static bool sweep(bool break_on_operation)
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
} 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;
@ -974,7 +981,7 @@ static bool sweep(bool break_on_operation)
if (temppeakLevel < actual_t[i]) { // Follow up
temppeakIndex = i;
temppeakLevel = actual_t[i];
} else if (temppeakLevel - setting_noise > actual_t[i]) { // Local max found
} else if (actual_t[i] < temppeakLevel - setting_noise) { // Local max found
int j = 0; // Insertion index
while (j<cur_max && actual_t[max_index[j]] >= temppeakLevel) // Find where to insert
@ -1085,6 +1092,23 @@ static bool sweep(bool break_on_operation)
}
} else if (setting_measurement == M_PHASE_NOISE && markers[0].index > 10) {
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) {
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 = POINTS_COUNT - 1;
} else if (setting_measurement == M_PASS_BAND && markers[0].index > 10) {
int t = markers[0].index;
float v = actual_t[t];
while (t > 0 && actual_t[t] > v - 3.0)
t --;
if (t > 0)
markers[1].index = t;
t = markers[0].index;
while (t < POINTS_COUNT - 1 && actual_t[t] > v - 3.0)
t ++;
if (t < POINTS_COUNT - 1 )
markers[2].index = t;
}
#endif
peakIndex = max_index[0];
@ -1116,7 +1140,130 @@ static bool sweep(bool break_on_operation)
return true;
}
//------------------------------- SEARCH ---------------------------------------------
int
marker_search_left_max(int from)
{
int i;
int found = -1;
if (uistat.current_trace == -1)
return -1;
int value = actual_t[from];
for (i = from - 1; i >= 0; i--) {
int new_value = actual_t[i];
if (new_value < value) {
value = new_value;
found = i;
} else if (new_value > value + setting_noise )
break;
}
for (; i >= 0; i--) {
int new_value = actual_t[i];
if (new_value > value) {
value = new_value;
found = i;
} else if (new_value < value - setting_noise )
break;
}
return found;
}
int
marker_search_right_max(int from)
{
int i;
int found = -1;
if (uistat.current_trace == -1)
return -1;
int value = actual_t[from];
for (i = from + 1; i < sweep_points; i++) {
int new_value = actual_t[i];
if (new_value < value) { // follow down
value = new_value;
found = i;
} else if (new_value > value + setting_noise) // larger then lowest value + noise
break; // past the minimum
}
for (; i < sweep_points; i++) {
int new_value = actual_t[i];
if (new_value > value) { // follow up
value = new_value;
found = i;
} else if (new_value < value - setting_noise)
break;
}
return found;
}
#define MINMAX_DELTA 10
int
marker_search_left_min(int from)
{
int i;
int found = from;
if (uistat.current_trace == -1)
return -1;
int value = actual_t[from];
for (i = from - 1; i >= 0; i--) {
int new_value = actual_t[i];
if (new_value > value) {
value = new_value; // follow up
// found = i;
} else if (new_value < value - MINMAX_DELTA )
break; // past the maximum
}
for (; i >= 0; i--) {
int new_value = actual_t[i];
if (new_value < value) {
value = new_value; // follow down
found = i;
} else if (new_value > value + MINMAX_DELTA )
break;
}
return found;
}
int
marker_search_right_min(int from)
{
int i;
int found = from;
if (uistat.current_trace == -1)
return -1;
int value = actual_t[from];
for (i = from + 1; i < sweep_points; i++) {
int new_value = actual_t[i];
if (new_value > value) { // follow up
value = new_value;
// found = i;
} else if (new_value < value - MINMAX_DELTA) // less then largest value - noise
break; // past the maximum
}
for (; i < sweep_points; i++) {
int new_value = actual_t[i];
if (new_value < value) { // follow down
value = new_value;
found = i;
} else if (new_value > value + MINMAX_DELTA) // larger then smallest value + noise
break;
}
return found;
}
// -------------------------- CAL STATUS ---------------------------------------------
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 };
@ -1170,7 +1317,7 @@ void draw_cal_status(void)
ili9341_drawstring("Attn:", x, y);
y += YSTEP;
plot_printf(buf, BLEN, "%ddB", -setting_attenuate);
plot_printf(buf, BLEN, "%ddB", setting_attenuate);
buf[5]=0;
ili9341_drawstring(buf, x, y);

43
ui.c

@ -81,6 +81,7 @@ static uint8_t keypad_mode;
static uint8_t keypads_last_index;
static char kp_buf[NUMINPUT_LEN+1];
static int8_t kp_index = 0;
static char *kp_help_text = NULL;
static uint8_t menu_current_level = 0;
static int8_t selection = 0;
@ -781,16 +782,24 @@ menu_marker_search_cb(int item, uint8_t data)
return;
switch (data) {
case 0: /* search Left */
i = marker_search_left_min(markers[active_marker].index);
break;
case 1: /* search right */
i = marker_search_right_min(markers[active_marker].index);
break;
#if 0
case 0: /* maximum */
case 1: /* minimum */
set_marker_search(data);
i = marker_search();
break;
#endif
case 2: /* search Left */
i = marker_search_left(markers[active_marker].index);
i = marker_search_left_max(markers[active_marker].index);
break;
case 3: /* search right */
i = marker_search_right(markers[active_marker].index);
i = marker_search_right_max(markers[active_marker].index);
break;
case 4: /* tracking */
markers[active_marker].mtype ^= M_TRACKING;
@ -1382,9 +1391,9 @@ draw_numeric_input(const char *buf)
int focused = FALSE;
uint16_t xsim = 0b0010010000000000;
uint16_t fg = DEFAULT_MENU_TEXT_COLOR;
uint16_t bg = config.menu_normal_color;
for (i = 0, x = 64; i < 10 && buf[i]; i++, xsim<<=1) {
uint16_t fg = DEFAULT_MENU_TEXT_COLOR;
uint16_t bg = config.menu_normal_color;
int c = buf[i];
if (c == '.')
c = KP_PERIOD;
@ -1411,7 +1420,18 @@ draw_numeric_input(const char *buf)
x += xsim&0x8000 ? NUM_FONT_GET_WIDTH+2+8 : NUM_FONT_GET_WIDTH+2;
}
// erase last
ili9341_fill(x, 240-NUM_INPUT_HEIGHT+4, NUM_FONT_GET_WIDTH+2+8, NUM_FONT_GET_WIDTH+2+8, config.menu_normal_color);
// ili9341_fill(x, 240-NUM_INPUT_HEIGHT+4, NUM_FONT_GET_WIDTH+2+8, NUM_FONT_GET_WIDTH+2+8, config.menu_normal_color);
ili9341_fill(x, 240-NUM_INPUT_HEIGHT+4, 320-64, NUM_FONT_GET_WIDTH+2+8, config.menu_normal_color);
if (buf[0] == 0 && kp_help_text != NULL) {
ili9341_set_foreground(fg);
ili9341_set_background(bg);
const char *l1,*l2;
if (menu_is_multiline(kp_help_text, &l1, &l2)) {
ili9341_drawstring_7x13(l1, 64+NUM_FONT_GET_WIDTH+2, 240-NUM_INPUT_HEIGHT+1);
ili9341_drawstring_7x13(l2, 64+NUM_FONT_GET_WIDTH+2, 240-NUM_INPUT_HEIGHT/2 + 1);
} else
ili9341_drawstring_7x13(kp_help_text, 64+NUM_FONT_GET_WIDTH+2, 240-(FONT_GET_HEIGHT+NUM_INPUT_HEIGHT)/2);
}
}
static int
@ -1651,7 +1671,10 @@ static void
erase_menu_buttons(void)
{
// ili9341_fill(area_width, 0, 320 - area_width, area_height, DEFAULT_BG_COLOR);
ili9341_fill(320-MENU_BUTTON_WIDTH, 0, MENU_BUTTON_WIDTH, MENU_BUTTON_HEIGHT*8, DEFAULT_BG_COLOR);
if (current_menu_is_form())
ili9341_fill(5*5, 0,320-5*5, MENU_BUTTON_HEIGHT*8, DEFAULT_BG_COLOR);
else
ili9341_fill(320-MENU_BUTTON_WIDTH, 0, MENU_BUTTON_WIDTH, MENU_BUTTON_HEIGHT*8, DEFAULT_BG_COLOR);
draw_frequencies();
}
@ -1843,15 +1866,15 @@ lever_move_marker(int status)
if (active_marker >= 0 && markers[active_marker].enabled) {
if ((status & EVT_DOWN) && markers[active_marker].index > 0) {
markers[active_marker].index -= step;
if (markers[active_marker].index < 5)
markers[active_marker].index = 5 ;
if (markers[active_marker].index < 0)
markers[active_marker].index = 0 ;
markers[active_marker].frequency = frequencies[markers[active_marker].index];
redraw_marker(active_marker);
}
if ((status & EVT_UP) && markers[active_marker].index < sweep_points-1) {
markers[active_marker].index += step;
if (markers[active_marker].index > POINTS_COUNT-5)
markers[active_marker].index = POINTS_COUNT-5 ;
if (markers[active_marker].index > POINTS_COUNT-1)
markers[active_marker].index = POINTS_COUNT-1 ;
markers[active_marker].frequency = frequencies[markers[active_marker].index];
redraw_marker(active_marker);
}

@ -647,6 +647,7 @@ static void menu_measure_cb(int item, uint8_t data)
markers[i].mtype = M_DELTA | M_TRACKING;
}
markers[0].mtype = M_REFERENCE | M_TRACKING;
kp_help_text = "Frequency of fundamental";
ui_mode_keypad(KM_CENTER);
ui_process_keypad();
set_sweep_frequency(ST_START, 0);
@ -660,11 +661,16 @@ static void menu_measure_cb(int item, uint8_t data)
markers[i].mtype = M_DELTA | M_TRACKING;
}
markers[0].mtype = M_REFERENCE | M_TRACKING;
kp_help_text = "Frequency of left signal";
ui_mode_keypad(KM_CENTER);
ui_process_keypad();
ui_mode_keypad(KM_SPAN);
int left = uistat.value;
kp_help_text = "Right signal";
ui_mode_keypad(KM_CENTER);
ui_process_keypad();
set_sweep_frequency(ST_SPAN, uistat.value*4);
int right = uistat.value;
set_sweep_frequency(ST_CENTER, (left+right)/2);
set_sweep_frequency(ST_SPAN, (right - left)*4);
set_measurement(M_OIP3);
break;
case M_PHASE_NOISE: // Phase noise
@ -677,16 +683,53 @@ static void menu_measure_cb(int item, uint8_t data)
markers[0].mtype = M_REFERENCE | M_TRACKING;
markers[1].enabled = M_ENABLED;
markers[1].mtype = M_DELTA | M_NOISE;
kp_help_text = "Frequency of signal";
ui_mode_keypad(KM_CENTER);
ui_process_keypad();
kp_help_text = "Frequency offset";
ui_mode_keypad(KM_SPAN);
ui_process_keypad();
set_sweep_frequency(ST_SPAN, uistat.value*4);
set_measurement(M_PHASE_NOISE);
SetAverage(4);
break;
case M_STOP_BAND: // STop band measurement
reset_settings(GetMode());
markers[1].enabled = M_ENABLED;
markers[1].mtype = M_DELTA;
markers[2].enabled = M_ENABLED;
markers[2].mtype = M_DELTA;
kp_help_text = "Frequency of signal";
ui_mode_keypad(KM_CENTER);
ui_process_keypad();
kp_help_text = "Width of signal";
ui_mode_keypad(KM_SPAN);
ui_process_keypad();
set_sweep_frequency(ST_SPAN, uistat.value*4);
set_measurement(M_STOP_BAND);
// SetAverage(4);
break;
case M_PASS_BAND: // STop band measurement
reset_settings(GetMode());
markers[1].enabled = M_ENABLED;
markers[1].mtype = M_DELTA;
markers[2].enabled = M_ENABLED;
markers[2].mtype = M_DELTA;
kp_help_text = "Frequency of signal";
ui_mode_keypad(KM_CENTER);
ui_process_keypad();
kp_help_text = "Width of signal";
ui_mode_keypad(KM_SPAN);
ui_process_keypad();
set_sweep_frequency(ST_SPAN, uistat.value*2);
set_measurement(M_PASS_BAND);
// SetAverage(4);
break;
}
kp_help_text = NULL;
#endif
// selection = -1;
ui_mode_normal();
@ -1014,10 +1057,10 @@ static const menuitem_t menu_marker_type[] = {
const menuitem_t menu_marker_search[] = {
//{ MT_CALLBACK, "OFF", menu_marker_search_cb },
{ MT_CALLBACK, 0, "MAXIMUM", menu_marker_search_cb },
{ MT_CALLBACK, 1, "MINIMUM", menu_marker_search_cb },
{ MT_CALLBACK, 2, "\2SEARCH\0" S_LARROW" LEFT", menu_marker_search_cb },
{ MT_CALLBACK, 3, "\2SEARCH\0" S_RARROW" RIGHT", menu_marker_search_cb },
{ MT_CALLBACK, 0, "\2MIN\0" S_LARROW" LEFT", menu_marker_search_cb },
{ MT_CALLBACK, 1, "\2MIN\0" S_RARROW" RIGHT", menu_marker_search_cb },
{ MT_CALLBACK, 2, "\2MAX\0" S_LARROW" LEFT", menu_marker_search_cb },
{ MT_CALLBACK, 3, "\2MAX\0" S_RARROW" RIGHT", menu_marker_search_cb },
{ MT_CALLBACK, 4, "TRACKING", menu_marker_search_cb },
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
{ MT_NONE, 0, NULL, NULL } // sentinel
@ -1104,9 +1147,11 @@ static const menuitem_t menu_settings[] =
static const menuitem_t menu_measure[] = {
{ MT_CALLBACK, M_OFF, "OFF", menu_measure_cb},
{ MT_CALLBACK, M_IMD, "IMD", menu_measure_cb},
{ MT_CALLBACK, M_IMD, "MARMONICS",menu_measure_cb},
{ MT_CALLBACK, M_OIP3, "OIP3", menu_measure_cb},
{ MT_CALLBACK, M_PHASE_NOISE, "\2PHASE\0NOISE",menu_measure_cb},
{ MT_CALLBACK, M_STOP_BAND, "\2STOP\0BAND",menu_measure_cb},
{ MT_CALLBACK, M_PASS_BAND, "\2PASS\0BAND",menu_measure_cb},
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
{ MT_NONE, 0, NULL, NULL } // sentinel
};

Loading…
Cancel
Save

Powered by TurnKey Linux.