Allow different source PLL power per sweep point, add power range to sweep

This commit is contained in:
Jan Käberich 2021-07-09 19:34:53 +02:00
parent 6490d6fd14
commit 7bc18881a5
10 changed files with 96 additions and 389 deletions

View file

@ -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 {

View file

@ -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]);

View file

@ -2,6 +2,7 @@
#include <cstdint>
#include "Flash.hpp"
#include "max2871.hpp"
namespace FPGA {

View file

@ -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);