Merge branch 'master' of github.com:jankae/LibreVNA
This commit is contained in:
commit
4243e64f7f
Binary file not shown.
@ -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{9}{2}{Window[1:0]}
|
||||||
\rwbits{11}{1}{SCEN}
|
\rwbits{11}{1}{SCEN}
|
||||||
\rwbits{12}{1}{LCEN}
|
\rwbits{12}{1}{LCEN}
|
||||||
\rwbits{13}{1}{EXP2}
|
\robits{13}{3}{reserved}
|
||||||
\rwbits{14}{1}{EXP1}
|
%\rwbits{13}{1}{EXP2}
|
||||||
\rwbits{15}{1}{PSEN}
|
%\rwbits{14}{1}{EXP1}
|
||||||
|
%\rwbits{15}{1}{PSEN}
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
@ -371,8 +372,8 @@ Setting & Window type\\
|
|||||||
\end{center}
|
\end{center}
|
||||||
\item \textbf{SCEN:}{Source chip enable}
|
\item \textbf{SCEN:}{Source chip enable}
|
||||||
\item \textbf{LCEN:}{LO chip enable}
|
\item \textbf{LCEN:}{LO chip enable}
|
||||||
\item \textbf{EXP1:}{Excite Port1 during sweep}
|
%\item \textbf{EXP1:}{Excite Port1 during sweep}
|
||||||
\item \textbf{EXP2:}{Excite Port2 during sweep}
|
%\item \textbf{EXP2:}{Excite Port2 during sweep}
|
||||||
\item \textbf{PSEN:}{Port switch enable}
|
\item \textbf{PSEN:}{Port switch enable}
|
||||||
\end{itemize}
|
\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).
|
For the the default IF frequency of $f_{IF2} = \SI{250}{\kilo\hertz}$ this evaluates to 10*Presc (see ADC prescaler register).
|
||||||
\end{itemize}
|
\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}
|
\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.
|
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}
|
\begin{center}
|
||||||
@ -574,12 +596,11 @@ Setting & Selected Power\\
|
|||||||
|
|
||||||
\section{Sampling Result}
|
\section{Sampling Result}
|
||||||
\label{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{center}
|
||||||
\begin{tikzpicture}
|
\begin{tikzpicture}
|
||||||
\bitrect{16}{304-\bit}
|
\bitrect{16}{304-\bit}
|
||||||
\rwbits{0}{1}{SRC}
|
\rwbits{0}{3}{STAGE[2:0]}
|
||||||
\robits{1}{2}{reserved}
|
|
||||||
\rwbits{3}{13}{POINT\_NUMBER[12:0]}
|
\rwbits{3}{13}{POINT\_NUMBER[12:0]}
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\begin{tikzpicture}
|
\begin{tikzpicture}
|
||||||
|
@ -50,8 +50,10 @@ entity SPICommands is
|
|||||||
SWEEP_WRITE : out STD_LOGIC_VECTOR (0 downto 0);
|
SWEEP_WRITE : out STD_LOGIC_VECTOR (0 downto 0);
|
||||||
SWEEP_POINTS : out STD_LOGIC_VECTOR (12 downto 0);
|
SWEEP_POINTS : out STD_LOGIC_VECTOR (12 downto 0);
|
||||||
NSAMPLES : out STD_LOGIC_VECTOR (12 downto 0);
|
NSAMPLES : out STD_LOGIC_VECTOR (12 downto 0);
|
||||||
EXCITE_PORT1 : out STD_LOGIC;
|
STAGES : out STD_LOGIC_VECTOR (2 downto 0);
|
||||||
EXCITE_PORT2 : out STD_LOGIC;
|
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;
|
PORT1_EN : out STD_LOGIC;
|
||||||
PORT2_EN : out STD_LOGIC;
|
PORT2_EN : out STD_LOGIC;
|
||||||
REF_EN : out STD_LOGIC;
|
REF_EN : out STD_LOGIC;
|
||||||
@ -154,8 +156,6 @@ begin
|
|||||||
SOURCE_CE_EN <= '0';
|
SOURCE_CE_EN <= '0';
|
||||||
LO_CE_EN <= '0';
|
LO_CE_EN <= '0';
|
||||||
PORTSWITCH_EN <= '0';
|
PORTSWITCH_EN <= '0';
|
||||||
EXCITE_PORT1 <= '0';
|
|
||||||
EXCITE_PORT2 <= '0';
|
|
||||||
LEDS <= (others => '1');
|
LEDS <= (others => '1');
|
||||||
WINDOW_SETTING <= "00";
|
WINDOW_SETTING <= "00";
|
||||||
unread_sampling_data <= '0';
|
unread_sampling_data <= '0';
|
||||||
@ -243,10 +243,12 @@ begin
|
|||||||
WINDOW_SETTING <= spi_buf_out(6 downto 5);
|
WINDOW_SETTING <= spi_buf_out(6 downto 5);
|
||||||
SOURCE_CE_EN <= spi_buf_out(4);
|
SOURCE_CE_EN <= spi_buf_out(4);
|
||||||
LO_CE_EN <= spi_buf_out(3);
|
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 4 => ADC_PRESCALER <= spi_buf_out(7 downto 0);
|
||||||
when 5 => ADC_PHASEINC <= spi_buf_out(11 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 8 => MAX2871_DEF_0(15 downto 0) <= spi_buf_out;
|
||||||
when 9 => MAX2871_DEF_0(31 downto 16) <= 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;
|
when 10 => MAX2871_DEF_1(15 downto 0) <= spi_buf_out;
|
||||||
|
@ -40,7 +40,6 @@ entity Sweep is
|
|||||||
SAMPLING_BUSY : in STD_LOGIC;
|
SAMPLING_BUSY : in STD_LOGIC;
|
||||||
SAMPLING_DONE : in STD_LOGIC;
|
SAMPLING_DONE : in STD_LOGIC;
|
||||||
START_SAMPLING : out STD_LOGIC;
|
START_SAMPLING : out STD_LOGIC;
|
||||||
PORT_SELECT : out STD_LOGIC;
|
|
||||||
BAND_SELECT : out STD_LOGIC;
|
BAND_SELECT : out STD_LOGIC;
|
||||||
-- fixed part of source/LO registers
|
-- fixed part of source/LO registers
|
||||||
MAX2871_DEF_4 : in STD_LOGIC_VECTOR (31 downto 0);
|
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);
|
--SETTLING_TIME : in STD_LOGIC_VECTOR (15 downto 0);
|
||||||
|
|
||||||
EXCITE_PORT1 : in STD_LOGIC;
|
STAGES : in STD_LOGIC_VECTOR (2 downto 0);
|
||||||
EXCITE_PORT2 : in STD_LOGIC;
|
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 signals
|
||||||
DEBUG_STATUS : out STD_LOGIC_VECTOR (10 downto 0);
|
DEBUG_STATUS : out STD_LOGIC_VECTOR (10 downto 0);
|
||||||
@ -78,10 +82,11 @@ end Sweep;
|
|||||||
|
|
||||||
architecture Behavioral of Sweep is
|
architecture Behavioral of Sweep is
|
||||||
signal point_cnt : unsigned(12 downto 0);
|
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 state : Point_states;
|
||||||
signal settling_cnt : unsigned(15 downto 0);
|
signal settling_cnt : unsigned(15 downto 0);
|
||||||
signal settling_time : 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);
|
signal config_reg : std_logic_vector(95 downto 0);
|
||||||
begin
|
begin
|
||||||
|
|
||||||
@ -121,10 +126,8 @@ begin
|
|||||||
|
|
||||||
DEBUG_STATUS(10 downto 8) <= "000" when state = TriggerSetup else
|
DEBUG_STATUS(10 downto 8) <= "000" when state = TriggerSetup else
|
||||||
"001" when state = SettingUp else
|
"001" when state = SettingUp else
|
||||||
"010" when state = SettlingPort1 else
|
"010" when state = Settling else
|
||||||
"011" when state = ExcitingPort1 else
|
"011" when state = Exciting else
|
||||||
"100" when state = SettlingPort2 else
|
|
||||||
"101" when state = ExcitingPort2 else
|
|
||||||
"110" when state = Done else
|
"110" when state = Done else
|
||||||
"111";
|
"111";
|
||||||
DEBUG_STATUS(7) <= PLL_RELOAD_DONE;
|
DEBUG_STATUS(7) <= PLL_RELOAD_DONE;
|
||||||
@ -139,15 +142,19 @@ begin
|
|||||||
if rising_edge(CLK) then
|
if rising_edge(CLK) then
|
||||||
if RESET = '1' then
|
if RESET = '1' then
|
||||||
point_cnt <= (others => '0');
|
point_cnt <= (others => '0');
|
||||||
|
stage_cnt <= (others => '0');
|
||||||
state <= TriggerSetup;
|
state <= TriggerSetup;
|
||||||
START_SAMPLING <= '0';
|
START_SAMPLING <= '0';
|
||||||
RELOAD_PLL_REGS <= '0';
|
RELOAD_PLL_REGS <= '0';
|
||||||
SWEEP_HALTED <= '0';
|
SWEEP_HALTED <= '0';
|
||||||
RESULT_INDEX <= (others => '1');
|
RESULT_INDEX <= (others => '1');
|
||||||
|
PORT1_ACTIVE <= '0';
|
||||||
|
PORT2_ACTIVE <= '0';
|
||||||
else
|
else
|
||||||
case state is
|
case state is
|
||||||
when TriggerSetup =>
|
when TriggerSetup =>
|
||||||
RELOAD_PLL_REGS <= '1';
|
RELOAD_PLL_REGS <= '1';
|
||||||
|
stage_cnt <= (others => '0');
|
||||||
if PLL_RELOAD_DONE = '0' then
|
if PLL_RELOAD_DONE = '0' then
|
||||||
state <= SettingUp;
|
state <= SettingUp;
|
||||||
end if;
|
end if;
|
||||||
@ -166,60 +173,52 @@ begin
|
|||||||
-- check if halted sweep is resumed
|
-- check if halted sweep is resumed
|
||||||
if config_reg(95) = '0' or SWEEP_RESUME = '1' then
|
if config_reg(95) = '0' or SWEEP_RESUME = '1' then
|
||||||
SWEEP_HALTED <= '0';
|
SWEEP_HALTED <= '0';
|
||||||
if EXCITE_PORT1 = '1' then
|
state <= Settling;
|
||||||
state <= SettlingPort1;
|
|
||||||
else
|
|
||||||
state <= SettlingPort2;
|
|
||||||
end if;
|
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
when SettlingPort1 =>
|
when Settling =>
|
||||||
PORT_SELECT <= '1';
|
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
|
-- wait for settling time to elapse
|
||||||
if settling_cnt > 0 then
|
if settling_cnt > 0 then
|
||||||
settling_cnt <= settling_cnt - 1;
|
settling_cnt <= settling_cnt - 1;
|
||||||
else
|
else
|
||||||
START_SAMPLING <= '1';
|
START_SAMPLING <= '1';
|
||||||
if SAMPLING_BUSY = '1' then
|
if SAMPLING_BUSY = '1' then
|
||||||
state <= ExcitingPort1;
|
state <= Exciting;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
when ExcitingPort1 =>
|
when Exciting =>
|
||||||
-- wait for sampling to finish
|
-- wait for sampling to finish
|
||||||
START_SAMPLING <= '0';
|
START_SAMPLING <= '0';
|
||||||
if SAMPLING_BUSY = '0' then
|
if SAMPLING_BUSY = '0' then
|
||||||
RESULT_INDEX <= "000" & std_logic_vector(point_cnt);
|
RESULT_INDEX <= std_logic_vector(stage_cnt) & std_logic_vector(point_cnt);
|
||||||
if EXCITE_PORT2 = '1' then
|
if stage_cnt < unsigned(STAGES) then
|
||||||
state <= SettlingPort2;
|
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
|
else
|
||||||
state <= NextPoint;
|
state <= NextPoint;
|
||||||
end if;
|
end if;
|
||||||
settling_cnt <= settling_time;
|
settling_cnt <= settling_time;
|
||||||
end if;
|
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 =>
|
when NextPoint =>
|
||||||
if point_cnt < unsigned(NPOINTS) then
|
if point_cnt < unsigned(NPOINTS) then
|
||||||
point_cnt <= point_cnt + 1;
|
point_cnt <= point_cnt + 1;
|
||||||
state <= TriggerSetup;
|
state <= TriggerSetup;
|
||||||
-- initial port depends on whether port 1 is exited
|
|
||||||
PORT_SELECT <= EXCITE_PORT1;
|
|
||||||
else
|
else
|
||||||
point_cnt <= (others => '0');
|
point_cnt <= (others => '0');
|
||||||
state <= Done;
|
state <= Done;
|
||||||
|
@ -224,7 +224,7 @@
|
|||||||
<status xil_pn:value="SuccessfullyRun"/>
|
<status xil_pn:value="SuccessfullyRun"/>
|
||||||
<status xil_pn:value="ReadyToRun"/>
|
<status xil_pn:value="ReadyToRun"/>
|
||||||
</transform>
|
</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="SuccessfullyRun"/>
|
||||||
<status xil_pn:value="ReadyToRun"/>
|
<status xil_pn:value="ReadyToRun"/>
|
||||||
<outfile xil_pn:name="ipcore_dir/DSP_SLICE.ngc"/>
|
<outfile xil_pn:name="ipcore_dir/DSP_SLICE.ngc"/>
|
||||||
@ -253,7 +253,7 @@
|
|||||||
<status xil_pn:value="SuccessfullyRun"/>
|
<status xil_pn:value="SuccessfullyRun"/>
|
||||||
<status xil_pn:value="ReadyToRun"/>
|
<status xil_pn:value="ReadyToRun"/>
|
||||||
</transform>
|
</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="SuccessfullyRun"/>
|
||||||
<status xil_pn:value="WarningsGenerated"/>
|
<status xil_pn:value="WarningsGenerated"/>
|
||||||
<status xil_pn:value="ReadyToRun"/>
|
<status xil_pn:value="ReadyToRun"/>
|
||||||
@ -275,7 +275,7 @@
|
|||||||
<status xil_pn:value="SuccessfullyRun"/>
|
<status xil_pn:value="SuccessfullyRun"/>
|
||||||
<status xil_pn:value="ReadyToRun"/>
|
<status xil_pn:value="ReadyToRun"/>
|
||||||
</transform>
|
</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="SuccessfullyRun"/>
|
||||||
<status xil_pn:value="ReadyToRun"/>
|
<status xil_pn:value="ReadyToRun"/>
|
||||||
<outfile xil_pn:name="_ngo"/>
|
<outfile xil_pn:name="_ngo"/>
|
||||||
@ -284,7 +284,7 @@
|
|||||||
<outfile xil_pn:name="top.ngd"/>
|
<outfile xil_pn:name="top.ngd"/>
|
||||||
<outfile xil_pn:name="top_ngdbuild.xrpt"/>
|
<outfile xil_pn:name="top_ngdbuild.xrpt"/>
|
||||||
</transform>
|
</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="SuccessfullyRun"/>
|
||||||
<status xil_pn:value="WarningsGenerated"/>
|
<status xil_pn:value="WarningsGenerated"/>
|
||||||
<status xil_pn:value="ReadyToRun"/>
|
<status xil_pn:value="ReadyToRun"/>
|
||||||
@ -298,7 +298,7 @@
|
|||||||
<outfile xil_pn:name="top_summary.xml"/>
|
<outfile xil_pn:name="top_summary.xml"/>
|
||||||
<outfile xil_pn:name="top_usage.xml"/>
|
<outfile xil_pn:name="top_usage.xml"/>
|
||||||
</transform>
|
</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="SuccessfullyRun"/>
|
||||||
<status xil_pn:value="ReadyToRun"/>
|
<status xil_pn:value="ReadyToRun"/>
|
||||||
<outfile xil_pn:name="_xmsgs/par.xmsgs"/>
|
<outfile xil_pn:name="_xmsgs/par.xmsgs"/>
|
||||||
@ -312,9 +312,8 @@
|
|||||||
<outfile xil_pn:name="top_pad.txt"/>
|
<outfile xil_pn:name="top_pad.txt"/>
|
||||||
<outfile xil_pn:name="top_par.xrpt"/>
|
<outfile xil_pn:name="top_par.xrpt"/>
|
||||||
</transform>
|
</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="SuccessfullyRun"/>
|
||||||
<status xil_pn:value="WarningsGenerated"/>
|
|
||||||
<status xil_pn:value="ReadyToRun"/>
|
<status xil_pn:value="ReadyToRun"/>
|
||||||
<outfile xil_pn:name="_xmsgs/bitgen.xmsgs"/>
|
<outfile xil_pn:name="_xmsgs/bitgen.xmsgs"/>
|
||||||
<outfile xil_pn:name="top.bgn"/>
|
<outfile xil_pn:name="top.bgn"/>
|
||||||
@ -366,7 +365,7 @@
|
|||||||
<status xil_pn:value="InputChanged"/>
|
<status xil_pn:value="InputChanged"/>
|
||||||
<status xil_pn:value="InputRemoved"/>
|
<status xil_pn:value="InputRemoved"/>
|
||||||
</transform>
|
</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="SuccessfullyRun"/>
|
||||||
<status xil_pn:value="ReadyToRun"/>
|
<status xil_pn:value="ReadyToRun"/>
|
||||||
<outfile xil_pn:name="_xmsgs/trce.xmsgs"/>
|
<outfile xil_pn:name="_xmsgs/trce.xmsgs"/>
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
|
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
|
||||||
</header>
|
</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>
|
<files>
|
||||||
<file xil_pn:name="top.vhd" xil_pn:type="FILE_VHDL">
|
<file xil_pn:name="top.vhd" xil_pn:type="FILE_VHDL">
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
|
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
|
||||||
</header>
|
</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>
|
<files>
|
||||||
<file xil_pn:name="DSP_SLICE.ngc" xil_pn:type="FILE_NGC">
|
<file xil_pn:name="DSP_SLICE.ngc" xil_pn:type="FILE_NGC">
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
|
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
|
||||||
</header>
|
</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>
|
<files>
|
||||||
<file xil_pn:name="PLL.ucf" xil_pn:type="FILE_UCF">
|
<file xil_pn:name="PLL.ucf" xil_pn:type="FILE_UCF">
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
|
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
|
||||||
</header>
|
</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>
|
<files>
|
||||||
<file xil_pn:name="SinCos.ngc" xil_pn:type="FILE_NGC">
|
<file xil_pn:name="SinCos.ngc" xil_pn:type="FILE_NGC">
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
|
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
|
||||||
</header>
|
</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>
|
<files>
|
||||||
<file xil_pn:name="SweepConfigMem.ngc" xil_pn:type="FILE_NGC">
|
<file xil_pn:name="SweepConfigMem.ngc" xil_pn:type="FILE_NGC">
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
|
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
|
||||||
</header>
|
</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>
|
<files>
|
||||||
<file xil_pn:name="result_bram.ngc" xil_pn:type="FILE_NGC">
|
<file xil_pn:name="result_bram.ngc" xil_pn:type="FILE_NGC">
|
||||||
|
BIN
FPGA/VNA/top.bin
BIN
FPGA/VNA/top.bin
Binary file not shown.
@ -124,7 +124,6 @@ architecture Behavioral of top is
|
|||||||
PLL_LOCKED : IN std_logic;
|
PLL_LOCKED : IN std_logic;
|
||||||
CONFIG_ADDRESS : OUT std_logic_vector(12 downto 0);
|
CONFIG_ADDRESS : OUT std_logic_vector(12 downto 0);
|
||||||
START_SAMPLING : OUT std_logic;
|
START_SAMPLING : OUT std_logic;
|
||||||
PORT_SELECT : OUT std_logic;
|
|
||||||
BAND_SELECT : out STD_LOGIC;
|
BAND_SELECT : out STD_LOGIC;
|
||||||
SOURCE_REG_4 : OUT std_logic_vector(31 downto 0);
|
SOURCE_REG_4 : OUT std_logic_vector(31 downto 0);
|
||||||
SOURCE_REG_3 : 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;
|
SWEEP_RESUME : in STD_LOGIC;
|
||||||
ATTENUATOR : OUT std_logic_vector(6 downto 0);
|
ATTENUATOR : OUT std_logic_vector(6 downto 0);
|
||||||
SOURCE_FILTER : OUT std_logic_vector(1 downto 0);
|
SOURCE_FILTER : OUT std_logic_vector(1 downto 0);
|
||||||
EXCITE_PORT1 : in STD_LOGIC;
|
STAGES : in STD_LOGIC_VECTOR (2 downto 0);
|
||||||
EXCITE_PORT2 : in STD_LOGIC;
|
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);
|
RESULT_INDEX : out STD_LOGIC_VECTOR (15 downto 0);
|
||||||
DEBUG_STATUS : out STD_LOGIC_VECTOR (10 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_WRITE : OUT std_logic_vector(0 to 0);
|
||||||
SWEEP_POINTS : OUT std_logic_vector(12 downto 0);
|
SWEEP_POINTS : OUT std_logic_vector(12 downto 0);
|
||||||
NSAMPLES : OUT std_logic_vector(12 downto 0);
|
NSAMPLES : OUT std_logic_vector(12 downto 0);
|
||||||
EXCITE_PORT1 : out STD_LOGIC;
|
STAGES : out STD_LOGIC_VECTOR (2 downto 0);
|
||||||
EXCITE_PORT2 : out STD_LOGIC;
|
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;
|
PORT1_EN : out STD_LOGIC;
|
||||||
PORT2_EN : out STD_LOGIC;
|
PORT2_EN : out STD_LOGIC;
|
||||||
REF_EN : out STD_LOGIC;
|
REF_EN : out STD_LOGIC;
|
||||||
@ -360,10 +366,14 @@ architecture Behavioral of top is
|
|||||||
|
|
||||||
-- Sweep signals
|
-- Sweep signals
|
||||||
signal sweep_points : std_logic_vector(12 downto 0);
|
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_data : std_logic_vector(95 downto 0);
|
||||||
signal sweep_config_address : std_logic_vector(12 downto 0);
|
signal sweep_config_address : std_logic_vector(12 downto 0);
|
||||||
signal source_filter : std_logic_vector(1 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_address : std_logic_vector(12 downto 0);
|
||||||
signal sweep_config_write_data : std_logic_vector(95 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_port1 : std_logic;
|
||||||
signal sweep_excite_port2 : std_logic;
|
signal sweep_excite_port2 : std_logic;
|
||||||
|
|
||||||
signal sweep_band : std_logic;
|
|
||||||
|
|
||||||
-- Configuration signals
|
-- Configuration signals
|
||||||
signal settling_time : std_logic_vector(15 downto 0);
|
signal settling_time : std_logic_vector(15 downto 0);
|
||||||
signal def_reg_4 : std_logic_vector(31 downto 0);
|
signal def_reg_4 : std_logic_vector(31 downto 0);
|
||||||
@ -428,10 +436,10 @@ begin
|
|||||||
LEDS(2) <= SOURCE_LD;
|
LEDS(2) <= SOURCE_LD;
|
||||||
LEDS(3) <= LO1_LD;
|
LEDS(3) <= LO1_LD;
|
||||||
-- Sweep and active port
|
-- Sweep and active port
|
||||||
PORT_SELECT2 <= not sweep_port_select and portswitch_en;
|
PORT_SELECT2 <= sweep_excite_port2 and portswitch_en;
|
||||||
PORT2_SELECT <= not sweep_port_select and portswitch_en;
|
PORT2_SELECT <= sweep_excite_port2 and portswitch_en;
|
||||||
PORT_SELECT1 <= sweep_port_select and portswitch_en;
|
PORT_SELECT1 <= sweep_excite_port1 and portswitch_en;
|
||||||
PORT1_SELECT <= sweep_port_select and portswitch_en;
|
PORT1_SELECT <= sweep_excite_port1 and portswitch_en;
|
||||||
BAND_SELECT_HIGH <= not sweep_band;
|
BAND_SELECT_HIGH <= not sweep_band;
|
||||||
BAND_SELECT_LOW <= sweep_band;
|
BAND_SELECT_LOW <= sweep_band;
|
||||||
PORT1_MIX2_EN <= port1mix_en;
|
PORT1_MIX2_EN <= port1mix_en;
|
||||||
@ -440,8 +448,8 @@ begin
|
|||||||
PORT2_MIX1_EN <= not port2mix_en;
|
PORT2_MIX1_EN <= not port2mix_en;
|
||||||
REF_MIX2_EN <= refmix_en;
|
REF_MIX2_EN <= refmix_en;
|
||||||
REF_MIX1_EN <= not refmix_en;
|
REF_MIX1_EN <= not refmix_en;
|
||||||
LEDS(4) <= not (not sweep_reset and not 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_port_select and portswitch_en);
|
LEDS(5) <= not (not sweep_reset and sweep_excite_port1 and portswitch_en);
|
||||||
-- Uncommitted LEDs
|
-- Uncommitted LEDs
|
||||||
LEDS(7 downto 6) <= user_leds(1 downto 0);
|
LEDS(7 downto 6) <= user_leds(1 downto 0);
|
||||||
--LEDS(7) <= '0';
|
--LEDS(7) <= '0';
|
||||||
@ -649,7 +657,6 @@ begin
|
|||||||
SAMPLING_BUSY => sampling_busy,
|
SAMPLING_BUSY => sampling_busy,
|
||||||
SAMPLING_DONE => sampling_done,
|
SAMPLING_DONE => sampling_done,
|
||||||
START_SAMPLING => sampling_start,
|
START_SAMPLING => sampling_start,
|
||||||
PORT_SELECT => sweep_port_select,
|
|
||||||
BAND_SELECT => sweep_band,
|
BAND_SELECT => sweep_band,
|
||||||
MAX2871_DEF_4 => def_reg_4,
|
MAX2871_DEF_4 => def_reg_4,
|
||||||
MAX2871_DEF_3 => def_reg_3,
|
MAX2871_DEF_3 => def_reg_3,
|
||||||
@ -670,8 +677,13 @@ begin
|
|||||||
SWEEP_RESUME => sweep_resume,
|
SWEEP_RESUME => sweep_resume,
|
||||||
ATTENUATOR => ATTENUATION,
|
ATTENUATOR => ATTENUATION,
|
||||||
SOURCE_FILTER => source_filter,
|
SOURCE_FILTER => source_filter,
|
||||||
EXCITE_PORT1 => sweep_excite_port1,
|
STAGES => sweep_stages,
|
||||||
EXCITE_PORT2 => sweep_excite_port2,
|
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,
|
DEBUG_STATUS => debug,
|
||||||
RESULT_INDEX => sampling_result(303 downto 288)
|
RESULT_INDEX => sampling_result(303 downto 288)
|
||||||
);
|
);
|
||||||
@ -740,8 +752,10 @@ begin
|
|||||||
RESET_MINMAX => adc_reset_minmax,
|
RESET_MINMAX => adc_reset_minmax,
|
||||||
SWEEP_HALTED => sweep_halted,
|
SWEEP_HALTED => sweep_halted,
|
||||||
SWEEP_RESUME => sweep_resume,
|
SWEEP_RESUME => sweep_resume,
|
||||||
EXCITE_PORT1 => sweep_excite_port1,
|
STAGES => sweep_stages,
|
||||||
EXCITE_PORT2 => sweep_excite_port2,
|
INDIVIDUAL_HALT => sweep_individual_halt,
|
||||||
|
PORT1_STAGE => sweep_port1_stage,
|
||||||
|
PORT2_STAGE => sweep_port2_stage,
|
||||||
DFT_BIN1_PHASEINC => dft_bin1_phaseinc,
|
DFT_BIN1_PHASEINC => dft_bin1_phaseinc,
|
||||||
DFT_DIFFBIN_PHASEINC => dft_diffbin_phaseinc,
|
DFT_DIFFBIN_PHASEINC => dft_diffbin_phaseinc,
|
||||||
DFT_RESULT_READY => dft_ready,
|
DFT_RESULT_READY => dft_ready,
|
||||||
|
@ -253,7 +253,7 @@ void AmplitudeCalDialog::RemoveAllPoints()
|
|||||||
|
|
||||||
bool AmplitudeCalDialog::AddPoint(AmplitudeCalDialog::CorrectionPoint &p)
|
bool AmplitudeCalDialog::AddPoint(AmplitudeCalDialog::CorrectionPoint &p)
|
||||||
{
|
{
|
||||||
if (points.size() >= Device::Info().limits_maxAmplitudePoints) {
|
if (points.size() >= Device::Info(dev).limits_maxAmplitudePoints) {
|
||||||
// already at limit
|
// already at limit
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -299,8 +299,8 @@ void AmplitudeCalDialog::AddPointDialog()
|
|||||||
ui->stopFreq->setUnit("Hz");
|
ui->stopFreq->setUnit("Hz");
|
||||||
ui->stopFreq->setPrefixes(" kMG");
|
ui->stopFreq->setPrefixes(" kMG");
|
||||||
ui->frequency->setValue(1000000000.0);
|
ui->frequency->setValue(1000000000.0);
|
||||||
ui->startFreq->setValue(Device::Info().limits_minFreq);
|
ui->startFreq->setValue(Device::Info(dev).limits_minFreq);
|
||||||
ui->stopFreq->setValue(Device::Info().limits_maxFreq);
|
ui->stopFreq->setValue(Device::Info(dev).limits_maxFreq);
|
||||||
connect(ui->singlePoint, &QRadioButton::toggled, [=](bool single) {
|
connect(ui->singlePoint, &QRadioButton::toggled, [=](bool single) {
|
||||||
ui->stopFreq->setEnabled(!single);
|
ui->stopFreq->setEnabled(!single);
|
||||||
ui->startFreq->setEnabled(!single);
|
ui->startFreq->setEnabled(!single);
|
||||||
|
@ -120,16 +120,6 @@ static constexpr Protocol::DeviceInfo defaultInfo = {
|
|||||||
.FW_minor = 0,
|
.FW_minor = 0,
|
||||||
.FW_patch = 0,
|
.FW_patch = 0,
|
||||||
.HW_Revision = '0',
|
.HW_Revision = '0',
|
||||||
.extRefAvailable = 0,
|
|
||||||
.extRefInUse = 0,
|
|
||||||
.FPGA_configured = 0,
|
|
||||||
.source_locked = 0,
|
|
||||||
.LO1_locked = 0,
|
|
||||||
.ADC_overload = 0,
|
|
||||||
.unlevel = 0,
|
|
||||||
.temp_source = 0,
|
|
||||||
.temp_LO1 = 0,
|
|
||||||
.temp_MCU = 0,
|
|
||||||
.limits_minFreq = 0,
|
.limits_minFreq = 0,
|
||||||
.limits_maxFreq = 6000000000,
|
.limits_maxFreq = 6000000000,
|
||||||
.limits_minIFBW = 10,
|
.limits_minIFBW = 10,
|
||||||
@ -143,14 +133,25 @@ static constexpr Protocol::DeviceInfo defaultInfo = {
|
|||||||
.limits_maxFreqHarmonic = 18000000000,
|
.limits_maxFreqHarmonic = 18000000000,
|
||||||
};
|
};
|
||||||
|
|
||||||
Protocol::DeviceInfo Device::lastInfo = defaultInfo;
|
static constexpr Protocol::DeviceStatusV1 defaultStatusV1 = {
|
||||||
|
.extRefAvailable = 0,
|
||||||
|
.extRefInUse = 0,
|
||||||
|
.FPGA_configured = 0,
|
||||||
|
.source_locked = 0,
|
||||||
|
.LO1_locked = 0,
|
||||||
|
.ADC_overload = 0,
|
||||||
|
.unlevel = 0,
|
||||||
|
.temp_source = 0,
|
||||||
|
.temp_LO1 = 0,
|
||||||
|
.temp_MCU = 0,
|
||||||
|
};
|
||||||
|
|
||||||
Device::Device(QString serial)
|
Device::Device(QString serial)
|
||||||
{
|
{
|
||||||
lastInfo = defaultInfo;
|
info = defaultInfo;
|
||||||
|
|
||||||
m_handle = nullptr;
|
m_handle = nullptr;
|
||||||
lastInfoValid = false;
|
infoValid = false;
|
||||||
libusb_init(&m_context);
|
libusb_init(&m_context);
|
||||||
#if LIBUSB_API_VERSION >= 0x01000106
|
#if LIBUSB_API_VERSION >= 0x01000106
|
||||||
libusb_set_option(m_context, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_INFO);
|
libusb_set_option(m_context, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_INFO);
|
||||||
@ -261,10 +262,10 @@ bool Device::Configure(Protocol::SpectrumAnalyzerSettings settings)
|
|||||||
return SendPacket(p);
|
return SendPacket(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Device::SetManual(Protocol::ManualControl manual)
|
bool Device::SetManual(Protocol::ManualControlV1 manual)
|
||||||
{
|
{
|
||||||
Protocol::PacketInfo p;
|
Protocol::PacketInfo p;
|
||||||
p.type = Protocol::PacketType::ManualControl;
|
p.type = Protocol::PacketType::ManualControlV1;
|
||||||
p.manual = manual;
|
p.manual = manual;
|
||||||
return SendPacket(p);
|
return SendPacket(p);
|
||||||
}
|
}
|
||||||
@ -393,25 +394,48 @@ void Device::SearchDevices(std::function<bool (libusb_device_handle *, QString)>
|
|||||||
|
|
||||||
const Protocol::DeviceInfo &Device::Info()
|
const Protocol::DeviceInfo &Device::Info()
|
||||||
{
|
{
|
||||||
return lastInfo;
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Protocol::DeviceInfo &Device::Info(Device *dev)
|
||||||
|
{
|
||||||
|
if(dev) {
|
||||||
|
return dev->Info();
|
||||||
|
} else {
|
||||||
|
return defaultInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Protocol::DeviceStatusV1 &Device::StatusV1()
|
||||||
|
{
|
||||||
|
return status.v1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Protocol::DeviceStatusV1 &Device::StatusV1(Device *dev)
|
||||||
|
{
|
||||||
|
if(dev) {
|
||||||
|
return dev->StatusV1();
|
||||||
|
} else {
|
||||||
|
return defaultStatusV1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Device::getLastDeviceInfoString()
|
QString Device::getLastDeviceInfoString()
|
||||||
{
|
{
|
||||||
QString ret;
|
QString ret;
|
||||||
if(!lastInfoValid) {
|
if(!infoValid) {
|
||||||
ret.append("No device information available yet");
|
ret.append("No device information available yet");
|
||||||
} else {
|
} else {
|
||||||
ret.append("HW Rev.");
|
ret.append("HW Rev.");
|
||||||
ret.append(lastInfo.HW_Revision);
|
ret.append(info.HW_Revision);
|
||||||
ret.append(" FW "+QString::number(lastInfo.FW_major)+"."+QString::number(lastInfo.FW_minor)+"."+QString::number(lastInfo.FW_patch));
|
ret.append(" FW "+QString::number(info.FW_major)+"."+QString::number(info.FW_minor)+"."+QString::number(info.FW_patch));
|
||||||
ret.append(" Temps: "+QString::number(lastInfo.temp_source)+"°C/"+QString::number(lastInfo.temp_LO1)+"°C/"+QString::number(lastInfo.temp_MCU)+"°C");
|
ret.append(" Temps: "+QString::number(status.v1.temp_source)+"°C/"+QString::number(status.v1.temp_LO1)+"°C/"+QString::number(status.v1.temp_MCU)+"°C");
|
||||||
ret.append(" Reference:");
|
ret.append(" Reference:");
|
||||||
if(lastInfo.extRefInUse) {
|
if(status.v1.extRefInUse) {
|
||||||
ret.append("External");
|
ret.append("External");
|
||||||
} else {
|
} else {
|
||||||
ret.append("Internal");
|
ret.append("Internal");
|
||||||
if(lastInfo.extRefAvailable) {
|
if(status.v1.extRefAvailable) {
|
||||||
ret.append(" (External available)");
|
ret.append(" (External available)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -431,8 +455,8 @@ void Device::ReceivedData()
|
|||||||
case Protocol::PacketType::Datapoint:
|
case Protocol::PacketType::Datapoint:
|
||||||
emit DatapointReceived(packet.datapoint);
|
emit DatapointReceived(packet.datapoint);
|
||||||
break;
|
break;
|
||||||
case Protocol::PacketType::Status:
|
case Protocol::PacketType::ManualStatusV1:
|
||||||
emit ManualStatusReceived(packet.status);
|
emit ManualStatusReceived(packet.manualStatusV1);
|
||||||
break;
|
break;
|
||||||
case Protocol::PacketType::SpectrumAnalyzerResult:
|
case Protocol::PacketType::SpectrumAnalyzerResult:
|
||||||
emit SpectrumResultReceived(packet.spectrumResult);
|
emit SpectrumResultReceived(packet.spectrumResult);
|
||||||
@ -443,15 +467,19 @@ void Device::ReceivedData()
|
|||||||
break;
|
break;
|
||||||
case Protocol::PacketType::DeviceInfo:
|
case Protocol::PacketType::DeviceInfo:
|
||||||
if(packet.info.ProtocolVersion != Protocol::Version) {
|
if(packet.info.ProtocolVersion != Protocol::Version) {
|
||||||
if(!lastInfoValid) {
|
if(!infoValid) {
|
||||||
emit NeedsFirmwareUpdate(packet.info.ProtocolVersion, Protocol::Version);
|
emit NeedsFirmwareUpdate(packet.info.ProtocolVersion, Protocol::Version);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
lastInfo = packet.info;
|
info = packet.info;
|
||||||
}
|
}
|
||||||
lastInfoValid = true;
|
infoValid = true;
|
||||||
emit DeviceInfoUpdated();
|
emit DeviceInfoUpdated();
|
||||||
break;
|
break;
|
||||||
|
case Protocol::PacketType::DeviceStatusV1:
|
||||||
|
status.v1 = packet.statusV1;
|
||||||
|
emit DeviceStatusUpdated();
|
||||||
|
break;
|
||||||
case Protocol::PacketType::Ack:
|
case Protocol::PacketType::Ack:
|
||||||
emit AckReceived();
|
emit AckReceived();
|
||||||
emit receivedAnswer(TransmissionResult::Ack);
|
emit receivedAnswer(TransmissionResult::Ack);
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(Protocol::Datapoint);
|
Q_DECLARE_METATYPE(Protocol::Datapoint);
|
||||||
Q_DECLARE_METATYPE(Protocol::ManualStatus);
|
Q_DECLARE_METATYPE(Protocol::ManualStatusV1);
|
||||||
Q_DECLARE_METATYPE(Protocol::SpectrumAnalyzerResult);
|
Q_DECLARE_METATYPE(Protocol::SpectrumAnalyzerResult);
|
||||||
Q_DECLARE_METATYPE(Protocol::AmplitudeCorrectionPoint);
|
Q_DECLARE_METATYPE(Protocol::AmplitudeCorrectionPoint);
|
||||||
|
|
||||||
@ -61,23 +61,27 @@ public:
|
|||||||
bool SendPacket(const Protocol::PacketInfo& packet, std::function<void(TransmissionResult)> cb = nullptr, unsigned int timeout = 500);
|
bool SendPacket(const Protocol::PacketInfo& packet, std::function<void(TransmissionResult)> cb = nullptr, unsigned int timeout = 500);
|
||||||
bool Configure(Protocol::SweepSettings settings, std::function<void(TransmissionResult)> cb = nullptr);
|
bool Configure(Protocol::SweepSettings settings, std::function<void(TransmissionResult)> cb = nullptr);
|
||||||
bool Configure(Protocol::SpectrumAnalyzerSettings settings);
|
bool Configure(Protocol::SpectrumAnalyzerSettings settings);
|
||||||
bool SetManual(Protocol::ManualControl manual);
|
bool SetManual(Protocol::ManualControlV1 manual);
|
||||||
bool SetIdle();
|
bool SetIdle();
|
||||||
bool SendFirmwareChunk(Protocol::FirmwarePacket &fw);
|
bool SendFirmwareChunk(Protocol::FirmwarePacket &fw);
|
||||||
bool SendCommandWithoutPayload(Protocol::PacketType type);
|
bool SendCommandWithoutPayload(Protocol::PacketType type);
|
||||||
QString serial() const;
|
QString serial() const;
|
||||||
static const Protocol::DeviceInfo& Info();
|
const Protocol::DeviceInfo& Info();
|
||||||
|
static const Protocol::DeviceInfo& Info(Device *dev);
|
||||||
|
Protocol::DeviceStatusV1& StatusV1();
|
||||||
|
static const Protocol::DeviceStatusV1& StatusV1(Device *dev);
|
||||||
QString getLastDeviceInfoString();
|
QString getLastDeviceInfoString();
|
||||||
|
|
||||||
// Returns serial numbers of all connected devices
|
// Returns serial numbers of all connected devices
|
||||||
static std::set<QString> GetDevices();
|
static std::set<QString> GetDevices();
|
||||||
signals:
|
signals:
|
||||||
void DatapointReceived(Protocol::Datapoint);
|
void DatapointReceived(Protocol::Datapoint);
|
||||||
void ManualStatusReceived(Protocol::ManualStatus);
|
void ManualStatusReceived(Protocol::ManualStatusV1);
|
||||||
void SpectrumResultReceived(Protocol::SpectrumAnalyzerResult);
|
void SpectrumResultReceived(Protocol::SpectrumAnalyzerResult);
|
||||||
void AmplitudeCorrectionPointReceived(Protocol::AmplitudeCorrectionPoint);
|
void AmplitudeCorrectionPointReceived(Protocol::AmplitudeCorrectionPoint);
|
||||||
void FrequencyCorrectionReceived(float ppm);
|
void FrequencyCorrectionReceived(float ppm);
|
||||||
void DeviceInfoUpdated();
|
void DeviceInfoUpdated();
|
||||||
|
void DeviceStatusUpdated();
|
||||||
void ConnectionLost();
|
void ConnectionLost();
|
||||||
void AckReceived();
|
void AckReceived();
|
||||||
void NackReceived();
|
void NackReceived();
|
||||||
@ -122,8 +126,11 @@ private:
|
|||||||
QString m_serial;
|
QString m_serial;
|
||||||
bool m_connected;
|
bool m_connected;
|
||||||
std::thread *m_receiveThread;
|
std::thread *m_receiveThread;
|
||||||
static Protocol::DeviceInfo lastInfo;
|
Protocol::DeviceInfo info;
|
||||||
bool lastInfoValid;
|
bool infoValid;
|
||||||
|
union {
|
||||||
|
Protocol::DeviceStatusV1 v1;
|
||||||
|
} status;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DEVICE_H
|
#endif // DEVICE_H
|
||||||
|
@ -580,7 +580,7 @@ double ManualControlDialog::getRefPhase()
|
|||||||
return ui->refphase->text().toDouble();
|
return ui->refphase->text().toDouble();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ManualControlDialog::NewStatus(Protocol::ManualStatus status)
|
void ManualControlDialog::NewStatus(Protocol::ManualStatusV1 status)
|
||||||
{
|
{
|
||||||
// ADC values
|
// ADC values
|
||||||
ui->port1min->setText(QString::number(status.port1min));
|
ui->port1min->setText(QString::number(status.port1min));
|
||||||
@ -616,7 +616,7 @@ void ManualControlDialog::NewStatus(Protocol::ManualStatus status)
|
|||||||
|
|
||||||
void ManualControlDialog::UpdateDevice()
|
void ManualControlDialog::UpdateDevice()
|
||||||
{
|
{
|
||||||
Protocol::ManualControl m;
|
Protocol::ManualControlV1 m;
|
||||||
// Source highband
|
// Source highband
|
||||||
m.SourceHighCE = ui->SourceCE->isChecked();
|
m.SourceHighCE = ui->SourceCE->isChecked();
|
||||||
m.SourceHighRFEN = ui->SourceRFEN->isChecked();
|
m.SourceHighRFEN = ui->SourceRFEN->isChecked();
|
||||||
|
@ -103,7 +103,7 @@ public:
|
|||||||
double getRefPhase();
|
double getRefPhase();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void NewStatus(Protocol::ManualStatus status);
|
void NewStatus(Protocol::ManualStatusV1 status);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void UpdateDevice();
|
void UpdateDevice();
|
||||||
|
@ -2,11 +2,10 @@
|
|||||||
|
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
|
||||||
Generator::Generator(AppWindow *window)
|
Generator::Generator(AppWindow *window, QString name)
|
||||||
: Mode(window, "Signal Generator")
|
: Mode(window, name, "GENerator")
|
||||||
, SCPINode("GENerator")
|
|
||||||
{
|
{
|
||||||
central = new SignalgeneratorWidget(window);
|
central = new SignalgeneratorWidget(window->getDevice(), window);
|
||||||
|
|
||||||
auto pref = Preferences::getInstance();
|
auto pref = Preferences::getInstance();
|
||||||
|
|
||||||
|
@ -5,13 +5,15 @@
|
|||||||
#include "signalgenwidget.h"
|
#include "signalgenwidget.h"
|
||||||
#include "scpi.h"
|
#include "scpi.h"
|
||||||
|
|
||||||
class Generator : public Mode, public SCPINode
|
class Generator : public Mode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Generator(AppWindow *window);
|
Generator(AppWindow *window, QString name = "Signal Generator");
|
||||||
void deactivate() override;
|
void deactivate() override;
|
||||||
void initializeDevice() override;
|
void initializeDevice() override;
|
||||||
|
|
||||||
|
virtual Type getType() override { return Type::SG;}
|
||||||
|
|
||||||
// Nothing to do for now
|
// Nothing to do for now
|
||||||
virtual nlohmann::json toJSON() override;
|
virtual nlohmann::json toJSON() override;
|
||||||
virtual void fromJSON(nlohmann::json j) override;
|
virtual void fromJSON(nlohmann::json j) override;
|
||||||
|
@ -2,9 +2,10 @@
|
|||||||
|
|
||||||
#include "ui_signalgenwidget.h"
|
#include "ui_signalgenwidget.h"
|
||||||
|
|
||||||
SignalgeneratorWidget::SignalgeneratorWidget(QWidget *parent) :
|
SignalgeneratorWidget::SignalgeneratorWidget(Device *&dev, QWidget *parent) :
|
||||||
QWidget(parent),
|
QWidget(parent),
|
||||||
ui(new Ui::SignalgeneratorWidget)
|
ui(new Ui::SignalgeneratorWidget),
|
||||||
|
dev(dev)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
ui->frequency->setUnit("Hz");
|
ui->frequency->setUnit("Hz");
|
||||||
@ -31,16 +32,16 @@ SignalgeneratorWidget::SignalgeneratorWidget(QWidget *parent) :
|
|||||||
ui->steps->setPrecision(0);
|
ui->steps->setPrecision(0);
|
||||||
|
|
||||||
connect(ui->frequency, &SIUnitEdit::valueChanged, [=](double newval) {
|
connect(ui->frequency, &SIUnitEdit::valueChanged, [=](double newval) {
|
||||||
if(newval < Device::Info().limits_minFreq) {
|
if(newval < Device::Info(dev).limits_minFreq) {
|
||||||
newval = Device::Info().limits_minFreq;
|
newval = Device::Info(dev).limits_minFreq;
|
||||||
} else if (newval > Device::Info().limits_maxFreq) {
|
} else if (newval > Device::Info(dev).limits_maxFreq) {
|
||||||
newval = Device::Info().limits_maxFreq;
|
newval = Device::Info(dev).limits_maxFreq;
|
||||||
}
|
}
|
||||||
ui->frequency->setValueQuiet(newval);
|
ui->frequency->setValueQuiet(newval);
|
||||||
if (newval < ui->span->value()/2)
|
if (newval < ui->span->value()/2)
|
||||||
ui->span->setValueQuiet(newval/2);
|
ui->span->setValueQuiet(newval/2);
|
||||||
if (newval + ui->span->value()/2 > Device::Info().limits_maxFreq)
|
if (newval + ui->span->value()/2 > Device::Info(dev).limits_maxFreq)
|
||||||
ui->span->setValueQuiet((Device::Info().limits_maxFreq - newval)*2);
|
ui->span->setValueQuiet((Device::Info(dev).limits_maxFreq - newval)*2);
|
||||||
newval = ui->frequency->value() - ui->span->value()/2;
|
newval = ui->frequency->value() - ui->span->value()/2;
|
||||||
ui->current->setValueQuiet(newval);
|
ui->current->setValueQuiet(newval);
|
||||||
emit SettingsChanged();
|
emit SettingsChanged();
|
||||||
@ -49,8 +50,8 @@ SignalgeneratorWidget::SignalgeneratorWidget(QWidget *parent) :
|
|||||||
connect(ui->span, &SIUnitEdit::valueChanged, [=](double newval) {
|
connect(ui->span, &SIUnitEdit::valueChanged, [=](double newval) {
|
||||||
if(newval < 0 ) {
|
if(newval < 0 ) {
|
||||||
newval = 0;
|
newval = 0;
|
||||||
} else if (newval > Device::Info().limits_maxFreq - Device::Info().limits_minFreq) {
|
} else if (newval > Device::Info(dev).limits_maxFreq - Device::Info(dev).limits_minFreq) {
|
||||||
newval = Device::Info().limits_maxFreq - Device::Info().limits_minFreq;
|
newval = Device::Info(dev).limits_maxFreq - Device::Info(dev).limits_minFreq;
|
||||||
}
|
}
|
||||||
ui->span->setValueQuiet(newval);
|
ui->span->setValueQuiet(newval);
|
||||||
|
|
||||||
@ -59,8 +60,8 @@ SignalgeneratorWidget::SignalgeneratorWidget(QWidget *parent) :
|
|||||||
ui->frequency->setValueQuiet(ui->span->value()/2);
|
ui->frequency->setValueQuiet(ui->span->value()/2);
|
||||||
}
|
}
|
||||||
newF = ui->frequency->value() + ui->span->value()/2;
|
newF = ui->frequency->value() + ui->span->value()/2;
|
||||||
if (newF > Device::Info().limits_maxFreq) {
|
if (newF > Device::Info(dev).limits_maxFreq) {
|
||||||
ui->frequency->setValueQuiet(Device::Info().limits_maxFreq - ui->span->value()/2);
|
ui->frequency->setValueQuiet(Device::Info(dev).limits_maxFreq - ui->span->value()/2);
|
||||||
}
|
}
|
||||||
|
|
||||||
newval = ui->frequency->value() - ui->span->value()/2;
|
newval = ui->frequency->value() - ui->span->value()/2;
|
||||||
@ -71,8 +72,8 @@ SignalgeneratorWidget::SignalgeneratorWidget(QWidget *parent) :
|
|||||||
connect(ui->current, &SIUnitEdit::valueChanged, [=](double newval) {
|
connect(ui->current, &SIUnitEdit::valueChanged, [=](double newval) {
|
||||||
if(newval < 0 ) {
|
if(newval < 0 ) {
|
||||||
newval = 0;
|
newval = 0;
|
||||||
} else if (newval > Device::Info().limits_maxFreq - Device::Info().limits_minFreq) {
|
} else if (newval > Device::Info(dev).limits_maxFreq - Device::Info(dev).limits_minFreq) {
|
||||||
newval = Device::Info().limits_maxFreq - Device::Info().limits_minFreq;
|
newval = Device::Info(dev).limits_maxFreq - Device::Info(dev).limits_minFreq;
|
||||||
}
|
}
|
||||||
ui->current->setValueQuiet(newval);
|
ui->current->setValueQuiet(newval);
|
||||||
emit SettingsChanged();
|
emit SettingsChanged();
|
||||||
|
@ -15,7 +15,7 @@ class SignalgeneratorWidget : public QWidget, public Savable
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit SignalgeneratorWidget(QWidget *parent = nullptr);
|
explicit SignalgeneratorWidget(Device*&dev, QWidget *parent = nullptr);
|
||||||
~SignalgeneratorWidget();
|
~SignalgeneratorWidget();
|
||||||
|
|
||||||
Protocol::GeneratorSettings getDeviceStatus();
|
Protocol::GeneratorSettings getDeviceStatus();
|
||||||
@ -36,6 +36,7 @@ protected:
|
|||||||
private:
|
private:
|
||||||
Ui::SignalgeneratorWidget *ui;
|
Ui::SignalgeneratorWidget *ui;
|
||||||
int m_timerId;
|
int m_timerId;
|
||||||
|
Device*&dev;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SIGNALGENERATOR_H
|
#endif // SIGNALGENERATOR_H
|
||||||
|
@ -45,9 +45,8 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
|
||||||
SpectrumAnalyzer::SpectrumAnalyzer(AppWindow *window)
|
SpectrumAnalyzer::SpectrumAnalyzer(AppWindow *window, QString name)
|
||||||
: Mode(window, "Spectrum Analyzer"),
|
: Mode(window, name, "SA"),
|
||||||
SCPINode("SA"),
|
|
||||||
central(new TileWidget(traceModel, window))
|
central(new TileWidget(traceModel, window))
|
||||||
{
|
{
|
||||||
averages = 1;
|
averages = 1;
|
||||||
@ -422,6 +421,10 @@ using namespace std;
|
|||||||
|
|
||||||
void SpectrumAnalyzer::NewDatapoint(Protocol::SpectrumAnalyzerResult d)
|
void SpectrumAnalyzer::NewDatapoint(Protocol::SpectrumAnalyzerResult d)
|
||||||
{
|
{
|
||||||
|
if(Mode::getActiveMode() != this) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(d.pointNum >= settings.pointNum) {
|
if(d.pointNum >= settings.pointNum) {
|
||||||
qWarning() << "Ignoring point with too large point number (" << d.pointNum << ")";
|
qWarning() << "Ignoring point with too large point number (" << d.pointNum << ")";
|
||||||
return;
|
return;
|
||||||
@ -555,14 +558,14 @@ void SpectrumAnalyzer::SetStopFreq(double freq)
|
|||||||
void SpectrumAnalyzer::SetCenterFreq(double freq)
|
void SpectrumAnalyzer::SetCenterFreq(double freq)
|
||||||
{
|
{
|
||||||
auto old_span = settings.f_stop - settings.f_start;
|
auto old_span = settings.f_stop - settings.f_start;
|
||||||
if (freq - old_span / 2 <= Device::Info().limits_minFreq) {
|
if (freq - old_span / 2 <= Device::Info(window->getDevice()).limits_minFreq) {
|
||||||
// would shift start frequency below minimum
|
// would shift start frequency below minimum
|
||||||
settings.f_start = 0;
|
settings.f_start = 0;
|
||||||
settings.f_stop = 2 * freq;
|
settings.f_stop = 2 * freq;
|
||||||
} else if(freq + old_span / 2 >= Device::Info().limits_maxFreq) {
|
} else if(freq + old_span / 2 >= Device::Info(window->getDevice()).limits_maxFreq) {
|
||||||
// would shift stop frequency above maximum
|
// would shift stop frequency above maximum
|
||||||
settings.f_start = 2 * freq - Device::Info().limits_maxFreq;
|
settings.f_start = 2 * freq - Device::Info(window->getDevice()).limits_maxFreq;
|
||||||
settings.f_stop = Device::Info().limits_maxFreq;
|
settings.f_stop = Device::Info(window->getDevice()).limits_maxFreq;
|
||||||
} else {
|
} else {
|
||||||
settings.f_start = freq - old_span / 2;
|
settings.f_start = freq - old_span / 2;
|
||||||
settings.f_stop = freq + old_span / 2;
|
settings.f_stop = freq + old_span / 2;
|
||||||
@ -573,14 +576,14 @@ void SpectrumAnalyzer::SetCenterFreq(double freq)
|
|||||||
void SpectrumAnalyzer::SetSpan(double span)
|
void SpectrumAnalyzer::SetSpan(double span)
|
||||||
{
|
{
|
||||||
auto old_center = (settings.f_start + settings.f_stop) / 2;
|
auto old_center = (settings.f_start + settings.f_stop) / 2;
|
||||||
if(old_center < Device::Info().limits_minFreq + span / 2) {
|
if(old_center < Device::Info(window->getDevice()).limits_minFreq + span / 2) {
|
||||||
// would shift start frequency below minimum
|
// would shift start frequency below minimum
|
||||||
settings.f_start = Device::Info().limits_minFreq;
|
settings.f_start = Device::Info(window->getDevice()).limits_minFreq;
|
||||||
settings.f_stop = Device::Info().limits_minFreq + span;
|
settings.f_stop = Device::Info(window->getDevice()).limits_minFreq + span;
|
||||||
} else if(old_center > Device::Info().limits_maxFreq - span / 2) {
|
} else if(old_center > Device::Info(window->getDevice()).limits_maxFreq - span / 2) {
|
||||||
// would shift stop frequency above maximum
|
// would shift stop frequency above maximum
|
||||||
settings.f_start = Device::Info().limits_maxFreq - span;
|
settings.f_start = Device::Info(window->getDevice()).limits_maxFreq - span;
|
||||||
settings.f_stop = Device::Info().limits_maxFreq;
|
settings.f_stop = Device::Info(window->getDevice()).limits_maxFreq;
|
||||||
} else {
|
} else {
|
||||||
settings.f_start = old_center - span / 2;
|
settings.f_start = old_center - span / 2;
|
||||||
settings.f_stop = settings.f_start + span;
|
settings.f_stop = settings.f_start + span;
|
||||||
@ -590,8 +593,8 @@ void SpectrumAnalyzer::SetSpan(double span)
|
|||||||
|
|
||||||
void SpectrumAnalyzer::SetFullSpan()
|
void SpectrumAnalyzer::SetFullSpan()
|
||||||
{
|
{
|
||||||
settings.f_start = Device::Info().limits_minFreq;
|
settings.f_start = Device::Info(window->getDevice()).limits_minFreq;
|
||||||
settings.f_stop = Device::Info().limits_maxFreq;
|
settings.f_stop = Device::Info(window->getDevice()).limits_maxFreq;
|
||||||
ConstrainAndUpdateFrequencies();
|
ConstrainAndUpdateFrequencies();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -619,10 +622,10 @@ void SpectrumAnalyzer::SpanZoomOut()
|
|||||||
|
|
||||||
void SpectrumAnalyzer::SetRBW(double bandwidth)
|
void SpectrumAnalyzer::SetRBW(double bandwidth)
|
||||||
{
|
{
|
||||||
if(bandwidth > Device::Info().limits_maxRBW) {
|
if(bandwidth > Device::Info(window->getDevice()).limits_maxRBW) {
|
||||||
bandwidth = Device::Info().limits_maxRBW;
|
bandwidth = Device::Info(window->getDevice()).limits_maxRBW;
|
||||||
} else if(bandwidth < Device::Info().limits_minRBW) {
|
} else if(bandwidth < Device::Info(window->getDevice()).limits_minRBW) {
|
||||||
bandwidth = Device::Info().limits_minRBW;
|
bandwidth = Device::Info(window->getDevice()).limits_minRBW;
|
||||||
}
|
}
|
||||||
settings.RBW = bandwidth;
|
settings.RBW = bandwidth;
|
||||||
emit RBWChanged(settings.RBW);
|
emit RBWChanged(settings.RBW);
|
||||||
@ -690,10 +693,10 @@ void SpectrumAnalyzer::SetTGPort(int port)
|
|||||||
|
|
||||||
void SpectrumAnalyzer::SetTGLevel(double level)
|
void SpectrumAnalyzer::SetTGLevel(double level)
|
||||||
{
|
{
|
||||||
if(level > Device::Info().limits_cdbm_max / 100.0) {
|
if(level > Device::Info(window->getDevice()).limits_cdbm_max / 100.0) {
|
||||||
level = Device::Info().limits_cdbm_max / 100.0;
|
level = Device::Info(window->getDevice()).limits_cdbm_max / 100.0;
|
||||||
} else if(level < Device::Info().limits_cdbm_min / 100.0) {
|
} else if(level < Device::Info(window->getDevice()).limits_cdbm_min / 100.0) {
|
||||||
level = Device::Info().limits_cdbm_min / 100.0;
|
level = Device::Info(window->getDevice()).limits_cdbm_min / 100.0;
|
||||||
}
|
}
|
||||||
emit TGLevelChanged(level);
|
emit TGLevelChanged(level);
|
||||||
settings.trackingPower = level * 100;
|
settings.trackingPower = level * 100;
|
||||||
@ -1015,24 +1018,24 @@ void SpectrumAnalyzer::UpdateAverageCount()
|
|||||||
|
|
||||||
void SpectrumAnalyzer::ConstrainAndUpdateFrequencies()
|
void SpectrumAnalyzer::ConstrainAndUpdateFrequencies()
|
||||||
{
|
{
|
||||||
if(settings.f_stop > Device::Info().limits_maxFreq) {
|
if(settings.f_stop > Device::Info(window->getDevice()).limits_maxFreq) {
|
||||||
settings.f_stop = Device::Info().limits_maxFreq;
|
settings.f_stop = Device::Info(window->getDevice()).limits_maxFreq;
|
||||||
}
|
}
|
||||||
if(settings.f_start > settings.f_stop) {
|
if(settings.f_start > settings.f_stop) {
|
||||||
settings.f_start = settings.f_stop;
|
settings.f_start = settings.f_stop;
|
||||||
}
|
}
|
||||||
if(settings.f_start < Device::Info().limits_minFreq) {
|
if(settings.f_start < Device::Info(window->getDevice()).limits_minFreq) {
|
||||||
settings.f_start = Device::Info().limits_minFreq;
|
settings.f_start = Device::Info(window->getDevice()).limits_minFreq;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool trackingOffset_limited = false;
|
bool trackingOffset_limited = false;
|
||||||
if(settings.f_stop + settings.trackingGeneratorOffset > Device::Info().limits_maxFreq) {
|
if(settings.f_stop + settings.trackingGeneratorOffset > Device::Info(window->getDevice()).limits_maxFreq) {
|
||||||
trackingOffset_limited = true;
|
trackingOffset_limited = true;
|
||||||
settings.trackingGeneratorOffset = Device::Info().limits_maxFreq - settings.f_stop;
|
settings.trackingGeneratorOffset = Device::Info(window->getDevice()).limits_maxFreq - settings.f_stop;
|
||||||
}
|
}
|
||||||
if((long) settings.f_start + settings.trackingGeneratorOffset < (long) Device::Info().limits_minFreq) {
|
if((long) settings.f_start + settings.trackingGeneratorOffset < (long) Device::Info(window->getDevice()).limits_minFreq) {
|
||||||
trackingOffset_limited = true;
|
trackingOffset_limited = true;
|
||||||
settings.trackingGeneratorOffset = Device::Info().limits_minFreq - settings.f_start;
|
settings.trackingGeneratorOffset = Device::Info(window->getDevice()).limits_minFreq - settings.f_start;
|
||||||
}
|
}
|
||||||
if(trackingOffset_limited) {
|
if(trackingOffset_limited) {
|
||||||
InformationBox::ShowMessage("Warning", "The selected tracking generator offset is not reachable for all frequencies with the current span. "
|
InformationBox::ShowMessage("Warning", "The selected tracking generator offset is not reachable for all frequencies with the current span. "
|
||||||
|
@ -12,15 +12,17 @@
|
|||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
|
|
||||||
class SpectrumAnalyzer : public Mode, public SCPINode
|
class SpectrumAnalyzer : public Mode
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
SpectrumAnalyzer(AppWindow *window);
|
SpectrumAnalyzer(AppWindow *window, QString name = "Spectrum Analyzer");
|
||||||
|
|
||||||
void deactivate() override;
|
void deactivate() override;
|
||||||
void initializeDevice() override;
|
void initializeDevice() override;
|
||||||
|
|
||||||
|
virtual Type getType() override { return Type::SA;}
|
||||||
|
|
||||||
// Only save/load user changeable stuff, no need to save the widgets/mode name etc.
|
// Only save/load user changeable stuff, no need to save the widgets/mode name etc.
|
||||||
virtual nlohmann::json toJSON() override;
|
virtual nlohmann::json toJSON() override;
|
||||||
virtual void fromJSON(nlohmann::json j) override;
|
virtual void fromJSON(nlohmann::json j) override;
|
||||||
|
@ -51,9 +51,8 @@
|
|||||||
#include <QErrorMessage>
|
#include <QErrorMessage>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
VNA::VNA(AppWindow *window)
|
VNA::VNA(AppWindow *window, QString name)
|
||||||
: Mode(window, "Vector Network Analyzer"),
|
: Mode(window, name, "VNA"),
|
||||||
SCPINode("VNA"),
|
|
||||||
deembedding(traceModel),
|
deembedding(traceModel),
|
||||||
deembedding_active(false),
|
deembedding_active(false),
|
||||||
central(new TileWidget(traceModel))
|
central(new TileWidget(traceModel))
|
||||||
@ -790,6 +789,11 @@ using namespace std;
|
|||||||
|
|
||||||
void VNA::NewDatapoint(Protocol::Datapoint d)
|
void VNA::NewDatapoint(Protocol::Datapoint d)
|
||||||
{
|
{
|
||||||
|
if(Mode::getActiveMode() != this) {
|
||||||
|
// ignore
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(changingSettings) {
|
if(changingSettings) {
|
||||||
// already setting new sweep settings, ignore incoming points from old settings
|
// already setting new sweep settings, ignore incoming points from old settings
|
||||||
return;
|
return;
|
||||||
@ -997,14 +1001,14 @@ void VNA::SetStopFreq(double freq)
|
|||||||
void VNA::SetCenterFreq(double freq)
|
void VNA::SetCenterFreq(double freq)
|
||||||
{
|
{
|
||||||
auto old_span = settings.Freq.stop - settings.Freq.start;
|
auto old_span = settings.Freq.stop - settings.Freq.start;
|
||||||
if (freq - old_span / 2 <= Device::Info().limits_minFreq) {
|
if (freq - old_span / 2 <= Device::Info(window->getDevice()).limits_minFreq) {
|
||||||
// would shift start frequency below minimum
|
// would shift start frequency below minimum
|
||||||
settings.Freq.start = 0;
|
settings.Freq.start = 0;
|
||||||
settings.Freq.stop = 2 * freq;
|
settings.Freq.stop = 2 * freq;
|
||||||
} else if(freq + old_span / 2 >= Device::Info().limits_maxFreq) {
|
} else if(freq + old_span / 2 >= Device::Info(window->getDevice()).limits_maxFreq) {
|
||||||
// would shift stop frequency above maximum
|
// would shift stop frequency above maximum
|
||||||
settings.Freq.start = 2 * freq - Device::Info().limits_maxFreq;
|
settings.Freq.start = 2 * freq - Device::Info(window->getDevice()).limits_maxFreq;
|
||||||
settings.Freq.stop = Device::Info().limits_maxFreq;
|
settings.Freq.stop = Device::Info(window->getDevice()).limits_maxFreq;
|
||||||
} else {
|
} else {
|
||||||
settings.Freq.start = freq - old_span / 2;
|
settings.Freq.start = freq - old_span / 2;
|
||||||
settings.Freq.stop = freq + old_span / 2;
|
settings.Freq.stop = freq + old_span / 2;
|
||||||
@ -1014,12 +1018,12 @@ void VNA::SetCenterFreq(double freq)
|
|||||||
|
|
||||||
void VNA::SetSpan(double span)
|
void VNA::SetSpan(double span)
|
||||||
{
|
{
|
||||||
auto maxFreq = Preferences::getInstance().Acquisition.harmonicMixing ? Device::Info().limits_maxFreqHarmonic : Device::Info().limits_maxFreq;
|
auto maxFreq = Preferences::getInstance().Acquisition.harmonicMixing ? Device::Info(window->getDevice()).limits_maxFreqHarmonic : Device::Info(window->getDevice()).limits_maxFreq;
|
||||||
auto old_center = (settings.Freq.start + settings.Freq.stop) / 2;
|
auto old_center = (settings.Freq.start + settings.Freq.stop) / 2;
|
||||||
if(old_center < Device::Info().limits_minFreq + span / 2) {
|
if(old_center < Device::Info(window->getDevice()).limits_minFreq + span / 2) {
|
||||||
// would shift start frequency below minimum
|
// would shift start frequency below minimum
|
||||||
settings.Freq.start = Device::Info().limits_minFreq;
|
settings.Freq.start = Device::Info(window->getDevice()).limits_minFreq;
|
||||||
settings.Freq.stop = Device::Info().limits_minFreq + span;
|
settings.Freq.stop = Device::Info(window->getDevice()).limits_minFreq + span;
|
||||||
} else if(old_center > maxFreq - span / 2) {
|
} else if(old_center > maxFreq - span / 2) {
|
||||||
// would shift stop frequency above maximum
|
// would shift stop frequency above maximum
|
||||||
settings.Freq.start = maxFreq - span;
|
settings.Freq.start = maxFreq - span;
|
||||||
@ -1033,8 +1037,8 @@ void VNA::SetSpan(double span)
|
|||||||
|
|
||||||
void VNA::SetFullSpan()
|
void VNA::SetFullSpan()
|
||||||
{
|
{
|
||||||
settings.Freq.start = Device::Info().limits_minFreq;
|
settings.Freq.start = Device::Info(window->getDevice()).limits_minFreq;
|
||||||
settings.Freq.stop = Device::Info().limits_maxFreq;
|
settings.Freq.stop = Device::Info(window->getDevice()).limits_maxFreq;
|
||||||
ConstrainAndUpdateFrequencies();
|
ConstrainAndUpdateFrequencies();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1072,10 +1076,10 @@ void VNA::SetLogSweep(bool log)
|
|||||||
|
|
||||||
void VNA::SetSourceLevel(double level)
|
void VNA::SetSourceLevel(double level)
|
||||||
{
|
{
|
||||||
if(level > Device::Info().limits_cdbm_max / 100.0) {
|
if(level > Device::Info(window->getDevice()).limits_cdbm_max / 100.0) {
|
||||||
level = Device::Info().limits_cdbm_max / 100.0;
|
level = Device::Info(window->getDevice()).limits_cdbm_max / 100.0;
|
||||||
} else if(level < Device::Info().limits_cdbm_min / 100.0) {
|
} else if(level < Device::Info(window->getDevice()).limits_cdbm_min / 100.0) {
|
||||||
level = Device::Info().limits_cdbm_min / 100.0;
|
level = Device::Info(window->getDevice()).limits_cdbm_min / 100.0;
|
||||||
}
|
}
|
||||||
emit sourceLevelChanged(level);
|
emit sourceLevelChanged(level);
|
||||||
settings.Freq.excitation_power = level;
|
settings.Freq.excitation_power = level;
|
||||||
@ -1105,15 +1109,15 @@ void VNA::SetPowerSweepFrequency(double freq)
|
|||||||
|
|
||||||
void VNA::SetPoints(unsigned int points)
|
void VNA::SetPoints(unsigned int points)
|
||||||
{
|
{
|
||||||
unsigned int maxPoints = Preferences::getInstance().Acquisition.allowSegmentedSweep ? UINT16_MAX : Device::Info().limits_maxPoints;
|
unsigned int maxPoints = Preferences::getInstance().Acquisition.allowSegmentedSweep ? UINT16_MAX : Device::Info(window->getDevice()).limits_maxPoints;
|
||||||
if(points > maxPoints) {
|
if(points > maxPoints) {
|
||||||
points = maxPoints;
|
points = maxPoints;
|
||||||
} else if (points < 2) {
|
} else if (points < 2) {
|
||||||
points = 2;
|
points = 2;
|
||||||
}
|
}
|
||||||
if (points > Device::Info().limits_maxPoints) {
|
if (points > Device::Info(window->getDevice()).limits_maxPoints) {
|
||||||
// needs segmented sweep
|
// needs segmented sweep
|
||||||
settings.segments = ceil((double) points / Device::Info().limits_maxPoints);
|
settings.segments = ceil((double) points / Device::Info(window->getDevice()).limits_maxPoints);
|
||||||
settings.activeSegment = 0;
|
settings.activeSegment = 0;
|
||||||
} else {
|
} else {
|
||||||
// can fit all points into one segment
|
// can fit all points into one segment
|
||||||
@ -1127,10 +1131,10 @@ void VNA::SetPoints(unsigned int points)
|
|||||||
|
|
||||||
void VNA::SetIFBandwidth(double bandwidth)
|
void VNA::SetIFBandwidth(double bandwidth)
|
||||||
{
|
{
|
||||||
if(bandwidth > Device::Info().limits_maxIFBW) {
|
if(bandwidth > Device::Info(window->getDevice()).limits_maxIFBW) {
|
||||||
bandwidth = Device::Info().limits_maxIFBW;
|
bandwidth = Device::Info(window->getDevice()).limits_maxIFBW;
|
||||||
} else if(bandwidth < Device::Info().limits_minIFBW) {
|
} else if(bandwidth < Device::Info(window->getDevice()).limits_minIFBW) {
|
||||||
bandwidth = Device::Info().limits_minIFBW;
|
bandwidth = Device::Info(window->getDevice()).limits_minIFBW;
|
||||||
}
|
}
|
||||||
settings.bandwidth = bandwidth;
|
settings.bandwidth = bandwidth;
|
||||||
emit IFBandwidthChanged(settings.bandwidth);
|
emit IFBandwidthChanged(settings.bandwidth);
|
||||||
@ -1478,9 +1482,9 @@ void VNA::ConstrainAndUpdateFrequencies()
|
|||||||
auto pref = Preferences::getInstance();
|
auto pref = Preferences::getInstance();
|
||||||
double maxFreq;
|
double maxFreq;
|
||||||
if(pref.Acquisition.harmonicMixing) {
|
if(pref.Acquisition.harmonicMixing) {
|
||||||
maxFreq = Device::Info().limits_maxFreqHarmonic;
|
maxFreq = Device::Info(window->getDevice()).limits_maxFreqHarmonic;
|
||||||
} else {
|
} else {
|
||||||
maxFreq = Device::Info().limits_maxFreq;
|
maxFreq = Device::Info(window->getDevice()).limits_maxFreq;
|
||||||
}
|
}
|
||||||
if(settings.Freq.stop > maxFreq) {
|
if(settings.Freq.stop > maxFreq) {
|
||||||
settings.Freq.stop = maxFreq;
|
settings.Freq.stop = maxFreq;
|
||||||
@ -1488,8 +1492,8 @@ void VNA::ConstrainAndUpdateFrequencies()
|
|||||||
if(settings.Freq.start > settings.Freq.stop) {
|
if(settings.Freq.start > settings.Freq.stop) {
|
||||||
settings.Freq.start = settings.Freq.stop;
|
settings.Freq.start = settings.Freq.stop;
|
||||||
}
|
}
|
||||||
if(settings.Freq.start < Device::Info().limits_minFreq) {
|
if(settings.Freq.start < Device::Info(window->getDevice()).limits_minFreq) {
|
||||||
settings.Freq.start = Device::Info().limits_minFreq;
|
settings.Freq.start = Device::Info(window->getDevice()).limits_minFreq;
|
||||||
}
|
}
|
||||||
emit startFreqChanged(settings.Freq.start);
|
emit startFreqChanged(settings.Freq.start);
|
||||||
emit stopFreqChanged(settings.Freq.stop);
|
emit stopFreqChanged(settings.Freq.stop);
|
||||||
|
@ -13,17 +13,19 @@
|
|||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
class VNA : public Mode, public SCPINode
|
class VNA : public Mode
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
VNA(AppWindow *window);
|
VNA(AppWindow *window, QString name = "Vector Network Analyzer");
|
||||||
|
|
||||||
void deactivate() override;
|
void deactivate() override;
|
||||||
void initializeDevice() override;
|
void initializeDevice() override;
|
||||||
void deviceDisconnected() override;
|
void deviceDisconnected() override;
|
||||||
void shutdown() override;
|
void shutdown() override;
|
||||||
|
|
||||||
|
virtual Type getType() override { return Type::VNA;}
|
||||||
|
|
||||||
// Only save/load user changeable stuff, no need to save the widgets/mode name etc.
|
// Only save/load user changeable stuff, no need to save the widgets/mode name etc.
|
||||||
virtual nlohmann::json toJSON() override;
|
virtual nlohmann::json toJSON() override;
|
||||||
virtual void fromJSON(nlohmann::json j) override;
|
virtual void fromJSON(nlohmann::json j) override;
|
||||||
|
@ -134,9 +134,9 @@ AppWindow::AppWindow(QWidget *parent)
|
|||||||
// Create GUI modes
|
// Create GUI modes
|
||||||
central = new QStackedWidget;
|
central = new QStackedWidget;
|
||||||
setCentralWidget(central);
|
setCentralWidget(central);
|
||||||
vna = new VNA(this);
|
auto vna = new VNA(this);
|
||||||
generator = new Generator(this);
|
auto generator = new Generator(this);
|
||||||
spectrumAnalyzer = new SpectrumAnalyzer(this);
|
auto spectrumAnalyzer = new SpectrumAnalyzer(this);
|
||||||
|
|
||||||
// UI connections
|
// UI connections
|
||||||
connect(ui->actionUpdate_Device_List, &QAction::triggered, this, &AppWindow::UpdateDeviceList);
|
connect(ui->actionUpdate_Device_List, &QAction::triggered, this, &AppWindow::UpdateDeviceList);
|
||||||
@ -235,7 +235,7 @@ AppWindow::AppWindow(QWidget *parent)
|
|||||||
vna->activate();
|
vna->activate();
|
||||||
|
|
||||||
qRegisterMetaType<Protocol::Datapoint>("Datapoint");
|
qRegisterMetaType<Protocol::Datapoint>("Datapoint");
|
||||||
qRegisterMetaType<Protocol::ManualStatus>("Manual");
|
qRegisterMetaType<Protocol::ManualStatusV1>("ManualV1");
|
||||||
qRegisterMetaType<Protocol::SpectrumAnalyzerResult>("SpectrumAnalyzerResult");
|
qRegisterMetaType<Protocol::SpectrumAnalyzerResult>("SpectrumAnalyzerResult");
|
||||||
qRegisterMetaType<Protocol::AmplitudeCorrectionPoint>("AmplitudeCorrection");
|
qRegisterMetaType<Protocol::AmplitudeCorrectionPoint>("AmplitudeCorrection");
|
||||||
|
|
||||||
@ -278,9 +278,9 @@ void AppWindow::closeEvent(QCloseEvent *event)
|
|||||||
if(pref.Startup.UseSetupFile && pref.Startup.AutosaveSetupFile) {
|
if(pref.Startup.UseSetupFile && pref.Startup.AutosaveSetupFile) {
|
||||||
SaveSetup(pref.Startup.SetupFile);
|
SaveSetup(pref.Startup.SetupFile);
|
||||||
}
|
}
|
||||||
vna->shutdown();
|
for(auto m : Mode::getModes()) {
|
||||||
generator->shutdown();
|
m->shutdown();
|
||||||
spectrumAnalyzer->shutdown();
|
}
|
||||||
delete device;
|
delete device;
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
settings.setValue("geometry", saveGeometry());
|
settings.setValue("geometry", saveGeometry());
|
||||||
@ -309,7 +309,7 @@ bool AppWindow::ConnectToDevice(QString serial)
|
|||||||
UpdateStatusBar(AppWindow::DeviceStatusBar::Connected);
|
UpdateStatusBar(AppWindow::DeviceStatusBar::Connected);
|
||||||
connect(device, &Device::LogLineReceived, &deviceLog, &DeviceLog::addLine);
|
connect(device, &Device::LogLineReceived, &deviceLog, &DeviceLog::addLine);
|
||||||
connect(device, &Device::ConnectionLost, this, &AppWindow::DeviceConnectionLost);
|
connect(device, &Device::ConnectionLost, this, &AppWindow::DeviceConnectionLost);
|
||||||
connect(device, &Device::DeviceInfoUpdated, this, &AppWindow::DeviceInfoUpdated);
|
connect(device, &Device::DeviceStatusUpdated, this, &AppWindow::DeviceStatusUpdated);
|
||||||
connect(device, &Device::NeedsFirmwareUpdate, this, &AppWindow::DeviceNeedsUpdate);
|
connect(device, &Device::NeedsFirmwareUpdate, this, &AppWindow::DeviceNeedsUpdate);
|
||||||
ui->actionDisconnect->setEnabled(true);
|
ui->actionDisconnect->setEnabled(true);
|
||||||
ui->actionManual_Control->setEnabled(true);
|
ui->actionManual_Control->setEnabled(true);
|
||||||
@ -465,7 +465,7 @@ void AppWindow::SetupSCPI()
|
|||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}, [=](QStringList) -> QString {
|
}, [=](QStringList) -> QString {
|
||||||
switch(Device::Info().extRefInUse) {
|
switch(Device::StatusV1(getDevice()).extRefInUse) {
|
||||||
case 0: return "INT";
|
case 0: return "INT";
|
||||||
case 1: return "EXT";
|
case 1: return "EXT";
|
||||||
default: return "ERROR";
|
default: return "ERROR";
|
||||||
@ -475,88 +475,89 @@ void AppWindow::SetupSCPI()
|
|||||||
if (params.size() != 1) {
|
if (params.size() != 1) {
|
||||||
return "ERROR";
|
return "ERROR";
|
||||||
}
|
}
|
||||||
|
Mode *mode = nullptr;
|
||||||
if (params[0] == "VNA") {
|
if (params[0] == "VNA") {
|
||||||
vna->activate();
|
mode = Mode::findFirstOfType(Mode::Type::VNA);
|
||||||
} else if(params[0] == "GEN") {
|
} else if(params[0] == "GEN") {
|
||||||
generator->activate();
|
mode = Mode::findFirstOfType(Mode::Type::SG);
|
||||||
} else if(params[0] == "SA") {
|
} else if(params[0] == "SA") {
|
||||||
spectrumAnalyzer->activate();
|
mode = Mode::findFirstOfType(Mode::Type::SA);
|
||||||
} else {
|
} else {
|
||||||
return "INVALID MDOE";
|
return "INVALID MDOE";
|
||||||
}
|
}
|
||||||
return "";
|
if(mode) {
|
||||||
}, [=](QStringList) -> QString {
|
mode->activate();
|
||||||
auto active = Mode::getActiveMode();
|
return "";
|
||||||
if(active == vna) {
|
|
||||||
return "VNA";
|
|
||||||
} else if(active == generator) {
|
|
||||||
return "GEN";
|
|
||||||
} else if(active == spectrumAnalyzer) {
|
|
||||||
return "SA";
|
|
||||||
} else {
|
} else {
|
||||||
return "ERROR";
|
return "ERROR";
|
||||||
}
|
}
|
||||||
|
}, [=](QStringList) -> QString {
|
||||||
|
auto active = Mode::getActiveMode();
|
||||||
|
if(active) {
|
||||||
|
switch(active->getType()) {
|
||||||
|
case Mode::Type::VNA: return "VNA";
|
||||||
|
case Mode::Type::SG: return "SG";
|
||||||
|
case Mode::Type::SA: return "SA";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "ERROR";
|
||||||
}));
|
}));
|
||||||
auto scpi_status = new SCPINode("STAtus");
|
auto scpi_status = new SCPINode("STAtus");
|
||||||
scpi_dev->add(scpi_status);
|
scpi_dev->add(scpi_status);
|
||||||
scpi_status->add(new SCPICommand("UNLOcked", nullptr, [=](QStringList){
|
scpi_status->add(new SCPICommand("UNLOcked", nullptr, [=](QStringList){
|
||||||
bool locked = Device::Info().source_locked && Device::Info().LO1_locked;
|
bool locked = Device::StatusV1(getDevice()).source_locked && Device::StatusV1(getDevice()).LO1_locked;
|
||||||
return locked ? "FALSE" : "TRUE";
|
return locked ? "FALSE" : "TRUE";
|
||||||
}));
|
}));
|
||||||
scpi_status->add(new SCPICommand("ADCOVERload", nullptr, [=](QStringList){
|
scpi_status->add(new SCPICommand("ADCOVERload", nullptr, [=](QStringList){
|
||||||
return Device::Info().ADC_overload ? "TRUE" : "FALSE";
|
return Device::StatusV1(getDevice()).ADC_overload ? "TRUE" : "FALSE";
|
||||||
}));
|
}));
|
||||||
scpi_status->add(new SCPICommand("UNLEVel", nullptr, [=](QStringList){
|
scpi_status->add(new SCPICommand("UNLEVel", nullptr, [=](QStringList){
|
||||||
return Device::Info().unlevel ? "TRUE" : "FALSE";
|
return Device::StatusV1(getDevice()).unlevel ? "TRUE" : "FALSE";
|
||||||
}));
|
}));
|
||||||
auto scpi_info = new SCPINode("INFo");
|
auto scpi_info = new SCPINode("INFo");
|
||||||
scpi_dev->add(scpi_info);
|
scpi_dev->add(scpi_info);
|
||||||
scpi_info->add(new SCPICommand("FWREVision", nullptr, [=](QStringList){
|
scpi_info->add(new SCPICommand("FWREVision", nullptr, [=](QStringList){
|
||||||
return QString::number(Device::Info().FW_major)+"."+QString::number(Device::Info().FW_minor)+"."+QString::number(Device::Info().FW_patch);
|
return QString::number(Device::Info(getDevice()).FW_major)+"."+QString::number(Device::Info(getDevice()).FW_minor)+"."+QString::number(Device::Info(getDevice()).FW_patch);
|
||||||
}));
|
}));
|
||||||
scpi_info->add(new SCPICommand("HWREVision", nullptr, [=](QStringList){
|
scpi_info->add(new SCPICommand("HWREVision", nullptr, [=](QStringList){
|
||||||
return QString(Device::Info().HW_Revision);
|
return QString(Device::Info(getDevice()).HW_Revision);
|
||||||
}));
|
}));
|
||||||
scpi_info->add(new SCPICommand("TEMPeratures", nullptr, [=](QStringList){
|
scpi_info->add(new SCPICommand("TEMPeratures", nullptr, [=](QStringList){
|
||||||
return QString::number(Device::Info().temp_source)+"/"+QString::number(Device::Info().temp_LO1)+"/"+QString::number(Device::Info().temp_MCU);
|
return QString::number(Device::StatusV1(getDevice()).temp_source)+"/"+QString::number(Device::StatusV1(getDevice()).temp_LO1)+"/"+QString::number(Device::StatusV1(getDevice()).temp_MCU);
|
||||||
}));
|
}));
|
||||||
auto scpi_limits = new SCPINode("LIMits");
|
auto scpi_limits = new SCPINode("LIMits");
|
||||||
scpi_info->add(scpi_limits);
|
scpi_info->add(scpi_limits);
|
||||||
scpi_limits->add(new SCPICommand("MINFrequency", nullptr, [=](QStringList){
|
scpi_limits->add(new SCPICommand("MINFrequency", nullptr, [=](QStringList){
|
||||||
return QString::number(Device::Info().limits_minFreq);
|
return QString::number(Device::Info(getDevice()).limits_minFreq);
|
||||||
}));
|
}));
|
||||||
scpi_limits->add(new SCPICommand("MAXFrequency", nullptr, [=](QStringList){
|
scpi_limits->add(new SCPICommand("MAXFrequency", nullptr, [=](QStringList){
|
||||||
return QString::number(Device::Info().limits_maxFreq);
|
return QString::number(Device::Info(getDevice()).limits_maxFreq);
|
||||||
}));
|
}));
|
||||||
scpi_limits->add(new SCPICommand("MINIFBW", nullptr, [=](QStringList){
|
scpi_limits->add(new SCPICommand("MINIFBW", nullptr, [=](QStringList){
|
||||||
return QString::number(Device::Info().limits_minIFBW);
|
return QString::number(Device::Info(getDevice()).limits_minIFBW);
|
||||||
}));
|
}));
|
||||||
scpi_limits->add(new SCPICommand("MAXIFBW", nullptr, [=](QStringList){
|
scpi_limits->add(new SCPICommand("MAXIFBW", nullptr, [=](QStringList){
|
||||||
return QString::number(Device::Info().limits_maxIFBW);
|
return QString::number(Device::Info(getDevice()).limits_maxIFBW);
|
||||||
}));
|
}));
|
||||||
scpi_limits->add(new SCPICommand("MAXPoints", nullptr, [=](QStringList){
|
scpi_limits->add(new SCPICommand("MAXPoints", nullptr, [=](QStringList){
|
||||||
return QString::number(Device::Info().limits_maxPoints);
|
return QString::number(Device::Info(getDevice()).limits_maxPoints);
|
||||||
}));
|
}));
|
||||||
scpi_limits->add(new SCPICommand("MINPOWer", nullptr, [=](QStringList){
|
scpi_limits->add(new SCPICommand("MINPOWer", nullptr, [=](QStringList){
|
||||||
return QString::number(Device::Info().limits_cdbm_min / 100.0);
|
return QString::number(Device::Info(getDevice()).limits_cdbm_min / 100.0);
|
||||||
}));
|
}));
|
||||||
scpi_limits->add(new SCPICommand("MAXPOWer", nullptr, [=](QStringList){
|
scpi_limits->add(new SCPICommand("MAXPOWer", nullptr, [=](QStringList){
|
||||||
return QString::number(Device::Info().limits_cdbm_max / 100.0);
|
return QString::number(Device::Info(getDevice()).limits_cdbm_max / 100.0);
|
||||||
}));
|
}));
|
||||||
scpi_limits->add(new SCPICommand("MINRBW", nullptr, [=](QStringList){
|
scpi_limits->add(new SCPICommand("MINRBW", nullptr, [=](QStringList){
|
||||||
return QString::number(Device::Info().limits_minRBW);
|
return QString::number(Device::Info(getDevice()).limits_minRBW);
|
||||||
}));
|
}));
|
||||||
scpi_limits->add(new SCPICommand("MAXRBW", nullptr, [=](QStringList){
|
scpi_limits->add(new SCPICommand("MAXRBW", nullptr, [=](QStringList){
|
||||||
return QString::number(Device::Info().limits_maxRBW);
|
return QString::number(Device::Info(getDevice()).limits_maxRBW);
|
||||||
}));
|
}));
|
||||||
scpi_limits->add(new SCPICommand("MAXHARMonicfrequency", nullptr, [=](QStringList){
|
scpi_limits->add(new SCPICommand("MAXHARMonicfrequency", nullptr, [=](QStringList){
|
||||||
return QString::number(Device::Info().limits_maxFreqHarmonic);
|
return QString::number(Device::Info(getDevice()).limits_maxFreqHarmonic);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
scpi.add(vna);
|
|
||||||
scpi.add(generator);
|
|
||||||
scpi.add(spectrumAnalyzer);
|
|
||||||
|
|
||||||
auto scpi_manual = new SCPINode("MANual");
|
auto scpi_manual = new SCPINode("MANual");
|
||||||
scpi_manual->add(new SCPICommand("STArt",[=](QStringList) -> QString {
|
scpi_manual->add(new SCPICommand("STArt",[=](QStringList) -> QString {
|
||||||
StartManualControl();
|
StartManualControl();
|
||||||
@ -798,6 +799,11 @@ void AppWindow::StopTCPServer()
|
|||||||
server = nullptr;
|
server = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SCPI* AppWindow::getSCPI()
|
||||||
|
{
|
||||||
|
return &scpi;
|
||||||
|
}
|
||||||
|
|
||||||
int AppWindow::UpdateDeviceList()
|
int AppWindow::UpdateDeviceList()
|
||||||
{
|
{
|
||||||
deviceActionGroup->setExclusive(true);
|
deviceActionGroup->setExclusive(true);
|
||||||
@ -918,7 +924,7 @@ void AppWindow::DeviceNeedsUpdate(int reported, int expected)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppWindow::DeviceInfoUpdated()
|
void AppWindow::DeviceStatusUpdated()
|
||||||
{
|
{
|
||||||
UpdateStatusBar(DeviceStatusBar::Updated);
|
UpdateStatusBar(DeviceStatusBar::Updated);
|
||||||
}
|
}
|
||||||
@ -963,10 +969,18 @@ void AppWindow::SaveSetup(QString filename)
|
|||||||
nlohmann::json AppWindow::SaveSetup()
|
nlohmann::json AppWindow::SaveSetup()
|
||||||
{
|
{
|
||||||
nlohmann::json j;
|
nlohmann::json j;
|
||||||
j["activeMode"] = Mode::getActiveMode()->getName().toStdString();
|
nlohmann::json jm;
|
||||||
j["VNA"] = vna->toJSON();
|
for(auto m : Mode::getModes()) {
|
||||||
j["Generator"] = generator->toJSON();
|
nlohmann::json jmode;
|
||||||
j["SpectrumAnalyzer"] = spectrumAnalyzer->toJSON();
|
jmode["type"] = Mode::TypeToName(m->getType()).toStdString();
|
||||||
|
jmode["name"] = m->getName().toStdString();
|
||||||
|
jmode["settings"] = m->toJSON();
|
||||||
|
jm.push_back(jmode);
|
||||||
|
}
|
||||||
|
j["Modes"] = jm;
|
||||||
|
if(Mode::getActiveMode()) {
|
||||||
|
j["activeMode"] = Mode::getActiveMode()->getName().toStdString();
|
||||||
|
}
|
||||||
nlohmann::json ref;
|
nlohmann::json ref;
|
||||||
ref["Mode"] = toolbars.reference.type->currentText().toStdString();
|
ref["Mode"] = toolbars.reference.type->currentText().toStdString();
|
||||||
ref["Output"] = toolbars.reference.outFreq->currentText().toStdString();
|
ref["Output"] = toolbars.reference.outFreq->currentText().toStdString();
|
||||||
@ -1003,20 +1017,36 @@ void AppWindow::LoadSetup(nlohmann::json j)
|
|||||||
toolbars.reference.type->setCurrentText(QString::fromStdString(j["Reference"].value("Mode", "Int")));
|
toolbars.reference.type->setCurrentText(QString::fromStdString(j["Reference"].value("Mode", "Int")));
|
||||||
toolbars.reference.outFreq->setCurrentText(QString::fromStdString(j["Reference"].value("Output", "Off")));
|
toolbars.reference.outFreq->setCurrentText(QString::fromStdString(j["Reference"].value("Output", "Off")));
|
||||||
}
|
}
|
||||||
|
while(Mode::getModes().size() > 0) {
|
||||||
|
delete Mode::getModes()[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// old style VNA/Generator/Spectrum Analyzer settings
|
||||||
if(j.contains("VNA")) {
|
if(j.contains("VNA")) {
|
||||||
|
auto vna = new VNA(this);
|
||||||
vna->fromJSON(j["VNA"]);
|
vna->fromJSON(j["VNA"]);
|
||||||
}
|
}
|
||||||
if(j.contains("Generator")) {
|
if(j.contains("Generator")) {
|
||||||
|
auto generator = new Generator(this);
|
||||||
generator->fromJSON(j["Generator"]);
|
generator->fromJSON(j["Generator"]);
|
||||||
}
|
}
|
||||||
if(j.contains("SpectrumAnalyzer")) {
|
if(j.contains("SpectrumAnalyzer")) {
|
||||||
|
auto spectrumAnalyzer = new SpectrumAnalyzer(this);
|
||||||
spectrumAnalyzer->fromJSON(j["SpectrumAnalyzer"]);
|
spectrumAnalyzer->fromJSON(j["SpectrumAnalyzer"]);
|
||||||
}
|
}
|
||||||
|
if(j.contains("Modes")) {
|
||||||
|
for(auto jm : j["Modes"]) {
|
||||||
|
auto type = Mode::TypeFromName(QString::fromStdString(jm.value("type", "Invalid")));
|
||||||
|
if(type != Mode::Type::Last && jm.contains("settings")) {
|
||||||
|
auto m = Mode::createNew(this, QString::fromStdString(jm.value("name", "")), type);
|
||||||
|
m->fromJSON(jm["settings"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// activate the correct mode
|
// activate the correct mode
|
||||||
QString modeName = QString::fromStdString(j.value("activeMode", ""));
|
QString modeName = QString::fromStdString(j.value("activeMode", ""));
|
||||||
std::vector<Mode*> modes = {vna, generator, spectrumAnalyzer};
|
for(auto m : Mode::getModes()) {
|
||||||
for(auto m : modes) {
|
|
||||||
if(m->getName() == modeName) {
|
if(m->getName() == modeName) {
|
||||||
m->activate();
|
m->activate();
|
||||||
break;
|
break;
|
||||||
@ -1024,7 +1054,7 @@ void AppWindow::LoadSetup(nlohmann::json j)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Device *AppWindow::getDevice() const
|
Device *&AppWindow::getDevice()
|
||||||
{
|
{
|
||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
@ -1104,14 +1134,12 @@ void AppWindow::UpdateStatusBar(DeviceStatusBar status)
|
|||||||
break;
|
break;
|
||||||
case DeviceStatusBar::Updated:
|
case DeviceStatusBar::Updated:
|
||||||
lDeviceInfo.setText(device->getLastDeviceInfoString());
|
lDeviceInfo.setText(device->getLastDeviceInfoString());
|
||||||
lADCOverload.setVisible(device->Info().ADC_overload);
|
lADCOverload.setVisible(device->StatusV1().ADC_overload);
|
||||||
lUnlevel.setVisible(device->Info().unlevel);
|
lUnlevel.setVisible(device->StatusV1().unlevel);
|
||||||
lUnlock.setVisible(!device->Info().LO1_locked || !device->Info().source_locked);
|
lUnlock.setVisible(!device->StatusV1().LO1_locked || !device->StatusV1().source_locked);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// invalid status
|
// invalid status
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -41,13 +41,15 @@ public:
|
|||||||
|
|
||||||
Ui::MainWindow *getUi() const;
|
Ui::MainWindow *getUi() const;
|
||||||
QStackedWidget *getCentral() const;
|
QStackedWidget *getCentral() const;
|
||||||
Device *getDevice() const;
|
Device*&getDevice();
|
||||||
|
|
||||||
const QString& getAppVersion() const;
|
const QString& getAppVersion() const;
|
||||||
const QString& getAppGitHash() const;
|
const QString& getAppGitHash() const;
|
||||||
|
|
||||||
static bool showGUI();
|
static bool showGUI();
|
||||||
|
|
||||||
|
SCPI* getSCPI();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void closeEvent(QCloseEvent *event) override;
|
void closeEvent(QCloseEvent *event) override;
|
||||||
private slots:
|
private slots:
|
||||||
@ -59,7 +61,7 @@ private slots:
|
|||||||
void UpdateAcquisitionFrequencies();
|
void UpdateAcquisitionFrequencies();
|
||||||
void StartFirmwareUpdateDialog();
|
void StartFirmwareUpdateDialog();
|
||||||
void DeviceNeedsUpdate(int reported, int expected);
|
void DeviceNeedsUpdate(int reported, int expected);
|
||||||
void DeviceInfoUpdated();
|
void DeviceStatusUpdated();
|
||||||
void SourceCalibrationDialog();
|
void SourceCalibrationDialog();
|
||||||
void ReceiverCalibrationDialog();
|
void ReceiverCalibrationDialog();
|
||||||
void FrequencyCalibrationDialog();
|
void FrequencyCalibrationDialog();
|
||||||
@ -100,11 +102,6 @@ private:
|
|||||||
|
|
||||||
ManualControlDialog *manual;
|
ManualControlDialog *manual;
|
||||||
|
|
||||||
// Modes
|
|
||||||
VNA *vna;
|
|
||||||
Generator *generator;
|
|
||||||
SpectrumAnalyzer *spectrumAnalyzer;
|
|
||||||
|
|
||||||
// Status bar widgets
|
// Status bar widgets
|
||||||
QLabel lConnectionStatus;
|
QLabel lConnectionStatus;
|
||||||
QLabel lDeviceInfo;
|
QLabel lDeviceInfo;
|
||||||
|
@ -1,44 +1,115 @@
|
|||||||
#include "mode.h"
|
#include "mode.h"
|
||||||
|
|
||||||
|
#include "Generator/generator.h"
|
||||||
|
#include "VNA/vna.h"
|
||||||
|
#include "SpectrumAnalyzer/spectrumanalyzer.h"
|
||||||
|
#include "CustomWidgets/informationbox.h"
|
||||||
|
|
||||||
#include "ui_main.h"
|
#include "ui_main.h"
|
||||||
|
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
|
#include <QInputDialog>
|
||||||
|
|
||||||
|
std::vector<Mode*> Mode::modes;
|
||||||
Mode* Mode::activeMode = nullptr;
|
Mode* Mode::activeMode = nullptr;
|
||||||
|
QTabBar* Mode::tabbar = nullptr;
|
||||||
QWidget* Mode::cornerWidget = nullptr;
|
QWidget* Mode::cornerWidget = nullptr;
|
||||||
QButtonGroup* Mode::modeButtonGroup = nullptr;
|
//QButtonGroup* Mode::modeButtonGroup = nullptr;
|
||||||
|
|
||||||
Mode::Mode(AppWindow *window, QString name)
|
Mode::Mode(AppWindow *window, QString name, QString SCPIname)
|
||||||
: QObject(window),
|
: QObject(window),
|
||||||
|
SCPINode(SCPIname),
|
||||||
window(window),
|
window(window),
|
||||||
name(name),
|
name(name),
|
||||||
central(nullptr)
|
central(nullptr)
|
||||||
{
|
{
|
||||||
|
if(!nameAllowed(name)) {
|
||||||
|
throw std::runtime_error("Unable to create mode, name already taken");
|
||||||
|
}
|
||||||
// Create mode switch button
|
// Create mode switch button
|
||||||
auto modeSwitch = new QPushButton(name);
|
|
||||||
modeSwitch->setCheckable(true);
|
|
||||||
modeSwitch->setMaximumHeight(window->menuBar()->height());
|
|
||||||
if(!cornerWidget) {
|
if(!cornerWidget) {
|
||||||
// this is the first created mode, initialize corner widget and set this mode as active
|
// this is the first created mode, initialize corner widget and set this mode as active
|
||||||
modeSwitch->setChecked(true);
|
cornerWidget = new QWidget();
|
||||||
cornerWidget = new QWidget;
|
|
||||||
cornerWidget->setLayout(new QHBoxLayout);
|
cornerWidget->setLayout(new QHBoxLayout);
|
||||||
cornerWidget->layout()->setSpacing(0);
|
cornerWidget->layout()->setSpacing(0);
|
||||||
cornerWidget->layout()->setMargin(0);
|
cornerWidget->layout()->setMargin(0);
|
||||||
cornerWidget->layout()->setContentsMargins(0,0,0,0);
|
cornerWidget->layout()->setContentsMargins(0,0,0,0);
|
||||||
window->menuBar()->setCornerWidget(cornerWidget);
|
cornerWidget->setMaximumHeight(window->menuBar()->height());
|
||||||
modeButtonGroup = new QButtonGroup;
|
|
||||||
// window->menuBar()->setMaximumHeight(window->menuBar()->height());
|
|
||||||
}
|
|
||||||
cornerWidget->layout()->addWidget(modeSwitch);
|
|
||||||
modeButtonGroup->addButton(modeSwitch);
|
|
||||||
|
|
||||||
connect(modeSwitch, &QPushButton::clicked, [=](){
|
tabbar = new QTabBar;
|
||||||
activate();
|
tabbar->setTabsClosable(true);
|
||||||
});
|
tabbar->setStyleSheet("QTabBar::tab { height: "+QString::number(window->menuBar()->height())+"px;}");
|
||||||
|
cornerWidget->layout()->addWidget(tabbar);
|
||||||
|
|
||||||
|
auto bAdd = new QPushButton();
|
||||||
|
QIcon icon;
|
||||||
|
QString iconThemeName = QString::fromUtf8("list-add");
|
||||||
|
if (QIcon::hasThemeIcon(iconThemeName)) {
|
||||||
|
icon = QIcon::fromTheme(iconThemeName);
|
||||||
|
} else {
|
||||||
|
icon.addFile(QString::fromUtf8(":/icons/add.png"), QSize(), QIcon::Normal, QIcon::Off);
|
||||||
|
}
|
||||||
|
bAdd->setIcon(icon);
|
||||||
|
|
||||||
|
auto mAdd = new QMenu();
|
||||||
|
for(unsigned int i=0;i<(int) Type::Last;i++) {
|
||||||
|
auto type = (Type) i;
|
||||||
|
auto action = new QAction(TypeToName(type));
|
||||||
|
mAdd->addAction(action);
|
||||||
|
connect(action, &QAction::triggered, [=](){
|
||||||
|
bool ok;
|
||||||
|
QString text = QInputDialog::getText(window, "Create new "+TypeToName(type)+" tab",
|
||||||
|
"Name:", QLineEdit::Normal,
|
||||||
|
TypeToName(type), &ok);
|
||||||
|
if(ok) {
|
||||||
|
if(!nameAllowed(text)) {
|
||||||
|
InformationBox::ShowError("Name collision", "Unable to create tab, no duplicate names allowed");
|
||||||
|
} else {
|
||||||
|
auto mode = Mode::createNew(window, text, type);
|
||||||
|
mode->activate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
bAdd->setMenu(mAdd);
|
||||||
|
bAdd->setMaximumHeight(window->menuBar()->height());
|
||||||
|
bAdd->setMaximumWidth(40);
|
||||||
|
cornerWidget->layout()->addWidget(bAdd);
|
||||||
|
|
||||||
|
window->menuBar()->setCornerWidget(cornerWidget);
|
||||||
|
|
||||||
|
connect(tabbar, &QTabBar::currentChanged, [=](int index){
|
||||||
|
modes[index]->activate();
|
||||||
|
});
|
||||||
|
connect(tabbar, &QTabBar::tabCloseRequested, [=](int index){
|
||||||
|
delete modes[index];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
modes.push_back(this);
|
||||||
|
tabbar->blockSignals(true);
|
||||||
|
tabbar->insertTab(tabbar->count(), name);
|
||||||
|
tabbar->blockSignals(false);
|
||||||
|
window->getSCPI()->add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
Mode::~Mode()
|
||||||
|
{
|
||||||
|
window->getSCPI()->remove(this);
|
||||||
|
if(activeMode == this) {
|
||||||
|
deactivate();
|
||||||
|
}
|
||||||
|
auto index = findTabIndex();
|
||||||
|
tabbar->blockSignals(true);
|
||||||
|
tabbar->removeTab(index);
|
||||||
|
tabbar->blockSignals(false);
|
||||||
|
modes.erase(modes.begin() + index);
|
||||||
|
if(modes.size() > 0) {
|
||||||
|
modes[tabbar->currentIndex()]->activate();
|
||||||
|
}
|
||||||
|
window->getCentral()->removeWidget(central);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mode::activate()
|
void Mode::activate()
|
||||||
@ -89,14 +160,10 @@ void Mode::activate()
|
|||||||
}
|
}
|
||||||
|
|
||||||
activeMode = this;
|
activeMode = this;
|
||||||
// force activation of correct pushbutton in case the mode switch was done via script/setup load.
|
// force activation of correct tab in case the mode switch was done via script/setup load.
|
||||||
// This will trigger a second activation of this mode in the signal of the button, but since it is
|
// This will trigger a second activation of this mode in the signal of the tab bar, but since it is
|
||||||
// already the active mode, this function will just return -> no recursion
|
// already the active mode, this function will just return -> no recursion
|
||||||
for(auto b : modeButtonGroup->buttons()) {
|
tabbar->setCurrentIndex(findTabIndex());
|
||||||
if(b->text() == name) {
|
|
||||||
b->click();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(window->getDevice()) {
|
if(window->getDevice()) {
|
||||||
initializeDevice();
|
initializeDevice();
|
||||||
@ -131,6 +198,9 @@ void Mode::deactivate()
|
|||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "Deactivated mode" << name;
|
qDebug() << "Deactivated mode" << name;
|
||||||
|
if(window->getDevice()) {
|
||||||
|
window->getDevice()->SetIdle();
|
||||||
|
}
|
||||||
activeMode = nullptr;
|
activeMode = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,6 +209,26 @@ Mode *Mode::getActiveMode()
|
|||||||
return activeMode;
|
return activeMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString Mode::TypeToName(Mode::Type t)
|
||||||
|
{
|
||||||
|
switch(t) {
|
||||||
|
case Type::VNA: return "Vector Network Analyzer";
|
||||||
|
case Type::SG: return "Signal Generator";
|
||||||
|
case Type::SA: return "Spectrum Analyzer";
|
||||||
|
default: return "Invalid";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Mode::Type Mode::TypeFromName(QString s)
|
||||||
|
{
|
||||||
|
for(unsigned int i=0;i<(int)Type::Last;i++) {
|
||||||
|
if(s == TypeToName((Type) i)) {
|
||||||
|
return (Type) i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Type::Last;
|
||||||
|
}
|
||||||
|
|
||||||
void Mode::saveSreenshot()
|
void Mode::saveSreenshot()
|
||||||
{
|
{
|
||||||
auto filename = QFileDialog::getSaveFileName(nullptr, "Save plot image", "", "PNG image files (*.png)", nullptr, QFileDialog::DontUseNativeDialog);
|
auto filename = QFileDialog::getSaveFileName(nullptr, "Save plot image", "", "PNG image files (*.png)", nullptr, QFileDialog::DontUseNativeDialog);
|
||||||
@ -153,6 +243,27 @@ void Mode::saveSreenshot()
|
|||||||
central->grab().save(filename);
|
central->grab().save(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Mode *Mode::createNew(AppWindow *window, QString name, Mode::Type t)
|
||||||
|
{
|
||||||
|
switch(t) {
|
||||||
|
case Type::VNA: return new VNA(window, name);
|
||||||
|
case Type::SG: return new Generator(window, name);
|
||||||
|
case Type::SA: return new SpectrumAnalyzer(window, name);
|
||||||
|
default: return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Mode::nameAllowed(QString name)
|
||||||
|
{
|
||||||
|
for(auto m : modes) {
|
||||||
|
if(m->getName() == name) {
|
||||||
|
// name already taken, no duplicates allowed
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void Mode::finalize(QWidget *centralWidget)
|
void Mode::finalize(QWidget *centralWidget)
|
||||||
{
|
{
|
||||||
central = centralWidget;
|
central = centralWidget;
|
||||||
@ -176,6 +287,27 @@ void Mode::finalize(QWidget *centralWidget)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Mode::findTabIndex()
|
||||||
|
{
|
||||||
|
auto it = std::find(modes.begin(), modes.end(), this);
|
||||||
|
return it - modes.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Mode *> Mode::getModes()
|
||||||
|
{
|
||||||
|
return modes;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mode *Mode::findFirstOfType(Mode::Type t)
|
||||||
|
{
|
||||||
|
for(auto m : modes) {
|
||||||
|
if(m->getType() == t) {
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void Mode::setStatusbarMessage(QString msg)
|
void Mode::setStatusbarMessage(QString msg)
|
||||||
{
|
{
|
||||||
statusbarMsg = msg;
|
statusbarMsg = msg;
|
||||||
@ -188,3 +320,14 @@ QString Mode::getName() const
|
|||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Mode::setName(const QString &value)
|
||||||
|
{
|
||||||
|
if(!nameAllowed(value)) {
|
||||||
|
// unable to use this name
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
name = value;
|
||||||
|
tabbar->setTabText(findTabIndex(), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -3,30 +3,50 @@
|
|||||||
|
|
||||||
#include "appwindow.h"
|
#include "appwindow.h"
|
||||||
#include "savable.h"
|
#include "savable.h"
|
||||||
|
#include "scpi.h"
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QButtonGroup>
|
#include <QButtonGroup>
|
||||||
#include <QToolBar>
|
#include <QToolBar>
|
||||||
|
#include <QTabBar>
|
||||||
#include <QDockWidget>
|
#include <QDockWidget>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
class Mode : public QObject, public Savable
|
class Mode : public QObject, public Savable, public SCPINode
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
Mode(AppWindow *window, QString name);
|
enum class Type {
|
||||||
|
VNA,
|
||||||
|
SG,
|
||||||
|
SA,
|
||||||
|
Last,
|
||||||
|
};
|
||||||
|
|
||||||
|
Mode(AppWindow *window, QString name, QString SCPIname);
|
||||||
|
~Mode();
|
||||||
|
|
||||||
virtual void activate(); // derived classes must call Mode::activate before doing anything
|
virtual void activate(); // derived classes must call Mode::activate before doing anything
|
||||||
virtual void deactivate(); // derived classes must call Mode::deactivate before returning
|
virtual void deactivate(); // derived classes must call Mode::deactivate before returning
|
||||||
virtual void shutdown(){}; // called when the application is about to exit
|
virtual void shutdown(){}; // called when the application is about to exit
|
||||||
QString getName() const;
|
QString getName() const;
|
||||||
|
void setName(const QString &value);
|
||||||
static Mode *getActiveMode();
|
static Mode *getActiveMode();
|
||||||
|
static QString TypeToName(Type t);
|
||||||
|
static Type TypeFromName(QString s);
|
||||||
|
virtual Type getType() = 0;
|
||||||
|
|
||||||
virtual void initializeDevice() = 0;
|
virtual void initializeDevice() = 0;
|
||||||
virtual void deviceDisconnected(){};
|
virtual void deviceDisconnected(){};
|
||||||
|
|
||||||
virtual void saveSreenshot();
|
virtual void saveSreenshot();
|
||||||
|
|
||||||
|
static Mode *createNew(AppWindow *window, QString name, Type t);
|
||||||
|
static bool nameAllowed(QString name);
|
||||||
|
static std::vector<Mode *> getModes();
|
||||||
|
static Mode* findFirstOfType(Type t);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void statusbarMessage(QString msg);
|
void statusbarMessage(QString msg);
|
||||||
protected:
|
protected:
|
||||||
@ -39,10 +59,13 @@ protected:
|
|||||||
std::set<QDockWidget*> docks;
|
std::set<QDockWidget*> docks;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
int findTabIndex();
|
||||||
|
static std::vector<Mode*> modes;
|
||||||
static Mode *activeMode;
|
static Mode *activeMode;
|
||||||
|
static QTabBar *tabbar;
|
||||||
static QWidget *cornerWidget;
|
static QWidget *cornerWidget;
|
||||||
static QButtonGroup *modeButtonGroup;
|
// static QButtonGroup *modeButtonGroup;
|
||||||
const QString name;
|
QString name;
|
||||||
QString statusbarMsg;
|
QString statusbarMsg;
|
||||||
QWidget *central;
|
QWidget *central;
|
||||||
};
|
};
|
||||||
|
@ -106,6 +106,17 @@ bool SCPINode::add(SCPINode *node)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SCPINode::remove(SCPINode *node)
|
||||||
|
{
|
||||||
|
auto it = std::find(subnodes.begin(), subnodes.end(), node);
|
||||||
|
if(it != subnodes.end()) {
|
||||||
|
subnodes.erase(it);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool SCPINode::add(SCPICommand *cmd)
|
bool SCPINode::add(SCPICommand *cmd)
|
||||||
{
|
{
|
||||||
if(nameCollision(cmd->name())) {
|
if(nameCollision(cmd->name())) {
|
||||||
|
@ -31,6 +31,7 @@ public:
|
|||||||
name(name){}
|
name(name){}
|
||||||
|
|
||||||
bool add(SCPINode *node);
|
bool add(SCPINode *node);
|
||||||
|
bool remove(SCPINode *node);
|
||||||
bool add(SCPICommand *cmd);
|
bool add(SCPICommand *cmd);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
||||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" 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 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 "${INPUTS}"" 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 "${INPUTS}"" prefer-non-shared="true">
|
||||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||||
</provider>
|
</provider>
|
||||||
@ -18,7 +18,7 @@
|
|||||||
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
||||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" 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 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 "${INPUTS}"" 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 "${INPUTS}"" prefer-non-shared="true">
|
||||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||||
</provider>
|
</provider>
|
||||||
|
@ -117,7 +117,7 @@ inline void App_Process() {
|
|||||||
sweepActive = VNA::Setup(recv_packet.settings);
|
sweepActive = VNA::Setup(recv_packet.settings);
|
||||||
Communication::SendWithoutPayload(Protocol::PacketType::Ack);
|
Communication::SendWithoutPayload(Protocol::PacketType::Ack);
|
||||||
break;
|
break;
|
||||||
case Protocol::PacketType::ManualControl:
|
case Protocol::PacketType::ManualControlV1:
|
||||||
sweepActive = false;
|
sweepActive = false;
|
||||||
last_measure_packet = recv_packet;
|
last_measure_packet = recv_packet;
|
||||||
Manual::Setup(recv_packet.manual);
|
Manual::Setup(recv_packet.manual);
|
||||||
@ -145,12 +145,21 @@ inline void App_Process() {
|
|||||||
SA::Setup(recv_packet.spectrumSettings);
|
SA::Setup(recv_packet.spectrumSettings);
|
||||||
Communication::SendWithoutPayload(Protocol::PacketType::Ack);
|
Communication::SendWithoutPayload(Protocol::PacketType::Ack);
|
||||||
break;
|
break;
|
||||||
case Protocol::PacketType::RequestDeviceInfo:
|
case Protocol::PacketType::RequestDeviceInfo: {
|
||||||
Communication::SendWithoutPayload(Protocol::PacketType::Ack);
|
Communication::SendWithoutPayload(Protocol::PacketType::Ack);
|
||||||
Protocol::PacketInfo p;
|
Protocol::PacketInfo p;
|
||||||
p.type = Protocol::PacketType::DeviceInfo;
|
p.type = Protocol::PacketType::DeviceInfo;
|
||||||
HW::fillDeviceInfo(&p.info);
|
p.info = HW::Info;
|
||||||
Communication::Send(p);
|
Communication::Send(p);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Protocol::PacketType::RequestDeviceStatus: {
|
||||||
|
Communication::SendWithoutPayload(Protocol::PacketType::Ack);
|
||||||
|
Protocol::PacketInfo p;
|
||||||
|
p.type = Protocol::PacketType::DeviceStatusV1;
|
||||||
|
HW::getDeviceStatus(&p.statusV1);
|
||||||
|
Communication::Send(p);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Protocol::PacketType::SetIdle:
|
case Protocol::PacketType::SetIdle:
|
||||||
HW::SetMode(HW::Mode::Idle);
|
HW::SetMode(HW::Mode::Idle);
|
||||||
|
@ -91,8 +91,9 @@ uint16_t Protocol::EncodePacket(const PacketInfo &packet, uint8_t *dest, uint16_
|
|||||||
case PacketType::SweepSettings: payload_size = sizeof(packet.settings); break;
|
case PacketType::SweepSettings: payload_size = sizeof(packet.settings); break;
|
||||||
case PacketType::Reference: payload_size = sizeof(packet.reference); break;
|
case PacketType::Reference: payload_size = sizeof(packet.reference); break;
|
||||||
case PacketType::DeviceInfo: payload_size = sizeof(packet.info); break;
|
case PacketType::DeviceInfo: payload_size = sizeof(packet.info); break;
|
||||||
case PacketType::Status: payload_size = sizeof(packet.status); break;
|
case PacketType::DeviceStatusV1: payload_size = sizeof(packet.statusV1); break;
|
||||||
case PacketType::ManualControl: payload_size = sizeof(packet.manual); break;
|
case PacketType::ManualStatusV1: payload_size = sizeof(packet.manualStatusV1); break;
|
||||||
|
case PacketType::ManualControlV1: payload_size = sizeof(packet.manual); break;
|
||||||
case PacketType::FirmwarePacket: payload_size = sizeof(packet.firmware); break;
|
case PacketType::FirmwarePacket: payload_size = sizeof(packet.firmware); break;
|
||||||
case PacketType::Generator: payload_size = sizeof(packet.generator); break;
|
case PacketType::Generator: payload_size = sizeof(packet.generator); break;
|
||||||
case PacketType::SpectrumAnalyzerSettings: payload_size = sizeof(packet.spectrumSettings); break;
|
case PacketType::SpectrumAnalyzerSettings: payload_size = sizeof(packet.spectrumSettings); break;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
namespace Protocol {
|
namespace Protocol {
|
||||||
|
|
||||||
static constexpr uint16_t Version = 9;
|
static constexpr uint16_t Version = 10;
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
|
|
||||||
@ -50,17 +50,8 @@ using DeviceInfo = struct _deviceInfo {
|
|||||||
uint8_t FW_major;
|
uint8_t FW_major;
|
||||||
uint8_t FW_minor;
|
uint8_t FW_minor;
|
||||||
uint8_t FW_patch;
|
uint8_t FW_patch;
|
||||||
|
uint8_t hardware_version;
|
||||||
char HW_Revision;
|
char HW_Revision;
|
||||||
uint8_t extRefAvailable:1;
|
|
||||||
uint8_t extRefInUse:1;
|
|
||||||
uint8_t FPGA_configured:1;
|
|
||||||
uint8_t source_locked:1;
|
|
||||||
uint8_t LO1_locked:1;
|
|
||||||
uint8_t ADC_overload:1;
|
|
||||||
uint8_t unlevel:1;
|
|
||||||
uint8_t temp_source;
|
|
||||||
uint8_t temp_LO1;
|
|
||||||
uint8_t temp_MCU;
|
|
||||||
uint64_t limits_minFreq;
|
uint64_t limits_minFreq;
|
||||||
uint64_t limits_maxFreq;
|
uint64_t limits_maxFreq;
|
||||||
uint32_t limits_minIFBW;
|
uint32_t limits_minIFBW;
|
||||||
@ -74,7 +65,21 @@ using DeviceInfo = struct _deviceInfo {
|
|||||||
uint64_t limits_maxFreqHarmonic;
|
uint64_t limits_maxFreqHarmonic;
|
||||||
};
|
};
|
||||||
|
|
||||||
using ManualStatus = struct _manualstatus {
|
using DeviceStatusV1 = struct _deviceStatusV1 {
|
||||||
|
uint8_t extRefAvailable:1;
|
||||||
|
uint8_t extRefInUse:1;
|
||||||
|
uint8_t FPGA_configured:1;
|
||||||
|
uint8_t source_locked:1;
|
||||||
|
uint8_t LO1_locked:1;
|
||||||
|
uint8_t ADC_overload:1;
|
||||||
|
uint8_t unlevel:1;
|
||||||
|
uint8_t temp_source;
|
||||||
|
uint8_t temp_LO1;
|
||||||
|
uint8_t temp_MCU;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
using ManualStatusV1 = struct _manualstatusV1 {
|
||||||
int16_t port1min, port1max;
|
int16_t port1min, port1max;
|
||||||
int16_t port2min, port2max;
|
int16_t port2min, port2max;
|
||||||
int16_t refmin, refmax;
|
int16_t refmin, refmax;
|
||||||
@ -87,7 +92,7 @@ using ManualStatus = struct _manualstatus {
|
|||||||
uint8_t LO_locked :1;
|
uint8_t LO_locked :1;
|
||||||
};
|
};
|
||||||
|
|
||||||
using ManualControl = struct _manualControl {
|
using ManualControlV1 = struct _manualControlV1 {
|
||||||
// Highband Source
|
// Highband Source
|
||||||
uint8_t SourceHighCE :1;
|
uint8_t SourceHighCE :1;
|
||||||
uint8_t SourceHighRFEN :1;
|
uint8_t SourceHighRFEN :1;
|
||||||
@ -170,8 +175,8 @@ enum class PacketType : uint8_t {
|
|||||||
None = 0,
|
None = 0,
|
||||||
Datapoint = 1,
|
Datapoint = 1,
|
||||||
SweepSettings = 2,
|
SweepSettings = 2,
|
||||||
Status = 3,
|
ManualStatusV1 = 3,
|
||||||
ManualControl = 4,
|
ManualControlV1 = 4,
|
||||||
DeviceInfo = 5,
|
DeviceInfo = 5,
|
||||||
FirmwarePacket = 6,
|
FirmwarePacket = 6,
|
||||||
Ack = 7,
|
Ack = 7,
|
||||||
@ -192,6 +197,8 @@ enum class PacketType : uint8_t {
|
|||||||
FrequencyCorrection = 22,
|
FrequencyCorrection = 22,
|
||||||
RequestAcquisitionFrequencySettings = 23,
|
RequestAcquisitionFrequencySettings = 23,
|
||||||
AcquisitionFrequencySettings = 24,
|
AcquisitionFrequencySettings = 24,
|
||||||
|
DeviceStatusV1 = 25,
|
||||||
|
RequestDeviceStatus = 26,
|
||||||
};
|
};
|
||||||
|
|
||||||
using PacketInfo = struct _packetinfo {
|
using PacketInfo = struct _packetinfo {
|
||||||
@ -201,10 +208,11 @@ using PacketInfo = struct _packetinfo {
|
|||||||
SweepSettings settings;
|
SweepSettings settings;
|
||||||
ReferenceSettings reference;
|
ReferenceSettings reference;
|
||||||
GeneratorSettings generator;
|
GeneratorSettings generator;
|
||||||
|
DeviceStatusV1 statusV1;
|
||||||
DeviceInfo info;
|
DeviceInfo info;
|
||||||
ManualControl manual;
|
ManualControlV1 manual;
|
||||||
FirmwarePacket firmware;
|
FirmwarePacket firmware;
|
||||||
ManualStatus status;
|
ManualStatusV1 manualStatusV1;
|
||||||
SpectrumAnalyzerSettings spectrumSettings;
|
SpectrumAnalyzerSettings spectrumSettings;
|
||||||
SpectrumAnalyzerResult spectrumResult;
|
SpectrumAnalyzerResult spectrumResult;
|
||||||
AmplitudeCorrectionPoint amplitudePoint;
|
AmplitudeCorrectionPoint amplitudePoint;
|
||||||
|
@ -130,6 +130,17 @@ void FPGA::SetSamplesPerPoint(uint32_t nsamples) {
|
|||||||
WriteRegister(Reg::SamplesPerPoint, 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) {
|
void FPGA::Enable(Periphery p, bool enable) {
|
||||||
if (enable) {
|
if (enable) {
|
||||||
SysCtrlReg |= (uint16_t) p;
|
SysCtrlReg |= (uint16_t) p;
|
||||||
@ -282,7 +293,7 @@ void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) {
|
|||||||
result.RefI = assembleSampleResultValue(&raw[8]);
|
result.RefI = assembleSampleResultValue(&raw[8]);
|
||||||
result.RefQ = assembleSampleResultValue(&raw[2]);
|
result.RefQ = assembleSampleResultValue(&raw[2]);
|
||||||
result.pointNum = (uint16_t)(raw[38]&0x1F) << 8 | raw[39];
|
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);
|
High(CS);
|
||||||
busy_reading = false;
|
busy_reading = false;
|
||||||
if ((status & 0x0004) && callback) {
|
if ((status & 0x0004) && callback) {
|
||||||
|
@ -17,6 +17,7 @@ enum class Reg {
|
|||||||
SystemControl = 0x03,
|
SystemControl = 0x03,
|
||||||
ADCPrescaler = 0x04,
|
ADCPrescaler = 0x04,
|
||||||
PhaseIncrement = 0x05,
|
PhaseIncrement = 0x05,
|
||||||
|
SweepSetup = 0x06,
|
||||||
MAX2871Def0LSB = 0x08,
|
MAX2871Def0LSB = 0x08,
|
||||||
MAX2871Def0MSB = 0x09,
|
MAX2871Def0MSB = 0x09,
|
||||||
MAX2871Def1LSB = 0x0A,
|
MAX2871Def1LSB = 0x0A,
|
||||||
@ -33,8 +34,8 @@ using SamplingResult = struct _samplingresult {
|
|||||||
int64_t P1I, P1Q;
|
int64_t P1I, P1Q;
|
||||||
int64_t P2I, P2Q;
|
int64_t P2I, P2Q;
|
||||||
int64_t RefI, RefQ;
|
int64_t RefI, RefQ;
|
||||||
uint16_t pointNum :15;
|
uint16_t pointNum :13;
|
||||||
uint16_t activePort :1;
|
uint16_t stageNum :3;
|
||||||
};
|
};
|
||||||
|
|
||||||
using DFTResult = struct _dftresult {
|
using DFTResult = struct _dftresult {
|
||||||
@ -59,8 +60,7 @@ enum class Periphery {
|
|||||||
DebugLED = 0x0080,
|
DebugLED = 0x0080,
|
||||||
SourceChip = 0x0010,
|
SourceChip = 0x0010,
|
||||||
LO1Chip = 0x0008,
|
LO1Chip = 0x0008,
|
||||||
ExcitePort2 = 0x0004,
|
|
||||||
ExcitePort1 = 0x0002,
|
|
||||||
PortSwitch = 0x0001,
|
PortSwitch = 0x0001,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -113,6 +113,7 @@ bool Init(HaltedCallback cb = nullptr);
|
|||||||
void WriteRegister(FPGA::Reg reg, uint16_t value);
|
void WriteRegister(FPGA::Reg reg, uint16_t value);
|
||||||
void SetNumberOfPoints(uint16_t npoints);
|
void SetNumberOfPoints(uint16_t npoints);
|
||||||
void SetSamplesPerPoint(uint32_t nsamples);
|
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 Enable(Periphery p, bool enable = true);
|
||||||
void Disable(Periphery p);
|
void Disable(Periphery p);
|
||||||
bool IsEnabled(Periphery p);
|
bool IsEnabled(Periphery p);
|
||||||
|
@ -11,7 +11,7 @@ void Generator::Setup(Protocol::GeneratorSettings g) {
|
|||||||
HW::SetIdle();
|
HW::SetIdle();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Protocol::ManualControl m;
|
Protocol::ManualControlV1 m;
|
||||||
// LOs not required
|
// LOs not required
|
||||||
m.LO1CE = 0;
|
m.LO1CE = 0;
|
||||||
m.LO1Frequency = 1000000000;
|
m.LO1Frequency = 1000000000;
|
||||||
|
@ -299,9 +299,7 @@ void HW::SetOutputUnlevel(bool unlev) {
|
|||||||
unlevel = unlev;
|
unlevel = unlev;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HW::fillDeviceInfo(Protocol::DeviceInfo *info, bool updateEvenWhenBusy) {
|
void HW::getDeviceStatus(Protocol::DeviceStatusV1 *status, bool updateEvenWhenBusy) {
|
||||||
// copy constant default values
|
|
||||||
memcpy(info, &HW::Info, sizeof(HW::Info));
|
|
||||||
if(activeMode == Mode::Idle || updateEvenWhenBusy) {
|
if(activeMode == Mode::Idle || updateEvenWhenBusy) {
|
||||||
// updating values from FPGA allowed
|
// updating values from FPGA allowed
|
||||||
|
|
||||||
@ -318,21 +316,21 @@ void HW::fillDeviceInfo(Protocol::DeviceInfo *info, bool updateEvenWhenBusy) {
|
|||||||
if(limits.P1min < -ADC_LIMIT || limits.P1max > ADC_LIMIT
|
if(limits.P1min < -ADC_LIMIT || limits.P1max > ADC_LIMIT
|
||||||
|| limits.P2min < -ADC_LIMIT || limits.P2max > ADC_LIMIT
|
|| limits.P2min < -ADC_LIMIT || limits.P2max > ADC_LIMIT
|
||||||
|| limits.Rmin < -ADC_LIMIT || limits.Rmax > ADC_LIMIT) {
|
|| limits.Rmin < -ADC_LIMIT || limits.Rmax > ADC_LIMIT) {
|
||||||
info->ADC_overload = true;
|
status->ADC_overload = true;
|
||||||
} else {
|
} else {
|
||||||
info->ADC_overload = false;
|
status->ADC_overload = false;
|
||||||
}
|
}
|
||||||
auto status = FPGA::GetStatus();
|
auto FPGA_status = FPGA::GetStatus();
|
||||||
info->LO1_locked = (status & (int) FPGA::Interrupt::LO1Unlock) ? 0 : 1;
|
status->LO1_locked = (FPGA_status & (int) FPGA::Interrupt::LO1Unlock) ? 0 : 1;
|
||||||
info->source_locked = (status & (int) FPGA::Interrupt::SourceUnlock) ? 0 : 1;
|
status->source_locked = (FPGA_status & (int) FPGA::Interrupt::SourceUnlock) ? 0 : 1;
|
||||||
info->extRefAvailable = Ref::available();
|
status->extRefAvailable = Ref::available();
|
||||||
info->extRefInUse = extRefInUse;
|
status->extRefInUse = extRefInUse;
|
||||||
info->unlevel = unlevel;
|
status->unlevel = unlevel;
|
||||||
info->temp_LO1 = tempLO;
|
status->temp_LO1 = tempLO;
|
||||||
info->temp_source = tempSource;
|
status->temp_source = tempSource;
|
||||||
FPGA::ResetADCLimits();
|
FPGA::ResetADCLimits();
|
||||||
}
|
}
|
||||||
info->temp_MCU = STM::getTemperature();
|
status->temp_MCU = STM::getTemperature();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HW::Ref::available() {
|
bool HW::Ref::available() {
|
||||||
|
@ -70,17 +70,8 @@ static constexpr Protocol::DeviceInfo Info = {
|
|||||||
.FW_major = FW_MAJOR,
|
.FW_major = FW_MAJOR,
|
||||||
.FW_minor = FW_MINOR,
|
.FW_minor = FW_MINOR,
|
||||||
.FW_patch = FW_PATCH,
|
.FW_patch = FW_PATCH,
|
||||||
|
.hardware_version = 1,
|
||||||
.HW_Revision = HW_REVISION,
|
.HW_Revision = HW_REVISION,
|
||||||
.extRefAvailable = 0,
|
|
||||||
.extRefInUse = 0,
|
|
||||||
.FPGA_configured = 0,
|
|
||||||
.source_locked = 0,
|
|
||||||
.LO1_locked = 0,
|
|
||||||
.ADC_overload = 0,
|
|
||||||
.unlevel = 0,
|
|
||||||
.temp_source = 0,
|
|
||||||
.temp_LO1 = 0,
|
|
||||||
.temp_MCU = 0,
|
|
||||||
.limits_minFreq = 0,
|
.limits_minFreq = 0,
|
||||||
.limits_maxFreq = 6000000000,
|
.limits_maxFreq = 6000000000,
|
||||||
.limits_minIFBW = DefaultADCSamplerate / MaxSamples,
|
.limits_minIFBW = DefaultADCSamplerate / MaxSamples,
|
||||||
@ -120,7 +111,7 @@ using AmplitudeSettings = struct _amplitudeSettings {
|
|||||||
AmplitudeSettings GetAmplitudeSettings(int16_t cdbm, uint64_t freq = 0, bool applyCorrections = false, bool port2 = false);
|
AmplitudeSettings GetAmplitudeSettings(int16_t cdbm, uint64_t freq = 0, bool applyCorrections = false, bool port2 = false);
|
||||||
|
|
||||||
bool GetTemps(uint8_t *source, uint8_t *lo);
|
bool GetTemps(uint8_t *source, uint8_t *lo);
|
||||||
void fillDeviceInfo(Protocol::DeviceInfo *info, bool updateEvenWhenBusy = false);
|
void getDeviceStatus(Protocol::DeviceStatusV1 *status, bool updateEvenWhenBusy = false);
|
||||||
namespace Ref {
|
namespace Ref {
|
||||||
bool available();
|
bool available();
|
||||||
bool usingExternal();
|
bool usingExternal();
|
||||||
|
@ -6,11 +6,11 @@
|
|||||||
|
|
||||||
static bool active = false;
|
static bool active = false;
|
||||||
static uint32_t samples;
|
static uint32_t samples;
|
||||||
static Protocol::ManualStatus status;
|
static Protocol::ManualStatusV1 status;
|
||||||
|
|
||||||
using namespace HWHAL;
|
using namespace HWHAL;
|
||||||
|
|
||||||
void Manual::Setup(Protocol::ManualControl m) {
|
void Manual::Setup(Protocol::ManualControlV1 m) {
|
||||||
HW::SetMode(HW::Mode::Manual);
|
HW::SetMode(HW::Mode::Manual);
|
||||||
samples = m.Samples;
|
samples = m.Samples;
|
||||||
FPGA::AbortSweep();
|
FPGA::AbortSweep();
|
||||||
@ -69,8 +69,7 @@ void Manual::Setup(Protocol::ManualControl m) {
|
|||||||
FPGA::Enable(FPGA::Periphery::Port1Mixer, m.Port1EN);
|
FPGA::Enable(FPGA::Periphery::Port1Mixer, m.Port1EN);
|
||||||
FPGA::Enable(FPGA::Periphery::Port2Mixer, m.Port2EN);
|
FPGA::Enable(FPGA::Periphery::Port2Mixer, m.Port2EN);
|
||||||
FPGA::Enable(FPGA::Periphery::RefMixer, m.RefEN);
|
FPGA::Enable(FPGA::Periphery::RefMixer, m.RefEN);
|
||||||
FPGA::Enable(FPGA::Periphery::ExcitePort1, m.PortSwitch == 0);
|
FPGA::SetupSweep(0, m.PortSwitch == 1, m.PortSwitch == 0);
|
||||||
FPGA::Enable(FPGA::Periphery::ExcitePort2, m.PortSwitch == 1);
|
|
||||||
FPGA::Enable(FPGA::Periphery::PortSwitch);
|
FPGA::Enable(FPGA::Periphery::PortSwitch);
|
||||||
|
|
||||||
// Enable new data and sweep halt interrupt
|
// Enable new data and sweep halt interrupt
|
||||||
@ -100,38 +99,38 @@ void Manual::Work() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Protocol::PacketInfo p;
|
Protocol::PacketInfo p;
|
||||||
p.type = Protocol::PacketType::Status;
|
p.type = Protocol::PacketType::ManualStatusV1;
|
||||||
p.status = status;
|
p.manualStatusV1 = status;
|
||||||
uint16_t isr_flags = FPGA::GetStatus();
|
uint16_t isr_flags = FPGA::GetStatus();
|
||||||
if (!(isr_flags & 0x0002)) {
|
if (!(isr_flags & 0x0002)) {
|
||||||
p.status.source_locked = 1;
|
p.manualStatusV1.source_locked = 1;
|
||||||
} else {
|
} else {
|
||||||
p.status.source_locked = 0;
|
p.manualStatusV1.source_locked = 0;
|
||||||
}
|
}
|
||||||
if (!(isr_flags & 0x0001)) {
|
if (!(isr_flags & 0x0001)) {
|
||||||
p.status.LO_locked = 1;
|
p.manualStatusV1.LO_locked = 1;
|
||||||
} else {
|
} else {
|
||||||
p.status.LO_locked = 0;
|
p.manualStatusV1.LO_locked = 0;
|
||||||
}
|
}
|
||||||
auto limits = FPGA::GetADCLimits();
|
auto limits = FPGA::GetADCLimits();
|
||||||
FPGA::ResetADCLimits();
|
FPGA::ResetADCLimits();
|
||||||
p.status.port1min = limits.P1min;
|
p.manualStatusV1.port1min = limits.P1min;
|
||||||
p.status.port1max = limits.P1max;
|
p.manualStatusV1.port1max = limits.P1max;
|
||||||
p.status.port2min = limits.P2min;
|
p.manualStatusV1.port2min = limits.P2min;
|
||||||
p.status.port2max = limits.P2max;
|
p.manualStatusV1.port2max = limits.P2max;
|
||||||
p.status.refmin = limits.Rmin;
|
p.manualStatusV1.refmin = limits.Rmin;
|
||||||
p.status.refmax = limits.Rmax;
|
p.manualStatusV1.refmax = limits.Rmax;
|
||||||
HW::GetTemps(&p.status.temp_source, &p.status.temp_LO);
|
HW::GetTemps(&p.manualStatusV1.temp_source, &p.manualStatusV1.temp_LO);
|
||||||
Communication::Send(p);
|
Communication::Send(p);
|
||||||
HW::Ref::update();
|
HW::Ref::update();
|
||||||
Protocol::PacketInfo packet;
|
Protocol::PacketInfo packet;
|
||||||
packet.type = Protocol::PacketType::DeviceInfo;
|
packet.type = Protocol::PacketType::DeviceStatusV1;
|
||||||
// Enable PLL chips for temperature reading
|
// Enable PLL chips for temperature reading
|
||||||
bool srcEn = FPGA::IsEnabled(FPGA::Periphery::SourceChip);
|
bool srcEn = FPGA::IsEnabled(FPGA::Periphery::SourceChip);
|
||||||
bool LOEn = FPGA::IsEnabled(FPGA::Periphery::LO1Chip);
|
bool LOEn = FPGA::IsEnabled(FPGA::Periphery::LO1Chip);
|
||||||
FPGA::Enable(FPGA::Periphery::SourceChip);
|
FPGA::Enable(FPGA::Periphery::SourceChip);
|
||||||
FPGA::Enable(FPGA::Periphery::LO1Chip);
|
FPGA::Enable(FPGA::Periphery::LO1Chip);
|
||||||
HW::fillDeviceInfo(&packet.info, true);
|
HW::getDeviceStatus(&packet.statusV1, true);
|
||||||
// restore PLL state
|
// restore PLL state
|
||||||
FPGA::Enable(FPGA::Periphery::SourceChip, srcEn);
|
FPGA::Enable(FPGA::Periphery::SourceChip, srcEn);
|
||||||
FPGA::Enable(FPGA::Periphery::LO1Chip, LOEn);
|
FPGA::Enable(FPGA::Periphery::LO1Chip, LOEn);
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
namespace Manual {
|
namespace Manual {
|
||||||
|
|
||||||
void Setup(Protocol::ManualControl m);
|
void Setup(Protocol::ManualControlV1 m);
|
||||||
bool MeasurementDone(const FPGA::SamplingResult &result);
|
bool MeasurementDone(const FPGA::SamplingResult &result);
|
||||||
void Work();
|
void Work();
|
||||||
void Stop();
|
void Stop();
|
||||||
|
@ -209,8 +209,7 @@ void SA::Setup(Protocol::SpectrumAnalyzerSettings settings) {
|
|||||||
FPGA::SetWindow((FPGA::Window) s.WindowType);
|
FPGA::SetWindow((FPGA::Window) s.WindowType);
|
||||||
FPGA::Enable(FPGA::Periphery::LO1Chip);
|
FPGA::Enable(FPGA::Periphery::LO1Chip);
|
||||||
FPGA::Enable(FPGA::Periphery::LO1RF);
|
FPGA::Enable(FPGA::Periphery::LO1RF);
|
||||||
FPGA::Enable(FPGA::Periphery::ExcitePort1, s.trackingGeneratorPort == 0);
|
FPGA::SetupSweep(0, s.trackingGeneratorPort == 1, s.trackingGeneratorPort == 0);
|
||||||
FPGA::Enable(FPGA::Periphery::ExcitePort2, s.trackingGeneratorPort == 1);
|
|
||||||
FPGA::Enable(FPGA::Periphery::PortSwitch, s.trackingGenerator);
|
FPGA::Enable(FPGA::Periphery::PortSwitch, s.trackingGenerator);
|
||||||
FPGA::Enable(FPGA::Periphery::Amplifier, s.trackingGenerator);
|
FPGA::Enable(FPGA::Periphery::Amplifier, s.trackingGenerator);
|
||||||
FPGA::Enable(FPGA::Periphery::Port1Mixer);
|
FPGA::Enable(FPGA::Periphery::Port1Mixer);
|
||||||
@ -386,8 +385,8 @@ void SA::Work() {
|
|||||||
// send device info every nth point
|
// send device info every nth point
|
||||||
FPGA::Enable(FPGA::Periphery::SourceChip); // needs to enable the chip to get a valid temperature reading
|
FPGA::Enable(FPGA::Periphery::SourceChip); // needs to enable the chip to get a valid temperature reading
|
||||||
Protocol::PacketInfo packet;
|
Protocol::PacketInfo packet;
|
||||||
packet.type = Protocol::PacketType::DeviceInfo;
|
packet.type = Protocol::PacketType::DeviceStatusV1;
|
||||||
HW::fillDeviceInfo(&packet.info, true);
|
HW::getDeviceStatus(&packet.statusV1, true);
|
||||||
FPGA::Disable(FPGA::Periphery::SourceChip);
|
FPGA::Disable(FPGA::Periphery::SourceChip);
|
||||||
Communication::Send(packet);
|
Communication::Send(packet);
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,9 @@
|
|||||||
|
|
||||||
static Protocol::SweepSettings settings;
|
static Protocol::SweepSettings settings;
|
||||||
static uint16_t pointCnt;
|
static uint16_t pointCnt;
|
||||||
|
static uint8_t stageCnt;
|
||||||
|
static uint8_t stages;
|
||||||
static double logMultiplier, logFrequency;
|
static double logMultiplier, logFrequency;
|
||||||
static bool excitingPort1;
|
|
||||||
static Protocol::Datapoint data;
|
static Protocol::Datapoint data;
|
||||||
static bool active = false;
|
static bool active = false;
|
||||||
static Si5351C::DriveStrength fixedPowerLowband;
|
static Si5351C::DriveStrength fixedPowerLowband;
|
||||||
@ -278,12 +279,22 @@ bool VNA::Setup(Protocol::SweepSettings s) {
|
|||||||
FPGA::Enable(FPGA::Periphery::SourceRF);
|
FPGA::Enable(FPGA::Periphery::SourceRF);
|
||||||
FPGA::Enable(FPGA::Periphery::LO1Chip);
|
FPGA::Enable(FPGA::Periphery::LO1Chip);
|
||||||
FPGA::Enable(FPGA::Periphery::LO1RF);
|
FPGA::Enable(FPGA::Periphery::LO1RF);
|
||||||
FPGA::Enable(FPGA::Periphery::ExcitePort1, s.excitePort1);
|
if(s.excitePort1 && s.excitePort2) {
|
||||||
FPGA::Enable(FPGA::Periphery::ExcitePort2, 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);
|
FPGA::Enable(FPGA::Periphery::PortSwitch);
|
||||||
pointCnt = 0;
|
pointCnt = 0;
|
||||||
// starting port depends on whether port 1 is active in sweep
|
stageCnt = 0;
|
||||||
excitingPort1 = s.excitePort1;
|
|
||||||
IFTableIndexCnt = 0;
|
IFTableIndexCnt = 0;
|
||||||
adcShifted = false;
|
adcShifted = false;
|
||||||
active = true;
|
active = true;
|
||||||
@ -306,8 +317,8 @@ bool VNA::MeasurementDone(const FPGA::SamplingResult &result) {
|
|||||||
if(!active) {
|
if(!active) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(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.activePort, !excitingPort1);
|
LOG_WARN("Indicated point does not match (%u != %u, %d != %d)", result.pointNum, pointCnt, result.stageNum, stageCnt);
|
||||||
FPGA::AbortSweep();
|
FPGA::AbortSweep();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -320,29 +331,24 @@ bool VNA::MeasurementDone(const FPGA::SamplingResult &result) {
|
|||||||
data.pointNum = pointCnt;
|
data.pointNum = pointCnt;
|
||||||
data.frequency = getPointFrequency(pointCnt);
|
data.frequency = getPointFrequency(pointCnt);
|
||||||
data.cdbm = settings.cdbm_excitation_start + (settings.cdbm_excitation_stop - settings.cdbm_excitation_start) * pointCnt / (settings.points - 1);
|
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.real_S11 = port1.real();
|
||||||
data.imag_S11 = port1.imag();
|
data.imag_S11 = port1.imag();
|
||||||
data.real_S21 = port2.real();
|
data.real_S21 = port2.real();
|
||||||
data.imag_S21 = port2.imag();
|
data.imag_S21 = port2.imag();
|
||||||
} else {
|
} else {
|
||||||
|
// stimulus is present at port 2
|
||||||
data.real_S12 = port1.real();
|
data.real_S12 = port1.real();
|
||||||
data.imag_S12 = port1.imag();
|
data.imag_S12 = port1.imag();
|
||||||
data.real_S22 = port2.real();
|
data.real_S22 = port2.real();
|
||||||
data.imag_S22 = port2.imag();
|
data.imag_S22 = port2.imag();
|
||||||
}
|
}
|
||||||
// figure out whether this sweep point is complete and which port gets excited next
|
// figure out whether this sweep point is complete
|
||||||
bool pointComplete = false;
|
stageCnt++;
|
||||||
if(settings.excitePort1 == 1 && settings.excitePort2 == 1) {
|
if(stageCnt == stages) {
|
||||||
// point is complete when port 2 was active
|
// point is complete
|
||||||
pointComplete = !excitingPort1;
|
stageCnt = 0;
|
||||||
// next measurement will be from other port
|
|
||||||
excitingPort1 = !excitingPort1;
|
|
||||||
} else {
|
|
||||||
// only one port active, point is complete after every measurement
|
|
||||||
pointComplete = true;
|
|
||||||
}
|
|
||||||
if(pointComplete) {
|
|
||||||
STM::DispatchToInterrupt(PassOnData);
|
STM::DispatchToInterrupt(PassOnData);
|
||||||
pointCnt++;
|
pointCnt++;
|
||||||
if (pointCnt >= settings.points) {
|
if (pointCnt >= settings.points) {
|
||||||
@ -361,8 +367,8 @@ void VNA::Work() {
|
|||||||
HW::Ref::update();
|
HW::Ref::update();
|
||||||
// Compile info packet
|
// Compile info packet
|
||||||
Protocol::PacketInfo packet;
|
Protocol::PacketInfo packet;
|
||||||
packet.type = Protocol::PacketType::DeviceInfo;
|
packet.type = Protocol::PacketType::DeviceStatusV1;
|
||||||
HW::fillDeviceInfo(&packet.info, true);
|
HW::getDeviceStatus(&packet.statusV1, true);
|
||||||
Communication::Send(packet);
|
Communication::Send(packet);
|
||||||
// do not reset unlevel flag here, as it is calculated only once at the setup of the sweep
|
// do not reset unlevel flag here, as it is calculated only once at the setup of the sweep
|
||||||
// Start next sweep
|
// Start next sweep
|
||||||
|
Loading…
Reference in New Issue
Block a user