TCXO offset calibration

This commit is contained in:
Jan Käberich 2021-05-01 18:34:53 +02:00
parent 4f4b2db549
commit 938f444c73
19 changed files with 319 additions and 34 deletions

View File

@ -0,0 +1,39 @@
#include "frequencycaldialog.h"
#include "ui_frequencycaldialog.h"
FrequencyCalDialog::FrequencyCalDialog(Device *dev, QWidget *parent) :
QDialog(parent),
ui(new Ui::FrequencyCalDialog),
dev(dev)
{
ui->setupUi(this);
ui->ppm->setUnit("ppm");
ui->ppm->setPrefixes(" ");
ui->ppm->setPrecision(4);
ui->ppm->setValue(0.0);
connect(dev, &Device::FrequencyCorrectionReceived, ui->ppm, &SIUnitEdit::setValueQuiet);
connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
connect(ui->buttonBox, &QDialogButtonBox::accepted, [=](){
// get value and transfer to device
Protocol::PacketInfo p;
p.type = Protocol::PacketType::FrequencyCorrection;
p.frequencyCorrection.ppm = ui->ppm->value();
dev->SendPacket(p);
// force restart of current mode for setting to take effect
auto activeMode = Mode::getActiveMode();
activeMode->deactivate();
activeMode->activate();
accept();
delete this;
});
// request setting from device
dev->SendCommandWithoutPayload(Protocol::PacketType::RequestFrequencyCorrection);
}
FrequencyCalDialog::~FrequencyCalDialog()
{
delete ui;
}

View File

@ -0,0 +1,25 @@
#ifndef FREQUENCYCALDIALOG_H
#define FREQUENCYCALDIALOG_H
#include <QDialog>
#include "Device/device.h"
#include "mode.h"
namespace Ui {
class FrequencyCalDialog;
}
class FrequencyCalDialog : public QDialog
{
Q_OBJECT
public:
explicit FrequencyCalDialog(Device *dev, QWidget *parent = nullptr);
~FrequencyCalDialog();
private:
Ui::FrequencyCalDialog *ui;
Device *dev;
};
#endif // FREQUENCYCALDIALOG_H

View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FrequencyCalDialog</class>
<widget class="QDialog" name="FrequencyCalDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>363</width>
<height>178</height>
</rect>
</property>
<property name="windowTitle">
<string>Frequency Calibration</string>
</property>
<property name="modal">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Specify the error of the internal TCXO to correct for it during measurements and signal generation. This setting has no effect when an external reference is used.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>TCXO offset:</string>
</property>
</widget>
</item>
<item>
<widget class="SIUnitEdit" name="ppm"/>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>SIUnitEdit</class>
<extends>QLineEdit</extends>
<header>CustomWidgets/siunitedit.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>FrequencyCalDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>FrequencyCalDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -459,6 +459,9 @@ void Device::ReceivedData()
emit NackReceived();
emit receivedAnswer(TransmissionResult::Nack);
break;
case Protocol::PacketType::FrequencyCorrection:
emit FrequencyCorrectionReceived(packet.frequencyCorrection.ppm);
break;
default:
break;
}

View File

@ -75,6 +75,7 @@ signals:
void ManualStatusReceived(Protocol::ManualStatus);
void SpectrumResultReceived(Protocol::SpectrumAnalyzerResult);
void AmplitudeCorrectionPointReceived(Protocol::AmplitudeCorrectionPoint);
void FrequencyCorrectionReceived(float ppm);
void DeviceInfoUpdated();
void ConnectionLost();
void AckReceived();

View File

