Added stages to FPGA protocol

This commit is contained in:
Jan Käberich 2022-04-01 23:01:22 +02:00
parent 4307a392fb
commit 37d8474260
19 changed files with 169 additions and 118 deletions

View File

@ -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}

View File

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

View File

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

View File

@ -224,7 +224,7 @@
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1625850461" xil_pn:in_ck="-4366097307991745463" xil_pn:name="TRAN_regenerateCores" xil_pn:prop_ck="-2723611991789822717" xil_pn:start_ts="1625850460">
<transform xil_pn:end_ts="1648844622" xil_pn:in_ck="-4366097307991745463" xil_pn:name="TRAN_regenerateCores" xil_pn:prop_ck="-2723611991789822717" xil_pn:start_ts="1648844621">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
<outfile xil_pn:name="ipcore_dir/DSP_SLICE.ngc"/>
@ -253,7 +253,7 @@
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1625861989" xil_pn:in_ck="2241500006820465658" xil_pn:name="TRANEXT_xstsynthesize_spartan6" xil_pn:prop_ck="3256065936432453276" xil_pn:start_ts="1625861965">
<transform xil_pn:end_ts="1648846416" xil_pn:in_ck="2241500006820465658" xil_pn:name="TRANEXT_xstsynthesize_spartan6" xil_pn:prop_ck="3256065936432453276" xil_pn:start_ts="1648846407">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="WarningsGenerated"/>
<status xil_pn:value="ReadyToRun"/>
@ -275,7 +275,7 @@
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1625861996" xil_pn:in_ck="5411862124762956458" xil_pn:name="TRANEXT_ngdbuild_FPGA" xil_pn:prop_ck="4604875190571501774" xil_pn:start_ts="1625861989">
<transform xil_pn:end_ts="1648846420" xil_pn:in_ck="5411862124762956458" xil_pn:name="TRANEXT_ngdbuild_FPGA" xil_pn:prop_ck="4604875190571501774" xil_pn:start_ts="1648846416">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
<outfile xil_pn:name="_ngo"/>
@ -284,7 +284,7 @@
<outfile xil_pn:name="top.ngd"/>
<outfile xil_pn:name="top_ngdbuild.xrpt"/>
</transform>
<transform xil_pn:end_ts="1625862085" xil_pn:in_ck="8512332261572065657" xil_pn:name="TRANEXT_map_spartan6" xil_pn:prop_ck="-4668962392366239264" xil_pn:start_ts="1625861996">
<transform xil_pn:end_ts="1648846449" xil_pn:in_ck="8512332261572065657" xil_pn:name="TRANEXT_map_spartan6" xil_pn:prop_ck="-4668962392366239264" xil_pn:start_ts="1648846420">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="WarningsGenerated"/>
<status xil_pn:value="ReadyToRun"/>
@ -298,7 +298,7 @@
<outfile xil_pn:name="top_summary.xml"/>
<outfile xil_pn:name="top_usage.xml"/>
</transform>
<transform xil_pn:end_ts="1625862116" xil_pn:in_ck="1117507038335044978" xil_pn:name="TRANEXT_par_spartan6" xil_pn:prop_ck="-1085068593928086116" xil_pn:start_ts="1625862085">
<transform xil_pn:end_ts="1648846462" xil_pn:in_ck="1117507038335044978" xil_pn:name="TRANEXT_par_spartan6" xil_pn:prop_ck="-1085068593928086116" xil_pn:start_ts="1648846449">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
<outfile xil_pn:name="_xmsgs/par.xmsgs"/>
@ -312,9 +312,8 @@
<outfile xil_pn:name="top_pad.txt"/>
<outfile xil_pn:name="top_par.xrpt"/>
</transform>
<transform xil_pn:end_ts="1625862132" xil_pn:in_ck="154288912438" xil_pn:name="TRANEXT_bitFile_spartan6" xil_pn:prop_ck="3274353840855015246" xil_pn:start_ts="1625862116">
<transform xil_pn:end_ts="1648846469" xil_pn:in_ck="154288912438" xil_pn:name="TRANEXT_bitFile_spartan6" xil_pn:prop_ck="3274353840855015246" xil_pn:start_ts="1648846462">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="WarningsGenerated"/>
<status xil_pn:value="ReadyToRun"/>
<outfile xil_pn:name="_xmsgs/bitgen.xmsgs"/>
<outfile xil_pn:name="top.bgn"/>
@ -366,7 +365,7 @@
<status xil_pn:value="InputChanged"/>
<status xil_pn:value="InputRemoved"/>
</transform>
<transform xil_pn:end_ts="1625862116" xil_pn:in_ck="8512326635937592693" xil_pn:name="TRAN_postRouteTrce" xil_pn:prop_ck="445577401284416184" xil_pn:start_ts="1625862109">
<transform xil_pn:end_ts="1648846462" xil_pn:in_ck="8512326635937592693" xil_pn:name="TRAN_postRouteTrce" xil_pn:prop_ck="445577401284416184" xil_pn:start_ts="1648846459">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
<outfile xil_pn:name="_xmsgs/trce.xmsgs"/>

View File

@ -12,7 +12,7 @@
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
</header>
<version xil_pn:ise_version="14.6" xil_pn:schema_version="2"/>
<version xil_pn:ise_version="14.7" xil_pn:schema_version="2"/>
<files>
<file xil_pn:name="top.vhd" xil_pn:type="FILE_VHDL">

View File

@ -12,7 +12,7 @@
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
</header>
<version xil_pn:ise_version="14.6" xil_pn:schema_version="2"/>
<version xil_pn:ise_version="14.7" xil_pn:schema_version="2"/>
<files>
<file xil_pn:name="DSP_SLICE.ngc" xil_pn:type="FILE_NGC">

View File

@ -12,7 +12,7 @@
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
</header>
<version xil_pn:ise_version="14.6" xil_pn:schema_version="2"/>
<version xil_pn:ise_version="14.7" xil_pn:schema_version="2"/>
<files>
<file xil_pn:name="PLL.ucf" xil_pn:type="FILE_UCF">

View File

@ -12,7 +12,7 @@
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
</header>
<version xil_pn:ise_version="14.6" xil_pn:schema_version="2"/>
<version xil_pn:ise_version="14.7" xil_pn:schema_version="2"/>
<files>
<file xil_pn:name="SinCos.ngc" xil_pn:type="FILE_NGC">

View File

@ -12,7 +12,7 @@
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
</header>
<version xil_pn:ise_version="14.6" xil_pn:schema_version="2"/>
<version xil_pn:ise_version="14.7" xil_pn:schema_version="2"/>
<files>
<file xil_pn:name="SweepConfigMem.ngc" xil_pn:type="FILE_NGC">

View File

@ -12,7 +12,7 @@
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
</header>
<version xil_pn:ise_version="14.6" xil_pn:schema_version="2"/>
<version xil_pn:ise_version="14.7" xil_pn:schema_version="2"/>
<files>
<file xil_pn:name="result_bram.ngc" xil_pn:type="FILE_NGC">

Binary file not shown.

View File

@ -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,

View File

@ -6,7 +6,7 @@
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
<provider copy-of="extension" id="org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser"/>
<provider class="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" console="false" env-hash="-1671998965483228530" id="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" keep-relative-paths="false" name="MCU ARM GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<provider class="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" console="false" env-hash="1949595105660943601" id="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" keep-relative-paths="false" name="MCU ARM GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
@ -18,7 +18,7 @@
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
<provider copy-of="extension" id="org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser"/>
<provider class="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" console="false" env-hash="-1671998965483228530" id="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" keep-relative-paths="false" name="MCU ARM GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<provider class="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" console="false" env-hash="1949595105660943601" id="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" keep-relative-paths="false" name="MCU ARM GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>

View File

@ -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) {

View File

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

View File

@ -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

View File

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

View File

@ -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) {