LibreVNA settings widget

This commit is contained in:
Jan Käberich 2023-02-06 18:06:50 +01:00
parent 2c86cf1d6c
commit 89e46057a5
13 changed files with 410 additions and 274 deletions

View File

@ -5,10 +5,11 @@
#include "frequencycaldialog.h"
#include "sourcecaldialog.h"
#include "receivercaldialog.h"
#include "unit.h"
#include "CustomWidgets/informationbox.h"
#include "ui_librevnadriversettingswidget.h"
using namespace std;
class Reference
@ -153,6 +154,9 @@ LibreVNADriver::LibreVNADriver()
specificSettings.push_back(Savable::SettingDescription(&VNAAdjustPowerLevel, "adjustPowerLevel", false));
specificSettings.push_back(Savable::SettingDescription(&SAUseDFT, "useDFT", true));
specificSettings.push_back(Savable::SettingDescription(&SARBWLimitForDFT, "RBWlimitDFT", 3000));
specificSettings.push_back(Savable::SettingDescription(&IF1, "IF1", 62000000));
specificSettings.push_back(Savable::SettingDescription(&ADCprescaler, "ADCprescaler", 128));
specificSettings.push_back(Savable::SettingDescription(&DFTPhaseInc, "DFTPhaseInc", 1280));
}
std::set<DeviceDriver::Flag> LibreVNADriver::getFlags()
@ -192,6 +196,94 @@ QString LibreVNADriver::getStatus()
return ret;
}
QWidget *LibreVNADriver::createSettingsWidget()
{
auto w = new QWidget;
auto ui = new Ui::LibreVNADriverSettingsWidget;
ui->setupUi(w);
// Set initial values
ui->CaptureRawReceiverValues->setChecked(captureRawReceiverValues);
ui->UseHarmonicMixing->setChecked(harmonicMixing);
ui->UseSignalID->setChecked(SASignalID);
ui->SuppressPeaks->setChecked(VNASuppressInvalidPeaks);
ui->AdjustPowerLevel->setChecked(VNAAdjustPowerLevel);
ui->DFTlimitRBW->setEnabled(false);
connect(ui->UseDFT, &QCheckBox::toggled, ui->DFTlimitRBW, &SIUnitEdit::setEnabled);
ui->UseDFT->setChecked(SAUseDFT);
ui->DFTlimitRBW->setUnit("Hz");
ui->DFTlimitRBW->setPrefixes(" kM");
ui->DFTlimitRBW->setPrecision(3);
ui->DFTlimitRBW->setValue(SARBWLimitForDFT);
auto updateADCRate = [=]() {
// update ADC rate, see FPGA protocol for calculation
ui->ADCRate->setValue(102400000.0 / ui->ADCpresc->value());
};
auto updateIF2 = [=]() {
auto ADCrate = ui->ADCRate->value();
ui->IF2->setValue(ADCrate * ui->ADCphaseInc->value() / 4096);
};
connect(ui->ADCpresc, qOverload<int>(&QSpinBox::valueChanged), updateADCRate);
connect(ui->ADCpresc, qOverload<int>(&QSpinBox::valueChanged), updateIF2);
connect(ui->ADCphaseInc, qOverload<int>(&QSpinBox::valueChanged), updateIF2);
ui->IF1->setUnit("Hz");
ui->IF1->setPrefixes(" kM");
ui->IF1->setPrecision(5);
ui->IF1->setValue(IF1);
ui->ADCpresc->setValue(ADCprescaler);
ui->ADCphaseInc->setValue(DFTPhaseInc);
updateADCRate();
updateIF2();
connect(ui->UseHarmonicMixing, &QCheckBox::toggled, [=](bool enabled) {
if(enabled) {
InformationBox::ShowMessage("Harmonic Mixing", "When harmonic mixing is enabled, the frequency range of the VNA is (theoretically) extended up to 18GHz "
"by using higher harmonics of the source signal as well as the 1.LO. The fundamental frequency is still present "
"in the output signal and might disturb the measurement if the DUT is not linear. Performance above 6GHz is not "
"specified and generally not very good. However, this mode might be useful if the signal of interest is just above "
"6GHz (typically useful values up to 7-8GHz). Performance below 6GHz is not affected by this setting");
}
});
// make connections to change the values
connect(ui->CaptureRawReceiverValues, &QCheckBox::toggled, this, [=](){
captureRawReceiverValues = ui->CaptureRawReceiverValues->isChecked();
});
connect(ui->UseHarmonicMixing, &QCheckBox::toggled, this, [=](){
harmonicMixing = ui->UseHarmonicMixing->isChecked();
});
connect(ui->UseSignalID, &QCheckBox::toggled, this, [=](){
SASignalID = ui->UseSignalID->isChecked();
});
connect(ui->SuppressPeaks, &QCheckBox::toggled, this, [=](){
VNASuppressInvalidPeaks = ui->SuppressPeaks->isChecked();
});
connect(ui->AdjustPowerLevel, &QCheckBox::toggled, this, [=](){
VNAAdjustPowerLevel = ui->AdjustPowerLevel->isChecked();
});
connect(ui->UseDFT, &QCheckBox::toggled, this, [=](){
SAUseDFT = ui->UseDFT->isChecked();
});
connect(ui->DFTlimitRBW, &SIUnitEdit::valueChanged, this, [=](){
SARBWLimitForDFT = ui->DFTlimitRBW->value();
});
connect(ui->IF1, &SIUnitEdit::valueChanged, this, [=](){
IF1 = ui->IF1->value();
});
connect(ui->ADCpresc, qOverload<int>(&QSpinBox::valueChanged), this, [=](){
ADCprescaler = ui->ADCpresc->value();
});
connect(ui->ADCphaseInc, qOverload<int>(&QSpinBox::valueChanged), this, [=](){
DFTPhaseInc = ui->ADCphaseInc->value();
});
return w;
}
QStringList LibreVNADriver::availableVNAMeasurements()
{
QStringList ret;
@ -539,6 +631,16 @@ void LibreVNADriver::handleReceivedPacket(const Protocol::PacketInfo &packet)
}
}
void LibreVNADriver::updateIFFrequencies()
{
Protocol::PacketInfo p;
p.type = Protocol::PacketType::AcquisitionFrequencySettings;
p.acquisitionFrequencySettings.IF1 = IF1;
p.acquisitionFrequencySettings.ADCprescaler = ADCprescaler;
p.acquisitionFrequencySettings.DFTphaseInc = DFTPhaseInc;
SendPacket(p);
}
unsigned int LibreVNADriver::getMaxAmplitudePoints() const
{
return limits_maxAmplitudePoints;

View File

@ -1,4 +1,4 @@
#ifndef LIBREVNADRIVER_H
#ifndef LIBREVNADRIVER_H
#define LIBREVNADRIVER_H
#include "../devicedriver.h"
@ -55,6 +55,18 @@ public:
*/
virtual QString getStatus() override;
/**
* @brief Returns a widget to edit the driver specific settings.
*
* The widget is displayed in the global settings dialog and allows the user to edit the settings
* specific to this driver. The application takes ownership of the widget after returning,
* create a new widget for every call to this function. If the driver has no specific settings
* or the settings do not need to be editable by the user, return a nullptr. In this case, no
* page for this driver is created in the settings dialog
* @return newly constructed settings widget or nullptr
*/
virtual QWidget* createSettingsWidget() override;
/**
* @brief Names of available measurements.
*
@ -166,6 +178,7 @@ signals:
protected slots:
void handleReceivedPacket(const Protocol::PacketInfo& packet);
protected:
void updateIFFrequencies();
bool connected;
QString serial;
@ -188,6 +201,9 @@ protected:
double SARBWLimitForDFT;
bool VNASuppressInvalidPeaks;
bool VNAAdjustPowerLevel;
double IF1;
unsigned int ADCprescaler;
unsigned int DFTPhaseInc;
};
Q_DECLARE_METATYPE(Protocol::PacketInfo)

View File

@ -0,0 +1,224 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>LibreVNADriverSettingsWidget</class>
<widget class="QWidget" name="LibreVNADriverSettingsWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>615</width>
<height>598</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Vector Network Analyzer</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QCheckBox" name="SuppressPeaks">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Due to limited fractional divider settings, the source and 1.LO PLLs are not able to reach every frequency exactly. At some specific frequencies this causes the final IF to shift. At these frequencies there will be a positive or negative peak in the trace measurement that is not actually there.&lt;br/&gt;&lt;br/&gt;Checking this option shifts the 2.LO for points where this could be an issue. This will remove the peaks but slows down the sweep slightly.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Suppress invalid peaks</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="AdjustPowerLevel">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If enabled, the step attenuator setting will be changed during the sweep to keep the selected output power across frequency as accurate as possible.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Adjust power level during sweep</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="UseHarmonicMixing">
<property name="text">
<string>Use harmonic mixing</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Spectrum Analyzer</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="UseSignalID">
<property name="text">
<string>Enable Signal ID</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QCheckBox" name="UseDFT">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Normally, the spectrum analyzer mode tunes the LO for each point and measures the final IF only at one frequency. When this option is enabled, a DFT of the final IF is calculated instead which covers multiple frequencies with one measurement.&lt;/p&gt;&lt;p&gt;This can speed up the measurement at low RBWs significantly.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Use DFT when RBW is below</string>
</property>
</widget>
</item>
<item>
<widget class="SIUnitEdit" name="DFTlimitRBW"/>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_25">
<property name="title">
<string>Debug - Acquisition</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_32">
<item>
<widget class="QCheckBox" name="CaptureRawReceiverValues">
<property name="text">
<string>Capture raw receiver values</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_15">
<property name="title">
<string>IF frequencies</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QLabel" name="label_34">
<property name="text">
<string>This section contains advanced system settings. It is recommended to leave them at default values unless you know what you are doing. Slight changes of the IF frequencies can be used to shift possible spikes to less problematic frequencies. Large changes of these frequencies may severely impact device performance.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_29">
<property name="text">
<string>IF 1:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="SIUnitEdit" name="IF1">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Frequency of the first IF&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_30">
<property name="text">
<string>ADC prescaler:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="ADCpresc">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;ADC prescaler in FPGA. The ADC sample rate is determined by 102.4MHz/prescaler&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="minimum">
<number>112</number>
</property>
<property name="maximum">
<number>255</number>
</property>
<property name="value">
<number>128</number>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_31">
<property name="text">
<string>ADC sample rate:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="SIUnitEdit" name="ADCRate">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_32">
<property name="text">
<string>Phase increment:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="ADCphaseInc">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Phase increment per ADC sample. Together with the ADC sample rate this determines the frequency of the second IF&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>4095</number>
</property>
<property name="value">
<number>1280</number>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_33">
<property name="text">
<string>IF 2:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="SIUnitEdit" name="IF2">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>SIUnitEdit</class>
<extends>QLineEdit</extends>
<header>CustomWidgets/siunitedit.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@ -132,6 +132,7 @@ bool LibreVNATCPDriver::connectTo(QString serial)
sendWithoutPayload(Protocol::PacketType::RequestDeviceInfo);
sendWithoutPayload(Protocol::PacketType::RequestDeviceStatus);
updateIFFrequencies();
return true;
}

View File

@ -219,6 +219,7 @@ bool LibreVNAUSBDriver::connectTo(QString serial)
sendWithoutPayload(Protocol::PacketType::RequestDeviceInfo);
sendWithoutPayload(Protocol::PacketType::RequestDeviceStatus);
updateIFFrequencies();
return true;
}

View File

@ -1,5 +1,8 @@
#include "devicedriver.h"
#include "LibreVNA/librevnatcpdriver.h"
#include "LibreVNA/librevnausbdriver.h"
DeviceDriver *DeviceDriver::activeDriver = nullptr;
DeviceDriver::~DeviceDriver()
@ -9,6 +12,17 @@ DeviceDriver::~DeviceDriver()
}
}
std::vector<DeviceDriver *> DeviceDriver::getDrivers()
{
static std::vector<DeviceDriver*> ret;
if (ret.size() == 0) {
// first function call
ret.push_back(new LibreVNAUSBDriver);
ret.push_back(new LibreVNATCPDriver);
}
return ret;
}
bool DeviceDriver::connectDevice(QString serial)
{
if(activeDriver && activeDriver != this) {

View File

@ -8,7 +8,7 @@
* - Derive from this class
* - Implement all pure virtual functions
* - Implement the virtual functions if the device supports the specific function
* - register the driver during application start
* - Add the new driver to getDrivers()
*/
#include "Tools/parameters.h"
@ -27,6 +27,12 @@ public:
DeviceDriver() {}
virtual ~DeviceDriver();
/**
* @brief Returns a list of all available drivers
* @return driverlist
*/
static std::vector<DeviceDriver*> getDrivers();
/**
* @brief Returns the driver name. It must be unique across all implemented drivers and is used to identify the driver
* @return driver name
@ -203,6 +209,18 @@ public:
*/
std::vector<Savable::SettingDescription> driverSpecificSettings() {return specificSettings;}
/**
* @brief Returns a widget to edit the driver specific settings.
*
* The widget is displayed in the global settings dialog and allows the user to edit the settings
* specific to this driver. The application takes ownership of the widget after returning,
* create a new widget for every call to this function. If the driver has no specific settings
* or the settings do not need to be editable by the user, return a nullptr. In this case, no
* page for this driver is created in the settings dialog
* @return newly constructed settings widget or nullptr
*/
virtual QWidget* createSettingsWidget() {return nullptr;}
/**
* @brief Return driver specific actions.
*

View File

@ -318,6 +318,7 @@ FORMS += \
Device/LibreVNA/automaticamplitudedialog.ui \
Device/LibreVNA/firmwareupdatedialog.ui \
Device/LibreVNA/frequencycaldialog.ui \
Device/LibreVNA/librevnadriversettingswidget.ui \
Device/LibreVNA/manualcontroldialog.ui \
Device/compounddeviceeditdialog.ui \
Device/devicelog.ui \

View File

@ -100,11 +100,7 @@ AppWindow::AppWindow(QWidget *parent)
Preferences::getInstance().load();
}
// Register device drivers
deviceDrivers.push_back(new LibreVNAUSBDriver());
deviceDrivers.push_back(new LibreVNATCPDriver());
for(auto driver : deviceDrivers) {
for(auto driver : DeviceDriver::getDrivers()) {
driver->registerTypes();
Preferences::getInstance().load(driver->driverSpecificSettings());
}
@ -325,10 +321,10 @@ void AppWindow::closeEvent(QCloseEvent *event)
delete modeHandler;
modeHandler = nullptr;
pref.store();
for(auto driver : deviceDrivers) {
for(auto driver : DeviceDriver::getDrivers()) {
Preferences::getInstance().store(driver->driverSpecificSettings());
}
for(auto driver : deviceDrivers) {
for(auto driver : DeviceDriver::getDrivers()) {
delete driver;
}
QMainWindow::closeEvent(event);
@ -347,7 +343,7 @@ bool AppWindow::ConnectToDevice(QString serial, DeviceDriver *driver)
}
try {
qDebug() << "Attempting to connect to device...";
for(auto d : deviceDrivers) {
for(auto d : DeviceDriver::getDrivers()) {
if(driver && driver != d) {
// not the specified driver
continue;
@ -522,7 +518,7 @@ void AppWindow::SetupSCPI()
}));
scpi_dev->add(new SCPICommand("LIST", nullptr, [=](QStringList) -> QString {
QString ret;
for(auto driver : deviceDrivers) {
for(auto driver : DeviceDriver::getDrivers()) {
for(auto d : driver->GetAvailableDevices()) {
ret += d + ",";
}
@ -983,7 +979,7 @@ int AppWindow::UpdateDeviceList()
deviceActionGroup->setExclusive(true);
ui->menuConnect_to->clear();
deviceList.clear();
for(auto driver : deviceDrivers) {
for(auto driver : DeviceDriver::getDrivers()) {
for(auto serial : driver->GetAvailableDevices()) {
DeviceEntry e;
e.driver = driver;

View File

@ -109,7 +109,6 @@ private:
Mode *lastActiveMode;
// VirtualDevice *vdevice;
std::vector<DeviceDriver*> deviceDrivers;
DeviceDriver *device;
class DeviceEntry {

View File

@ -89,20 +89,6 @@ PreferencesDialog::PreferencesDialog(Preferences *pref, QWidget *parent) :
ui->StartupSARBW->setPrefixes(" k");
// Acquisition page
ui->AcquisitionDFTlimitRBW->setUnit("Hz");
ui->AcquisitionDFTlimitRBW->setPrefixes(" k");
connect(ui->AcquisitionUseDFT, &QCheckBox::toggled, [=](bool enabled) {
ui->AcquisitionDFTlimitRBW->setEnabled(enabled);
});
ui->AcquisitionIF1->setUnit("Hz");
ui->AcquisitionIF1->setPrefixes(" kM");
ui->AcquisitionIF1->setPrecision(6);
ui->AcquisitionADCRate->setUnit("Hz");
ui->AcquisitionADCRate->setPrefixes(" kM");
ui->AcquisitionADCRate->setPrecision(6);
ui->AcquisitionIF2->setUnit("Hz");
ui->AcquisitionIF2->setPrefixes(" kM");
ui->AcquisitionIF2->setPrecision(6);
ui->AcquisitionFullSpanStart->setUnit("Hz");
ui->AcquisitionFullSpanStart->setPrefixes(" kMG");
ui->AcquisitionFullSpanStart->setPrecision(6);
@ -111,17 +97,6 @@ PreferencesDialog::PreferencesDialog(Preferences *pref, QWidget *parent) :
ui->AcquisitionFullSpanStop->setPrefixes(" kMG");
ui->AcquisitionFullSpanStop->setPrecision(6);
ui->AcquisitionFullSpanStop->setEnabled(false);
auto updateADCRate = [=]() {
// update ADC rate, see FPGA protocol for calculation
ui->AcquisitionADCRate->setValue(102400000.0 / ui->AcquisitionADCpresc->value());
};
auto updateIF2 = [=]() {
auto ADCrate = ui->AcquisitionADCRate->value();
ui->AcquisitionIF2->setValue(ADCrate * ui->AcquisitionADCphaseInc->value() / 4096);
};
connect(ui->AcquisitionADCpresc, qOverload<int>(&QSpinBox::valueChanged), updateADCRate);
connect(ui->AcquisitionADCpresc, qOverload<int>(&QSpinBox::valueChanged), updateIF2);
connect(ui->AcquisitionADCphaseInc, qOverload<int>(&QSpinBox::valueChanged), updateIF2);
connect(ui->AcquisitionFullSpanBehavior, qOverload<int>(&QComboBox::currentIndexChanged), [=](){
ui->AcquisitionFullSpanStart->setEnabled(ui->AcquisitionFullSpanBehavior->currentIndex() == 1);
@ -216,6 +191,20 @@ PreferencesDialog::PreferencesDialog(Preferences *pref, QWidget *parent) :
ui->DebugMaxUSBlogSize->setUnit("B");
ui->DebugMaxUSBlogSize->setPrefixes(" kMG");
// Add device driver settings
QTreeWidgetItem *item = ui->treeWidget->findItems("Device Drivers", Qt::MatchExactly)[0];
for(auto driver : DeviceDriver::getDrivers()) {
auto w = driver->createSettingsWidget();
if(!w) {
continue;
}
w->setObjectName(driver->getDriverName());
ui->pageWidget->addWidget(w);
auto driverItem = new QTreeWidgetItem();
driverItem->setText(0, driver->getDriverName());
item->addChild(driverItem);
}
// Page selection
connect(ui->treeWidget, &QTreeWidget::currentItemChanged, [=](QTreeWidgetItem *current, QTreeWidgetItem *) {
auto name = current->text(0);
@ -270,18 +259,6 @@ PreferencesDialog::PreferencesDialog(Preferences *pref, QWidget *parent) :
});
setInitialGUIState();
updateADCRate();
updateIF2();
connect(ui->AcquisitionUseHarmonic, &QCheckBox::toggled, [=](bool enabled) {
if(enabled) {
InformationBox::ShowMessage("Harmonic Mixing", "When harmonic mixing is enabled, the frequency range of the VNA is (theoretically) extended up to 18GHz "
"by using higher harmonics of the source signal as well as the 1.LO. The fundamental frequency is still present "
"in the output signal and might disturb the measurement if the DUT is not linear. Performance above 6GHz is not "
"specified and generally not very good. However, this mode might be useful if the signal of interest is just above "
"6GHz (typically useful values up to 7-8GHz). Performance below 6GHz is not affected by this setting");
}
});
}
PreferencesDialog::~PreferencesDialog()
@ -322,16 +299,8 @@ void PreferencesDialog::setInitialGUIState()
ui->StartupSASignalID->setChecked(p->Startup.SA.signalID);
ui->AcquisitionAlwaysExciteBoth->setChecked(p->Acquisition.alwaysExciteAllPorts);
ui->AcquisitionSuppressPeaks->setChecked(p->Acquisition.suppressPeaks);
ui->AcquisitionAdjustPowerLevel->setChecked(p->Acquisition.adjustPowerLevel);
ui->AcquisitionUseHarmonic->setChecked(p->Acquisition.harmonicMixing);
ui->AcquisitionAllowSegmentedSweep->setChecked(p->Acquisition.allowSegmentedSweep);
ui->AcquisitionUseDFT->setChecked(p->Acquisition.useDFTinSAmode);
ui->AcquisitionDFTlimitRBW->setValue(p->Acquisition.RBWLimitForDFT);
ui->AcquisitionAveragingMode->setCurrentIndex(p->Acquisition.useMedianAveraging ? 1 : 0);
ui->AcquisitionIF1->setValue(p->Acquisition.IF1);
ui->AcquisitionADCpresc->setValue(p->Acquisition.ADCprescaler);
ui->AcquisitionADCphaseInc->setValue(p->Acquisition.DFTPhaseInc);
ui->AcquisitionFullSpanBehavior->setCurrentIndex(p->Acquisition.fullSpanManual ? 1 : 0);
ui->AcquisitionFullSpanStart->setValue(p->Acquisition.fullSpanStart);
ui->AcquisitionFullSpanStop->setValue(p->Acquisition.fullSpanStop);
@ -392,7 +361,6 @@ void PreferencesDialog::setInitialGUIState()
ui->DebugMaxUSBlogSize->setValue(p->Debug.USBlogSizeLimit);
ui->DebugSaveTraceData->setChecked(p->Debug.saveTraceData);
ui->DebugCaptureRawReceiverValues->setChecked(p->Debug.makeRawReceiverValuesAvailable);
for(auto cd : p->compoundDevices) {
ui->compoundList->addItem(cd->getDesription());
@ -431,16 +399,8 @@ void PreferencesDialog::updateFromGUI()
p->Startup.SA.signalID = ui->StartupSASignalID->isChecked();
p->Acquisition.alwaysExciteAllPorts = ui->AcquisitionAlwaysExciteBoth->isChecked();
p->Acquisition.suppressPeaks = ui->AcquisitionSuppressPeaks->isChecked();
p->Acquisition.adjustPowerLevel = ui->AcquisitionAdjustPowerLevel->isChecked();
p->Acquisition.harmonicMixing = ui->AcquisitionUseHarmonic->isChecked();
p->Acquisition.allowSegmentedSweep = ui->AcquisitionAllowSegmentedSweep->isChecked();
p->Acquisition.useDFTinSAmode = ui->AcquisitionUseDFT->isChecked();
p->Acquisition.RBWLimitForDFT = ui->AcquisitionDFTlimitRBW->value();
p->Acquisition.useMedianAveraging = ui->AcquisitionAveragingMode->currentIndex() == 1;
p->Acquisition.IF1 = ui->AcquisitionIF1->value();
p->Acquisition.ADCprescaler = ui->AcquisitionADCpresc->value();
p->Acquisition.DFTPhaseInc = ui->AcquisitionADCphaseInc->value();
p->Acquisition.fullSpanManual = ui->AcquisitionFullSpanBehavior->currentIndex() == 1;
p->Acquisition.fullSpanStart = ui->AcquisitionFullSpanStart->value();
p->Acquisition.fullSpanStop = ui->AcquisitionFullSpanStop->value();
@ -500,7 +460,6 @@ void PreferencesDialog::updateFromGUI()
p->Debug.USBlogSizeLimit = ui->DebugMaxUSBlogSize->value();
p->Debug.saveTraceData = ui->DebugSaveTraceData->isChecked();
p->Debug.makeRawReceiverValuesAvailable = ui->DebugCaptureRawReceiverValues->isChecked();
p->nonTrivialWriting();
}

View File

@ -96,19 +96,9 @@ public:
} Startup;
struct {
bool alwaysExciteAllPorts;
bool suppressPeaks;
bool adjustPowerLevel;
bool harmonicMixing;
bool allowSegmentedSweep;
bool useDFTinSAmode;
double RBWLimitForDFT;
bool useMedianAveraging;
// advanced, hardware specific settings
double IF1;
int ADCprescaler;
int DFTPhaseInc;
// Full span settings
bool fullSpanManual;
double fullSpanStart;
@ -165,7 +155,6 @@ public:
struct {
double USBlogSizeLimit;
bool saveTraceData;
bool makeRawReceiverValuesAvailable;
} Debug;
bool TCPoverride; // in case of manual port specification via command line
@ -212,16 +201,8 @@ private:
{&Startup.SA.averaging, "Startup.SA.averaging", 1},
{&Startup.SA.signalID, "Startup.SA.signalID", true},
{&Acquisition.alwaysExciteAllPorts, "Acquisition.alwaysExciteBothPorts", true},
{&Acquisition.suppressPeaks, "Acquisition.suppressPeaks", true},
{&Acquisition.adjustPowerLevel, "Acquisition.adjustPowerLevel", false},
{&Acquisition.harmonicMixing, "Acquisition.harmonicMixing", false},
{&Acquisition.allowSegmentedSweep, "Acquisition.allowSegmentedSweep", false},
{&Acquisition.useDFTinSAmode, "Acquisition.useDFTinSAmode", true},
{&Acquisition.RBWLimitForDFT, "Acquisition.RBWLimitForDFT", 3000.0},
{&Acquisition.useMedianAveraging, "Acquisition.useMedianAveraging", false},
{&Acquisition.IF1, "Acquisition.IF1", 62000000},
{&Acquisition.ADCprescaler, "Acquisition.ADCprescaler", 128},
{&Acquisition.DFTPhaseInc, "Acquisition.DFTPhaseInc", 1280},
{&Acquisition.fullSpanManual, "Acquisition.fullSpanManual", false},
{&Acquisition.fullSpanStart, "Acquisition.fullSpanStart", 0.0},
{&Acquisition.fullSpanStop, "Acquisition.fullSpanStop", 6000000000.0},
@ -277,7 +258,6 @@ private:
{&SCPIServer.port, "SCPIServer.port", 19542},
{&Debug.USBlogSizeLimit, "Debug.USBlogSizeLimit", 10000000.0},
{&Debug.saveTraceData, "Debug.saveTraceData", false},
{&Debug.makeRawReceiverValuesAvailable, "Debug.makeRawReceiverValuesAvailable", false},
{&compoundDeviceJSON, "compoundDeviceJSON", "[]"},
}};
};

View File

@ -76,6 +76,11 @@
<string>Debug</string>
</property>
</item>
<item>
<property name="text">
<string>Device Drivers</string>
</property>
</item>
</widget>
</item>
<item>
@ -712,8 +717,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>565</width>
<height>863</height>
<width>763</width>
<height>561</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_21">
@ -733,33 +738,6 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="AcquisitionSuppressPeaks">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Due to limited fractional divider settings, the source and 1.LO PLLs are not able to reach every frequency exactly. At some specific frequencies this causes the final IF to shift. At these frequencies there will be a positive or negative peak in the trace measurement that is not actually there.&lt;br/&gt;&lt;br/&gt;Checking this option shifts the 2.LO for points where this could be an issue. This will remove the peaks but slows down the sweep slightly.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Suppress invalid peaks</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="AcquisitionAdjustPowerLevel">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If enabled, the step attenuator setting will be changed during the sweep to keep the selected output power across frequency as accurate as possible.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Adjust power level during sweep</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="AcquisitionUseHarmonic">
<property name="text">
<string>Use harmonic mixing</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="AcquisitionAllowSegmentedSweep">
<property name="text">
@ -770,32 +748,6 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_7">
<property name="title">
<string>Spectrum Analyzer</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<layout class="QFormLayout" name="formLayout_5">
<item row="0" column="0">
<widget class="QCheckBox" name="AcquisitionUseDFT">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Normally, the spectrum analyzer mode tunes the LO for each point and measures the final IF only at one frequency. When this option is enabled, a DFT of the final IF is calculated instead which covers multiple frequencies with one measurement.&lt;/p&gt;&lt;p&gt;This can speed up the measurement at low RBWs significantly.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Use DFT when RBW is below</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="SIUnitEdit" name="AcquisitionDFTlimitRBW"/>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_14">
<property name="title">
@ -827,117 +779,6 @@
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox_15">
<property name="title">
<string>IF frequencies</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QLabel" name="label_34">
<property name="text">
<string>This section contains advanced system settings. It is recommended to leave them at default values unless you know what you are doing. Slight changes of the IF frequencies can be used to shift possible spikes to less problematic frequencies. Large changes of these frequencies may severely impact device performance.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_29">
<property name="text">
<string>IF 1:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="SIUnitEdit" name="AcquisitionIF1">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Frequency of the first IF&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_30">
<property name="text">
<string>ADC prescaler:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="AcquisitionADCpresc">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;ADC prescaler in FPGA. The ADC sample rate is determined by 102.4MHz/prescaler&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="minimum">
<number>112</number>
</property>
<property name="maximum">
<number>255</number>
</property>
<property name="value">
<number>128</number>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_31">
<property name="text">
<string>ADC sample rate:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="SIUnitEdit" name="AcquisitionADCRate">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_32">
<property name="text">
<string>Phase increment:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="AcquisitionADCphaseInc">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Phase increment per ADC sample. Together with the ADC sample rate this determines the frequency of the second IF&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>4095</number>
</property>
<property name="value">
<number>1280</number>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_33">
<property name="text">
<string>IF 2:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="SIUnitEdit" name="AcquisitionIF2">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_19">
<property name="title">
@ -1033,8 +874,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>553</width>
<height>969</height>
<width>749</width>
<height>952</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_22">
@ -1455,7 +1296,7 @@
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<y>-44</y>
<width>749</width>
<height>605</height>
</rect>
@ -1998,22 +1839,6 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_25">
<property name="title">
<string>Acquisition</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_32">
<item>
<widget class="QCheckBox" name="DebugCaptureRawReceiverValues">
<property name="text">
<string>Capture raw receiver values</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_9">
<property name="orientation">