@ -5,6 +5,7 @@ HEADERS += \
Calibration/calibrationtracedialog.h \
Calibration/calkit.h \
Calibration/calkitdialog.h \
Calibration/frequencycaldialog.h \
Calibration/manualcalibrationdialog.h \
Calibration/measurementmodel.h \
Calibration/receivercaldialog.h \
@ -128,6 +129,7 @@ SOURCES += \
Calibration/calibrationtracedialog.cpp \
Calibration/calkit.cpp \
Calibration/calkitdialog.cpp \
Calibration/frequencycaldialog.cpp \
Calibration/manualcalibrationdialog.cpp \
Calibration/measurementmodel.cpp \
Calibration/receivercaldialog.cpp \
@ -244,6 +246,7 @@ FORMS += \
Calibration/automaticamplitudedialog.ui \
Calibration/calibrationtracedialog.ui \
Calibration/calkitdialog.ui \
Calibration/frequencycaldialog.ui \
Calibration/manualcalibrationdialog.ui \
CustomWidgets/jsonpickerdialog.ui \
CustomWidgets/tilewidget.ui \

View File

@ -46,6 +46,7 @@
#include "SpectrumAnalyzer/spectrumanalyzer.h"
#include "Calibration/sourcecaldialog.h"
#include "Calibration/receivercaldialog.h"
#include "Calibration/frequencycaldialog.h"
#include <QDebug>
#include "CustomWidgets/jsonpickerdialog.h"
#include <QCommandLineParser>
@ -185,6 +186,7 @@ AppWindow::AppWindow(QWidget *parent)
connect(ui->actionFirmware_Update, &QAction::triggered, this, &AppWindow::StartFirmwareUpdateDialog);
connect(ui->actionSource_Calibration, &QAction::triggered, this, &AppWindow::SourceCalibrationDialog);
connect(ui->actionReceiver_Calibration, &QAction::triggered, this, &AppWindow::ReceiverCalibrationDialog);
connect(ui->actionFrequency_Calibration, &QAction::triggered, this, &AppWindow::FrequencyCalibrationDialog);
connect(ui->actionPreferences, &QAction::triggered, [=](){
// save previous SCPI settings in case they change
auto &p = Preferences::getInstance();
@ -291,6 +293,7 @@ bool AppWindow::ConnectToDevice(QString serial)
ui->actionFirmware_Update->setEnabled(true);
ui->actionSource_Calibration->setEnabled(true);
ui->actionReceiver_Calibration->setEnabled(true);
ui->actionFrequency_Calibration->setEnabled(true);
Mode::getActiveMode()->initializeDevice();
UpdateReference();
@ -321,6 +324,7 @@ void AppWindow::DisconnectDevice()
ui->actionFirmware_Update->setEnabled(false);
ui->actionSource_Calibration->setEnabled(false);
ui->actionReceiver_Calibration->setEnabled(false);
ui->actionFrequency_Calibration->setEnabled(false);
for(auto a : deviceActionGroup->actions()) {
a->setChecked(false);
}
@ -654,6 +658,12 @@ void AppWindow::ReceiverCalibrationDialog()
d->exec();
}
void AppWindow::FrequencyCalibrationDialog()
{
auto d = new FrequencyCalDialog(device);
d->exec();
}
nlohmann::json AppWindow::SaveSetup()
{
nlohmann::json j;

View File

@ -53,6 +53,7 @@ private slots:
void DeviceNeedsUpdate(int reported, int expected);
void SourceCalibrationDialog();
void ReceiverCalibrationDialog();
void FrequencyCalibrationDialog();
nlohmann::json SaveSetup();
void LoadSetup(nlohmann::json j);
private:

View File

@ -54,6 +54,7 @@
<addaction name="separator"/>
<addaction name="actionSource_Calibration"/>
<addaction name="actionReceiver_Calibration"/>
<addaction name="actionFrequency_Calibration"/>
</widget>
<widget class="QMenu" name="menuWindow">
<property name="title">
@ -193,12 +194,21 @@
</action>
<action name="actionSave_image">
<property name="icon">
<iconset theme="camera-photo"/>
<iconset theme="camera-photo">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="text">
<string>Save image...</string>
</property>
</action>
<action name="actionFrequency_Calibration">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Frequency Calibration</string>
</property>
</action>
</widget>
<resources>
<include location="icons.qrc"/>

View File

@ -1,3 +1,4 @@
#include <Cal.hpp>
#include <VNA.hpp>
#include "App.h"
@ -18,7 +19,6 @@
#include "Generator.hpp"
#include "SpectrumAnalyzer.hpp"
#include "HW_HAL.hpp"
#include "AmplitudeCal.hpp"
#define LOG_LEVEL LOG_LEVEL_INFO
#define LOG_MODULE "App"
@ -86,7 +86,7 @@ void App_Start() {
EN_6V_GPIO_Port->BSRR = EN_6V_Pin;
#endif
AmplitudeCal::Load();
Cal::Load();
if (!HW::Init()) {
LOG_CRIT("Initialization failed, unable to start");
@ -191,18 +191,31 @@ void App_Start() {
#endif
case Protocol::PacketType::RequestSourceCal:
Communication::SendWithoutPayload(Protocol::PacketType::Ack);
AmplitudeCal::SendSource();
Cal::SendSource();
break;
case Protocol::PacketType::RequestReceiverCal:
Communication::SendWithoutPayload(Protocol::PacketType::Ack);
AmplitudeCal::SendReceiver();
Cal::SendReceiver();
break;
case Protocol::PacketType::SourceCalPoint:
AmplitudeCal::AddSourcePoint(recv_packet.amplitudePoint);
Cal::AddSourcePoint(recv_packet.amplitudePoint);
Communication::SendWithoutPayload(Protocol::PacketType::Ack);
break;
case Protocol::PacketType::ReceiverCalPoint:
AmplitudeCal::AddReceiverPoint(recv_packet.amplitudePoint);
Cal::AddReceiverPoint(recv_packet.amplitudePoint);
Communication::SendWithoutPayload(Protocol::PacketType::Ack);
break;
case Protocol::PacketType::RequestFrequencyCorrection:
Communication::SendWithoutPayload(Protocol::PacketType::Ack);
{
Protocol::PacketInfo send;
send.type = Protocol::PacketType::FrequencyCorrection;
send.frequencyCorrection.ppm = Cal::getFrequencyCal();
Communication::Send(send);
}
break;
case Protocol::PacketType::FrequencyCorrection:
Cal::setFrequencyCal(recv_packet.frequencyCorrection.ppm);
Communication::SendWithoutPayload(Protocol::PacketType::Ack);
break;
default:

View File

@ -1,7 +1,8 @@
#include "AmplitudeCal.hpp"
#include <Cal.hpp>
#include <cstring>
#include "Communication.h"
#include "HW_HAL.hpp"
#include "Hardware.hpp"
#define LOG_LEVEL LOG_LEVEL_INFO
#define LOG_MODULE "CAL"
@ -9,26 +10,27 @@
// increment when Calibration struct format changed. If a wrong version is found in flash, it will revert to default values
static constexpr uint16_t version = 0x0000;
static constexpr uint16_t version = 0x0001;
using CorrectionTable = struct {
uint8_t usedPoints;
uint32_t freq[AmplitudeCal::maxPoints]; // LSB = 10Hz
int16_t port1Correction[AmplitudeCal::maxPoints]; // LSB = 0.01db
int16_t port2Correction[AmplitudeCal::maxPoints]; // LSB = 0.01db
uint32_t freq[Cal::maxPoints]; // LSB = 10Hz
int16_t port1Correction[Cal::maxPoints]; // LSB = 0.01db
int16_t port2Correction[Cal::maxPoints]; // LSB = 0.01db
};
using Calibration = struct _calibration {
uint16_t version;
CorrectionTable Source;
CorrectionTable Receiver;
float TCXO_PPM_correction;
};
static Calibration cal;
static_assert(sizeof(cal) <= AmplitudeCal::flash_size, "Reserved flash size is too small");
static_assert(sizeof(cal) <= Cal::flash_size, "Reserved flash size is too small");
bool AmplitudeCal::Load() {
bool Cal::Load() {
HWHAL::flash.read(flash_address, sizeof(cal), &cal);
if(cal.version != version) {
LOG_WARN("Invalid version in flash, expected %u, got %u", version, cal.version);
@ -44,7 +46,7 @@ bool AmplitudeCal::Load() {
}
}
bool AmplitudeCal::Save() {
bool Cal::Save() {
if(!HWHAL::flash.eraseRange(flash_address, flash_size)) {
return false;
}
@ -56,7 +58,7 @@ bool AmplitudeCal::Save() {
return HWHAL::flash.write(flash_address, write_size, &cal);
}
void AmplitudeCal::SetDefault() {
void Cal::SetDefault() {
memset(&cal, 0, sizeof(cal));
cal.version = version;
cal.Source.usedPoints = 1;
@ -66,10 +68,10 @@ void AmplitudeCal::SetDefault() {
LOG_INFO("Set to default");
}
static AmplitudeCal::Correction InterpolateCorrection(const CorrectionTable& table, uint64_t freq) {
static Cal::Correction InterpolateCorrection(const CorrectionTable& table, uint64_t freq) {
// adjust LSB to match table
freq /= 10;
AmplitudeCal::Correction ret;
Cal::Correction ret;
// find first valid index that is higher than the given frequency
uint8_t i = 0;
for (; i < table.usedPoints; i++) {
@ -94,11 +96,11 @@ static AmplitudeCal::Correction InterpolateCorrection(const CorrectionTable& tab
return ret;
}
AmplitudeCal::Correction AmplitudeCal::SourceCorrection(uint64_t freq) {
Cal::Correction Cal::SourceCorrection(uint64_t freq) {
return InterpolateCorrection(cal.Source, freq);
}
AmplitudeCal::Correction AmplitudeCal::ReceiverCorrection(uint64_t freq) {
Cal::Correction Cal::ReceiverCorrection(uint64_t freq) {
return InterpolateCorrection(cal.Receiver, freq);
}
@ -116,34 +118,64 @@ static void SendCorrectionTable(const CorrectionTable& table, Protocol::PacketTy
}
}
void AmplitudeCal::SendSource() {
void Cal::SendSource() {
SendCorrectionTable(cal.Source, Protocol::PacketType::SourceCalPoint);
}
void AmplitudeCal::SendReceiver() {
void Cal::SendReceiver() {
SendCorrectionTable(cal.Receiver, Protocol::PacketType::ReceiverCalPoint);
}
static void addPoint(CorrectionTable& table, const Protocol::AmplitudeCorrectionPoint& p) {
if(p.pointNum >= AmplitudeCal::maxPoints) {
if(p.pointNum >= Cal::maxPoints) {
// ignore out-of-bounds point
return;
}
table.freq[p.pointNum] = p.freq;
table.port1Correction[p.pointNum] = p.port1;
table.port2Correction[p.pointNum] = p.port2;
if(p.pointNum == p.totalPoints - 1 || p.pointNum == AmplitudeCal::maxPoints - 1) {
if(p.pointNum == p.totalPoints - 1 || p.pointNum == Cal::maxPoints - 1) {
// this was the last point, update used points and save
table.usedPoints = p.totalPoints;
LOG_INFO("Last point received, saving to flash");
AmplitudeCal::Save();
Cal::Save();
}
}
void AmplitudeCal::AddSourcePoint(const Protocol::AmplitudeCorrectionPoint& p) {
void Cal::AddSourcePoint(const Protocol::AmplitudeCorrectionPoint& p) {
addPoint(cal.Source, p);
}
void AmplitudeCal::AddReceiverPoint(const Protocol::AmplitudeCorrectionPoint& p) {
void Cal::AddReceiverPoint(const Protocol::AmplitudeCorrectionPoint& p) {
addPoint(cal.Receiver, p);
}
uint64_t Cal::FrequencyCorrectionToDevice(uint64_t freq) {
// The frequency calibration is only used when the internal reference is active.
// If an external reference is in use, it is assumed to already be at the correct frequency
if(!HW::Ref::usingExternal()) {
freq -= freq * cal.TCXO_PPM_correction * 1e-6f;
}
return freq;
}
uint64_t Cal::FrequencyCorrectionFromDevice(uint64_t freq) {
if(!HW::Ref::usingExternal()) {
// this formula is not exactly correct, it should actually be
// freq *= (1+PPM*10^-6). However, this can not be used directly
// due to floating point limitation. But the error of this approximation
// is so small that is doesn't make a difference (as the result only has
// 1Hz resolution anyway)
freq += freq * cal.TCXO_PPM_correction * 1e-6f;
}
return freq;
}
float Cal::getFrequencyCal() {
return cal.TCXO_PPM_correction;
}
bool Cal::setFrequencyCal(float ppm) {
cal.TCXO_PPM_correction = ppm;
return Save();
}

View File

@ -5,7 +5,7 @@
#include "Firmware.hpp"
#include "Protocol.hpp"
namespace AmplitudeCal {
namespace Cal {
constexpr uint8_t maxPoints = 64;
constexpr uint32_t flash_address = Firmware::maxSize; // stored directly behind firmware in flash
@ -22,9 +22,16 @@ using Correction = struct _correction {
Correction SourceCorrection(uint64_t freq);
Correction ReceiverCorrection(uint64_t freq);
// converts a frequency as received from the GUI to a calibrated value that should be used for the PLLs etc.
uint64_t FrequencyCorrectionToDevice(uint64_t freq);
// corrects a measured frequency to its calibrated value for transfer to the GUI
uint64_t FrequencyCorrectionFromDevice(uint64_t freq);
void SendSource();
void SendReceiver();
void AddSourcePoint(const Protocol::AmplitudeCorrectionPoint& p);
void AddReceiverPoint(const Protocol::AmplitudeCorrectionPoint& p);
float getFrequencyCal();
bool setFrequencyCal(float ppm);
}

View File

@ -99,6 +99,7 @@ uint16_t Protocol::EncodePacket(const PacketInfo &packet, uint8_t *dest, uint16_
case PacketType::SpectrumAnalyzerResult: payload_size = sizeof(packet.spectrumResult); break;
case PacketType::SourceCalPoint:
case PacketType::ReceiverCalPoint: payload_size = sizeof(packet.amplitudePoint); break;
case PacketType::FrequencyCorrection: payload_size = sizeof(packet.frequencyCorrection); break;
case PacketType::Ack:
case PacketType::PerformFirmwareUpdate:
case PacketType::ClearFlash:
@ -107,6 +108,7 @@ uint16_t Protocol::EncodePacket(const PacketInfo &packet, uint8_t *dest, uint16_
case PacketType::RequestSourceCal:
case PacketType::RequestReceiverCal:
case PacketType::SetIdle:
case PacketType::RequestFrequencyCorrection:
// no payload
break;
case PacketType::None:

View File

@ -4,7 +4,7 @@
namespace Protocol {
static constexpr uint16_t Version = 4;
static constexpr uint16_t Version = 5;
#pragma pack(push, 1)
@ -152,6 +152,10 @@ using AmplitudeCorrectionPoint = struct _amplitudecorrectionpoint {
int16_t port2;
};
using FrequencyCorrection = struct _frequencycorrection {
float ppm;
};
enum class PacketType : uint8_t {
None = 0,
Datapoint = 1,
@ -174,6 +178,8 @@ enum class PacketType : uint8_t {
SourceCalPoint = 18,
ReceiverCalPoint = 19,
SetIdle = 20,
RequestFrequencyCorrection = 21,
FrequencyCorrection = 22,
};
using PacketInfo = struct _packetinfo {
@ -190,6 +196,7 @@ using PacketInfo = struct _packetinfo {
SpectrumAnalyzerSettings spectrumSettings;
SpectrumAnalyzerResult spectrumResult;
AmplitudeCorrectionPoint amplitudePoint;
FrequencyCorrection frequencyCorrection;
};
};

View File

@ -1,9 +1,9 @@
#include <Cal.hpp>
#include "Generator.hpp"
#include "Manual.hpp"
#include "Hardware.hpp"
#include "max2871.hpp"
#include "Si5351C.hpp"
#include "AmplitudeCal.hpp"
void Generator::Setup(Protocol::GeneratorSettings g) {
if(g.activePort == 0) {
@ -35,6 +35,7 @@ void Generator::Setup(Protocol::GeneratorSettings g) {
m.PortSwitch = 1;
break;
}
g.frequency = Cal::FrequencyCorrectionToDevice(g.frequency);
auto amplitude = HW::GetAmplitudeSettings(g.cdbm_level, g.frequency, g.applyAmplitudeCorrection, g.activePort == 2);
// Select correct source
if(g.frequency < HW::BandSwitchFrequency) {

View File

@ -235,7 +235,7 @@ void HW::SetIdle() {
HW::AmplitudeSettings HW::GetAmplitudeSettings(int16_t cdbm, uint64_t freq, bool applyCorrections, bool port2) {
if (applyCorrections) {
auto correction = AmplitudeCal::SourceCorrection(freq);
auto correction = Cal::SourceCorrection(freq);
if (port2) {
cdbm += correction.port2;
} else {
@ -336,6 +336,10 @@ void HW::Ref::set(Protocol::ReferenceSettings s) {
ref = s;
}
bool HW::Ref::usingExternal() {
return extRefInUse;
}
void HW::Ref::update() {
if(extOutFreq != ref.ExtRefOuputFreq) {
extOutFreq = ref.ExtRefOuputFreq;

View File

@ -1,9 +1,9 @@
#pragma once
#include <Cal.hpp>
#include <cstdint>
#include "Protocol.hpp"
#include "FPGA/FPGA.hpp"
#include "AmplitudeCal.hpp"
#include "max2871.hpp"
#include "Si5351C.hpp"
@ -73,7 +73,7 @@ static constexpr Protocol::DeviceInfo Info = {
.limits_cdbm_max = 0,
.limits_minRBW = (uint32_t) (ADCSamplerate * 2.23f / MaxSamples),
.limits_maxRBW = (uint32_t) (ADCSamplerate * 2.23f / MinSamples),
.limits_maxAmplitudePoints = AmplitudeCal::maxPoints,
.limits_maxAmplitudePoints = Cal::maxPoints,
.limits_maxFreqHarmonic = 18000000000,
};
@ -106,6 +106,7 @@ bool GetTemps(uint8_t *source, uint8_t *lo);
void fillDeviceInfo(Protocol::DeviceInfo *info, bool updateEvenWhenBusy = false);
namespace Ref {
bool available();
bool usingExternal();
// reference won't change until update is called
void set(Protocol::ReferenceSettings s);
void update();

View File

@ -38,6 +38,7 @@ static bool trackingLowband;
static void StartNextSample() {
uint64_t freq = s.f_start + (s.f_stop - s.f_start) * pointCnt / (points - 1);
freq = Cal::FrequencyCorrectionToDevice(freq);
uint64_t LO1freq;
uint32_t LO2freq;
switch(signalIDstep) {
@ -364,7 +365,7 @@ void SA::Work() {
p.spectrumResult.port1 /= 253000000.0;
p.spectrumResult.port2 /= 253000000.0;
if (s.applyReceiverCorrection) {
auto correction = AmplitudeCal::ReceiverCorrection(p.spectrumResult.frequency);
auto correction = Cal::ReceiverCorrection(p.spectrumResult.frequency);
p.spectrumResult.port1 *= powf(10.0f, (float) correction.port1 / 100.0f / 20.0f);
p.spectrumResult.port2 *= powf(10.0f, (float) correction.port2 / 100.0f / 20.0f);
}

View File

@ -117,6 +117,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);
freq = Cal::FrequencyCorrectionToDevice(freq);
if(freq > 6000000000ULL) {
harmonic_mixing = true;