diff --git a/Documentation/DeveloperInfo/FPGA_protocol.pdf b/Documentation/DeveloperInfo/FPGA_protocol.pdf index d457216..c30225d 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 2f3563f..459343e 100644 --- a/Documentation/DeveloperInfo/FPGA_protocol.tex +++ b/Documentation/DeveloperInfo/FPGA_protocol.tex @@ -343,9 +343,10 @@ The register contains the number of points per sweep negative one, e.g. set to 1 \rwbits{9}{2}{Window[1:0]} \rwbits{11}{1}{SCEN} \rwbits{12}{1}{LCEN} -\rwbits{13}{1}{EXP2} -\rwbits{14}{1}{EXP1} -\rwbits{15}{1}{PSEN} +\robits{13}{3}{reserved} +%\rwbits{13}{1}{EXP2} +%\rwbits{14}{1}{EXP1} +%\rwbits{15}{1}{PSEN} \end{tikzpicture} \end{center} \begin{itemize} @@ -371,8 +372,8 @@ Setting & Window type\\ \end{center} \item \textbf{SCEN:}{Source chip enable} \item \textbf{LCEN:}{LO chip enable} -\item \textbf{EXP1:}{Excite Port1 during sweep} -\item \textbf{EXP2:}{Excite Port2 during sweep} +%\item \textbf{EXP1:}{Excite Port1 during sweep} +%\item \textbf{EXP2:}{Excite Port2 during sweep} \item \textbf{PSEN:}{Port switch enable} \end{itemize} @@ -407,6 +408,27 @@ $$ PhaseInc = \frac{4096 * f_{IF2}}{SR_{ADC}} $$ For the the default IF frequency of $f_{IF2} = \SI{250}{\kilo\hertz}$ this evaluates to 10*Presc (see ADC prescaler register). \end{itemize} +\subsection{Sweep setup: 0x06} +Each point in the sweep is done in stages. Each stage consists of (optionally) routing the source signal to one of the ports and sampling of all ADCs. A "new data" interrupt is triggered after each stage. +\label{reg:sweepsetup} +\begin{center} +\begin{tikzpicture} +\bitrect{16}{16-\bit} +\rwbits{0}{3}{Stages} +\rwbits{3}{1}{IH} +\robits{4}{6}{reserved} +\rwbits{10}{3}{Port 1 stage} +\rwbits{13}{3}{Port 2 stage} +\end{tikzpicture} +\end{center} +\begin{itemize} +\item \textbf{Stages} Number of stages per point - 1. Normally the number of stages is equal to the number of ports but it can also be less (e.g. if only S11 is measured). +\item \textbf{IH:} Individual halt: Sets the behavior of the "halt sweep" bit (see section~\ref{sweepconfig}). If 1, the sampling is halted before each stage. If 0, the sampling is only halted before the point and all stages are executed without additional halts inbetween. +\item \textbf{Port 1 stage} Number of stage during which the source signal is routed to port 1. Must not have the same value as Port 2 stage. +\item \textbf{Port 2 stage} Number of stage during which the source signal is routed to port 2. Must not have the same value as Port 1 stage. + +\end{itemize} + \subsection{MAX2871 Default Values Registers: 0x08-0x0F} See datasheet of MAX2871 for bit descriptions. Bits for the fields N, FRAC, M, VCO and DIV\_A are "don't care" as they will be overwritten by the SweepConfig setting. \begin{center} @@ -574,12 +596,11 @@ Setting & Selected Power\\ \section{Sampling Result} \label{result} -Each point in the sweep generates two sampling results. The first one contains the measurement when the source was routed to Port 1, the second sampling result was taken when the source was routed to Port 2. +Each point in the sweep generates a sampling results for each stage (see section~\ref{reg:sweepsetup}). \begin{center} \begin{tikzpicture} \bitrect{16}{304-\bit} -\rwbits{0}{1}{SRC} -\robits{1}{2}{reserved} +\rwbits{0}{3}{STAGE[2:0]} \rwbits{3}{13}{POINT\_NUMBER[12:0]} \end{tikzpicture} \begin{tikzpicture} diff --git a/FPGA/VNA/SPIConfig.vhd b/FPGA/VNA/SPIConfig.vhd index 62307c6..8503c4b 100644 --- a/FPGA/VNA/SPIConfig.vhd +++ b/FPGA/VNA/SPIConfig.vhd @@ -50,8 +50,10 @@ entity SPICommands is SWEEP_WRITE : out STD_LOGIC_VECTOR (0 downto 0); SWEEP_POINTS : out STD_LOGIC_VECTOR (12 downto 0); NSAMPLES : out STD_LOGIC_VECTOR (12 downto 0); - EXCITE_PORT1 : out STD_LOGIC; - EXCITE_PORT2 : out STD_LOGIC; + STAGES : out STD_LOGIC_VECTOR (2 downto 0); + INDIVIDUAL_HALT : out STD_LOGIC; + PORT1_STAGE : out STD_LOGIC_VECTOR (2 downto 0); + PORT2_STAGE : out STD_LOGIC_VECTOR (2 downto 0); PORT1_EN : out STD_LOGIC; PORT2_EN : out STD_LOGIC; REF_EN : out STD_LOGIC; @@ -154,8 +156,6 @@ begin SOURCE_CE_EN <= '0'; LO_CE_EN <= '0'; PORTSWITCH_EN <= '0'; - EXCITE_PORT1 <= '0'; - EXCITE_PORT2 <= '0'; LEDS <= (others => '1'); WINDOW_SETTING <= "00"; unread_sampling_data <= '0'; @@ -243,10 +243,12 @@ begin WINDOW_SETTING <= spi_buf_out(6 downto 5); SOURCE_CE_EN <= spi_buf_out(4); LO_CE_EN <= spi_buf_out(3); - EXCITE_PORT1 <= spi_buf_out(1); - EXCITE_PORT2 <= spi_buf_out(2); when 4 => ADC_PRESCALER <= spi_buf_out(7 downto 0); when 5 => ADC_PHASEINC <= spi_buf_out(11 downto 0); + when 6 => STAGES <= spi_buf_out(15 downto 13); + INDIVIDUAL_HALT <= spi_buf_out(12); + PORT1_STAGE <= spi_buf_out(5 downto 3); + PORT2_STAGE <= spi_buf_out(2 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/Sweep.vhd b/FPGA/VNA/Sweep.vhd index 223b911..f2ff7d0 100644 --- a/FPGA/VNA/Sweep.vhd +++ b/FPGA/VNA/Sweep.vhd @@ -40,7 +40,6 @@ entity Sweep is SAMPLING_BUSY : in STD_LOGIC; SAMPLING_DONE : in STD_LOGIC; START_SAMPLING : out STD_LOGIC; - PORT_SELECT : out STD_LOGIC; BAND_SELECT : out STD_LOGIC; -- fixed part of source/LO registers MAX2871_DEF_4 : in STD_LOGIC_VECTOR (31 downto 0); @@ -67,8 +66,13 @@ entity Sweep is --SETTLING_TIME : in STD_LOGIC_VECTOR (15 downto 0); - EXCITE_PORT1 : in STD_LOGIC; - EXCITE_PORT2 : in STD_LOGIC; + STAGES : in STD_LOGIC_VECTOR (2 downto 0); + INDIVIDUAL_HALT : in STD_LOGIC; + PORT1_STAGE : in STD_LOGIC_VECTOR (2 downto 0); + PORT2_STAGE : in STD_LOGIC_VECTOR (2 downto 0); + + PORT1_ACTIVE : out STD_LOGIC; + PORT2_ACTIVE : out STD_LOGIC; -- Debug signals DEBUG_STATUS : out STD_LOGIC_VECTOR (10 downto 0); @@ -78,10 +82,11 @@ end Sweep; architecture Behavioral of Sweep is signal point_cnt : unsigned(12 downto 0); - type Point_states is (TriggerSetup, SettingUp, SettlingPort1, ExcitingPort1, SettlingPort2, ExcitingPort2, NextPoint, Done); + type Point_states is (TriggerSetup, SettingUp, Settling, Exciting, NextPoint, Done); signal state : Point_states; signal settling_cnt : unsigned(15 downto 0); signal settling_time : unsigned(15 downto 0); + signal stage_cnt : unsigned (2 downto 0); signal config_reg : std_logic_vector(95 downto 0); begin @@ -121,10 +126,8 @@ begin DEBUG_STATUS(10 downto 8) <= "000" when state = TriggerSetup else "001" when state = SettingUp else - "010" when state = SettlingPort1 else - "011" when state = ExcitingPort1 else - "100" when state = SettlingPort2 else - "101" when state = ExcitingPort2 else + "010" when state = Settling else + "011" when state = Exciting else "110" when state = Done else "111"; DEBUG_STATUS(7) <= PLL_RELOAD_DONE; @@ -139,15 +142,19 @@ begin if rising_edge(CLK) then if RESET = '1' then point_cnt <= (others => '0'); + stage_cnt <= (others => '0'); state <= TriggerSetup; START_SAMPLING <= '0'; RELOAD_PLL_REGS <= '0'; SWEEP_HALTED <= '0'; RESULT_INDEX <= (others => '1'); + PORT1_ACTIVE <= '0'; + PORT2_ACTIVE <= '0'; else case state is when TriggerSetup => RELOAD_PLL_REGS <= '1'; + stage_cnt <= (others => '0'); if PLL_RELOAD_DONE = '0' then state <= SettingUp; end if; @@ -166,60 +173,52 @@ begin -- check if halted sweep is resumed if config_reg(95) = '0' or SWEEP_RESUME = '1' then SWEEP_HALTED <= '0'; - if EXCITE_PORT1 = '1' then - state <= SettlingPort1; - else - state <= SettlingPort2; - end if; + state <= Settling; end if; end if; - when SettlingPort1 => - PORT_SELECT <= '1'; + when Settling => + if std_logic_vector(stage_cnt) = PORT1_STAGE then + PORT1_ACTIVE <= '1'; + else + PORT1_ACTIVE <= '0'; + end if; + if std_logic_vector(stage_cnt) = PORT2_STAGE then + PORT2_ACTIVE <= '1'; + else + PORT2_ACTIVE <= '0'; + end if; -- wait for settling time to elapse if settling_cnt > 0 then settling_cnt <= settling_cnt - 1; else START_SAMPLING <= '1'; if SAMPLING_BUSY = '1' then - state <= ExcitingPort1; + state <= Exciting; end if; end if; - when ExcitingPort1 => + when Exciting => -- wait for sampling to finish START_SAMPLING <= '0'; if SAMPLING_BUSY = '0' then - RESULT_INDEX <= "000" & std_logic_vector(point_cnt); - if EXCITE_PORT2 = '1' then - state <= SettlingPort2; + RESULT_INDEX <= std_logic_vector(stage_cnt) & std_logic_vector(point_cnt); + if stage_cnt < unsigned(STAGES) then + stage_cnt <= stage_cnt + 1; + if INDIVIDUAL_HALT = '1' then + -- wait for HALT SWEEP bit again if set + state <= SettingUp; + else + -- no need to halt again, can go directly to settling + state <= Settling; + end if; else state <= NextPoint; end if; settling_cnt <= settling_time; end if; - when SettlingPort2 => - PORT_SELECT <= '0'; - -- wait for settling time to elapse - if settling_cnt > 0 then - settling_cnt <= settling_cnt - 1; - else - START_SAMPLING <= '1'; - if SAMPLING_BUSY = '1' then - state <= ExcitingPort2; - end if; - end if; - when ExcitingPort2 => - -- wait for sampling to finish - START_SAMPLING <= '0'; - RESULT_INDEX <= "100" & std_logic_vector(point_cnt); - if SAMPLING_BUSY = '0' then - state <= NextPoint; - end if; when NextPoint => if point_cnt < unsigned(NPOINTS) then point_cnt <= point_cnt + 1; state <= TriggerSetup; - -- initial port depends on whether port 1 is exited - PORT_SELECT <= EXCITE_PORT1; else point_cnt <= (others => '0'); state <= Done; diff --git a/FPGA/VNA/VNA.gise b/FPGA/VNA/VNA.gise index 238cc3f..67a2b99 100644 --- a/FPGA/VNA/VNA.gise +++ b/FPGA/VNA/VNA.gise @@ -224,7 +224,7 @@ - + @@ -253,7 +253,7 @@ - + @@ -275,7 +275,7 @@ - + @@ -284,7 +284,7 @@ - + @@ -298,7 +298,7 @@ - + @@ -312,9 +312,8 @@ - + - @@ -366,7 +365,7 @@ - + diff --git a/FPGA/VNA/VNA.xise b/FPGA/VNA/VNA.xise index 7f1807b..23fe1cf 100644 --- a/FPGA/VNA/VNA.xise +++ b/FPGA/VNA/VNA.xise @@ -12,7 +12,7 @@ - + diff --git a/FPGA/VNA/ipcore_dir/DSP_SLICE.xise b/FPGA/VNA/ipcore_dir/DSP_SLICE.xise index b4222ea..92644f3 100644 --- a/FPGA/VNA/ipcore_dir/DSP_SLICE.xise +++ b/FPGA/VNA/ipcore_dir/DSP_SLICE.xise @@ -12,7 +12,7 @@ - + diff --git a/FPGA/VNA/ipcore_dir/PLL.xise b/FPGA/VNA/ipcore_dir/PLL.xise index ceaa4a6..b0b1f74 100644 --- a/FPGA/VNA/ipcore_dir/PLL.xise +++ b/FPGA/VNA/ipcore_dir/PLL.xise @@ -12,7 +12,7 @@ - + diff --git a/FPGA/VNA/ipcore_dir/SinCos.xise b/FPGA/VNA/ipcore_dir/SinCos.xise index 423665e..48631e5 100644 --- a/FPGA/VNA/ipcore_dir/SinCos.xise +++ b/FPGA/VNA/ipcore_dir/SinCos.xise @@ -12,7 +12,7 @@ - + diff --git a/FPGA/VNA/ipcore_dir/SweepConfigMem.xise b/FPGA/VNA/ipcore_dir/SweepConfigMem.xise index e1d6091..eb7b0f0 100644 --- a/FPGA/VNA/ipcore_dir/SweepConfigMem.xise +++ b/FPGA/VNA/ipcore_dir/SweepConfigMem.xise @@ -12,7 +12,7 @@ - + diff --git a/FPGA/VNA/ipcore_dir/result_bram.xise b/FPGA/VNA/ipcore_dir/result_bram.xise index dc81dae..caffa95 100644 --- a/FPGA/VNA/ipcore_dir/result_bram.xise +++ b/FPGA/VNA/ipcore_dir/result_bram.xise @@ -12,7 +12,7 @@ - + diff --git a/FPGA/VNA/top.bin b/FPGA/VNA/top.bin index 313f393..1ed3339 100644 Binary files a/FPGA/VNA/top.bin and b/FPGA/VNA/top.bin differ diff --git a/FPGA/VNA/top.vhd b/FPGA/VNA/top.vhd index ebd5e22..3879038 100644 --- a/FPGA/VNA/top.vhd +++ b/FPGA/VNA/top.vhd @@ -124,7 +124,6 @@ architecture Behavioral of top is PLL_LOCKED : IN std_logic; CONFIG_ADDRESS : OUT std_logic_vector(12 downto 0); START_SAMPLING : OUT std_logic; - PORT_SELECT : OUT std_logic; BAND_SELECT : out STD_LOGIC; SOURCE_REG_4 : OUT std_logic_vector(31 downto 0); SOURCE_REG_3 : OUT std_logic_vector(31 downto 0); @@ -139,8 +138,13 @@ architecture Behavioral of top is SWEEP_RESUME : in STD_LOGIC; ATTENUATOR : OUT std_logic_vector(6 downto 0); SOURCE_FILTER : OUT std_logic_vector(1 downto 0); - EXCITE_PORT1 : in STD_LOGIC; - EXCITE_PORT2 : in STD_LOGIC; + STAGES : in STD_LOGIC_VECTOR (2 downto 0); + INDIVIDUAL_HALT : in STD_LOGIC; + PORT1_STAGE : in STD_LOGIC_VECTOR (2 downto 0); + PORT2_STAGE : in STD_LOGIC_VECTOR (2 downto 0); + + PORT1_ACTIVE : out STD_LOGIC; + PORT2_ACTIVE : out STD_LOGIC; RESULT_INDEX : out STD_LOGIC_VECTOR (15 downto 0); DEBUG_STATUS : out STD_LOGIC_VECTOR (10 downto 0) ); @@ -243,8 +247,10 @@ architecture Behavioral of top is SWEEP_WRITE : OUT std_logic_vector(0 to 0); SWEEP_POINTS : OUT std_logic_vector(12 downto 0); NSAMPLES : OUT std_logic_vector(12 downto 0); - EXCITE_PORT1 : out STD_LOGIC; - EXCITE_PORT2 : out STD_LOGIC; + STAGES : out STD_LOGIC_VECTOR (2 downto 0); + INDIVIDUAL_HALT : out STD_LOGIC; + PORT1_STAGE : out STD_LOGIC_VECTOR (2 downto 0); + PORT2_STAGE : out STD_LOGIC_VECTOR (2 downto 0); PORT1_EN : out STD_LOGIC; PORT2_EN : out STD_LOGIC; REF_EN : out STD_LOGIC; @@ -360,10 +366,14 @@ architecture Behavioral of top is -- Sweep signals signal sweep_points : std_logic_vector(12 downto 0); + signal sweep_stages : STD_LOGIC_VECTOR (2 downto 0); + signal sweep_individual_halt : STD_LOGIC; + signal sweep_port1_stage : STD_LOGIC_VECTOR (2 downto 0); + signal sweep_port2_stage : STD_LOGIC_VECTOR (2 downto 0); signal sweep_config_data : std_logic_vector(95 downto 0); signal sweep_config_address : std_logic_vector(12 downto 0); signal source_filter : std_logic_vector(1 downto 0); - signal sweep_port_select : std_logic; + signal sweep_band : std_logic; signal sweep_config_write_address : std_logic_vector(12 downto 0); signal sweep_config_write_data : std_logic_vector(95 downto 0); @@ -376,8 +386,6 @@ architecture Behavioral of top is signal sweep_excite_port1 : std_logic; signal sweep_excite_port2 : std_logic; - signal sweep_band : std_logic; - -- Configuration signals signal settling_time : std_logic_vector(15 downto 0); signal def_reg_4 : std_logic_vector(31 downto 0); @@ -428,10 +436,10 @@ begin LEDS(2) <= SOURCE_LD; LEDS(3) <= LO1_LD; -- Sweep and active port - 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; + PORT_SELECT2 <= sweep_excite_port2 and portswitch_en; + PORT2_SELECT <= sweep_excite_port2 and portswitch_en; + PORT_SELECT1 <= sweep_excite_port1 and portswitch_en; + PORT1_SELECT <= sweep_excite_port1 and portswitch_en; BAND_SELECT_HIGH <= not sweep_band; BAND_SELECT_LOW <= sweep_band; PORT1_MIX2_EN <= port1mix_en; @@ -440,8 +448,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 and portswitch_en); - LEDS(5) <= not (not sweep_reset and sweep_port_select and portswitch_en); + LEDS(4) <= not (not sweep_reset and sweep_excite_port2 and portswitch_en); + LEDS(5) <= not (not sweep_reset and sweep_excite_port1 and portswitch_en); -- Uncommitted LEDs LEDS(7 downto 6) <= user_leds(1 downto 0); --LEDS(7) <= '0'; @@ -649,7 +657,6 @@ begin SAMPLING_BUSY => sampling_busy, SAMPLING_DONE => sampling_done, START_SAMPLING => sampling_start, - PORT_SELECT => sweep_port_select, BAND_SELECT => sweep_band, MAX2871_DEF_4 => def_reg_4, MAX2871_DEF_3 => def_reg_3, @@ -670,8 +677,13 @@ begin SWEEP_RESUME => sweep_resume, ATTENUATOR => ATTENUATION, SOURCE_FILTER => source_filter, - EXCITE_PORT1 => sweep_excite_port1, - EXCITE_PORT2 => sweep_excite_port2, + STAGES => sweep_stages, + INDIVIDUAL_HALT => sweep_individual_halt, + PORT1_STAGE => sweep_port1_stage, + PORT2_STAGE => sweep_port2_stage, + + PORT1_ACTIVE => sweep_excite_port1, + PORT2_ACTIVE => sweep_excite_port2, DEBUG_STATUS => debug, RESULT_INDEX => sampling_result(303 downto 288) ); @@ -740,8 +752,10 @@ begin RESET_MINMAX => adc_reset_minmax, SWEEP_HALTED => sweep_halted, SWEEP_RESUME => sweep_resume, - EXCITE_PORT1 => sweep_excite_port1, - EXCITE_PORT2 => sweep_excite_port2, + STAGES => sweep_stages, + INDIVIDUAL_HALT => sweep_individual_halt, + PORT1_STAGE => sweep_port1_stage, + PORT2_STAGE => sweep_port2_stage, DFT_BIN1_PHASEINC => dft_bin1_phaseinc, DFT_DIFFBIN_PHASEINC => dft_diffbin_phaseinc, DFT_RESULT_READY => dft_ready, diff --git a/Software/VNA_embedded/.settings/language.settings.xml b/Software/VNA_embedded/.settings/language.settings.xml index 0c8cdbb..87b5f55 100644 --- a/Software/VNA_embedded/.settings/language.settings.xml +++ b/Software/VNA_embedded/.settings/language.settings.xml @@ -6,7 +6,7 @@ - + @@ -18,7 +18,7 @@ - + diff --git a/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.cpp b/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.cpp index bbafe92..7f47c4e 100644 --- a/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.cpp +++ b/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.cpp @@ -130,6 +130,17 @@ void FPGA::SetSamplesPerPoint(uint32_t nsamples) { WriteRegister(Reg::SamplesPerPoint, nsamples); } +void FPGA::SetupSweep(uint8_t stages, uint8_t port1_stage, uint8_t port2_stage, bool individual_halt) { + uint16_t value = 0x0000; + value |= (uint16_t) (stages & 0x07) << 13; + if(individual_halt) { + value |= 0x1000; + } + value |= (port1_stage & 0x07) << 3; + value |= (port2_stage & 0x07) << 0; + WriteRegister(Reg::SweepSetup, value); +} + void FPGA::Enable(Periphery p, bool enable) { if (enable) { SysCtrlReg |= (uint16_t) p; @@ -282,7 +293,7 @@ void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) { result.RefI = assembleSampleResultValue(&raw[8]); result.RefQ = assembleSampleResultValue(&raw[2]); result.pointNum = (uint16_t)(raw[38]&0x1F) << 8 | raw[39]; - result.activePort = raw[38] & 0x80 ? 1 : 0; + result.stageNum = (raw[38] & 0xE0) >> 5; High(CS); busy_reading = false; if ((status & 0x0004) && callback) { diff --git a/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.hpp b/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.hpp index 6540fd6..98cd586 100644 --- a/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.hpp +++ b/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.hpp @@ -17,6 +17,7 @@ enum class Reg { SystemControl = 0x03, ADCPrescaler = 0x04, PhaseIncrement = 0x05, + SweepSetup = 0x06, MAX2871Def0LSB = 0x08, MAX2871Def0MSB = 0x09, MAX2871Def1LSB = 0x0A, @@ -33,8 +34,8 @@ using SamplingResult = struct _samplingresult { int64_t P1I, P1Q; int64_t P2I, P2Q; int64_t RefI, RefQ; - uint16_t pointNum :15; - uint16_t activePort :1; + uint16_t pointNum :13; + uint16_t stageNum :3; }; using DFTResult = struct _dftresult { @@ -59,8 +60,7 @@ enum class Periphery { DebugLED = 0x0080, SourceChip = 0x0010, LO1Chip = 0x0008, - ExcitePort2 = 0x0004, - ExcitePort1 = 0x0002, + PortSwitch = 0x0001, }; @@ -113,6 +113,7 @@ bool Init(HaltedCallback cb = nullptr); void WriteRegister(FPGA::Reg reg, uint16_t value); void SetNumberOfPoints(uint16_t npoints); void SetSamplesPerPoint(uint32_t nsamples); +void SetupSweep(uint8_t stages, uint8_t port1_stage, uint8_t port2_stage, bool individual_halt = false); void Enable(Periphery p, bool enable = true); void Disable(Periphery p); bool IsEnabled(Periphery p); diff --git a/Software/VNA_embedded/Application/Manual.cpp b/Software/VNA_embedded/Application/Manual.cpp index 9229457..e48f334 100644 --- a/Software/VNA_embedded/Application/Manual.cpp +++ b/Software/VNA_embedded/Application/Manual.cpp @@ -69,8 +69,7 @@ void Manual::Setup(Protocol::ManualControl m) { FPGA::Enable(FPGA::Periphery::Port1Mixer, m.Port1EN); FPGA::Enable(FPGA::Periphery::Port2Mixer, m.Port2EN); FPGA::Enable(FPGA::Periphery::RefMixer, m.RefEN); - FPGA::Enable(FPGA::Periphery::ExcitePort1, m.PortSwitch == 0); - FPGA::Enable(FPGA::Periphery::ExcitePort2, m.PortSwitch == 1); + FPGA::SetupSweep(0, m.PortSwitch == 1, m.PortSwitch == 0); FPGA::Enable(FPGA::Periphery::PortSwitch); // Enable new data and sweep halt interrupt diff --git a/Software/VNA_embedded/Application/SpectrumAnalyzer.cpp b/Software/VNA_embedded/Application/SpectrumAnalyzer.cpp index e9c60b6..c5cc48d 100644 --- a/Software/VNA_embedded/Application/SpectrumAnalyzer.cpp +++ b/Software/VNA_embedded/Application/SpectrumAnalyzer.cpp @@ -209,8 +209,7 @@ void SA::Setup(Protocol::SpectrumAnalyzerSettings settings) { FPGA::SetWindow((FPGA::Window) s.WindowType); FPGA::Enable(FPGA::Periphery::LO1Chip); FPGA::Enable(FPGA::Periphery::LO1RF); - FPGA::Enable(FPGA::Periphery::ExcitePort1, s.trackingGeneratorPort == 0); - FPGA::Enable(FPGA::Periphery::ExcitePort2, s.trackingGeneratorPort == 1); + FPGA::SetupSweep(0, s.trackingGeneratorPort == 1, s.trackingGeneratorPort == 0); FPGA::Enable(FPGA::Periphery::PortSwitch, s.trackingGenerator); FPGA::Enable(FPGA::Periphery::Amplifier, s.trackingGenerator); FPGA::Enable(FPGA::Periphery::Port1Mixer); diff --git a/Software/VNA_embedded/Application/VNA.cpp b/Software/VNA_embedded/Application/VNA.cpp index 3e9b9de..8a856dc 100644 --- a/Software/VNA_embedded/Application/VNA.cpp +++ b/Software/VNA_embedded/Application/VNA.cpp @@ -21,8 +21,9 @@ static Protocol::SweepSettings settings; static uint16_t pointCnt; +static uint8_t stageCnt; +static uint8_t stages; static double logMultiplier, logFrequency; -static bool excitingPort1; static Protocol::Datapoint data; static bool active = false; static Si5351C::DriveStrength fixedPowerLowband; @@ -278,12 +279,22 @@ bool VNA::Setup(Protocol::SweepSettings s) { FPGA::Enable(FPGA::Periphery::SourceRF); FPGA::Enable(FPGA::Periphery::LO1Chip); FPGA::Enable(FPGA::Periphery::LO1RF); - FPGA::Enable(FPGA::Periphery::ExcitePort1, s.excitePort1); - FPGA::Enable(FPGA::Periphery::ExcitePort2, s.excitePort2); + if(s.excitePort1 && s.excitePort2) { + // two stages, port 1 first, followed by port 2 + FPGA::SetupSweep(1, 0, 1); + stages = 2; + } else if(s.excitePort1) { + // one stage, port 1 only + FPGA::SetupSweep(0, 0, 1); + stages = 1; + } else { + // one stage, port 2 only + FPGA::SetupSweep(0, 1, 0); + stages = 1; + } FPGA::Enable(FPGA::Periphery::PortSwitch); pointCnt = 0; - // starting port depends on whether port 1 is active in sweep - excitingPort1 = s.excitePort1; + stageCnt = 0; IFTableIndexCnt = 0; adcShifted = false; active = true; @@ -306,8 +317,8 @@ bool VNA::MeasurementDone(const FPGA::SamplingResult &result) { if(!active) { return false; } - if(result.pointNum != pointCnt || !result.activePort != excitingPort1) { - LOG_WARN("Indicated point does not match (%u != %u, %d != %d)", result.pointNum, pointCnt, result.activePort, !excitingPort1); + if(result.pointNum != pointCnt || result.stageNum != stageCnt) { + LOG_WARN("Indicated point does not match (%u != %u, %d != %d)", result.pointNum, pointCnt, result.stageNum, stageCnt); FPGA::AbortSweep(); return false; } @@ -320,29 +331,24 @@ bool VNA::MeasurementDone(const FPGA::SamplingResult &result) { data.pointNum = pointCnt; data.frequency = getPointFrequency(pointCnt); data.cdbm = settings.cdbm_excitation_start + (settings.cdbm_excitation_stop - settings.cdbm_excitation_start) * pointCnt / (settings.points - 1); - if(excitingPort1) { + if(stageCnt == 0 && settings.excitePort1) { + // stimulus is present at port 1 data.real_S11 = port1.real(); data.imag_S11 = port1.imag(); data.real_S21 = port2.real(); data.imag_S21 = port2.imag(); } else { + // stimulus is present at port 2 data.real_S12 = port1.real(); data.imag_S12 = port1.imag(); data.real_S22 = port2.real(); data.imag_S22 = port2.imag(); } - // figure out whether this sweep point is complete and which port gets excited next - bool pointComplete = false; - if(settings.excitePort1 == 1 && settings.excitePort2 == 1) { - // point is complete when port 2 was active - pointComplete = !excitingPort1; - // next measurement will be from other port - excitingPort1 = !excitingPort1; - } else { - // only one port active, point is complete after every measurement - pointComplete = true; - } - if(pointComplete) { + // figure out whether this sweep point is complete + stageCnt++; + if(stageCnt == stages) { + // point is complete + stageCnt = 0; STM::DispatchToInterrupt(PassOnData); pointCnt++; if (pointCnt >= settings.points) {