mirror of
https://github.com/jankae/LibreVNA.git
synced 2025-12-06 07:12:10 +01:00
WIP: preparations for ADC rate switching
This commit is contained in:
parent
fe08937bb7
commit
b9f3c694d1
|
|
@ -85,7 +85,17 @@ entity SPICommands is
|
||||||
DFT_NEXT_OUTPUT : out STD_LOGIC;
|
DFT_NEXT_OUTPUT : out STD_LOGIC;
|
||||||
DFT_ENABLE : out STD_LOGIC;
|
DFT_ENABLE : out STD_LOGIC;
|
||||||
|
|
||||||
DEBUG_STATUS : in STD_LOGIC_VECTOR(10 downto 0));
|
DEBUG_STATUS : in STD_LOGIC_VECTOR(10 downto 0);
|
||||||
|
|
||||||
|
ADC_PRESCALER_ALT1 : out STD_LOGIC_VECTOR(7 downto 0);
|
||||||
|
ADC_PHASEINC_ALT1 : out STD_LOGIC_VECTOR(11 downto 0);
|
||||||
|
ADC_PRESCALER_ALT2 : out STD_LOGIC_VECTOR(7 downto 0);
|
||||||
|
ADC_PHASEINC_ALT2 : out STD_LOGIC_VECTOR(11 downto 0);
|
||||||
|
ADC_PRESCALER_ALT3 : out STD_LOGIC_VECTOR(7 downto 0);
|
||||||
|
ADC_PHASEINC_ALT3 : out STD_LOGIC_VECTOR(11 downto 0);
|
||||||
|
ADC_PRESCALER_ALT4 : out STD_LOGIC_VECTOR(7 downto 0);
|
||||||
|
ADC_PHASEINC_ALT4 : out STD_LOGIC_VECTOR(11 downto 0)
|
||||||
|
);
|
||||||
end SPICommands;
|
end SPICommands;
|
||||||
|
|
||||||
architecture Behavioral of SPICommands is
|
architecture Behavioral of SPICommands is
|
||||||
|
|
@ -270,6 +280,14 @@ begin
|
||||||
when 15 => MAX2871_DEF_4(31 downto 16) <= spi_buf_out;
|
when 15 => MAX2871_DEF_4(31 downto 16) <= spi_buf_out;
|
||||||
when 18 => DFT_BIN1_PHASEINC <= spi_buf_out;
|
when 18 => DFT_BIN1_PHASEINC <= spi_buf_out;
|
||||||
when 19 => DFT_DIFFBIN_PHASEINC <= spi_buf_out;
|
when 19 => DFT_DIFFBIN_PHASEINC <= spi_buf_out;
|
||||||
|
when 24 => ADC_PRESCALER_ALT1 <= spi_buf_out(7 downto 0);
|
||||||
|
when 25 => ADC_PHASEINC_ALT1 <= spi_buf_out(11 downto 0);
|
||||||
|
when 26 => ADC_PRESCALER_ALT2 <= spi_buf_out(7 downto 0);
|
||||||
|
when 27 => ADC_PHASEINC_ALT2 <= spi_buf_out(11 downto 0);
|
||||||
|
when 28 => ADC_PRESCALER_ALT3 <= spi_buf_out(7 downto 0);
|
||||||
|
when 29 => ADC_PHASEINC_ALT3 <= spi_buf_out(11 downto 0);
|
||||||
|
when 30 => ADC_PRESCALER_ALT4 <= spi_buf_out(7 downto 0);
|
||||||
|
when 31 => ADC_PHASEINC_ALT4 <= spi_buf_out(11 downto 0);
|
||||||
when others =>
|
when others =>
|
||||||
end case;
|
end case;
|
||||||
selected_register <= selected_register + 1;
|
selected_register <= selected_register + 1;
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,8 @@ entity Sweep is
|
||||||
|
|
||||||
SOURCE_CE : out STD_LOGIC;
|
SOURCE_CE : out STD_LOGIC;
|
||||||
|
|
||||||
|
ADC_SEL : out STD_LOGIC_VECTOR(2 downto 0);
|
||||||
|
|
||||||
-- Debug signals
|
-- Debug signals
|
||||||
DEBUG_STATUS : out STD_LOGIC_VECTOR (10 downto 0);
|
DEBUG_STATUS : out STD_LOGIC_VECTOR (10 downto 0);
|
||||||
RESULT_INDEX : out STD_LOGIC_VECTOR (15 downto 0)
|
RESULT_INDEX : out STD_LOGIC_VECTOR (15 downto 0)
|
||||||
|
|
@ -124,15 +126,16 @@ begin
|
||||||
SOURCE_FILTER <= config_reg(89 downto 88);
|
SOURCE_FILTER <= config_reg(89 downto 88);
|
||||||
BAND_SELECT <= config_reg(48);
|
BAND_SELECT <= config_reg(48);
|
||||||
SOURCE_CE <= source_active;
|
SOURCE_CE <= source_active;
|
||||||
|
ADC_SEL <= config_reg(92 downto 90);
|
||||||
|
|
||||||
NSAMPLES <= USER_NSAMPLES when config_reg(92 downto 90) = "000" else
|
NSAMPLES <= USER_NSAMPLES;-- when config_reg(92 downto 90) = "000" else
|
||||||
std_logic_vector(to_unsigned(6, 13)) when config_reg(92 downto 90) = "001" else
|
--std_logic_vector(to_unsigned(6, 13)) when config_reg(92 downto 90) = "001" else
|
||||||
std_logic_vector(to_unsigned(19, 13)) when config_reg(92 downto 90) = "010" else
|
--std_logic_vector(to_unsigned(19, 13)) when config_reg(92 downto 90) = "010" else
|
||||||
std_logic_vector(to_unsigned(57, 13)) when config_reg(92 downto 90) = "011" else
|
--std_logic_vector(to_unsigned(57, 13)) when config_reg(92 downto 90) = "011" else
|
||||||
std_logic_vector(to_unsigned(190, 13)) when config_reg(92 downto 90) = "100" else
|
--std_logic_vector(to_unsigned(190, 13)) when config_reg(92 downto 90) = "100" else
|
||||||
std_logic_vector(to_unsigned(571, 13)) when config_reg(92 downto 90) = "101" else
|
--std_logic_vector(to_unsigned(571, 13)) when config_reg(92 downto 90) = "101" else
|
||||||
std_logic_vector(to_unsigned(1904, 13)) when config_reg(92 downto 90) = "110" else
|
--std_logic_vector(to_unsigned(1904, 13)) when config_reg(92 downto 90) = "110" else
|
||||||
std_logic_vector(to_unsigned(5712, 13));
|
--std_logic_vector(to_unsigned(5712, 13));
|
||||||
|
|
||||||
DEBUG_STATUS(10 downto 7) <= "0000" when state = TriggerSetup else
|
DEBUG_STATUS(10 downto 7) <= "0000" when state = TriggerSetup else
|
||||||
"0001" when state = SettingUp else
|
"0001" when state = SettingUp else
|
||||||
|
|
|
||||||
|
|
@ -178,6 +178,7 @@
|
||||||
<transform xil_pn:end_ts="1708955295" xil_pn:in_ck="-4366097307991745463" xil_pn:name="TRAN_regenerateCoresSim" xil_pn:prop_ck="-2723611991789822717" xil_pn:start_ts="1708955295">
|
<transform xil_pn:end_ts="1708955295" xil_pn:in_ck="-4366097307991745463" xil_pn:name="TRAN_regenerateCoresSim" xil_pn:prop_ck="-2723611991789822717" xil_pn:start_ts="1708955295">
|
||||||
<status xil_pn:value="SuccessfullyRun"/>
|
<status xil_pn:value="SuccessfullyRun"/>
|
||||||
<status xil_pn:value="ReadyToRun"/>
|
<status xil_pn:value="ReadyToRun"/>
|
||||||
|
<status xil_pn:value="OutOfDateForInputs"/>
|
||||||
<outfile xil_pn:name="ipcore_dir/DSP_SLICE.ngc"/>
|
<outfile xil_pn:name="ipcore_dir/DSP_SLICE.ngc"/>
|
||||||
<outfile xil_pn:name="ipcore_dir/DSP_SLICE.vhd"/>
|
<outfile xil_pn:name="ipcore_dir/DSP_SLICE.vhd"/>
|
||||||
<outfile xil_pn:name="ipcore_dir/PLL.vhd"/>
|
<outfile xil_pn:name="ipcore_dir/PLL.vhd"/>
|
||||||
|
|
@ -257,7 +258,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="1708953094" xil_pn:in_ck="-4366097307991745463" xil_pn:name="TRAN_regenerateCores" xil_pn:prop_ck="-2723611991789822717" xil_pn:start_ts="1708953094">
|
<transform xil_pn:end_ts="1716659207" xil_pn:in_ck="-4366097307991745463" xil_pn:name="TRAN_regenerateCores" xil_pn:prop_ck="-2723611991789822717" xil_pn:start_ts="1716659207">
|
||||||
<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"/>
|
||||||
|
|
@ -286,7 +287,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="1708958126" xil_pn:in_ck="2241500006820465658" xil_pn:name="TRANEXT_xstsynthesize_spartan6" xil_pn:prop_ck="3256065936432453276" xil_pn:start_ts="1708958116">
|
<transform xil_pn:end_ts="1716659296" xil_pn:in_ck="2241500006820465658" xil_pn:name="TRANEXT_xstsynthesize_spartan6" xil_pn:prop_ck="3256065936432453276" xil_pn:start_ts="1716659286">
|
||||||
<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"/>
|
||||||
|
|
@ -308,7 +309,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="1708958131" xil_pn:in_ck="5411862124762956458" xil_pn:name="TRANEXT_ngdbuild_FPGA" xil_pn:prop_ck="4604875190571501774" xil_pn:start_ts="1708958126">
|
<transform xil_pn:end_ts="1716659313" xil_pn:in_ck="5411862124762956458" xil_pn:name="TRANEXT_ngdbuild_FPGA" xil_pn:prop_ck="4604875190571501774" xil_pn:start_ts="1716659309">
|
||||||
<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"/>
|
||||||
|
|
@ -317,7 +318,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="1708958154" xil_pn:in_ck="8512332261572065657" xil_pn:name="TRANEXT_map_spartan6" xil_pn:prop_ck="-4668962392366239264" xil_pn:start_ts="1708958131">
|
<transform xil_pn:end_ts="1716659337" xil_pn:in_ck="8512332261572065657" xil_pn:name="TRANEXT_map_spartan6" xil_pn:prop_ck="-4668962392366239264" xil_pn:start_ts="1716659313">
|
||||||
<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"/>
|
||||||
|
|
@ -331,7 +332,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="1708958170" xil_pn:in_ck="1117507038335044978" xil_pn:name="TRANEXT_par_spartan6" xil_pn:prop_ck="-1085068593928086116" xil_pn:start_ts="1708958154">
|
<transform xil_pn:end_ts="1716659352" xil_pn:in_ck="1117507038335044978" xil_pn:name="TRANEXT_par_spartan6" xil_pn:prop_ck="-1085068593928086116" xil_pn:start_ts="1716659337">
|
||||||
<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"/>
|
||||||
|
|
@ -345,7 +346,7 @@
|
||||||
<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="1708958180" xil_pn:in_ck="154288912438" xil_pn:name="TRANEXT_bitFile_spartan6" xil_pn:prop_ck="3274353840855015246" xil_pn:start_ts="1708958170">
|
<transform xil_pn:end_ts="1716659362" xil_pn:in_ck="154288912438" xil_pn:name="TRANEXT_bitFile_spartan6" xil_pn:prop_ck="3274353840855015246" xil_pn:start_ts="1716659352">
|
||||||
<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/bitgen.xmsgs"/>
|
<outfile xil_pn:name="_xmsgs/bitgen.xmsgs"/>
|
||||||
|
|
@ -398,7 +399,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="1708958170" xil_pn:in_ck="8512326635937592693" xil_pn:name="TRAN_postRouteTrce" xil_pn:prop_ck="445577401284416184" xil_pn:start_ts="1708958166">
|
<transform xil_pn:end_ts="1716659352" xil_pn:in_ck="8512326635937592693" xil_pn:name="TRAN_postRouteTrce" xil_pn:prop_ck="445577401284416184" xil_pn:start_ts="1716659348">
|
||||||
<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"/>
|
||||||
|
|
|
||||||
BIN
FPGA/VNA/top.bin
BIN
FPGA/VNA/top.bin
Binary file not shown.
|
|
@ -152,6 +152,9 @@ architecture Behavioral of top is
|
||||||
PORT1_ACTIVE : out STD_LOGIC;
|
PORT1_ACTIVE : out STD_LOGIC;
|
||||||
PORT2_ACTIVE : out STD_LOGIC;
|
PORT2_ACTIVE : out STD_LOGIC;
|
||||||
SOURCE_CE : out STD_LOGIC;
|
SOURCE_CE : out STD_LOGIC;
|
||||||
|
|
||||||
|
ADC_SEL : out STD_LOGIC_VECTOR(2 downto 0);
|
||||||
|
|
||||||
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)
|
||||||
);
|
);
|
||||||
|
|
@ -284,7 +287,16 @@ architecture Behavioral of top is
|
||||||
DFT_OUTPUT : in STD_LOGIC_VECTOR (191 downto 0);
|
DFT_OUTPUT : in STD_LOGIC_VECTOR (191 downto 0);
|
||||||
DFT_NEXT_OUTPUT : out STD_LOGIC;
|
DFT_NEXT_OUTPUT : out STD_LOGIC;
|
||||||
DFT_ENABLE : out STD_LOGIC;
|
DFT_ENABLE : out STD_LOGIC;
|
||||||
DEBUG_STATUS : in STD_LOGIC_VECTOR (10 downto 0)
|
DEBUG_STATUS : in STD_LOGIC_VECTOR (10 downto 0);
|
||||||
|
|
||||||
|
ADC_PRESCALER_ALT1 : out STD_LOGIC_VECTOR(7 downto 0);
|
||||||
|
ADC_PHASEINC_ALT1 : out STD_LOGIC_VECTOR(11 downto 0);
|
||||||
|
ADC_PRESCALER_ALT2 : out STD_LOGIC_VECTOR(7 downto 0);
|
||||||
|
ADC_PHASEINC_ALT2 : out STD_LOGIC_VECTOR(11 downto 0);
|
||||||
|
ADC_PRESCALER_ALT3 : out STD_LOGIC_VECTOR(7 downto 0);
|
||||||
|
ADC_PHASEINC_ALT3 : out STD_LOGIC_VECTOR(11 downto 0);
|
||||||
|
ADC_PRESCALER_ALT4 : out STD_LOGIC_VECTOR(7 downto 0);
|
||||||
|
ADC_PHASEINC_ALT4 : out STD_LOGIC_VECTOR(11 downto 0)
|
||||||
);
|
);
|
||||||
END COMPONENT;
|
END COMPONENT;
|
||||||
|
|
||||||
|
|
@ -376,6 +388,17 @@ architecture Behavioral of top is
|
||||||
signal sampling_prescaler : std_logic_vector(7 downto 0);
|
signal sampling_prescaler : std_logic_vector(7 downto 0);
|
||||||
signal sampling_phaseinc : std_logic_vector(11 downto 0);
|
signal sampling_phaseinc : std_logic_vector(11 downto 0);
|
||||||
|
|
||||||
|
signal ADC_PRESCALER : STD_LOGIC_VECTOR(7 downto 0);
|
||||||
|
signal ADC_PHASEINC : STD_LOGIC_VECTOR(11 downto 0);
|
||||||
|
signal ADC_PRESCALER_ALT1 : STD_LOGIC_VECTOR(7 downto 0);
|
||||||
|
signal ADC_PHASEINC_ALT1 : STD_LOGIC_VECTOR(11 downto 0);
|
||||||
|
signal ADC_PRESCALER_ALT2 : STD_LOGIC_VECTOR(7 downto 0);
|
||||||
|
signal ADC_PHASEINC_ALT2 : STD_LOGIC_VECTOR(11 downto 0);
|
||||||
|
signal ADC_PRESCALER_ALT3 : STD_LOGIC_VECTOR(7 downto 0);
|
||||||
|
signal ADC_PHASEINC_ALT3 : STD_LOGIC_VECTOR(11 downto 0);
|
||||||
|
signal ADC_PRESCALER_ALT4 : STD_LOGIC_VECTOR(7 downto 0);
|
||||||
|
signal ADC_PHASEINC_ALT4 : STD_LOGIC_VECTOR(11 downto 0);
|
||||||
|
|
||||||
-- 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_stages : STD_LOGIC_VECTOR (2 downto 0);
|
||||||
|
|
@ -405,6 +428,8 @@ architecture Behavioral of top is
|
||||||
signal sweep_trigger_in : std_logic;
|
signal sweep_trigger_in : std_logic;
|
||||||
signal sweep_trigger_out : std_logic;
|
signal sweep_trigger_out : std_logic;
|
||||||
|
|
||||||
|
signal sweep_adc_sel : std_logic_vector(2 downto 0);
|
||||||
|
|
||||||
-- 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);
|
||||||
|
|
@ -727,6 +752,7 @@ begin
|
||||||
PORT1_ACTIVE => sweep_excite_port1,
|
PORT1_ACTIVE => sweep_excite_port1,
|
||||||
PORT2_ACTIVE => sweep_excite_port2,
|
PORT2_ACTIVE => sweep_excite_port2,
|
||||||
SOURCE_CE => sweep_source_CE,
|
SOURCE_CE => sweep_source_CE,
|
||||||
|
ADC_SEL => sweep_adc_sel,
|
||||||
DEBUG_STATUS => debug,
|
DEBUG_STATUS => debug,
|
||||||
RESULT_INDEX => sampling_result(303 downto 288)
|
RESULT_INDEX => sampling_result(303 downto 288)
|
||||||
);
|
);
|
||||||
|
|
@ -740,6 +766,18 @@ begin
|
||||||
|
|
||||||
ATTENUATION <= sweep_attenuator when HW_overwrite_enabled = '0' else HW_overwrite_data(14 downto 8);
|
ATTENUATION <= sweep_attenuator when HW_overwrite_enabled = '0' else HW_overwrite_data(14 downto 8);
|
||||||
|
|
||||||
|
-- ADC sample rate mapping
|
||||||
|
sampling_prescaler <= ADC_PRESCALER when sweep_adc_sel(2) = '0' else
|
||||||
|
ADC_PRESCALER_ALT1 when sweep_adc_sel(1 downto 0) = "00" else
|
||||||
|
ADC_PRESCALER_ALT2 when sweep_adc_sel(1 downto 0) = "01" else
|
||||||
|
ADC_PRESCALER_ALT3 when sweep_adc_sel(1 downto 0) = "10" else
|
||||||
|
ADC_PRESCALER_ALT4;
|
||||||
|
sampling_phaseinc <= ADC_PHASEINC when sweep_adc_sel(2) = '0' else
|
||||||
|
ADC_PHASEINC_ALT1 when sweep_adc_sel(1 downto 0) = "00" else
|
||||||
|
ADC_PHASEINC_ALT2 when sweep_adc_sel(1 downto 0) = "01" else
|
||||||
|
ADC_PHASEINC_ALT3 when sweep_adc_sel(1 downto 0) = "10" else
|
||||||
|
ADC_PHASEINC_ALT4;
|
||||||
|
|
||||||
-- PLL/SPI mux
|
-- PLL/SPI mux
|
||||||
-- only select FPGA SPI slave when both AUX1 and AUX2 are low
|
-- only select FPGA SPI slave when both AUX1 and AUX2 are low
|
||||||
fpga_select <= nss_sync when aux1_sync = '0' and aux2_sync = '0' else '1';
|
fpga_select <= nss_sync when aux1_sync = '0' and aux2_sync = '0' else '1';
|
||||||
|
|
@ -794,8 +832,8 @@ begin
|
||||||
PORTSWITCH_EN => portswitch_en,
|
PORTSWITCH_EN => portswitch_en,
|
||||||
LEDS => user_leds,
|
LEDS => user_leds,
|
||||||
WINDOW_SETTING => sampling_window,
|
WINDOW_SETTING => sampling_window,
|
||||||
ADC_PRESCALER => sampling_prescaler,
|
ADC_PRESCALER => ADC_PRESCALER,
|
||||||
ADC_PHASEINC => sampling_phaseinc,
|
ADC_PHASEINC => ADC_PHASEINC,
|
||||||
INTERRUPT_ASSERTED => intr,
|
INTERRUPT_ASSERTED => intr,
|
||||||
RESET_MINMAX => adc_reset_minmax,
|
RESET_MINMAX => adc_reset_minmax,
|
||||||
SWEEP_HALTED => sweep_halted,
|
SWEEP_HALTED => sweep_halted,
|
||||||
|
|
@ -813,7 +851,15 @@ begin
|
||||||
DFT_OUTPUT => dft_output,
|
DFT_OUTPUT => dft_output,
|
||||||
DFT_NEXT_OUTPUT => dft_next_output,
|
DFT_NEXT_OUTPUT => dft_next_output,
|
||||||
DFT_ENABLE => dft_enable,
|
DFT_ENABLE => dft_enable,
|
||||||
DEBUG_STATUS => debug
|
DEBUG_STATUS => debug,
|
||||||
|
ADC_PRESCALER_ALT1 => ADC_PRESCALER_ALT1,
|
||||||
|
ADC_PHASEINC_ALT1 => ADC_PHASEINC_ALT1,
|
||||||
|
ADC_PRESCALER_ALT2 => ADC_PRESCALER_ALT2,
|
||||||
|
ADC_PHASEINC_ALT2 => ADC_PHASEINC_ALT2,
|
||||||
|
ADC_PRESCALER_ALT3 => ADC_PRESCALER_ALT3,
|
||||||
|
ADC_PHASEINC_ALT3 => ADC_PHASEINC_ALT3,
|
||||||
|
ADC_PRESCALER_ALT4 => ADC_PRESCALER_ALT4,
|
||||||
|
ADC_PHASEINC_ALT4 => ADC_PHASEINC_ALT4
|
||||||
);
|
);
|
||||||
|
|
||||||
dft_reset <= not dft_enable;
|
dft_reset <= not dft_enable;
|
||||||
|
|
|
||||||
|
|
@ -199,7 +199,7 @@ void FPGA::WriteMAX2871Default(uint32_t *DefaultRegs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FPGA::WriteSweepConfig(uint16_t pointnum, bool lowband, uint32_t *SourceRegs, uint32_t *LORegs,
|
void FPGA::WriteSweepConfig(uint16_t pointnum, bool lowband, uint32_t *SourceRegs, uint32_t *LORegs,
|
||||||
uint8_t attenuation, uint64_t frequency, SettlingTime settling, Samples samples, bool halt, LowpassFilter filter) {
|
uint8_t attenuation, uint64_t frequency, SettlingTime settling, ADCSamplerate rate, bool halt, LowpassFilter filter) {
|
||||||
uint16_t send[7];
|
uint16_t send[7];
|
||||||
// select which point this sweep config is for
|
// select which point this sweep config is for
|
||||||
send[0] = pointnum & 0x1FFF;
|
send[0] = pointnum & 0x1FFF;
|
||||||
|
|
@ -223,7 +223,7 @@ void FPGA::WriteSweepConfig(uint16_t pointnum, bool lowband, uint32_t *SourceReg
|
||||||
send[1] |= 0x8000;
|
send[1] |= 0x8000;
|
||||||
}
|
}
|
||||||
send[1] |= (int) settling << 13;
|
send[1] |= (int) settling << 13;
|
||||||
send[1] |= (int) samples << 10;
|
send[1] |= (int) rate << 10;
|
||||||
if(filter == LowpassFilter::Auto) {
|
if(filter == LowpassFilter::Auto) {
|
||||||
// Select source LP filter
|
// Select source LP filter
|
||||||
if (frequency >= 3500000000) {
|
if (frequency >= 3500000000) {
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,14 @@ enum class Reg {
|
||||||
MAX2871Def4MSB = 0x0F,
|
MAX2871Def4MSB = 0x0F,
|
||||||
DFTFirstBin = 0x12,
|
DFTFirstBin = 0x12,
|
||||||
DFTFreqSpacing = 0x13,
|
DFTFreqSpacing = 0x13,
|
||||||
|
ADCPrescalerAlt1 = 0x18,
|
||||||
|
PhaseIncrementAlt1 = 0x19,
|
||||||
|
ADCPrescalerAlt2 = 0x1A,
|
||||||
|
PhaseIncrementAlt2 = 0x1B,
|
||||||
|
ADCPrescalerAlt3 = 0x1C,
|
||||||
|
PhaseIncrementAlt3 = 0x1D,
|
||||||
|
ADCPrescalerAlt4 = 0x1E,
|
||||||
|
PhaseIncrementAlt4 = 0x1F,
|
||||||
};
|
};
|
||||||
|
|
||||||
using SamplingResult = struct _samplingresult {
|
using SamplingResult = struct _samplingresult {
|
||||||
|
|
@ -89,15 +97,12 @@ enum class SettlingTime {
|
||||||
us540 = 0x03,
|
us540 = 0x03,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class Samples {
|
enum class ADCSamplerate {
|
||||||
SPPRegister = 0x00,
|
Default = 0x00,
|
||||||
S96 = 0x01,
|
Alt1 = 0x04,
|
||||||
S304 = 0x02,
|
Alt2 = 0x05,
|
||||||
S912 = 0x03,
|
Alt3 = 0x06,
|
||||||
S3040 = 0x04,
|
Alt4 = 0x07,
|
||||||
S9136 = 0x05,
|
|
||||||
S30464 = 0x06,
|
|
||||||
S91392 = 0x07,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class Window {
|
enum class Window {
|
||||||
|
|
@ -124,7 +129,7 @@ void DisableInterrupt(Interrupt i);
|
||||||
void DisableAllInterrupts();
|
void DisableAllInterrupts();
|
||||||
void WriteMAX2871Default(uint32_t *DefaultRegs);
|
void WriteMAX2871Default(uint32_t *DefaultRegs);
|
||||||
void WriteSweepConfig(uint16_t pointnum, bool lowband, uint32_t *SourceRegs, uint32_t *LORegs,
|
void WriteSweepConfig(uint16_t pointnum, bool lowband, uint32_t *SourceRegs, uint32_t *LORegs,
|
||||||
uint8_t attenuation, uint64_t frequency, SettlingTime settling, Samples samples, bool halt = false, LowpassFilter filter = LowpassFilter::Auto);
|
uint8_t attenuation, uint64_t frequency, SettlingTime settling, ADCSamplerate rate, bool halt = false, LowpassFilter filter = LowpassFilter::Auto);
|
||||||
using ReadCallback = void(*)(const SamplingResult &result);
|
using ReadCallback = void(*)(const SamplingResult &result);
|
||||||
bool InitiateSampleRead(ReadCallback cb);
|
bool InitiateSampleRead(ReadCallback cb);
|
||||||
void SetupDFT(uint32_t f_firstBin, uint32_t f_binSpacing);
|
void SetupDFT(uint32_t f_firstBin, uint32_t f_binSpacing);
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ void Manual::Setup(Protocol::ManualControl m) {
|
||||||
// Configure single sweep point
|
// Configure single sweep point
|
||||||
FPGA::WriteSweepConfig(0, !m.V1.SourceHighband, Source.GetRegisters(),
|
FPGA::WriteSweepConfig(0, !m.V1.SourceHighband, Source.GetRegisters(),
|
||||||
LO1.GetRegisters(), m.V1.attenuator, 0, FPGA::SettlingTime::us60,
|
LO1.GetRegisters(), m.V1.attenuator, 0, FPGA::SettlingTime::us60,
|
||||||
FPGA::Samples::SPPRegister, 0,
|
FPGA::ADCSamplerate::Default, 0,
|
||||||
(FPGA::LowpassFilter) m.V1.SourceHighLowpass);
|
(FPGA::LowpassFilter) m.V1.SourceHighLowpass);
|
||||||
|
|
||||||
FPGA::SetWindow((FPGA::Window) m.V1.WindowType);
|
FPGA::SetWindow((FPGA::Window) m.V1.WindowType);
|
||||||
|
|
|
||||||
|
|
@ -175,7 +175,7 @@ static void StartNextSample() {
|
||||||
|
|
||||||
// Configure the sampling in the FPGA
|
// Configure the sampling in the FPGA
|
||||||
FPGA::WriteSweepConfig(0, trackingLowband, Source.GetRegisters(), LO1.GetRegisters(), attenuator,
|
FPGA::WriteSweepConfig(0, trackingLowband, Source.GetRegisters(), LO1.GetRegisters(), attenuator,
|
||||||
trackingFreq, FPGA::SettlingTime::us60, FPGA::Samples::SPPRegister, 0,
|
trackingFreq, FPGA::SettlingTime::us60, FPGA::ADCSamplerate::Default, 0,
|
||||||
FPGA::LowpassFilter::Auto);
|
FPGA::LowpassFilter::Auto);
|
||||||
|
|
||||||
if(firstSample && (signalIDstep == 0)) {
|
if(firstSample && (signalIDstep == 0)) {
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
#include "Trigger.hpp"
|
#include "Trigger.hpp"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
#define LOG_LEVEL LOG_LEVEL_INFO
|
#define LOG_LEVEL LOG_LEVEL_INFO
|
||||||
#define LOG_MODULE "VNA"
|
#define LOG_MODULE "VNA"
|
||||||
|
|
@ -51,6 +52,8 @@ static constexpr uint32_t reservedUSBbuffer = maxPointsBetweenHalts * (sizeof(Pr
|
||||||
|
|
||||||
using namespace HWHAL;
|
using namespace HWHAL;
|
||||||
|
|
||||||
|
static constexpr uint8_t alternativePrescalers[] = {112, 113, 114, 115};
|
||||||
|
|
||||||
static uint64_t getPointFrequency(uint16_t pointNum) {
|
static uint64_t getPointFrequency(uint16_t pointNum) {
|
||||||
if(!settings.logSweep) {
|
if(!settings.logSweep) {
|
||||||
return settings.f_start + (settings.f_stop - settings.f_start) * pointNum / (settings.points - 1);
|
return settings.f_start + (settings.f_stop - settings.f_start) * pointNum / (settings.points - 1);
|
||||||
|
|
@ -70,51 +73,220 @@ static uint64_t getPointFrequency(uint16_t pointNum) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setPLLFrequencies(uint64_t f) {
|
static uint32_t closestLOAlias(uint64_t LO1, uint64_t LO2, uint32_t IFBW) {
|
||||||
if(f > HW::Info.limits_maxFreq) {
|
constexpr uint64_t max_LO_harmonic = 2000000000;
|
||||||
Source.SetFrequency(f / sourceHarmonic);
|
constexpr uint32_t max_ADC_alias = 5000000;
|
||||||
LO1.SetFrequency((f + HW::getIF1()) / LOHarmonic);
|
|
||||||
} else {
|
uint32_t closestAlias = std::numeric_limits<uint32_t>::max();
|
||||||
if(f >= HW::BandSwitchFrequency) {
|
|
||||||
Source.SetFrequency(f);
|
for(int64_t lo1 = LO1; lo1 <= (int64_t) max_LO_harmonic; lo1 += LO1) {
|
||||||
}
|
// figure out which 2.LO harmonics we have to check
|
||||||
LO1.SetFrequency(f + HW::getIF1());
|
uint64_t lo2_min = lo1 - max_ADC_alias;
|
||||||
}
|
uint64_t lo2_max = lo1 + max_ADC_alias;
|
||||||
|
|
||||||
|
uint16_t lo2_min_harm = ((lo2_min + LO2 - 1) / LO2);
|
||||||
|
uint16_t lo2_max_harm = lo2_max / LO2;
|
||||||
|
|
||||||
|
if(lo2_max_harm * LO2 > max_LO_harmonic) {
|
||||||
|
lo2_max_harm = max_LO_harmonic / LO2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool needs2LOshift(uint64_t f, uint32_t current2LO, uint32_t IFBW, uint32_t *new2LO) {
|
if(lo2_min_harm > lo2_max_harm) {
|
||||||
// Check if 2.LO needs to be shifted
|
// no aliasing possible, skip 2.LO loop
|
||||||
uint64_t actualSource, actual1LO;
|
continue;
|
||||||
actualSource = Source.GetActualFrequency();
|
|
||||||
actual1LO = LO1.GetActualFrequency();
|
|
||||||
if(f > HW::Info.limits_maxFreq) {
|
|
||||||
actualSource *= sourceHarmonic;
|
|
||||||
actual1LO *= LOHarmonic;
|
|
||||||
} else if(f < HW::BandSwitchFrequency) {
|
|
||||||
// can use the lowband PLL with high frequency resolution, assume perfect frequency match
|
|
||||||
actualSource = f;
|
|
||||||
}
|
}
|
||||||
uint32_t actualFirstIF = actual1LO - actualSource;
|
|
||||||
uint32_t actualFinalIF = actualFirstIF - current2LO;
|
for(int64_t lo2 = LO2 * lo2_min_harm; lo2 <= (int64_t) LO2 * lo2_max_harm; lo2 += LO2) {
|
||||||
uint32_t IFdeviation = abs(actualFinalIF - HW::getIF2());
|
uint32_t mixing = llabs(lo1 - lo2);
|
||||||
if(IFdeviation > IFBW / 2) {
|
if(mixing > max_ADC_alias) {
|
||||||
*new2LO = actualFirstIF - HW::getIF2();
|
continue;
|
||||||
return true;
|
}
|
||||||
} else {
|
int32_t alias = Util::Alias(mixing, HW::getADCRate());
|
||||||
// no shift required
|
uint32_t alias_dist = labs((int32_t) HW::getIF2() - alias);
|
||||||
|
if(alias_dist < closestAlias) {
|
||||||
|
closestAlias = alias_dist;
|
||||||
|
}
|
||||||
|
// if(abs(HW::getIF2() - alias) <= IFBW*3) {
|
||||||
|
// // we do have LO mixing products aliasing into the 2.IF
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return closestAlias;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool noLOAliasing(uint64_t LO1, uint64_t LO2, uint32_t IFBW) {
|
||||||
|
constexpr uint64_t max_LO_harmonic = 2000000000;
|
||||||
|
constexpr uint32_t max_ADC_alias = 5000000;
|
||||||
|
|
||||||
|
for(int64_t lo1 = LO1; lo1 <= (int64_t) max_LO_harmonic; lo1 += LO1) {
|
||||||
|
// figure out which 2.LO harmonics we have to check
|
||||||
|
uint64_t lo2_min = lo1 - max_ADC_alias;
|
||||||
|
uint64_t lo2_max = lo1 + max_ADC_alias;
|
||||||
|
|
||||||
|
uint16_t lo2_min_harm = ((lo2_min + LO2 - 1) / LO2);
|
||||||
|
uint16_t lo2_max_harm = lo2_max / LO2;
|
||||||
|
|
||||||
|
if(lo2_max_harm * LO2 > max_LO_harmonic) {
|
||||||
|
lo2_max_harm = max_LO_harmonic / LO2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(lo2_min_harm > lo2_max_harm) {
|
||||||
|
// no aliasing possible, skip 2.LO loop
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int64_t lo2 = LO2 * lo2_min_harm; lo2 <= (int64_t) LO2 * lo2_max_harm; lo2 += LO2) {
|
||||||
|
uint32_t mixing = llabs(lo1 - lo2);
|
||||||
|
if(mixing > max_ADC_alias) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int32_t alias = Util::Alias(mixing, HW::getADCRate());
|
||||||
|
if(abs(HW::getIF2() - alias) <= IFBW*3) {
|
||||||
|
// we do have LO mixing products aliasing into the 2.IF
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// all good, no aliasing
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool setPLLFrequencies(uint64_t f, uint32_t current2LO, uint32_t IFBW, uint32_t *new2LO) {
|
||||||
|
const std::array<uint32_t, 21> IF_shifts = { 0, IFBW * 2, IFBW * 3,
|
||||||
|
IFBW * 5, IFBW * 7, IFBW * 7 / 10, IFBW * 11 / 10, IFBW * 13
|
||||||
|
/ 10, IFBW * 17 / 10, IFBW * 19 / 10, IFBW, IFBW * 23 / 10,
|
||||||
|
IFBW * 29 / 10, IFBW * 31 / 10, IFBW * 37 / 10, IFBW * 41 / 10, IFBW
|
||||||
|
* 43 / 10, IFBW * 47 / 10, IFBW * 53 / 10, IFBW * 59 / 10,
|
||||||
|
IFBW * 61 / 10 };
|
||||||
|
|
||||||
|
uint64_t actualSource;
|
||||||
|
// set the source, this will never change
|
||||||
|
if (f > HW::Info.limits_maxFreq) {
|
||||||
|
Source.SetFrequency(f / sourceHarmonic);
|
||||||
|
actualSource = Source.GetActualFrequency() * sourceHarmonic;
|
||||||
|
} else if (f >= HW::BandSwitchFrequency) {
|
||||||
|
Source.SetFrequency(f);
|
||||||
|
actualSource = Source.GetActualFrequency();
|
||||||
|
} else {
|
||||||
|
// source will be set in sweep halted interrupt
|
||||||
|
actualSource = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t maxIndex = IF_shifts.size();
|
||||||
|
if(!settings.suppressPeaks) {
|
||||||
|
maxIndex = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t bestIndex = 0;
|
||||||
|
uint32_t furthestAliasDistance = 0;
|
||||||
|
|
||||||
|
for(uint8_t i = 0;i<maxIndex;i++) {
|
||||||
|
auto shift = IF_shifts[i];
|
||||||
|
// set the 1.LO
|
||||||
|
uint64_t actual1LO;
|
||||||
|
if(f > HW::Info.limits_maxFreq) {
|
||||||
|
LO1.SetFrequency((f + HW::getIF1() + shift) / LOHarmonic);
|
||||||
|
actual1LO = LO1.GetActualFrequency() * LOHarmonic;
|
||||||
|
} else {
|
||||||
|
LO1.SetFrequency(f + HW::getIF1() + shift);
|
||||||
|
actual1LO = LO1.GetActualFrequency();
|
||||||
|
}
|
||||||
|
// adjust 2.LO if necessary
|
||||||
|
*new2LO = current2LO;
|
||||||
|
uint32_t actualFirstIF = actual1LO - actualSource;
|
||||||
|
uint32_t actualFinalIF = actualFirstIF - *new2LO;
|
||||||
|
uint32_t IFdeviation = abs(actualFinalIF - HW::getIF2());
|
||||||
|
if(IFdeviation > IFBW / 2) {
|
||||||
|
*new2LO = actualFirstIF - HW::getIF2();
|
||||||
|
}
|
||||||
|
|
||||||
|
// LOG_ERR("Checking F=%lu, SRC=%lu, LO1=%lu", (uint32_t) f, (uint32_t) actualSource, (uint32_t) actual1LO);
|
||||||
|
|
||||||
|
auto closest_alias = closestLOAlias(actual1LO, *new2LO, IFBW);
|
||||||
|
if(closest_alias > IFBW * 3) {
|
||||||
|
// no need to look further, chose this option
|
||||||
|
return true;
|
||||||
|
} else if(closest_alias > furthestAliasDistance) {
|
||||||
|
bestIndex = i;
|
||||||
|
furthestAliasDistance = closest_alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
// // check if LO mixing product aliases into the ADC
|
||||||
|
// if(noLOAliasing(actual1LO, *new2LO, IFBW)) {
|
||||||
|
// // found an IF that can be used without problems
|
||||||
|
// if(shift != 0) {
|
||||||
|
//// LOG_WARN("Shifting IF for f=%lu, LO1=%lu, LO2= %lu", (uint32_t) f, (uint32_t) actual1LO, *new2LO);
|
||||||
|
// }
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
// all available IF shifts result in aliasing in the ADC
|
||||||
|
// LOG_ERR("Failed to shift IF for f=%lu", (uint32_t) f);
|
||||||
|
// no perfect option, use best shift
|
||||||
|
auto shift = IF_shifts[bestIndex];
|
||||||
|
// set the 1.LO
|
||||||
|
uint64_t actual1LO;
|
||||||
|
if(f > HW::Info.limits_maxFreq) {
|
||||||
|
LO1.SetFrequency((f + HW::getIF1() + shift) / LOHarmonic);
|
||||||
|
actual1LO = LO1.GetActualFrequency() * LOHarmonic;
|
||||||
|
} else {
|
||||||
|
LO1.SetFrequency(f + HW::getIF1() + shift);
|
||||||
|
actual1LO = LO1.GetActualFrequency();
|
||||||
|
}
|
||||||
|
// adjust 2.LO if necessary
|
||||||
|
*new2LO = current2LO;
|
||||||
|
uint32_t actualFirstIF = actual1LO - actualSource;
|
||||||
|
uint32_t actualFinalIF = actualFirstIF - *new2LO;
|
||||||
|
uint32_t IFdeviation = abs(actualFinalIF - HW::getIF2());
|
||||||
|
if(IFdeviation > IFBW / 2) {
|
||||||
|
*new2LO = actualFirstIF - HW::getIF2();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//static bool needs2LOshift(uint64_t f, uint32_t current2LO, uint32_t IFBW, uint32_t *new2LO) {
|
||||||
|
// // Check if 2.LO needs to be shifted
|
||||||
|
// uint64_t actualSource, actual1LO;
|
||||||
|
// actualSource = Source.GetActualFrequency();
|
||||||
|
// actual1LO = LO1.GetActualFrequency();
|
||||||
|
// if(f > HW::Info.limits_maxFreq) {
|
||||||
|
// actualSource *= sourceHarmonic;
|
||||||
|
// actual1LO *= LOHarmonic;
|
||||||
|
// } else if(f < HW::BandSwitchFrequency) {
|
||||||
|
// // can use the lowband PLL with high frequency resolution, assume perfect frequency match
|
||||||
|
// actualSource = f;
|
||||||
|
// }
|
||||||
|
// uint32_t actualFirstIF = actual1LO - actualSource;
|
||||||
|
// uint32_t actualFinalIF = actualFirstIF - current2LO;
|
||||||
|
// uint32_t IFdeviation = abs(actualFinalIF - HW::getIF2());
|
||||||
|
// if(IFdeviation > IFBW / 2) {
|
||||||
|
// *new2LO = actualFirstIF - HW::getIF2();
|
||||||
|
// return true;
|
||||||
|
// } else {
|
||||||
|
// // no shift required
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
bool VNA::Setup(Protocol::SweepSettings s) {
|
bool VNA::Setup(Protocol::SweepSettings s) {
|
||||||
|
// Abort possible active sweep first
|
||||||
VNA::Stop();
|
VNA::Stop();
|
||||||
vTaskDelay(5);
|
vTaskDelay(5);
|
||||||
data.clear();
|
data.clear();
|
||||||
HW::SetMode(HW::Mode::VNA);
|
HW::SetMode(HW::Mode::VNA);
|
||||||
// Abort possible active sweep first
|
|
||||||
FPGA::SetMode(FPGA::Mode::FPGA);
|
FPGA::SetMode(FPGA::Mode::FPGA);
|
||||||
|
// Configure the ADC prescalers
|
||||||
FPGA::WriteRegister(FPGA::Reg::ADCPrescaler, HW::getADCPrescaler());
|
FPGA::WriteRegister(FPGA::Reg::ADCPrescaler, HW::getADCPrescaler());
|
||||||
FPGA::WriteRegister(FPGA::Reg::PhaseIncrement, HW::getDFTPhaseInc());
|
FPGA::WriteRegister(FPGA::Reg::PhaseIncrement, HW::getDFTPhaseInc());
|
||||||
|
FPGA::WriteRegister(FPGA::Reg::ADCPrescalerAlt1, alternativePrescalers[0]);
|
||||||
|
FPGA::WriteRegister(FPGA::Reg::PhaseIncrementAlt1, alternativePrescalers[0]*10);
|
||||||
|
FPGA::WriteRegister(FPGA::Reg::ADCPrescalerAlt2, alternativePrescalers[1]);
|
||||||
|
FPGA::WriteRegister(FPGA::Reg::PhaseIncrementAlt2, alternativePrescalers[1]*10);
|
||||||
|
FPGA::WriteRegister(FPGA::Reg::ADCPrescalerAlt3, alternativePrescalers[2]);
|
||||||
|
FPGA::WriteRegister(FPGA::Reg::PhaseIncrementAlt3, alternativePrescalers[2]*10);
|
||||||
|
FPGA::WriteRegister(FPGA::Reg::ADCPrescalerAlt4, alternativePrescalers[3]);
|
||||||
|
FPGA::WriteRegister(FPGA::Reg::PhaseIncrementAlt4, alternativePrescalers[3]*10);
|
||||||
if(settings.points > FPGA::MaxPoints) {
|
if(settings.points > FPGA::MaxPoints) {
|
||||||
settings.points = FPGA::MaxPoints;
|
settings.points = FPGA::MaxPoints;
|
||||||
}
|
}
|
||||||
|
|
@ -192,12 +364,13 @@ bool VNA::Setup(Protocol::SweepSettings s) {
|
||||||
}
|
}
|
||||||
// SetFrequency only manipulates the register content in RAM, no SPI communication is done.
|
// SetFrequency only manipulates the register content in RAM, no SPI communication is done.
|
||||||
// No mode-switch of FPGA necessary here.
|
// No mode-switch of FPGA necessary here.
|
||||||
setPLLFrequencies(freq);
|
uint32_t new2LO;
|
||||||
if(s.suppressPeaks) {
|
setPLLFrequencies(freq, last_LO2, actualBandwidth, &new2LO);
|
||||||
if(needs2LOshift(freq, last_LO2, actualBandwidth, &last_LO2)) {
|
if(new2LO != last_LO2 && s.suppressPeaks) {
|
||||||
|
last_LO2 = new2LO;
|
||||||
needs_halt = true;
|
needs_halt = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (last_lowband && !lowband) {
|
if (last_lowband && !lowband) {
|
||||||
// additional halt before first highband point to enable highband source
|
// additional halt before first highband point to enable highband source
|
||||||
needs_halt = true;
|
needs_halt = true;
|
||||||
|
|
@ -233,7 +406,7 @@ bool VNA::Setup(Protocol::SweepSettings s) {
|
||||||
|
|
||||||
FPGA::WriteSweepConfig(i, lowband, Source.GetRegisters(),
|
FPGA::WriteSweepConfig(i, lowband, Source.GetRegisters(),
|
||||||
LO1.GetRegisters(), attenuator, freq, FPGA::SettlingTime::us60,
|
LO1.GetRegisters(), attenuator, freq, FPGA::SettlingTime::us60,
|
||||||
FPGA::Samples::SPPRegister, needs_halt);
|
FPGA::ADCSamplerate::Default, needs_halt);
|
||||||
last_lowband = lowband;
|
last_lowband = lowband;
|
||||||
}
|
}
|
||||||
// revert clk configuration to previous value (might have been changed in sweep calculation)
|
// revert clk configuration to previous value (might have been changed in sweep calculation)
|
||||||
|
|
@ -261,6 +434,7 @@ bool VNA::Setup(Protocol::SweepSettings s) {
|
||||||
FPGA::EnableInterrupt(FPGA::Interrupt::NewData);
|
FPGA::EnableInterrupt(FPGA::Interrupt::NewData);
|
||||||
FPGA::EnableInterrupt(FPGA::Interrupt::SweepHalted);
|
FPGA::EnableInterrupt(FPGA::Interrupt::SweepHalted);
|
||||||
// Start the sweep if not configured for standby
|
// Start the sweep if not configured for standby
|
||||||
|
last_LO2 = HW::getIF1() - HW::getIF2();
|
||||||
firstPoint = true;
|
firstPoint = true;
|
||||||
if (settings.standby) {
|
if (settings.standby) {
|
||||||
waitingInStandby = true;
|
waitingInStandby = true;
|
||||||
|
|
@ -426,8 +600,10 @@ void VNA::SweepHalted() {
|
||||||
if(settings.suppressPeaks) {
|
if(settings.suppressPeaks) {
|
||||||
// does not actually change PLL settings, just calculates the register values and
|
// does not actually change PLL settings, just calculates the register values and
|
||||||
// is required to determine the need for a 2.LO shift
|
// is required to determine the need for a 2.LO shift
|
||||||
setPLLFrequencies(frequency);
|
uint32_t new2LO;
|
||||||
if(needs2LOshift(frequency, last_LO2, actualBandwidth, &last_LO2)) {
|
setPLLFrequencies(frequency, last_LO2, actualBandwidth, &new2LO);
|
||||||
|
if(new2LO != last_LO2) {
|
||||||
|
last_LO2 = new2LO;
|
||||||
Si5351.SetCLK(SiChannel::Port1LO2, last_LO2, Si5351C::PLL::B, Si5351C::DriveStrength::mA2);
|
Si5351.SetCLK(SiChannel::Port1LO2, last_LO2, Si5351C::PLL::B, Si5351C::DriveStrength::mA2);
|
||||||
Si5351.SetCLK(SiChannel::Port2LO2, last_LO2, Si5351C::PLL::B, Si5351C::DriveStrength::mA2);
|
Si5351.SetCLK(SiChannel::Port2LO2, last_LO2, Si5351C::PLL::B, Si5351C::DriveStrength::mA2);
|
||||||
Si5351.SetCLK(SiChannel::RefLO2, last_LO2, Si5351C::PLL::B, Si5351C::DriveStrength::mA2);
|
Si5351.SetCLK(SiChannel::RefLO2, last_LO2, Si5351C::PLL::B, Si5351C::DriveStrength::mA2);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue