diff --git a/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/librevnadriver.cpp b/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/librevnadriver.cpp index a51ba48..af52d58 100644 --- a/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/librevnadriver.cpp +++ b/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/librevnadriver.cpp @@ -3,6 +3,7 @@ #include "manualcontroldialogV1.h" #include "manualcontroldialogvff.h" #include "manualcontroldialogvfe.h" +#include "manualcontroldialogVE0.h" #include "deviceconfigurationdialogv1.h" #include "deviceconfigurationdialogvff.h" #include "deviceconfigurationdialogvfe.h" @@ -127,6 +128,9 @@ LibreVNADriver::LibreVNADriver() case 1: manualControlDialog = new ManualControlDialogV1(*this); break; + case 0xE0: + manualControlDialog = new ManualControlDialogVE0(*this); + break; case 0xFE: manualControlDialog = new ManualControlDialogVFE(*this); break; @@ -769,6 +773,7 @@ QString LibreVNADriver::hardwareVersionToString(uint8_t version) { switch(version) { case 0x01: return "1"; + case 0xE0: return "SAP1"; case 0xFE: return "P2"; case 0xFF: return "PT"; default: return "Unknown"; diff --git a/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/manualcontroldialogVE0.cpp b/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/manualcontroldialogVE0.cpp new file mode 100644 index 0000000..f50843f --- /dev/null +++ b/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/manualcontroldialogVE0.cpp @@ -0,0 +1,179 @@ +#include "manualcontroldialogVE0.h" + +#include "ui_manualcontroldialogVE0.h" +#include "Util/util.h" + +#include +#include +#include +#include + + +using namespace std; + +ManualControlDialogVE0::ManualControlDialogVE0(LibreVNADriver &dev, QWidget *parent) : + QDialog(parent), + ui(new Ui::ManualControlDialogVE0), + dev(dev) +{ + ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + + emit dev.acquireControl(); + + ui->src1Freq->setUnit("Hz"); + ui->src1Freq->setPrefixes(" kMG"); + ui->src1Freq->setPrecision(6); + ui->src1Freq->setValueQuiet(100000000); + + ui->src2Freq->setUnit("Hz"); + ui->src2Freq->setPrefixes(" kMG"); + ui->src2Freq->setPrecision(6); + ui->src2Freq->setValueQuiet(100000000); + + ui->LO1Freq->setUnit("Hz"); + ui->LO1Freq->setPrefixes(" kMG"); + ui->LO1Freq->setPrecision(6); + ui->LO1Freq->setValueQuiet(100000000); + + ui->LO2Freq->setUnit("Hz"); + ui->LO2Freq->setPrefixes(" kMG"); + ui->LO2Freq->setPrecision(6); + ui->LO2Freq->setValueQuiet(100000000); + + // Readonly widgets + auto MakeReadOnly = [](QWidget* w) { + w->setAttribute(Qt::WA_TransparentForMouseEvents); + w->setFocusPolicy(Qt::NoFocus); + }; + 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->src1CE, &QCheckBox::toggled, [=](bool) { UpdateDevice(); }); + connect(ui->src2CE, &QCheckBox::toggled, [=](bool) { UpdateDevice(); }); + connect(ui->LO1CE, &QCheckBox::toggled, [=](bool) { UpdateDevice(); }); + connect(ui->LO2CE, &QCheckBox::toggled, [=](bool) { UpdateDevice(); }); + connect(ui->srcAmp, &QCheckBox::toggled, [=](bool) { UpdateDevice(); }); + connect(ui->LO1CE, &QCheckBox::toggled, [=](bool) { UpdateDevice(); }); + + connect(ui->srcSel, qOverload(&QComboBox::activated), [=](int) { UpdateDevice(); }); + connect(ui->portSel, qOverload(&QComboBox::activated), [=](int) { UpdateDevice(); }); + connect(ui->LOSel, qOverload(&QComboBox::activated), [=](int) { UpdateDevice(); }); + connect(ui->P1Path, qOverload(&QComboBox::activated), [=](int) { UpdateDevice(); }); + connect(ui->P1Amp, qOverload(&QComboBox::activated), [=](int) { UpdateDevice(); }); + connect(ui->P2Path, qOverload(&QComboBox::activated), [=](int) { UpdateDevice(); }); + connect(ui->P2Amp, qOverload(&QComboBox::activated), [=](int) { UpdateDevice(); }); + connect(ui->RefAmp, qOverload(&QComboBox::activated), [=](int) { UpdateDevice(); }); + connect(ui->Window, qOverload(&QComboBox::activated), [=](int) { UpdateDevice(); }); + + connect(ui->src1Freq, &SIUnitEdit::valueChanged, [=](double) { UpdateDevice(); }); + connect(ui->src2Freq, &SIUnitEdit::valueChanged, [=](double) { UpdateDevice(); }); + connect(ui->LO1Freq, &SIUnitEdit::valueChanged, [=](double) { UpdateDevice(); }); + connect(ui->LO2Freq, &SIUnitEdit::valueChanged, [=](double) { UpdateDevice(); }); + + connect(ui->src1Pwr, qOverload(&QSpinBox::valueChanged), [=](double) { UpdateDevice(); }); + connect(ui->src2Pwr, qOverload(&QSpinBox::valueChanged), [=](double) { UpdateDevice(); }); + connect(ui->LO1Pwr, qOverload(&QSpinBox::valueChanged), [=](double) { UpdateDevice(); }); + connect(ui->LO2Pwr, qOverload(&QSpinBox::valueChanged), [=](double) { UpdateDevice(); }); + connect(ui->Samples, qOverload(&QSpinBox::valueChanged), [=](double) { UpdateDevice(); }); + + UpdateDevice(); +} + +ManualControlDialogVE0::~ManualControlDialogVE0() +{ + emit dev.releaseControl(); + delete ui; +} + +void ManualControlDialogVE0::NewStatus(Protocol::ManualStatus status) +{ + // ADC values + auto &s = status.VE0; + ui->port1min->setText(QString::number(s.port1min)); + ui->port1max->setText(QString::number(s.port1max)); + auto port1 = complex(s.port1real, s.port1imag); + ui->port1mag->setText(QString::number(abs(port1))); + ui->port1phase->setText(QString::number(arg(port1)*180/M_PI)); + + ui->port2min->setText(QString::number(s.port2min)); + ui->port2max->setText(QString::number(s.port2max)); + auto port2 = complex(s.port2real, s.port2imag); + ui->port2mag->setText(QString::number(abs(port2))); + ui->port2phase->setText(QString::number(arg(port2)*180/M_PI)); + + ui->refmin->setText(QString::number(s.refmin)); + ui->refmax->setText(QString::number(s.refmax)); + auto ref = complex(s.refreal, s.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) + "°"); +} + +void ManualControlDialogVE0::UpdateDevice() +{ + Protocol::PacketInfo p; + p.type = Protocol::PacketType::ManualControl; + auto &m = p.manual.VE0; + // Source + m.src1Freq = ui->src1Freq->value(); + m.src2Freq = ui->src2Freq->value(); + m.src1Pwr = ui->src1Pwr->value(); + m.src2Pwr = ui->src2Pwr->value(); + m.src1CE = ui->src1CE->isChecked(); + m.src2CE = ui->src2CE->isChecked(); + m.srcSel = ui->srcSel->currentIndex(); + m.portSel = ui->portSel->currentIndex(); + m.srcAmp = ui->srcAmp->isChecked(); + // LO + m.LO1Freq = ui->LO1Freq->value(); + m.LO2Freq = ui->LO2Freq->value(); + m.LO1Pwr = ui->LO1Pwr->value(); + m.LO2Pwr = ui->LO2Pwr->value(); + m.LO1CE = ui->LO1CE->isChecked(); + m.LO2CE = ui->LO2CE->isChecked(); + m.LOSel = ui->LOSel->currentIndex(); + // Port 1 + m.P1PathSel = ui->P1Path->currentIndex(); + m.P1AmpOn = ui->P1Amp->currentIndex() == 1 ? 1 : 0; + m.P1AmpBypass = ui->P1Amp->currentIndex() == 2 ? 1 : 0; + // Port 2 + m.P2PathSel = ui->P2Path->currentIndex(); + m.P2AmpOn = ui->P2Amp->currentIndex() == 1 ? 1 : 0; + m.P2AmpBypass = ui->P2Amp->currentIndex() == 2 ? 1 : 0; + // Reference + m.RefAmpOn = ui->RefAmp->currentIndex() == 1 ? 1 : 0; + m.RefAmpBypass = ui->RefAmp->currentIndex() == 2 ? 1 : 0; + // Acquisition + m.Samples = ui->Samples->value(); + m.WindowType = ui->Window->currentIndex(); + + qDebug() << "Updating manual control state"; + + dev.SendPacket(p); +} diff --git a/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/manualcontroldialogVE0.h b/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/manualcontroldialogVE0.h new file mode 100644 index 0000000..075661e --- /dev/null +++ b/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/manualcontroldialogVE0.h @@ -0,0 +1,34 @@ +#ifndef MANUALCONTROLDIALOGVE0_H +#define MANUALCONTROLDIALOGVE0_H + +#include "librevnadriver.h" + +#include +#include + +namespace Ui { +class ManualControlDialogVE0; +} + +class ManualControlDialogVE0 : public QDialog +{ + Q_OBJECT + +public: + explicit ManualControlDialogVE0(LibreVNADriver &dev, QWidget *parent = nullptr); + ~ManualControlDialogVE0(); + +public slots: + void NewStatus(Protocol::ManualStatus status); + +private: + void UpdateDevice(); + Ui::ManualControlDialogVE0 *ui; + LibreVNADriver &dev; + std::complex port1referenced; + std::complex port2referenced; + + std::vector commands; +}; + +#endif // MANUALCONTROLDIALOGVE0_H diff --git a/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/manualcontroldialogVE0.ui b/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/manualcontroldialogVE0.ui new file mode 100644 index 0000000..72db624 --- /dev/null +++ b/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/manualcontroldialogVE0.ui @@ -0,0 +1,797 @@ + + + ManualControlDialogVE0 + + + Qt::WindowModality::ApplicationModal + + + + 0 + 0 + 777 + 717 + + + + Manual System Control + + + + + + + + + + Signal Generation + + + + + + Source + + + + + + PLL1 + + + + + + Chip Enable + + + + + + + + + Power: + + + + + + + Frequency: + + + + + + + + + + 18 + + + 18 + + + + + + + + + + + + PLL2 + + + + + + Chip Enable + + + + + + + + + Power: + + + + + + + Frequency: + + + + + + + + + + 18 + + + 18 + + + + + + + + + + + + + + PLL selection: + + + + + + + 1 + + + + None + + + + + PLL1 + + + + + PLL2 + + + + + + + + Amplifier: + + + + + + + Enable + + + + + + + Port selection: + + + + + + + + None + + + + + Port 1 + + + + + Port 2 + + + + + + + + + + Qt::Orientation::Vertical + + + + 20 + 40 + + + + + + + + + + + LO + + + + + + PLL1 + + + + + + Chip Enable + + + + + + + + + Power: + + + + + + + Frequency: + + + + + + + + + + 63 + + + 18 + + + + + + + + + + + + PLL2 + + + + + + Chip Enable + + + + + + + + + Power: + + + + + + + Frequency: + + + + + + + + + + 18 + + + 18 + + + + + + + + + + + + + + PLL selection: + + + + + + + + PLL1 + + + + + PLL2 + + + + + + + + + + Qt::Orientation::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + Signal Analysis + + + + + + + + Port 1 + + + + + + Path: + + + + + + + + Reflection + + + + + Transmission + + + + + + + + Amplifier: + + + + + + + + Off + + + + + On + + + + + Bypass + + + + + + + + + + + Port 2 + + + + + + Path: + + + + + + + + Reflection + + + + + Transmission + + + + + + + + Amplifier: + + + + + + + + Off + + + + + On + + + + + Bypass + + + + + + + + + + + + + + + Reference + + + + + + Amplifier: + + + + + + + + Off + + + + + On + + + + + Bypass + + + + + + + + + + + Acquisition + + + + + + Samples: + + + + + + + 8 + + + 131072 + + + 8 + + + 131072 + + + + + + + Window: + + + + + + + + None + + + + + Kaiser + + + + + Hann + + + + + Flat Top + + + + + + + + + + + + + + + + + + Measurements + + + + + + Port 1 + + + + + + + + ADC min: + + + + + + + + + + ADC max: + + + + + + + + + + Magnitude: + + + + + + + + + + Phase: + + + + + + + + + + Referenced: + + + + + + + + + + + + + + + Port 2 + + + + + + + + ADC min: + + + + + + + + + + ADC max: + + + + + + + + + + Magnitude: + + + + + + + + + + Phase: + + + + + + + + + + Referenced: + + + + + + + + + + + + + + + Reference + + + + + + + + ADC min: + + + + + + + + + + ADC max: + + + + + + + + + + Magnitude: + + + + + + + + + + Phase: + + + + + + + + + + + + + + + + + + + + + SIUnitEdit + QLineEdit +
CustomWidgets/siunitedit.h
+
+
+ + + + + + +
diff --git a/Software/PC_Application/LibreVNA-GUI/LibreVNA-GUI.pro b/Software/PC_Application/LibreVNA-GUI/LibreVNA-GUI.pro index 913de1a..0337498 100644 --- a/Software/PC_Application/LibreVNA-GUI/LibreVNA-GUI.pro +++ b/Software/PC_Application/LibreVNA-GUI/LibreVNA-GUI.pro @@ -35,6 +35,7 @@ HEADERS += \ Device/LibreVNA/librevnatcpdriver.h \ Device/LibreVNA/librevnausbdriver.h \ Device/LibreVNA/manualcontroldialogV1.h \ + Device/LibreVNA/manualcontroldialogVE0.h \ Device/LibreVNA/manualcontroldialogvfe.h \ Device/LibreVNA/manualcontroldialogvff.h \ Device/LibreVNA/receivercaldialog.h \ @@ -201,6 +202,7 @@ SOURCES += \ Device/LibreVNA/librevnatcpdriver.cpp \ Device/LibreVNA/librevnausbdriver.cpp \ Device/LibreVNA/manualcontroldialogV1.cpp \ + Device/LibreVNA/manualcontroldialogVE0.cpp \ Device/LibreVNA/manualcontroldialogvfe.cpp \ Device/LibreVNA/manualcontroldialogvff.cpp \ Device/LibreVNA/receivercaldialog.cpp \ @@ -362,6 +364,7 @@ FORMS += \ Device/LibreVNA/frequencycaldialog.ui \ Device/LibreVNA/librevnadriversettingswidget.ui \ Device/LibreVNA/manualcontroldialogV1.ui \ + Device/LibreVNA/manualcontroldialogVE0.ui \ Device/LibreVNA/manualcontroldialogvfe.ui \ Device/LibreVNA/manualcontroldialogvff.ui \ Device/devicelog.ui \ diff --git a/Software/PC_Application/LibreVNA-Test/LibreVNA-Test.pro b/Software/PC_Application/LibreVNA-Test/LibreVNA-Test.pro index 63820e5..56cd18a 100644 --- a/Software/PC_Application/LibreVNA-Test/LibreVNA-Test.pro +++ b/Software/PC_Application/LibreVNA-Test/LibreVNA-Test.pro @@ -36,6 +36,7 @@ SOURCES += \ ../LibreVNA-GUI/Device/LibreVNA/librevnatcpdriver.cpp \ ../LibreVNA-GUI/Device/LibreVNA/librevnausbdriver.cpp \ ../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogV1.cpp \ + ../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogVE0.cpp \ ../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogvfe.cpp \ ../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogvff.cpp \ ../LibreVNA-GUI/Device/LibreVNA/receivercaldialog.cpp \ @@ -224,6 +225,7 @@ HEADERS += \ ../LibreVNA-GUI/Device/LibreVNA/librevnatcpdriver.h \ ../LibreVNA-GUI/Device/LibreVNA/librevnausbdriver.h \ ../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogV1.h \ + ../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogVE0.h \ ../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogvfe.h \ ../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogvff.h \ ../LibreVNA-GUI/Device/LibreVNA/receivercaldialog.h \ @@ -397,6 +399,7 @@ FORMS += \ ../LibreVNA-GUI/Device/LibreVNA/librevnadriversettingswidget.ui \ ../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogV1.ui \ ../LibreVNA-GUI/Device/LibreVNA/Compound/compounddeviceeditdialog.ui \ + ../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogVE0.ui \ ../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogvfe.ui \ ../LibreVNA-GUI/Device/LibreVNA/manualcontroldialogvff.ui \ ../LibreVNA-GUI/Device/devicelog.ui \ diff --git a/Software/VNA_embedded/Application/Communication/Protocol.hpp b/Software/VNA_embedded/Application/Communication/Protocol.hpp index 8f92a77..c521c68 100644 --- a/Software/VNA_embedded/Application/Communication/Protocol.hpp +++ b/Software/VNA_embedded/Application/Communication/Protocol.hpp @@ -285,6 +285,14 @@ using ManualStatus = struct _manualstatus { uint16_t temp_eCal; // in 1/100 °C uint16_t power_heater; // in mW } VFE; + struct { + int16_t port1min, port1max; + int16_t port2min, port2max; + int16_t refmin, refmax; + float port1real, port1imag; + float port2real, port2imag; + float refreal, refimag; + } VE0; }; }; @@ -367,6 +375,42 @@ using ManualControl = struct _manualControl { uint8_t eCal_state :2; uint16_t eCal_target; // in 1/100 °C } VFE; + struct { + // Source + uint32_t src1Freq; + uint32_t src2Freq; + uint8_t src1Pwr; + uint8_t src2Pwr; + uint8_t src1CE :1; + uint8_t src2CE :1; + uint8_t srcSel :2; // 0: switch off, 1: PLL1 selected, 2: PLL2 selected + uint8_t portSel :2; // 0: both off, 1: port 1 selected, 2: port 2 selected + uint8_t srcAmp :1; + uint8_t unused1 :1; + // LO + uint32_t LO1Freq; + uint32_t LO2Freq; + uint8_t LO1Pwr; + uint8_t LO2Pwr; + uint8_t LO1CE :1; + uint8_t LO2CE :1; + uint8_t LOSel :1; // 0: PLL1 selected, 1: PLL2 selected + uint8_t unused2 :5; + // Port 1 + uint8_t P1PathSel :1; // 0: reflection path selected, 1: transmission path selected + uint8_t P1AmpOn :1; + uint8_t P1AmpBypass :1; + // Port 2 + uint8_t P2PathSel :1; // 0: reflection path selected, 1: transmission path selected + uint8_t P2AmpOn :1; + uint8_t P2AmpBypass :1; + // Reference + uint8_t RefAmpOn :1; + uint8_t RefAmpBypass :1; + // Acquisition + uint32_t Samples; + uint8_t WindowType :2; + } VE0; }; };