diff --git a/Documentation/DeveloperInfo/FPGA_protocol.pdf b/Documentation/DeveloperInfo/FPGA_protocol.pdf index 0e4cacd..d457216 100644 Binary files a/Documentation/DeveloperInfo/FPGA_protocol.pdf and b/Documentation/DeveloperInfo/FPGA_protocol.pdf differ diff --git a/Documentation/DeveloperInfo/FPGA_protocol.tex b/Documentation/DeveloperInfo/FPGA_protocol.tex index 40acb96..2f3563f 100644 --- a/Documentation/DeveloperInfo/FPGA_protocol.tex +++ b/Documentation/DeveloperInfo/FPGA_protocol.tex @@ -13,6 +13,8 @@ {geometry} \usepackage{tikz} \usepackage{siunitx} +\DeclareSIUnit{\belmilliwatt}{Bm} +\DeclareSIUnit{\dBm}{\deci\belmilliwatt} \pgfdeclarelayer{background} \pgfdeclarelayer{foreground} @@ -494,24 +496,26 @@ The SweepConfig contains data for the source and LO1 PLL as well as the attenuat \bitrect{16}{64-\bit} \rwbits{0}{3}{LO DIV\_A[2:0]} \rwbits{3}{6}{LO VCO[5:0]} -\rwbits{9}{7}{LO N[6:0]} +\rwbits{9}{6}{LO N[5:0]} +\rwbits{15}{1}{BS} \end{tikzpicture} \begin{tikzpicture} \bitrect{16}{48-\bit} -\rwbits{0}{1}{BS} -\rwbits{1}{7}{Attenuator[6:0]} -\rwbits{8}{8}{Source M[11:4]} +\rwbits{0}{2}{PWR[1:0]} +\rwbits{2}{7}{Attenuator[6:0]} +\rwbits{9}{7}{Source M[11:5]} \end{tikzpicture} \begin{tikzpicture} \bitrect{16}{32-\bit} -\rwbits{0}{4}{Source M[3:0]} -\rwbits{4}{12}{Source FRAC[11:0]} +\rwbits{0}{5}{Source M[4:0]} +\rwbits{5}{11}{Source FRAC[11:1]} \end{tikzpicture} \begin{tikzpicture} \bitrect{16}{16-\bit} -\rwbits{0}{3}{Source DIV\_A[2:0]} -\rwbits{3}{6}{Source VCO[5:0]} -\rwbits{9}{7}{Source N[6:0]} +\rwbits{0}{1}{F[0]} +\rwbits{1}{3}{Source DIV\_A[2:0]} +\rwbits{4}{6}{Source VCO[5:0]} +\rwbits{10}{6}{Source N[5:0]} \end{tikzpicture} \end{center} \begin{itemize} @@ -554,6 +558,17 @@ Setting & Selected Band\\ \end{tabular} \end{center} \item \textbf{BS: Band select.} Set to 0 for highband, set to 1 for lowband. +\item \textbf{PWR:} Power setting of source PLL. Will be written to register 4, bits [4:3] of the source PLL, controlling the output power of output A. +\begin{center} +\begin{tabular}{ c|c } +Setting & Selected Power\\ + \hline +00 & \SI{-4}{\dBm}\\ +01 & \SI{-1}{\dBm}\\ +10 & \SI{2}{\dBm}\\ +11 & \SI{5}{\dBm}\\ +\end{tabular} +\end{center} \item \textbf{Attenuator:} Attenuation of source signal in \SI{0.25}{\decibel}. \end{itemize} diff --git a/FPGA/VNA/Sweep.vhd b/FPGA/VNA/Sweep.vhd index 3c81251..223b911 100644 --- a/FPGA/VNA/Sweep.vhd +++ b/FPGA/VNA/Sweep.vhd @@ -89,16 +89,16 @@ begin -- assemble registers -- source register 0: N divider and fractional division value - SOURCE_REG_0 <= MAX2871_DEF_0(31) & "000000000" & config_reg(6 downto 0) & config_reg(27 downto 16) & "000"; + SOURCE_REG_0 <= MAX2871_DEF_0(31) & "0000000000" & config_reg(5 downto 0) & config_reg(26 downto 15) & "000"; -- source register 1: Modulus value - SOURCE_REG_1 <= MAX2871_DEF_1(31 downto 15) & config_reg(39 downto 28) & "001"; + SOURCE_REG_1 <= MAX2871_DEF_1(31 downto 15) & config_reg(38 downto 27) & "001"; -- source register 3: VCO selection - SOURCE_REG_3 <= config_reg(12 downto 7) & MAX2871_DEF_3(25 downto 3) & "011"; - -- output power A passed on from default registers, output B disabled - SOURCE_REG_4 <= MAX2871_DEF_4(31 downto 23) & config_reg(15 downto 13) & MAX2871_DEF_4(19 downto 9) & "000" & MAX2871_DEF_4(5 downto 3) & "100"; + SOURCE_REG_3 <= config_reg(11 downto 6) & MAX2871_DEF_3(25 downto 3) & "011"; + -- output power A from config, output B disabled + SOURCE_REG_4 <= MAX2871_DEF_4(31 downto 23) & config_reg(14 downto 12) & MAX2871_DEF_4(19 downto 9) & "000" & MAX2871_DEF_4(5) & config_reg(47 downto 46) & "100"; -- LO register 0: N divider and fractional division value - LO_REG_0 <= MAX2871_DEF_0(31) & "000000000" & config_reg(54 downto 48) & config_reg(75 downto 64) & "000"; + LO_REG_0 <= MAX2871_DEF_0(31) & "0000000000" & config_reg(54 downto 49) & config_reg(75 downto 64) & "000"; -- LO register 1: Modulus value LO_REG_1 <= MAX2871_DEF_1(31 downto 15) & config_reg(87 downto 76) & "001"; -- LO register 3: VCO selection @@ -106,9 +106,9 @@ begin -- both outputs enabled at +5dbm LO_REG_4 <= MAX2871_DEF_4(31 downto 23) & config_reg(63 downto 61) & MAX2871_DEF_4(19 downto 9) & "111111100"; - ATTENUATOR <= config_reg(46 downto 40); + ATTENUATOR <= config_reg(45 downto 39); SOURCE_FILTER <= config_reg(89 downto 88); - BAND_SELECT <= config_reg(47); + BAND_SELECT <= config_reg(48); NSAMPLES <= USER_NSAMPLES when config_reg(92 downto 90) = "000" else std_logic_vector(to_unsigned(6, 13)) when config_reg(92 downto 90) = "001" else diff --git a/FPGA/VNA/VNA.gise b/FPGA/VNA/VNA.gise index f25e55f..238cc3f 100644 --- a/FPGA/VNA/VNA.gise +++ b/FPGA/VNA/VNA.gise @@ -224,7 +224,7 @@ - + @@ -253,7 +253,7 @@ - + @@ -275,7 +275,7 @@ - + @@ -284,12 +284,10 @@ - + - - @@ -300,7 +298,7 @@ - + @@ -314,7 +312,7 @@ - + @@ -368,7 +366,7 @@ - + diff --git a/FPGA/VNA/ipcore_dir/result_bram.xise b/FPGA/VNA/ipcore_dir/result_bram.xise index 0abc844..dc81dae 100644 --- a/FPGA/VNA/ipcore_dir/result_bram.xise +++ b/FPGA/VNA/ipcore_dir/result_bram.xise @@ -17,11 +17,11 @@ - + - + @@ -29,357 +29,28 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - diff --git a/FPGA/VNA/top.bin b/FPGA/VNA/top.bin index 1a6d8e3..313f393 100644 Binary files a/FPGA/VNA/top.bin and b/FPGA/VNA/top.bin differ diff --git a/Software/VNA_embedded/Application/Communication/Protocol.hpp b/Software/VNA_embedded/Application/Communication/Protocol.hpp index 02a9a3d..002284c 100644 --- a/Software/VNA_embedded/Application/Communication/Protocol.hpp +++ b/Software/VNA_embedded/Application/Communication/Protocol.hpp @@ -4,7 +4,7 @@ namespace Protocol { -static constexpr uint16_t Version = 5; +static constexpr uint16_t Version = 7; #pragma pack(push, 1) @@ -22,10 +22,12 @@ using SweepSettings = struct _sweepSettings { uint64_t f_stop; uint16_t points; uint32_t if_bandwidth; - int16_t cdbm_excitation; // in 1/100 dbm + int16_t cdbm_excitation_start; // in 1/100 dbm uint8_t excitePort1:1; uint8_t excitePort2:1; uint8_t suppressPeaks:1; + uint8_t fixedPowerSetting:1; // if set the attenuator and source PLL power will not be changed across the sweep + int16_t cdbm_excitation_stop; // in 1/100 dbm }; using ReferenceSettings = struct _referenceSettings { diff --git a/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.cpp b/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.cpp index 7d3db0e..2f950fa 100644 --- a/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.cpp +++ b/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.cpp @@ -197,6 +197,8 @@ void FPGA::WriteSweepConfig(uint16_t pointnum, bool lowband, uint32_t *SourceReg uint16_t Source_VCO = (SourceRegs[3] & 0xFC000000) >> 26; uint16_t Source_DIV_A = (SourceRegs[4] & 0x00700000) >> 20; + uint16_t Source_Power = (SourceRegs[4] & 0x00000018) >> 3; + send[1] = LO_M >> 4; if (halt) { send[1] |= 0x8000; @@ -218,13 +220,13 @@ void FPGA::WriteSweepConfig(uint16_t pointnum, bool lowband, uint32_t *SourceReg send[1] |= (int) filter << 8; } send[2] = (LO_M & 0x000F) << 12 | LO_FRAC; - send[3] = LO_DIV_A << 13 | LO_VCO << 7 | LO_N; - send[4] = (uint16_t) attenuation << 8 | Source_M >> 4; + send[3] = LO_DIV_A << 13 | LO_VCO << 7 | LO_N << 1; + send[4] = Source_Power << 14 | (uint16_t) attenuation << 7 | Source_M >> 5; if (lowband) { - send[4] |= 0x8000; + send[3] |= 0x0001; } - send[5] = (Source_M & 0x000F) << 12 | Source_FRAC; - send[6] = Source_DIV_A << 13 | Source_VCO << 7 | Source_N; + send[5] = (Source_M & 0x001F) << 11 | Source_FRAC >> 1; + send[6] = (Source_FRAC & 0x0001) << 15 | Source_DIV_A << 12 | Source_VCO << 6 | Source_N; SwitchBytes(send[0]); SwitchBytes(send[1]); SwitchBytes(send[2]); diff --git a/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.hpp b/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.hpp index a10a58b..6540fd6 100644 --- a/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.hpp +++ b/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.hpp @@ -2,6 +2,7 @@ #include #include "Flash.hpp" +#include "max2871.hpp" namespace FPGA { diff --git a/Software/VNA_embedded/Application/VNA.cpp b/Software/VNA_embedded/Application/VNA.cpp index 64ba197..f4dd3cb 100644 --- a/Software/VNA_embedded/Application/VNA.cpp +++ b/Software/VNA_embedded/Application/VNA.cpp @@ -23,7 +23,7 @@ static uint16_t pointCnt; static bool excitingPort1; static Protocol::Datapoint data; static bool active = false; -static bool sourceHighPower; +static Si5351C::DriveStrength fixedPowerLowband; static bool adcShifted; static uint32_t actualBandwidth; @@ -76,26 +76,24 @@ bool VNA::Setup(Protocol::SweepSettings s) { // has to be one less than actual number of samples FPGA::SetSamplesPerPoint(samplesPerPoint); - // Set level (not very accurate) - int16_t cdbm = s.cdbm_excitation; - if(cdbm > -1000) { - // use higher source power (approx 0dbm with no attenuation) - sourceHighPower = true; - Source.SetPowerOutA(MAX2871::Power::p5dbm, true); - } else { - // use lower source power (approx -10dbm with no attenuation) - sourceHighPower = false; - Source.SetPowerOutA(MAX2871::Power::n4dbm, true); - cdbm += 1000; - } - uint8_t attenuator; - if(cdbm >= 0) { - attenuator = 0; - } else if (cdbm <= -3175){ - attenuator = 127; - } else { - attenuator = (-cdbm) / 25; + // Start with average level + auto cdbm = (s.cdbm_excitation_start + s.cdbm_excitation_stop) / 2; + // correct for port 1, assumes port 2 is identical + auto centerFreq = (s.f_start + s.f_stop) / 2; + // force calculation of amplitude setting for PLL, even with lower frequencies + if(centerFreq < HW::BandSwitchFrequency) { + centerFreq = HW::BandSwitchFrequency; } + auto amplitude = HW::GetAmplitudeSettings(cdbm, centerFreq, true, false); + + uint8_t fixedAttenuatorHighband = amplitude.attenuator; + Source.SetPowerOutA(amplitude.highBandPower, true); + + // amplitude calculation for lowband + amplitude = HW::GetAmplitudeSettings(cdbm, HW::BandSwitchFrequency / 2, true, false); + uint8_t fixedAttenuatorLowband = amplitude.attenuator; + fixedPowerLowband = amplitude.lowBandPower; + FPGA::WriteMAX2871Default(Source.GetRegisters()); uint32_t last_LO2 = HW::IF1 - HW::IF2; @@ -117,6 +115,7 @@ bool VNA::Setup(Protocol::SweepSettings s) { for (uint16_t i = 0; i < points; i++) { bool harmonic_mixing = false; uint64_t freq = s.f_start + (s.f_stop - s.f_start) * i / (points - 1); + int16_t power = s.cdbm_excitation_start + (s.cdbm_excitation_stop - s.cdbm_excitation_start) * i / (points - 1); freq = Cal::FrequencyCorrectionToDevice(freq); if(freq > 6000000000ULL) { @@ -206,6 +205,16 @@ bool VNA::Setup(Protocol::SweepSettings s) { pointsWithoutHalt = 0; } + uint8_t attenuator = freq >= HW::BandSwitchFrequency ? fixedAttenuatorHighband : fixedAttenuatorLowband; + if(!s.fixedPowerSetting) { + // adapt power level throughout the sweep + amplitude = HW::GetAmplitudeSettings(power, freq, true, false); + if(freq >= HW::BandSwitchFrequency) { + Source.SetPowerOutA(amplitude.highBandPower, true); + } + attenuator = amplitude.attenuator; + } + FPGA::WriteSweepConfig(i, lowband, Source.GetRegisters(), LO1.GetRegisters(), attenuator, freq, FPGA::SettlingTime::us20, FPGA::Samples::SPPRegister, needs_halt); @@ -331,11 +340,20 @@ void VNA::SweepHalted() { uint64_t frequency = settings.f_start + (settings.f_stop - settings.f_start) * pointCnt / (settings.points - 1); + int16_t power = settings.cdbm_excitation_start + + (settings.cdbm_excitation_stop - settings.cdbm_excitation_start) + * pointCnt / (settings.points - 1); bool adcShiftRequired = false; if (frequency < HW::BandSwitchFrequency) { + auto driveStrength = fixedPowerLowband; + if(!settings.fixedPowerSetting) { + auto amplitude = HW::GetAmplitudeSettings(power, frequency, true, false); + // attenuator value has already been set in sweep setup + driveStrength = amplitude.lowBandPower; + } + // need the Si5351 as Source - Si5351.SetCLK(SiChannel::LowbandSource, frequency, Si5351C::PLL::B, - sourceHighPower ? Si5351C::DriveStrength::mA8 : Si5351C::DriveStrength::mA4); + Si5351.SetCLK(SiChannel::LowbandSource, frequency, Si5351C::PLL::B, driveStrength); if (pointCnt == 0) { // First point in sweep, enable CLK Si5351.Enable(SiChannel::LowbandSource);