From a1559e77ac16fb30fd85e58ecf7da298111e37df Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Tue, 2 Mar 2021 13:04:01 +0100 Subject: [PATCH] low output corrected --- Makefile | 2 +- main.c | 3 +- nanovna.h | 52 +++++++++++++------- sa_core.c | 141 +++++++++++++++++++++++++++++++----------------------- ui.c | 2 + 5 files changed, 120 insertions(+), 80 deletions(-) diff --git a/Makefile b/Makefile index bc4a5a3..b961841 100644 --- a/Makefile +++ b/Makefile @@ -265,7 +265,7 @@ ifeq ($(TARGET),F303) UDEFS+= -DUSB_DP_R_VDD #-DCH_DBG_STATISTICS else -UDEFS = -DSHELL_CMD_TEST_ENABLED=FALSE -DSHELL_CMD_MEM_ENABLED=FALSE -DARM_MATH_CM0 -DVERSION=\"$(VERSION)\" +UDEFS = -DSHELL_CMD_TEST_ENABLED=FALSE -DSHELL_CMD_MEM_ENABLED=FALSE -DARM_MATH_CM0 -DVERSION=\"$(VERSION)\" -DTINYSA_F072 -DTINYSA3 endif # Define ASM defines here diff --git a/main.c b/main.c index 7e61356..3cb0565 100644 --- a/main.c +++ b/main.c @@ -2967,6 +2967,7 @@ int main(void) /* * Init Shell console connection data (after load config for settings) */ + shell_init_connection(); #ifdef TINYSA4 @@ -3066,7 +3067,7 @@ void HardFault_Handler(void) void hard_fault_handler_c(uint32_t *sp) { -#if 0 +#ifdef TINYSA4 uint32_t r0 = sp[0]; uint32_t r1 = sp[1]; uint32_t r2 = sp[2]; diff --git a/nanovna.h b/nanovna.h index c432e27..a4c2f82 100644 --- a/nanovna.h +++ b/nanovna.h @@ -20,11 +20,23 @@ #ifdef TINYSA_F303 #include "adc_F303.h" -// #define TINYSA4 +#ifdef TINYSA_F072 +#error "Remove comment for #ifdef TINYSA_F303" +#endif +#ifndef TINYSA4 +#define TINYSA4 +#endif #define TINYSA4_PROTO -#else +#endif + +#ifdef TINYSA_F072 +#ifdef TINYSA_F303 +#error "Remove comment for #ifdef TINYSA_F072" +#endif +#ifndef TINYSA3 #define TINYSA3 #endif +#endif // Need enable HAL_USE_SPI in halconf.h #define __USE_DISPLAY_DMA__ @@ -241,12 +253,16 @@ void set_extra_lna(int t); // ------------------------------- sa_core.c ---------------------------------- -extern int level_min(void); -extern int level_max(void); -extern int level_range(void); +extern float level_min(void); +extern float level_max(void); +extern float level_range(void); extern const char * const unit_string[]; +#ifdef TINYSA4 +extern float *drive_dBm; +#else extern const int8_t drive_dBm []; +#endif extern uint8_t signal_is_AM; extern const int reffer_freq[]; extern freq_t minFreq; @@ -833,26 +849,29 @@ typedef struct setting int mode; uint16_t _sweep_points; int16_t attenuate_x2; - int auto_attenuation; + uint8_t auto_attenuation; + uint8_t below_IF; + int8_t _active_marker; + int8_t unit; + uint8_t mirror_masking; + uint8_t subtract_stored; // uint8_t increases size + uint8_t agc; + uint8_t lna; + uint8_t auto_reflevel; + int modulation; + int show_stored; int atten_step; + int test; + int harmonic; uint32_t rbw_x10; - int below_IF; int average; - int show_stored; - int subtract_stored; int lo_drive; // 0-3 , 3dB steps int rx_drive; // 0-15 , 7=+20dBm, 3dB steps - int agc; - int lna; - int auto_reflevel; float reflevel; float scale; int tracking; - int modulation; int step_delay; freq_t frequency_step; - int test; - int harmonic; int decay; int attack; int noise; @@ -866,11 +885,8 @@ typedef struct setting int measurement; int refer; int spur_removal; - int mirror_masking; trace_t _trace[TRACES_MAX]; marker_t _markers[MARKERS_MAX]; - int8_t _active_marker; - int8_t unit; float offset; float trigger_level; int trigger_direction; diff --git a/sa_core.c b/sa_core.c index 1d1ce07..f6ed6ff 100644 --- a/sa_core.c +++ b/sa_core.c @@ -48,7 +48,7 @@ freq_t maxFreq = 520000000; int spur_gate = 100; uint32_t old_CFGR; uint32_t orig_CFGR; -int high_out_adf4350 = true; +int high_out_adf4350 = false; int debug_frequencies = false; @@ -70,31 +70,37 @@ static freq_t real_old_freq[4] = { 0, 0, 0, 0}; #endif #ifdef TINYSA4 -const int8_t drive_dBm [] = {-15,-12,-9,-6}; +const float si_drive_dBm [] = {-41, -30, -21, -17, -12, -11, -10, -8.5, -7.5, -6.5, -5.5, -4.5, -3.5, -3 , -2, -1.5, -1, -0.5, 0}; +const float adf_drive_dBm[] = {-15,-12,-9,-6}; +const uint8_t drive_register[] = {0, 1, 2, 3, 4, 5, 6, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}; + +float *drive_dBm = (float *) si_drive_dBm; + #else const int8_t drive_dBm [16] = {-38, -32, -30, -27, -24, -19, -15, -12, -5, -2, 0, 3, 6, 9, 12, 16}; #endif #ifdef TINYSA4 -#define SI_DRIVE_STEP 0.5 // Power step per step in drive level -#define SWITCH_ATTENUATION 34 +#define SWITCH_ATTENUATION (high_out_adf4350 ? 0 : 37) //#define POWER_OFFSET -18 // Max level with all enabled //#define POWER_RANGE 70 -#define MAX_DRIVE 16 -//#define MAX_DRIVE_DBM 3 -#define MIN_DRIVE 8 -#define SL_GENHIGH_LEVEL_MIN -15 -#define SL_GENHIGH_LEVEL_RANGE 9 -#define SL_GENLOW_LEVEL_MIN -88 -#define SL_GENLOW_LEVEL_RANGE 70 +#define MAX_DRIVE (high_out_adf4350 ? 3 : 18) +#define MIN_DRIVE (high_out_adf4350 ? 0: 2) +//#define SL_GENHIGH_LEVEL_MIN -15 +//#define SL_GENHIGH_LEVEL_RANGE 9 + +#define SL_GENHIGH_LEVEL_MIN drive_dBm[MIN_DRIVE] +#define SL_GENHIGH_LEVEL_RANGE (drive_dBm[MAX_DRIVE] - drive_dBm[MIN_DRIVE]) +#define SL_GENHIGH_LEVEL_MAX drive_dBm[MAX_DRIVE] + +#define SL_GENLOW_LEVEL_MIN -104 +#define SL_GENLOW_LEVEL_RANGE 90 #else -#define SI_DRIVE_STEP 3 #define SWITCH_ATTENUATION 30 #define POWER_OFFSET 15 -#define MAX_DRIVE 11 -#define MAX_DRIVE_DBM 3 +#define MAX_DRIVE (setting.mode == M_GENHIGH ? 15 : 11) #define MIN_DRIVE 8 #define SL_GENHIGH_LEVEL_MIN -38 #define SL_GENHIGH_LEVEL_RANGE 51 @@ -102,6 +108,8 @@ const int8_t drive_dBm [16] = {-38, -32, -30, -27, -24, -19, -15, -12, -5, -2, 0 #define SL_GENLOW_LEVEL_RANGE 70 #endif +#define BELOW_MAX_DRIVE(X) (drive_dBm[X] - drive_dBm[MAX_DRIVE]) + #define RECEIVE_SWITCH_ATTENUATION 21 // TODO differentiate for tinySA3 and tinySA4 @@ -157,6 +165,10 @@ void reset_settings(int m) { // strcpy((char *)spi_buffer, dummy); setting.mode = m; +#ifdef TINYSA4 + high_out_adf4350 = false; // Must be false in the low modes + drive_dBm = (float *) si_drive_dBm; +#endif update_min_max_freq(); sweep_mode |= SWEEP_ENABLE; setting.unit_scale_index = 0; @@ -178,7 +190,7 @@ void reset_settings(int m) #endif setting.show_stored = 0; setting.auto_attenuation = false; - setting.subtract_stored = 0; + setting.subtract_stored = false; setting.normalize_level = 0.0; #ifdef TINYSA4 setting.lo_drive=1; @@ -232,7 +244,7 @@ void reset_settings(int m) #else setting.spur_removal = S_OFF; #endif - setting.mirror_masking = 0; + setting.mirror_masking = false; setting.slider_position = 0; setting.slider_span = 100000; #endif // __SPUR__ @@ -263,7 +275,7 @@ void reset_settings(int m) setting.rx_drive=MAX_DRIVE; setting.lo_drive=1; #else - setting.rx_drive=8; +// setting.rx_drive=8; setting.lo_drive=13; #endif set_sweep_frequency(ST_CENTER, 10000000); @@ -288,7 +300,7 @@ void reset_settings(int m) break; case M_GENHIGH: #ifdef TINYSA4 - setting.lo_drive=1; + setting.lo_drive=MIN_DRIVE; set_sweep_frequency(ST_CENTER, (minFreq + maxFreq)/2 ); setting.extra_lna = false; #else @@ -476,6 +488,7 @@ void toggle_tracking_output(void) void toggle_high_out_adf4350(void) { high_out_adf4350 = !high_out_adf4350; + drive_dBm = (float *) (high_out_adf4350 ? adf_drive_dBm : si_drive_dBm); dirty = true; } @@ -606,15 +619,17 @@ void set_auto_reflevel(int v) setting.auto_reflevel = v; } -int level_min(void) +float level_min(void) { + int l; if (setting.mode == M_GENLOW) - return SL_GENLOW_LEVEL_MIN + config.low_level_output_offset; + l = SL_GENLOW_LEVEL_MIN + config.low_level_output_offset; else - return SL_GENHIGH_LEVEL_MIN + config.high_level_output_offset; + l = SL_GENHIGH_LEVEL_MIN + config.high_level_output_offset; + return l; } -int level_max(void) +float level_max(void) { if (setting.mode == M_GENLOW) return SL_GENLOW_LEVEL_MIN + SL_GENLOW_LEVEL_RANGE + config.low_level_output_offset; @@ -622,26 +637,14 @@ int level_max(void) return SL_GENHIGH_LEVEL_MIN + SL_GENHIGH_LEVEL_RANGE + config.high_level_output_offset; } -int level_range(void) +float level_range(void) { + int r; if (setting.mode == M_GENLOW) - return SL_GENLOW_LEVEL_RANGE ; + r = SL_GENLOW_LEVEL_RANGE ; else - return SL_GENHIGH_LEVEL_RANGE; -} - -float get_attenuation(void) -{ - float actual_attenuation = setting.attenuate_x2 / 2.0; - if (setting.mode == M_GENLOW) { - return (float)( level_max() - actual_attenuation - (MAX_DRIVE - setting.rx_drive) * SI_DRIVE_STEP - ( setting.atten_step ? SWITCH_ATTENUATION : 0) ); - } else if (setting.atten_step) { - if (setting.mode == M_LOW) - return actual_attenuation + RECEIVE_SWITCH_ATTENUATION; - else - return actual_attenuation + SWITCH_ATTENUATION; - } - return(actual_attenuation); + r = SL_GENHIGH_LEVEL_RANGE; + return r; } static pureRSSI_t get_signal_path_loss(void){ @@ -659,16 +662,16 @@ static pureRSSI_t get_signal_path_loss(void){ void set_level(float v) // Set the output level in dB in high/low output { if (setting.mode == M_GENHIGH) { - int d = 0; + unsigned int d = 0; v = v - config.high_level_output_offset; - while (drive_dBm[d] < v - 1 && (unsigned int)d < (sizeof(drive_dBm)/sizeof(drive_dBm[0]))-1 ) + while (drive_dBm[d] < v && d < MAX_DRIVE) // Find level equal or above requested level d++; // if (d == 8 && v < -12) // Round towards closest level // d = 7; set_lo_drive(d); } else { setting.level = v; - set_attenuation((int)v); + set_attenuation(setting.level - config.low_level_output_offset); } dirty = true; } @@ -678,10 +681,26 @@ float get_level(void) if (setting.mode == M_GENHIGH) { return drive_dBm[setting.lo_drive] + config.high_level_output_offset; } else { - return get_attenuation(); + setting.level = get_attenuation() + config.low_level_output_offset; + return setting.level; } } + +float get_attenuation(void) +{ + float actual_attenuation = setting.attenuate_x2 / 2.0; + if (setting.mode == M_GENLOW) { + return (float)( level_max() - actual_attenuation + BELOW_MAX_DRIVE(setting.rx_drive) - ( setting.atten_step ? SWITCH_ATTENUATION : 0) ); + } else if (setting.atten_step) { + if (setting.mode == M_LOW) + return actual_attenuation + RECEIVE_SWITCH_ATTENUATION; + else + return actual_attenuation + SWITCH_ATTENUATION; + } + return(actual_attenuation); +} + void set_attenuation(float a) // Is used both in low output mode and high/low input mode { if (setting.mode == M_GENLOW) { @@ -694,11 +713,11 @@ void set_attenuation(float a) // Is used both in low output mode and high/ } else { setting.atten_step = 0; } - setting.rx_drive = MAX_DRIVE; // defined as 0dB level - while (a <= - SI_DRIVE_STEP && setting.rx_drive > MIN_DRIVE) { - a += SI_DRIVE_STEP; + setting.rx_drive = MAX_DRIVE; // Reduce level till it fits in attenuator range + while (a - BELOW_MAX_DRIVE(setting.rx_drive) < - 31 && setting.rx_drive > MIN_DRIVE) { setting.rx_drive--; } + a -= BELOW_MAX_DRIVE(setting.rx_drive); a = -a; } else { if (setting.mode == M_LOW && a > 31.5) { @@ -1680,7 +1699,7 @@ case M_GENHIGH: // Direct output from 1 enable_extra_lna(false); enable_ultra(false); #endif - #ifdef __SI4432__ +#ifdef __SI4432__ SI4432_Sel = SI4432_RX ; SI4432_Receive(); set_switch_receive(); @@ -1712,13 +1731,13 @@ case M_GENHIGH: // Direct output from 1 ADF4351_enable_aux_out(false); ADF4351_enable_out(false); #ifdef __SI4468__ + SI4463_set_output_level(setting.lo_drive); // Must be before init_tx SI4463_init_tx(); // if (setting.lo_drive < 32) { // enable_rx_output(false); // use switch as attenuator // } else { enable_rx_output(true); // } - SI4463_set_output_level(setting.lo_drive); #endif } @@ -1754,7 +1773,7 @@ void update_rbw(void) // calculate the actual_rbw and the vbwSteps (# #endif } else #ifdef TINYSA4 - temp_actual_rbw_x10 = setting.vbw_x10; // rbw is NOT twice the frequency step to ensure no gaps in coverage + temp_actual_rbw_x10 = 2*setting.vbw_x10; // rbw is NOT twice the frequency step to ensure no gaps in coverage #else temp_actual_rbw_x10 = 2*setting.vbw_x10; // rbw is twice the frequency step to ensure no gaps in coverage #endif @@ -1784,12 +1803,16 @@ void update_rbw(void) // calculate the actual_rbw and the vbwSteps (# #endif actual_rbw_x10 = set_rbw(actual_rbw_x10); // see what rbw the SI4432 can realize if (setting.frequency_step > 0 && MODE_INPUT(setting.mode)) { // When doing frequency scanning in input mode +#ifdef TINYSA4 if (setting.vbw_x10 > actual_rbw_x10) - vbwSteps = 1+(setting.vbw_x10 / actual_rbw_x10); //((int)(2 * (setting.vbw_x10 + (actual_rbw_x10/8)) / actual_rbw_x10)); // calculate # steps in between each frequency step due to rbw being less than frequency step - if (vbwSteps < 1) // at least one step, should never happen - vbwSteps = 1; + vbwSteps = 1+(setting.vbw_x10 / actual_rbw_x10); //((int)(2 * (setting.vbw_x10 + (actual_rbw_x10/8)) / actual_rbw_x10)); // calculate # steps in between each frequency step due to rbw being less than frequency step +#else + vbwSteps = ((int)(2 * (setting.vbw_x10 + (actual_rbw_x10/2)) / actual_rbw_x10)); // calculate # steps in between each frequency step due to rbw being less than frequency step +#endif if (setting.step_delay_mode==SD_PRECISE) // if in Precise scanning vbwSteps *= 2; // use twice as many steps + if (vbwSteps < 1) // at least one step, should never happen + vbwSteps = 1; } else { // in all other modes setting.vbw_x10 = actual_rbw_x10; } @@ -2215,7 +2238,7 @@ pureRSSI_t perform(bool break_on_operation, int i, freq_t f, int tracking) / else ls -= 0.5; float a = ((int)((setting.level + ((float)i / sweep_points) * ls)*2.0)) / 2.0; - a += PURE_TO_float(get_frequency_correction(f)); + a += PURE_TO_float(get_frequency_correction(f)) - config.low_level_output_offset; if (a != old_a) { old_a = a; a = a - level_max(); // convert to all settings maximum power output equals a = zero @@ -2236,11 +2259,11 @@ pureRSSI_t perform(bool break_on_operation, int i, freq_t f, int tracking) / #endif } - int d = MAX_DRIVE; // Start at highest drive level; - while (a < -SI_DRIVE_STEP && d > MIN_DRIVE) { - d--; // Reduce drive - a = a + SI_DRIVE_STEP; // and compensate + int d = MAX_DRIVE; // Reduce level till it fits in attenuator range + while (a - BELOW_MAX_DRIVE(d) < - 31 && d > MIN_DRIVE) { + d--; } + a -= BELOW_MAX_DRIVE(d); #ifdef __SI4432__ SI4432_Sel = SI4432_RX ; SI4432_Drive(d); @@ -2248,8 +2271,6 @@ pureRSSI_t perform(bool break_on_operation, int i, freq_t f, int tracking) / #ifdef __SI4463__ SI4463_set_output_level(d); #endif - - if (a > 0) a = 0; if (a < -31.5) @@ -2587,7 +2608,7 @@ modulation_again: } else if (setting.mode == M_GENHIGH) { if (high_out_adf4350) { set_freq (ADF4351_LO, lf); // sweep LO, local_IF = 0 in high mode - local_IF = lf; + local_IF = 0; } else { set_freq (SI4463_RX, lf); // sweep RX, local_IF = 0 in high mode local_IF = 0; diff --git a/ui.c b/ui.c index 83370a3..cbc78e5 100644 --- a/ui.c +++ b/ui.c @@ -1903,6 +1903,8 @@ draw_menu_buttons(const menuitem_t *menu) ili9341_line(button_start + i * MENU_FORM_WIDTH/5, y+button_height-9, button_start + i * MENU_FORM_WIDTH/5, y+button_height); } draw_slider: + if (local_slider_positions < button_start) + local_slider_positions = button_start; blit8BitWidthBitmap(local_slider_positions - 4, y, 7, 5, slider_bitmap); } else if (menu[i].data == KM_HIGHOUTLEVEL) { local_slider_positions = ((get_level() - level_min() ) * (MENU_FORM_WIDTH-8)) / level_range() + OFFSETX+4;