mirror of
https://github.com/jankae/LibreVNA.git
synced 2026-02-05 07:04:28 +01:00
Working dwell time feature
- Bugfixes: - improve SPI timing in FPGA - fix markers and reduce CPU load when using markers with fast traces - New features: - dwell time configurable in acquisition toolbar - PLL settling delay in device configuration - device configuration persistent across power cycles
This commit is contained in:
parent
24314e2361
commit
a4faeb28b0
|
|
@ -91,7 +91,8 @@ end SPICommands;
|
|||
|
||||
architecture Behavioral of SPICommands is
|
||||
COMPONENT spi_slave
|
||||
Generic(W : integer);
|
||||
Generic(W : integer;
|
||||
PREWIDTH : integer);
|
||||
PORT(
|
||||
SPI_CLK : in STD_LOGIC;
|
||||
MISO : out STD_LOGIC;
|
||||
|
|
@ -100,7 +101,9 @@ architecture Behavioral of SPICommands is
|
|||
BUF_OUT : out STD_LOGIC_VECTOR (W-1 downto 0) := (others => '0');
|
||||
BUF_IN : in STD_LOGIC_VECTOR (W-1 downto 0);
|
||||
CLK : in STD_LOGIC;
|
||||
COMPLETE : out STD_LOGIC
|
||||
COMPLETE : out STD_LOGIC;
|
||||
PRE_COMPLETE : out STD_LOGIC;
|
||||
PRE_BUF_OUT : out STD_LOGIC_VECTOR (PREWIDTH-1 downto 0)
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
|
|
@ -108,6 +111,8 @@ architecture Behavioral of SPICommands is
|
|||
signal spi_buf_out : std_logic_vector(15 downto 0);
|
||||
signal spi_buf_in : std_logic_vector(15 downto 0);
|
||||
signal spi_complete : std_logic;
|
||||
signal spi_pre_complete : std_logic;
|
||||
signal spi_pre_buf_out : std_logic_vector(2 downto 0);
|
||||
signal word_cnt : integer range 0 to 19;
|
||||
type SPI_states is (FirstWord, WriteSweepConfig, ReadResult, WriteRegister);
|
||||
signal state : SPI_states;
|
||||
|
|
@ -128,7 +133,8 @@ architecture Behavioral of SPICommands is
|
|||
signal sweepconfig_buffer : std_logic_vector(79 downto 0);
|
||||
begin
|
||||
SPI: spi_slave
|
||||
GENERIC MAP(w => 16)
|
||||
GENERIC MAP(W => 16,
|
||||
PREWIDTH => 3)
|
||||
PORT MAP(
|
||||
SPI_CLK => SCLK,
|
||||
MISO => MISO,
|
||||
|
|
@ -137,7 +143,9 @@ begin
|
|||
BUF_OUT => spi_buf_out,
|
||||
BUF_IN => spi_buf_in,
|
||||
CLK => CLK,
|
||||
COMPLETE =>spi_complete
|
||||
COMPLETE => spi_complete,
|
||||
PRE_COMPLETE => spi_pre_complete,
|
||||
PRE_BUF_OUT => spi_pre_buf_out
|
||||
);
|
||||
|
||||
SWEEP_WRITE(0) <= sweep_config_write;
|
||||
|
|
@ -205,91 +213,113 @@ begin
|
|||
word_cnt <= 0;
|
||||
spi_buf_in <= interrupt_status;
|
||||
state <= FirstWord;
|
||||
elsif spi_complete = '1' then
|
||||
word_cnt <= word_cnt + 1;
|
||||
else
|
||||
-- handle read operations when the first PREWIDTH bits are complete
|
||||
if spi_pre_complete = '1' then
|
||||
case state is
|
||||
when FirstWord =>
|
||||
-- initial word determines action
|
||||
case spi_buf_out(15 downto 13) is
|
||||
when "000" => state <= WriteSweepConfig;
|
||||
-- also extract the point number
|
||||
SWEEP_ADDRESS <= spi_buf_out(12 downto 0);
|
||||
when "001" => state <= FirstWord;
|
||||
SWEEP_RESUME <= '1';
|
||||
when "010" => state <= FirstWord;
|
||||
spi_buf_in <= "1111000010100101";
|
||||
when "011" => state <= FirstWord;
|
||||
RESET_MINMAX <= '1';
|
||||
when "100" => state <= WriteRegister;
|
||||
selected_register <= to_integer(unsigned(spi_buf_out(4 downto 0)));
|
||||
when "101" => state <= ReadResult;-- can use same state as read result, but the latched data will contain the DFT values
|
||||
latched_result(175 downto 0) <= DFT_OUTPUT(191 downto 16);
|
||||
spi_buf_in <= DFT_OUTPUT(15 downto 0);
|
||||
dft_next <= '1';
|
||||
when "110" => state <= ReadResult;
|
||||
latched_result <= SAMPLING_RESULT(303 downto 16);
|
||||
spi_buf_in <= SAMPLING_RESULT(15 downto 0);
|
||||
unread_sampling_data <= '0';
|
||||
when "111" => state <= ReadResult; -- can use same state as read result, but the latched data will contain the min/max ADC values
|
||||
latched_result(79 downto 0) <= ADC_MINMAX(95 downto 16);
|
||||
spi_buf_in <= ADC_MINMAX(15 downto 0);
|
||||
when others => state <= FirstWord;
|
||||
-- initial word determines the action
|
||||
case spi_pre_buf_out is
|
||||
when "010" => state <= FirstWord;
|
||||
spi_buf_in <= "1111000010100101";
|
||||
when "101" => state <= ReadResult;-- can use same state as read result, but the latched data will contain the DFT values
|
||||
latched_result(175 downto 0) <= DFT_OUTPUT(191 downto 16);
|
||||
spi_buf_in <= DFT_OUTPUT(15 downto 0);
|
||||
dft_next <= '1';
|
||||
when "110" => state <= ReadResult;
|
||||
latched_result <= SAMPLING_RESULT(303 downto 16);
|
||||
spi_buf_in <= SAMPLING_RESULT(15 downto 0);
|
||||
unread_sampling_data <= '0';
|
||||
when "111" => state <= ReadResult; -- can use same state as read result, but the latched data will contain the min/max ADC values
|
||||
latched_result(79 downto 0) <= ADC_MINMAX(95 downto 16);
|
||||
spi_buf_in <= ADC_MINMAX(15 downto 0);
|
||||
--ignore other options
|
||||
when others =>
|
||||
end case;
|
||||
when WriteRegister =>
|
||||
-- write received data into previously selected register
|
||||
case selected_register is
|
||||
when 0 => interrupt_mask <= spi_buf_out;
|
||||
when 1 => SWEEP_POINTS <= spi_buf_out(12 downto 0);
|
||||
when 2 => NSAMPLES <= spi_buf_out(12 downto 0);
|
||||
when 3 => PORTSWITCH_EN <= spi_buf_out(0);
|
||||
PORT1_EN <= spi_buf_out(15);
|
||||
PORT2_EN <= spi_buf_out(14);
|
||||
REF_EN <= spi_buf_out(13);
|
||||
AMP_SHDN <= not spi_buf_out(12);
|
||||
SOURCE_RF_EN <= spi_buf_out(11);
|
||||
LO_RF_EN <= spi_buf_out(10);
|
||||
LEDS <= not spi_buf_out(9 downto 7);
|
||||
WINDOW_SETTING <= spi_buf_out(6 downto 5);
|
||||
SOURCE_CE_EN <= spi_buf_out(4);
|
||||
LO_CE_EN <= spi_buf_out(3);
|
||||
SYNC_MASTER <= spi_buf_out(1);
|
||||
when 4 => ADC_PRESCALER <= spi_buf_out(7 downto 0);
|
||||
when 5 => ADC_PHASEINC <= spi_buf_out(11 downto 0);
|
||||
when 6 => STAGES <= spi_buf_out(15 downto 13);
|
||||
SYNC_ENABLED <= spi_buf_out(12);
|
||||
PORT1_STAGE <= spi_buf_out(5 downto 3);
|
||||
PORT2_STAGE <= spi_buf_out(2 downto 0);
|
||||
when 7 => SPI_OVERWRITE_ENABLED <= spi_buf_out(15);
|
||||
SPI_OVERWRITE_DATA <= spi_buf_out(14 downto 0);
|
||||
when 8 => MAX2871_DEF_0(15 downto 0) <= spi_buf_out;
|
||||
when 9 => MAX2871_DEF_0(31 downto 16) <= spi_buf_out;
|
||||
when 10 => MAX2871_DEF_1(15 downto 0) <= spi_buf_out;
|
||||
when 11 => MAX2871_DEF_1(31 downto 16) <= spi_buf_out;
|
||||
when 12 => MAX2871_DEF_3(15 downto 0) <= spi_buf_out;
|
||||
when 13 => MAX2871_DEF_3(31 downto 16) <= spi_buf_out;
|
||||
when 14 => MAX2871_DEF_4(15 downto 0) <= spi_buf_out;
|
||||
when 15 => MAX2871_DEF_4(31 downto 16) <= spi_buf_out;
|
||||
when 18 => DFT_BIN1_PHASEINC <= spi_buf_out;
|
||||
when 19 => DFT_DIFFBIN_PHASEINC <= spi_buf_out;
|
||||
when 20 => SETTLING_TIME(15 downto 0) <= spi_buf_out;
|
||||
when 21 => SETTLING_TIME(19 downto 16) <= spi_buf_out(3 downto 0);
|
||||
when others =>
|
||||
end case;
|
||||
selected_register <= selected_register + 1;
|
||||
when WriteSweepConfig =>
|
||||
if word_cnt = 6 then
|
||||
-- Sweep config data is complete pass on
|
||||
SWEEP_DATA <= sweepconfig_buffer & spi_buf_out;
|
||||
sweep_config_write <= '1';
|
||||
else
|
||||
-- shift next word into buffer
|
||||
sweepconfig_buffer <= sweepconfig_buffer(63 downto 0) & spi_buf_out;
|
||||
end if;
|
||||
when ReadResult =>
|
||||
-- pass on next word of latched result
|
||||
spi_buf_in <= latched_result(15 downto 0);
|
||||
latched_result <= "0000000000000000" & latched_result(287 downto 16);
|
||||
when ReadResult =>
|
||||
-- pass on next word of latched result
|
||||
spi_buf_in <= latched_result(15 downto 0);
|
||||
latched_result <= "0000000000000000" & latched_result(287 downto 16);
|
||||
when others =>
|
||||
end case;
|
||||
end if;
|
||||
-- handle write operations when the whole word is complete
|
||||
if spi_complete = '1' then
|
||||
word_cnt <= word_cnt + 1;
|
||||
case state is
|
||||
when FirstWord =>
|
||||
-- initial word determines action
|
||||
case spi_buf_out(15 downto 13) is
|
||||
when "000" => state <= WriteSweepConfig;
|
||||
-- also extract the point number
|
||||
SWEEP_ADDRESS <= spi_buf_out(12 downto 0);
|
||||
when "001" => state <= FirstWord;
|
||||
SWEEP_RESUME <= '1';
|
||||
when "011" => state <= FirstWord;
|
||||
RESET_MINMAX <= '1';
|
||||
when "100" => state <= WriteRegister;
|
||||
selected_register <= to_integer(unsigned(spi_buf_out(4 downto 0)));
|
||||
-- ignore read options (already handled in other state machine)
|
||||
when "010" =>
|
||||
when "101" =>
|
||||
when "110" =>
|
||||
when "111" =>
|
||||
when others => state <= FirstWord;
|
||||
end case;
|
||||
when WriteRegister =>
|
||||
-- write received data into previously selected register
|
||||
case selected_register is
|
||||
when 0 => interrupt_mask <= spi_buf_out;
|
||||
when 1 => SWEEP_POINTS <= spi_buf_out(12 downto 0);
|
||||
when 2 => NSAMPLES <= spi_buf_out(12 downto 0);
|
||||
when 3 => PORTSWITCH_EN <= spi_buf_out(0);
|
||||
PORT1_EN <= spi_buf_out(15);
|
||||
PORT2_EN <= spi_buf_out(14);
|
||||
REF_EN <= spi_buf_out(13);
|
||||
AMP_SHDN <= not spi_buf_out(12);
|
||||
SOURCE_RF_EN <= spi_buf_out(11);
|
||||
LO_RF_EN <= spi_buf_out(10);
|
||||
LEDS <= not spi_buf_out(9 downto 7);
|
||||
WINDOW_SETTING <= spi_buf_out(6 downto 5);
|
||||
SOURCE_CE_EN <= spi_buf_out(4);
|
||||
LO_CE_EN <= spi_buf_out(3);
|
||||
SYNC_MASTER <= spi_buf_out(1);
|
||||
when 4 => ADC_PRESCALER <= spi_buf_out(7 downto 0);
|
||||
when 5 => ADC_PHASEINC <= spi_buf_out(11 downto 0);
|
||||
when 6 => STAGES <= spi_buf_out(15 downto 13);
|
||||
SYNC_ENABLED <= spi_buf_out(12);
|
||||
PORT1_STAGE <= spi_buf_out(5 downto 3);
|
||||
PORT2_STAGE <= spi_buf_out(2 downto 0);
|
||||
when 7 => SPI_OVERWRITE_ENABLED <= spi_buf_out(15);
|
||||
SPI_OVERWRITE_DATA <= spi_buf_out(14 downto 0);
|
||||
when 8 => MAX2871_DEF_0(15 downto 0) <= spi_buf_out;
|
||||
when 9 => MAX2871_DEF_0(31 downto 16) <= spi_buf_out;
|
||||
when 10 => MAX2871_DEF_1(15 downto 0) <= spi_buf_out;
|
||||
when 11 => MAX2871_DEF_1(31 downto 16) <= spi_buf_out;
|
||||
when 12 => MAX2871_DEF_3(15 downto 0) <= spi_buf_out;
|
||||
when 13 => MAX2871_DEF_3(31 downto 16) <= spi_buf_out;
|
||||
when 14 => MAX2871_DEF_4(15 downto 0) <= spi_buf_out;
|
||||
when 15 => MAX2871_DEF_4(31 downto 16) <= spi_buf_out;
|
||||
when 18 => DFT_BIN1_PHASEINC <= spi_buf_out;
|
||||
when 19 => DFT_DIFFBIN_PHASEINC <= spi_buf_out;
|
||||
when 20 => SETTLING_TIME(15 downto 0) <= spi_buf_out;
|
||||
when 21 => SETTLING_TIME(19 downto 16) <= spi_buf_out(3 downto 0);
|
||||
when others =>
|
||||
end case;
|
||||
selected_register <= selected_register + 1;
|
||||
when WriteSweepConfig =>
|
||||
if word_cnt = 6 then
|
||||
-- Sweep config data is complete pass on
|
||||
SWEEP_DATA <= sweepconfig_buffer & spi_buf_out;
|
||||
sweep_config_write <= '1';
|
||||
else
|
||||
-- shift next word into buffer
|
||||
sweepconfig_buffer <= sweepconfig_buffer(63 downto 0) & spi_buf_out;
|
||||
end if;
|
||||
-- read already handled in pre_complete, ignore
|
||||
when ReadResult =>
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
|
|
|||
|
|
@ -40,7 +40,8 @@ ARCHITECTURE behavior OF Test_SPI IS
|
|||
-- Component Declaration for the Unit Under Test (UUT)
|
||||
|
||||
COMPONENT spi_slave
|
||||
GENERIC(W : integer);
|
||||
GENERIC(W : integer;
|
||||
PREWIDTH : integer);
|
||||
PORT(
|
||||
SPI_CLK : IN std_logic;
|
||||
MISO : OUT std_logic;
|
||||
|
|
@ -49,7 +50,9 @@ ARCHITECTURE behavior OF Test_SPI IS
|
|||
BUF_OUT : OUT std_logic_vector(W-1 downto 0);
|
||||
BUF_IN : IN std_logic_vector(W-1 downto 0);
|
||||
CLK : IN std_logic;
|
||||
COMPLETE : OUT std_logic
|
||||
COMPLETE : OUT std_logic;
|
||||
PRE_COMPLETE : out STD_LOGIC;
|
||||
PRE_BUF_OUT : out STD_LOGIC_VECTOR (PREWIDTH-1 downto 0)
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
|
|
@ -65,6 +68,8 @@ ARCHITECTURE behavior OF Test_SPI IS
|
|||
signal MISO : std_logic;
|
||||
signal BUF_OUT : std_logic_vector(15 downto 0);
|
||||
signal COMPLETE : std_logic;
|
||||
signal PRE_COMPLETE : std_logic;
|
||||
signal PRE_BUF_OUT : std_logic_vector(2 downto 0);
|
||||
|
||||
-- Clock period definitions
|
||||
constant CLK_period : time := 9.765625 ns;
|
||||
|
|
@ -76,7 +81,7 @@ BEGIN
|
|||
|
||||
-- Instantiate the Unit Under Test (UUT)
|
||||
uut: spi_slave
|
||||
GENERIC MAP(W => 16)
|
||||
GENERIC MAP(W => 16, PREWIDTH => 3)
|
||||
PORT MAP (
|
||||
SPI_CLK => SPI_CLK,
|
||||
MISO => MISO,
|
||||
|
|
@ -85,7 +90,9 @@ BEGIN
|
|||
BUF_OUT => BUF_OUT,
|
||||
BUF_IN => BUF_IN,
|
||||
CLK => CLK,
|
||||
COMPLETE => COMPLETE
|
||||
COMPLETE => COMPLETE,
|
||||
PRE_COMPLETE => PRE_COMPLETE,
|
||||
PRE_BUF_OUT => PRE_BUF_OUT
|
||||
);
|
||||
|
||||
-- Clock process definitions
|
||||
|
|
|
|||
|
|
@ -293,11 +293,30 @@ BEGIN
|
|||
wait for 100 ns;
|
||||
RESET <= '0';
|
||||
wait for CLK_period*10;
|
||||
-- read static test register
|
||||
NSS <= '0';
|
||||
SPI("0100000000000000");
|
||||
SPI("0000000000000000");
|
||||
NSS <= '1';
|
||||
|
||||
wait for CLK_period*50;
|
||||
-- write register 3 = 0xFFFF (enable all periphery)
|
||||
NSS <= '0';
|
||||
SPI("1000000000000011");
|
||||
SPI("1111111111111111");
|
||||
NSS <= '1';
|
||||
|
||||
wait for CLK_period*50;
|
||||
-- set sampling result and read first 4 words
|
||||
SAMPLING_RESULT(63 downto 0) <= "1111000011110000101010101010101001010101010101010000111100001111";
|
||||
NSS <= '0';
|
||||
SPI("1100000000000000");
|
||||
SPI("0000000000000000");
|
||||
SPI("0000000000000000");
|
||||
SPI("0000000000000000");
|
||||
SPI("0000000000000000");
|
||||
NSS <= '1';
|
||||
|
||||
wait for CLK_period*50;
|
||||
-- insert stimulus here
|
||||
-- write number of points
|
||||
|
|
|
|||
|
|
@ -137,13 +137,9 @@
|
|||
<status xil_pn:value="SuccessfullyRun"/>
|
||||
<status xil_pn:value="ReadyToRun"/>
|
||||
</transform>
|
||||
<transform xil_pn:end_ts="1735841254" xil_pn:in_ck="-3235419683908193302" xil_pn:name="TRAN_copyAbstractToPostAbstractSimulation" xil_pn:start_ts="1735841254">
|
||||
<transform xil_pn:end_ts="1735897915" xil_pn:in_ck="-3235419683908193302" xil_pn:name="TRAN_copyAbstractToPostAbstractSimulation" xil_pn:start_ts="1735897915">
|
||||
<status xil_pn:value="SuccessfullyRun"/>
|
||||
<status xil_pn:value="ReadyToRun"/>
|
||||
<status xil_pn:value="OutOfDateForInputs"/>
|
||||
<status xil_pn:value="OutOfDateForOutputs"/>
|
||||
<status xil_pn:value="InputChanged"/>
|
||||
<status xil_pn:value="OutputChanged"/>
|
||||
<outfile xil_pn:name="DFT.vhd"/>
|
||||
<outfile xil_pn:name="MAX2871.vhd"/>
|
||||
<outfile xil_pn:name="MCP33131.vhd"/>
|
||||
|
|
@ -167,15 +163,15 @@
|
|||
<outfile xil_pn:name="top.vhd"/>
|
||||
<outfile xil_pn:name="window.vhd"/>
|
||||
</transform>
|
||||
<transform xil_pn:end_ts="1735841278" xil_pn:name="TRAN_xawsToSimhdl" xil_pn:prop_ck="9011583378592605907" xil_pn:start_ts="1735841278">
|
||||
<transform xil_pn:end_ts="1735898132" xil_pn:name="TRAN_xawsToSimhdl" xil_pn:prop_ck="9011583378592605907" xil_pn:start_ts="1735898132">
|
||||
<status xil_pn:value="SuccessfullyRun"/>
|
||||
<status xil_pn:value="ReadyToRun"/>
|
||||
</transform>
|
||||
<transform xil_pn:end_ts="1735841278" xil_pn:name="TRAN_schematicsToHdlSim" xil_pn:prop_ck="2919554697640690001" xil_pn:start_ts="1735841278">
|
||||
<transform xil_pn:end_ts="1735898132" xil_pn:name="TRAN_schematicsToHdlSim" xil_pn:prop_ck="2919554697640690001" xil_pn:start_ts="1735898132">
|
||||
<status xil_pn:value="SuccessfullyRun"/>
|
||||
<status xil_pn:value="ReadyToRun"/>
|
||||
</transform>
|
||||
<transform xil_pn:end_ts="1735834278" xil_pn:in_ck="-4366097307991745463" xil_pn:name="TRAN_regenerateCoresSim" xil_pn:prop_ck="-2723611991789822717" xil_pn:start_ts="1735834278">
|
||||
<transform xil_pn:end_ts="1735887598" xil_pn:in_ck="-4366097307991745463" xil_pn:name="TRAN_regenerateCoresSim" xil_pn:prop_ck="-2723611991789822717" xil_pn:start_ts="1735887598">
|
||||
<status xil_pn:value="SuccessfullyRun"/>
|
||||
<status xil_pn:value="ReadyToRun"/>
|
||||
<outfile xil_pn:name="ipcore_dir/DSP_SLICE.ngc"/>
|
||||
|
|
@ -188,14 +184,9 @@
|
|||
<outfile xil_pn:name="ipcore_dir/result_bram.ngc"/>
|
||||
<outfile xil_pn:name="ipcore_dir/result_bram.vhd"/>
|
||||
</transform>
|
||||
<transform xil_pn:end_ts="1735841254" xil_pn:in_ck="-9185925483828391381" xil_pn:name="TRAN_copyPostAbstractToPreSimulation" xil_pn:start_ts="1735841254">
|
||||
<transform xil_pn:end_ts="1735897915" xil_pn:in_ck="-9185925483828391381" xil_pn:name="TRAN_copyPostAbstractToPreSimulation" xil_pn:start_ts="1735897915">
|
||||
<status xil_pn:value="SuccessfullyRun"/>
|
||||
<status xil_pn:value="ReadyToRun"/>
|
||||
<status xil_pn:value="OutOfDateForInputs"/>
|
||||
<status xil_pn:value="OutOfDateForPredecessor"/>
|
||||
<status xil_pn:value="OutOfDateForOutputs"/>
|
||||
<status xil_pn:value="InputChanged"/>
|
||||
<status xil_pn:value="OutputChanged"/>
|
||||
<outfile xil_pn:name="DFT.vhd"/>
|
||||
<outfile xil_pn:name="MAX2871.vhd"/>
|
||||
<outfile xil_pn:name="MCP33131.vhd"/>
|
||||
|
|
@ -224,13 +215,10 @@
|
|||
<outfile xil_pn:name="top.vhd"/>
|
||||
<outfile xil_pn:name="window.vhd"/>
|
||||
</transform>
|
||||
<transform xil_pn:end_ts="1735841280" xil_pn:in_ck="-9185925483828391381" xil_pn:name="TRAN_ISimulateBehavioralModelRunFuse" xil_pn:prop_ck="-8439971377188504826" xil_pn:start_ts="1735841278">
|
||||
<transform xil_pn:end_ts="1735898134" xil_pn:in_ck="-9185925483828391381" xil_pn:name="TRAN_ISimulateBehavioralModelRunFuse" xil_pn:prop_ck="-8439971377188504826" xil_pn:start_ts="1735898132">
|
||||
<status xil_pn:value="SuccessfullyRun"/>
|
||||
<status xil_pn:value="ReadyToRun"/>
|
||||
<status xil_pn:value="OutOfDateForInputs"/>
|
||||
<status xil_pn:value="OutOfDateForPredecessor"/>
|
||||
<status xil_pn:value="OutOfDateForOutputs"/>
|
||||
<status xil_pn:value="InputChanged"/>
|
||||
<status xil_pn:value="OutputChanged"/>
|
||||
<outfile xil_pn:name="Test_SPICommands_beh.prj"/>
|
||||
<outfile xil_pn:name="Test_SPICommands_isim_beh.exe"/>
|
||||
|
|
@ -239,10 +227,9 @@
|
|||
<outfile xil_pn:name="isim.log"/>
|
||||
<outfile xil_pn:name="xilinxsim.ini"/>
|
||||
</transform>
|
||||
<transform xil_pn:end_ts="1735841280" xil_pn:in_ck="4191604156099045257" xil_pn:name="TRAN_ISimulateBehavioralModel" xil_pn:prop_ck="-6574364550222252173" xil_pn:start_ts="1735841280">
|
||||
<transform xil_pn:end_ts="1735898134" xil_pn:in_ck="4191604156099045257" xil_pn:name="TRAN_ISimulateBehavioralModel" xil_pn:prop_ck="-6574364550222252173" xil_pn:start_ts="1735898134">
|
||||
<status xil_pn:value="SuccessfullyRun"/>
|
||||
<status xil_pn:value="ReadyToRun"/>
|
||||
<status xil_pn:value="OutOfDateForPredecessor"/>
|
||||
<status xil_pn:value="OutOfDateForOutputs"/>
|
||||
<status xil_pn:value="OutputChanged"/>
|
||||
<outfile xil_pn:name="Test_SPICommands_isim_beh.wdb"/>
|
||||
|
|
@ -257,7 +244,7 @@
|
|||
<status xil_pn:value="SuccessfullyRun"/>
|
||||
<status xil_pn:value="ReadyToRun"/>
|
||||
</transform>
|
||||
<transform xil_pn:end_ts="1735835257" xil_pn:in_ck="-4366097307991745463" xil_pn:name="TRAN_regenerateCores" xil_pn:prop_ck="-2723611991789822717" xil_pn:start_ts="1735835257">
|
||||
<transform xil_pn:end_ts="1735889214" xil_pn:in_ck="-4366097307991745463" xil_pn:name="TRAN_regenerateCores" xil_pn:prop_ck="-2723611991789822717" xil_pn:start_ts="1735889214">
|
||||
<status xil_pn:value="SuccessfullyRun"/>
|
||||
<status xil_pn:value="ReadyToRun"/>
|
||||
<outfile xil_pn:name="ipcore_dir/DSP_SLICE.ngc"/>
|
||||
|
|
@ -286,13 +273,11 @@
|
|||
<status xil_pn:value="SuccessfullyRun"/>
|
||||
<status xil_pn:value="ReadyToRun"/>
|
||||
</transform>
|
||||
<transform xil_pn:end_ts="1735840845" xil_pn:in_ck="2241500006820465658" xil_pn:name="TRANEXT_xstsynthesize_spartan6" xil_pn:prop_ck="3256065936432453276" xil_pn:start_ts="1735840834">
|
||||
<transform xil_pn:end_ts="1735898634" xil_pn:in_ck="2241500006820465658" xil_pn:name="TRANEXT_xstsynthesize_spartan6" xil_pn:prop_ck="3256065936432453276" xil_pn:start_ts="1735898623">
|
||||
<status xil_pn:value="SuccessfullyRun"/>
|
||||
<status xil_pn:value="WarningsGenerated"/>
|
||||
<status xil_pn:value="ReadyToRun"/>
|
||||
<status xil_pn:value="OutOfDateForInputs"/>
|
||||
<status xil_pn:value="OutOfDateForOutputs"/>
|
||||
<status xil_pn:value="InputChanged"/>
|
||||
<status xil_pn:value="OutputChanged"/>
|
||||
<outfile xil_pn:name="_xmsgs/xst.xmsgs"/>
|
||||
<outfile xil_pn:name="top.lso"/>
|
||||
|
|
@ -306,33 +291,23 @@
|
|||
<outfile xil_pn:name="webtalk_pn.xml"/>
|
||||
<outfile xil_pn:name="xst"/>
|
||||
</transform>
|
||||
<transform xil_pn:end_ts="1735839469" xil_pn:in_ck="934418963425178690" xil_pn:name="TRAN_compileBCD2" xil_pn:prop_ck="6693835875156060939" xil_pn:start_ts="1735839469">
|
||||
<transform xil_pn:end_ts="1735898634" xil_pn:in_ck="934418963425178690" xil_pn:name="TRAN_compileBCD2" xil_pn:prop_ck="6693835875156060939" xil_pn:start_ts="1735898634">
|
||||
<status xil_pn:value="SuccessfullyRun"/>
|
||||
<status xil_pn:value="ReadyToRun"/>
|
||||
<status xil_pn:value="OutOfDateForInputs"/>
|
||||
<status xil_pn:value="InputChanged"/>
|
||||
</transform>
|
||||
<transform xil_pn:end_ts="1735840849" xil_pn:in_ck="5411862124762956458" xil_pn:name="TRANEXT_ngdbuild_FPGA" xil_pn:prop_ck="4604875190571501774" xil_pn:start_ts="1735840845">
|
||||
<transform xil_pn:end_ts="1735898638" xil_pn:in_ck="5411862124762956458" xil_pn:name="TRANEXT_ngdbuild_FPGA" xil_pn:prop_ck="4604875190571501774" xil_pn:start_ts="1735898634">
|
||||
<status xil_pn:value="SuccessfullyRun"/>
|
||||
<status xil_pn:value="ReadyToRun"/>
|
||||
<status xil_pn:value="OutOfDateForInputs"/>
|
||||
<status xil_pn:value="OutOfDateForPredecessor"/>
|
||||
<status xil_pn:value="InputChanged"/>
|
||||
<outfile xil_pn:name="_ngo"/>
|
||||
<outfile xil_pn:name="_xmsgs/ngdbuild.xmsgs"/>
|
||||
<outfile xil_pn:name="top.bld"/>
|
||||
<outfile xil_pn:name="top.ngd"/>
|
||||
<outfile xil_pn:name="top_ngdbuild.xrpt"/>
|
||||
</transform>
|
||||
<transform xil_pn:end_ts="1735840960" xil_pn:in_ck="8512332261572065657" xil_pn:name="TRANEXT_map_spartan6" xil_pn:prop_ck="-4668962392366239264" xil_pn:start_ts="1735840849">
|
||||
<transform xil_pn:end_ts="1735898720" xil_pn:in_ck="8512332261572065657" xil_pn:name="TRANEXT_map_spartan6" xil_pn:prop_ck="-4668962392366239264" xil_pn:start_ts="1735898638">
|
||||
<status xil_pn:value="SuccessfullyRun"/>
|
||||
<status xil_pn:value="WarningsGenerated"/>
|
||||
<status xil_pn:value="ReadyToRun"/>
|
||||
<status xil_pn:value="OutOfDateForInputs"/>
|
||||
<status xil_pn:value="OutOfDateForPredecessor"/>
|
||||
<status xil_pn:value="OutOfDateForOutputs"/>
|
||||
<status xil_pn:value="InputChanged"/>
|
||||
<status xil_pn:value="OutputChanged"/>
|
||||
<outfile xil_pn:name="_xmsgs/map.xmsgs"/>
|
||||
<outfile xil_pn:name="top.pcf"/>
|
||||
<outfile xil_pn:name="top_map.map"/>
|
||||
|
|
@ -343,12 +318,10 @@
|
|||
<outfile xil_pn:name="top_summary.xml"/>
|
||||
<outfile xil_pn:name="top_usage.xml"/>
|
||||
</transform>
|
||||
<transform xil_pn:end_ts="1735840975" xil_pn:in_ck="1117507038335044978" xil_pn:name="TRANEXT_par_spartan6" xil_pn:prop_ck="-1085068593928086116" xil_pn:start_ts="1735840960">
|
||||
<transform xil_pn:end_ts="1735898743" xil_pn:in_ck="1117507038335044978" xil_pn:name="TRANEXT_par_spartan6" xil_pn:prop_ck="-1085068593928086116" xil_pn:start_ts="1735898720">
|
||||
<status xil_pn:value="SuccessfullyRun"/>
|
||||
<status xil_pn:value="WarningsGenerated"/>
|
||||
<status xil_pn:value="ReadyToRun"/>
|
||||
<status xil_pn:value="OutOfDateForInputs"/>
|
||||
<status xil_pn:value="OutOfDateForPredecessor"/>
|
||||
<status xil_pn:value="InputChanged"/>
|
||||
<outfile xil_pn:name="_xmsgs/par.xmsgs"/>
|
||||
<outfile xil_pn:name="top.ncd"/>
|
||||
<outfile xil_pn:name="top.pad"/>
|
||||
|
|
@ -360,10 +333,9 @@
|
|||
<outfile xil_pn:name="top_pad.txt"/>
|
||||
<outfile xil_pn:name="top_par.xrpt"/>
|
||||
</transform>
|
||||
<transform xil_pn:end_ts="1735840985" xil_pn:in_ck="154288912438" xil_pn:name="TRANEXT_bitFile_spartan6" xil_pn:prop_ck="3274353840855015246" xil_pn:start_ts="1735840975">
|
||||
<transform xil_pn:end_ts="1735898752" xil_pn:in_ck="154288912438" xil_pn:name="TRANEXT_bitFile_spartan6" xil_pn:prop_ck="3274353840855015246" xil_pn:start_ts="1735898743">
|
||||
<status xil_pn:value="SuccessfullyRun"/>
|
||||
<status xil_pn:value="ReadyToRun"/>
|
||||
<status xil_pn:value="OutOfDateForPredecessor"/>
|
||||
<outfile xil_pn:name="_xmsgs/bitgen.xmsgs"/>
|
||||
<outfile xil_pn:name="top.bgn"/>
|
||||
<outfile xil_pn:name="top.bin"/>
|
||||
|
|
@ -378,7 +350,6 @@
|
|||
<status xil_pn:value="SuccessfullyRun"/>
|
||||
<status xil_pn:value="ReadyToRun"/>
|
||||
<status xil_pn:value="OutOfDateForInputs"/>
|
||||
<status xil_pn:value="OutOfDateForPredecessor"/>
|
||||
<status xil_pn:value="OutOfDateForOutputs"/>
|
||||
<status xil_pn:value="InputAdded"/>
|
||||
<status xil_pn:value="InputChanged"/>
|
||||
|
|
@ -389,7 +360,6 @@
|
|||
<status xil_pn:value="SuccessfullyRun"/>
|
||||
<status xil_pn:value="ReadyToRun"/>
|
||||
<status xil_pn:value="OutOfDateForInputs"/>
|
||||
<status xil_pn:value="OutOfDateForPredecessor"/>
|
||||
<status xil_pn:value="OutOfDateForOutputs"/>
|
||||
<status xil_pn:value="InputAdded"/>
|
||||
<status xil_pn:value="InputChanged"/>
|
||||
|
|
@ -401,7 +371,6 @@
|
|||
<status xil_pn:value="SuccessfullyRun"/>
|
||||
<status xil_pn:value="ReadyToRun"/>
|
||||
<status xil_pn:value="OutOfDateForInputs"/>
|
||||
<status xil_pn:value="OutOfDateForPredecessor"/>
|
||||
<status xil_pn:value="OutOfDateForOutputs"/>
|
||||
<status xil_pn:value="InputAdded"/>
|
||||
<status xil_pn:value="InputChanged"/>
|
||||
|
|
@ -413,17 +382,14 @@
|
|||
<status xil_pn:value="SuccessfullyRun"/>
|
||||
<status xil_pn:value="ReadyToRun"/>
|
||||
<status xil_pn:value="OutOfDateForInputs"/>
|
||||
<status xil_pn:value="OutOfDateForPredecessor"/>
|
||||
<status xil_pn:value="InputAdded"/>
|
||||
<status xil_pn:value="InputChanged"/>
|
||||
<status xil_pn:value="InputRemoved"/>
|
||||
</transform>
|
||||
<transform xil_pn:end_ts="1735840975" xil_pn:in_ck="8512326635937592693" xil_pn:name="TRAN_postRouteTrce" xil_pn:prop_ck="445577401284416184" xil_pn:start_ts="1735840971">
|
||||
<transform xil_pn:end_ts="1735898743" xil_pn:in_ck="8512326635937592693" xil_pn:name="TRAN_postRouteTrce" xil_pn:prop_ck="445577401284416184" xil_pn:start_ts="1735898738">
|
||||
<status xil_pn:value="SuccessfullyRun"/>
|
||||
<status xil_pn:value="WarningsGenerated"/>
|
||||
<status xil_pn:value="ReadyToRun"/>
|
||||
<status xil_pn:value="OutOfDateForInputs"/>
|
||||
<status xil_pn:value="OutOfDateForPredecessor"/>
|
||||
<status xil_pn:value="InputChanged"/>
|
||||
<outfile xil_pn:name="_xmsgs/trce.xmsgs"/>
|
||||
<outfile xil_pn:name="top.twr"/>
|
||||
<outfile xil_pn:name="top.twx"/>
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@ use IEEE.numeric_std.all;
|
|||
--use UNISIM.VComponents.all;
|
||||
|
||||
entity spi_slave is
|
||||
generic ( W : integer);
|
||||
generic ( W : integer;
|
||||
PREWIDTH : integer);
|
||||
Port ( SPI_CLK : in STD_LOGIC;
|
||||
MISO : out STD_LOGIC;
|
||||
MOSI : in STD_LOGIC;
|
||||
|
|
@ -39,9 +40,12 @@ entity spi_slave is
|
|||
BUF_OUT : out STD_LOGIC_VECTOR (W-1 downto 0) := (others => '0');
|
||||
BUF_IN : in STD_LOGIC_VECTOR (W-1 downto 0);
|
||||
CLK : in STD_LOGIC;
|
||||
COMPLETE : out STD_LOGIC
|
||||
-- RISING_TOGGLE : inout STD_LOGIC;
|
||||
-- FALLING_TOGGLE : inout STD_LOGIC
|
||||
COMPLETE : out STD_LOGIC;
|
||||
-- processing the complete word after it is complete leaves very little time
|
||||
-- for read operations. Indicate when the first PREWIDTH bits are ready which
|
||||
-- allows more time to prepare the response to the next word
|
||||
PRE_COMPLETE : out STD_LOGIC;
|
||||
PRE_BUF_OUT : out STD_LOGIC_VECTOR (PREWIDTH-1 downto 0) := (others => '0')
|
||||
);
|
||||
end spi_slave;
|
||||
|
||||
|
|
@ -52,6 +56,8 @@ architecture Behavioral of spi_slave is
|
|||
signal data_valid : STD_LOGIC_VECTOR(2 downto 0);
|
||||
signal data_synced : STD_LOGIC_VECTOR(2 downto 0);
|
||||
signal data : STD_LOGIC_VECTOR(W-1 downto 0);
|
||||
signal pre_data : STD_LOGIC_VECTOR(PREWIDTH-1 downto 0);
|
||||
signal pre_data_valid : STD_LOGIC_VECTOR(3 downto 0);
|
||||
|
||||
signal bit_cnt : integer range 0 to W-1;
|
||||
begin
|
||||
|
|
@ -59,9 +65,11 @@ begin
|
|||
process(CLK)
|
||||
begin
|
||||
if rising_edge(CLK) then
|
||||
data_valid(2 downto 1) <= data_valid(1 downto 0);
|
||||
COMPLETE <= '0';
|
||||
if data_valid(1) = '1' then
|
||||
PRE_COMPLETE <= '0';
|
||||
data_valid(2 downto 1) <= data_valid(1 downto 0);
|
||||
pre_data_valid(3 downto 1) <= pre_data_valid(2 downto 0);
|
||||
if data_valid(2) = '1' then
|
||||
if data_synced(0) = '0' then
|
||||
BUF_OUT <= data;
|
||||
COMPLETE <= '1';
|
||||
|
|
@ -70,19 +78,33 @@ begin
|
|||
else
|
||||
data_synced(0) <= '0';
|
||||
end if;
|
||||
if pre_data_valid(3 downto 2) = "01" then
|
||||
-- pre_data has just become valid
|
||||
PRE_BUF_OUT <= pre_data;
|
||||
PRE_COMPLETE <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
--MISO <= BUF_IN(W - 1 - bit_cnt);-- when bit_cnt = 0 else miso_buffer(W-2);
|
||||
MISO <= BUF_IN(15) when bit_cnt = 0 else miso_buffer(W-2);
|
||||
|
||||
slave_in: process(SPI_CLK)
|
||||
slave_in: process(SPI_CLK, CS)
|
||||
begin
|
||||
if rising_edge(SPI_CLK) then
|
||||
-- FALLING_TOGGLE <= not FALLING_TOGGLE;
|
||||
if CS = '1' then
|
||||
bit_cnt <= 0;
|
||||
data_valid(0) <= '0';
|
||||
pre_data_valid(0) <= '0';
|
||||
elsif rising_edge(SPI_CLK) then
|
||||
-- data input process: sample on the rising edge
|
||||
data_synced(2 downto 1) <= data_synced(1 downto 0);
|
||||
if bit_cnt = PREWIDTH-1 then
|
||||
-- first couple of bits are ready
|
||||
pre_data <= mosi_buffer(PREWIDTH-2 downto 0) & MOSI;
|
||||
pre_data_valid(0) <= '1';
|
||||
end if;
|
||||
if bit_cnt = W-1 then
|
||||
-- this was the last bit
|
||||
pre_data_valid(0) <= '0';
|
||||
data_valid(0) <= '1';
|
||||
data <= mosi_buffer(W-2 downto 0) & MOSI;
|
||||
else
|
||||
|
|
@ -91,14 +113,9 @@ begin
|
|||
end if;
|
||||
mosi_buffer <= mosi_buffer(W-3 downto 0) & MOSI;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
slave_out: process(SPI_CLK, CS, BUF_IN, bit_cnt)
|
||||
begin
|
||||
if CS = '1' then
|
||||
bit_cnt <= 0;
|
||||
elsif falling_edge(SPI_CLK) then
|
||||
|
||||
-- data output process: data should be launched on the falling edge
|
||||
-- but the delay is too large. Launch on the rising edge instead
|
||||
if bit_cnt < W-1 then
|
||||
bit_cnt <= bit_cnt + 1;
|
||||
if bit_cnt = 0 then
|
||||
|
|
@ -108,9 +125,27 @@ begin
|
|||
end if;
|
||||
else
|
||||
bit_cnt <= 0;
|
||||
--miso_buffer <= BUF_IN;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- slave_out: process(SPI_CLK, CS, BUF_IN, bit_cnt)
|
||||
-- begin
|
||||
-- if CS = '1' then
|
||||
-- bit_cnt <= 0;
|
||||
-- elsif falling_edge(SPI_CLK) then
|
||||
-- if bit_cnt < W-1 then
|
||||
-- bit_cnt <= bit_cnt + 1;
|
||||
-- if bit_cnt = 0 then
|
||||
-- miso_buffer <= BUF_IN;
|
||||
-- else
|
||||
-- miso_buffer <= miso_buffer(W-2 downto 0) & '0';
|
||||
-- end if;
|
||||
-- else
|
||||
-- bit_cnt <= 0;
|
||||
-- --miso_buffer <= BUF_IN;
|
||||
-- end if;
|
||||
-- end if;
|
||||
-- end process;
|
||||
|
||||
end Behavioral;
|
||||
BIN
FPGA/VNA/top.bin
BIN
FPGA/VNA/top.bin
Binary file not shown.
|
|
@ -1,9 +1,23 @@
|
|||
CONFIG VCCAUX = 3.3;
|
||||
# Global FPGA clock
|
||||
NET "CLK" PERIOD = 62.5 ns HIGH 50%;
|
||||
|
||||
# Constraints for SPI interface to MCU
|
||||
NET "MCU_SCK" PERIOD = 23.52941176ns HIGH 50%;
|
||||
NET "MCU_MOSI" OFFSET = IN 2ns VALID 3ns BEFORE "MCU_SCK";
|
||||
NET "MCU_MISO" OFFSET = OUT 18.529ns VALID 10ns AFTER "MCU_SCK";
|
||||
NET "MCU_MISO" SLEW = FAST;
|
||||
|
||||
# ADC constraints
|
||||
NET "REF_SCLK" PERIOD = 19.5ns HIGH 50%;
|
||||
NET "REF_SDO" OFFSET = IN 9ns VALID 9ns BEFORE "REF_SCLK";
|
||||
NET "PORT1_SCLK" PERIOD = 19.5ns HIGH 50%;
|
||||
NET "PORT1_SDO" OFFSET = IN 9ns VALID 9ns BEFORE "PORT1_SCLK";
|
||||
NET "PORT2_SCLK" PERIOD = 19.5ns HIGH 50%;
|
||||
NET "PORT2_SDO" OFFSET = IN 9ns VALID 9ns BEFORE "PORT2_SCLK";
|
||||
NET "PORT1_SCLK" SLEW = FAST;
|
||||
NET "PORT2_SCLK" SLEW = FAST;
|
||||
NET "REF_SCLK" SLEW = FAST;
|
||||
|
||||
NET "ATTENUATION[6]" IOSTANDARD = LVCMOS33;
|
||||
NET "ATTENUATION[5]" IOSTANDARD = LVCMOS33;
|
||||
|
|
@ -63,10 +77,6 @@ NET "MCU_AUX3" IOSTANDARD = LVCMOS33;
|
|||
NET "TRIGGER_IN" IOSTANDARD = LVCMOS33;
|
||||
NET "TRIGGER_OUT" IOSTANDARD = LVCMOS33;
|
||||
|
||||
NET "PORT1_SCLK" SLEW = FAST;
|
||||
NET "PORT2_SCLK" SLEW = FAST;
|
||||
NET "REF_SCLK" SLEW = FAST;
|
||||
|
||||
NET "ATTENUATION[6]" LOC = P9;
|
||||
NET "ATTENUATION[5]" LOC = P10;
|
||||
NET "ATTENUATION[4]" LOC = P11;
|
||||
|
|
|
|||
|
|
@ -562,7 +562,7 @@ begin
|
|||
|
||||
|
||||
Source: MAX2871
|
||||
GENERIC MAP(CLK_DIV => 10)
|
||||
GENERIC MAP(CLK_DIV => 6)
|
||||
PORT MAP(
|
||||
CLK => clk_pll,
|
||||
RESET => int_reset,
|
||||
|
|
@ -577,7 +577,7 @@ begin
|
|||
DONE => source_reloaded
|
||||
);
|
||||
LO1: MAX2871
|
||||
GENERIC MAP(CLK_DIV => 10)
|
||||
GENERIC MAP(CLK_DIV => 6)
|
||||
PORT MAP(
|
||||
CLK => clk_pll,
|
||||
RESET => int_reset,
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ void DeviceConfigurationDialogV1::updateGUI(const Protocol::DeviceConfig &c)
|
|||
ui->IF1->setEnabled(true);
|
||||
ui->ADCpresc->setValue(c.V1.ADCprescaler);
|
||||
ui->ADCphaseInc->setValue(c.V1.DFTphaseInc);
|
||||
ui->PLLSettlingDelay->setValue(c.V1.PLLSettlingDelay);
|
||||
}
|
||||
|
||||
void DeviceConfigurationDialogV1::updateDevice()
|
||||
|
|
@ -80,5 +81,6 @@ void DeviceConfigurationDialogV1::updateDevice()
|
|||
p.deviceConfig.V1.IF1 = ui->IF1->value();
|
||||
p.deviceConfig.V1.ADCprescaler = ui->ADCpresc->value();
|
||||
p.deviceConfig.V1.DFTphaseInc = ui->ADCphaseInc->value();
|
||||
p.deviceConfig.V1.PLLSettlingDelay = ui->PLLSettlingDelay->value();
|
||||
dev.SendPacket(p);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,14 +6,24 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>487</width>
|
||||
<height>356</height>
|
||||
<width>454</width>
|
||||
<height>464</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Device Configuration</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>This dialog contains advanced system settings. It is recommended to leave them at default values unless you know what you are doing.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_15">
|
||||
<property name="title">
|
||||
|
|
@ -23,26 +33,13 @@
|
|||
<item>
|
||||
<widget class="QLabel" name="label_34">
|
||||
<property name="text">
|
||||
<string>This section contains advanced system settings. It is recommended to leave them at default values unless you know what you are doing. Slight changes of the IF frequencies can be used to shift possible spikes to less problematic frequencies. Large changes of these frequencies may severely impact device performance.</string>
|
||||
<string>Slight changes of the IF frequencies can be used to shift possible spikes to less problematic frequencies. Large changes of these frequencies may severely impact device performance.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
|
|
@ -138,6 +135,32 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Other settings</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>PLL settling delay [us]:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="PLLSettlingDelay">
|
||||
<property name="minimum">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>255</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
|
|
|
|||
|
|
@ -684,7 +684,6 @@ void LibreVNADriver::handleReceivedPacket(const Protocol::PacketInfo &packet)
|
|||
info.Limits.VNA.maxIFBW = packet.info.limits_maxIFBW;
|
||||
info.Limits.VNA.mindBm = (double) packet.info.limits_cdbm_min / 100;
|
||||
info.Limits.VNA.maxdBm = (double) packet.info.limits_cdbm_max / 100;
|
||||
info.Limits.VNA.minDwellTime = (double) packet.info.limits_minDwellTime * 1e-6;
|
||||
info.Limits.VNA.maxDwellTime = (double) packet.info.limits_maxDwellTime * 1e-6;
|
||||
|
||||
info.Limits.Generator.ports = packet.info.num_ports;
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ LibreVNAUSBDriver::LibreVNAUSBDriver()
|
|||
dataBuffer = nullptr;
|
||||
logBuffer = nullptr;
|
||||
m_receiveThread = nullptr;
|
||||
lastTimestamp = QDateTime::currentDateTime();
|
||||
byteCnt = 0;
|
||||
|
||||
specificSettings.push_back(Savable::SettingDescription(&captureRawReceiverValues, "LibreVNAUSBDriver.captureRawReceiverValues", false));
|
||||
specificSettings.push_back(Savable::SettingDescription(&harmonicMixing, "LibreVNAUSBDriver.harmonicMixing", false));
|
||||
|
|
@ -183,11 +185,19 @@ void LibreVNAUSBDriver::ReceivedData()
|
|||
case Protocol::PacketType::Nack:
|
||||
emit receivedAnswer(TransmissionResult::Nack);
|
||||
break;
|
||||
default:
|
||||
default:
|
||||
// pass on to LibreVNADriver class
|
||||
emit receivedPacket(packet);
|
||||
break;
|
||||
}
|
||||
// byteCnt += handled_len;
|
||||
// auto now = QDateTime::currentDateTime();
|
||||
// if(lastTimestamp.time().msecsTo(now.time()) > 1000) {
|
||||
// lastTimestamp = now;
|
||||
// constexpr unsigned int maxThroughput = 12000000 / 8;
|
||||
// qDebug() << "USB throughput: " << byteCnt << "(" << (double) byteCnt * 100.0 / maxThroughput << "%)";
|
||||
// byteCnt = 0;
|
||||
// }
|
||||
} while (handled_len > 0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <QQueue>
|
||||
#include <QTimer>
|
||||
#include <QDateTime>
|
||||
|
||||
class LibreVNAUSBDriver : public LibreVNADriver
|
||||
{
|
||||
|
|
@ -76,6 +77,11 @@ private:
|
|||
std::thread *m_receiveThread;
|
||||
|
||||
std::mutex accessMutex;
|
||||
|
||||
// USB throughput indicator
|
||||
QDateTime lastTimestamp;
|
||||
unsigned long byteCnt;
|
||||
|
||||
};
|
||||
|
||||
#endif // LIBREVNAUSBDRIVER_H
|
||||
|
|
|
|||
|
|
@ -118,7 +118,6 @@ DeviceDriver::Info::Info()
|
|||
Limits.VNA.minIFBW = 1;
|
||||
Limits.VNA.maxIFBW = 100000000;
|
||||
Limits.VNA.maxPoints = 65535;
|
||||
Limits.VNA.minDwellTime = 0;
|
||||
Limits.VNA.maxDwellTime = 1;
|
||||
|
||||
Limits.Generator.ports = 2;
|
||||
|
|
|
|||
|
|
@ -102,8 +102,8 @@ public:
|
|||
unsigned int maxPoints;
|
||||
// Stimulus level limits in dBm
|
||||
double mindBm, maxdBm;
|
||||
// dwell time limts
|
||||
double minDwellTime, maxDwellTime;
|
||||
// dwell time limit
|
||||
double maxDwellTime;
|
||||
} VNA;
|
||||
struct {
|
||||
// Number of ports
|
||||
|
|
|
|||
|
|
@ -788,8 +788,10 @@ void Marker::parentTraceDeleted(Trace *t)
|
|||
}
|
||||
}
|
||||
|
||||
void Marker::traceDataChanged()
|
||||
void Marker::traceDataChanged(unsigned int begin, unsigned int end)
|
||||
{
|
||||
Q_UNUSED(begin)
|
||||
Q_UNUSED(end)
|
||||
complex<double> newdata;
|
||||
if(!parentTrace || parentTrace->numSamples() == 0) {
|
||||
// no data, invalidate
|
||||
|
|
@ -1088,7 +1090,7 @@ void Marker::constrainPosition()
|
|||
position = parentTrace->sample(parentTrace->index(position)).x;
|
||||
}
|
||||
}
|
||||
traceDataChanged();
|
||||
traceDataChanged(0, parentTrace->size());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ signals:
|
|||
|
||||
private slots:
|
||||
void parentTraceDeleted(Trace *t);
|
||||
void traceDataChanged();
|
||||
void traceDataChanged(unsigned int begin, unsigned int end);
|
||||
void updateSymbol();
|
||||
void checkDeltaMarker();
|
||||
void deltaDeleted();
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ void Math::DFT::inputSamplesChanged(unsigned int begin, unsigned int end)
|
|||
{
|
||||
Q_UNUSED(begin);
|
||||
Q_UNUSED(end);
|
||||
if(input->getData().size() < 2) {
|
||||
if(input->numSamples() < 2) {
|
||||
// not enough input data
|
||||
clearOutput();
|
||||
warning("Not enough input samples");
|
||||
|
|
@ -161,7 +161,7 @@ void Math::DFT::inputSamplesChanged(unsigned int begin, unsigned int end)
|
|||
void Math::DFT::updateDFT()
|
||||
{
|
||||
if(dataType != DataType::Invalid) {
|
||||
inputSamplesChanged(0, input->getData().size());
|
||||
inputSamplesChanged(0, input->numSamples());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -142,6 +142,6 @@ void Math::Expression::expressionChanged()
|
|||
break;
|
||||
}
|
||||
if(input) {
|
||||
inputSamplesChanged(0, input->getData().size());
|
||||
inputSamplesChanged(0, input->numSamples());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ void TDR::setMode(Mode m)
|
|||
}
|
||||
mode = m;
|
||||
if(input) {
|
||||
inputSamplesChanged(0, input->getData().size());
|
||||
inputSamplesChanged(0, input->numSamples());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -213,7 +213,7 @@ void TDR::inputSamplesChanged(unsigned int begin, unsigned int end)
|
|||
{
|
||||
Q_UNUSED(begin);
|
||||
Q_UNUSED(end);
|
||||
if(input->getData().size() >= 2) {
|
||||
if(input->numSamples() >= 2) {
|
||||
// trigger calculation in thread
|
||||
semphr.release();
|
||||
success();
|
||||
|
|
@ -227,7 +227,7 @@ void TDR::inputSamplesChanged(unsigned int begin, unsigned int end)
|
|||
void TDR::updateTDR()
|
||||
{
|
||||
if(dataType != DataType::Invalid) {
|
||||
inputSamplesChanged(0, input->getData().size());
|
||||
inputSamplesChanged(0, input->numSamples());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -324,3 +324,29 @@ std::vector<TraceMath::Data> TraceMath::getData()
|
|||
dataMutex.unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
double TraceMath::minX()
|
||||
{
|
||||
double ret;
|
||||
dataMutex.lock();
|
||||
if(data.size() > 0) {
|
||||
ret = data.front().x;
|
||||
} else {
|
||||
ret = std::numeric_limits<double>::max();
|
||||
}
|
||||
dataMutex.unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
double TraceMath::maxX()
|
||||
{
|
||||
double ret;
|
||||
dataMutex.lock();
|
||||
if(data.size() > 0) {
|
||||
ret = data.back().x;
|
||||
} else {
|
||||
ret = std::numeric_limits<double>::min();
|
||||
}
|
||||
dataMutex.unlock();
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
class Trace;
|
||||
|
||||
class TraceMath : public QObject, public Savable {
|
||||
friend class Trace;
|
||||
Q_OBJECT
|
||||
public:
|
||||
TraceMath();
|
||||
|
|
@ -112,6 +113,8 @@ public:
|
|||
|
||||
DataType getDataType() const;
|
||||
virtual std::vector<Data> getData();
|
||||
virtual double minX();
|
||||
virtual double maxX();
|
||||
Status getStatus() const;
|
||||
QString getStatusDescription() const;
|
||||
virtual Type getType() = 0;
|
||||
|
|
|
|||
|
|
@ -1354,19 +1354,19 @@ void Trace::clearDeembedding()
|
|||
|
||||
double Trace::minX()
|
||||
{
|
||||
if(lastMath->numSamples() > 0) {
|
||||
return lastMath->getData().front().x;
|
||||
if(lastMath == this) {
|
||||
return TraceMath::minX();
|
||||
} else {
|
||||
return numeric_limits<double>::max();
|
||||
return lastMath->minX();
|
||||
}
|
||||
}
|
||||
|
||||
double Trace::maxX()
|
||||
{
|
||||
if(lastMath->numSamples() > 0) {
|
||||
return lastMath->getData().back().x;
|
||||
if(lastMath == this) {
|
||||
return TraceMath::maxX();
|
||||
} else {
|
||||
return numeric_limits<double>::lowest();
|
||||
return lastMath->maxX();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1620,12 +1620,16 @@ double Trace::getGroupDelay(double frequency)
|
|||
|
||||
int Trace::index(double x)
|
||||
{
|
||||
auto lower = lower_bound(lastMath->getData().begin(), lastMath->getData().end(), x, [](const Data &lhs, const double x) -> bool {
|
||||
int ret;
|
||||
lastMath->dataMutex.lock();
|
||||
auto lower = lower_bound(lastMath->data.begin(), lastMath->data.end(), x, [](const Data &lhs, const double x) -> bool {
|
||||
return lhs.x < x;
|
||||
});
|
||||
if(lower == lastMath->getData().end()) {
|
||||
if(lower == lastMath->data.end()) {
|
||||
// actually beyond the last sample, return the index of the last anyway to avoid access past data
|
||||
return lastMath->getData().size() - 1;
|
||||
ret = lastMath->data.size() - 1;
|
||||
}
|
||||
return lower - lastMath->getData().begin();
|
||||
ret = lower - lastMath->data.begin();
|
||||
lastMath->dataMutex.unlock();
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,8 +74,8 @@ public:
|
|||
void setDeembeddingActive(bool active);
|
||||
void clearDeembedding();
|
||||
|
||||
double minX();
|
||||
double maxX();
|
||||
double minX() override;
|
||||
double maxX() override;
|
||||
double findExtremum(bool max, double xmin = std::numeric_limits<double>::lowest(), double xmax = std::numeric_limits<double>::max());
|
||||
/* Searches for peaks in the trace data and returns the peak frequencies in ascending order.
|
||||
* Up to maxPeaks will be returned, with higher level peaks taking priority over lower level peaks.
|
||||
|
|
|
|||
|
|
@ -653,6 +653,7 @@ VNA::VNA(AppWindow *window, QString name)
|
|||
SetPowerSweepFrequency(pref.Startup.DefaultSweep.dbm_freq);
|
||||
SetIFBandwidth(pref.Startup.DefaultSweep.bandwidth);
|
||||
SetAveraging(pref.Startup.DefaultSweep.averaging);
|
||||
SetDwellTime(pref.Startup.DefaultSweep.dwellTime);
|
||||
SetPoints(pref.Startup.DefaultSweep.points);
|
||||
if(pref.Startup.DefaultSweep.type == "Power Sweep") {
|
||||
SetSweepType(SweepType::Power);
|
||||
|
|
@ -836,6 +837,7 @@ void VNA::resetSettings()
|
|||
SetStopPower(DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxdBm);
|
||||
SetPowerSweepFrequency(DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxFreq);
|
||||
SetIFBandwidth(1000);
|
||||
SetDwellTime(0);
|
||||
SetAveraging(1);
|
||||
SetPoints(501);
|
||||
SetSweepType(SweepType::Frequency);
|
||||
|
|
@ -1246,8 +1248,6 @@ void VNA::SetSourceLevel(double level)
|
|||
void VNA::SetDwellTime(double time) {
|
||||
if(time > DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxDwellTime) {
|
||||
time = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxDwellTime;
|
||||
} else if(time < DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minDwellTime) {
|
||||
time = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minDwellTime;
|
||||
}
|
||||
emit dwellTimeChanged(time);
|
||||
settings.dwellTime = time;
|
||||
|
|
@ -1640,6 +1640,7 @@ void VNA::LoadSweepSettings()
|
|||
SetPoints(s.value("SweepPoints", pref.Startup.DefaultSweep.points).toInt());
|
||||
SetIFBandwidth(s.value("SweepBandwidth", pref.Startup.DefaultSweep.bandwidth).toUInt());
|
||||
SetAveraging(s.value("SweepAveraging", pref.Startup.DefaultSweep.averaging).toInt());
|
||||
SetDwellTime(s.value("SweepDwellTime", pref.Startup.DefaultSweep.dwellTime).toDouble());
|
||||
ConstrainAndUpdateFrequencies();
|
||||
auto typeString = s.value("SweepType", pref.Startup.DefaultSweep.type).toString();
|
||||
if(typeString == "Power") {
|
||||
|
|
@ -1663,6 +1664,7 @@ void VNA::StoreSweepSettings()
|
|||
s.setValue("SweepBandwidth", settings.bandwidth);
|
||||
s.setValue("SweepPoints", settings.npoints);
|
||||
s.setValue("SweepAveraging", averages);
|
||||
s.setValue("SweepDwellTime", settings.dwellTime);
|
||||
}
|
||||
|
||||
void VNA::UpdateCalWidget()
|
||||
|
|
@ -1680,13 +1682,12 @@ void VNA::ConstrainAllSettings()
|
|||
auto maxIFBW = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxIFBW;
|
||||
auto minIFBW = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minIFBW;
|
||||
auto maxDwell = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxDwellTime;
|
||||
auto minDwell = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minDwellTime;
|
||||
auto maxPoints = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxPoints;
|
||||
Util::constrain(settings.Freq.start, minFreq, maxFreq);
|
||||
Util::constrain(settings.Freq.stop, minFreq, maxFreq);
|
||||
Util::constrain(settings.Freq.excitation_power, minPower, maxPower);
|
||||
Util::constrain(settings.bandwidth, minIFBW, maxIFBW);
|
||||
Util::constrain(settings.dwellTime, minDwell, maxDwell);
|
||||
Util::constrain(settings.dwellTime, 0.0, maxDwell);
|
||||
Util::constrain(settings.npoints, (unsigned int) 0, maxPoints);
|
||||
Util::constrain(settings.Power.frequency, minFreq, maxFreq);
|
||||
Util::constrain(settings.Power.start, minPower, maxPower);
|
||||
|
|
@ -1832,7 +1833,7 @@ void VNA::preset()
|
|||
|
||||
void VNA::deviceInfoUpdated()
|
||||
{
|
||||
if(DeviceDriver::getInfo(window->getDevice()).supportedFeatures.count(DeviceDriver::Feature::VNADwellTime)) {
|
||||
if(window->getDevice()->supports(DeviceDriver::Feature::VNADwellTime)) {
|
||||
acquisitionDwellTime->setEnabled(true);
|
||||
} else {
|
||||
acquisitionDwellTime->setEnabled(false);
|
||||
|
|
|
|||
|
|
@ -78,6 +78,9 @@ PreferencesDialog::PreferencesDialog(Preferences *pref, QWidget *parent) :
|
|||
ui->StartupSweepPowerFrequency->setPrefixes(" kMG");
|
||||
ui->StartupSweepBandwidth->setUnit("Hz");
|
||||
ui->StartupSweepBandwidth->setPrefixes(" k");
|
||||
ui->StartupSweepDwellTime->setUnit("s");
|
||||
ui->StartupSweepDwellTime->setPrefixes("um ");
|
||||
ui->StartupSweepDwellTime->setPrecision(3);
|
||||
ui->StartupGeneratorFrequency->setUnit("Hz");
|
||||
ui->StartupGeneratorFrequency->setPrefixes(" kMG");
|
||||
ui->StartupSAStart->setUnit("Hz");
|
||||
|
|
@ -246,6 +249,7 @@ void PreferencesDialog::setInitialGUIState()
|
|||
ui->StartupGeneratorFrequency->setValue(p->Startup.Generator.frequency);
|
||||
ui->StartupGeneratorLevel->setValue(p->Startup.Generator.level);
|
||||
ui->StartupSweepAveraging->setValue(p->Startup.DefaultSweep.averaging);
|
||||
ui->StartupSweepDwellTime->setValue(p->Startup.DefaultSweep.dwellTime);
|
||||
ui->StartupSAStart->setValue(p->Startup.SA.start);
|
||||
ui->StartupSAStop->setValue(p->Startup.SA.stop);
|
||||
ui->StartupSARBW->setValue(p->Startup.SA.RBW);
|
||||
|
|
@ -360,6 +364,7 @@ void PreferencesDialog::updateFromGUI()
|
|||
p->Startup.DefaultSweep.bandwidth = ui->StartupSweepBandwidth->value();
|
||||
p->Startup.DefaultSweep.points = ui->StartupSweepPoints->value();
|
||||
p->Startup.DefaultSweep.averaging = ui->StartupSweepAveraging->value();
|
||||
p->Startup.DefaultSweep.dwellTime = ui->StartupSweepDwellTime->value();
|
||||
p->Startup.Generator.frequency = ui->StartupGeneratorFrequency->value();
|
||||
p->Startup.Generator.level = ui->StartupGeneratorLevel->value();
|
||||
p->Startup.SA.start = ui->StartupSAStart->value();
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ public:
|
|||
int points;
|
||||
double bandwidth;
|
||||
int averaging;
|
||||
double dwellTime;
|
||||
} DefaultSweep;
|
||||
struct {
|
||||
double frequency;
|
||||
|
|
@ -232,6 +233,7 @@ private:
|
|||
{&Startup.DefaultSweep.points, "Startup.DefaultSweep.points", 501},
|
||||
{&Startup.DefaultSweep.bandwidth, "Startup.DefaultSweep.bandwidth", 1000.0},
|
||||
{&Startup.DefaultSweep.averaging, "Startup.DefaultSweep.averaging", 1},
|
||||
{&Startup.DefaultSweep.dwellTime, "Startup.DefaultSweep.dwellTime", 60e-6},
|
||||
{&Startup.Generator.frequency, "Startup.Generator.frequency", 1000000000.0},
|
||||
{&Startup.Generator.level, "Startup.Generator.level", -10.00},
|
||||
{&Startup.SA.start, "Startup.SA.start", 950000000.0},
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
<item>
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QTreeWidget" name="treeWidget">
|
||||
<property name="sizePolicy">
|
||||
|
|
@ -98,7 +98,7 @@
|
|||
</size>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>2</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="Startup">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
|
|
@ -111,9 +111,9 @@
|
|||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>-206</y>
|
||||
<width>679</width>
|
||||
<height>836</height>
|
||||
<y>0</y>
|
||||
<width>683</width>
|
||||
<height>928</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_13">
|
||||
|
|
@ -167,7 +167,7 @@
|
|||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
|
@ -201,7 +201,7 @@
|
|||
<item>
|
||||
<spacer name="verticalSpacer_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
|
@ -268,7 +268,7 @@
|
|||
<item>
|
||||
<spacer name="verticalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
|
@ -493,6 +493,16 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_63">
|
||||
<property name="text">
|
||||
<string>Dwell Time:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="SIUnitEdit" name="StartupSweepDwellTime"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
|
|
@ -673,7 +683,7 @@
|
|||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
|
@ -703,8 +713,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>696</width>
|
||||
<height>564</height>
|
||||
<width>564</width>
|
||||
<height>477</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_21">
|
||||
|
|
@ -867,7 +877,7 @@
|
|||
<item>
|
||||
<spacer name="horizontalSpacer_8">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
|
@ -898,7 +908,7 @@
|
|||
<item>
|
||||
<spacer name="horizontalSpacer_9">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
|
@ -916,7 +926,7 @@
|
|||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
|
@ -943,9 +953,9 @@
|
|||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>-400</y>
|
||||
<width>679</width>
|
||||
<height>992</height>
|
||||
<y>0</y>
|
||||
<width>683</width>
|
||||
<height>1118</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_22">
|
||||
|
|
@ -1233,7 +1243,7 @@
|
|||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
|
@ -1257,7 +1267,7 @@
|
|||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
|
@ -1291,7 +1301,7 @@
|
|||
<item>
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
|
@ -1436,7 +1446,7 @@
|
|||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
|
@ -1466,8 +1476,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>402</width>
|
||||
<height>540</height>
|
||||
<width>683</width>
|
||||
<height>605</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||
|
|
@ -1684,7 +1694,7 @@
|
|||
<item>
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
|
@ -1711,7 +1721,7 @@
|
|||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="MarkerInterpolate">
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QComboBox::AdjustToContents</enum>
|
||||
<enum>QComboBox::SizeAdjustPolicy::AdjustToContents</enum>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
|
|
@ -1782,7 +1792,7 @@
|
|||
<item>
|
||||
<spacer name="verticalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
|
@ -1812,8 +1822,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>138</width>
|
||||
<height>112</height>
|
||||
<width>697</width>
|
||||
<height>563</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_12">
|
||||
|
|
@ -1859,7 +1869,7 @@
|
|||
<item>
|
||||
<spacer name="verticalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
|
@ -1874,7 +1884,7 @@
|
|||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
|
@ -2056,7 +2066,7 @@
|
|||
<item>
|
||||
<spacer name="verticalSpacer_8">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
|
@ -2071,7 +2081,7 @@
|
|||
<item>
|
||||
<spacer name="horizontalSpacer_10">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
|
@ -2095,8 +2105,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>696</width>
|
||||
<height>564</height>
|
||||
<width>697</width>
|
||||
<height>563</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_19">
|
||||
|
|
@ -2156,7 +2166,7 @@
|
|||
<item>
|
||||
<spacer name="verticalSpacer_9">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
|
@ -2171,7 +2181,7 @@
|
|||
<item>
|
||||
<spacer name="horizontalSpacer_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
|
|
@ -2193,10 +2203,10 @@
|
|||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Apply|QDialogButtonBox::Ok|QDialogButtonBox::Open|QDialogButtonBox::RestoreDefaults|QDialogButtonBox::Save</set>
|
||||
<set>QDialogButtonBox::StandardButton::Apply|QDialogButtonBox::StandardButton::Ok|QDialogButtonBox::StandardButton::Open|QDialogButtonBox::StandardButton::RestoreDefaults|QDialogButtonBox::StandardButton::Save</set>
|
||||
</property>
|
||||
<property name="centerButtons">
|
||||
<bool>false</bool>
|
||||
|
|
|
|||
|
|
@ -273,7 +273,7 @@ inline void App_Process() {
|
|||
}
|
||||
break;
|
||||
case Protocol::PacketType::DeviceConfiguration:
|
||||
HW::setAcquisitionFrequencies(recv_packet.deviceConfig);
|
||||
HW::setDeviceConfig(recv_packet.deviceConfig);
|
||||
Communication::SendWithoutPayload(Protocol::PacketType::Ack);
|
||||
break;
|
||||
case Protocol::PacketType::SetTrigger:
|
||||
|
|
|
|||
|
|
@ -216,7 +216,6 @@ using DeviceInfo = struct _deviceInfo {
|
|||
uint8_t limits_maxAmplitudePoints;
|
||||
uint64_t limits_maxFreqHarmonic;
|
||||
uint8_t num_ports;
|
||||
uint16_t limits_minDwellTime;
|
||||
uint16_t limits_maxDwellTime;
|
||||
};
|
||||
|
||||
|
|
@ -440,6 +439,7 @@ using DeviceConfig = struct _deviceconfig {
|
|||
uint32_t IF1;
|
||||
uint8_t ADCprescaler;
|
||||
uint16_t DFTphaseInc;
|
||||
uint8_t PLLSettlingDelay;
|
||||
} V1;
|
||||
struct {
|
||||
uint32_t ip;
|
||||
|
|
|
|||
|
|
@ -353,7 +353,7 @@ void FPGA::SetMode(Mode mode) {
|
|||
Low(AUX2);
|
||||
Delay::us(1);
|
||||
High(CS);
|
||||
// Configure SPI to use faster speed of 32MHz
|
||||
// Configure SPI to use faster speed of 42.5MHz
|
||||
FPGA_SPI.Instance->CR1 = (FPGA_SPI.Instance->CR1 & ~SPI_CR1_BR_Msk) | SPI_BAUDRATEPRESCALER_4;
|
||||
break;
|
||||
case Mode::SourcePLL:
|
||||
|
|
@ -361,15 +361,15 @@ void FPGA::SetMode(Mode mode) {
|
|||
Low(AUX2);
|
||||
Delay::us(1);
|
||||
High(AUX1);
|
||||
// Configure SPI to use slower speed of 16MHz (MAX2871 is limited to 20MHz)
|
||||
FPGA_SPI.Instance->CR1 = (FPGA_SPI.Instance->CR1 & ~SPI_CR1_BR_Msk) | SPI_BAUDRATEPRESCALER_8;
|
||||
// Configure SPI to use slower speed of 10.625MHz (MAX2871 is limited to 20MHz)
|
||||
FPGA_SPI.Instance->CR1 = (FPGA_SPI.Instance->CR1 & ~SPI_CR1_BR_Msk) | SPI_BAUDRATEPRESCALER_16;
|
||||
break;
|
||||
case Mode::LOPLL:
|
||||
Low(CS);
|
||||
Low(AUX1);
|
||||
Delay::us(1);
|
||||
High(AUX2);
|
||||
// Configure SPI to use slower speed of 16MHz (MAX2871 is limited to 20MHz)
|
||||
// Configure SPI to use slower speed of 10.625MHz (MAX2871 is limited to 20MHz)
|
||||
FPGA_SPI.Instance->CR1 = (FPGA_SPI.Instance->CR1 & ~SPI_CR1_BR_Msk) | SPI_BAUDRATEPRESCALER_8;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
#include "stm.hpp"
|
||||
|
||||
#define LOG_LEVEL LOG_LEVEL_INFO
|
||||
#define LOG_MODULE "STM"
|
||||
#include "Log.h"
|
||||
|
||||
using Callback = void(*)(void);
|
||||
static constexpr uint8_t numCallbacks = 10;
|
||||
static Callback callbacks[numCallbacks];
|
||||
|
|
@ -34,6 +38,7 @@ bool STM::DispatchToInterrupt(void (*cb)(void)) {
|
|||
return true;
|
||||
} else {
|
||||
// already at limit
|
||||
LOG_ERR("Interrupt dispatch queue full");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,11 +26,17 @@ static bool StatusUpdateFlag = true;
|
|||
static Protocol::ReferenceSettings ref;
|
||||
static volatile uint64_t lastISR;
|
||||
|
||||
static uint32_t IF1 = HW::DefaultIF1;
|
||||
static uint32_t IF2 = HW::DefaultIF2;
|
||||
static uint32_t ADCsamplerate = HW::DefaultADCSamplerate;
|
||||
static uint8_t ADCprescaler = HW::DefaultADCprescaler;
|
||||
static uint16_t DFTphaseInc = HW::DefaultDFTphaseInc;
|
||||
// increment when device config struct format changed. If a wrong version is found in flash, it will revert to default values
|
||||
static constexpr uint16_t deviceConfigVersion = 0x001;
|
||||
|
||||
using DeviceConfig = struct _devicConfig {
|
||||
uint16_t version;
|
||||
Protocol::DeviceConfig config;
|
||||
uint32_t IF2;
|
||||
uint32_t ADCsamplerate;
|
||||
};
|
||||
|
||||
static DeviceConfig deviceConfig;
|
||||
|
||||
using namespace HWHAL;
|
||||
|
||||
|
|
@ -100,6 +106,8 @@ bool HW::Init() {
|
|||
|
||||
activeMode = Mode::Idle;
|
||||
|
||||
LoadDeviceConfig();
|
||||
|
||||
Si5351.Init();
|
||||
|
||||
// Use Si5351 to generate reference frequencies for other PLLs and ADC
|
||||
|
|
@ -152,12 +160,12 @@ bool HW::Init() {
|
|||
FPGA::DisableHardwareOverwrite();
|
||||
|
||||
// Set default ADC samplerate
|
||||
FPGA::WriteRegister(FPGA::Reg::ADCPrescaler, ADCprescaler);
|
||||
FPGA::WriteRegister(FPGA::Reg::ADCPrescaler, deviceConfig.config.V1.ADCprescaler);
|
||||
// Set phase increment according to
|
||||
FPGA::WriteRegister(FPGA::Reg::PhaseIncrement, DFTphaseInc);
|
||||
FPGA::WriteRegister(FPGA::Reg::PhaseIncrement, deviceConfig.config.V1.DFTphaseInc);
|
||||
|
||||
// Set default settling time
|
||||
FPGA::SetSettlingTime(HW::DefaultDwellTime);
|
||||
FPGA::SetSettlingTime(deviceConfig.config.V1.PLLSettlingDelay);
|
||||
|
||||
Exti::SetCallback(FPGA_INTR_GPIO_Port, FPGA_INTR_Pin, Exti::EdgeType::Rising, Exti::Pull::Down, FPGA_Interrupt);
|
||||
|
||||
|
|
@ -190,7 +198,7 @@ bool HW::Init() {
|
|||
} else {
|
||||
LOG_INFO("LO1 VCO map complete");
|
||||
}
|
||||
LO1.SetFrequency(1000000000 + IF1);
|
||||
LO1.SetFrequency(1000000000 + deviceConfig.config.V1.IF1);
|
||||
LO1.UpdateFrequency();
|
||||
LOG_DEBUG("LO temp: %u", LO1.GetTemp());
|
||||
|
||||
|
|
@ -428,37 +436,39 @@ Si5351C::PLLSource HW::Ref::getSource() {
|
|||
}
|
||||
}
|
||||
|
||||
void HW::setAcquisitionFrequencies(Protocol::DeviceConfig s) {
|
||||
IF1 = s.V1.IF1;
|
||||
ADCprescaler = s.V1.ADCprescaler;
|
||||
DFTphaseInc = s.V1.DFTphaseInc;
|
||||
float ADCrate = (float) FPGA::Clockrate / ADCprescaler;
|
||||
IF2 = ADCrate * DFTphaseInc / 4096;
|
||||
ADCsamplerate = ADCrate;
|
||||
static void updateOtherParametersFromProtocolDeviceConfig() {
|
||||
float ADCrate = (float) FPGA::Clockrate / deviceConfig.config.V1.ADCprescaler;
|
||||
deviceConfig.IF2 = ADCrate * deviceConfig.config.V1.DFTphaseInc / 4096;
|
||||
deviceConfig.ADCsamplerate = ADCrate;
|
||||
}
|
||||
|
||||
void HW::setDeviceConfig(Protocol::DeviceConfig s) {
|
||||
deviceConfig.config = s;
|
||||
if(deviceConfig.config.V1.PLLSettlingDelay < HW::MinPLLSettlingDelay) {
|
||||
deviceConfig.config.V1.PLLSettlingDelay = HW::MinPLLSettlingDelay;
|
||||
}
|
||||
updateOtherParametersFromProtocolDeviceConfig();
|
||||
SaveDeviceConfig();
|
||||
}
|
||||
|
||||
Protocol::DeviceConfig HW::getDeviceConfig() {
|
||||
Protocol::DeviceConfig s;
|
||||
s.V1.ADCprescaler = ADCprescaler;
|
||||
s.V1.DFTphaseInc = DFTphaseInc;
|
||||
s.V1.IF1 = IF1;
|
||||
return s;
|
||||
return deviceConfig.config;
|
||||
}
|
||||
|
||||
uint32_t HW::getIF1() {
|
||||
return IF1;
|
||||
return deviceConfig.config.V1.IF1;
|
||||
}
|
||||
|
||||
uint32_t HW::getIF2() {
|
||||
return IF2;
|
||||
return deviceConfig.IF2;
|
||||
}
|
||||
|
||||
uint32_t HW::getADCRate() {
|
||||
return ADCsamplerate;
|
||||
return deviceConfig.ADCsamplerate;
|
||||
}
|
||||
|
||||
uint8_t HW::getADCPrescaler() {
|
||||
return ADCprescaler;
|
||||
return deviceConfig.config.V1.ADCprescaler;
|
||||
}
|
||||
|
||||
uint64_t HW::getLastISRTimestamp() {
|
||||
|
|
@ -496,6 +506,44 @@ void HW::updateDeviceStatus() {
|
|||
}
|
||||
|
||||
uint16_t HW::getDFTPhaseInc() {
|
||||
return DFTphaseInc;
|
||||
return deviceConfig.config.V1.DFTphaseInc;
|
||||
}
|
||||
|
||||
uint8_t HW::getPLLSettlingDelay() {
|
||||
return deviceConfig.config.V1.PLLSettlingDelay;
|
||||
}
|
||||
|
||||
bool HW::LoadDeviceConfig() {
|
||||
HWHAL::flash.read(flash_address, sizeof(deviceConfig), &deviceConfig);
|
||||
if(deviceConfig.version != deviceConfigVersion) {
|
||||
LOG_WARN("Invalid version in flash, expected %u, got %u", deviceConfigVersion, deviceConfig.version);
|
||||
SetDefaultDeviceConfig();
|
||||
return false;
|
||||
} else {
|
||||
LOG_INFO("Device config loaded from flash");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool HW::SaveDeviceConfig() {
|
||||
if(!HWHAL::flash.eraseRange(flash_address, flash_size)) {
|
||||
return false;
|
||||
}
|
||||
uint32_t write_size = sizeof(deviceConfig);
|
||||
if(write_size % Flash::PageSize != 0) {
|
||||
// round up to next page
|
||||
write_size += Flash::PageSize - write_size % Flash::PageSize;
|
||||
}
|
||||
return HWHAL::flash.write(flash_address, write_size, &deviceConfig);
|
||||
}
|
||||
|
||||
void HW::SetDefaultDeviceConfig() {
|
||||
memset(&deviceConfig, 0, sizeof(deviceConfig));
|
||||
deviceConfig.version = deviceConfigVersion;
|
||||
deviceConfig.config.V1.IF1 = HW::DefaultIF1;
|
||||
deviceConfig.config.V1.ADCprescaler = HW::DefaultADCprescaler;
|
||||
deviceConfig.config.V1.DFTphaseInc = HW::DefaultDFTphaseInc;
|
||||
deviceConfig.config.V1.PLLSettlingDelay = HW::DefaultPLLSettlingDelay;
|
||||
updateOtherParametersFromProtocolDeviceConfig();
|
||||
LOG_INFO("Device config set to default");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,8 @@ static constexpr uint32_t BandSwitchFrequency = 25000000;
|
|||
static constexpr uint32_t DefaultLO2 = DefaultIF1 - DefaultIF2;
|
||||
static constexpr uint8_t LO2Multiplier = 13;
|
||||
static constexpr uint32_t SI5351CPLLAlignedFrequency = DefaultLO2 * LO2Multiplier;
|
||||
static constexpr uint16_t DefaultDwellTime = 60;
|
||||
static constexpr uint16_t DefaultPLLSettlingDelay = 60;
|
||||
static constexpr uint16_t MinPLLSettlingDelay = 10;
|
||||
|
||||
static constexpr uint8_t DefaultADCprescaler = FPGA::Clockrate / DefaultADCSamplerate;
|
||||
static_assert(DefaultADCprescaler * DefaultADCSamplerate == FPGA::Clockrate, "ADCSamplerate can not be reached exactly");
|
||||
|
|
@ -87,7 +88,6 @@ static constexpr Protocol::DeviceInfo Info = {
|
|||
.limits_maxAmplitudePoints = Cal::maxPoints,
|
||||
.limits_maxFreqHarmonic = 18000000000,
|
||||
.num_ports = 2,
|
||||
.limits_minDwellTime = 0,
|
||||
.limits_maxDwellTime = 10239,
|
||||
};
|
||||
|
||||
|
|
@ -135,13 +135,21 @@ namespace Ref {
|
|||
Si5351C::PLLSource getSource();
|
||||
}
|
||||
|
||||
// Acquisition frequency settings
|
||||
void setAcquisitionFrequencies(Protocol::DeviceConfig s);
|
||||
// Device configuration settings
|
||||
constexpr uint32_t flash_address = Firmware::maxSize + Cal::flash_size; // stored directly behind calibration in flash
|
||||
constexpr uint32_t flash_size = 4096; // reserve one sector for now
|
||||
|
||||
bool LoadDeviceConfig();
|
||||
bool SaveDeviceConfig();
|
||||
void SetDefaultDeviceConfig();
|
||||
|
||||
void setDeviceConfig(Protocol::DeviceConfig s);
|
||||
Protocol::DeviceConfig getDeviceConfig();
|
||||
uint32_t getIF1();
|
||||
uint32_t getIF2();
|
||||
uint32_t getADCRate();
|
||||
uint8_t getADCPrescaler();
|
||||
uint16_t getDFTPhaseInc();
|
||||
uint8_t getPLLSettlingDelay();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,8 @@ static_assert(alternativePhaseInc * alternativeSamplerate == 4096 * HW::DefaultI
|
|||
|
||||
// Constants for USB buffer overflow prevention
|
||||
static constexpr uint16_t maxPointsBetweenHalts = 40;
|
||||
static constexpr uint32_t reservedUSBbuffer = maxPointsBetweenHalts * (sizeof(Protocol::Datapoint) + 8 /*USB packet overhead*/);
|
||||
static constexpr uint16_t full2portDatapointSize = 66;// See Protocol::VNADatapoint::
|
||||
static constexpr uint32_t reservedUSBbuffer = (maxPointsBetweenHalts + 2 /*additional buffer*/) * (full2portDatapointSize + 8 /*USB packet overhead*/);
|
||||
|
||||
using namespace HWHAL;
|
||||
|
||||
|
|
@ -118,6 +119,9 @@ bool VNA::Setup(Protocol::SweepSettings s) {
|
|||
if(settings.points > FPGA::MaxPoints) {
|
||||
settings.points = FPGA::MaxPoints;
|
||||
}
|
||||
if(settings.dwell_time > HW::Info.limits_maxDwellTime) {
|
||||
settings.dwell_time = HW::Info.limits_maxDwellTime;
|
||||
}
|
||||
settings = s;
|
||||
// calculate factor between adjacent points for log sweep for faster calculation when sweeping
|
||||
logMultiplier = pow((double) settings.f_stop / settings.f_start, 1.0 / (settings.points-1));
|
||||
|
|
@ -132,7 +136,7 @@ bool VNA::Setup(Protocol::SweepSettings s) {
|
|||
// has to be one less than actual number of samples
|
||||
FPGA::SetSamplesPerPoint(samplesPerPoint);
|
||||
|
||||
FPGA::SetSettlingTime(s.dwell_time);
|
||||
FPGA::SetSettlingTime(s.dwell_time + HW::getPLLSettlingDelay());
|
||||
|
||||
// reset unlevel flag if it was set from a previous sweep/mode
|
||||
HW::SetOutputUnlevel(false);
|
||||
|
|
@ -216,6 +220,7 @@ bool VNA::Setup(Protocol::SweepSettings s) {
|
|||
pointsWithoutHalt++;
|
||||
if(pointsWithoutHalt > maxPointsBetweenHalts) {
|
||||
needs_halt = true;
|
||||
pointsWithoutHalt = 0;
|
||||
}
|
||||
} else {
|
||||
pointsWithoutHalt = 0;
|
||||
|
|
@ -304,7 +309,9 @@ static void PassOnData() {
|
|||
Protocol::PacketInfo info;
|
||||
info.type = Protocol::PacketType::VNADatapoint;
|
||||
info.VNAdatapoint = &data;
|
||||
Communication::Send(info);
|
||||
if(!Communication::Send(info)) {
|
||||
LOG_ERR("Failed to transmit VNADatapoint");
|
||||
}
|
||||
data.clear();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue