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);