diff --git a/FPGA/VNA/MCP33131.vhd b/FPGA/VNA/MCP33131.vhd index 9f4eeba..8b560c3 100644 --- a/FPGA/VNA/MCP33131.vhd +++ b/FPGA/VNA/MCP33131.vhd @@ -50,7 +50,7 @@ architecture Behavioral of MCP33131 is signal div_cnt : integer range 0 to (CLK_DIV/2)-1; signal sclk_phase : std_logic; signal adc_data : std_logic_vector(15 downto 0); - type States is (Idle, Conversion, Transmission); + type States is (Idle, Conversion, WAIT_tEN, Transmission); signal state : States; signal min_int, max_int, data_int : signed(15 downto 0); begin @@ -100,8 +100,10 @@ begin div_cnt <= 0; CONVSTART <= '0'; adc_data <= "0000000000000001"; - state <= Transmission; + state <= WAIT_tEN; end if; + when WAIT_tEN => + state <= Transmission; when Transmission => if(div_cnt < (CLK_DIV/2)-1) then div_cnt <= div_cnt + 1; diff --git a/FPGA/VNA/SPIConfig.vhd b/FPGA/VNA/SPIConfig.vhd index 5bf4ed2..48a0d19 100644 --- a/FPGA/VNA/SPIConfig.vhd +++ b/FPGA/VNA/SPIConfig.vhd @@ -60,8 +60,11 @@ entity SPICommands is LO_RF_EN : out STD_LOGIC; SOURCE_CE_EN : out STD_LOGIC; LO_CE_EN : out STD_LOGIC; + PORTSWITCH_EN : out STD_LOGIC; LEDS : out STD_LOGIC_VECTOR(2 downto 0); WINDOW_SETTING : out STD_LOGIC_VECTOR(1 downto 0); + ADC_PRESCALER : out STD_LOGIC_VECTOR(7 downto 0); + ADC_PHASEINC : out STD_LOGIC_VECTOR(11 downto 0); INTERRUPT_ASSERTED : out STD_LOGIC; RESET_MINMAX : out STD_LOGIC; SWEEP_HALTED : in STD_LOGIC; @@ -139,10 +142,13 @@ begin LO_RF_EN <= '0'; SOURCE_CE_EN <= '0'; LO_CE_EN <= '0'; + PORTSWITCH_EN <= '0'; LEDS <= (others => '1'); WINDOW_SETTING <= "00"; unread_sampling_data <= '0'; interrupt_mask <= (others => '0'); + ADC_PRESCALER <= std_logic_vector(to_unsigned(112, 8)); + ADC_PHASEINC <= std_logic_vector(to_unsigned(1120, 12)); RESET_MINMAX <= '0'; else if sweep_config_write = '1' then @@ -191,7 +197,7 @@ begin when 0 => interrupt_mask <= spi_buf_out; when 1 => SWEEP_POINTS <= spi_buf_out(12 downto 0); when 2 => NSAMPLES <= spi_buf_out(9 downto 0); - when 3 => --NSAMPLES(16) <= spi_buf_out(0); + when 3 => PORTSWITCH_EN <= spi_buf_out(0); PORT1_EN <= spi_buf_out(15); PORT2_EN <= spi_buf_out(14); REF_EN <= spi_buf_out(13); @@ -204,8 +210,8 @@ begin LO_CE_EN <= spi_buf_out(3); EXCITE_PORT1 <= spi_buf_out(1); EXCITE_PORT2 <= spi_buf_out(2); - --when 4 => SETTLING_TIME <= spi_buf_out; - + when 4 => ADC_PRESCALER <= spi_buf_out(7 downto 0); + when 5 => ADC_PHASEINC <= spi_buf_out(11 downto 0); when 8 => MAX2871_DEF_0(15 downto 0) <= spi_buf_out; when 9 => MAX2871_DEF_0(31 downto 16) <= spi_buf_out; when 10 => MAX2871_DEF_1(15 downto 0) <= spi_buf_out; diff --git a/FPGA/VNA/Sampling.vhd b/FPGA/VNA/Sampling.vhd index c50ef8a..3199960 100644 --- a/FPGA/VNA/Sampling.vhd +++ b/FPGA/VNA/Sampling.vhd @@ -30,12 +30,11 @@ use IEEE.NUMERIC_STD.ALL; --use UNISIM.VComponents.all; entity Sampling is - Generic(CLK_DIV : integer; - CLK_FREQ : integer; - IF_FREQ : integer; - CLK_CYCLES_PRE_DONE : integer); + Generic(CLK_CYCLES_PRE_DONE : integer); Port ( CLK : in STD_LOGIC; RESET : in STD_LOGIC; + ADC_PRESCALER : in STD_LOGIC_VECTOR(7 downto 0); + PHASEINC : in STD_LOGIC_VECTOR(11 downto 0); PORT1 : in STD_LOGIC_VECTOR (15 downto 0); PORT2 : in STD_LOGIC_VECTOR (15 downto 0); REF : in STD_LOGIC_VECTOR (15 downto 0); @@ -87,11 +86,10 @@ END COMPONENT; signal p2_Q : signed(47 downto 0); signal r_I : signed(47 downto 0); signal r_Q : signed(47 downto 0); - signal clk_cnt : integer range 0 to CLK_DIV - 1; + signal clk_cnt : integer range 0 to 255; signal sample_cnt : integer range 0 to 131071; signal samples_to_take : integer range 0 to 131071; - constant phase_inc : integer := IF_FREQ * 4096 * CLK_DIV / CLK_FREQ; signal phase : std_logic_vector(11 downto 0); signal sine : std_logic_vector(15 downto 0); signal cosine : std_logic_vector(15 downto 0); @@ -206,7 +204,7 @@ begin else -- when not idle, generate pulses for ADCs if state /= Idle then - if clk_cnt = CLK_DIV - 1 then + if clk_cnt = unsigned(ADC_PRESCALER) - 1 then ADC_START <= '1'; clk_cnt <= 0; else @@ -234,7 +232,7 @@ begin phase <= (others => '0'); if START = '1' then state <= Sampling; - samples_to_take <= to_integer(unsigned(SAMPLES & "0000000")); + samples_to_take <= to_integer(unsigned(SAMPLES & "0000000") - 1); end if; when Sampling => DONE <= '0'; @@ -260,7 +258,7 @@ begin ACTIVE <= '1'; DONE <= '0'; PRE_DONE <= '0'; - phase <= std_logic_vector(unsigned(phase) + phase_inc); + phase <= std_logic_vector(unsigned(phase) + unsigned(PHASEINC)); if sample_cnt < samples_to_take then sample_cnt <= sample_cnt + 1; state <= Sampling; diff --git a/FPGA/VNA/Test_MCP33131.vhd b/FPGA/VNA/Test_MCP33131.vhd index f258386..ed1c257 100644 --- a/FPGA/VNA/Test_MCP33131.vhd +++ b/FPGA/VNA/Test_MCP33131.vhd @@ -79,7 +79,7 @@ BEGIN -- Instantiate the Unit Under Test (UUT) uut: MCP33131 GENERIC MAP(CLK_DIV => 2, - CONVCYCLES => 71) + CONVCYCLES => 77) PORT MAP ( CLK => CLK, RESET => RESET, @@ -106,13 +106,13 @@ BEGIN begin -- hold reset state for 100 ns. RESET <= '1'; - wait for 100 ns; + wait for CLK_period*10.5; RESET <= '0'; wait for CLK_period*10; -- insert stimulus here while True loop - wait for CLK_period*105; + wait for CLK_period*111; START <= '1'; wait for CLK_period; START <= '0'; diff --git a/FPGA/VNA/VNA.gise b/FPGA/VNA/VNA.gise index 1009a69..743defc 100644 --- a/FPGA/VNA/VNA.gise +++ b/FPGA/VNA/VNA.gise @@ -47,9 +47,7 @@ - - @@ -126,7 +124,7 @@ - + @@ -153,11 +151,11 @@ - + - + @@ -172,7 +170,7 @@ - + @@ -196,15 +194,11 @@ - - - - - + @@ -213,21 +207,21 @@ - - + + - + - + @@ -266,7 +260,7 @@ - + @@ -288,7 +282,7 @@ - + @@ -297,10 +291,12 @@ - + + + @@ -311,7 +307,7 @@ - + @@ -325,7 +321,7 @@ - + @@ -371,7 +367,7 @@ - + diff --git a/FPGA/VNA/VNA.xise b/FPGA/VNA/VNA.xise index 52974f8..97ea6ba 100644 --- a/FPGA/VNA/VNA.xise +++ b/FPGA/VNA/VNA.xise @@ -23,11 +23,11 @@ - + - + @@ -117,11 +117,11 @@ - + - + @@ -382,8 +382,8 @@ - - + + @@ -401,7 +401,7 @@ - + @@ -453,7 +453,7 @@ - + diff --git a/FPGA/VNA/top.vhd b/FPGA/VNA/top.vhd index f00413e..f50f8dd 100644 --- a/FPGA/VNA/top.vhd +++ b/FPGA/VNA/top.vhd @@ -145,13 +145,12 @@ architecture Behavioral of top is ); END COMPONENT; COMPONENT Sampling - Generic(CLK_DIV : integer; - CLK_FREQ : integer; - IF_FREQ : integer; - CLK_CYCLES_PRE_DONE : integer); + Generic(CLK_CYCLES_PRE_DONE : integer); PORT( CLK : IN std_logic; RESET : IN std_logic; + ADC_PRESCALER : in STD_LOGIC_VECTOR(7 downto 0); + PHASEINC : in STD_LOGIC_VECTOR(11 downto 0); PORT1 : IN std_logic_vector(15 downto 0); PORT2 : IN std_logic_vector(15 downto 0); REF : IN std_logic_vector(15 downto 0); @@ -236,8 +235,11 @@ architecture Behavioral of top is LO_RF_EN : out STD_LOGIC; SOURCE_CE_EN : out STD_LOGIC; LO_CE_EN : out STD_LOGIC; + PORTSWITCH_EN : out STD_LOGIC; LEDS : out STD_LOGIC_VECTOR(2 downto 0); WINDOW_SETTING : out STD_LOGIC_VECTOR(1 downto 0); + ADC_PRESCALER : out STD_LOGIC_VECTOR(7 downto 0); + ADC_PHASEINC : out STD_LOGIC_VECTOR(11 downto 0); INTERRUPT_ASSERTED : OUT std_logic; RESET_MINMAX : out STD_LOGIC; SWEEP_HALTED : in STD_LOGIC; @@ -307,6 +309,8 @@ architecture Behavioral of top is signal sampling_user_samples : std_logic_vector(9 downto 0); signal sampling_result : std_logic_vector(287 downto 0); signal sampling_window : std_logic_vector(1 downto 0); + signal sampling_prescaler : std_logic_vector(7 downto 0); + signal sampling_phaseinc : std_logic_vector(11 downto 0); -- Sweep signals signal sweep_points : std_logic_vector(12 downto 0); @@ -338,6 +342,7 @@ architecture Behavioral of top is signal port1mix_en : std_logic; signal port2mix_en : std_logic; signal refmix_en : std_logic; + signal portswitch_en : std_logic; -- PLL/SPI internal mux signal fpga_select : std_logic; @@ -367,10 +372,10 @@ begin LEDS(2) <= SOURCE_LD; LEDS(3) <= LO1_LD; -- Sweep and active port - PORT_SELECT2 <= not sweep_port_select; - PORT2_SELECT <= not sweep_port_select; - PORT_SELECT1 <= sweep_port_select; - PORT1_SELECT <= sweep_port_select; + PORT_SELECT2 <= not sweep_port_select and portswitch_en; + PORT2_SELECT <= not sweep_port_select and portswitch_en; + PORT_SELECT1 <= sweep_port_select and portswitch_en; + PORT1_SELECT <= sweep_port_select and portswitch_en; BAND_SELECT_HIGH <= not sweep_band; BAND_SELECT_LOW <= sweep_band; PORT1_MIX2_EN <= port1mix_en; @@ -379,8 +384,8 @@ begin PORT2_MIX1_EN <= not port2mix_en; REF_MIX2_EN <= refmix_en; REF_MIX1_EN <= not refmix_en; - LEDS(4) <= not (not sweep_reset and not sweep_port_select); - LEDS(5) <= not (not sweep_reset and sweep_port_select); + LEDS(4) <= not (not sweep_reset and not sweep_port_select and portswitch_en); + LEDS(5) <= not (not sweep_reset and sweep_port_select and portswitch_en); -- Uncommitted LEDs LEDS(7 downto 6) <= user_leds(1 downto 0); --LEDS(7) <= '0'; @@ -480,7 +485,7 @@ begin Port1ADC: MCP33131 GENERIC MAP(CLK_DIV => 2, - CONVCYCLES => 73) + CONVCYCLES => 77) PORT MAP( CLK => clk160, RESET => int_reset, @@ -496,7 +501,7 @@ begin ); Port2ADC: MCP33131 GENERIC MAP(CLK_DIV => 2, - CONVCYCLES => 73) + CONVCYCLES => 77) PORT MAP( CLK => clk160, RESET => int_reset, @@ -512,7 +517,7 @@ begin ); RefADC: MCP33131 GENERIC MAP(CLK_DIV => 2, - CONVCYCLES => 73) + CONVCYCLES => 77) PORT MAP( CLK => clk160, RESET => int_reset, @@ -528,13 +533,12 @@ begin ); Sampler: Sampling - GENERIC MAP(CLK_DIV => 112, - CLK_FREQ => 102400000, - IF_FREQ => 250000, - CLK_CYCLES_PRE_DONE => 0) + GENERIC MAP(CLK_CYCLES_PRE_DONE => 0) PORT MAP( CLK => clk160, RESET => sweep_reset, + ADC_PRESCALER => sampling_prescaler, + PHASEINC => sampling_phaseinc, PORT1 => adc_port1_data, PORT2 => adc_port2_data, REF => adc_ref_data, @@ -648,8 +652,11 @@ begin LO_RF_EN => LO1_RF_EN, SOURCE_CE_EN => SOURCE_CE, LO_CE_EN => LO1_CE, + PORTSWITCH_EN => portswitch_en, LEDS => user_leds, WINDOW_SETTING => sampling_window, + ADC_PRESCALER => sampling_prescaler, + ADC_PHASEINC => sampling_phaseinc, INTERRUPT_ASSERTED => intr, RESET_MINMAX => adc_reset_minmax, SWEEP_HALTED => sweep_halted, diff --git a/Software/PC_Application/Application b/Software/PC_Application/Application index cb7a605..8f7913e 100755 Binary files a/Software/PC_Application/Application and b/Software/PC_Application/Application differ diff --git a/Software/PC_Application/SpectrumAnalyzer/spectrumanalyzer.cpp b/Software/PC_Application/SpectrumAnalyzer/spectrumanalyzer.cpp index a4a3413..aeb57be 100644 --- a/Software/PC_Application/SpectrumAnalyzer/spectrumanalyzer.cpp +++ b/Software/PC_Application/SpectrumAnalyzer/spectrumanalyzer.cpp @@ -189,8 +189,8 @@ SpectrumAnalyzer::SpectrumAnalyzer(AppWindow *window) // if(pref.Startup.RememberSweepSettings) { // LoadSweepSettings(); // } else { - settings.f_start = pref.Startup.DefaultSweep.start; - settings.f_stop = pref.Startup.DefaultSweep.stop; + settings.f_start = 950000000; + settings.f_stop = 1050000000; ConstrainAndUpdateFrequencies(); SetRBW(10000); settings.WindowType = 1; @@ -235,7 +235,7 @@ void SpectrumAnalyzer::SettingsChanged() } average.reset(); traceModel.clearVNAData(); - TracePlot::UpdateSpan(settings.f_start, settings.f_stop); + emit traceModel.SpanChanged(settings.f_start, settings.f_stop); } void SpectrumAnalyzer::StartImpedanceMatching() diff --git a/Software/PC_Application/Traces/tracebodeplot.cpp b/Software/PC_Application/Traces/tracebodeplot.cpp index 05b648c..0c91168 100644 --- a/Software/PC_Application/Traces/tracebodeplot.cpp +++ b/Software/PC_Application/Traces/tracebodeplot.cpp @@ -146,6 +146,8 @@ TraceBodePlot::TraceBodePlot(TraceModel &model, QWidget *parent) // enable autoscaling and set for full span (no information about actual span available yet) setXAxis(0, 6000000000); setXAxis(true, 0, 6000000000, 600000000); + // get notified when the span changes + connect(&model, &TraceModel::SpanChanged, this, qOverload(&TraceBodePlot::setXAxis)); } TraceBodePlot::~TraceBodePlot() diff --git a/Software/PC_Application/Traces/tracemodel.h b/Software/PC_Application/Traces/tracemodel.h index 28bcde9..874b238 100644 --- a/Software/PC_Application/Traces/tracemodel.h +++ b/Software/PC_Application/Traces/tracemodel.h @@ -25,7 +25,9 @@ public: std::vector getTraces(); bool PortExcitationRequired(int port); + signals: + void SpanChanged(double fmin, double fmax); void traceAdded(Trace *t); void traceRemoved(Trace *t); void requiredExcitation(bool excitePort1, bool excitePort2); diff --git a/Software/PC_Application/Traces/traceplot.cpp b/Software/PC_Application/Traces/traceplot.cpp index 552a867..d90ef77 100644 --- a/Software/PC_Application/Traces/traceplot.cpp +++ b/Software/PC_Application/Traces/traceplot.cpp @@ -48,13 +48,6 @@ void TracePlot::mouseDoubleClickEvent(QMouseEvent *) { emit doubleClicked(this); } -void TracePlot::UpdateSpan(double fmin, double fmax) -{ - for(auto p : plots) { - p->setXAxis(fmin, fmax); - } -} - void TracePlot::initializeTraceInfo(TraceModel &model) { // Populate already present traces diff --git a/Software/PC_Application/Traces/traceplot.h b/Software/PC_Application/Traces/traceplot.h index c6806e5..0270616 100644 --- a/Software/PC_Application/Traces/traceplot.h +++ b/Software/PC_Application/Traces/traceplot.h @@ -19,7 +19,6 @@ public: virtual void setXAxis(double min, double max){Q_UNUSED(min);Q_UNUSED(max)}; static std::set getPlots(); - static void UpdateSpan(double fmin, double fmax); signals: void doubleClicked(QWidget *w); diff --git a/Software/PC_Application/VNA/vna.cpp b/Software/PC_Application/VNA/vna.cpp index 9990461..5ea16cf 100644 --- a/Software/PC_Application/VNA/vna.cpp +++ b/Software/PC_Application/VNA/vna.cpp @@ -544,7 +544,7 @@ void VNA::SettingsChanged() average.reset(); traceModel.clearVNAData(); UpdateStatusPanel(); - TracePlot::UpdateSpan(settings.f_start, settings.f_stop); + emit traceModel.SpanChanged(settings.f_start, settings.f_stop); } void VNA::StartImpedanceMatching() diff --git a/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.cpp b/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.cpp index e0d6e42..414f97a 100644 --- a/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.cpp +++ b/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.cpp @@ -21,7 +21,7 @@ static void SwitchBytes(int16_t &value) { value = (value & 0xFF00) >> 8 | (value & 0x00FF) << 8; } -void WriteRegister(FPGA::Reg reg, uint16_t value) { +void FPGA::WriteRegister(FPGA::Reg reg, uint16_t value) { uint8_t cmd[4] = {0x80, (uint8_t) reg, (uint8_t) (value >> 8), (uint8_t) (value & 0xFF)}; Low(CS); HAL_SPI_Transmit(&FPGA_SPI, (uint8_t*) cmd, 4, 100); diff --git a/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.hpp b/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.hpp index 731c244..5ddfdf3 100644 --- a/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.hpp +++ b/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.hpp @@ -12,7 +12,8 @@ enum class Reg { SweepPoints = 0x01, SamplesPerPoint = 0x02, SystemControl = 0x03, - SettlingTime = 0x04, + ADCPrescaler = 0x04, + PhaseIncrement = 0x05, MAX2871Def0LSB = 0x08, MAX2871Def0MSB = 0x09, MAX2871Def1LSB = 0x0A, @@ -49,6 +50,7 @@ enum class Periphery { LO1Chip = 0x0008, ExcitePort2 = 0x0004, ExcitePort1 = 0x0002, + PortSwitch = 0x0001, }; enum class Interrupt { @@ -96,6 +98,7 @@ bool Configure(Flash *f, uint32_t start_address, uint32_t bitstream_size); using HaltedCallback = void(*)(void); bool Init(HaltedCallback cb = nullptr); +void WriteRegister(FPGA::Reg reg, uint16_t value); void SetNumberOfPoints(uint16_t npoints); void SetSamplesPerPoint(uint32_t nsamples); void Enable(Periphery p, bool enable = true); diff --git a/Software/VNA_embedded/Application/Hardware.cpp b/Software/VNA_embedded/Application/Hardware.cpp index 62294c3..6c65f85 100644 --- a/Software/VNA_embedded/Application/Hardware.cpp +++ b/Software/VNA_embedded/Application/Hardware.cpp @@ -119,6 +119,10 @@ bool HW::Init(WorkRequest wr) { return false; } + // Set default ADC samplerate + FPGA::WriteRegister(FPGA::Reg::ADCPrescaler, 112); + FPGA::WriteRegister(FPGA::Reg::PhaseIncrement, 1120); + // Enable new data and sweep halt interrupt FPGA::EnableInterrupt(FPGA::Interrupt::NewData); FPGA::EnableInterrupt(FPGA::Interrupt::SweepHalted); @@ -211,6 +215,7 @@ void HW::SetIdle() { FPGA::Enable(FPGA::Periphery::Port1Mixer, false); FPGA::Enable(FPGA::Periphery::Port2Mixer, false); FPGA::Enable(FPGA::Periphery::RefMixer, false); + FPGA::Enable(FPGA::Periphery::PortSwitch, false); } void HW::fillDeviceInfo(Protocol::DeviceInfo *info) { diff --git a/Software/VNA_embedded/Application/Manual.cpp b/Software/VNA_embedded/Application/Manual.cpp index b3ca07b..42d0f29 100644 --- a/Software/VNA_embedded/Application/Manual.cpp +++ b/Software/VNA_embedded/Application/Manual.cpp @@ -71,6 +71,7 @@ void Manual::Setup(Protocol::ManualControl m) { FPGA::Enable(FPGA::Periphery::RefMixer, m.RefEN); FPGA::Enable(FPGA::Periphery::ExcitePort1, m.PortSwitch == 0); FPGA::Enable(FPGA::Periphery::ExcitePort2, m.PortSwitch == 1); + FPGA::Enable(FPGA::Periphery::PortSwitch); active = true; FPGA::StartSweep(); diff --git a/Software/VNA_embedded/Application/SpectrumAnalyzer.cpp b/Software/VNA_embedded/Application/SpectrumAnalyzer.cpp index 8fec47e..004dc75 100644 --- a/Software/VNA_embedded/Application/SpectrumAnalyzer.cpp +++ b/Software/VNA_embedded/Application/SpectrumAnalyzer.cpp @@ -17,6 +17,7 @@ static uint8_t signalIDstep; static uint32_t sampleNum; static Protocol::PacketInfo p; static bool active = false; +static uint32_t lastLO2; static float port1Measurement, port2Measurement; @@ -32,30 +33,44 @@ static void StartNextSample() { // reset minimum amplitudes in first signal ID step port1Measurement = std::numeric_limits::max(); port2Measurement = std::numeric_limits::max(); + // Use default LO frequencies LO1freq = freq + HW::IF1; LO2freq = HW::IF1 - HW::IF2; + FPGA::WriteRegister(FPGA::Reg::ADCPrescaler, 112); + FPGA::WriteRegister(FPGA::Reg::PhaseIncrement, 1120); break; case 1: + // Shift first LO to other side LO1freq = freq - HW::IF1; LO2freq = HW::IF1 - HW::IF2; break; case 2: + // Shift both LOs to other side LO1freq = freq + HW::IF1; LO2freq = HW::IF1 + HW::IF2; break; case 3: + // Shift second LO to other side LO1freq = freq - HW::IF1; LO2freq = HW::IF1 + HW::IF2; break; + case 4: + // Use default frequencies with different ADC samplerate to remove images in final IF + LO1freq = freq + HW::IF1; + LO2freq = HW::IF1 - HW::IF2; + FPGA::WriteRegister(FPGA::Reg::ADCPrescaler, 120); + FPGA::WriteRegister(FPGA::Reg::PhaseIncrement, 1200); } LO1.SetFrequency(LO1freq); // LO1 is not able to reach all frequencies with the required precision, adjust LO2 to account for deviation int32_t LO1deviation = (int64_t) LO1.GetActualFrequency() - LO1freq; LO2freq += LO1deviation; - // Adjust LO2 PLL - // Generate second LO with Si5351 - Si5351.SetCLK(SiChannel::Port1LO2, LO2freq, Si5351C::PLL::B, Si5351C::DriveStrength::mA2); - Si5351.SetCLK(SiChannel::Port2LO2, LO2freq, Si5351C::PLL::B, Si5351C::DriveStrength::mA2); + // only adjust LO2 PLL if necessary (if the deviation is significantly less than the RBW it does not matter) + if((uint32_t) abs(LO2freq - lastLO2) > s.RBW / 2) { + Si5351.SetCLK(SiChannel::Port1LO2, LO2freq, Si5351C::PLL::B, Si5351C::DriveStrength::mA2); + Si5351.SetCLK(SiChannel::Port2LO2, LO2freq, Si5351C::PLL::B, Si5351C::DriveStrength::mA2); + lastLO2 = LO2freq; + } // Configure the sampling in the FPGA FPGA::WriteSweepConfig(0, 0, Source.GetRegisters(), LO1.GetRegisters(), 0, 0, FPGA::SettlingTime::us20, FPGA::Samples::SPPRegister, 0, @@ -74,7 +89,7 @@ void SA::Setup(Protocol::SpectrumAnalyzerSettings settings) { // individually start each point and do the sweep in the uC FPGA::SetNumberOfPoints(1); // calculate amount of required points - points = (s.f_stop - s.f_start) / s.RBW; + points = 2 * (s.f_stop - s.f_start) / s.RBW; // adjust to integer multiple of requested result points (in order to have the same amount of measurements in each bin) points += s.pointNum - points % s.pointNum; binSize = points / s.pointNum; @@ -97,6 +112,7 @@ void SA::Setup(Protocol::SpectrumAnalyzerSettings settings) { FPGA::Enable(FPGA::Periphery::ExcitePort1); FPGA::Enable(FPGA::Periphery::Port1Mixer); FPGA::Enable(FPGA::Periphery::Port2Mixer); + lastLO2 = 0; active = true; StartNextSample(); } @@ -121,7 +137,7 @@ void SA::Work() { if(!active) { return; } - if(!s.SignalID || signalIDstep >= 3) { + if(!s.SignalID || signalIDstep >= 4) { // this measurement point is done, handle result according to detector uint16_t binIndex = pointCnt / binSize; uint32_t pointInBin = pointCnt % binSize; diff --git a/Software/VNA_embedded/Application/VNA.cpp b/Software/VNA_embedded/Application/VNA.cpp index f9323d2..9b5927a 100644 --- a/Software/VNA_embedded/Application/VNA.cpp +++ b/Software/VNA_embedded/Application/VNA.cpp @@ -165,6 +165,7 @@ bool VNA::Setup(Protocol::SweepSettings s, SweepCallback cb) { FPGA::Enable(FPGA::Periphery::LO1RF); FPGA::Enable(FPGA::Periphery::ExcitePort1, s.excitePort1); FPGA::Enable(FPGA::Periphery::ExcitePort2, s.excitePort2); + FPGA::Enable(FPGA::Periphery::PortSwitch); pointCnt = 0; // starting port depends on whether port 1 is active in sweep excitingPort1 = s.excitePort1; diff --git a/Software/VNA_embedded/Src/main.c b/Software/VNA_embedded/Src/main.c index 8de70f5..552641b 100644 --- a/Software/VNA_embedded/Src/main.c +++ b/Software/VNA_embedded/Src/main.c @@ -244,7 +244,7 @@ static void MX_I2C2_Init(void) /* USER CODE END I2C2_Init 1 */ hi2c2.Instance = I2C2; - hi2c2.Init.Timing = 0x20B0D9FF; + hi2c2.Init.Timing = 0x00E057FD; hi2c2.Init.OwnAddress1 = 0; hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; diff --git a/Software/VNA_embedded/VNA_embedded.ioc b/Software/VNA_embedded/VNA_embedded.ioc index bebe509..217582d 100644 --- a/Software/VNA_embedded/VNA_embedded.ioc +++ b/Software/VNA_embedded/VNA_embedded.ioc @@ -85,8 +85,9 @@ FREERTOS.configENABLE_BACKWARD_COMPATIBILITY=1 FREERTOS.configTOTAL_HEAP_SIZE=2048 FREERTOS.configUSE_MUTEXES=1 File.Version=6 -I2C2.IPParameters=Timing -I2C2.Timing=0x20B0D9FF +I2C2.I2C_Speed_Mode=I2C_Fast +I2C2.IPParameters=Timing,I2C_Speed_Mode +I2C2.Timing=0x00E057FD KeepUserPlacement=false Mcu.Family=STM32G4 Mcu.IP0=DMA