@@ -50,6 +50,10 @@ static constexpr uint16_t maxPointsBetweenHalts = 40;
5050static constexpr uint16_t full2portDatapointSize = 66 ;// See Protocol::VNADatapoint::
5151static constexpr uint32_t reservedUSBbuffer = (maxPointsBetweenHalts + 2 /* additional buffer*/ ) * (full2portDatapointSize + 8 /* USB packet overhead*/ );
5252
53+ static uint32_t PLLRefFreqs[] = {HW::PLLRef, HW::PLLRef - 1000000 };
54+ static constexpr uint8_t PLLRefFreqsNum = sizeof (PLLRefFreqs)/sizeof (PLLRefFreqs[0 ]);
55+ static uint8_t sourceRefIndex, LO1RefIndex;
56+
5357using namespace HWHAL ;
5458
5559static uint64_t getPointFrequency (uint16_t pointNum) {
@@ -71,16 +75,43 @@ static uint64_t getPointFrequency(uint16_t pointNum) {
7175 }
7276}
7377
74- static void setPLLFrequencies (uint64_t f) {
78+ static bool setPLLFrequencies (uint64_t f) {
79+ uint64_t sourceFreq = 0 ;
80+ uint64_t LOFreq = 0 ;
7581 if (f > HW::Info.limits_maxFreq ) {
76- Source. SetFrequency ( f / sourceHarmonic) ;
77- LO1. SetFrequency (( f + HW::getIF1 ()) / LOHarmonic) ;
82+ sourceFreq = f / sourceHarmonic;
83+ LOFreq = ( f + HW::getIF1 ()) / LOHarmonic;
7884 } else {
7985 if (f >= HW::BandSwitchFrequency) {
80- Source. SetFrequency (f) ;
86+ sourceFreq = f ;
8187 }
82- LO1.SetFrequency (f + HW::getIF1 ());
88+ LOFreq = f + HW::getIF1 ();
89+ }
90+ if (sourceFreq > 0 ) {
91+ Source.SetFrequency (sourceFreq);
8392 }
93+ LO1.SetFrequency (LOFreq);
94+ bool needsRefSwitch = false ;
95+ if (settings.suppressPeaks ) {
96+ // Integer spurs can cause a small peak.
97+ uint32_t sourceDist = Source.DistanceToIntegerSpur ();
98+ uint32_t LODist = LO1.DistanceToIntegerSpur ();
99+ if ((sourceDist > 0 ) && (sourceDist < 3 * HW::getIF2 ())) {
100+ LOG_INFO (" Source spur at %lu: %lu" , (uint32_t ) f, sourceDist);
101+ sourceRefIndex = !sourceRefIndex;
102+ Source.SetReference (PLLRefFreqs[sourceRefIndex], false , 1 , false );
103+ Source.SetFrequency (sourceFreq);
104+ needsRefSwitch = true ;
105+ }
106+ if ((LODist > 0 ) && (LODist < 3 * HW::getIF2 ())) {
107+ LOG_INFO (" LO spur at %lu" , (uint32_t ) f);
108+ LO1RefIndex = !LO1RefIndex;
109+ LO1.SetReference (PLLRefFreqs[LO1RefIndex], false , 1 , false );
110+ LO1.SetFrequency (LOFreq);
111+ needsRefSwitch = true ;
112+ }
113+ }
114+ return needsRefSwitch;
84115}
85116
86117static bool needs2LOshift (uint64_t f, uint32_t current2LO, uint32_t IFBW, uint32_t *new2LO) {
@@ -108,11 +139,17 @@ static bool needs2LOshift(uint64_t f, uint32_t current2LO, uint32_t IFBW, uint32
108139}
109140
110141bool VNA::Setup (Protocol::SweepSettings s) {
142+ // Abort possible active sweep first
111143 VNA::Stop ();
112144 vTaskDelay (5 );
113145 data.clear ();
114146 HW::SetMode (HW::Mode::VNA);
115- // Abort possible active sweep first
147+
148+ sourceRefIndex = 0 ;
149+ LO1RefIndex = 0 ;
150+ Source.SetReference (PLLRefFreqs[sourceRefIndex], false , 1 , false );
151+ LO1.SetReference (PLLRefFreqs[LO1RefIndex], false , 1 , false );
152+
116153 FPGA::SetMode (FPGA::Mode::FPGA);
117154 FPGA::WriteRegister (FPGA::Reg::ADCPrescaler, HW::getADCPrescaler ());
118155 FPGA::WriteRegister (FPGA::Reg::PhaseIncrement, HW::getDFTPhaseInc ());
@@ -199,7 +236,9 @@ bool VNA::Setup(Protocol::SweepSettings s) {
199236 }
200237 // SetFrequency only manipulates the register content in RAM, no SPI communication is done.
201238 // No mode-switch of FPGA necessary here.
202- setPLLFrequencies (freq);
239+ if (setPLLFrequencies (freq)) {
240+ needs_halt = true ;
241+ }
203242 uint32_t new_LO2;
204243 auto needs_shift = needs2LOshift (freq, last_LO2, actualBandwidth, &new_LO2);
205244 if (needs_shift) {
@@ -249,6 +288,11 @@ bool VNA::Setup(Protocol::SweepSettings s) {
249288 FPGA::Samples::SPPRegister, needs_halt);
250289 last_lowband = lowband;
251290 }
291+ // reset a possibly changed PLL reference index
292+ sourceRefIndex = 0 ;
293+ LO1RefIndex = 0 ;
294+ Source.SetReference (PLLRefFreqs[sourceRefIndex], false , 1 , false );
295+ LO1.SetReference (PLLRefFreqs[LO1RefIndex], false , 1 , false );
252296 // revert clk configuration to previous value (might have been changed in sweep calculation)
253297 Si5351.SetCLK (SiChannel::RefLO2, HW::getIF1 () - HW::getIF2 (), Si5351C::PLL::B, Si5351C::DriveStrength::mA2 );
254298 Si5351.ResetPLL (Si5351C::PLL::B);
@@ -438,10 +482,30 @@ void VNA::SweepHalted() {
438482 Si5351.Disable (SiChannel::LowbandSource);
439483 FPGA::Enable (FPGA::Periphery::SourceRF);
440484 }
485+
486+ if (pointCnt == 0 && settings.suppressPeaks ) {
487+ sourceRefIndex = 0 ;
488+ LO1RefIndex = 0 ;
489+ Source.SetReference (PLLRefFreqs[sourceRefIndex], false , 1 , false );
490+ LO1.SetReference (PLLRefFreqs[LO1RefIndex], false , 1 , false );
491+ // update PLL reference frequencies
492+ Si5351.SetCLK (SiChannel::Source, PLLRefFreqs[sourceRefIndex], Si5351C::PLL::A, Si5351C::DriveStrength::mA8 );
493+ Si5351.SetCLK (SiChannel::LO1, PLLRefFreqs[LO1RefIndex], Si5351C::PLL::A, Si5351C::DriveStrength::mA8 );
494+ last_LO2 = HW::getIF1 () - HW::getIF2 ();
495+ Si5351.SetPLL (Si5351C::PLL::B, last_LO2*HW::LO2Multiplier, HW::Ref::getSource ());
496+ Si5351.ResetPLL (Si5351C::PLL::B);
497+ Si5351.WaitForLock (Si5351C::PLL::B, 10 );
498+ HAL_Delay (2 );
499+ }
500+
441501 if (settings.suppressPeaks ) {
442502 // does not actually change PLL settings, just calculates the register values and
443503 // is required to determine the need for a 2.LO shift
444- setPLLFrequencies (frequency);
504+ if (setPLLFrequencies (frequency)) {
505+ // update PLL reference frequencies
506+ Si5351.SetCLK (SiChannel::Source, PLLRefFreqs[sourceRefIndex], Si5351C::PLL::A, Si5351C::DriveStrength::mA8 );
507+ Si5351.SetCLK (SiChannel::LO1, PLLRefFreqs[LO1RefIndex], Si5351C::PLL::A, Si5351C::DriveStrength::mA8 );
508+ }
445509 if (needs2LOshift (frequency, last_LO2, actualBandwidth, &last_LO2)) {
446510 Si5351.SetPLL (Si5351C::PLL::B, last_LO2*HW::LO2Multiplier, HW::Ref::getSource ());
447511 Si5351.ResetPLL (Si5351C::PLL::B);
@@ -451,14 +515,6 @@ void VNA::SweepHalted() {
451515 }
452516 }
453517
454- if (pointCnt == 0 ) {
455- last_LO2 = HW::getIF1 () - HW::getIF2 ();
456- Si5351.SetPLL (Si5351C::PLL::B, last_LO2*HW::LO2Multiplier, HW::Ref::getSource ());
457- Si5351.ResetPLL (Si5351C::PLL::B);
458- Si5351.WaitForLock (Si5351C::PLL::B, 10 );
459- HAL_Delay (2 );
460- }
461-
462518 if (adcShiftRequired) {
463519 FPGA::WriteRegister (FPGA::Reg::ADCPrescaler, alternativePrescaler);
464520 FPGA::WriteRegister (FPGA::Reg::PhaseIncrement, alternativePhaseInc);
0 commit comments