From 60a5e9f5c616143e873ee3a38746758cc1ef02b4 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Tue, 6 Apr 2021 15:16:54 +0200 Subject: [PATCH] Menu updated, marker position at time --- main.c | 19 ++++++++++++++++--- nanovna.h | 6 ++++-- sa_core.c | 36 +++++++++++++++++++++++++++--------- si4468.c | 52 +++++++++++++++++++++++++++++++++++++++------------- ui.c | 2 ++ ui_sa.c | 39 +++++++++++++++++++++++++++++++++++++-- 6 files changed, 125 insertions(+), 29 deletions(-) diff --git a/main.c b/main.c index b412254..5caac99 100644 --- a/main.c +++ b/main.c @@ -424,7 +424,7 @@ VNA_SHELL_FUNCTION(cmd_reset) { (void)argc; (void)argv; - +#ifndef TINYSA4 if (argc == 1) { if (get_str_index(argv[0], "dfu") == 0) { shell_printf("Performing reset to DFU mode\r\n"); @@ -432,6 +432,7 @@ VNA_SHELL_FUNCTION(cmd_reset) return; } } +#endif shell_printf("Performing reset\r\n"); rccEnableWWDG(FALSE); @@ -1017,8 +1018,8 @@ config_t config = { .high_level_output_offset = 0.0, // Uncalibrated .correction_frequency = {{ 1000000, 500000000, 1000000000, 1500000000, 2000000000, 2500000000, 3000000000, 3500000000, 4000000000, 4500000000, 5000000000, 5500000000, 6000000000, 6500000000, 7000000000, 7500000000, 8000000000, 8500000000, 9000000000, 10000000000 }, { 1000000, 500000000, 1000000000, 1500000000, 2000000000, 2500000000, 3000000000, 3500000000, 4000000000, 4500000000, 5000000000, 5500000000, 6000000000, 6500000000, 7000000000, 7500000000, 8000000000, 8500000000, 9000000000, 10000000000 }}, - .correction_value = {{ 0, +1.5, +4, +4, +2, +3.5, +8, +12, +15, +13, +12, +23, +26, +26, +26, +26, +26, +27, +27, +27 }, - { 0, +1, +4.5, +1, +2.5, +6.5, +9, +15, +15.5, +28, +29, +41, +48, +48, +48, +48, +48, +48, +48, +48 }}, + .correction_value = {{ 0, +1.5, +2, +4, +2, +3.5, +6.5, +9.5, +10, +9, +9, +23, +24, +24, +24, +24, +24, +24, +24, +24 }, + { 0, +1, +2.5, +1, +2.5, +6, +9, +11.5, +14.5, +23, +25, +36, +46, +46, +46, +46, +46, +46, +46, +46 }}, .setting_frequency_30mhz = 30000000, .cor_am = 0, .cor_wfm = 0, @@ -1253,6 +1254,18 @@ void set_marker_frequency(int m, freq_t f) } } +void set_marker_time(int m, float f) +{ + if (m == MARKER_INVALID || !markers[m].enabled) + return; + markers[m].mtype &= ~M_TRACKING; + int i = f * (float)(sweep_points-1)* ONE_SECOND_TIME / setting.actual_sweep_time_us; + if (i >= sweep_points) + return; + markers[m].index = i; + markers[m].frequency = 0; +} + static void set_frequencies(freq_t start, freq_t stop, uint16_t points) { diff --git a/nanovna.h b/nanovna.h index 7adf1a5..f2d8ae9 100644 --- a/nanovna.h +++ b/nanovna.h @@ -85,7 +85,7 @@ #endif #ifdef TINYSA4 #define DEFAULT_IF ((freq_t)977400000) -#define DEFAULT_SPUR_OFFSET ((freq_t)1500000) +#define DEFAULT_SPUR_OFFSET ((freq_t)1300000) #define DEFAULT_MAX_FREQ ((freq_t)800000000) #define HIGH_MIN_FREQ_MHZ 136// 825 #define HIGH_MAX_FREQ_MHZ 1130 @@ -93,6 +93,7 @@ //#define ULTRA_MAX_FREQ 2900000000ULL #define MAX_LO_FREQ 4350000000ULL #define LOW_MAX_FREQ 800000000ULL +#define MIN_BELOW_LO 550000000ULL #endif /* * main.c @@ -222,6 +223,7 @@ void send_region(const char *t, int16_t x, int16_t y, int16_t w, int16_t h); void send_buffer(uint8_t * buf, int s); #endif void set_marker_frequency(int m, freq_t f); +void set_marker_time(int m, float f); void toggle_sweep(void); void toggle_mute(void); void load_default_properties(void); @@ -1348,7 +1350,7 @@ extern void ADF4351_modulo(int m); extern void ADF4351_csr(int c); extern void ADF4351_fastlock(int c); extern int SI4463_R; -extern volatile int64_t ADF4350_modulo; +extern int64_t ADF4350_modulo; extern void SI446x_set_AGC_LNA(uint8_t v); extern void SI4463_init_rx(void); extern void SI4463_init_tx(void); diff --git a/sa_core.c b/sa_core.c index 4efc52d..b1d890f 100644 --- a/sa_core.c +++ b/sa_core.c @@ -1771,7 +1771,7 @@ case M_LOW: // Mixed into 0 set_AGC_LNA(); #ifdef TINYSA4 ADF4351_enable(true); - ADF4351_drive(setting.lo_drive); +// ADF4351_drive(setting.lo_drive); if (setting.tracking_output) ADF4351_enable_aux_out(true); else @@ -1856,7 +1856,7 @@ case M_GENLOW: // Mixed output from 0 #endif #ifdef TINYSA4 ADF4351_enable_out(true); - ADF4351_drive(setting.lo_drive); +// ADF4351_drive(setting.lo_drive); ADF4351_enable(true); ADF4351_enable_aux_out(false); @@ -2484,9 +2484,9 @@ pureRSSI_t perform(bool break_on_operation, int i, freq_t f, int tracking) / // ----------------------------- set mixer drive -------------------------------------------- if (setting.lo_drive & 0x04){ int target_drive; - if (f < 400000000ULL) + if (f < 2400000000ULL) target_drive = 1; - else if (f < 2000000000ULL) + else if (f < 3000000000ULL) target_drive = 2; else target_drive = 3; @@ -2783,7 +2783,7 @@ again: // Spur redu if (S_STATE(setting.spur_removal)){ // If in low input mode and spur reduction is on if (setting.below_IF == S_AUTO_OFF && // Auto and not yet in below IF #ifdef TINYSA4 - ( lf > ULTRA_MAX_FREQ || lf < local_IF/2 || ( lf + (uint64_t)local_IF< MAX_LO_FREQ && lf > 136000000ULL + local_IF) ) + ( lf > ULTRA_MAX_FREQ || lf < local_IF/2 || ( lf + (uint64_t)local_IF< MAX_LO_FREQ && lf > MIN_BELOW_LO + local_IF) ) #else (lf < local_IF / 2 || lf > local_IF) #endif @@ -2898,7 +2898,12 @@ again: // Spur redu ADF4351_R_counter(1); } else if (lf < LOW_MAX_FREQ && lf >= TXCO_DIV3 && MODE_INPUT(setting.mode)) { - if (ADF4350_modulo == 0) ADF4351_modulo(60); + if (ADF4350_modulo == 0) { + if (actual_rbw_x10 >= 3000) + ADF4351_modulo(1000); + else + ADF4351_modulo(60); + } freq_t tf = ((lf + actual_rbw_x10*1000) / TCXO) * TCXO; if (tf + actual_rbw_x10*100 >= lf && tf < lf + actual_rbw_x10*100) { // 30MHz ADF4351_R_counter(6); @@ -2913,7 +2918,12 @@ again: // Spur redu ADF4351_R_counter(1); } } else { - if (ADF4350_modulo == 0) ADF4351_modulo(60); + if (ADF4350_modulo == 0) { + if (actual_rbw_x10 >= 3000) + ADF4351_modulo(1000); + else + ADF4351_modulo(60); + } if (setting.frequency_step < 100000) ADF4351_R_counter(3); else @@ -3350,6 +3360,7 @@ sweep_again: // stay in sweep loop when output mo if (refreshing) scandirty = false; if (break_on_operation && operation_requested) { // break loop if needed + abort: if (setting.actual_sweep_time_us > ONE_SECOND_TIME /* && MODE_INPUT(setting.mode) */) { ili9341_set_background(LCD_BG_COLOR); ili9341_fill(OFFSETX, CHART_BOTTOM+1, WIDTH, 1); // Erase progress bar @@ -3387,8 +3398,15 @@ sweep_again: // stay in sweep loop when output mo if (setting.additional_step_delay_us && (MODE_INPUT(setting.mode) || setting.modulation == MO_NONE)) { // No delay when modulation is active if (setting.additional_step_delay_us < 30*ONE_MS_TIME) // Maximum delay time using my_microsecond_delay my_microsecond_delay(setting.additional_step_delay_us); - else - osalThreadSleepMilliseconds(setting.additional_step_delay_us / ONE_MS_TIME); + else { + int tm = setting.additional_step_delay_us / ONE_MS_TIME; + do { + osalThreadSleepMilliseconds(tm>100?100:tm); + if (break_on_operation && operation_requested) + goto abort; + tm -= 100; + } while (tm > 0); + } } } diff --git a/si4468.c b/si4468.c index 824fe30..fbf864e 100644 --- a/si4468.c +++ b/si4468.c @@ -931,6 +931,9 @@ uint32_t registers[6] = {0xC80000, 0x8008011, 0x1800C642, 0x48963,0xA5003C , 0x #else uint32_t registers[6] = {0xA00000, 0x8000011, 0x4E42, 0x4B3,0xDC003C , 0x580005} ; //10 MHz ref #endif +uint32_t old_registers[6]; + +bool reg_dirty[6] = {true, true, true, true, true, true}; int debug = 0; ioline_t ADF4351_LE[2] = { LINE_LO_SEL, LINE_LO_SEL}; //int ADF4351_Mux = 7; @@ -954,7 +957,7 @@ uint64_t PFDRFout[6] = {XTAL,XTAL,XTAL,10000000,10000000,10000000}; //Reference //uint64_t Chrystal[6] = {XTAL,XTAL,XTAL,10000000,10000000,10000000}; //double FRACF; // Temp -volatile int64_t +int64_t // INTA, // Temp ADF4350_modulo = 0, // Linked to spur table!!!!! // MOD, @@ -1013,11 +1016,16 @@ void ADF4351_Setup(void) void ADF4351_WriteRegister32(int channel, const uint32_t value) { - registers[value & 0x07] = value; - for (int i = 3; i >= 0; i--) shiftOut((value >> (8 * i)) & 0xFF); - palSetLine(ADF4351_LE[channel]); - my_microsecond_delay(1); // Must - palClearLine(ADF4351_LE[channel]); +// if (reg_dirty[value & 0x07] || (value & 0x07) == 0) { + if (old_registers[value & 0x07] != registers[value & 0x07] || (value & 0x07) == 0 ) { + registers[value & 0x07] = value; + for (int i = 3; i >= 0; i--) shiftOut((value >> (8 * i)) & 0xFF); + palSetLine(ADF4351_LE[channel]); + my_microsecond_delay(1); // Must + palClearLine(ADF4351_LE[channel]); +// reg_dirty[value & 0x07] = false; + old_registers[value & 0x07] = registers[value & 0x07]; + } } void ADF4351_Set(int channel) @@ -1038,12 +1046,14 @@ void ADF4351_Set(int channel) void ADF4351_disable_output(void) { bitClear (registers[4], 5); // main output + reg_dirty[4] = true; ADF4351_Set(0); } void ADF4351_enable_output(void) { bitSet (registers[4], 5); // main output + reg_dirty[4] = true; ADF4351_Set(0); } #endif @@ -1090,6 +1100,7 @@ void ADF4351_spur_mode(int S) bitSet (registers[2], 30); // R set to 8 else bitClear (registers[2], 30); // R set to 8 + reg_dirty[2] = true; ADF4351_Set(0); } @@ -1116,6 +1127,8 @@ void ADF4351_R_counter(int R) clear_frequency_cache(); // When R changes the possible frequencies will change registers[2] &= ~ (((unsigned long)0x3FF) << 14); registers[2] |= (((unsigned long)R) << 14); + reg_dirty[2] = true; + ADF4351_Set(0); } @@ -1123,6 +1136,7 @@ void ADF4351_mux(int R) { registers[2] &= ~ (((unsigned long)0x7) << 26); registers[2] |= (((unsigned long)R & (unsigned long)0x07) << 26); + reg_dirty[2] = true; ADF4351_Set(0); } @@ -1130,6 +1144,7 @@ void ADF4351_csr(int c) { registers[3] &= ~ (((unsigned long)0x1) << 18); registers[3] |= (((unsigned long)c & (unsigned long)0x01) << 18); + reg_dirty[3] = true; ADF4351_Set(0); } @@ -1137,6 +1152,7 @@ void ADF4351_fastlock(int c) { registers[3] &= ~ (((unsigned long)0x3) << 15); registers[3] |= (((unsigned long)c & (unsigned long)0x03) << 15); + reg_dirty[3] = true; ADF4351_Set(0); } @@ -1144,6 +1160,7 @@ void ADF4351_CP(int p) { registers[2] &= ~ (((unsigned long)0xF) << 9); registers[2] |= (((unsigned long)p) << 9); + reg_dirty[2] = true; ADF4351_Set(0); } @@ -1152,6 +1169,7 @@ void ADF4351_drive(int p) p &= 0x03; registers[4] &= ~ (((unsigned long)0x3) << 3); registers[4] |= (((unsigned long)p) << 3); + reg_dirty[4] = true; ADF4351_Set(0); } @@ -1160,6 +1178,7 @@ void ADF4351_aux_drive(int p) p &= 0x03; registers[4] &= ~ (((unsigned long)0x3) << 6); registers[4] |= (((unsigned long)p) << 6); + reg_dirty[4] = true; ADF4351_Set(0); } #if 0 @@ -1207,10 +1226,11 @@ uint64_t ADF4351_prepare_frequency(int channel, uint64_t freq) // freq / 10Hz bitWrite (registers[4], 21, 0); bitWrite (registers[4], 20, 0); } + reg_dirty[4] = true; #if 1 - volatile uint32_t PFDR = (uint32_t)PFDRFout[channel]; + uint32_t PFDR = (uint32_t)PFDRFout[channel]; uint32_t MOD = ADF4350_modulo; if (MOD == 0) MOD = 60; @@ -1225,7 +1245,7 @@ uint64_t ADF4351_prepare_frequency(int channel, uint64_t freq) // freq / 10Hz #else - volatile uint64_t PFDR = PFDRFout[channel]; + uint64_t PFDR = PFDRFout[channel]; uint16_t MOD = ADF4350_modulo; if (MOD == 0) MOD = 60; @@ -1257,7 +1277,7 @@ uint64_t ADF4351_prepare_frequency(int channel, uint64_t freq) // freq / 10Hz #endif uint64_t actual_freq = ((uint64_t)PFDR *(INTA * MOD +FRAC))/OutputDivider / MOD; #if 0 - volatile int max_delta = PFDRFout[channel]/OutputDivider/MOD/100; + int max_delta = PFDRFout[channel]/OutputDivider/MOD/100; if (actual_freq < freq - max_delta || actual_freq > freq + max_delta ){ while(1) my_microsecond_delay(10); @@ -1276,11 +1296,13 @@ uint64_t ADF4351_prepare_frequency(int channel, uint64_t freq) // freq / 10Hz registers[0] = 0; registers[0] = INTA << 15; // OK registers[0] = registers[0] + (FRAC << 3); + reg_dirty[0] = true; if (MOD == 1) MOD = 2; registers[1] = 0; registers[1] = MOD << 3; registers[1] = registers[1] + 1 ; // restore address "001" bitSet (registers[1], 27); // Prescaler at 8/9 + reg_dirty[1] = true; return actual_freq; } @@ -1290,6 +1312,7 @@ void ADF4351_enable(int s) bitClear(registers[4], 11); // Inverse logic!!!!! else bitSet(registers[4], 11); + reg_dirty[4] = true; ADF4351_Set(0); } @@ -1299,6 +1322,7 @@ void ADF4351_enable_aux_out(int s) bitSet(registers[4], 8); else bitClear(registers[4], 8); + reg_dirty[4] = true; ADF4351_Set(0); } @@ -1313,6 +1337,8 @@ void ADF4351_enable_out(int s) bitSet(registers[2], 5); // Enable power down bitSet(registers[2], 11); // Enable VCO power down } + reg_dirty[2] = true; + reg_dirty[4] = true; ADF4351_Set(0); } @@ -1585,7 +1611,7 @@ void SI4463_set_output_level(int t) } void SI4463_start_tx(uint8_t CHANNEL) { -// volatile si446x_state_t s; +// si446x_state_t s; #if 0 s = SI4463_get_state(); if (s == SI446X_STATE_RX){ @@ -1649,7 +1675,7 @@ void SI4463_start_tx(uint8_t CHANNEL) void SI4463_start_rx(uint8_t CHANNEL) { - volatile si446x_state_t s = SI4463_get_state(); + si446x_state_t s = SI4463_get_state(); if (s == SI446X_STATE_TX){ SI4463_set_state(SI446X_STATE_READY); } @@ -2626,7 +2652,7 @@ void SI4463_init_rx(void) clear_frequency_cache(); SI4463_start_rx(SI4463_channel); #if 0 -volatile si446x_state_t s ; + si446x_state_t s ; again: Si446x_getInfo(&SI4463_info); @@ -2675,7 +2701,7 @@ reset: #endif SI4463_start_tx(0); #if 0 -volatile si446x_state_t s ; + si446x_state_t s ; again: Si446x_getInfo(&SI4463_info); diff --git a/ui.c b/ui.c index adae8d6..2389739 100644 --- a/ui.c +++ b/ui.c @@ -567,6 +567,7 @@ extern const char *states[]; } } +#ifndef TINYSA4 void enter_dfu(void) { @@ -581,6 +582,7 @@ enter_dfu(void) *((unsigned long *)BOOT_FROM_SYTEM_MEMORY_MAGIC_ADDRESS) = BOOT_FROM_SYTEM_MEMORY_MAGIC; NVIC_SystemReset(); } +#endif static void select_lever_mode(int mode) diff --git a/ui_sa.c b/ui_sa.c index 3a58f68..b9c8ee6 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -429,6 +429,7 @@ enum { #ifdef __LIMITS__ KM_LIMIT_FREQ, KM_LIMIT_LEVEL, #endif + KM_MARKER_TIME, // #35 KM_NONE // always at enum end }; @@ -480,6 +481,7 @@ static const struct { {keypads_freq , "END\nFREQ"}, // KM_LIMIT_FREQ {keypads_plusmin_unit , "LEVEL"}, // KM_LIMIT_LEVEL #endif + {keypads_time , "MARKER\nTIME"}, // KM_MARKER_TIME }; #if 0 // Not used @@ -501,6 +503,7 @@ static const menuitem_t menu_highoutputmode[]; static const menuitem_t menu_modulation[]; static const menuitem_t menu_top[]; static const menuitem_t menu_reffer[]; +static const menuitem_t menu_sweep_points[]; static const menuitem_t menu_modulation[]; static const menuitem_t menu_limit_modify[]; //static const menuitem_t menu_drive_wide[]; @@ -678,13 +681,14 @@ static UI_FUNCTION_CALLBACK(menu_config_cb) redraw_frame(); request_to_redraw_grid(); } - +#ifndef TINYSA4 static UI_FUNCTION_CALLBACK(menu_dfu_cb) { (void)data; (void)item; enter_dfu(); } +#endif #ifdef __LISTEN__ static UI_FUNCTION_ADV_CALLBACK(menu_listen_acb) @@ -1597,6 +1601,20 @@ static UI_FUNCTION_ADV_CALLBACK(menu_outputmode_acb) toggle_mute(); } +static UI_FUNCTION_ADV_CALLBACK(menu_enter_marker_acb) +{ + (void) data; + (void) item; + if(b){ + b->param_1.text = FREQ_IS_CW() ? "TIME" : "FREQUENCY"; + return; + } + if (FREQ_IS_CW()) + ui_mode_keypad(KM_MARKER_TIME); + else + ui_mode_keypad(KM_MARKER); +} + #ifdef TINYSA4 static const uint16_t points_setting[] = {51, 101, 201, 290, 450}; #else @@ -1724,6 +1742,7 @@ static const menuitem_t menu_sweep[] = { { 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_SUBMENU, 0, "SWEEP POINTS", menu_sweep_points}, { MT_FORM | MT_CANCEL, 0, S_LARROW" BACK",NULL }, { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; @@ -1877,7 +1896,7 @@ const menuitem_t menu_marker_search[] = { { MT_CALLBACK, 1, "MIN\n" S_RARROW" RIGHT", menu_marker_search_cb }, { MT_CALLBACK, 2, "MAX\n" S_LARROW" LEFT", menu_marker_search_cb }, { MT_CALLBACK, 3, "MAX\n" S_RARROW" RIGHT", menu_marker_search_cb }, - { MT_KEYPAD, KM_MARKER, "ENTER\nFREQUENCY", NULL}, + { MT_ADV_CALLBACK, 0, "ENTER\n%s", menu_enter_marker_acb}, { MT_ADV_CALLBACK, M_TRACKING, "TRACKING",menu_marker_modify_acb }, { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel @@ -1960,11 +1979,13 @@ static const menuitem_t menu_marker[] = { { MT_NONE, 0, NULL, NULL } // sentinel }; +#ifndef TINYSA4 static const menuitem_t menu_dfu[] = { { MT_FORM | MT_CALLBACK, 0, "ENTER DFU", menu_dfu_cb}, { MT_FORM | MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; +#endif #ifdef __HARMONIC__ static const menuitem_t menu_harmonic[] = @@ -2095,10 +2116,14 @@ static const menuitem_t menu_settings2[] = static const menuitem_t menu_settings[] = { { MT_ADV_CALLBACK | MT_LOW, 0,"LO OUTPUT", menu_lo_output_acb}, +#ifndef TINYSA4 { MT_KEYPAD, KM_ACTUALPOWER, "ACTUAL\nPOWER", NULL}, +#endif { MT_KEYPAD | MT_LOW, KM_IF, "IF FREQ", "0=auto IF"}, { MT_SUBMENU,0, "SCAN SPEED", menu_scanning_speed}, +#ifndef TINYSA4 { MT_KEYPAD, KM_REPEAT, "SAMPLE\nREPEAT", "1..100"}, +#endif #ifdef TINYSA4 { MT_SUBMENU | MT_LOW,0, "MIXER\nDRIVE", menu_mixer_drive}, #else @@ -2203,7 +2228,14 @@ static const menuitem_t menu_config[] = { { MT_SUBMENU, 0, "CONNECTION", menu_connection}, #endif { MT_SUBMENU, 0, "EXPERT\nCONFIG", menu_settings}, +#ifndef TINYSA4 { MT_SUBMENU, 0, S_RARROW" DFU", menu_dfu}, +#endif +#ifdef TINYSA4 + { MT_KEYPAD, KM_ACTUALPOWER, "ACTUAL\nPOWER", NULL}, + { MT_KEYPAD, KM_REPEAT, "SAMPLE\nREPEAT", "1..100"}, +#endif + { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; @@ -2668,6 +2700,9 @@ set_numeric_value(void) case KM_MARKER: set_marker_frequency(active_marker, (freq_t)uistat.value - (setting.frequency_offset - FREQUENCY_SHIFT)); break; + case KM_MARKER_TIME: + set_marker_time(active_marker, uistat.value); + break; case KM_MODULATION: set_modulation_frequency((int)uistat.value); break;