Merge branch 'master' into tinySA-V4-SI4463

Removed_REF_marker
erikkaashoek 5 years ago
commit 9e2749ede0

@ -958,8 +958,8 @@ const uint8_t x5x7_bits[] =
+--------+ */
0b01100000|CHAR5x7_WIDTH_5px,
0b10010000,
0b10110000,
0b11010000,
0b10010000,
0b10010000,
0b10010000,
0b10010000,
0b01100000,

@ -1345,8 +1345,8 @@ const uint8_t x7x11b_bits[] =
0b01111000,
0b11001100,
0b11001100,
0b11011100,
0b11101100,
0b11001100,
0b11001100,
0b11001100,
0b11001100,
0b11001100,

@ -122,7 +122,8 @@ const char *info_about[]={
"Platform: " PLATFORM_NAME,
0 // sentinel
};
extern int dirty;
uint16_t dirty = true;
bool completed = false;
@ -201,6 +202,10 @@ static THD_FUNCTION(Thread1, arg)
}
#pragma GCC push_options
#pragma GCC optimize ("Os")
int
is_paused(void)
{
@ -2528,10 +2533,12 @@ static void shell_init_connection(void){
// Only USB console, shell_stream always on USB
#define PREPARE_STREAM
#if 0 // Not used
// Check connection as Active, if no suspend input
static bool shell_check_connect(void){
return SDU1.config->usbp->state == USB_ACTIVE;
}
#endif
// Init shell I/O connection over USB
static void shell_init_connection(void){
@ -2698,6 +2705,7 @@ static DACConfig dac1cfg1 = {
datamode: DAC_DHRM_12BIT_RIGHT
};
#pragma GCC pop_options
static const GPTConfig gpt4cfg = {
1000000, // 1 MHz timer clock.

@ -211,7 +211,8 @@ extern const char *info_about[];
extern const char * const unit_string[];
extern uint8_t signal_is_AM;
extern const int reffer_freq[];
extern uint32_t minFreq;
extern uint32_t maxFreq;
int level_is_calibrated(void);
void reset_settings(int);
void update_min_max_freq(void);
@ -419,7 +420,7 @@ extern const uint8_t numfont16x22[];
#define bFONT_GET_DATA(ch) ( &x7x11b_bits[(ch-bFONT_START_CHAR)*bFONT_GET_HEIGHT])
#define bFONT_GET_WIDTH(ch) (8-(x7x11b_bits[(ch-bFONT_START_CHAR)*bFONT_GET_HEIGHT]&7))
#if 1 // Set to 0 to save 3kByte
#if 1 // Set to 0 to save 3kByte and loose nice font
#define wFONT_START_CHAR 0x17
#define wFONT_MAX_WIDTH 12
#define wFONT_GET_HEIGHT 14
@ -759,7 +760,7 @@ typedef struct setting
// uint32_t _frequency1;
int mode;
uint16_t _sweep_points;
float attenuate;
int16_t attenuate_x2;
int auto_attenuation;
int atten_step;
uint32_t rbw_x10;
@ -820,9 +821,11 @@ typedef struct setting
float normalize_level; // Level to set normalize to, zero if not doing anything
int modulation_frequency;
int trigger_mode;
uint32_t checksum;
int slider_position;
int32_t slider_span;
int extra_lna;
int ultra;
uint32_t checksum; // must be last
}setting_t;
extern setting_t setting;
@ -1024,6 +1027,15 @@ typedef struct ui_button {
char text[32];
} ui_button_t;
typedef struct ui_slider {
uint8_t keypad;
uint8_t has_steps;
uint16_t slider_position;
uint16_t slider_step;
float min_value;
float max_value;
} ui_slider_t;
extern uistat_t uistat;
void ui_init(void);
void ui_show(void);

@ -25,7 +25,7 @@
#pragma GCC push_options
// #pragma GCC optimize ("O2") // Makes the code just a bit faster, disable during debugging.
#pragma GCC optimize ("Os") // Makes the code just a bit faster, disable during debugging.
#ifdef __SCROLL__
@ -517,6 +517,9 @@ draw_on_strut(int v0, int d, int color)
#define LOG_10_SQRT_50 ((float)0.84948500216800)
#define POW_30_20 ((float) 0.215443469)
#define POW_SQRT ((float)1.5234153789)
#define LOG_10_SQRT_50_x20_plus30 ((float)46.98970004336)
#define LOG_10_SQRT_50_x20_plus90 ((float)106.98970004336)
/*
* calculate log10f(abs(gamma))
*/
@ -535,11 +538,11 @@ value(const float v)
{
case U_DBMV:
// return v + 30.0 + 20.0*log10f(sqrt(50));
return v + 30.0 + 20.0*LOG_10_SQRT_50; //TODO convert constants to single float number as GCC compiler does runtime calculation
return v + LOG_10_SQRT_50_x20_plus30; // + 30.0 + 20.0*LOG_10_SQRT_50; //TODO convert constants to single float number as GCC compiler does runtime calculation
break;
case U_DBUV:
// return v + 90.0 + 20.0*log10f(sqrt(50.0)); //TODO convert constants to single float number as GCC compiler does runtime calculation
return v + 90.0 + 20.0*LOG_10_SQRT_50;
return v + LOG_10_SQRT_50_x20_plus90; // 90.0 + 20.0*LOG_10_SQRT_50;
break;
case U_VOLT:
// return pow(10, (v-30.0)/20.0) * sqrt((float)50.0);
@ -562,11 +565,11 @@ to_dBm(const float v)
{
case U_DBMV:
// return v - 30.0 - 20.0*log10f(sqrt(50));
return v - 30.0 - 20.0*LOG_10_SQRT_50;
return v - LOG_10_SQRT_50_x20_plus30; // (30.0 + 20.0*LOG_10_SQRT_50);
break;
case U_DBUV:
// return v - 90.0 - 20.0*log10f(sqrt(50.0)); //TODO convert constants to single float number as GCC compiler does runtime calculation
return v - 90.0 - 20.0*LOG_10_SQRT_50;
return v - LOG_10_SQRT_50_x20_plus90; // (90.0 + 20.0*LOG_10_SQRT_50);
break;
case U_VOLT:
// return log10f( v / (sqrt(50.0))) * 20.0 + 30.0 ;

@ -383,7 +383,7 @@ VNA_SHELL_FUNCTION(cmd_y)
shell_printf("\r\n");
#endif
}
#if 0 // not used
VNA_SHELL_FUNCTION(cmd_z)
{
static const char cmd_z_list[] = "t|r|i";
@ -409,7 +409,7 @@ VNA_SHELL_FUNCTION(cmd_z)
#endif
}
}
#endif
VNA_SHELL_FUNCTION(cmd_selftest)
{

@ -21,7 +21,7 @@
#include "stdlib.h"
#pragma GCC push_options
#pragma GCC optimize ("Os") // "Os" causes problem in selftest!!!!!!!!
#pragma GCC optimize ("Os")
//#define __DEBUG_AGC__ If set the AGC value will be shown in the stored trace and FAST_SWEEP rmmode will be disabled
@ -30,14 +30,14 @@
#undef __FAST_SWEEP__
#endif
#endif
int dirty = true;
// uint8_t dirty = true;
int scandirty = true;
setting_t setting;
uint32_t frequencies[POINTS_COUNT];
uint16_t actual_rbw_x10 = 0;
int vbwSteps = 1;
uint16_t vbwSteps = 1;
uint32_t minFreq = 0;
uint32_t maxFreq = 520000000;
@ -93,7 +93,7 @@ void reset_settings(int m)
setting.unit = U_DBM;
set_scale(10);
set_reflevel(-10);
setting.attenuate = 0;
setting.attenuate_x2 = 0;
setting.rbw_x10 = 0;
setting.average = 0;
setting.harmonic = 0;
@ -144,6 +144,9 @@ void reset_settings(int m)
setting.spur_removal = S_OFF;
#endif
setting.mirror_masking = 0;
setting.slider_position = 0;
setting.slider_span = 100000;
#endif
switch(m) {
case M_LOW:
@ -153,8 +156,8 @@ void reset_settings(int m)
set_sweep_frequency(ST_STOP, 2900000000); // TODO <----------------- temp ----------------------
else
set_sweep_frequency(ST_STOP, 800000000); // TODO <----------------- temp ----------------------
setting.attenuate = 0.0; // <---------------- WARNING -----------------
setting.auto_attenuation = false; // <---------------- WARNING -----------------
setting.attenuate_x2 = 0; // TODO <----------------- temp ---------------
setting.auto_attenuation = true;
setting.sweep_time_us = 0;
setting.lo_drive=1;
break;
@ -162,7 +165,7 @@ void reset_settings(int m)
case M_ULTRA:
set_sweep_frequency(ST_START, minFreq);
set_sweep_frequency(ST_STOP, maxFreq);
setting.attenuate = 0;
setting.attenuate_x2 = 0;
setting.sweep_time_us = 0;
break;
#endif
@ -185,7 +188,7 @@ void reset_settings(int m)
setting.sweep_time_us = 10*ONE_SECOND_TIME;
break;
}
for (int i = 0; i< MARKERS_MAX; i++) {
for (uint8_t i = 0; i< MARKERS_MAX; i++) {
markers[i].enabled = M_DISABLED;
markers[i].mtype = M_NORMAL;
}
@ -293,7 +296,7 @@ void set_measurement(int m)
for (int j = 0; j < setting._sweep_points; j++)
stored_t[j] = -150;
setting.linearity_step = 0;
setting.attenuate = 29.0;
setting.attenuate_x2 = 29*2;
setting.auto_attenuation = false;
}
#endif
@ -466,9 +469,9 @@ void set_auto_attenuation(void)
{
setting.auto_attenuation = true;
if (setting.mode == M_LOW) {
setting.attenuate = 30.0;
setting.attenuate_x2 = 60;
} else {
setting.attenuate = 0;
setting.attenuate_x2 = 0;
}
setting.atten_step = false;
dirty = true;
@ -481,18 +484,19 @@ void set_auto_reflevel(int v)
float get_attenuation(void)
{
float actual_attenuation = setting.attenuate_x2 / 2.0;
if (setting.mode == M_GENLOW) {
if (setting.atten_step)
return ( -(POWER_OFFSET + setting.attenuate - (setting.atten_step-1)*POWER_STEP + SWITCH_ATTENUATION));
return ( -(POWER_OFFSET + actual_attenuation - (setting.atten_step-1)*POWER_STEP + SWITCH_ATTENUATION));
else
return ( -POWER_OFFSET - setting.attenuate + (setting.rx_drive & 7) * 3);
return ( -POWER_OFFSET - actual_attenuation + (setting.rx_drive & 7) * 3);
} else if (setting.atten_step) {
if (setting.mode == M_LOW)
return setting.attenuate + RECEIVE_SWITCH_ATTENUATION;
return actual_attenuation + RECEIVE_SWITCH_ATTENUATION;
else
return setting.attenuate + SWITCH_ATTENUATION;
return actual_attenuation + SWITCH_ATTENUATION;
}
return(setting.attenuate);
return(actual_attenuation);
}
static pureRSSI_t get_signal_path_loss(void){
@ -507,7 +511,7 @@ static pureRSSI_t get_signal_path_loss(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) // Set the drive level of the LO
void set_level(float v) // Set the output level in dB in high/low output
{
if (setting.mode == M_GENHIGH) {
int d = 0;
@ -523,7 +527,7 @@ void set_level(float v) // Set the drive level of the LO
dirty = true;
}
void set_attenuation(float a) // Is used both in output mode and input mode
void set_attenuation(float a) // Is used both in low output mode and high/low input mode
{
if (setting.mode == M_GENLOW) {
a = a + POWER_OFFSET;
@ -565,9 +569,9 @@ void set_attenuation(float a) // Is used both in output mode and input mod
a=31.0;
if (setting.mode == M_HIGH) // No attenuator in high mode
a = 0;
if (setting.attenuate == a)
if (setting.attenuate_x2 == a*2)
return;
setting.attenuate = a;
setting.attenuate_x2 = a*2;
dirty = true;
}
@ -964,10 +968,12 @@ void set_scale(float t) {
round_reflevel_to_scale();
}
extern char low_level_help_text[12];
void set_offset(float offset)
{
setting.offset = offset;
plot_printf(low_level_help_text, sizeof low_level_help_text, "%+d..%+d", -76 + (int)offset, -6 + (int)offset);
force_set_markmap();
dirty = true; // No HW update required, only status panel refresh but need to ensure the cached value is updated in the calculation of the RSSI
}
@ -1085,7 +1091,7 @@ void apply_settings(void) // Ensure all settings in the setting structure
if (setting.mode == M_HIGH)
PE4302_Write_Byte(40); // Ensure defined input impedance of low port when using high input mode (power calibration)
else
PE4302_Write_Byte((int)(setting.attenuate * 2));
PE4302_Write_Byte((int)(setting.attenuate_x2));
#endif
if (setting.mode == M_LOW) {
@ -1373,7 +1379,7 @@ case M_ULTRA:
else
set_switch_off();
// SI4432_Receive(); For noise testing only
SI4432_Transmit(setting.drive);
SI4432_Transmit(setting.lo_drive);
// set_calibration_freq(setting.refer);
#endif
enable_rx_output(false);
@ -1421,7 +1427,7 @@ case M_GENLOW: // Mixed output from 0
} else {
set_switch_transmit();
}
SI4432_Transmit(setting.drive);
SI4432_Transmit(setting.rx_drive);
SI4432_Sel = SI4432_LO ;
if (setting.modulation == MO_EXTERNAL) {
@ -1459,12 +1465,12 @@ case M_GENHIGH: // Direct output from 1
set_switch_receive();
SI4432_Sel = SI4432_LO ;
if (setting.drive < 8) {
if (setting.lo_drive < 8) {
set_switch_off(); // use switch as attenuator
} else {
set_switch_transmit();
}
SI4432_Transmit(setting.drive);
SI4432_Transmit(setting.lo_drive);
#endif
#ifdef __SI4468__
SI4463_init_tx();
@ -1906,7 +1912,7 @@ modulation_again:
// ----------------------------------------------------- modulation for output modes ---------------------------------------
if (MODE_OUTPUT(setting.mode)){
if (setting.modulation == MO_AM) { // AM modulation
int p = setting.attenuate * 2 + am_modulation[modulation_counter];
int p = setting.attenuate_x2 + am_modulation[modulation_counter];
if (p>63) p = 63;
else if (p< 0) p = 0;
#ifdef __PE4302__
@ -1973,8 +1979,13 @@ modulation_again:
local_IF = DEFAULT_IF;
if (setting.mode == M_LOW) {
if (tracking) { // VERY SPECIAL CASE!!!!! Measure BPF
#if 0 // Isolation test
local_IF = lf;
lf = 0;
#else
local_IF += lf - reffer_freq[setting.refer]; // Offset so fundamental of reffer is visible
lf = reffer_freq[setting.refer];
#endif
} else {
if(!in_selftest && avoid_spur(lf)) { // check if alternate IF is needed to avoid spur.
local_IF = spur_alternate_IF;
@ -2052,7 +2063,7 @@ modulation_again:
#endif
{ // Else set LO ('s)
uint32_t target_f;
if (setting.mode == M_LOW && !setting.tracking && S_STATE(setting.below_IF)) // if in low input mode and below IF
if (setting.mode == M_LOW && !setting.tracking && S_STATE(setting.below_IF)) // if in low input mode and below IF
target_f = local_IF-lf; // set LO SI4432 to below IF frequency
else
target_f = local_IF+lf; // otherwise to above IF, local_IF == 0 in high mode
@ -2620,17 +2631,17 @@ sweep_again: // stay in sweep loop when output mo
int changed = false;
int delta = 0;
int actual_max_level = (max_index[0] == 0 ? -100 :(int) (actual_t[max_index[0]] - get_attenuation()) ); // If no max found reduce attenuation
if (actual_max_level < AUTO_TARGET_LEVEL && setting.attenuate > 0) {
if (actual_max_level < AUTO_TARGET_LEVEL && setting.attenuate_x2 > 0) {
delta = - (AUTO_TARGET_LEVEL - actual_max_level);
} else if (actual_max_level > AUTO_TARGET_LEVEL && setting.attenuate < 30) {
} else if (actual_max_level > AUTO_TARGET_LEVEL && setting.attenuate_x2 < 60) {
delta = actual_max_level - AUTO_TARGET_LEVEL;
}
if ((chVTGetSystemTimeX() - sweep_elapsed > 10000 && delta != 0) || delta > 5 ) {
setting.attenuate += delta;
if (setting.attenuate < 0)
setting.attenuate= 0;
if (setting.attenuate > 30)
setting.attenuate = 30;
setting.attenuate_x2 += delta + delta;
if (setting.attenuate_x2 < 0)
setting.attenuate_x2= 0;
if (setting.attenuate_x2 > 60)
setting.attenuate_x2 = 60;
changed = true;
sweep_elapsed = chVTGetSystemTimeX();
}
@ -2905,7 +2916,7 @@ sweep_again: // stay in sweep loop when output mo
#ifdef __LINEARITY__
//---------------- in Linearity measurement the attenuation has to be adapted ------------------
if (setting.measurement == M_LINEARITY && setting.linearity_step < sweep_points) {
setting.attenuate = 29.0 - setting.linearity_step * 30.0 / (sweep_points);
setting.attenuate_x2 = (29.0 - setting.linearity_step * 30.0 / (sweep_points))*2.0;
dirty = true;
stored_t[setting.linearity_step] = peakLevel;
setting.linearity_step++;
@ -3071,11 +3082,11 @@ enum {
TP_SILENT, TPH_SILENT, TP_10MHZ, TP_10MHZEXTRA, TP_10MHZ_SWITCH, TP_30MHZ, TPH_30MHZ, TPH_30MHZ_SWITCH
};
#define TEST_COUNT 21
#define TEST_COUNT (sizeof test_case / sizeof test_case[0])
#define W2P(w) (sweep_points * w / 100) // convert width in % to actual sweep points
static const struct {
typedef struct test_case {
int kind;
int setup;
float center; // In MHz
@ -3083,7 +3094,9 @@ static const struct {
float pass;
int width;
float stop;
} test_case [TEST_COUNT] =
} test_case_t;
const test_case_t test_case [] =
{// Condition Preparation Center Span Pass Width(%)Stop
{TC_BELOW, TP_SILENT, 0.005, 0.01, 0, 0, 0}, // 1 Zero Hz leakage
{TC_BELOW, TP_SILENT, 0.015, 0.01, -30, 0, 0}, // 2 Phase noise of zero Hz
@ -3092,7 +3105,7 @@ static const struct {
#define TEST_SILENCE 4
{TC_BELOW, TP_SILENT, 200, 100, -75, 0, 0}, // 5 Wide band noise floor low mode
{TC_BELOW, TPH_SILENT, 600, 720, -75, 0, 0}, // 6 Wide band noise floor high mode
{TC_SIGNAL, TP_10MHZEXTRA, 10, 8, -20, 27, -80 }, // 7 BPF loss and stop band
{TC_SIGNAL, TP_10MHZEXTRA, 10, 7, -20, 27, -80 }, // 7 BPF loss and stop band
{TC_FLAT, TP_10MHZEXTRA, 10, 4, -18, 9, -60}, // 8 BPF pass band flatness
{TC_BELOW, TP_30MHZ, 400, 60, -75, 0, -75}, // 9 LPF cutoff
{TC_SIGNAL, TP_10MHZ_SWITCH,20, 7, -39, 10, -60 }, // 10 Switch isolation using high attenuation
@ -3122,8 +3135,8 @@ static const char *(test_text [4]) =
{
"Waiting", "Pass", "Fail", "Critical"
};
static const char *(test_fail_cause [TEST_COUNT]);
static const char *(test_fail_cause [TEST_COUNT]);
static int test_status[TEST_COUNT];
static int show_test_info = FALSE;
static volatile int test_wait = false;
@ -3375,7 +3388,7 @@ common_silent:
set_mode(M_LOW);
setting.tracking = true; //Sweep BPF
setting.auto_IF = false;
setting.frequency_IF = DEFAULT_IF; // Center on SAW filters
setting.frequency_IF = DEFAULT_IF+200000; // Center on SAW filters
set_refer_output(2);
goto common;
case TP_10MHZ: // 10MHz input
@ -3470,7 +3483,7 @@ void self_test(int test)
reset_settings(M_LOW); // Make sure we are in a defined state
in_selftest = true;
menu_autosettings_cb(0);
for (int i=0; i < TEST_COUNT; i++) { // All test cases waiting
for (uint16_t i=0; i < TEST_COUNT; i++) { // All test cases waiting
if (test_case[i].kind == TC_END)
break;
test_status[i] = TS_WAITING;
@ -3489,7 +3502,7 @@ void self_test(int test)
test_step = TEST_END;
ili9341_set_foreground(LCD_BRIGHT_COLOR_RED);
ili9341_drawstring_7x13("Signal level too low", 30, 140);
ili9341_drawstring_7x13("Check cable between High and Low connectors", 30, 160);
ili9341_drawstring_7x13("Did you connect high and low ports with cable?", 0, 210);
goto resume2;
}

166
ui.c

@ -88,6 +88,16 @@ static char *kp_help_text = NULL;
static uint8_t menu_current_level = 0;
static int selection = 0;
static const uint8_t slider_bitmap[]=
{
_BMP8(0b11111110),
_BMP8(0b11111110),
_BMP8(0b11111110),
_BMP8(0b01111100),
_BMP8(0b00111000),
_BMP8(0b00010000)
};
// Button definition (used in MT_ADV_CALLBACK for custom)
#define BUTTON_ICON_NONE -1
#define BUTTON_ICON_NOCHECK 0
@ -215,7 +225,7 @@ static int btn_wait_release(void)
}
// ADC read count for measure X and Y (2^N count)
#define TOUCH_X_N 3
#define TOUCH_X_N 4
#define TOUCH_Y_N 3
static int
touch_measure_y(void)
@ -289,8 +299,13 @@ touch_check(void)
{
int stat = touch_status();
if (stat) {
static int prev_x=0;
int y = touch_measure_y();
int x = touch_measure_x();
#define X_NOISE 5
if (x > prev_x - X_NOISE && x < prev_x + X_NOISE) // avoid noise
x = prev_x;
prev_x = x;
touch_prepare_sense();
if (touch_status())
{
@ -1843,6 +1858,21 @@ draw_menu_buttons(const menuitem_t *menu)
blit8BitWidthBitmap(button_start+MENU_FORM_WIDTH- FORM_ICON_WIDTH-8,y+(button_height-FORM_ICON_HEIGHT)/2,FORM_ICON_WIDTH,FORM_ICON_HEIGHT,&right_icons[((menu[i].data >>0)&0xf)*2*FORM_ICON_HEIGHT]);
}
#endif
int local_slider_positions = 0;
if (MT_MASK(menu[i].type) == MT_KEYPAD) {
if (menu[i].data == KM_CENTER) {
local_slider_positions = LCD_WIDTH/2+setting.slider_position;
goto draw_slider;
} else if (menu[i].data == KM_LOWOUTLEVEL) {
local_slider_positions = (get_attenuation() + 76 ) * MENU_FORM_WIDTH / 70 + OFFSETX;
goto draw_slider;
}
}
if (MT_MASK(menu[i].type) == MT_ADV_CALLBACK && menu[i].reference == menu_sdrive_acb) {
local_slider_positions = (menu_drive_value[setting.lo_drive] + 38 ) * MENU_FORM_WIDTH / 51 + OFFSETX;
draw_slider:
blit8BitWidthBitmap(local_slider_positions - 4, y, 7, 6, slider_bitmap);
}
} else {
int button_width = MENU_BUTTON_WIDTH;
int button_start = LCD_WIDTH - MENU_BUTTON_WIDTH;
@ -1874,6 +1904,28 @@ draw_menu_buttons(const menuitem_t *menu)
static systime_t prev_touch_time = 0;
static int prev_touch_button = -1;
enum { SL_UNKNOWN, SL_SPAN, SL_MOVE};
void set_keypad_value(int v)
{
keypad_mode = v;
set_numeric_value();
}
void check_frequency_slider(uint32_t slider_freq)
{
if ( (maxFreq - minFreq) < (uint32_t)setting.slider_span ) {
setting.slider_span = maxFreq - minFreq; // absolute mode with max step size
}
uint32_t half_span = setting.slider_span >> 1;
if (minFreq + (uint32_t)half_span > slider_freq) {
setting.slider_position -= (minFreq + half_span - slider_freq) / (setting.slider_span /MENU_FORM_WIDTH); // reposition if needed
}
if (maxFreq < slider_freq + (uint32_t)half_span) {
setting.slider_position += (slider_freq + half_span - maxFreq) / (setting.slider_span /MENU_FORM_WIDTH); // reposition if needed
}
}
static void
menu_select_touch(int i)
@ -1882,49 +1934,115 @@ menu_select_touch(int i)
draw_menu();
#if 1 // drag values
const menuitem_t *menu = menu_stack[menu_current_level];
int keypad = menu[i].data;
prev_touch_time = chVTGetSystemTimeX();
if (menu_is_form(menu) && MT_MASK(menu[i].type) == MT_KEYPAD){
int touch_x, touch_y;
touch_position(&touch_x, &touch_y);
int touch_x, touch_y, prev_touch_x = 0;
// touch_position(&touch_x, &touch_y);
systime_t dt = 0;
while (touch_check() != EVT_TOUCH_RELEASED) {
int mode = SL_UNKNOWN;
while (touch_check() != EVT_TOUCH_NONE) {
systime_t ticks = chVTGetSystemTimeX();
if (prev_touch_button != i) { // new button, initialize
prev_touch_time = ticks;
prev_touch_button = i;
}
dt = ticks - prev_touch_time;
if (dt > BUTTON_DOWN_LONG_TICKS) {
int v = menu[i].data;
touch_position(&touch_x, &touch_y);
if (touch_x != prev_touch_x /* - 1 || prev_touch_x + 1 < touch_x */ ) {
int old_keypad_mode = keypad_mode;
keypad_mode = v;
keypad_mode = keypad;
fetch_numeric_target();
float m = 1.0;
#define TOUCH_DEAD_ZONE 5
if (touch_x < LCD_WIDTH/2 - TOUCH_DEAD_ZONE) {
m = 1 / (1 + pow(10, -6 + ((LCD_WIDTH/2 - TOUCH_DEAD_ZONE) - touch_x)/20.0));
} else if (touch_x > LCD_WIDTH/2 + 10) {
m = 1 + pow(10, -6 + (touch_x - (LCD_WIDTH/2 + TOUCH_DEAD_ZONE))/20.0);
int new_slider = touch_x - LCD_WIDTH/2;
if (new_slider < -MENU_FORM_WIDTH/2)
new_slider = -MENU_FORM_WIDTH/2;
if (new_slider > MENU_FORM_WIDTH/2)
new_slider = MENU_FORM_WIDTH/2;
if (menu_is_form(menu) && MT_MASK(menu[i].type) == MT_KEYPAD && keypad == KM_CENTER){
#define TOUCH_DEAD_ZONE 40
if (mode == SL_UNKNOWN ) {
if (setting.slider_position - TOUCH_DEAD_ZONE < new_slider && new_slider < setting.slider_position + TOUCH_DEAD_ZONE) { // Pick up slider
mode = SL_MOVE;
} else {
mode = SL_SPAN;
goto first_span;
}
}
if (mode == SL_MOVE ) {
uistat.value = uistat.value - setting.slider_position * (setting.slider_span/MENU_FORM_WIDTH) + new_slider * (setting.slider_span/MENU_FORM_WIDTH);
if (uistat.value < minFreq)
uistat.value = minFreq;
if (uistat.value > maxFreq)
uistat.value = maxFreq;
setting.slider_position = new_slider;
set_keypad_value(keypad);
perform(false, 0, (uint32_t)uistat.value, false);
draw_menu();
} else if (mode == SL_SPAN ){
uint32_t slider_freq;
first_span:
slider_freq = (uint32_t) uistat.value;
int pw=new_slider + LCD_WIDTH/2;
setting.slider_position = pw - LCD_WIDTH/2; // Show delta on slider
setting.slider_span = 10;
while (pw>0) {
setting.slider_span += setting.slider_span;
pw -= 12;
if (pw <=0)
break;
setting.slider_span += setting.slider_span + (setting.slider_span >>1);
pw -= 12;
if (pw<=0)
break;
setting.slider_span *= 2;
pw -= 12;
}
if ((uint32_t)setting.slider_span > (maxFreq - minFreq))
setting.slider_span = (maxFreq - minFreq);
uint32_t old_minFreq = minFreq; // Save when in high mode
minFreq = 0; // And set minFreq to 0 for span display
uistat.value = setting.slider_span;
set_keypad_value(keypad);
center_text[0] = 'S';
center_text[1] = 'P';
center_text[2] = 'A';
center_text[3] = 'N';
draw_menu(); // Show slider span
minFreq = old_minFreq; // and restore minFreq
uistat.value = (float) slider_freq; // and restore current slider freq
set_keypad_value(keypad);
center_text[0] = 'F';
center_text[1] = 'R';
center_text[2] = 'E';
center_text[3] = 'Q';
setting.slider_position = 0; // reset slider after span change
check_frequency_slider(slider_freq);
}
} else if (menu_is_form(menu) && MT_MASK(menu[i].type) == MT_KEYPAD && keypad == KM_LOWOUTLEVEL) {
uistat.value = setting.offset + (touch_x - OFFSETX) *( -6 - -76) / MENU_FORM_WIDTH + -76;
set_keypad_value(keypad);
apply:
perform(false, 0, get_sweep_frequency(ST_CENTER), false);
draw_menu();
// }
} else if (MT_MASK(menu[i].type) == MT_ADV_CALLBACK && menu[i].reference == menu_sdrive_acb) {
set_level( (touch_x - OFFSETX) *( 13 - -38) / MENU_FORM_WIDTH + -38 );
goto apply;
}
uistat.value *= m;
set_numeric_value();
// selection = -1;
draw_menu();
keypad_mode = old_keypad_mode;
return;
}
}
prev_touch_x = touch_x;
}
if (dt > BUTTON_DOWN_LONG_TICKS) {
selection = -1;
draw_menu();
return;
}
setting.slider_position = 0; // Reset slider when entering frequency
prev_touch_button = -1;
} else
#endif
touch_wait_release();
// touch_wait_release();
selection = -1;
menu_invoke(i);
}

@ -402,11 +402,17 @@ static const keypads_t keypads_time[] = {
};
enum {
KM_START, KM_STOP, KM_CENTER, KM_SPAN, KM_CW, KM_REFLEVEL, KM_SCALE, KM_ATTENUATION,
KM_START, KM_STOP, KM_CENTER, KM_SPAN, KM_CW, // These must be first to share common help text
KM_REFLEVEL, KM_SCALE, KM_ATTENUATION,
KM_ACTUALPOWER, KM_IF, KM_SAMPLETIME, KM_DRIVE, KM_LOWOUTLEVEL, KM_DECAY, KM_NOISE,
KM_10MHZ, KM_REPEAT, KM_OFFSET, KM_TRIGGER, KM_LEVELSWEEP, KM_SWEEP_TIME, KM_OFFSET_DELAY,
KM_FAST_SPEEDUP, KM_GRIDLINES, KM_MARKER, KM_MODULATION,KM_COR_AM,KM_COR_WFM, KM_COR_NFM, KM_IF2,
KM_R,KM_MOD,KM_CP,KM_ATTACK,
KM_FAST_SPEEDUP, KM_GRIDLINES, KM_MARKER, KM_MODULATION,
KM_R,KM_MOD,KM_CP,
#if 0
KM_COR_AM,KM_COR_WFM, KM_COR_NFM,
#endif
KM_ATTACK,
KM_IF2,
KM_NONE // always at enum end
};
@ -440,9 +446,11 @@ static const struct {
{keypads_positive , "MINIMUM\nGRIDLINES"}, // KM_GRIDLINES
{keypads_freq , "MARKER\nFREQ"}, // KM_MARKER
{keypads_freq , "MODULATION\nFREQ"}, // KM_MODULATION
#if 0
{keypads_plusmin , "COR\nAM"}, // KM_COR_AM
{keypads_plusmin , "COR\nWFM"}, // KM_COR_WFM
{keypads_plusmin , "COR\nNFM"}, // KM_COR_NFM
#endif
{keypads_freq , "IF2"}, // KM_IF2
{keypads_positive , "R"}, // KM_R
{keypads_positive , "MODULO"}, // KM_MOD
@ -450,6 +458,14 @@ static const struct {
{keypads_positive , "ATTACK"}, // KM_ATTACK
};
#if 0 // Not used
ui_slider_t ui_sliders [] =
{
{ KM_CENTER, true, 0, 1000000, 0, 350000000, M_GENLOW},
{ KM_CENTER, true, 0, 1000000, 240000000, 960000000, M_GENHIGH},
{ KM_LOWOUTLEVEL, false,0, 1, -76, -6, M_GENLOW},
};
#endif
// ===[MENU CALLBACKS]=========================================================
@ -472,6 +488,7 @@ static const menuitem_t menu_topultra[];
static UI_FUNCTION_ADV_CALLBACK(menu_sweep_acb)
{
(void)data;
(void)item;
if (b){
if (setting.level_sweep != 0 || get_sweep_frequency(ST_SPAN) != 0) {
plot_printf(uistat.text, sizeof uistat.text, "SW:%3.2fMHz %+ddB %.3Fs",
@ -723,12 +740,12 @@ static UI_FUNCTION_ADV_CALLBACK(menu_sreffer_acb){
}
const int8_t menu_drive_value[]={-38,-35,-33,-30,-27,-24,-21,-19, -7,-4,-2,1,4,7,10,13};
static UI_FUNCTION_ADV_CALLBACK(menu_drive_acb)
static UI_FUNCTION_ADV_CALLBACK(menu_lo_drive_acb)
{
(void)item;
if(b){
b->param_1.i = menu_drive_value[data] + (setting.mode==M_GENHIGH ? setting.offset : 0);
b->icon = data == setting.drive ? BUTTON_ICON_GROUP_CHECKED : BUTTON_ICON_GROUP;
b->icon = data == setting.lo_drive ? BUTTON_ICON_GROUP_CHECKED : BUTTON_ICON_GROUP;
return;
}
//Serial.println(item);
@ -742,7 +759,7 @@ static UI_FUNCTION_ADV_CALLBACK(menu_sdrive_acb){
(void)item;
(void)data;
if(b){
b->param_1.i = menu_drive_value[setting.drive] + (setting.mode==M_GENHIGH ? setting.offset : 0);
b->param_1.i = menu_drive_value[setting.lo_drive] + (setting.mode==M_GENHIGH ? setting.offset : 0);
return;
}
menu_push_submenu(menu_drive_wide);
@ -1459,33 +1476,33 @@ static const menuitem_t menu_lo_drive[] = {
};
static const menuitem_t menu_drive_wide3[] = {
{ MT_FORM | MT_ADV_CALLBACK, 5, "%+ddBm", menu_drive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 4, "%+ddBm", menu_drive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 3, "%+ddBm", menu_drive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 2, "%+ddBm", menu_drive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 1, "%+ddBm", menu_drive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 0, "%+ddBm", menu_drive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 5, "%+ddBm", menu_lo_drive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 4, "%+ddBm", menu_lo_drive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 3, "%+ddBm", menu_lo_drive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 2, "%+ddBm", menu_lo_drive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 1, "%+ddBm", menu_lo_drive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 0, "%+ddBm", menu_lo_drive_acb},
{ MT_FORM | MT_CANCEL, 255, S_LARROW" BACK", NULL },
{ MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel
};
static const menuitem_t menu_drive_wide2[] = {
{ MT_FORM | MT_ADV_CALLBACK, 10, "%+ddBm", menu_drive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 9, "%+ddBm", menu_drive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 8, "%+ddBm", menu_drive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 7, "%+ddBm", menu_drive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 6, "%+ddBm", menu_drive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 10, "%+ddBm", menu_lo_drive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 9, "%+ddBm", menu_lo_drive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 8, "%+ddBm", menu_lo_drive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 7, "%+ddBm", menu_lo_drive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 6, "%+ddBm", menu_lo_drive_acb},
{ MT_FORM | MT_SUBMENU, 255, S_RARROW" MORE", menu_drive_wide3},
{ MT_FORM | MT_CANCEL, 255, S_LARROW" BACK", NULL },
{ MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel
};
static const menuitem_t menu_drive_wide[] = {
{ MT_FORM | MT_ADV_CALLBACK, 15, "%+ddBm", menu_drive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 14, "%+ddBm", menu_drive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 13, "%+ddBm", menu_drive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 12, "%+ddBm", menu_drive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 11, "%+ddBm", menu_drive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 15, "%+ddBm", menu_lo_drive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 14, "%+ddBm", menu_lo_drive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 13, "%+ddBm", menu_lo_drive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 12, "%+ddBm", menu_lo_drive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 11, "%+ddBm", menu_lo_drive_acb},
{ MT_FORM | MT_SUBMENU, 255, S_RARROW" MORE", menu_drive_wide2},
{ MT_FORM | MT_CANCEL, 255, S_LARROW" BACK", NULL },
{ MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel
@ -1511,31 +1528,33 @@ static const menuitem_t menu_sweep[] = {
{ MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel
};
char low_level_help_text[12] = "-76..-6";
char center_text[10] = "FREQ: %s";
static const menuitem_t menu_lowoutputmode[] = {
{ MT_FORM | MT_ADV_CALLBACK, 0, "LOW OUTPUT %s", menu_outputmode_acb},
{ MT_FORM | MT_KEYPAD, KM_CENTER, "FREQ: %s", "10kHz..350MHz"},
{ MT_FORM | MT_KEYPAD, KM_LOWOUTLEVEL, "LEVEL: %s", "-76..-6"},
// { MT_FORM | MT_ADV_CALLBACK, 0, "MOD: %s", menu_smodulation_acb},
{ MT_FORM | MT_SUBMENU, 255, S_RARROW" Settings", menu_settings3},
{ MT_FORM | MT_KEYPAD, KM_CENTER, center_text, "10kHz..350MHz"},
{ MT_FORM | MT_KEYPAD, KM_LOWOUTLEVEL, "LEVEL: %s", low_level_help_text /* "-76..-6" */},
{ MT_FORM | MT_ADV_CALLBACK, 0, "MOD: %s", menu_smodulation_acb},
{ MT_FORM | MT_ADV_CALLBACK, 0, "%s", menu_sweep_acb},
// { MT_FORM | MT_KEYPAD, KM_SPAN, "SPAN: %s", "0..350MHz"},
// { MT_FORM | MT_KEYPAD | MT_LOW, KM_LEVELSWEEP,"LEVEL CHANGE: %s", "-70..70"},
// { MT_FORM | MT_KEYPAD, KM_SWEEP_TIME, "SWEEP TIME: %s", "0..600 seconds"},
{ MT_FORM | MT_KEYPAD, KM_OFFSET, "AMP: %s", "-100..+100"},
{ MT_FORM | MT_KEYPAD, KM_OFFSET, "EXTERNAL AMP: %s", "-100..+100"},
{ MT_FORM | MT_CANCEL, 0, "MODE", NULL },
{ MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel
};
static const menuitem_t menu_highoutputmode[] = {
{ MT_FORM | MT_ADV_CALLBACK, 0, "HIGH OUTPUT %s", menu_outputmode_acb},
{ MT_FORM | MT_KEYPAD, KM_CENTER, "FREQ: %s", "240MHz..960MHz"},
{ MT_FORM | MT_KEYPAD, KM_CENTER, center_text, "240MHz..960MHz"},
{ MT_FORM | MT_ADV_CALLBACK, 0, "LEVEL: %+ddBm", menu_sdrive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 0, "MOD: %s", menu_smodulation_acb},
{ MT_FORM | MT_KEYPAD, KM_SPAN, "SPAN: %s", NULL},
{ MT_FORM | MT_KEYPAD, KM_SWEEP_TIME,"SWEEP TIME: %s", "0..600 seconds"},
{ MT_FORM | MT_KEYPAD, KM_OFFSET, "AMP: %s", "-100..+100"},
{ MT_FORM | MT_KEYPAD, KM_OFFSET, "EXTERNAL AMP: %s", "-100..+100"},
{ MT_FORM | MT_CANCEL, 0, "MODE", NULL },
{ MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel
};
@ -1756,9 +1775,11 @@ static const menuitem_t menu_settings3[] =
{
{ MT_KEYPAD, KM_10MHZ, "CORRECT\nFREQUENCY", "Enter actual lMHz frequency"},
{ MT_KEYPAD, KM_GRIDLINES, "MINIMUM\nGRIDLINES", "Enter minimum horizontal grid divisions"},
// { MT_KEYPAD, KM_COR_AM, "COR\nAM", "Enter AM modulation correction"},
#if 0 // only used during development
{ MT_KEYPAD, KM_COR_AM, "COR\nAM", "Enter AM modulation correction"},
{ MT_KEYPAD, KM_COR_WFM, "COR\nWFM", "Enter WFM modulation correction"},
// { MT_KEYPAD, KM_COR_NFM, "COR\nNFM", "Enter NFM modulation correction"},
{ MT_KEYPAD, KM_COR_NFM, "COR\nNFM", "Enter NFM modulation correction"},
#endif
// { MT_KEYPAD | MT_LOW, KM_IF2, "IF2 FREQ", "Set to zero for no IF2"},
{ MT_KEYPAD, KM_R, "R", "Set R"},
{ MT_KEYPAD, KM_MOD, "MODULO", "Set MODULO"},
@ -2070,7 +2091,7 @@ static void fetch_numeric_target(void)
break;
case KM_CENTER:
uistat.value = get_sweep_frequency(ST_CENTER);
plot_printf(uistat.text, sizeof uistat.text, "%3.3fMHz", uistat.value / 1000000.0);
plot_printf(uistat.text, sizeof uistat.text, "%3.4fMHz", uistat.value / 1000000.0);
break;
case KM_SPAN:
uistat.value = get_sweep_frequency(ST_SPAN);
@ -2168,7 +2189,7 @@ static void fetch_numeric_target(void)
// if (setting.sweep_time_us < calc_min_sweep_time_us())
// uistat.value = calc_min_sweep_time_us();
// else
uistat.value = setting.actual_sweep_time_us;
uistat.value = setting.sweep_time_us;
uistat.value /= (float)ONE_SECOND_TIME;
plot_printf(uistat.text, sizeof uistat.text, "%.3Fs", uistat.value);
break;
@ -2313,6 +2334,7 @@ set_numeric_value(void)
case KM_MODULATION:
set_modulation_frequency((int)uistat.value);
break;
#if 0
case KM_COR_AM:
config.cor_am =(int)uistat.value;
config_save();
@ -2325,7 +2347,7 @@ set_numeric_value(void)
config.cor_nfm =(int)uistat.value;
config_save();
break;
#endif
}
}

Loading…
Cancel
Save

Powered by TurnKey Linux.