From 01a665f306966343a63eca479ffdbe7251b321ac Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Mon, 6 Apr 2020 15:55:56 +0200 Subject: [PATCH 1/4] Powerlevels, spur table and marker menu update --- sa_core.c | 29 +++++++++++++++++++++++------ ui.c | 4 ++++ ui_sa.c | 6 +++--- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/sa_core.c b/sa_core.c index 495ff13..a75253b 100644 --- a/sa_core.c +++ b/sa_core.c @@ -606,12 +606,28 @@ search_maximum(int m, int center, int span) } //static int spur_old_stepdelay = 0; -static const unsigned int spur_IF = 433900000; -static const unsigned int spur_alternate_IF = 434100000; +static const unsigned int spur_IF = 433800000; +static const unsigned int spur_alternate_IF = 434000000; static const int spur_table[] = { - 470000, - 780000, + 870000, + 970000, + 1460000, + 1610000, + 1840000, + 2840000, + 2890000, + 2970000, + 4780000, + 4810000, + 4850000, + 4880000, + 8100000, + 8140000, + 10870000, + 14880000, +#ifdef IF_AT_4339 + 780000, 830000, 880000, 949000, @@ -639,13 +655,14 @@ static const int spur_table[] = 11420000, 14880000, 16820000, +#endif }; int avoid_spur(int f) { int window = ((int)actual_rbw ) * 1000*2; - if (window < 50000) - window = 50000; +// 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++) { diff --git a/ui.c b/ui.c index 01467da..874a530 100644 --- a/ui.c +++ b/ui.c @@ -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; diff --git a/ui_sa.c b/ui_sa.c index b417646..c509c52 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -529,9 +529,9 @@ const char *menu_drive_text[]={"-24dBm","-20dBm","-16dBm","-12dBm"," 6dBm"," 10 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, 2, " 16dBm", menu_drive_cb}, + { MT_CALLBACK, 1, " 12dBm", menu_drive_cb}, + { MT_CALLBACK, 0, " 8dBm", menu_drive_cb}, { MT_CANCEL, 255, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; From 495063f5bf273d7ff0d0a76327e0dfbdba07cde9 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Mon, 6 Apr 2020 19:19:23 +0200 Subject: [PATCH 2/4] First experiment with span in output mode --- main.c | 6 +- sa_core.c | 241 ++++++++++++++++++++++++++++-------------------------- si4432.c | 18 +++- ui_sa.c | 2 + 4 files changed, 149 insertions(+), 118 deletions(-) diff --git a/main.c b/main.c index a0fd3ae..f9d28d7 100644 --- a/main.c +++ b/main.c @@ -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 diff --git a/sa_core.c b/sa_core.c index a75253b..649f75b 100644 --- a/sa_core.c +++ b/sa_core.c @@ -444,6 +444,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; } @@ -685,7 +689,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; @@ -698,7 +702,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) @@ -706,7 +710,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) @@ -719,16 +723,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); @@ -747,70 +757,70 @@ 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] ; - } - // 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= temppeakLevel) // Find where to insert @@ -819,20 +829,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 @@ -846,75 +857,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(GPIOC, GPIOC_LED); return true; diff --git a/si4432.c b/si4432.c index 0042f32..9556736 100644 --- a/si4432.c +++ b/si4432.c @@ -131,6 +131,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); @@ -225,7 +227,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 ); @@ -266,6 +268,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 diff --git a/ui_sa.c b/ui_sa.c index c509c52..3fb55e5 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -570,6 +570,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 +580,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 }; From 993388625e19fbd332a4ca65c105652feedad30f Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Tue, 7 Apr 2020 14:34:15 +0200 Subject: [PATCH 3/4] Improved SI4432 setup and selftest for sample time and attenuator --- main.c | 2 +- sa_core.c | 158 +++++++++++++++++++++++++++++++++++------------------- si4432.c | 45 +++++++++------- ui_sa.c | 46 ++++++++++------ 4 files changed, 162 insertions(+), 89 deletions(-) diff --git a/main.c b/main.c index f9d28d7..0bb8ddf 100644 --- a/main.c +++ b/main.c @@ -125,7 +125,7 @@ static THD_FUNCTION(Thread1, arg) while (1) { bool completed = false; if (sweep_mode&(SWEEP_ENABLE|SWEEP_ONCE)) { - if (dirty) +// if (dirty) completed = sweep(true); sweep_mode&=~SWEEP_ONCE; } else if (sweep_mode & SWEEP_SELFTEST) { diff --git a/sa_core.c b/sa_core.c index 649f75b..9c1a802 100644 --- a/sa_core.c +++ b/sa_core.c @@ -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=0; // 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,7 +70,7 @@ void reset_settings(int m) SetRefpos(-10); break; case M_GENLOW: - setting_drive=1; // 0-3 , 3=+20dBm + setting_drive=8; minFreq = 0; maxFreq = 520000000; set_sweep_frequency(ST_CENTER, (int32_t) 10000000); @@ -84,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); @@ -128,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; } @@ -158,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); } @@ -176,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 { @@ -388,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); @@ -501,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 @@ -518,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; } @@ -764,6 +753,10 @@ static bool sweep(bool break_on_operation) // back to toplevel to handle ui operation if (operation_requested && break_on_operation) return false; + if (MODE_OUTPUT(setting_mode)) { + osalThreadSleepMilliseconds(10); + } + if (MODE_INPUT(setting_mode)) { // if (setting_spur == 1) { // First pass // temp_t[i] = RSSI; @@ -1086,7 +1079,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; @@ -1109,8 +1102,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}, }; @@ -1130,6 +1125,7 @@ static float test_value; static void test_acquire(int i) { + (void)i; pause_sweep(); #if 0 if (test_case[i].center < 300) @@ -1137,8 +1133,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); @@ -1371,13 +1365,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 1 // 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 @@ -1408,6 +1456,8 @@ void self_test(void) set_refer_output(0); reset_settings(M_LOW); in_selftest = false; +#endif +#endif } void reset_calibration(void) diff --git a/si4432.c b/si4432.c index 9556736..83c2e01 100644 --- a/si4432.c +++ b/si4432.c @@ -145,12 +145,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); } @@ -161,9 +163,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); } @@ -174,17 +178,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; @@ -203,7 +207,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){ @@ -255,7 +264,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 diff --git a/ui_sa.c b/ui_sa.c index 3fb55e5..37940f9 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -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, " 16dBm", menu_drive_cb}, - { MT_CALLBACK, 1, " 12dBm", menu_drive_cb}, - { MT_CALLBACK, 0, " 8dBm", 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 @@ -951,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; } From 6422f9c5ed9bde1b90e1c42e4ee33791ffbdb164 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Tue, 7 Apr 2020 15:08:14 +0200 Subject: [PATCH 4/4] spur table updated and default IF corrected --- main.c | 2 +- sa_core.c | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/main.c b/main.c index 0bb8ddf..2c3e0e9 100644 --- a/main.c +++ b/main.c @@ -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__ diff --git a/sa_core.c b/sa_core.c index 9c1a802..c3c96ef 100644 --- a/sa_core.c +++ b/sa_core.c @@ -603,7 +603,14 @@ static const unsigned int spur_IF = 433800000; static const unsigned int spur_alternate_IF = 434000000; static const int spur_table[] = { - 870000, + 420000, + 490000, + 510000, + 1600000, + 1840000, + 2960000, +/* + 870000, 970000, 1460000, 1610000, @@ -619,6 +626,7 @@ static const int spur_table[] = 8140000, 10870000, 14880000, +*/ #ifdef IF_AT_4339 780000, 830000, @@ -1375,7 +1383,7 @@ extern float SI4432_force_RBW(int i); void self_test(void) { -#if 1 // RAttenuator test +#if 0 // RAttenuator test int local_test_status; in_selftest = true; reset_settings(M_LOW);