diff --git a/FPGA/VNA/SPIConfig.vhd b/FPGA/VNA/SPIConfig.vhd index 1ccbd03..5bf4ed2 100644 --- a/FPGA/VNA/SPIConfig.vhd +++ b/FPGA/VNA/SPIConfig.vhd @@ -45,12 +45,11 @@ entity SPICommands is MAX2871_DEF_3 : out STD_LOGIC_VECTOR (31 downto 0); MAX2871_DEF_1 : out STD_LOGIC_VECTOR (31 downto 0); MAX2871_DEF_0 : out STD_LOGIC_VECTOR (31 downto 0); - SWEEP_DATA : out STD_LOGIC_VECTOR (111 downto 0); + SWEEP_DATA : out STD_LOGIC_VECTOR (95 downto 0); SWEEP_ADDRESS : out STD_LOGIC_VECTOR (12 downto 0); SWEEP_WRITE : out STD_LOGIC_VECTOR (0 downto 0); SWEEP_POINTS : out STD_LOGIC_VECTOR (12 downto 0); - NSAMPLES : out STD_LOGIC_VECTOR (16 downto 0); - SETTLING_TIME : out STD_LOGIC_VECTOR (15 downto 0); + NSAMPLES : out STD_LOGIC_VECTOR (9 downto 0); EXCITE_PORT1 : out STD_LOGIC; EXCITE_PORT2 : out STD_LOGIC; PORT1_EN : out STD_LOGIC; @@ -62,7 +61,7 @@ entity SPICommands is SOURCE_CE_EN : out STD_LOGIC; LO_CE_EN : out STD_LOGIC; LEDS : out STD_LOGIC_VECTOR(2 downto 0); - SYNC_SETTING : out STD_LOGIC_VECTOR(1 downto 0); + WINDOW_SETTING : out STD_LOGIC_VECTOR(1 downto 0); INTERRUPT_ASSERTED : out STD_LOGIC; RESET_MINMAX : out STD_LOGIC; SWEEP_HALTED : in STD_LOGIC; @@ -102,7 +101,7 @@ architecture Behavioral of SPICommands is signal interrupt_status : std_logic_vector(15 downto 0); signal latched_result : std_logic_vector(271 downto 0); - signal sweepconfig_buffer : std_logic_vector(95 downto 0); + signal sweepconfig_buffer : std_logic_vector(79 downto 0); begin SPI: spi_slave GENERIC MAP(w => 16) @@ -131,7 +130,7 @@ begin data_overrun <= '0'; SWEEP_POINTS <= (others => '0'); NSAMPLES <= (others => '0'); - SETTLING_TIME <= (others => '0'); + --SETTLING_TIME <= (others => '0'); PORT1_EN <= '0'; PORT2_EN <= '0'; REF_EN <= '0'; @@ -141,7 +140,7 @@ begin SOURCE_CE_EN <= '0'; LO_CE_EN <= '0'; LEDS <= (others => '1'); - SYNC_SETTING <= "00"; + WINDOW_SETTING <= "00"; unread_sampling_data <= '0'; interrupt_mask <= (others => '0'); RESET_MINMAX <= '0'; @@ -191,8 +190,8 @@ begin case selected_register is when 0 => interrupt_mask <= spi_buf_out; when 1 => SWEEP_POINTS <= spi_buf_out(12 downto 0); - when 2 => NSAMPLES(15 downto 0) <= spi_buf_out; - when 3 => NSAMPLES(16) <= spi_buf_out(0); + when 2 => NSAMPLES <= spi_buf_out(9 downto 0); + when 3 => --NSAMPLES(16) <= spi_buf_out(0); PORT1_EN <= spi_buf_out(15); PORT2_EN <= spi_buf_out(14); REF_EN <= spi_buf_out(13); @@ -200,12 +199,12 @@ begin SOURCE_RF_EN <= spi_buf_out(11); LO_RF_EN <= spi_buf_out(10); LEDS <= not spi_buf_out(9 downto 7); - SYNC_SETTING <= spi_buf_out(6 downto 5); + WINDOW_SETTING <= spi_buf_out(6 downto 5); SOURCE_CE_EN <= spi_buf_out(4); LO_CE_EN <= spi_buf_out(3); EXCITE_PORT1 <= spi_buf_out(1); EXCITE_PORT2 <= spi_buf_out(2); - when 4 => SETTLING_TIME <= spi_buf_out; + --when 4 => SETTLING_TIME <= spi_buf_out; when 8 => MAX2871_DEF_0(15 downto 0) <= spi_buf_out; when 9 => MAX2871_DEF_0(31 downto 16) <= spi_buf_out; @@ -219,13 +218,13 @@ begin end case; selected_register <= selected_register + 1; elsif state = WriteSweepConfig then - if word_cnt = 7 then + 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(79 downto 0) & spi_buf_out; + sweepconfig_buffer <= sweepconfig_buffer(63 downto 0) & spi_buf_out; end if; elsif state = ReadResult then -- pass on next word of latched result diff --git a/FPGA/VNA/Sampling.vhd b/FPGA/VNA/Sampling.vhd index d1f6d3f..cdc6a84 100644 --- a/FPGA/VNA/Sampling.vhd +++ b/FPGA/VNA/Sampling.vhd @@ -44,7 +44,7 @@ entity Sampling is DONE : out STD_LOGIC; PRE_DONE : out STD_LOGIC; START : in STD_LOGIC; - SAMPLES : in STD_LOGIC_VECTOR (16 downto 0); + SAMPLES : in STD_LOGIC_VECTOR (9 downto 0); PORT1_I : out STD_LOGIC_VECTOR (47 downto 0); PORT1_Q : out STD_LOGIC_VECTOR (47 downto 0); PORT2_I : out STD_LOGIC_VECTOR (47 downto 0); @@ -80,6 +80,7 @@ END COMPONENT; signal r_Q : signed(47 downto 0); signal clk_cnt : integer range 0 to CLK_DIV - 1; signal sample_cnt : integer range 0 to 131071; + signal samples_to_take : integer range 0 to 131071; constant phase_inc : integer := IF_FREQ * 4096 * CLK_DIV / CLK_FREQ; signal phase : std_logic_vector(11 downto 0); @@ -194,6 +195,7 @@ begin phase <= (others => '0'); if START = '1' then state <= Sampling; + samples_to_take <= to_integer(unsigned(SAMPLES & "0000000")); end if; when Sampling => DONE <= '0'; @@ -220,7 +222,7 @@ begin DONE <= '0'; PRE_DONE <= '0'; phase <= std_logic_vector(unsigned(phase) + phase_inc); - if sample_cnt < unsigned(SAMPLES) then + if sample_cnt < samples_to_take then sample_cnt <= sample_cnt + 1; state <= Sampling; else diff --git a/FPGA/VNA/Sweep.vhd b/FPGA/VNA/Sweep.vhd index 9367607..72e0d32 100644 --- a/FPGA/VNA/Sweep.vhd +++ b/FPGA/VNA/Sweep.vhd @@ -34,7 +34,9 @@ entity Sweep is RESET : in STD_LOGIC; NPOINTS : in STD_LOGIC_VECTOR (12 downto 0); CONFIG_ADDRESS : out STD_LOGIC_VECTOR (12 downto 0); - CONFIG_DATA : in STD_LOGIC_VECTOR (111 downto 0); + CONFIG_DATA : in STD_LOGIC_VECTOR (95 downto 0); + USER_NSAMPLES : in STD_LOGIC_VECTOR (9 downto 0); + NSAMPLES : out STD_LOGIC_VECTOR (9 downto 0); SAMPLING_BUSY : in STD_LOGIC; SAMPLING_DONE : in STD_LOGIC; START_SAMPLING : out STD_LOGIC; @@ -63,7 +65,7 @@ entity Sweep is ATTENUATOR : out STD_LOGIC_VECTOR(6 downto 0); SOURCE_FILTER : out STD_LOGIC_VECTOR(1 downto 0); - SETTLING_TIME : in STD_LOGIC_VECTOR (15 downto 0); + --SETTLING_TIME : in STD_LOGIC_VECTOR (15 downto 0); EXCITE_PORT1 : in STD_LOGIC; EXCITE_PORT2 : in STD_LOGIC; @@ -78,40 +80,47 @@ architecture Behavioral of Sweep is type Point_states is (TriggerSetup, SettingUp, SettlingPort1, ExcitingPort1, SettlingPort2, ExcitingPort2, Done); signal state : Point_states; signal settling_cnt : unsigned(15 downto 0); + signal settling_time : unsigned(15 downto 0); begin CONFIG_ADDRESS <= std_logic_vector(point_cnt); -- assemble registers - -- sweep config content: - -- 15 downto 0: Source N divider - -- 27 downto 16: Source Frac - -- 39 downto 28: Source M - -- 45 downto 40: Source VCO selection - -- 48 downto 46: Source DIVA - -- 55 downto 49: Attenuator selection - -- 71 downto 56: LO N divider - -- 83 downto 72: LO Frac - -- 95 downto 84: LO M - -- 101 downto 96: LO VCO selection - -- 104 downto 102: LO DIVA - -- 106 downto 105: Source filter selection - -- 111 downto 107: reserved - SOURCE_REG_0 <= MAX2871_DEF_0(31) & CONFIG_DATA(15 downto 0) & CONFIG_DATA(27 downto 16) & "000"; + -- source register 0: N divider and fractional division value + SOURCE_REG_0 <= MAX2871_DEF_0(31) & "000000000" & CONFIG_DATA(6 downto 0) & CONFIG_DATA(27 downto 16) & "000"; + -- source register 1: Modulus value SOURCE_REG_1 <= MAX2871_DEF_1(31 downto 15) & CONFIG_DATA(39 downto 28) & "001"; - SOURCE_REG_3 <= CONFIG_DATA(45 downto 40) & MAX2871_DEF_3(25 downto 3) & "011"; + -- source register 3: VCO selection + SOURCE_REG_3 <= CONFIG_DATA(12 downto 7) & MAX2871_DEF_3(25 downto 3) & "011"; -- output power A passed on from default registers, output B disabled - SOURCE_REG_4 <= MAX2871_DEF_4(31 downto 23) & CONFIG_DATA(48 downto 46) & MAX2871_DEF_4(19 downto 9) & "000" & MAX2871_DEF_4(5 downto 3) & "100"; + SOURCE_REG_4 <= MAX2871_DEF_4(31 downto 23) & CONFIG_DATA(15 downto 13) & MAX2871_DEF_4(19 downto 9) & "000" & MAX2871_DEF_4(5 downto 3) & "100"; - LO_REG_0 <= MAX2871_DEF_0(31) & CONFIG_DATA(71 downto 56) & CONFIG_DATA(83 downto 72) & "000"; - LO_REG_1 <= MAX2871_DEF_1(31 downto 15) & CONFIG_DATA(95 downto 84) & "001"; - LO_REG_3 <= CONFIG_DATA(101 downto 96) & MAX2871_DEF_3(25 downto 3) & "011"; + -- LO register 0: N divider and fractional division value + LO_REG_0 <= MAX2871_DEF_0(31) & "000000000" & CONFIG_DATA(54 downto 48) & CONFIG_DATA(75 downto 64) & "000"; + -- LO register 1: Modulus value + LO_REG_1 <= MAX2871_DEF_1(31 downto 15) & CONFIG_DATA(87 downto 76) & "001"; + -- LO register 3: VCO selection + LO_REG_3 <= CONFIG_DATA(60 downto 55) & MAX2871_DEF_3(25 downto 3) & "011"; -- both outputs enabled at -1dbm - LO_REG_4 <= MAX2871_DEF_4(31 downto 23) & CONFIG_DATA(104 downto 102) & MAX2871_DEF_4(19 downto 9) & "101101100"; + LO_REG_4 <= MAX2871_DEF_4(31 downto 23) & CONFIG_DATA(63 downto 61) & MAX2871_DEF_4(19 downto 9) & "101101100"; - ATTENUATOR <= CONFIG_DATA(55 downto 49); - SOURCE_FILTER <= CONFIG_DATA(106 downto 105); - BAND_SELECT <= CONFIG_DATA(110); + ATTENUATOR <= CONFIG_DATA(46 downto 40); + SOURCE_FILTER <= CONFIG_DATA(89 downto 88); + BAND_SELECT <= CONFIG_DATA(47); + + settling_time <= to_unsigned(2048, 16) when CONFIG_DATA(94 downto 93) = "00" else -- 20us + to_unsigned(6144, 16) when CONFIG_DATA(94 downto 93) = "01" else -- 60us + to_unsigned(18432, 16) when CONFIG_DATA(94 downto 93) = "10" else -- 180us + to_unsigned(55296, 16); -- 540us + + NSAMPLES <= USER_NSAMPLES when CONFIG_DATA(92 downto 90) = "000" else + std_logic_vector(to_unsigned(1, 10)) when CONFIG_DATA(92 downto 90) = "001" else + std_logic_vector(to_unsigned(3, 10)) when CONFIG_DATA(92 downto 90) = "010" else + std_logic_vector(to_unsigned(7, 10)) when CONFIG_DATA(92 downto 90) = "011" else + std_logic_vector(to_unsigned(24, 10)) when CONFIG_DATA(92 downto 90) = "100" else + std_logic_vector(to_unsigned(71, 10)) when CONFIG_DATA(92 downto 90) = "101" else + std_logic_vector(to_unsigned(238, 10)) when CONFIG_DATA(92 downto 90) = "110" else + std_logic_vector(to_unsigned(714, 10)); DEBUG_STATUS(10 downto 8) <= "000" when state = TriggerSetup else "001" when state = SettingUp else @@ -134,6 +143,7 @@ begin state <= TriggerSetup; START_SAMPLING <= '0'; RELOAD_PLL_REGS <= '0'; + SWEEP_HALTED <= '0'; else case state is when TriggerSetup => @@ -143,11 +153,11 @@ begin end if; when SettingUp => -- highest bit in CONFIG_DATA determines whether the sweep should be halted prior to sampling - SWEEP_HALTED <= CONFIG_DATA(111); + SWEEP_HALTED <= CONFIG_DATA(95); RELOAD_PLL_REGS <= '0'; if PLL_RELOAD_DONE = '1' and PLL_LOCKED = '1' then -- check if halted sweep is resumed - if CONFIG_DATA(111) = '0' or SWEEP_RESUME = '1' then + if CONFIG_DATA(95) = '0' or SWEEP_RESUME = '1' then SWEEP_HALTED <= '0'; if EXCITE_PORT1 = '1' then state <= SettlingPort1; @@ -156,7 +166,7 @@ begin else state <= Done; end if; - settling_cnt <= unsigned(SETTLING_TIME); + settling_cnt <= settling_time; end if; end if; when SettlingPort1 => diff --git a/FPGA/VNA/VNA.gise b/FPGA/VNA/VNA.gise index 18d9233..4732579 100644 --- a/FPGA/VNA/VNA.gise +++ b/FPGA/VNA/VNA.gise @@ -142,6 +142,10 @@ + + + + @@ -192,7 +196,7 @@ - + @@ -219,7 +223,7 @@ - + @@ -241,7 +245,7 @@ - + @@ -250,7 +254,7 @@ - + @@ -266,7 +270,7 @@ - + @@ -280,7 +284,7 @@ - + @@ -326,7 +330,7 @@ - + diff --git a/FPGA/VNA/top.vhd b/FPGA/VNA/top.vhd index a62c65c..fd5db50 100644 --- a/FPGA/VNA/top.vhd +++ b/FPGA/VNA/top.vhd @@ -111,7 +111,9 @@ architecture Behavioral of top is CLK : IN std_logic; RESET : IN std_logic; NPOINTS : IN std_logic_vector(12 downto 0); - CONFIG_DATA : IN std_logic_vector(111 downto 0); + CONFIG_DATA : IN std_logic_vector(95 downto 0); + USER_NSAMPLES : in STD_LOGIC_VECTOR (9 downto 0); + NSAMPLES : out STD_LOGIC_VECTOR (9 downto 0); SAMPLING_BUSY : in STD_LOGIC; SAMPLING_DONE : IN std_logic; MAX2871_DEF_4 : IN std_logic_vector(31 downto 0); @@ -119,8 +121,7 @@ architecture Behavioral of top is MAX2871_DEF_1 : IN std_logic_vector(31 downto 0); MAX2871_DEF_0 : IN std_logic_vector(31 downto 0); PLL_RELOAD_DONE : IN std_logic; - PLL_LOCKED : IN std_logic; - SETTLING_TIME : IN std_logic_vector(15 downto 0); + PLL_LOCKED : IN std_logic; CONFIG_ADDRESS : OUT std_logic_vector(12 downto 0); START_SAMPLING : OUT std_logic; PORT_SELECT : OUT std_logic; @@ -138,8 +139,8 @@ architecture Behavioral of top is SWEEP_RESUME : in STD_LOGIC; ATTENUATOR : OUT std_logic_vector(6 downto 0); SOURCE_FILTER : OUT std_logic_vector(1 downto 0); - EXCITE_PORT1 : out STD_LOGIC; - EXCITE_PORT2 : out STD_LOGIC; + EXCITE_PORT1 : in STD_LOGIC; + EXCITE_PORT2 : in STD_LOGIC; DEBUG_STATUS : out STD_LOGIC_VECTOR (10 downto 0) ); END COMPONENT; @@ -156,7 +157,7 @@ architecture Behavioral of top is REF : IN std_logic_vector(15 downto 0); NEW_SAMPLE : IN std_logic; START : IN std_logic; - SAMPLES : IN std_logic_vector(16 downto 0); + SAMPLES : IN std_logic_vector(9 downto 0); ADC_START : OUT std_logic; DONE : OUT std_logic; PRE_DONE : OUT std_logic; @@ -219,12 +220,11 @@ architecture Behavioral of top is MAX2871_DEF_3 : OUT std_logic_vector(31 downto 0); MAX2871_DEF_1 : OUT std_logic_vector(31 downto 0); MAX2871_DEF_0 : OUT std_logic_vector(31 downto 0); - SWEEP_DATA : OUT std_logic_vector(111 downto 0); + SWEEP_DATA : OUT std_logic_vector(95 downto 0); SWEEP_ADDRESS : OUT std_logic_vector(12 downto 0); SWEEP_WRITE : OUT std_logic_vector(0 to 0); SWEEP_POINTS : OUT std_logic_vector(12 downto 0); - NSAMPLES : OUT std_logic_vector(16 downto 0); - SETTLING_TIME : out STD_LOGIC_VECTOR (15 downto 0); + NSAMPLES : OUT std_logic_vector(9 downto 0); EXCITE_PORT1 : out STD_LOGIC; EXCITE_PORT2 : out STD_LOGIC; PORT1_EN : out STD_LOGIC; @@ -236,7 +236,7 @@ architecture Behavioral of top is SOURCE_CE_EN : out STD_LOGIC; LO_CE_EN : out STD_LOGIC; LEDS : out STD_LOGIC_VECTOR(2 downto 0); - SYNC_SETTING : out STD_LOGIC_VECTOR(1 downto 0); + WINDOW_SETTING : out STD_LOGIC_VECTOR(1 downto 0); INTERRUPT_ASSERTED : OUT std_logic; RESET_MINMAX : out STD_LOGIC; SWEEP_HALTED : in STD_LOGIC; @@ -251,10 +251,10 @@ architecture Behavioral of top is ena : IN STD_LOGIC; wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0); addra : IN STD_LOGIC_VECTOR(12 DOWNTO 0); - dina : IN STD_LOGIC_VECTOR(111 DOWNTO 0); + dina : IN STD_LOGIC_VECTOR(95 DOWNTO 0); clkb : IN STD_LOGIC; addrb : IN STD_LOGIC_VECTOR(12 DOWNTO 0); - doutb : OUT STD_LOGIC_VECTOR(111 DOWNTO 0) + doutb : OUT STD_LOGIC_VECTOR(95 DOWNTO 0) ); END COMPONENT; @@ -302,18 +302,19 @@ architecture Behavioral of top is signal sampling_busy : std_logic; signal sampling_done : std_logic; signal sampling_start : std_logic; - signal sampling_samples : std_logic_vector(16 downto 0); + signal sampling_samples : std_logic_vector(9 downto 0); + signal sampling_user_samples : std_logic_vector(9 downto 0); signal sampling_result : std_logic_vector(287 downto 0); -- Sweep signals signal sweep_points : std_logic_vector(12 downto 0); - signal sweep_config_data : std_logic_vector(111 downto 0); + signal sweep_config_data : std_logic_vector(95 downto 0); signal sweep_config_address : std_logic_vector(12 downto 0); signal source_filter : std_logic_vector(1 downto 0); signal sweep_port_select : std_logic; signal sweep_config_write_address : std_logic_vector(12 downto 0); - signal sweep_config_write_data : std_logic_vector(111 downto 0); + signal sweep_config_write_data : std_logic_vector(95 downto 0); signal sweep_config_write : std_logic_vector(0 downto 0); signal sweep_reset : std_logic; @@ -558,6 +559,8 @@ begin NPOINTS => sweep_points, CONFIG_ADDRESS => sweep_config_address, CONFIG_DATA => sweep_config_data, + USER_NSAMPLES => sampling_user_samples, + NSAMPLES => sampling_user_samples, SAMPLING_BUSY => sampling_busy, SAMPLING_DONE => sampling_done, START_SAMPLING => sampling_start, @@ -582,7 +585,6 @@ begin SWEEP_RESUME => sweep_resume, ATTENUATOR => ATTENUATION, SOURCE_FILTER => source_filter, - SETTLING_TIME => settling_time, EXCITE_PORT1 => sweep_excite_port1, EXCITE_PORT2 => sweep_excite_port2, DEBUG_STATUS => debug @@ -632,7 +634,6 @@ begin SWEEP_WRITE => sweep_config_write, SWEEP_POINTS => sweep_points, NSAMPLES => sampling_samples, - SETTLING_TIME => settling_time, PORT1_EN => port1mix_en, PORT2_EN => port2mix_en, REF_EN => refmix_en, @@ -642,7 +643,7 @@ begin SOURCE_CE_EN => SOURCE_CE, LO_CE_EN => LO1_CE, LEDS => user_leds, - SYNC_SETTING => open, + WINDOW_SETTING => open, INTERRUPT_ASSERTED => intr, RESET_MINMAX => adc_reset_minmax, SWEEP_HALTED => sweep_halted, diff --git a/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.cpp b/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.cpp index bbf50b3..900a02b 100644 --- a/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.cpp +++ b/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.cpp @@ -95,23 +95,11 @@ void FPGA::SetNumberOfPoints(uint16_t npoints) { } void FPGA::SetSamplesPerPoint(uint32_t nsamples) { - // register has to be set to number of nsamples - 1 - nsamples--; + // register is in multiples of 128 + nsamples /= 128; // constrain to maximum value - nsamples &= 0x1FFFF; - // highest bit is located at the system control register - SysCtrlReg &= ~0x0001; - SysCtrlReg |= nsamples >> 16; - WriteRegister(Reg::SystemControl, SysCtrlReg); - WriteRegister(Reg::SamplesPerPoint, nsamples & 0xFFFF); -} - -void FPGA::SetSettlingTime(uint16_t us) { - if (us > 639) { - us = 639; - } - uint16_t regval = (uint32_t) us * 1024 / 10; - WriteRegister(Reg::SettlingTime, regval); + nsamples &= 0x03FF; + WriteRegister(Reg::SamplesPerPoint, nsamples); } void FPGA::Enable(Periphery p, bool enable) { @@ -150,42 +138,53 @@ void FPGA::WriteMAX2871Default(uint32_t *DefaultRegs) { } void FPGA::WriteSweepConfig(uint16_t pointnum, bool lowband, uint32_t *SourceRegs, uint32_t *LORegs, - uint8_t attenuation, uint64_t frequency, bool halt, LowpassFilter filter) { - uint16_t send[8]; + uint8_t attenuation, uint64_t frequency, SettlingTime settling, Samples samples, bool halt, LowpassFilter filter) { + uint16_t send[7]; // select which point this sweep config is for send[0] = pointnum & 0x1FFF; // assemble sweep config from required fields of PLL registers - send[1] = (LORegs[4] & 0x00700000) >> 14 | (LORegs[3] & 0xFC000000) >> 26; + uint16_t LO_N = (LORegs[0] & 0x7FFF8000) >> 15; + uint16_t LO_FRAC = (LORegs[0] & 0x00007FF8) >> 3; + uint16_t LO_M = (LORegs[1] & 0x00007FF8) >> 3; + uint16_t LO_VCO = (LORegs[3] & 0xFC000000) >> 26; + uint16_t LO_DIV_A = (LORegs[4] & 0x00700000) >> 20; + + uint16_t Source_N = (SourceRegs[0] & 0x7FFF8000) >> 15; + uint16_t Source_FRAC = (SourceRegs[0] & 0x00007FF8) >> 3; + uint16_t Source_M = (SourceRegs[1] & 0x00007FF8) >> 3; + uint16_t Source_VCO = (SourceRegs[3] & 0xFC000000) >> 26; + uint16_t Source_DIV_A = (SourceRegs[4] & 0x00700000) >> 20; + + send[1] = LO_M >> 4; if (halt) { send[1] |= 0x8000; } - if (lowband) { - send[1] |= 0x4000; - } - switch(filter) { - case LowpassFilter::Auto: + send[1] |= (int) settling << 13; + send[1] |= (int) samples << 10; + if(filter == LowpassFilter::Auto) { // Select source LP filter if (frequency >= 3500000000) { - send[1] |= 0x0600; + send[1] |= (int) LowpassFilter::None << 8; } else if (frequency >= 1800000000) { - send[1] |= 0x0400; + send[1] |= (int) LowpassFilter::M3500 << 8; } else if (frequency >= 900000000) { - send[1] |= 0x0200; + send[1] |= (int) LowpassFilter::M1880 << 8; + } else { + send[1] |= (int) LowpassFilter::M947 << 8; } - break; - case LowpassFilter::M947: break; - case LowpassFilter::M1880: send[1] |= 0x0200; break; - case LowpassFilter::M3500: send[1] |= 0x0400; break; - case LowpassFilter::None: send[1] |= 0x0600; break; + } else { + send[1] |= (int) filter << 8; } - send[2] = (LORegs[1] & 0x00007FF8) << 1 | (LORegs[0] & 0x00007800) >> 11; - send[3] = (LORegs[0] & 0x000007F8) << 5 | (LORegs[0] & 0x7F800000) >> 23; - send[4] = (LORegs[0] & 0x007F8000) >> 7 | (attenuation & 0x7F) << 1 | (SourceRegs[4] & 0x00400000) >> 22; - send[5] = (SourceRegs[4] & 0x00300000) >> 6 | (SourceRegs[3] & 0xFC000000) >> 18 | (SourceRegs[1] & 0x00007F80) >> 7; - send[6] = (SourceRegs[1] & 0x00000078) << 9 | (SourceRegs[0] & 0x00007FF8) >> 3; - send[7] = (SourceRegs[0] & 0x7FFF8000) >> 15; + send[2] = (LO_M & 0x000F) << 12 | LO_FRAC; + send[3] = LO_DIV_A << 13 | LO_VCO << 7 | LO_N; + send[4] = (uint16_t) attenuation << 8 | Source_M >> 4; + if (lowband) { + send[4] |= 0x8000; + } + send[5] = (Source_M & 0x000F) << 12 | Source_FRAC; + send[6] = Source_DIV_A << 13 | Source_VCO << 7 | Source_N; Low(CS); - HAL_SPI_Transmit(&FPGA_SPI, (uint8_t*) send, 8, 100); + HAL_SPI_Transmit(&FPGA_SPI, (uint8_t*) send, 7, 100); High(CS); } diff --git a/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.hpp b/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.hpp index df877cf..ee8e20b 100644 --- a/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.hpp +++ b/Software/VNA_embedded/Application/Drivers/FPGA/FPGA.hpp @@ -67,20 +67,37 @@ enum class LowpassFilter { Auto = 0xFF, }; +enum class SettlingTime { + us20 = 0x00, + us60 = 0x01, + us180 = 0x02, + us540 = 0x03, +}; + +enum class Samples { + SPPRegister = 0x00, + S128 = 0x01, + S384 = 0x02, + S896 = 0x03, + S3072 = 0x04, + S9088 = 0x05, + S30464 = 0x06, + S91392 = 0x07, +}; + bool Configure(Flash *f, uint32_t start_address, uint32_t bitstream_size); using HaltedCallback = void(*)(void); bool Init(HaltedCallback cb = nullptr); void SetNumberOfPoints(uint16_t npoints); void SetSamplesPerPoint(uint32_t nsamples); -void SetSettlingTime(uint16_t us); void Enable(Periphery p, bool enable = true); void Disable(Periphery p); void EnableInterrupt(Interrupt i); void DisableInterrupt(Interrupt i); void WriteMAX2871Default(uint32_t *DefaultRegs); void WriteSweepConfig(uint16_t pointnum, bool lowband, uint32_t *SourceRegs, uint32_t *LORegs, - uint8_t attenuation, uint64_t frequency, bool halt = false, LowpassFilter filter = LowpassFilter::Auto); + uint8_t attenuation, uint64_t frequency, SettlingTime settling, Samples samples, bool halt = false, LowpassFilter filter = LowpassFilter::Auto); using ReadCallback = void(*)(SamplingResult result); bool InitiateSampleRead(ReadCallback cb); ADCLimits GetADCLimits(); diff --git a/Software/VNA_embedded/Application/VNA.cpp b/Software/VNA_embedded/Application/VNA.cpp index 354d0b8..e4c4f3f 100644 --- a/Software/VNA_embedded/Application/VNA.cpp +++ b/Software/VNA_embedded/Application/VNA.cpp @@ -224,7 +224,6 @@ bool VNA::ConfigureSweep(Protocol::SweepSettings s, SweepCallback cb) { FPGA::AbortSweep(); uint16_t points = settings.points <= FPGA::MaxPoints ? settings.points : FPGA::MaxPoints; // Configure sweep - FPGA::SetSettlingTime(500); FPGA::SetNumberOfPoints(points); uint32_t samplesPerPoint = (1000000 / s.if_bandwidth); // round up to next multiple of 128 (128 samples are spread across 35 IF2 periods) @@ -316,7 +315,9 @@ bool VNA::ConfigureSweep(Protocol::SweepSettings s, SweepCallback cb) { needs_halt = true; } LO1.SetFrequency(freq + used_IF); - FPGA::WriteSweepConfig(i, lowband, Source.GetRegisters(), LO1.GetRegisters(), attenuator, freq, needs_halt); + FPGA::WriteSweepConfig(i, lowband, Source.GetRegisters(), + LO1.GetRegisters(), attenuator, freq, FPGA::SettlingTime::us540, + FPGA::Samples::SPPRegister, needs_halt); last_lowband = lowband; } // // revert clk configuration to previous value (might have been changed in sweep calculation) @@ -382,11 +383,11 @@ bool VNA::ConfigureManual(Protocol::ManualControl m, StatusCallback cb) { FPGA::SetNumberOfPoints(1); FPGA::SetSamplesPerPoint(m.Samples); - FPGA::SetSettlingTime(1); // Configure single sweep point FPGA::WriteSweepConfig(0, !m.SourceHighband, Source.GetRegisters(), - LO1.GetRegisters(), m.attenuator, 0, 0, + LO1.GetRegisters(), m.attenuator, 0, FPGA::SettlingTime::us20, + FPGA::Samples::SPPRegister, 0, (FPGA::LowpassFilter) m.SourceHighLowpass); // Enable/Disable periphery