From 17e4fad5d1a26b4dd02ce96bc4386ad97c3251ef Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Tue, 25 Apr 2023 17:25:54 +0200 Subject: [PATCH] UPdated --- main.c | 6 +- nanovna.h | 6 +- sa_core.c | 31 +++-- si4468.c | 405 +++++++++++++++++++++++++++++++++++++++++++++++++++++- ui.c | 5 +- 5 files changed, 434 insertions(+), 19 deletions(-) diff --git a/main.c b/main.c index 952389a..5b78e97 100644 --- a/main.c +++ b/main.c @@ -2861,10 +2861,10 @@ int main(void) if (adc1_single_read(0)> 1000) max2871 = true; if (max2871) { - MAX_LO_FREQ = 6000000000ULL + config.overclock; ULTRA_MAX_FREQ = 6950000000ULL + config.overclock; // Start of harmonic mode - MAX_ABOVE_IF_FREQ = 5021000000ULL + config.overclock; // Range to use for below IF - MIN_BELOW_IF_FREQ = 4041000000ULL + config.overclock; // Range to use for below IF + MAX_LO_FREQ = 6000000000ULL + config.overclock; + MAX_ABOVE_IF_FREQ = 4021000000ULL + config.overclock; // Range to use for below IF + MIN_BELOW_IF_FREQ = 4021000000ULL + config.overclock; // Range to use for below IF } else { ULTRA_MAX_FREQ = 5340000000ULL + config.overclock; // Start of harmonic mode diff --git a/nanovna.h b/nanovna.h index 65be6ca..783faed 100644 --- a/nanovna.h +++ b/nanovna.h @@ -53,7 +53,7 @@ #define __ADF4351__ #define __NEW_SWITCHES__ #define __ULTRA_OUT__ // Use ADF output over LOW out -#define __SI5351__ +//#define __SI5351__ #endif #define __PE4302__ //#define __SIMULATION__ @@ -113,7 +113,7 @@ #define __MARKER_CACHE__ #define TINYSA4_4 #ifdef TINYSA4_4 -#define __SI5351__ +//#define __SI5351__ #endif //#define __FFT_VBW__ //#define __FFT_DECONV__ @@ -1821,7 +1821,9 @@ extern int force_signal_path; extern void ADF4351_mux(int R); extern void ADF4351_force_refresh(void); extern void ADF4351_CP(int p); +extern uint16_t ADF4351_get_CP(void); extern void ADF4351_modulo(int m); +extern uint16_t ADF4351_get_modulo(void); extern void ADF4351_csr(int c); extern void ADF4351_fastlock(int c); extern void ADF4351_recalculate_PFDRFout(void); diff --git a/sa_core.c b/sa_core.c index c8f9270..a120f35 100644 --- a/sa_core.c +++ b/sa_core.c @@ -22,7 +22,7 @@ #pragma GCC push_options #ifdef TINYSA4 -#pragma GCC optimize ("Og") +#pragma GCC optimize ("O0") #else #pragma GCC optimize ("Os") #endif @@ -515,7 +515,7 @@ void update_min_max_freq(void) if (setting.mixer_output) maxFreq = ULTRA_MAX_FREQ+60000000; // Add 60MHz to go to 5.40GHz else - maxFreq = 4400000000ULL+config.overclock; // 4.4GHz + maxFreq = MAX_LO_FREQ+config.overclock; // 4.4GHz #else maxFreq = MAX_LOW_OUTPUT_FREQ; #endif @@ -2661,7 +2661,7 @@ case M_GENHIGH: // Direct output from 1 SI4463_init_rx(); enable_rx_output(true); // to protect the SI enable_ADF_output(true, true); - ADF4351_aux_drive(setting.lo_drive); +// ADF4351_aux_drive(setting.lo_drive); enable_extra_lna(false); enable_ultra(true); // Open low output #else @@ -3813,7 +3813,7 @@ pureRSSI_t perform(bool break_on_operation, int i, freq_t f, int tracking) / SI4463_set_output_level(d); else #endif - ADF4351_aux_drive(d); + // ADF4351_aux_drive(d); #endif } } @@ -4285,11 +4285,21 @@ again: // Spur redu if (setting.R == 0) { setting.increased_R = false; if (setting.mode == M_GENLOW) { - if (local_modulo == 0) ADF4351_modulo(1000); - ADF4351_R_counter(3); + if (max2871) { + if (local_modulo == 0) ADF4351_modulo(100); + ADF4351_R_counter(-1); + } else { + if (local_modulo == 0) ADF4351_modulo(1000); + ADF4351_R_counter(3); + } } else if (lf > 8000000 && lf < 3000000000 && MODE_INPUT(setting.mode)) { - if (local_modulo == 0) ADF4351_modulo(4000); - + if (max2871) + if (local_modulo == 0) { + if (max2871) + ADF4351_modulo(100); + else + ADF4351_modulo(4000); + } freq_t tf = ((lf + actual_rbw_x10*200) / TCXO) * TCXO; if (tf + actual_rbw_x10*200 >= lf && tf < lf + actual_rbw_x10*200 /* && tf != 180000000 */ ) { // 30MHz setting.increased_R = true; @@ -4326,7 +4336,10 @@ again: // Spur redu } else { // Input above 800 MHz if (local_modulo == 0) { // if (actual_rbw_x10 >= 3000) - ADF4351_modulo(4000); + if (max2871) + ADF4351_modulo(100); + else + ADF4351_modulo(4000); // else // ADF4351_modulo(60); } diff --git a/si4468.c b/si4468.c index f46749b..a415669 100644 --- a/si4468.c +++ b/si4468.c @@ -24,7 +24,7 @@ #include "spi.h" #pragma GCC push_options -#pragma GCC optimize ("O2") +#pragma GCC optimize ("O0") //#define __USE_FRR_FOR_RSSI__ @@ -251,6 +251,403 @@ bool PE4302_Write_Byte(unsigned char DATA ) //------------------------------- ADF4351 ------------------------------------- +#define __NEW_ADF4351__ +#ifdef __NEW_ADF4351__ + +bool ADF4351_frequency_changed = false; + +uint16_t R = 1; +int old_R = 0; +uint16_t N = 1; +uint16_t frac = 0; +uint16_t modulus = 32; +uint16_t out_div = 0; +uint16_t mux = 0; +uint16_t csr = 1; // cycle slip reduction +uint16_t bscm = 1; // Band select clock mode + +// uint32_t reg_0 = 0; +uint32_t reg_1 = 0; +uint32_t reg_2 = 0; +uint32_t reg_3 = 0; +uint32_t reg_4 = 0; +uint32_t reg_5 = 0; + +uint16_t id = 0; +uint8_t rfPower = 0b00; +static freq_t prev_actual_freq = 0; +bool pdwn = false; +uint16_t powerDown = 0; + + +static const uint8_t auxPower = 0b00; + +// band select divider. 1 to 255. +static const uint8_t bsDivider = 255; // For set internal logic clock (24M / 192 = 125k) max 125k + +// charge pump current, 0 to 15. +static uint8_t cpCurrent = 0; + +// CLKDIV divider (for fastlock and phase resync). 0 to 4095. +static const uint16_t clkDivDivider = 6; + +static const uint16_t phase = 1; + +static enum { + CLKDIVMODE_OFF = 0b00, + CLKDIVMODE_FASTLOCK = 0b01, + CLKDIVMODE_RESYNC = 0b10 +} clkDivMode = CLKDIVMODE_OFF; + +static const enum { + LD_LOW = 0b00, + LD_LOCK_DETECT = 0b01, + LD_HIGH = 0b11 +} ld_pin = LD_LOCK_DETECT; // Used for led output + +bool refDouble = false; +static const bool refDiv2 = false; +static const bool rfEnable = true; +static const bool auxEnable = false; +static const bool feedbackFromDivided = true; + +static const bool LDF = false; +static const bool LDP = true; + +static enum { + LD_LOW_NOISE = 0b00, + LD_LOW_SPUR1 = 0b10, + LD_LOW_SPUR2 = 0b11 +} noiseMode = LD_LOW_NOISE; + +/* +static const enum { + p_4_div_5 = 0, // min integer 23, max freq = 3.0GHz + p_8_div_9 = 1 // min integer 75, max freq = 4.4GHz +} prescaler = p_8_div_9; +*/ +static const enum { + CPt_NORMAL = 0b00, // Work, use default + CPt_LONG_RESET = 0b01, // Work + CPt_FORCE_SOURCE = 0b10, + CPt_FORCE_SINK = 0b11, +} CP_Test = CPt_NORMAL; + +static const enum { + CPm_DISABLE = 0b00, // Default + CPm_10pct = 0b01, + CPm_20pct = 0b10, + CPm_30pct = 0b11, // ! Show best linearity result +} CP_Mode = CPm_30pct; + +//static const bool LDS = false; + +#define CS_ADF0_HIGH {palSetLine(LINE_LO_SEL);ADF_CS_DELAY;} +#define CS_ADF0_LOW {palClearLine(LINE_LO_SEL);ADF_CS_DELAY;} + + +void ADF4351_WriteRegister32(int channel, const uint32_t value) +{ + (void) channel; + // Select chip + CS_ADF0_LOW; + // Send 32 bit register + #if 1 + SPI_WRITE_8BIT(SI4432_SPI, (value >> 24)); + SPI_WRITE_8BIT(SI4432_SPI, (value >> 16)); + SPI_WRITE_8BIT(SI4432_SPI, (value >> 8)); + SPI_WRITE_8BIT(SI4432_SPI, (value >> 0)); + while (SPI_IS_BUSY(SI4432_SPI)); // drop rx and wait tx + #else + shiftOut((value >> 24) & 0xFF); + shiftOut((value >> 16) & 0xFF); + shiftOut((value >> 8) & 0xFF); + shiftOut((value >> 0) & 0xFF); + #endif + // unselect + CS_ADF0_HIGH; +} + +void sendConfig(void) { + if (SI4432_SPI_SPEED != ADF_SPI_SPEED) + SPI_BR_SET(SI4432_SPI, ADF_SPI_SPEED); + if (max2871) { + pdwn = false; //Power down is no longer active. + uint32_t reg; + const bool fractional = false; + const bool LDS = true; + const uint32_t phase = 1; // Recommended + + // reg 5 + // LD pin register 5 + reg = (ld_pin<<22) | 0b101; + if (reg!=reg_5) {ADF4351_WriteRegister32(id, reg); reg_5 = reg;} + + // reg 4 + // fb rf divider bs divider VCO down mtld aux sel aux en aux pwr rf en rf pwr register 4 + reg = (feedbackFromDivided<<23) | (out_div<<20) | (bsDivider<<12) | (powerDown<<11) | (0<<10) | (0<<9) | (auxEnable<<8) | (auxPower<<6) | (rfEnable<<5) | (rfPower<<3) | 0b100; + if (reg!=reg_4) {ADF4351_WriteRegister32(id, reg); reg_4 = reg;} + + // reg 3 + // bscm | csr mutedel clkdiv mode clkdiv register 3 + reg = (bscm<<23) | (csr<<18) | (0<<17) | (clkDivMode<<15) | (clkDivDivider<<3) | 0b011; + if (reg!=reg_3) {ADF4351_WriteRegister32(id, reg); reg_3 = reg;} + + // reg 2 cp three reset + // LD speed noise mode muxout ref dbr ref div2 R DB CP current LDF LDP PD pol powerdown state counter register 2 + reg = (LDS<<31) | (noiseMode<<29) | (mux<<26) | (refDouble<<25) | (refDiv2 << 24) | (R<<14) | (0<<13) | (cpCurrent<<9) | (LDF<<8) | (LDP<<7) | (1<<6) | (pdwn<<5) | (0<<4) | (0<<3) | 0b010; + if (reg!=reg_2) {ADF4351_WriteRegister32(id, reg); reg_2 = reg;} + + // reg 1 + // CP mode CP test phase frac modulus + reg = (CP_Mode<<29) | (CP_Test<<27) | (phase<<15) | (modulus<<3) | 0b001; + if (reg!=reg_1) {ADF4351_WriteRegister32(id, reg); reg_1 = reg;} + + // reg 0 (need always send for apply some reg 1 - 5 settings + reg = (fractional<<31) | (N<<15) | (frac<<3) | 0b000; + /*if (reg!=reg_0)*/ {ADF4351_WriteRegister32(id, reg);/* reg_0 = reg;*/} + } else { + pdwn = false; //Power down is no longer active. + uint32_t reg; +#ifdef BOARD_DOUBLE_REF_MODE + uint32_t prescaler = (N > 75) ? 1 : 0; +#else + uint32_t prescaler = 1; +#endif + // reg 5 + // LD pin register 5 + reg = (ld_pin<<22) | (0b11<<19)| 0b101; + if (reg!=reg_5) {ADF4351_WriteRegister32(id, reg); reg_5 = reg;} + + // reg 4 + // fb rf divider bs divider VCO down mtld aux sel aux en aux pwr rf en rf pwr register 4 + reg = (feedbackFromDivided<<23) | (out_div<<20) | (bsDivider<<12) | (0<<11) | (0<<10) | (0<<9) | (auxEnable<<8) | (auxPower<<6) | (rfEnable<<5) | (rfPower<<3) | 0b100; + if (reg!=reg_4) {ADF4351_WriteRegister32(id, reg); reg_4 = reg;} + + // reg 3 + // csr clkdiv mode clkdiv register 3 + reg = (csr<<18) | (clkDivMode<<15) | (clkDivDivider<<3) | 0b011; + if (reg!=reg_3) {ADF4351_WriteRegister32(id, reg); reg_3 = reg;} + + // reg 2 cp three reset + // noise mode muxout ref dbr ref div2 R DB CP current LDF LDP PD pol powerdown state counter register 2 + reg = (noiseMode<<29) | (mux<<26) | (refDouble<<25) | (refDiv2 << 24) | (R<<14) | (0<<13) | (cpCurrent<<9) | (LDF<<8) | (LDP<<7) | (1<<6) | (pdwn<<5) | (0<<4) | (0<<3) | 0b010; + if (reg!=reg_2) {ADF4351_WriteRegister32(id, reg); reg_2 = reg;} + + // reg 1 + // prescaler phase frac modulus + reg = (prescaler<<27) | (phase<<15) | (modulus<<3) | 0b001; + if (reg!=reg_1) {ADF4351_WriteRegister32(id, reg); reg_1 = reg;} + + // reg 0 (need always send for apply some reg 1 - 5 settings + reg = (N<<15) | (frac<<3) | 0b000; + /*if (reg!=reg_0)*/ {ADF4351_WriteRegister32(id, reg);/* reg_0 = reg;*/} + } + if (SI4432_SPI_SPEED != ADF_SPI_SPEED) + SPI_BR_SET(SI4432_SPI, SI4432_SPI_SPEED); +} + + +void sendPowerdown(bool p) { + if(pdwn == p) + return; + pdwn = p; + uint32_t reg = (noiseMode<<29) | (0b001<<26) | (refDouble<<25) | (refDiv2 << 24) | (R<<14) | (cpCurrent<<9) | (0<<8) | (0<<7) | (1<<6) | (pdwn<<5) | 0b010; + if (reg!=reg_2) {ADF4351_WriteRegister32(id, reg); reg_2 = reg;} +} + + +static uint32_t adf4350_get_O(uint64_t freqHz) { + if(max2871) { + if(freqHz > 3000000000) return 0; // 1 + else if(freqHz > 1500000000) return 1; // 2 + else if(freqHz > 750000000) return 2; // 4 + else if(freqHz > 375000000) return 3; // 8 + else if(freqHz > 187500000) return 4; // 16 + else if(freqHz > 137500000) return 5; // 32 + else if(freqHz > 68750000) return 6; // 64 + else/*if(freqHz > 34375000)*/return 7; //128 + }else{ + if(freqHz > 2200000000) return 0; // 1 + else if(freqHz > 1100000000) return 1; // 2 + else if(freqHz > 550000000) return 2; // 4 + else if(freqHz > 275000000) return 3; // 8 + else/*if(freqHz > 137500000)*/return 4; // 16 + } +} + +uint64_t ADF4351_set_frequency(int channel, uint64_t freqHz) { + if (prev_actual_freq == freqHz) + return prev_actual_freq; + (void) channel; + // RFout = xtalFreqHz × (N + FRAC/MOD) = xtalFreqHz × (N * MOD + FRAC) / MOD + // step = xtalFreqHz / MOD; !!!! should get integer result, also this result should divided by 16 + // for 24M step = 24M / 4000 = 6k and 6k/16 = 375 + // Nx = RFout / step + // N * 4000 + frac = Nx + // N = Nx / 4000 + // frac = Nx % 4000 + + uint32_t xtal = (uint32_t)(config.setting_frequency_30mhz / 100ULL); + if (refDouble) { + xtal<<=1; + } + if (R > 1) + xtal /= R; + + out_div = adf4350_get_O(freqHz); + + uint32_t step = (xtal) / modulus; + uint32_t _N = (freqHz<> (bit)) & 0x01) #define bitSet(value, bit) ((value) |= (1UL << (bit))) @@ -714,6 +1111,7 @@ void ADF4351_enable_out(int s) osalThreadSleepMilliseconds(1); } +#endif // ------------------------------ SI4468 ------------------------------------- @@ -748,7 +1146,7 @@ extern volatile int sleep; }; #else -inline int SI4463_wait_CTS(void) { +int SI4463_wait_CTS(void) { int t=0; while (!SI4463_READ_CTS) { t++; @@ -2236,9 +2634,10 @@ static int old_high = 2; void enable_ADF_output(int f, int t) { + (void) t; ADF4351_enable(true); ADF4351_enable_out(f); - ADF4351_enable_aux_out(t); +// ADF4351_enable_aux_out(t); } #ifdef __NEW_SWITCHES__ diff --git a/ui.c b/ui.c index 1b41f69..f19e364 100644 --- a/ui.c +++ b/ui.c @@ -4943,6 +4943,7 @@ static const menuitem_t menu_stimulus[] = { { MT_SUBMENU, 0, "VBW", menu_vbw}, #endif { MT_ADV_CALLBACK,0, "SHIFT\nFREQ", menu_shift_acb}, + { MT_CALLBACK, ST_CENTER, "MARKER\n"S_RARROW" CENTER", menu_marker_op_cb }, { MT_NONE, 0, NULL, menu_back} // next-> menu_back }; @@ -5100,8 +5101,8 @@ static void fetch_numeric_target(uint8_t mode) plot_printf(uistat.text, sizeof uistat.text, "AUTO"); break; case KM_CP: - uistat.value = ADF4350_modulo; - plot_printf(uistat.text, sizeof uistat.text, "%d", ADF4350_modulo); + uistat.value = ADF4351_get_CP(); + plot_printf(uistat.text, sizeof uistat.text, "%d", ((int32_t)uistat.value)); break; #endif case KM_SAMPLETIME: