Manual control dialog for prototype 0xD0
Some checks failed
Build / PC_Application_Ubuntu (push) Has been cancelled
Build / PC_Application_RPi5 (push) Has been cancelled
Build / PC_Application_Windows (push) Has been cancelled
Build / PC_Application_OSX (push) Has been cancelled
Build / PC_Application_OSX_13 (push) Has been cancelled
Build / Embedded_Firmware (push) Has been cancelled
HIL_Tests / Get_Repository (push) Has been cancelled
Unit_Tests / Tests (push) Has been cancelled
HIL_Tests / PC_Application_RPi5 (push) Has been cancelled
HIL_Tests / Embedded_Firmware (push) Has been cancelled
HIL_Tests / HIL (push) Has been cancelled

This commit is contained in:
Jan Käberich 2025-10-15 10:23:08 +02:00
parent 5d00d4786b
commit f51c6a0bce
8 changed files with 1794 additions and 0 deletions

View file

@ -4,6 +4,7 @@
#include "manualcontroldialogvff.h" #include "manualcontroldialogvff.h"
#include "manualcontroldialogvfe.h" #include "manualcontroldialogvfe.h"
#include "manualcontroldialogVE0.h" #include "manualcontroldialogVE0.h"
#include "manualcontroldialogVD0.h"
#include "deviceconfigurationdialogv1.h" #include "deviceconfigurationdialogv1.h"
#include "deviceconfigurationdialogvff.h" #include "deviceconfigurationdialogvff.h"
#include "deviceconfigurationdialogvfe.h" #include "deviceconfigurationdialogvfe.h"
@ -128,6 +129,9 @@ LibreVNADriver::LibreVNADriver()
case 1: case 1:
manualControlDialog = new ManualControlDialogV1(*this); manualControlDialog = new ManualControlDialogV1(*this);
break; break;
case 0xD0:
manualControlDialog = new ManualControlDialogVD0(*this);
break;
case 0xE0: case 0xE0:
manualControlDialog = new ManualControlDialogVE0(*this); manualControlDialog = new ManualControlDialogVE0(*this);
break; break;
@ -794,6 +798,7 @@ QString LibreVNADriver::getFirmwareMagicString()
{ {
switch(hardwareVersion) { switch(hardwareVersion) {
case 0x01: return "VNA!"; case 0x01: return "VNA!";
case 0xD0: return "VHP1";
case 0xE0: return "VNS1"; case 0xE0: return "VNS1";
case 0xFE: return "VNP2"; case 0xFE: return "VNP2";
case 0xFF: return "VNPT"; case 0xFF: return "VNPT";

View file

@ -0,0 +1,812 @@
#include "manualcontroldialogVD0.h"
#include "ui_manualcontroldialogVD0.h"
#include "Util/util.h"
#include <QComboBox>
#include <QDebug>
#include <QButtonGroup>
#include <complex>
using namespace std;
ManualControlDialogVD0::ManualControlDialogVD0(LibreVNADriver &dev, QWidget *parent) :
QDialog(parent),
ui(new Ui::ManualControlDialogVD0),
dev(dev)
{
ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose);
emit dev.acquireControl();
ui->SourceLowFrequency->setUnit("Hz");
ui->SourceLowFrequency->setPrefixes(" kM");
ui->SourceLowFrequency->setPrecision(6);
ui->SourceLowFrequency->setValueQuiet(1000000);
ui->SourceHighFrequency->setUnit("Hz");
ui->SourceHighFrequency->setPrefixes(" kMG");
ui->SourceHighFrequency->setPrecision(6);
ui->SourceHighFrequency->setValueQuiet(1000000000);
ui->IFHigh->setUnit("Hz");
ui->IFHigh->setPrefixes(" kM");
ui->IFHigh->setPrecision(6);
ui->IFLow->setUnit("Hz");
ui->IFLow->setPrefixes(" kM");
ui->IFLow->setPrecision(6);
ui->LOHighFrequency->setUnit("Hz");
ui->LOHighFrequency->setPrefixes(" kMG");
ui->LOHighFrequency->setPrecision(6);
ui->LOLowFrequency->setUnit("Hz");
ui->LOLowFrequency->setPrefixes(" kM");
ui->LOLowFrequency->setPrecision(6);
auto UpdateLOHigh = [=]() {
double sourceFreq;
if (ui->SwitchLowband->isChecked()) {
sourceFreq = ui->SourceLowFrequency->value();
} else {
sourceFreq = ui->SourceHighFrequency->value();
}
if (ui->LOHighFreqType->currentIndex() == 0) {
// fixed IF mode
ui->LOHighFrequency->setValueQuiet(sourceFreq + ui->IFHigh->value());
} else {
// Manual Frequency mode
ui->IFHigh->setValueQuiet(ui->LOHighFrequency->value() - sourceFreq);
}
};
auto UpdateLOLow = [=]() {
double sourceFreq;
if (ui->SwitchLowband->isChecked()) {
sourceFreq = ui->SourceLowFrequency->value();
} else {
sourceFreq = ui->SourceHighFrequency->value();
}
if (ui->LOLowFreqType->currentIndex() == 0) {
// fixed IF mode
ui->LOLowFrequency->setValueQuiet(sourceFreq + ui->IFLow->value());
} else {
// Manual Frequency mode
ui->IFLow->setValueQuiet(ui->LOLowFrequency->value() - sourceFreq);
}
};
connect(ui->IFHigh, &SIUnitEdit::valueChanged, [=](double) {
UpdateLOHigh();
});
connect(ui->LOHighFrequency, &SIUnitEdit::valueChanged, [=](double) {
UpdateLOHigh();
});
connect(ui->IFLow, &SIUnitEdit::valueChanged, [=](double) {
UpdateLOLow();
});
connect(ui->LOLowFrequency, &SIUnitEdit::valueChanged, [=](double) {
UpdateLOLow();
});
connect(ui->SourceSwitchGroup, qOverload<int, bool>(&QButtonGroup::idToggled), [=](int, bool) {
UpdateLOHigh();
UpdateLOLow();
});
connect(ui->SourceLowFrequency, &SIUnitEdit::valueChanged, [=](double) {
UpdateLOHigh();
UpdateLOLow();
});
connect(ui->SourceHighFrequency, &SIUnitEdit::valueChanged, [=](double) {
UpdateLOHigh();
UpdateLOLow();
});
ui->IFHigh->setValue(233750);
ui->IFLow->setValue(233750);
// LO high/low mode switch connections
connect(ui->LOHighFreqType, qOverload<int>(&QComboBox::activated), this, [=](int index) {
switch(index) {
case 0:
ui->LOHighFrequency->setEnabled(false);
ui->IFHigh->setEnabled(true);
break;
case 1:
ui->LOHighFrequency->setEnabled(true);
ui->IFHigh->setEnabled(false);
break;
}
});
connect(ui->LOLowFreqType, qOverload<int>(&QComboBox::activated), this, [=](int index) {
switch(index) {
case 0:
ui->LOLowFrequency->setEnabled(false);
ui->IFLow->setEnabled(true);
break;
case 1:
ui->LOLowFrequency->setEnabled(true);
ui->IFLow->setEnabled(false);
break;
}
});
// Readonly widgets
auto MakeReadOnly = [](QWidget* w) {
w->setAttribute(Qt::WA_TransparentForMouseEvents);
w->setFocusPolicy(Qt::NoFocus);
};
MakeReadOnly(ui->SourceLocked);
MakeReadOnly(ui->LOLocked);
MakeReadOnly(ui->port1min);
MakeReadOnly(ui->port1max);
MakeReadOnly(ui->port1mag);
MakeReadOnly(ui->port1phase);
MakeReadOnly(ui->port1referenced);
MakeReadOnly(ui->port2min);
MakeReadOnly(ui->port2max);
MakeReadOnly(ui->port2mag);
MakeReadOnly(ui->port2phase);
MakeReadOnly(ui->port2referenced);
MakeReadOnly(ui->refmin);
MakeReadOnly(ui->refmax);
MakeReadOnly(ui->refmag);
MakeReadOnly(ui->refphase);
connect(&dev, &LibreVNADriver::receivedPacket, this, [=](const Protocol::PacketInfo &p){
if(p.type == Protocol::PacketType::ManualStatus) {
NewStatus(p.manualStatus);
}
}, Qt::QueuedConnection);
connect(ui->SourceCE, &QCheckBox::toggled, this, [=](bool) { UpdateDevice(); });
connect(ui->LOHighCE, &QCheckBox::toggled, this, [=](bool) { UpdateDevice(); });
connect(ui->SourceLowEnable, &QCheckBox::toggled, this, [=](bool) { UpdateDevice(); });
connect(ui->LOLowEnable, &QCheckBox::toggled, this, [=](bool) { UpdateDevice(); });
connect(ui->Port1Enable, &QCheckBox::toggled, this, [=](bool) { UpdateDevice(); });
connect(ui->Port2Enable, &QCheckBox::toggled, this, [=](bool) { UpdateDevice(); });
connect(ui->RefEnable, &QCheckBox::toggled, this, [=](bool) { UpdateDevice(); });
connect(ui->SourceLowpass, qOverload<int>(&QComboBox::activated), this, [=](int) { UpdateDevice(); });
connect(ui->SourceLowPower, qOverload<int>(&QComboBox::activated), this, [=](int) { UpdateDevice(); });
connect(ui->LOLowPower, qOverload<int>(&QComboBox::activated), this, [=](int) { UpdateDevice(); });
connect(ui->cbWindow, qOverload<int>(&QComboBox::activated), this, [=](int) { UpdateDevice(); });
connect(ui->SourceHighFrequency, &SIUnitEdit::valueChanged, this, [=](double) { UpdateDevice(); });
connect(ui->SourceLowFrequency, &SIUnitEdit::valueChanged, this, [=](double) { UpdateDevice(); });
connect(ui->LOHighFrequency, &SIUnitEdit::valueChanged, this, [=](double) { UpdateDevice(); });
connect(ui->IFHigh, &SIUnitEdit::valueChanged, this, [=](double) { UpdateDevice(); });
connect(ui->LOLowFrequency, &SIUnitEdit::valueChanged, this, [=](double) { UpdateDevice(); });
connect(ui->IFLow, &SIUnitEdit::valueChanged, this, [=](double) { UpdateDevice(); });
connect(ui->PortSwitchGroup, qOverload<int, bool>(&QButtonGroup::idToggled), this, [=](int, bool) { UpdateDevice(); });
connect(ui->SourceSwitchGroup, qOverload<int, bool>(&QButtonGroup::idToggled), this, [=](int, bool) { UpdateDevice(); });
connect(ui->LOSwitchGroup, qOverload<int, bool>(&QButtonGroup::idToggled), this, [=](int, bool) { UpdateDevice(); });
connect(ui->Attenuator, qOverload<double>(&QDoubleSpinBox::valueChanged), this, [=](double) { UpdateDevice(); });
connect(ui->SourceHighPower, qOverload<int>(&QSpinBox::valueChanged), this, [=](int) { UpdateDevice(); });
connect(ui->Samples, qOverload<int>(&QSpinBox::valueChanged), this, [=](double) { UpdateDevice(); });
// Create the SCPI commands
auto addBooleanManualSetting = [=](QString cmd, void(ManualControlDialogVD0::*set)(bool), bool(ManualControlDialogVD0::*get)(void)) {
commands.push_back(new SCPICommand(cmd, [=](QStringList params) -> QString {
bool enable;
if(!SCPI::paramToBool(params, 0, enable)) {
return SCPI::getResultName(SCPI::Result::Error);
}
auto set_fn = std::bind(set, this, std::placeholders::_1);
set_fn(enable);
return SCPI::getResultName(SCPI::Result::Empty);
}, [=](QStringList) -> QString {
auto get_fn = std::bind(get, this);
return get_fn() ? SCPI::getResultName(SCPI::Result::True) : SCPI::getResultName(SCPI::Result::False);
}));
};
auto addDoubleManualSetting = [=](QString cmd, void(ManualControlDialogVD0::*set)(double), double(ManualControlDialogVD0::*get)(void)) {
commands.push_back(new SCPICommand(cmd, [=](QStringList params) -> QString {
double value;
if(!SCPI::paramToDouble(params, 0, value)) {
return SCPI::getResultName(SCPI::Result::Error);
}
auto set_fn = std::bind(set, this, std::placeholders::_1);
set_fn(value);
return SCPI::getResultName(SCPI::Result::Empty);
}, [=](QStringList) -> QString {
auto get_fn = std::bind(get, this);
return QString::number(get_fn());
}));
};
auto addIntegerManualSetting = [=](QString cmd, void(ManualControlDialogVD0::*set)(int), int(ManualControlDialogVD0::*get)(void)) {
commands.push_back(new SCPICommand(cmd, [=](QStringList params) -> QString {
double value;
if(!SCPI::paramToDouble(params, 0, value)) {
return SCPI::getResultName(SCPI::Result::Error);
}
auto set_fn = std::bind(set, this, std::placeholders::_1);
set_fn(value);
return SCPI::getResultName(SCPI::Result::Empty);
}, [=](QStringList) -> QString {
auto get_fn = std::bind(get, this);
return QString::number(get_fn());
}));
};
auto addIntegerManualSettingWithReturnValue = [=](QString cmd, bool(ManualControlDialogVD0::*set)(int), int(ManualControlDialogVD0::*get)(void)) {
commands.push_back(new SCPICommand(cmd, [=](QStringList params) -> QString {
double value;
if(!SCPI::paramToDouble(params, 0, value)) {
return SCPI::getResultName(SCPI::Result::Error);
}
auto set_fn = std::bind(set, this, std::placeholders::_1);
if(set_fn(value)) {
return SCPI::getResultName(SCPI::Result::Empty);
} else {
return SCPI::getResultName(SCPI::Result::Error);
}
}, [=](QStringList) -> QString {
auto get_fn = std::bind(get, this);
return QString::number(get_fn());
}));
};
auto addIntegerManualQuery = [=](QString cmd, int(ManualControlDialogVD0::*get)(void)) {
commands.push_back(new SCPICommand(cmd, nullptr, [=](QStringList) -> QString {
auto get_fn = std::bind(get, this);
return QString::number(get_fn());
}));
};
auto addDoubleManualQuery = [=](QString cmd, double(ManualControlDialogVD0::*get)(void)) {
commands.push_back(new SCPICommand(cmd, nullptr, [=](QStringList) -> QString {
auto get_fn = std::bind(get, this);
return QString::number(get_fn());
}));
};
auto addBooleanManualQuery = [=](QString cmd, bool(ManualControlDialogVD0::*get)(void)) {
commands.push_back(new SCPICommand(cmd, nullptr, [=](QStringList) -> QString {
auto get_fn = std::bind(get, this);
return get_fn() ? SCPI::getResultName(SCPI::Result::True) : SCPI::getResultName(SCPI::Result::False);
}));
};
auto addComplexManualQuery = [=](QString cmd, std::complex<double>(ManualControlDialogVD0::*get)(void)) {
commands.push_back(new SCPICommand(cmd, nullptr, [=](QStringList) -> QString {
auto get_fn = std::bind(get, this);
auto res = get_fn();
return QString::number(res.real())+","+QString::number(res.imag());
}));
};
addBooleanManualSetting("MANual:HSRC_CE", &ManualControlDialogVD0::setHighSourceChipEnable, &ManualControlDialogVD0::getHighSourceChipEnable);
addBooleanManualQuery("MANual:HSRC_LOCKed", &ManualControlDialogVD0::getHighSourceLocked);
addIntegerManualSettingWithReturnValue("MANual:HSRC_PWR", &ManualControlDialogVD0::setHighSourcePower, &ManualControlDialogVD0::getHighSourcePower);
addDoubleManualSetting("MANual:HSRC_FREQ", &ManualControlDialogVD0::setHighSourceFrequency, &ManualControlDialogVD0::getHighSourceFrequency);
commands.push_back(new SCPICommand("MANual:HSRC_LPF", [=](QStringList params) -> QString {
long value;
if(!SCPI::paramToLong(params, 0, value)) {
return SCPI::getResultName(SCPI::Result::Error);
}
switch(value) {
case 947:
setHighSourceLPF(ManualControlDialogVD0::LPF::M947);
break;
case 1880:
setHighSourceLPF(ManualControlDialogVD0::LPF::M1880);
break;
case 3500:
setHighSourceLPF(ManualControlDialogVD0::LPF::M3500);
break;
case 0:
setHighSourceLPF(ManualControlDialogVD0::LPF::None);
break;
default:
return SCPI::getResultName(SCPI::Result::Error);
}
return SCPI::getResultName(SCPI::Result::Empty);
}, [=](QStringList) -> QString {
auto lpf = getHighSourceLPF();
switch(lpf) {
case ManualControlDialogVD0::LPF::M947: return "947";
case ManualControlDialogVD0::LPF::M1880: return "1880";
case ManualControlDialogVD0::LPF::M3500: return "3500";
case ManualControlDialogVD0::LPF::None: return "0";
default: return SCPI::getResultName(SCPI::Result::Error);
}
}));
addBooleanManualSetting("MANual:LSRC_EN", &ManualControlDialogVD0::setLowSourceEnable, &ManualControlDialogVD0::getLowSourceEnable);
addIntegerManualSettingWithReturnValue("MANual:LSRC_PWR", &ManualControlDialogVD0::setLowSourcePower, &ManualControlDialogVD0::getLowSourcePower);
addDoubleManualSetting("MANual:LSRC_FREQ", &ManualControlDialogVD0::setLowSourceFrequency, &ManualControlDialogVD0::getLowSourceFrequency);
addBooleanManualSetting("MANual:BAND_SW", &ManualControlDialogVD0::setHighband, &ManualControlDialogVD0::getHighband);
addDoubleManualSetting("MANual:ATTenuator", &ManualControlDialogVD0::setAttenuator, &ManualControlDialogVD0::getAttenuator);
addIntegerManualSettingWithReturnValue("MANual:PORT_SW", &ManualControlDialogVD0::setPortSwitch, &ManualControlDialogVD0::getPortSwitch);
addBooleanManualSetting("MANual:LOHigh_CE", &ManualControlDialogVD0::setLOHighChipEnable, &ManualControlDialogVD0::getLOHighChipEnable);
addBooleanManualQuery("MANual:LOHigh_LOCKed", &ManualControlDialogVD0::getLOHighLocked);
addDoubleManualSetting("MANual:LOHigh_FREQ", &ManualControlDialogVD0::setLOHighFrequency, &ManualControlDialogVD0::getLOHighFrequency);
addDoubleManualSetting("MANual:IFHigh_FREQ", &ManualControlDialogVD0::setIFHighFrequency, &ManualControlDialogVD0::getIFHighFrequency);
addBooleanManualSetting("MANual:LOLow_EN", &ManualControlDialogVD0::setLOLowEnable, &ManualControlDialogVD0::getLOLowEnable);
addDoubleManualSetting("MANual:LOLow_FREQ", &ManualControlDialogVD0::setLOLowFrequency, &ManualControlDialogVD0::getLOLowFrequency);
addDoubleManualSetting("MANual:IFLow_FREQ", &ManualControlDialogVD0::setIFLowFrequency, &ManualControlDialogVD0::getIFLowFrequency);
addBooleanManualSetting("MANual:PORT1_EN", &ManualControlDialogVD0::setPort1Enable, &ManualControlDialogVD0::getPort1Enable);
addBooleanManualSetting("MANual:PORT2_EN", &ManualControlDialogVD0::setPort2Enable, &ManualControlDialogVD0::getPort2Enable);
addBooleanManualSetting("MANual:REF_EN", &ManualControlDialogVD0::setRefEnable, &ManualControlDialogVD0::getRefEnable);
addIntegerManualSetting("MANual:SAMPLES", &ManualControlDialogVD0::setNumSamples, &ManualControlDialogVD0::getNumSamples);
commands.push_back(new SCPICommand("MANual:WINdow", [=](QStringList params) -> QString {
if(params.size() < 1) {
return SCPI::getResultName(SCPI::Result::Error);
}
if (params[0] == "NONE") {
setWindow(ManualControlDialogVD0::Window::None);
} else if(params[0] == "KAISER") {
setWindow(ManualControlDialogVD0::Window::Kaiser);
} else if(params[0] == "HANN") {
setWindow(ManualControlDialogVD0::Window::Hann);
} else if(params[0] == "FLATTOP") {
setWindow(ManualControlDialogVD0::Window::FlatTop);
} else {
return "INVALID WINDOW";
}
return SCPI::getResultName(SCPI::Result::Empty);
}, [=](QStringList) -> QString {
switch((ManualControlDialogVD0::Window) getWindow()) {
case ManualControlDialogVD0::Window::None: return "NONE";
case ManualControlDialogVD0::Window::Kaiser: return "KAISER";
case ManualControlDialogVD0::Window::Hann: return "HANN";
case ManualControlDialogVD0::Window::FlatTop: return "FLATTOP";
default: return SCPI::getResultName(SCPI::Result::Error);
}
}));
addIntegerManualQuery("MANual:PORT1_MIN", &ManualControlDialogVD0::getPort1MinADC);
addIntegerManualQuery("MANual:PORT1_MAX", &ManualControlDialogVD0::getPort1MaxADC);
addDoubleManualQuery("MANual:PORT1_MAG", &ManualControlDialogVD0::getPort1Magnitude);
addDoubleManualQuery("MANual:PORT1_PHAse", &ManualControlDialogVD0::getPort1Phase);
addComplexManualQuery("MANual:PORT1_REFerenced", &ManualControlDialogVD0::getPort1Referenced);
addIntegerManualQuery("MANual:PORT2_MIN", &ManualControlDialogVD0::getPort2MinADC);
addIntegerManualQuery("MANual:PORT2_MAX", &ManualControlDialogVD0::getPort2MaxADC);
addDoubleManualQuery("MANual:PORT2_MAG", &ManualControlDialogVD0::getPort2Magnitude);
addDoubleManualQuery("MANual:PORT2_PHAse", &ManualControlDialogVD0::getPort2Phase);
addComplexManualQuery("MANual:PORT2_REFerenced", &ManualControlDialogVD0::getPort2Referenced);
addIntegerManualQuery("MANual:REF_MIN", &ManualControlDialogVD0::getRefMinADC);
addIntegerManualQuery("MANual:REF_MAX", &ManualControlDialogVD0::getRefMaxADC);
addDoubleManualQuery("MANual:REF_MAG", &ManualControlDialogVD0::getRefMagnitude);
addDoubleManualQuery("MANual:REF_PHAse", &ManualControlDialogVD0::getRefPhase);
for(auto c : commands) {
emit dev.addSCPICommand(c);
}
UpdateDevice();
}
ManualControlDialogVD0::~ManualControlDialogVD0()
{
for(auto c : commands) {
emit dev.removeSCPICommand(c);
}
emit dev.releaseControl();
delete ui;
}
void ManualControlDialogVD0::setHighSourceChipEnable(bool enable)
{
ui->SourceCE->setChecked(enable);
}
bool ManualControlDialogVD0::getHighSourceChipEnable()
{
return ui->SourceCE->isChecked();
}
bool ManualControlDialogVD0::getHighSourceLocked()
{
return ui->SourceLocked->isChecked();
}
bool ManualControlDialogVD0::setHighSourcePower(int dBm)
{
if(dBm < 0 || dBm > ui->SourceHighPower->maximum()) {
return false;
} else {
ui->SourceHighPower->setValue(dBm);
return true;
}
}
int ManualControlDialogVD0::getHighSourcePower()
{
return ui->SourceHighPower->value();
}
void ManualControlDialogVD0::setHighSourceFrequency(double f)
{
ui->SourceHighFrequency->setValue(f);
}
double ManualControlDialogVD0::getHighSourceFrequency()
{
return ui->SourceHighFrequency->value();
}
void ManualControlDialogVD0::setHighSourceLPF(ManualControlDialogVD0::LPF lpf)
{
switch(lpf) {
case LPF::M947:
ui->SourceLowpass->setCurrentIndex(0);
break;
case LPF::M1880:
ui->SourceLowpass->setCurrentIndex(1);
break;
case LPF::M3500:
ui->SourceLowpass->setCurrentIndex(2);
break;
case LPF::None:
ui->SourceLowpass->setCurrentIndex(3);
break;
}
}
ManualControlDialogVD0::LPF ManualControlDialogVD0::getHighSourceLPF()
{
LPF lpfs[4] = {LPF::M947, LPF::M1880, LPF::M3500, LPF::None};
return lpfs[ui->SourceLowpass->currentIndex()];
}
void ManualControlDialogVD0::setLowSourceEnable(bool enable)
{
ui->SourceLowEnable->setChecked(enable);
}
bool ManualControlDialogVD0::getLowSourceEnable()
{
return ui->SourceLowEnable->isChecked();
}
bool ManualControlDialogVD0::setLowSourcePower(int mA)
{
switch(mA) {
case 2:
ui->SourceLowPower->setCurrentIndex(0);
break;
case 4:
ui->SourceLowPower->setCurrentIndex(1);
break;
case 6:
ui->SourceLowPower->setCurrentIndex(2);
break;
case 8:
ui->SourceLowPower->setCurrentIndex(3);
break;
default:
// invalid power setting
return false;
}
return true;
}
int ManualControlDialogVD0::getLowSourcePower()
{
int powers[4] = {2,4,6,8};
return powers[ui->SourceLowPower->currentIndex()];
}
void ManualControlDialogVD0::setLowSourceFrequency(double f)
{
ui->SourceLowFrequency->setValue(f);
}
double ManualControlDialogVD0::getLowSourceFrequency()
{
return ui->SourceLowFrequency->value();
}
void ManualControlDialogVD0::setHighband(bool high)
{
if(high) {
ui->SwitchHighband->setChecked(true);
} else {
ui->SwitchLowband->setChecked(true);
}
}
bool ManualControlDialogVD0::getHighband()
{
return ui->SwitchHighband->isChecked();
}
void ManualControlDialogVD0::setAttenuator(double att)
{
ui->Attenuator->setValue(att);
}
double ManualControlDialogVD0::getAttenuator()
{
return ui->Attenuator->value();
}
bool ManualControlDialogVD0::setPortSwitch(int port)
{
switch(port) {
case 1:
ui->Port1Switch->setChecked(true);
break;
case 2:
ui->Port2Switch->setChecked(true);
break;
default:
// invalid port
return false;
}
return true;
}
int ManualControlDialogVD0::getPortSwitch()
{
if(ui->Port1Switch->isChecked()) {
return 1;
} else {
return 2;
}
}
void ManualControlDialogVD0::setLOHighChipEnable(bool enable)
{
ui->LOHighCE->setChecked(enable);
}
bool ManualControlDialogVD0::getLOHighChipEnable()
{
return ui->LOHighCE->isChecked();
}
bool ManualControlDialogVD0::getLOHighLocked()
{
return ui->LOLocked->isChecked();
}
void ManualControlDialogVD0::setLOHighFrequency(double f)
{
ui->LOHighFreqType->setCurrentIndex(1);
ui->LOHighFrequency->setValue(f);
}
double ManualControlDialogVD0::getLOHighFrequency()
{
return ui->LOHighFrequency->value();
}
void ManualControlDialogVD0::setIFHighFrequency(double f)
{
ui->LOHighFreqType->setCurrentIndex(0);
ui->IFHigh->setValue(f);
}
double ManualControlDialogVD0::getIFHighFrequency()
{
return ui->IFHigh->value();
}
void ManualControlDialogVD0::setLOLowEnable(bool enable)
{
ui->LOLowEnable->setChecked(enable);
}
bool ManualControlDialogVD0::getLOLowEnable()
{
return ui->LOLowEnable->isChecked();
}
void ManualControlDialogVD0::setLOLowFrequency(double f)
{
ui->LOLowFreqType->setCurrentIndex(1);
ui->LOLowFrequency->setValue(f);
}
double ManualControlDialogVD0::getLOLowFrequency()
{
return ui->LOLowFrequency->value();
}
void ManualControlDialogVD0::setIFLowFrequency(double f)
{
ui->LOLowFreqType->setCurrentIndex(0);
ui->IFLow->setValue(f);
}
double ManualControlDialogVD0::getIFLowFrequency()
{
return ui->IFLow->value();
}
void ManualControlDialogVD0::setPort1Enable(bool enable)
{
ui->Port1Enable->setChecked(enable);
}
bool ManualControlDialogVD0::getPort1Enable()
{
return ui->Port1Enable->isChecked();
}
void ManualControlDialogVD0::setPort2Enable(bool enable)
{
ui->Port2Enable->setChecked(enable);
}
bool ManualControlDialogVD0::getPort2Enable()
{
return ui->Port2Enable->isChecked();
}
void ManualControlDialogVD0::setRefEnable(bool enable)
{
ui->RefEnable->setChecked(enable);
}
bool ManualControlDialogVD0::getRefEnable()
{
return ui->RefEnable->isChecked();
}
void ManualControlDialogVD0::setNumSamples(int samples)
{
ui->Samples->setValue(samples);
}
int ManualControlDialogVD0::getNumSamples()
{
return ui->Samples->value();
}
void ManualControlDialogVD0::setWindow(ManualControlDialogVD0::Window w)
{
ui->cbWindow->setCurrentIndex((int) w);
}
ManualControlDialogVD0::Window ManualControlDialogVD0::getWindow()
{
return (Window) ui->cbWindow->currentIndex();
}
int ManualControlDialogVD0::getPort1MinADC()
{
return ui->port1min->text().toInt();
}
int ManualControlDialogVD0::getPort1MaxADC()
{
return ui->port1max->text().toInt();
}
double ManualControlDialogVD0::getPort1Magnitude()
{
return ui->port1mag->text().toDouble();
}
double ManualControlDialogVD0::getPort1Phase()
{
return ui->port1phase->text().toDouble();
}
std::complex<double> ManualControlDialogVD0::getPort1Referenced()
{
return port1referenced;
}
int ManualControlDialogVD0::getPort2MinADC()
{
return ui->port2min->text().toInt();
}
int ManualControlDialogVD0::getPort2MaxADC()
{
return ui->port2max->text().toInt();
}
double ManualControlDialogVD0::getPort2Magnitude()
{
return ui->port2mag->text().toDouble();
}
double ManualControlDialogVD0::getPort2Phase()
{
return ui->port2phase->text().toDouble();
}
std::complex<double> ManualControlDialogVD0::getPort2Referenced()
{
return port2referenced;
}
int ManualControlDialogVD0::getRefMinADC()
{
return ui->refmin->text().toInt();
}
int ManualControlDialogVD0::getRefMaxADC()
{
return ui->refmax->text().toInt();
}
double ManualControlDialogVD0::getRefMagnitude()
{
return ui->refmag->text().toDouble();
}
double ManualControlDialogVD0::getRefPhase()
{
return ui->refphase->text().toDouble();
}
void ManualControlDialogVD0::NewStatus(Protocol::ManualStatus status)
{
// ADC values
ui->port1min->setText(QString::number(status.VD0.port1min));
ui->port1max->setText(QString::number(status.VD0.port1max));
auto port1 = complex<double>(status.VD0.port1real, status.VD0.port1imag);
ui->port1mag->setText(QString::number(abs(port1)));
ui->port1phase->setText(QString::number(arg(port1)*180/M_PI));
ui->port2min->setText(QString::number(status.VD0.port2min));
ui->port2max->setText(QString::number(status.VD0.port2max));
auto port2 = complex<double>(status.VD0.port2real, status.VD0.port2imag);
ui->port2mag->setText(QString::number(abs(port2)));
ui->port2phase->setText(QString::number(arg(port2)*180/M_PI));
ui->refmin->setText(QString::number(status.VD0.refmin));
ui->refmax->setText(QString::number(status.VD0.refmax));
auto ref = complex<double>(status.VD0.refreal, status.VD0.refimag);
ui->refmag->setText(QString::number(abs(ref)));
ui->refphase->setText(QString::number(arg(ref)*180/M_PI));
port1referenced = port1 / ref;
port2referenced = port2 / ref;
auto port1db = Util::SparamTodB(port1referenced);
auto port2db = Util::SparamTodB(port2referenced);
ui->port1referenced->setText(QString::number(port1db, 'f', 1) + "db@" + QString::number(arg(port1referenced)*180/M_PI, 'f', 0) + "°");
ui->port2referenced->setText(QString::number(port2db, 'f', 1) + "db@" + QString::number(arg(port2referenced)*180/M_PI, 'f', 0) + "°");
// PLL state
ui->SourceLocked->setChecked(status.VD0.source_locked);
ui->LOLocked->setChecked(status.VD0.LO_locked);
}
void ManualControlDialogVD0::UpdateDevice()
{
Protocol::PacketInfo p;
p.type = Protocol::PacketType::ManualControl;
auto &m = p.manual.VD0;
// Source highband
m.SourceHighCE = ui->SourceCE->isChecked();
m.SourceHighPower = ui->SourceHighPower->value();
m.SourceHighFrequency = ui->SourceHighFrequency->value();
m.SourceHighLowpass = ui->SourceLowpass->currentIndex();
// Source lowband
m.SourceLowEN = ui->SourceLowEnable->isChecked();
m.SourceLowPower = ui->SourceLowPower->currentIndex();
m.SourceLowFrequency = ui->SourceLowFrequency->value();
// Source signal path
m.SourceHighband = ui->SwitchHighband->isChecked();
m.PortSwitch = ui->Port2Switch->isChecked();
m.attenuator = -ui->Attenuator->value() / 0.25;
// LO High
m.LOHighCE = ui->LOHighCE->isChecked();
m.LOHighFrequency = ui->LOHighFrequency->value();
// LOLow
m.LOLowEN = ui->LOLowEnable->isChecked();
m.LOLowFrequency = ui->LOLowFrequency->value();
m.LOLowPower = ui->LOLowPower->currentIndex();
// LO signal path
m.LOHighband = ui->LOSwitchHighband->isChecked();
// Acquisition
m.Port1EN = ui->Port1Enable->isChecked();
m.Port2EN = ui->Port2Enable->isChecked();
m.RefEN = ui->RefEnable->isChecked();
m.Samples = ui->Samples->value();
m.WindowType = ui->cbWindow->currentIndex();
qDebug() << "Updating manual control state";
dev.SendPacket(p);
}

View file

@ -0,0 +1,114 @@
#ifndef MANUALCONTROLDIALOGVD0_H
#define MANUALCONTROLDIALOGVD0_H
#include "librevnadriver.h"
#include <QDialog>
#include <complex>
namespace Ui {
class ManualControlDialogVD0;
}
class ManualControlDialogVD0 : public QDialog
{
Q_OBJECT
public:
explicit ManualControlDialogVD0(LibreVNADriver &dev, QWidget *parent = nullptr);
~ManualControlDialogVD0();
void setHighSourceChipEnable(bool enable);
bool getHighSourceChipEnable();
void setHighSourceRFEnable(bool enable);
bool getHighSourceRFEnable();
bool getHighSourceLocked();
bool setHighSourcePower(int dBm);
int getHighSourcePower();
void setHighSourceFrequency(double f);
double getHighSourceFrequency();
enum class LPF {
M947,
M1880,
M3500,
None,
};
void setHighSourceLPF(LPF lpf);
LPF getHighSourceLPF();
void setLowSourceEnable(bool enable);
bool getLowSourceEnable();
bool setLowSourcePower(int mA);
int getLowSourcePower();
void setLowSourceFrequency(double f);
double getLowSourceFrequency();
void setHighband(bool high);
bool getHighband();
void setAttenuator(double att);
double getAttenuator();
bool setPortSwitch(int port);
int getPortSwitch();
void setLOHighChipEnable(bool enable);
bool getLOHighChipEnable();
bool getLOHighLocked();
void setLOHighFrequency(double f);
double getLOHighFrequency();
void setIFHighFrequency(double f);
double getIFHighFrequency();
void setLOLowEnable(bool enable);
bool getLOLowEnable();
void setLOLowFrequency(double f);
double getLOLowFrequency();
void setIFLowFrequency(double f);
double getIFLowFrequency();
void setPort1Enable(bool enable);
bool getPort1Enable();
void setPort2Enable(bool enable);
bool getPort2Enable();
void setRefEnable(bool enable);
bool getRefEnable();
void setNumSamples(int samples);
int getNumSamples();
enum class Window {
None = 0,
Kaiser = 1,
Hann = 2,
FlatTop = 3
};
void setWindow(Window w);
Window getWindow();
int getPort1MinADC();
int getPort1MaxADC();
double getPort1Magnitude();
double getPort1Phase();
std::complex<double> getPort1Referenced();
int getPort2MinADC();
int getPort2MaxADC();
double getPort2Magnitude();
double getPort2Phase();
std::complex<double> getPort2Referenced();
int getRefMinADC();
int getRefMaxADC();
double getRefMagnitude();
double getRefPhase();
public slots:
void NewStatus(Protocol::ManualStatus status);
private:
void UpdateDevice();
Ui::ManualControlDialogVD0 *ui;
LibreVNADriver &dev;
std::complex<double> port1referenced;
std::complex<double> port2referenced;
std::vector<SCPICommand*> commands;
};
#endif // MANUALCONTROLDIALOGVD0_H

View file

@ -0,0 +1,812 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ManualControlDialogVD0</class>
<widget class="QDialog" name="ManualControlDialogVD0">
<property name="windowModality">
<enum>Qt::WindowModality::ApplicationModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>857</width>
<height>747</height>
</rect>
</property>
<property name="windowTitle">
<string>Manual System Control</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<layout class="QVBoxLayout" name="verticalLayout_15">
<item>
<widget class="QGroupBox" name="groupBox_10">
<property name="title">
<string>Signal Generation</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_14">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Highband Source</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_10">
<item>
<widget class="QCheckBox" name="SourceCE">
<property name="text">
<string>Chip Enable</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="SourceLocked">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Locked</string>
</property>
</widget>
</item>
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Power:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Frequency:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="SIUnitEdit" name="SourceHighFrequency"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Lowpass:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="SourceLowpass">
<item>
<property name="text">
<string>947MHz</string>
</property>
</item>
<item>
<property name="text">
<string>1880MHz</string>
</property>
</item>
<item>
<property name="text">
<string>3500MHz</string>
</property>
</item>
<item>
<property name="text">
<string>None</string>
</property>
</item>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="SourceHighPower">
<property name="maximum">
<number>63</number>
</property>
<property name="value">
<number>63</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Lowband Source</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="SourceLowEnable">
<property name="text">
<string>Enable</string>
</property>
</widget>
</item>
<item>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Power:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="SourceLowPower">
<item>
<property name="text">
<string>2mA</string>
</property>
</item>
<item>
<property name="text">
<string>4mA</string>
</property>
</item>
<item>
<property name="text">
<string>6mA</string>
</property>
</item>
<item>
<property name="text">
<string>8mA</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Frequency:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="SIUnitEdit" name="SourceLowFrequency"/>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Source Switch</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QRadioButton" name="SwitchLowband">
<property name="text">
<string>Lowband</string>
</property>
<attribute name="buttonGroup">
<string notr="true">SourceSwitchGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QRadioButton" name="SwitchHighband">
<property name="text">
<string>Highband</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">SourceSwitchGroup</string>
</attribute>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_12">
<item>
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Attenuator</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QDoubleSpinBox" name="Attenuator">
<property name="suffix">
<string>db</string>
</property>
<property name="minimum">
<double>-31.750000000000000</double>
</property>
<property name="maximum">
<double>0.000000000000000</double>
</property>
<property name="singleStep">
<double>0.250000000000000</double>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_6">
<property name="title">
<string>Port Switch</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QRadioButton" name="Port1Switch">
<property name="text">
<string>Port 1</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">PortSwitchGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QRadioButton" name="Port2Switch">
<property name="text">
<string>Port 2</string>
</property>
<attribute name="buttonGroup">
<string notr="true">PortSwitchGroup</string>
</attribute>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_11">
<property name="title">
<string>Signal Analysis</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,1">
<item>
<layout class="QVBoxLayout" name="verticalLayout_13">
<item>
<widget class="QGroupBox" name="groupBox_7">
<property name="title">
<string>Highband LO</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QCheckBox" name="LOHighCE">
<property name="text">
<string>Chip Enable</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="LOLocked">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Locked</string>
</property>
</widget>
</item>
<item>
<layout class="QFormLayout" name="formLayout_3">
<item row="1" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Frequency:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="SIUnitEdit" name="LOHighFrequency">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>IF:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="SIUnitEdit" name="IFHigh"/>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="LOHighFreqType">
<item>
<property name="text">
<string>IF</string>
</property>
</item>
<item>
<property name="text">
<string>Absolute</string>
</property>
</item>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Freq. Type:</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>Lowband LO</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_9">
<item>
<widget class="QCheckBox" name="LOLowEnable">
<property name="text">
<string>Enable</string>
</property>
</widget>
</item>
<item>
<layout class="QFormLayout" name="formLayout_4">
<item row="0" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Power:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="LOLowPower">
<item>
<property name="text">
<string>2mA</string>
</property>
</item>
<item>
<property name="text">
<string>4mA</string>
</property>
</item>
<item>
<property name="text">
<string>6mA</string>
</property>
</item>
<item>
<property name="text">
<string>8mA</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>Freq. Type:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="LOLowFreqType">
<item>
<property name="text">
<string>IF</string>
</property>
</item>
<item>
<property name="text">
<string>Absolute</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Frequency:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="SIUnitEdit" name="LOLowFrequency"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_16">
<property name="text">
<string>IF:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="SIUnitEdit" name="IFLow"/>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_20">
<item>
<widget class="QGroupBox" name="groupBox_9">
<property name="title">
<string>Aquisition</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="QCheckBox" name="Port1Enable">
<property name="text">
<string>Port 1 Enable</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="Port2Enable">
<property name="text">
<string>Port 2 Enable</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="RefEnable">
<property name="text">
<string>Reference Enable</string>
</property>
</widget>
</item>
<item>
<layout class="QFormLayout" name="formLayout_5">
<item row="0" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Samples:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="Samples">
<property name="minimum">
<number>16</number>
</property>
<property name="maximum">
<number>131072</number>
</property>
<property name="singleStep">
<number>16</number>
</property>
<property name="value">
<number>131072</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_15">
<property name="text">
<string>Window:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="cbWindow">
<item>
<property name="text">
<string>None</string>
</property>
</item>
<item>
<property name="text">
<string>Kaiser</string>
</property>
</item>
<item>
<property name="text">
<string>Hann</string>
</property>
</item>
<item>
<property name="text">
<string>Flat Top</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_8">
<property name="title">
<string>LO Switch</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_11">
<item>
<widget class="QRadioButton" name="LOSwitchLowband">
<property name="text">
<string>Lowband</string>
</property>
<attribute name="buttonGroup">
<string notr="true">LOSwitchGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QRadioButton" name="LOSwitchHighband">
<property name="text">
<string>Highband</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">LOSwitchGroup</string>
</attribute>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox_12">
<property name="title">
<string>Measurements</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_16">
<item>
<widget class="QGroupBox" name="groupBox_16">
<property name="title">
<string>Port 1</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_19">
<item>
<layout class="QFormLayout" name="formLayout_9">
<item row="0" column="0">
<widget class="QLabel" name="label_25">
<property name="text">
<string>ADC min:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="port1min"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_26">
<property name="text">
<string>ADC max:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="port1max"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_27">
<property name="text">
<string>Magnitude:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="port1mag"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_28">
<property name="text">
<string>Phase:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="port1phase"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Referenced:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="port1referenced"/>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_14">
<property name="title">
<string>Port 2</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_17">
<item>
<layout class="QFormLayout" name="formLayout_7">
<item row="0" column="0">
<widget class="QLabel" name="label_17">
<property name="text">
<string>ADC min:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="port2min"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_18">
<property name="text">
<string>ADC max:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="port2max"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_19">
<property name="text">
<string>Magnitude:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="port2mag"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_20">
<property name="text">
<string>Phase:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="port2phase"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_14">
<property name="text">
<string>Referenced:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="port2referenced"/>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_15">
<property name="title">
<string>Reference</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_18">
<item>
<layout class="QFormLayout" name="formLayout_8">
<item row="0" column="0">
<widget class="QLabel" name="label_21">
<property name="text">
<string>ADC min:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="refmin"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_22">
<property name="text">
<string>ADC max:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="refmax"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_23">
<property name="text">
<string>Magnitude:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="refmag"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_24">
<property name="text">
<string>Phase:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="refphase"/>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>SIUnitEdit</class>
<extends>QLineEdit</extends>
<header>CustomWidgets/siunitedit.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
<buttongroups>
<buttongroup name="PortSwitchGroup"/>
<buttongroup name="SourceSwitchGroup"/>
<buttongroup name="LOSwitchGroup"/>
</buttongroups>
</ui>

View file

@ -35,6 +35,7 @@ HEADERS += \
Device/LibreVNA/librevnatcpdriver.h \ Device/LibreVNA/librevnatcpdriver.h \
Device/LibreVNA/librevnausbdriver.h \ Device/LibreVNA/librevnausbdriver.h \
Device/LibreVNA/manualcontroldialogV1.h \ Device/LibreVNA/manualcontroldialogV1.h \
Device/LibreVNA/manualcontroldialogVD0.h \
Device/LibreVNA/manualcontroldialogVE0.h \ Device/LibreVNA/manualcontroldialogVE0.h \
Device/LibreVNA/manualcontroldialogvfe.h \ Device/LibreVNA/manualcontroldialogvfe.h \
Device/LibreVNA/manualcontroldialogvff.h \ Device/LibreVNA/manualcontroldialogvff.h \
@ -203,6 +204,7 @@ SOURCES += \
Device/LibreVNA/librevnatcpdriver.cpp \ Device/LibreVNA/librevnatcpdriver.cpp \
Device/LibreVNA/librevnausbdriver.cpp \ Device/LibreVNA/librevnausbdriver.cpp \
Device/LibreVNA/manualcontroldialogV1.cpp \ Device/LibreVNA/manualcontroldialogV1.cpp \
Device/LibreVNA/manualcontroldialogVD0.cpp \
Device/LibreVNA/manualcontroldialogVE0.cpp \ Device/LibreVNA/manualcontroldialogVE0.cpp \
Device/LibreVNA/manualcontroldialogvfe.cpp \ Device/LibreVNA/manualcontroldialogvfe.cpp \
Device/LibreVNA/manualcontroldialogvff.cpp \ Device/LibreVNA/manualcontroldialogvff.cpp \
@ -366,6 +368,7 @@ FORMS += \
Device/LibreVNA/frequencycaldialog.ui \ Device/LibreVNA/frequencycaldialog.ui \
Device/LibreVNA/librevnadriversettingswidget.ui \ Device/LibreVNA/librevnadriversettingswidget.ui \
Device/LibreVNA/manualcontroldialogV1.ui \ Device/LibreVNA/manualcontroldialogV1.ui \
Device/LibreVNA/manualcontroldialogVD0.ui \
Device/LibreVNA/manualcontroldialogVE0.ui \ Device/LibreVNA/manualcontroldialogVE0.ui \
Device/LibreVNA/manualcontroldialogvfe.ui \ Device/LibreVNA/manualcontroldialogvfe.ui \
Device/LibreVNA/manualcontroldialogvff.ui \ Device/LibreVNA/manualcontroldialogvff.ui \

View file

@ -36,6 +36,7 @@ SOURCES += \
../LibreVNA-GUI/Device/LibreVNA/librevnatcpdriver.cpp \ ../LibreVNA-GUI/Device/LibreVNA/librevnatcpdriver.cpp \
../LibreVNA-GUI/Device/LibreVNA/librevnausbdriver.cpp \ ../LibreVNA-GUI/Device/LibreVNA/librevnausbdriver.cpp \
../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogV1.cpp \ ../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogV1.cpp \
../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogVD0.cpp \
../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogVE0.cpp \ ../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogVE0.cpp \
../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogvfe.cpp \ ../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogvfe.cpp \
../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogvff.cpp \ ../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogvff.cpp \
@ -226,6 +227,7 @@ HEADERS += \
../LibreVNA-GUI/Device/LibreVNA/librevnatcpdriver.h \ ../LibreVNA-GUI/Device/LibreVNA/librevnatcpdriver.h \
../LibreVNA-GUI/Device/LibreVNA/librevnausbdriver.h \ ../LibreVNA-GUI/Device/LibreVNA/librevnausbdriver.h \
../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogV1.h \ ../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogV1.h \
../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogVD0.h \
../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogVE0.h \ ../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogVE0.h \
../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogvfe.h \ ../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogvfe.h \
../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogvff.h \ ../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogvff.h \
@ -401,6 +403,7 @@ FORMS += \
../LibreVNA-GUI/Device/LibreVNA/librevnadriversettingswidget.ui \ ../LibreVNA-GUI/Device/LibreVNA/librevnadriversettingswidget.ui \
../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogV1.ui \ ../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogV1.ui \
../LibreVNA-GUI/Device/LibreVNA/Compound/compounddeviceeditdialog.ui \ ../LibreVNA-GUI/Device/LibreVNA/Compound/compounddeviceeditdialog.ui \
../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogVD0.ui \
../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogVE0.ui \ ../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogVE0.ui \
../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogvfe.ui \ ../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogvfe.ui \
../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogvff.ui \ ../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogvff.ui \

View file

@ -293,6 +293,16 @@ using ManualStatus = struct _manualstatus {
float port2real, port2imag; float port2real, port2imag;
float refreal, refimag; float refreal, refimag;
} VE0; } VE0;
struct {
int32_t port1min, port1max;
int32_t port2min, port2max;
int32_t refmin, refmax;
float port1real, port1imag;
float port2real, port2imag;
float refreal, refimag;
uint8_t source_locked :1;
uint8_t LO_locked :1;
} VD0;
}; };
}; };
@ -411,6 +421,37 @@ using ManualControl = struct _manualControl {
uint32_t Samples; uint32_t Samples;
uint8_t WindowType :2; uint8_t WindowType :2;
} VE0; } VE0;
struct {
// Highband Source
uint8_t SourceHighCE :1;
uint8_t SourceHighPower :6;
uint8_t SourceHighLowpass :2;
uint64_t SourceHighFrequency;
// Lowband Source
uint8_t SourceLowEN :1;
uint8_t SourceLowPower :2;
uint32_t SourceLowFrequency;
// Source signal path
uint8_t attenuator :7;
uint8_t SourceHighband :1;
uint8_t PortSwitch :1;
// Highband LO
uint8_t LOHighCE :1;
uint8_t LOHighPower :6;
uint64_t LOHighFrequency;
// Lowband LO
uint8_t LOLowEN :1;
uint8_t LOLowPower :2;
uint32_t LOLowFrequency;
// LO signal path
uint8_t LOHighband :1;
// Acquisition
uint8_t Port1EN :1;
uint8_t Port2EN :1;
uint8_t RefEN :1;
uint32_t Samples;
uint8_t WindowType :2;
} VD0;
}; };
}; };

View file

@ -291,6 +291,10 @@ bool FPGA::InitiateSampleRead(ReadCallback cb) {
callback = cb; callback = cb;
static uint8_t cmd[40] = {0xC0, 0x00}; static uint8_t cmd[40] = {0xC0, 0x00};
// Start data read // Start data read
if(HAL_SPI_GetState(&FPGA_SPI) != HAL_SPI_STATE_READY) {
LOG_WARN("SPI abort: %d", HAL_SPI_GetState(&FPGA_SPI));
HAL_SPI_Abort(&FPGA_SPI);
}
Low(CS); Low(CS);
busy_reading = true; busy_reading = true;
if(HAL_SPI_TransmitReceive_DMA(&FPGA_SPI, cmd, raw, 40) != HAL_OK) { if(HAL_SPI_TransmitReceive_DMA(&FPGA_SPI, cmd, raw, 40) != HAL_OK) {