mirror of
https://github.com/jankae/LibreVNA.git
synced 2026-04-04 14:07:30 +00:00
Allow different source PLL power per sweep point, add power range to sweep
This commit is contained in:
parent
6490d6fd14
commit
7bc18881a5
10 changed files with 96 additions and 389 deletions
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
namespace Protocol {
|
||||
|
||||
static constexpr uint16_t Version = 5;
|
||||
static constexpr uint16_t Version = 7;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
|
|
@ -22,10 +22,12 @@ using SweepSettings = struct _sweepSettings {
|
|||
uint64_t f_stop;
|
||||
uint16_t points;
|
||||
uint32_t if_bandwidth;
|
||||
int16_t cdbm_excitation; // in 1/100 dbm
|
||||
int16_t cdbm_excitation_start; // in 1/100 dbm
|
||||
uint8_t excitePort1:1;
|
||||
uint8_t excitePort2:1;
|
||||
uint8_t suppressPeaks:1;
|
||||
uint8_t fixedPowerSetting:1; // if set the attenuator and source PLL power will not be changed across the sweep
|
||||
int16_t cdbm_excitation_stop; // in 1/100 dbm
|
||||
};
|
||||
|
||||
using ReferenceSettings = struct _referenceSettings {
|
||||
|
|
|
|||
|
|
@ -197,6 +197,8 @@ void FPGA::WriteSweepConfig(uint16_t pointnum, bool lowband, uint32_t *SourceReg
|
|||
uint16_t Source_VCO = (SourceRegs[3] & 0xFC000000) >> 26;
|
||||
uint16_t Source_DIV_A = (SourceRegs[4] & 0x00700000) >> 20;
|
||||
|
||||
uint16_t Source_Power = (SourceRegs[4] & 0x00000018) >> 3;
|
||||
|
||||
send[1] = LO_M >> 4;
|
||||
if (halt) {
|
||||
send[1] |= 0x8000;
|
||||
|
|
@ -218,13 +220,13 @@ void FPGA::WriteSweepConfig(uint16_t pointnum, bool lowband, uint32_t *SourceReg
|
|||
send[1] |= (int) filter << 8;
|
||||
}
|
||||
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;
|
||||
send[3] = LO_DIV_A << 13 | LO_VCO << 7 | LO_N << 1;
|
||||
send[4] = Source_Power << 14 | (uint16_t) attenuation << 7 | Source_M >> 5;
|
||||
if (lowband) {
|
||||
send[4] |= 0x8000;
|
||||
send[3] |= 0x0001;
|
||||
}
|
||||
send[5] = (Source_M & 0x000F) << 12 | Source_FRAC;
|
||||
send[6] = Source_DIV_A << 13 | Source_VCO << 7 | Source_N;
|
||||
send[5] = (Source_M & 0x001F) << 11 | Source_FRAC >> 1;
|
||||
send[6] = (Source_FRAC & 0x0001) << 15 | Source_DIV_A << 12 | Source_VCO << 6 | Source_N;
|
||||
SwitchBytes(send[0]);
|
||||
SwitchBytes(send[1]);
|
||||
SwitchBytes(send[2]);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <cstdint>
|
||||
#include "Flash.hpp"
|
||||
#include "max2871.hpp"
|
||||
|
||||
namespace FPGA {
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ static uint16_t pointCnt;
|
|||
static bool excitingPort1;
|
||||
static Protocol::Datapoint data;
|
||||
static bool active = false;
|
||||
static bool sourceHighPower;
|
||||
static Si5351C::DriveStrength fixedPowerLowband;
|
||||
static bool adcShifted;
|
||||
static uint32_t actualBandwidth;
|
||||
|
||||
|
|
@ -76,26 +76,24 @@ bool VNA::Setup(Protocol::SweepSettings s) {
|
|||
// has to be one less than actual number of samples
|
||||
FPGA::SetSamplesPerPoint(samplesPerPoint);
|
||||
|
||||
// Set level (not very accurate)
|
||||
int16_t cdbm = s.cdbm_excitation;
|
||||
if(cdbm > -1000) {
|
||||
// use higher source power (approx 0dbm with no attenuation)
|
||||
sourceHighPower = true;
|
||||
Source.SetPowerOutA(MAX2871::Power::p5dbm, true);
|
||||
} else {
|
||||
// use lower source power (approx -10dbm with no attenuation)
|
||||
sourceHighPower = false;
|
||||
Source.SetPowerOutA(MAX2871::Power::n4dbm, true);
|
||||
cdbm += 1000;
|
||||
}
|
||||
uint8_t attenuator;
|
||||
if(cdbm >= 0) {
|
||||
attenuator = 0;
|
||||
} else if (cdbm <= -3175){
|
||||
attenuator = 127;
|
||||
} else {
|
||||
attenuator = (-cdbm) / 25;
|
||||
// Start with average level
|
||||
auto cdbm = (s.cdbm_excitation_start + s.cdbm_excitation_stop) / 2;
|
||||
// correct for port 1, assumes port 2 is identical
|
||||
auto centerFreq = (s.f_start + s.f_stop) / 2;
|
||||
// force calculation of amplitude setting for PLL, even with lower frequencies
|
||||
if(centerFreq < HW::BandSwitchFrequency) {
|
||||
centerFreq = HW::BandSwitchFrequency;
|
||||
}
|
||||
auto amplitude = HW::GetAmplitudeSettings(cdbm, centerFreq, true, false);
|
||||
|
||||
uint8_t fixedAttenuatorHighband = amplitude.attenuator;
|
||||
Source.SetPowerOutA(amplitude.highBandPower, true);
|
||||
|
||||
// amplitude calculation for lowband
|
||||
amplitude = HW::GetAmplitudeSettings(cdbm, HW::BandSwitchFrequency / 2, true, false);
|
||||
uint8_t fixedAttenuatorLowband = amplitude.attenuator;
|
||||
fixedPowerLowband = amplitude.lowBandPower;
|
||||
|
||||
FPGA::WriteMAX2871Default(Source.GetRegisters());
|
||||
|
||||
uint32_t last_LO2 = HW::IF1 - HW::IF2;
|
||||
|
|
@ -117,6 +115,7 @@ bool VNA::Setup(Protocol::SweepSettings s) {
|
|||
for (uint16_t i = 0; i < points; i++) {
|
||||
bool harmonic_mixing = false;
|
||||
uint64_t freq = s.f_start + (s.f_stop - s.f_start) * i / (points - 1);
|
||||
int16_t power = s.cdbm_excitation_start + (s.cdbm_excitation_stop - s.cdbm_excitation_start) * i / (points - 1);
|
||||
freq = Cal::FrequencyCorrectionToDevice(freq);
|
||||
|
||||
if(freq > 6000000000ULL) {
|
||||
|
|
@ -206,6 +205,16 @@ bool VNA::Setup(Protocol::SweepSettings s) {
|
|||
pointsWithoutHalt = 0;
|
||||
}
|
||||
|
||||
uint8_t attenuator = freq >= HW::BandSwitchFrequency ? fixedAttenuatorHighband : fixedAttenuatorLowband;
|
||||
if(!s.fixedPowerSetting) {
|
||||
// adapt power level throughout the sweep
|
||||
amplitude = HW::GetAmplitudeSettings(power, freq, true, false);
|
||||
if(freq >= HW::BandSwitchFrequency) {
|
||||
Source.SetPowerOutA(amplitude.highBandPower, true);
|
||||
}
|
||||
attenuator = amplitude.attenuator;
|
||||
}
|
||||
|
||||
FPGA::WriteSweepConfig(i, lowband, Source.GetRegisters(),
|
||||
LO1.GetRegisters(), attenuator, freq, FPGA::SettlingTime::us20,
|
||||
FPGA::Samples::SPPRegister, needs_halt);
|
||||
|
|
@ -331,11 +340,20 @@ void VNA::SweepHalted() {
|
|||
uint64_t frequency = settings.f_start
|
||||
+ (settings.f_stop - settings.f_start) * pointCnt
|
||||
/ (settings.points - 1);
|
||||
int16_t power = settings.cdbm_excitation_start
|
||||
+ (settings.cdbm_excitation_stop - settings.cdbm_excitation_start)
|
||||
* pointCnt / (settings.points - 1);
|
||||
bool adcShiftRequired = false;
|
||||
if (frequency < HW::BandSwitchFrequency) {
|
||||
auto driveStrength = fixedPowerLowband;
|
||||
if(!settings.fixedPowerSetting) {
|
||||
auto amplitude = HW::GetAmplitudeSettings(power, frequency, true, false);
|
||||
// attenuator value has already been set in sweep setup
|
||||
driveStrength = amplitude.lowBandPower;
|
||||
}
|
||||
|
||||
// need the Si5351 as Source
|
||||
Si5351.SetCLK(SiChannel::LowbandSource, frequency, Si5351C::PLL::B,
|
||||
sourceHighPower ? Si5351C::DriveStrength::mA8 : Si5351C::DriveStrength::mA4);
|
||||
Si5351.SetCLK(SiChannel::LowbandSource, frequency, Si5351C::PLL::B, driveStrength);
|
||||
if (pointCnt == 0) {
|
||||
// First point in sweep, enable CLK
|
||||
Si5351.Enable(SiChannel::LowbandSource);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue