Merge branch 'tinySA' into tinySA-v0.2

tinySA-v0.2
erikkaashoek 6 years ago
commit e986514a18

@ -1,5 +1,4 @@
/*
* Copyright (c) 2016-2017, TAKAHASHI Tomohiro (TTRFTECH) edy555@gmail.com
* All rights reserved.
*
* This is free software; you can redistribute it and/or modify
@ -116,7 +115,7 @@ const char *info_about[]={
"Platform: " PLATFORM_NAME,
0 // sentinel
};
extern int dirty;
static THD_WORKING_AREA(waThread1, 900);
static THD_FUNCTION(Thread1, arg)
{
@ -126,7 +125,8 @@ static THD_FUNCTION(Thread1, arg)
while (1) {
bool completed = false;
if (sweep_mode&(SWEEP_ENABLE|SWEEP_ONCE)) {
completed = sweep(true);
// if (dirty)
completed = sweep(true);
sweep_mode&=~SWEEP_ONCE;
} else if (sweep_mode & SWEEP_SELFTEST) {
self_test(); // call from lowest level to save stack space
@ -830,7 +830,7 @@ void load_default_properties(void)
//current_props.magic = CONFIG_MAGIC;
current_props._frequency0 = 0; // start = 0Hz
current_props._frequency1 = 350000000; // end = 350MHz
current_props._frequency_IF= 433900000,
current_props._frequency_IF= 433800000,
current_props._sweep_points = POINTS_COUNT;
#ifdef VNA__

@ -13,7 +13,7 @@ int setting_rbw = 0;
int setting_average = 0;
int setting_show_stored = 0;
int setting_subtract_stored = 0;
int setting_drive=1; // 0-3 , 3=+20dBm
int setting_drive=13; // 0-7 , 7=+20dBm, 3dB steps
int setting_agc = true;
int setting_lna = false;
int setting_tracking = false;
@ -42,12 +42,12 @@ void reset_settings(int m)
{
setting_mode = m;
setting_attenuate = 0;
setting_step_atten = 0;
setting_rbw = 0;
setting_average = 0;
setting_show_stored = 0;
setting_subtract_stored = 0;
setting_drive=1; // 0-3 , 3=+20dBm
setting_drive=13;
setting_step_atten = 0; // Only used in low output mode
setting_agc = true;
setting_lna = false;
setting_tracking = false;
@ -70,6 +70,7 @@ void reset_settings(int m)
SetRefpos(-10);
break;
case M_GENLOW:
setting_drive=8;
minFreq = 0;
maxFreq = 520000000;
set_sweep_frequency(ST_CENTER, (int32_t) 10000000);
@ -83,6 +84,7 @@ void reset_settings(int m)
SetRefpos(-30);
break;
case M_GENHIGH:
setting_drive=8;
minFreq = 240000000;
maxFreq = 960000000;
set_sweep_frequency(ST_CENTER, (int32_t) 300000000);
@ -127,14 +129,7 @@ void set_measurement(int m)
}
void SetDrive(int d)
{
setting_drive = (d & 3);
if (setting_mode == M_GENHIGH) {
if (!(d & 4))
setting_step_atten = 1;
else
setting_step_atten = 0;
setting_drive = d;
}
setting_drive = d;
dirty = true;
}
@ -157,16 +152,16 @@ int GetMode(void)
#define POWER_STEP 0 // Should be 5 dB but appearently it is lower
#define POWER_OFFSET 2
#define POWER_OFFSET 12
#define SWITCH_ATTENUATION 29
int GetAttenuation(void)
{
if (setting_mode == M_GENLOW) {
if (setting_step_atten)
return ( - (POWER_OFFSET + setting_attenuate - (setting_step_atten-1)*POWER_STEP + SWITCH_ATTENUATION));
return ( -(POWER_OFFSET + setting_attenuate - (setting_step_atten-1)*POWER_STEP + SWITCH_ATTENUATION));
else
return ( -(POWER_OFFSET + setting_attenuate));
return ( -POWER_OFFSET - setting_attenuate + (setting_drive & 7) * 3);
}
return(setting_attenuate);
}
@ -175,24 +170,27 @@ int GetAttenuation(void)
void SetAttenuation(int a)
{
if (setting_mode == M_GENLOW) {
setting_drive = 0;
a = a + POWER_OFFSET;
if( a > - SWITCH_ATTENUATION + 3*POWER_STEP) {
if (a > 0) {
setting_drive++;
a = a - 3;
}
if (a > 0) {
setting_drive++;
a = a - 3;
}
if (a > 0) {
setting_drive++;
a = a - 3;
}
if (a > 0)
a = 0;
if( a > - SWITCH_ATTENUATION) {
setting_step_atten = 0;
} else {
a = a + SWITCH_ATTENUATION;
#if 0
if (a >= 2 * POWER_STEP) {
setting_step_atten = 3; // Max drive
a = a - 2 * POWER_STEP;
} else if (a >= POWER_STEP ) {
setting_step_atten = 2; // Max drive
a = a - POWER_STEP;
} else {
setting_step_atten = 1;
}
#else
setting_step_atten = 1; // drive level is unpredictable
#endif
setting_step_atten = 1;
}
a = -a;
} else {
@ -387,21 +385,14 @@ void SetMode(int m)
void apply_settings(void)
{
if (setting_step_delay == 0){
if (MODE_LOW(setting_mode)) {
if (actual_rbw >300.0) actualStepDelay = 400;
else if (actual_rbw >100.0) actualStepDelay = 500;
else if (actual_rbw > 30.0) actualStepDelay = 900;
else if (actual_rbw > 10.0) actualStepDelay = 900;
else if (actual_rbw > 3.0) actualStepDelay = 1000;
else actualStepDelay = 1500;
} else {
if (actual_rbw >300.0) actualStepDelay = 900;
else if (actual_rbw >100.0) actualStepDelay = 900;
else if (actual_rbw > 30.0) actualStepDelay = 900;
else if (actual_rbw > 10.0) actualStepDelay = 1800;
else if (actual_rbw > 3.0) actualStepDelay = 6000;
else actualStepDelay = 8000;
}
if (actual_rbw >142.0) actualStepDelay = 350;
else if (actual_rbw > 75.0) actualStepDelay = 450;
else if (actual_rbw > 56.0) actualStepDelay = 600;
else if (actual_rbw > 37.0) actualStepDelay = 800;
else if (actual_rbw > 18.0) actualStepDelay = 1100;
else if (actual_rbw > 9.0) actualStepDelay = 2000;
else if (actual_rbw > 5.0) actualStepDelay = 3500;
else actualStepDelay = 6000;
} else
actualStepDelay = setting_step_delay;
PE4302_Write_Byte(setting_attenuate * 2);
@ -443,6 +434,10 @@ void setFreq(int V, unsigned long freq)
{
SI4432_Sel = V;
if (old_freq[V] != freq) {
if (V == 0) {
V = -V;
V = -V;
}
SI4432_Set_Frequency(freq);
old_freq[V] = freq;
}
@ -496,15 +491,14 @@ case M_GENLOW: // Mixed output from 0
SI4432_Sel = 0;
if (setting_step_atten) {
SetSwitchReceive();
SI4432_Transmit(setting_step_atten-1);
} else {
SetSwitchTransmit();
SI4432_Transmit(0); // To prevent damage to the BPF always set low drive
}
SI4432_Transmit(setting_drive); // Not to overdrive the mixer
SI4432_Sel = 1;
SetSwitchReceive();
SI4432_Transmit(setting_drive);
SI4432_Transmit(13); // Fix LO drive a 10dBm
break;
case M_GENHIGH: // Direct output from 1
@ -513,12 +507,12 @@ case M_GENHIGH: // Direct output from 1
SetSwitchReceive();
SI4432_Sel = 1;
if (setting_step_atten) {
if (setting_drive < 8) {
SetSwitchReceive();
} else {
SetSwitchTransmit();
}
SI4432_Transmit(setting_drive & 3);
SI4432_Transmit(setting_drive);
break;
}
@ -606,18 +600,71 @@ search_maximum(int m, int center, int span)
//static int spur_old_stepdelay = 0;
static const unsigned int spur_IF = 433800000;
static const unsigned int spur_alternate_IF = 433600000;
static const unsigned int spur_alternate_IF = 434000000;
static const int spur_table[] =
{
470000,
420000,
490000,
510000,
1600000,
1840000,
2960000,
/*
870000,
970000,
1460000,
1610000,
1840000,
2840000,
2890000,
2970000,
4780000,
4810000,
4850000,
4880000,
8100000,
8140000,
10870000,
14880000,
*/
#ifdef IF_AT_4339
780000,
830000,
880000,
949000,
1390000,
1468000,
1830000,
1900000,
2770000,
2840000,
2880000,
4710000,
4780000,
4800000,
4880000,
6510000,
6750000,
6790000,
6860000,
7340000,
8100000,
8200000,
8880000,
// 9970000, 10MHz!!!!!!
10870000,
11420000,
14880000,
16820000,
#endif
};
int avoid_spur(int f)
{
int window = ((int)actual_rbw ) * 1000*2;
if (window < 50000)
window = 50000;
if (! setting_mode == M_LOW || frequency_IF != spur_IF || actual_rbw >= 300.0)
// if (window < 50000)
// window = 50000;
if (! setting_mode == M_LOW || frequency_IF != spur_IF || actual_rbw > 300.0)
return(false);
for (unsigned int i = 0; i < (sizeof spur_table)/sizeof(int); i++) {
if (f/window == spur_table[i]/window) {
@ -639,7 +686,7 @@ float perform(bool break_on_operation, int i, int32_t f, int tracking)
long local_IF;
if (MODE_HIGH(setting_mode))
local_IF = 0;
else if (avoid_spur(f))
else if (setting_mode == M_LOW && avoid_spur(f))
local_IF = spur_alternate_IF;
else
local_IF = frequency_IF;
@ -652,7 +699,7 @@ float perform(bool break_on_operation, int i, int32_t f, int tracking)
if (local_IF) {
setFreq (0, local_IF);
}
if (setting_modulation == MO_AM) {
if (MODE_OUTPUT(setting_mode) && setting_modulation == MO_AM) {
int p = setting_attenuate * 2 + modulation_counter;
PE4302_Write_Byte(p);
if (modulation_counter == 3)
@ -660,7 +707,7 @@ float perform(bool break_on_operation, int i, int32_t f, int tracking)
else
modulation_counter++;
chThdSleepMicroseconds(250);
} else if (setting_modulation == MO_NFM || setting_modulation == MO_WFM ) {
} else if (MODE_OUTPUT(setting_mode) && (setting_modulation == MO_NFM || setting_modulation == MO_WFM )) {
SI4432_Sel = 1;
SI4432_Write_Byte(0x79, modulation_counter); // Use frequency hopping channel for FM modulation
if (modulation_counter == 3)
@ -673,16 +720,22 @@ float perform(bool break_on_operation, int i, int32_t f, int tracking)
int t = 0;
do {
int lf = (uint32_t)(f + (int)(t * 500 * actual_rbw));
if (tracking)
if (MODE_INPUT(setting_mode) && tracking)
setFreq (0, local_IF + lf - reffer_freq[setting_refer]); // Offset so fundamental of reffer is visible
#if 0
if (lf >11000000 || lf < 9000000) {
lf = lf;
break;
}
#endif
setFreq (1, local_IF + lf);
if (MODE_OUTPUT(setting_mode))
if (MODE_OUTPUT(setting_mode)) // No substepping in output mode
return(0);
float subRSSI = SI4432_RSSI(lf, MODE_SELECT(setting_mode))+settingLevelOffset()+setting_attenuate;
if (RSSI < subRSSI)
RSSI = subRSSI;
t++;
if ((operation_requested && break_on_operation ) || (MODE_OUTPUT(setting_mode))) // output modes do not step.
if (operation_requested && break_on_operation) // output modes do not step.
break; // abort
} while (t < vbwSteps);
return(RSSI);
@ -701,70 +754,74 @@ static bool sweep(bool break_on_operation)
temppeakLevel = -150;
float temp_min_level = 100;
// spur_old_stepdelay = 0;
//again:
//again:
for (int i = 0; i < sweep_points; i++) {
RSSI = perform(break_on_operation, i, frequencies[i], setting_tracking);
// back to toplevel to handle ui operation
if (operation_requested && break_on_operation)
return false;
// if (setting_spur == 1) { // First pass
// temp_t[i] = RSSI;
// continue; // Skip all other processing
// }
// if (setting_spur == -1) // Second pass
// RSSI = ( RSSI < temp_t[i] ? RSSI : temp_t[i]); // Minimum of two passes
temp_t[i] = RSSI;
if (setting_subtract_stored) {
RSSI = RSSI - stored_t[i] ;
if (MODE_OUTPUT(setting_mode)) {
osalThreadSleepMilliseconds(10);
}
// stored_t[i] = (SI4432_Read_Byte(0x69) & 0x0f) * 3.0 - 90.0; // Display the AGC value in thestored trace
if (scandirty || setting_average == AV_OFF) {
actual_t[i] = RSSI;
age[i] = 0;
} else {
switch(setting_average) {
case AV_MIN: if (actual_t[i] > RSSI) actual_t[i] = RSSI; break;
case AV_MAX_HOLD: if (actual_t[i] < RSSI) actual_t[i] = RSSI; break;
case AV_MAX_DECAY:
if (actual_t[i] < RSSI) {
actual_t[i] = RSSI;
age[i] = 0;
} else {
if (age[i] > setting_decay)
actual_t[i] -= 0.5;
else
age[i] += 1;
if (MODE_INPUT(setting_mode)) {
// if (setting_spur == 1) { // First pass
// temp_t[i] = RSSI;
// continue; // Skip all other processing
// }
// if (setting_spur == -1) // Second pass
// RSSI = ( RSSI < temp_t[i] ? RSSI : temp_t[i]); // Minimum of two passes
temp_t[i] = RSSI;
if (setting_subtract_stored) {
RSSI = RSSI - stored_t[i] ;
}
// stored_t[i] = (SI4432_Read_Byte(0x69) & 0x0f) * 3.0 - 90.0; // Display the AGC value in thestored trace
if (scandirty || setting_average == AV_OFF) {
actual_t[i] = RSSI;
age[i] = 0;
} else {
switch(setting_average) {
case AV_MIN: if (actual_t[i] > RSSI) actual_t[i] = RSSI; break;
case AV_MAX_HOLD: if (actual_t[i] < RSSI) actual_t[i] = RSSI; break;
case AV_MAX_DECAY:
if (actual_t[i] < RSSI) {
actual_t[i] = RSSI;
age[i] = 0;
} else {
if (age[i] > setting_decay)
actual_t[i] -= 0.5;
else
age[i] += 1;
}
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;
}
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
// START_PROFILE
if (i == 0) {
cur_max = 0; // Always at least one maximum
temppeakIndex = 0;
temppeakLevel = actual_t[i];
max_index[0] = 0;
downslope = true;
}
if (downslope) {
if (temppeakLevel > actual_t[i]) { // Follow down
temppeakIndex = i; // Latest minimum
// START_PROFILE
if (i == 0) {
cur_max = 0; // Always at least one maximum
temppeakIndex = 0;
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;
max_index[0] = 0;
downslope = true;
}
} 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
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
int j = 0; // Insertion index
while (j<cur_max && actual_t[max_index[j]] >= temppeakLevel) // Find where to insert
@ -773,20 +830,21 @@ static bool sweep(bool break_on_operation)
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
// maxlevel_index[k] = maxlevel_index[k-1]; // Only for debugging
k--;
}
max_index[j] = temppeakIndex;
// maxlevel_index[j] = actual_t[temppeakIndex]; // Only for debugging
// maxlevel_index[j] = actual_t[temppeakIndex]; // Only for debugging
if (cur_max < MAX_MAX) {
cur_max++;
}
//STOP_PROFILE
//STOP_PROFILE
}
temppeakIndex = i; // Latest minimum
temppeakLevel = actual_t[i];
downslope = true;
}
}
}
#else
@ -800,75 +858,77 @@ static bool sweep(bool break_on_operation)
temp_min_level = actual_t[i];
#endif
}
// if (setting_spur == 1) {
// setting_spur = -1;
// goto again;
// } else if (setting_spur == -1)
// setting_spur = 1;
// if (setting_spur == 1) {
// setting_spur = -1;
// goto again;
// } else if (setting_spur == -1)
// setting_spur = 1;
if (scandirty) {
scandirty = false;
draw_cal_status();
}
#if 1
int i = 0;
int m = 0;
while (i < cur_max) { // For all maxima found
if (MODE_INPUT(setting_mode)) {
int i = 0;
int m = 0;
while (i < cur_max) { // For all maxima found
while (m < MARKERS_MAX) {
if (markers[m].enabled == M_TRACKING_ENABLED) { // Available marker found
markers[m].index = max_index[i];
markers[m].frequency = frequencies[markers[m].index];
m++;
break; // Next maximum
}
m++; // Try next marker
}
i++;
}
while (m < MARKERS_MAX) {
if (markers[m].enabled == M_TRACKING_ENABLED) { // Available marker found
markers[m].index = max_index[i];
if (markers[m].enabled == M_TRACKING_ENABLED ) { // More available markers found
markers[m].index = 0; // Enabled but no max
markers[m].frequency = frequencies[markers[m].index];
m++;
break; // Next maximum
}
m++; // Try next marker
}
i++;
}
while (m < MARKERS_MAX) {
if (markers[m].enabled == M_TRACKING_ENABLED ) { // More available markers found
markers[m].index = 0; // Enabled but no max
markers[m].frequency = frequencies[markers[m].index];
}
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;
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);
}
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];
peakIndex = max_index[0];
peakLevel = actual_t[peakIndex];
peakFreq = frequencies[peakIndex];
#else
int peak_marker = 0;
markers[peak_marker].enabled = true;
markers[peak_marker].index = peakIndex;
markers[peak_marker].frequency = frequencies[markers[peak_marker].index];
int peak_marker = 0;
markers[peak_marker].enabled = true;
markers[peak_marker].index = peakIndex;
markers[peak_marker].frequency = frequencies[markers[peak_marker].index];
#endif
min_level = temp_min_level;
min_level = temp_min_level;
#if 0 // Auto ref level setting
int scale = get_trace_scale(2);
int rp = (NGRIDY - get_trace_refpos(2)) * scale;
if (scale > 0 && peakLevel > rp && peakLevel - min_level < 8 * scale ) {
SetRefpos((((int)(peakLevel/scale)) + 1) * scale);
}
if (scale > 0 && min_level < rp - 9*scale && peakLevel - min_level < 8 * scale ) {
int new_rp = (((int)((min_level + 9*scale)/scale)) - 1) * scale;
if (new_rp < rp)
SetRefpos(new_rp);
}
int scale = get_trace_scale(2);
int rp = (NGRIDY - get_trace_refpos(2)) * scale;
if (scale > 0 && peakLevel > rp && peakLevel - min_level < 8 * scale ) {
SetRefpos((((int)(peakLevel/scale)) + 1) * scale);
}
if (scale > 0 && min_level < rp - 9*scale && peakLevel - min_level < 8 * scale ) {
int new_rp = (((int)((min_level + 9*scale)/scale)) - 1) * scale;
if (new_rp < rp)
SetRefpos(new_rp);
}
#endif
}
// redraw_marker(peak_marker, FALSE);
palSetPad(GPIOB, GPIOB_LED);
return true;
@ -1027,7 +1087,7 @@ enum {
TP_SILENT, TPH_SILENT, TP_10MHZ, TP_10MHZEXTRA, TP_30MHZ, TPH_30MHZ
};
#define TEST_COUNT 14
#define TEST_COUNT 16
static const struct {
int kind;
@ -1050,8 +1110,10 @@ static const struct {
{TC_BELOW, TP_30MHZ, 430, 60, -75, 0, -85}, // 9 LPF cutoff
{TC_END, 0, 0, 0, 0, 0, 0},
{TC_MEASURE, TP_30MHZ, 30, 7, -25, 30, -80 }, // 11 Measure power level and noise
{TC_MEASURE, TP_30MHZ, 270, 4, -50, 30, -85 }, // 13 Measure powerlevel and noise
{TC_MEASURE, TPH_30MHZ, 270, 4, -35, 30, -50 }, // 14 Calibrate power high mode
{TC_MEASURE, TP_30MHZ, 270, 4, -50, 30, -85 }, // 12 Measure powerlevel and noise
{TC_MEASURE, TPH_30MHZ, 270, 4, -35, 30, -50 }, // 13 Calibrate power high mode
{TC_END, 0, 0, 0, 0, 0, 0},
{TC_MEASURE, TP_30MHZ, 30, 1, -25, 30, -80 }, // 15 Measure RBW step time
{TC_END, 0, 0, 0, 0, 0, 0},
};
@ -1071,6 +1133,7 @@ static float test_value;
static void test_acquire(int i)
{
(void)i;
pause_sweep();
#if 0
if (test_case[i].center < 300)
@ -1078,8 +1141,6 @@ static void test_acquire(int i)
else
setting_mode = M_HIGH;
#endif
set_sweep_frequency(ST_CENTER, (int32_t)(test_case[i].center * 1000000));
set_sweep_frequency(ST_SPAN, (int32_t)(test_case[i].span * 1000000));
SetAverage(4);
sweep(false);
sweep(false);
@ -1312,13 +1373,67 @@ common_silent:
}
trace[TRACE_STORED].enabled = true;
SetRefpos(test_case[i].pass+10);
set_sweep_frequency(ST_CENTER, (int32_t)(test_case[i].center * 1000000));
set_sweep_frequency(ST_SPAN, (int32_t)(test_case[i].span * 1000000));
draw_cal_status();
}
extern void menu_autosettings_cb(int item);
extern float SI4432_force_RBW(int i);
void self_test(void)
{
#if 0 // RAttenuator test
int local_test_status;
in_selftest = true;
reset_settings(M_LOW);
int i = 14; // calibrate low mode power on 30 MHz;
test_prepare(i);
for (int j= 0; j < 32; j++ ) {
test_prepare(i);
SetAttenuation(j);
test_acquire(i); // Acquire test
local_test_status = test_validate(i); // Validate test
shell_printf("Target %d, actual %f\n\r",j, peakLevel);
}
return;
#else
#if 0 // RBW step time search
int local_test_status;
in_selftest = true;
reset_settings(M_LOW);
int i = 14; // calibrate low mode power on 30 MHz;
test_prepare(i);
setting_step_delay = 6000;
for (int j= 0; j < 57; j++ ) {
setting_step_delay = setting_step_delay * 4/3;
setting_rbw = SI4432_force_RBW(j);
shell_printf("RBW = %d, ",setting_rbw);
test_prepare(i);
test_acquire(i); // Acquire test
local_test_status = test_validate(i); // Validate test
float saved_peakLevel = peakLevel;
if (peakLevel < -30) {
shell_printf("Peak level too low, abort\n\r");
return;
}
shell_printf("Start level = %f, ",peakLevel);
while (setting_step_delay > 100 && peakLevel > saved_peakLevel - 1) {
setting_step_delay = setting_step_delay * 3 / 4;
// test_prepare(i);
// shell_printf("RBW = %f\n\r",SI4432_force_RBW(j));
test_acquire(i); // Acquire test
local_test_status = test_validate(i); // Validate test
// shell_printf("Step %f, %d",peakLevel, setting_step_delay);
}
setting_step_delay = setting_step_delay * 4 / 3;
shell_printf("End level = %f, step time = %d\n\r",peakLevel, setting_step_delay);
}
return;
#else
in_selftest = true;
menu_autosettings_cb(0);
for (int i=0; i < TEST_COUNT; i++) { // All test cases waiting
@ -1349,6 +1464,8 @@ void self_test(void)
set_refer_output(0);
reset_settings(M_LOW);
in_selftest = false;
#endif
#endif
}
void reset_calibration(void)

@ -134,6 +134,8 @@ byte SI4432_Read_Byte( byte ADR )
void SI4432_Reset(void)
{
int count = 0;
SI4432_Read_Byte ( 0x03 ); // Clear pending interrupts
SI4432_Read_Byte ( 0x04 );
// always perform a system reset (don't send 0x87)
SI4432_Write_Byte( 0x07, 0x80);
chThdSleepMilliseconds(50);
@ -146,12 +148,14 @@ void SI4432_Reset(void)
void SI4432_Transmit(int d)
{
int count = 0;
SI4432_Write_Byte(0x6D, (byte) (0x1C+d));
SI4432_Write_Byte(0x6D, (byte) (0x18+(d & 7)));
if (( SI4432_Read_Byte ( 0x02 ) & 0x03 ) == 2)
return; // Already in transmit mode
chThdSleepMilliseconds(10);
SI4432_Write_Byte( 0x07, 0x0b);
chThdSleepMilliseconds(20);
SI4432_Write_Byte( 0x07, 0x03);
chThdSleepMilliseconds(20);
SI4432_Write_Byte( 0x07, 0x0b);
chThdSleepMilliseconds(30);
while (count++ < 100 && ( SI4432_Read_Byte ( 0x02 ) & 0x03 ) != 2) {
chThdSleepMilliseconds(10);
}
@ -162,9 +166,11 @@ void SI4432_Receive(void)
int count = 0;
if (( SI4432_Read_Byte ( 0x02 ) & 0x03 ) == 1)
return; // Already in receive mode
chThdSleepMilliseconds(10);
SI4432_Write_Byte( 0x07, 0x07);
chThdSleepMilliseconds(20);
SI4432_Write_Byte( 0x07, 0x03);
chThdSleepMilliseconds(20);
SI4432_Write_Byte( 0x07, 0x07);
chThdSleepMilliseconds(30);
while (count++ < 100 && ( SI4432_Read_Byte ( 0x02 ) & 0x03 ) != 1) {
chThdSleepMilliseconds(5);
}
@ -175,17 +181,17 @@ void SI4432_Receive(void)
// for which WISH is greater than the first entry, use those values,
// Return the first entry of the following triple for the RBW actually achieved
static const short RBW_choices[] = { // Each quadrupple is: ndec, fils, WISH*10, corr*10
5,1,26,5, 5,2,28,5, 5,3,31,5, 5,4,32,5, 5,5,37,5, 5,6,42,5,
5,7,45,5, 4,1,49,5,
4,2,54,5, 4,3,59,5, 4,4,61,5, 4,5,72,5, 4,6,82,5, 4,7,88,5,
3,1,95,5, 3,2,106,5, 3,3,115,5, 3,4,121,5, 3,5,142,5, 3,6,162,5,
3,7,175,5, 2,1,189,5, 2,2,210,5, 2,3,227,5, 2,4,240,5, 2,5,282,5,
2,6,322,5, 2,7,347,5, 1,1,377,5, 1,2,417,5, 1,3,452,5, 1,4,479,5,
1,5,562,5, 1,6,641,5, 1,7,692,5, 0,1,752,5, 0,2,832,5, 0,3,900,5,
0,4,953,5, 0,5,1121,5, 0,6,1279,5, 0,7,1379,5, 1,4,1428,5, 1,5,1678,5,
1,9,1811,5, 0,15,1915,5, 0,1,2251,5, 0,2,2488,5, 0,3,2693,5,
0,4,2849,5, 0,8,3355,5, 0,9,3618,5, 0,10,4202,5, 0,11,4684,5, 0,12,5188,5,
0,13,5770,5, 0,14,6207,5
5,1,26,0, 5,2,28,0, 5,3,31,0, 5,4,32,0, 5,5,37,0, 5,6,42,10,
5,7,45,10, 4,1,49,10,
4,2,54,10, 4,3,59,10, 4,4,61,10, 4,5,72,10, 4,6,82,10, 4,7,88,10,
3,1,95,10, 3,2,106,5, 3,3,115,0, 3,4,121,0, 3,5,142,0, 3,6,162,10,
3,7,175,10, 2,1,189,10, 2,2,210,10, 2,3,227,10, 2,4,240,10, 2,5,282,5,
2,6,322,10, 2,7,347,10, 1,1,377,10, 1,2,417,10, 1,3,452,10, 1,4,479,5,
1,5,562,10, 1,6,641,10, 1,7,692,10, 0,1,752,10, 0,2,832,10, 0,3,900,5,
0,4,953,10, 0,5,1121,10, 0,6,1279,10, 0,7,1379,5, 1,4,1428,0, 1,5,1678,-10,
1,9,1811,65, 0,15,1915,120, 0,1,2251,-5, 0,2,2488,0, 0,3,2693,-5,
0,4,2849,0, 0,8,3355,30, 0,9,3618,60, 0,10,4202,25, 0,11,4684,25, 0,12,5188,35,
0,13,5770,35, 0,14,6207,35
};
static float SI4432_RSSI_correction = 0;
@ -204,7 +210,12 @@ float SI4432_SET_RBW(float w) {
SI4432_RSSI_correction = RBW_choices[i]/10.0;
uint8_t BW = (dwn3 << 7) | (ndec << 4) | fils ;
SI4432_Write_Byte(0x1C , BW ) ;
return ((float)WISH / 10.0) ;
return (((float)WISH) / 10.0) ;
}
float SI4432_force_RBW(int i)
{
return(SI4432_SET_RBW((float)(RBW_choices[i*4+2]/10.0)));
}
float SI4432_RBW_table(int i){
@ -228,7 +239,7 @@ void SI4432_Set_Frequency ( long Freq ) {
int N = Freq / 10000000;
Carrier = ( 4 * ( Freq - N * 10000000 )) / 625;
int Freq_Band = ( N - 24 ) | ( hbsel << 5 ) | ( sbsel << 6 );
#if 0
#if 1
SI4432_Write_Byte ( 0x75, Freq_Band );
SI4432_Write_Byte ( 0x76, (Carrier>>8) & 0xFF );
SI4432_Write_Byte ( 0x77, Carrier & 0xFF );
@ -257,7 +268,7 @@ float SI4432_RSSI(uint32_t i, int s)
RSSI_RAW = (unsigned char)SI4432_Read_Byte( 0x26 ) ;
// if (MODE_INPUT(setting_mode) && RSSI_RAW == 0)
// SI4432_Init();
float dBm = (RSSI_RAW-240)/2.0;
float dBm = (RSSI_RAW-240)/2.0 - SI4432_RSSI_correction;
#ifdef __SIMULATION__
dBm = Simulated_SI4432_RSSI(i,s);
#endif
@ -270,6 +281,20 @@ float SI4432_RSSI(uint32_t i, int s)
void SI4432_Sub_Init(void)
{
SI4432_Reset();
//set VCO and PLL Only for SI4432 V2
SI4432_Write_Byte(0x72, 0x1F); //write 0x1F to the Frequency Deviation register
SI4432_Write_Byte(0x5A, 0x7F); //write 0x7F to the VCO Current Trimming register
SI4432_Write_Byte(0x58, 0x80); //write 0xD7 to the ChargepumpCurrentTrimmingOverride register
SI4432_Write_Byte(0x59, 0x40); //write 0x40 to the Divider Current Trimming register
//set the AGC
SI4432_Write_Byte(0x6A, 0x0B); //write 0x0B to the AGC Override 2 register
//set ADC reference voltage to 0.9V
SI4432_Write_Byte(0x68, 0x04); //write 0x04 to the Deltasigma ADC Tuning 2 register
SI4432_Write_Byte(0x1F, 0x03); //write 0x03 to the Clock Recovery Gearshift Override register
SI4432_Write_Byte(0x05, 0x0);
SI4432_Write_Byte(0x06, 0x0);
// Enable receiver chain

@ -126,6 +126,7 @@ static void choose_active_marker(void);
static void menu_move_back(void);
static void menu_push_submenu(const menuitem_t *submenu);
static const menuitem_t menu_marker_type[];
static int btn_check(void)
{
@ -842,6 +843,9 @@ menu_marker_sel_cb(int item, uint8_t data)
markers[item].enabled = M_TRACKING_ENABLED; // default tracking enabled
active_marker_select(item);
}
if (markers[item].enabled)
menu_push_submenu(menu_marker_type);
} else if (item == 4) { /* all off */
for (t = 0; t < MARKERS_MAX; t++)
markers[t].enabled = M_DISABLED;

@ -521,35 +521,49 @@ static void menu_pause_cb(int item, uint8_t data)
}
//const int menu_drive_value[]={5,10,15,20};
const char *menu_drive_text[]={"-24dBm","-20dBm","-16dBm","-12dBm"," 6dBm"," 10dBm"," 14dBm"," 18dBm"};
const char *menu_drive_text[]={"-30dBm","-27dBm","-24dBm","-21dBm","-18dBm","-15dBm","-12dBm"," -9dBm", " -6dBm"," -3dBm"," 0dBm"," 3dBm"," 6dBm"," 10dBm"," 14dBm"," 18dBm"};
// ===[MENU DEFINITION]=========================================================
static const menuitem_t menu_drive[] = {
{ MT_CALLBACK, 3, " 20dBm", menu_drive_cb},
{ MT_CALLBACK, 2, " 15dBm", menu_drive_cb},
{ MT_CALLBACK, 1, " 10dBm", menu_drive_cb},
{ MT_CALLBACK, 0, " 5dBm", menu_drive_cb},
{ MT_CALLBACK, 7, " 20dBm", menu_drive_cb},
{ MT_CALLBACK, 6, " 16dBm", menu_drive_cb},
{ MT_CALLBACK, 5, " 12dBm", menu_drive_cb},
{ MT_CALLBACK, 4, " 8dBm", menu_drive_cb},
{ MT_CANCEL, 255, S_LARROW" BACK", NULL },
{ MT_NONE, 0, NULL, NULL } // sentinel
};
static const menuitem_t menu_drive_wide2[] = {
{ MT_FORM | MT_CALLBACK, 2, "-16dBm", menu_drive_cb },
{ MT_FORM | MT_CALLBACK, 1, "-20dBm", menu_drive_cb},
{ MT_FORM | MT_CALLBACK, 0, "-24dBm", menu_drive_cb},
static const menuitem_t menu_drive_wide3[] = {
{ MT_FORM | MT_CALLBACK, 5, "-15dBm", menu_drive_cb },
{ MT_FORM | MT_CALLBACK, 4, "-18dBm", menu_drive_cb},
{ MT_FORM | MT_CALLBACK, 3, "-21dBm", menu_drive_cb},
{ MT_FORM | MT_CALLBACK, 2, "-24dBm", menu_drive_cb },
{ MT_FORM | MT_CALLBACK, 1, "-27dBm", menu_drive_cb},
{ MT_FORM | MT_CALLBACK, 0, "-30dBm", menu_drive_cb},
{ MT_FORM | MT_CANCEL, 255, S_LARROW" BACK", NULL },
{ MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel
{ MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel
};
static const menuitem_t menu_drive_wide2[] = {
{ MT_FORM | MT_CALLBACK, 10, " 0dBm", menu_drive_cb },
{ MT_FORM | MT_CALLBACK, 9, " -3dBm", menu_drive_cb},
{ MT_FORM | MT_CALLBACK, 8, " -6dBm", menu_drive_cb},
{ MT_FORM | MT_CALLBACK, 7, " -9dBm", menu_drive_cb },
{ MT_FORM | MT_CALLBACK, 6, "-12dBm", menu_drive_cb},
{ 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_CALLBACK, 7, " 18dBm", menu_drive_cb},
{ MT_FORM | MT_CALLBACK, 6, " 14dBm", menu_drive_cb},
{ MT_FORM | MT_CALLBACK, 5, " 10dBm", menu_drive_cb},
{ MT_FORM | MT_CALLBACK, 4, " 6dBm", menu_drive_cb},
{ MT_FORM | MT_CALLBACK, 3, "-12dBm", menu_drive_cb},
{ MT_FORM | MT_CALLBACK, 15, " 18dBm", menu_drive_cb},
{ MT_FORM | MT_CALLBACK, 14, " 14dBm", menu_drive_cb},
{ MT_FORM | MT_CALLBACK, 13, " 10dBm", menu_drive_cb},
{ MT_FORM | MT_CALLBACK, 12, " 6dBm", menu_drive_cb},
{ MT_FORM | MT_CALLBACK, 11, " 3dBm", menu_drive_cb},
{ 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
@ -570,6 +584,7 @@ const menuitem_t menu_lowoutputmode[] = {
{ MT_FORM | MT_KEYPAD, KM_CENTER, "FREQ: %s", NULL},
{ MT_FORM | MT_KEYPAD, KM_LOWOUTLEVEL, "LEVEL: %s", NULL},
{ MT_FORM | MT_SUBMENU, 0, "MODULATION: %s", menu_modulation},
{ MT_FORM | MT_KEYPAD, KM_SPAN, "SPAN: %s", NULL},
{ MT_FORM | MT_CANCEL, 0, S_LARROW" BACK", NULL },
{ MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel
};
@ -579,6 +594,7 @@ const menuitem_t menu_highoutputmode[] = {
{ MT_FORM | MT_KEYPAD, KM_CENTER, "FREQ: %s", NULL},
{ MT_FORM | MT_SUBMENU, 0, "LEVEL: %s", menu_drive_wide},
{ MT_FORM | MT_SUBMENU, 0, "MODULATION: %s", menu_modulation},
{ MT_FORM | MT_KEYPAD, KM_SPAN, "SPAN: %s", NULL},
{ MT_FORM | MT_CANCEL, 0, S_LARROW" BACK",NULL },
{ MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel
};
@ -949,7 +965,7 @@ static void menu_item_modify_attribute(
mark = true;
}
} else if (menu == menu_drive || menu == menu_drive_wide || menu == menu_drive_wide2) {
} else if (menu == menu_drive || menu == menu_drive_wide || menu == menu_drive_wide2|| menu == menu_drive_wide3) {
if (menu[item].data == setting_drive){
mark = true;
}

Loading…
Cancel
Save

Powered by TurnKey Linux.