Enforce amplitude cal point limit, SCPI command for reading trace data

This commit is contained in:
Jan Käberich 2021-04-12 19:48:19 +02:00
parent 611b1ef59d
commit 62939ff882
21 changed files with 342 additions and 116 deletions

View File

@ -9,6 +9,7 @@
#include <QFileDialog>
#include "json.hpp"
#include <fstream>
#include <CustomWidgets/informationbox.h>
using namespace std;
using namespace nlohmann;
@ -90,7 +91,10 @@ AmplitudeCalDialog::AmplitudeCalDialog(Device *dev, QWidget *parent) :
p.port1set = false;
p.port2set = false;
UpdateAmplitude(p);
AddPoint(p);
if(!AddPoint(p)) {
InformationBox::ShowMessage("Limit reached", "Unable to add all points from file, would not fit into the device");
break;
}
}
});
@ -176,6 +180,7 @@ void AmplitudeCalDialog::setAmplitude(double amplitude, unsigned int point, bool
void AmplitudeCalDialog::ReceivedPoint(Protocol::AmplitudeCorrectionPoint p)
{
// qDebug() << "Received amplitude calibration point" << p.pointNum << "/" << p.totalPoints;
CorrectionPoint c;
c.frequency = p.freq * 10.0;
c.correctionPort1 = p.port1;
@ -199,7 +204,7 @@ void AmplitudeCalDialog::LoadFromDevice()
ui->load->setEnabled(false);
dev->SetIdle();
RemoveAllPoints();
qDebug() << "Asking for amplitude calibration";
// qDebug() << "Asking for amplitude calibration";
connect(dev, &Device::AmplitudeCorrectionPointReceived, this, &AmplitudeCalDialog::ReceivedPoint);
dev->SendCommandWithoutPayload(requestCommand());
edited = false;
@ -219,6 +224,7 @@ void AmplitudeCalDialog::SaveToDevice()
info.amplitudePoint.totalPoints = points.size();
info.amplitudePoint.pointNum = i;
dev->SendPacket(info);
// qDebug() << "Sent amplitude calibration point" << i << "/" << points.size();
}
edited = false;
UpdateSaveButton();
@ -242,8 +248,12 @@ void AmplitudeCalDialog::RemoveAllPoints()
UpdateSaveButton();
}
void AmplitudeCalDialog::AddPoint(AmplitudeCalDialog::CorrectionPoint &p)
bool AmplitudeCalDialog::AddPoint(AmplitudeCalDialog::CorrectionPoint &p)
{
if (points.size() >= Device::Info().limits_maxAmplitudePoints) {
// already at limit
return false;
}
// find position at which this frequency gets inserted
auto index = upper_bound(points.begin(), points.end(), p.frequency, [](double value, const CorrectionPoint& p){
return value < p.frequency;
@ -253,9 +263,10 @@ void AmplitudeCalDialog::AddPoint(AmplitudeCalDialog::CorrectionPoint &p)
points.insert(index, p);
model.endInsertRows();
UpdateSaveButton();
return true;
}
void AmplitudeCalDialog::AddPoint(double frequency)
bool AmplitudeCalDialog::AddPoint(double frequency)
{
CorrectionPoint newPoint;
newPoint.frequency = frequency;
@ -263,8 +274,11 @@ void AmplitudeCalDialog::AddPoint(double frequency)
newPoint.correctionPort2 = 0;
newPoint.port1set = false;
newPoint.port2set = false;
AddPoint(newPoint);
auto success = AddPoint(newPoint);
if (success) {
edited = true;
}
return success;
}
void AmplitudeCalDialog::AddPointDialog()
@ -296,14 +310,19 @@ void AmplitudeCalDialog::AddPointDialog()
RemoveAllPoints();
}
if(ui->singlePoint->isChecked()) {
AddPoint(ui->frequency->value());
if(!AddPoint(ui->frequency->value())) {
InformationBox::ShowMessage("Limit reached", "Can't add any more points, would not fit into the device");
}
} else {
double freq_start = ui->startFreq->value();
double freq_stop = ui->stopFreq->value();
unsigned int points = ui->numPoints->value();
double freq_step = (freq_stop - freq_start) / (points - 1);
for(unsigned int i=0;i<points;i++) {
AddPoint(freq_start + i * freq_step);
if(!AddPoint(freq_start + i * freq_step)) {
InformationBox::ShowMessage("Limit reached", "Can't add any more points, would not fit into the device");
break;
}
}
}
});

View File

@ -72,8 +72,8 @@ protected slots:
void SaveToDevice();
void RemovePoint(unsigned int i);
void RemoveAllPoints();
void AddPoint(CorrectionPoint& p);
void AddPoint(double frequency);
bool AddPoint(CorrectionPoint& p);
bool AddPoint(double frequency);
void AddPointDialog();
void AutomaticMeasurementDialog();
void ReceivedMeasurement(Protocol::SpectrumAnalyzerResult res);

View File

@ -169,7 +169,7 @@ Calkit Calkit::fromFile(QString filename)
" calibration kit format. Future versions of this application might not support"
" it anymore. Please save the calibration kit to update to the new format");
msg->setStandardButtons(QMessageBox::Ok);
msg->exec();
msg->show();
}
file.close();

View File

@ -16,7 +16,7 @@ void InformationBox::ShowMessage(QString title, QString message, QString message
QSettings s;
if(!s.contains(hashToSettingsKey(hash))) {
auto box = new InformationBox(title, message, hash, nullptr);
box->exec();
box->show();
}
}

View File

@ -170,7 +170,7 @@ Device::Device(QString serial)
if(!m_handle) {
QString message = "No device found";
auto msg = new QMessageBox(QMessageBox::Icon::Warning, "Error opening device", message);
msg->exec();
msg->show();
libusb_exit(m_context);
throw std::runtime_error(message.toStdString());
return;
@ -187,7 +187,7 @@ Device::Device(QString serial)
message.append("\" Maybe you are already connected to this device?");
qWarning() << message;
auto msg = new QMessageBox(QMessageBox::Icon::Warning, "Error opening device", message);
msg->exec();
msg->show();
libusb_exit(m_context);
throw std::runtime_error(message.toStdString());
}
@ -360,7 +360,7 @@ void Device::SearchDevices(std::function<bool (libusb_device_handle *, QString)>
"If that is not the case, you can try installing the WinUSB driver using Zadig (https://zadig.akeo.ie/)");
qWarning() << message;
auto msg = new QMessageBox(QMessageBox::Icon::Warning, "Error opening device", message);
msg->exec();
msg->show();
}
continue;
}
@ -520,6 +520,12 @@ void Device::transmissionFinished(TransmissionResult result)
qWarning() << "transmissionFinished with empty transmission queue, stray Ack?";
return;
}
if(result == TransmissionResult::Timeout) {
qWarning() << "transmissionFinished with timeout";
}
if(result == TransmissionResult::Nack) {
qWarning() << "transmissionFinished with NACK";
}
auto t = transmissionQueue.dequeue();
if(t.callback) {
t.callback(result);

View File

@ -57,7 +57,7 @@ public:
// connect to a VNA device. If serial is specified only connecting to this device, otherwise to the first one found
Device(QString serial = QString());
~Device();
bool SendPacket(const Protocol::PacketInfo& packet, std::function<void(TransmissionResult)> cb = nullptr, unsigned int timeout = 200);
bool SendPacket(const Protocol::PacketInfo& packet, std::function<void(TransmissionResult)> cb = nullptr, unsigned int timeout = 500);
bool Configure(Protocol::SweepSettings settings, std::function<void(TransmissionResult)> cb = nullptr);
bool Configure(Protocol::SpectrumAnalyzerSettings settings);
bool SetManual(Protocol::ManualControl manual);

View File

@ -66,7 +66,7 @@ void Generator::setupSCPI()
central->setFrequency(newval);
return "";
}
}, [=]() -> QString {
}, [=](QStringList) -> QString {
return QString::number(central->getDeviceStatus().frequency);
}));
add(new SCPICommand("LVL", [=](QStringList params) -> QString {
@ -81,7 +81,7 @@ void Generator::setupSCPI()
central->setLevel(newval);
return "";
}
}, [=]() -> QString {
}, [=](QStringList) -> QString {
return QString::number(central->getDeviceStatus().cdbm_level / 100.0);
}));
add(new SCPICommand("PORT", [=](QStringList params) -> QString {
@ -96,7 +96,7 @@ void Generator::setupSCPI()
central->setPort(newval);
return "";
}
}, [=]() -> QString {
}, [=](QStringList) -> QString {
return QString::number(central->getDeviceStatus().activePort);
}));
}

View File

@ -235,7 +235,8 @@ SpectrumAnalyzer::SpectrumAnalyzer(AppWindow *window)
markerModel = new TraceMarkerModel(traceModel, this);
auto tracesDock = new QDockWidget("Traces");
tracesDock->setWidget(new TraceWidgetSA(traceModel, window));
traceWidget = new TraceWidgetSA(traceModel, window);
tracesDock->setWidget(traceWidget);
window->addDockWidget(Qt::LeftDockWidgetArea, tracesDock);
docks.insert(tracesDock);
@ -677,7 +678,7 @@ void SpectrumAnalyzer::SetupSCPI()
SetSpan(newval);
return "";
}
}, [=]() -> QString {
}, [=](QStringList) -> QString {
return QString::number(settings.f_stop - settings.f_start);
}));
scpi_freq->add(new SCPICommand("START", [=](QStringList params) -> QString {
@ -688,7 +689,7 @@ void SpectrumAnalyzer::SetupSCPI()
SetStartFreq(newval);
return "";
}
}, [=]() -> QString {
}, [=](QStringList) -> QString {
return QString::number(settings.f_start);
}));
scpi_freq->add(new SCPICommand("CENTer", [=](QStringList params) -> QString {
@ -699,7 +700,7 @@ void SpectrumAnalyzer::SetupSCPI()
SetCenterFreq(newval);
return "";
}
}, [=]() -> QString {
}, [=](QStringList) -> QString {
return QString::number((settings.f_start + settings.f_stop)/2);
}));
scpi_freq->add(new SCPICommand("STOP", [=](QStringList params) -> QString {
@ -710,10 +711,11 @@ void SpectrumAnalyzer::SetupSCPI()
SetStopFreq(newval);
return "";
}
}, [=]() -> QString {
}, [=](QStringList) -> QString {
return QString::number(settings.f_stop);
}));
scpi_freq->add(new SCPICommand("FULL", [=](QStringList params) -> QString {
Q_UNUSED(params)
SetFullSpan();
return "";
}, nullptr));
@ -727,7 +729,7 @@ void SpectrumAnalyzer::SetupSCPI()
SetRBW(newval);
return "";
}
}, [=]() -> QString {
}, [=](QStringList) -> QString {
return QString::number(settings.RBW);
}));
scpi_acq->add(new SCPICommand("WINDow", [=](QStringList params) -> QString {
@ -746,7 +748,7 @@ void SpectrumAnalyzer::SetupSCPI()
return "INVALID MDOE";
}
return "";
}, [=]() -> QString {
}, [=](QStringList) -> QString {
switch((Window) settings.WindowType) {
case Window::None: return "NONE";
case Window::Kaiser: return "KAISER";
@ -773,7 +775,7 @@ void SpectrumAnalyzer::SetupSCPI()
return "INVALID MDOE";
}
return "";
}, [=]() -> QString {
}, [=](QStringList) -> QString {
switch((Detector) settings.Detector) {
case Detector::PPeak: return "+PEAK";
case Detector::NPeak: return "-PEAK";
@ -791,7 +793,7 @@ void SpectrumAnalyzer::SetupSCPI()
SetAveraging(newval);
return "";
}
}, [=]() -> QString {
}, [=](QStringList) -> QString {
return QString::number(averages);
}));
scpi_acq->add(new SCPICommand("SIGid", [=](QStringList params) -> QString {
@ -806,7 +808,7 @@ void SpectrumAnalyzer::SetupSCPI()
return "ERROR";
}
return "";
}, [=]() -> QString {
}, [=](QStringList) -> QString {
return settings.SignalID ? "1" : "0";
}));
auto scpi_tg = new SCPINode("TRACKing");
@ -823,7 +825,7 @@ void SpectrumAnalyzer::SetupSCPI()
return "ERROR";
}
return "";
}, [=]() -> QString {
}, [=](QStringList) -> QString {
return settings.trackingGenerator ? "1" : "0";
}));
scpi_tg->add(new SCPICommand("Port", [=](QStringList params) -> QString {
@ -838,7 +840,7 @@ void SpectrumAnalyzer::SetupSCPI()
return "ERROR";
}
return "";
}, [=]() -> QString {
}, [=](QStringList) -> QString {
return settings.trackingGeneratorPort ? "2" : "1";
}));
scpi_tg->add(new SCPICommand("LVL", [=](QStringList params) -> QString {
@ -853,7 +855,7 @@ void SpectrumAnalyzer::SetupSCPI()
SetTGLevel(newval);
return "";
}
}, [=]() -> QString {
}, [=](QStringList) -> QString {
return QString::number(settings.trackingPower / 100.0);
}));
scpi_tg->add(new SCPICommand("OFFset", [=](QStringList params) -> QString {
@ -868,7 +870,7 @@ void SpectrumAnalyzer::SetupSCPI()
SetTGOffset(newval);
return "";
}
}, [=]() -> QString {
}, [=](QStringList) -> QString {
return QString::number(settings.trackingGeneratorOffset);
}));
auto scpi_norm = new SCPINode("NORMalize");
@ -885,7 +887,7 @@ void SpectrumAnalyzer::SetupSCPI()
return "ERROR";
}
return "";
}, [=]() -> QString {
}, [=](QStringList) -> QString {
return normalize.active ? "1" : "0";
}));
scpi_norm->add(new SCPICommand("MEASure", [=](QStringList params) -> QString {
@ -905,9 +907,10 @@ void SpectrumAnalyzer::SetupSCPI()
SetNormalizationLevel(newval);
return "";
}
}, [=]() -> QString {
}, [=](QStringList) -> QString {
return QString::number(normalize.Level->value());
}));
SCPINode::add(traceWidget);
}
void SpectrumAnalyzer::UpdateAverageCount()

View File

@ -9,6 +9,7 @@
#include <QComboBox>
#include <QCheckBox>
#include "scpi.h"
#include "Traces/tracewidget.h"
class SpectrumAnalyzer : public Mode, public SCPINode
{
@ -76,6 +77,7 @@ private:
Protocol::SpectrumAnalyzerSettings settings;
unsigned int averages;
TraceModel traceModel;
TraceWidget *traceWidget;
TraceMarkerModel *markerModel;
Averaging average;

View File

@ -12,6 +12,7 @@
TraceWidget::TraceWidget(TraceModel &model, QWidget *parent) :
QWidget(parent),
SCPINode("TRACe"),
ui(new Ui::TraceWidget),
model(model)
{
@ -23,6 +24,7 @@ TraceWidget::TraceWidget(TraceModel &model, QWidget *parent) :
connect(ui->bExport, &QPushButton::clicked, this, &TraceWidget::exportDialog);
installEventFilter(this);
createCount = 0;
SetupSCPI();
}
TraceWidget::~TraceWidget()
@ -133,3 +135,54 @@ void TraceWidget::on_view_clicked(const QModelIndex &index)
break;
}
}
void TraceWidget::SetupSCPI()
{
auto findTrace = [=](QStringList params) -> Trace* {
if(params.size() < 1) {
return nullptr;
}
// check if trace is specified by number
bool ok;
auto n = params[0].toUInt(&ok);
if(ok) {
// check if enough traces exist
if(n < model.getTraces().size()) {
return model.getTraces()[n];
} else {
// invalid number
return nullptr;
}
} else {
// trace specified by name
for(auto t : model.getTraces()) {
if(t->name().compare(params[0], Qt::CaseInsensitive) == 0) {
return t;
}
}
// not found
return nullptr;
}
};
add(new SCPICommand("LIST", nullptr, [=](QStringList){
QString ret;
for(auto t : model.getTraces()) {
ret += t->name() + ",";
}
ret.chop(1);
return ret;
}));
add(new SCPICommand("DATA", nullptr, [=](QStringList params) -> QString {
auto t = findTrace(params);
if(!t) {
return "ERROR";
}
QString ret;
for(unsigned int i=0;i<t->size();i++) {
auto d = t->sample(i);
ret += "["+QString::number(d.x)+","+QString::number(d.y.real())+","+QString::number(d.y.imag())+"],";
}
ret.chop(1);
return ret;
}));
}

View File

@ -3,12 +3,13 @@
#include <QWidget>
#include "tracemodel.h"
#include "scpi.h"
namespace Ui {
class TraceWidget;
}
class TraceWidget : public QWidget
class TraceWidget : public QWidget, public SCPINode
{
Q_OBJECT
@ -26,6 +27,7 @@ protected slots:
virtual void importDialog() = 0;
protected:
void SetupSCPI();
bool eventFilter(QObject *obj, QEvent *event) override;
virtual Trace::LiveParameter defaultParameter() = 0;
QPoint dragStartPosition;

View File

@ -219,7 +219,7 @@ bool TraceXYPlot::isTDRtype(TraceXYPlot::YAxisType type)
void TraceXYPlot::axisSetupDialog()
{
auto setup = new XYplotAxisDialog(this);
setup->exec();
setup->show();
}
void TraceXYPlot::updateContextMenu()

View File

@ -59,8 +59,6 @@ VNA::VNA(AppWindow *window)
calDialog.reset();
calEdited = false;
SetupSCPI();
// Create default traces
auto tS11 = new Trace("S11", Qt::yellow);
tS11->fromLivedata(Trace::LivedataType::Overwrite, Trace::LiveParameter::S11);
@ -421,7 +419,8 @@ VNA::VNA(AppWindow *window)
markerModel = new TraceMarkerModel(traceModel, this);
auto tracesDock = new QDockWidget("Traces");
tracesDock->setWidget(new TraceWidgetVNA(traceModel, cal, deembedding));
traceWidget = new TraceWidgetVNA(traceModel, cal, deembedding);
tracesDock->setWidget(traceWidget);
window->addDockWidget(Qt::LeftDockWidgetArea, tracesDock);
docks.insert(tracesDock);
@ -433,6 +432,8 @@ VNA::VNA(AppWindow *window)
window->addDockWidget(Qt::BottomDockWidgetArea, markerDock);
docks.insert(markerDock);
SetupSCPI();
// Set initial sweep settings
auto pref = Preferences::getInstance();
if(pref.Acquisition.alwaysExciteBothPorts) {
@ -902,7 +903,7 @@ void VNA::SetupSCPI()
SetSpan(newval);
return "";
}
}, [=]() -> QString {
}, [=](QStringList) -> QString {
return QString::number(settings.f_stop - settings.f_start);
}));
scpi_freq->add(new SCPICommand("START", [=](QStringList params) -> QString {
@ -913,7 +914,7 @@ void VNA::SetupSCPI()
SetStartFreq(newval);
return "";
}
}, [=]() -> QString {
}, [=](QStringList) -> QString {
return QString::number(settings.f_start);
}));
scpi_freq->add(new SCPICommand("CENTer", [=](QStringList params) -> QString {
@ -924,7 +925,7 @@ void VNA::SetupSCPI()
SetCenterFreq(newval);
return "";
}
}, [=]() -> QString {
}, [=](QStringList) -> QString {
return QString::number((settings.f_start + settings.f_stop)/2);
}));
scpi_freq->add(new SCPICommand("STOP", [=](QStringList params) -> QString {
@ -935,10 +936,11 @@ void VNA::SetupSCPI()
SetStopFreq(newval);
return "";
}
}, [=]() -> QString {
}, [=](QStringList) -> QString {
return QString::number(settings.f_stop);
}));
scpi_freq->add(new SCPICommand("FULL", [=](QStringList params) -> QString {
Q_UNUSED(params)
SetFullSpan();
return "";
}, nullptr));
@ -952,7 +954,7 @@ void VNA::SetupSCPI()
SetIFBandwidth(newval);
return "";
}
}, [=]() -> QString {
}, [=](QStringList) -> QString {
return QString::number(settings.if_bandwidth);
}));
scpi_acq->add(new SCPICommand("POINTS", [=](QStringList params) -> QString {
@ -963,7 +965,7 @@ void VNA::SetupSCPI()
SetPoints(newval);
return "";
}
}, [=]() -> QString {
}, [=](QStringList) -> QString {
return QString::number(settings.points);
}));
scpi_acq->add(new SCPICommand("AVG", [=](QStringList params) -> QString {
@ -974,7 +976,7 @@ void VNA::SetupSCPI()
SetAveraging(newval);
return "";
}
}, [=]() -> QString {
}, [=](QStringList) -> QString {
return QString::number(averages);
}));
auto scpi_stim = new SCPINode("STIMulus");
@ -991,9 +993,10 @@ void VNA::SetupSCPI()
SetSourceLevel(newval);
return "";
}
}, [=]() -> QString {
}, [=](QStringList) -> QString {
return QString::number(settings.cdbm_excitation / 100.0);
}));
SCPINode::add(traceWidget);
}
void VNA::ConstrainAndUpdateFrequencies()

View File

@ -10,6 +10,7 @@
#include <functional>
#include "Deembedding/deembedding.h"
#include "scpi.h"
#include "Traces/tracewidget.h"
class VNA : public Mode, public SCPINode
{
@ -66,6 +67,7 @@ private:
Protocol::SweepSettings settings;
unsigned int averages;
TraceModel traceModel;
TraceWidget *traceWidget;
TraceMarkerModel *markerModel;
Averaging average;

View File

@ -95,60 +95,6 @@ AppWindow::AppWindow(QWidget *parent)
StartTCPServer(Preferences::getInstance().General.SCPI.port);
}
scpi.add(new SCPICommand("*IDN", nullptr, [=](){
return "LibreVNA-GUI";
}));
auto scpi_dev = new SCPINode("DEVice");
scpi.add(scpi_dev);
scpi_dev->add(new SCPICommand("DISConnect", [=](QStringList params) -> QString {
Q_UNUSED(params)
DisconnectDevice();
return "";
}, nullptr));
scpi_dev->add(new SCPICommand("CONNect", [=](QStringList params) -> QString {
QString serial;
if(params.size() > 0) {
serial = params[0];
}
if(!ConnectToDevice(serial)) {
return "Device not found";
} else {
return "";
}
}, [=]() -> QString {
if(device) {
return device->serial();
} else {
return "Not connected";
}
}));
scpi.add(new SCPICommand("MODE", [=](QStringList params) -> QString {
if (params.size() != 1) {
return "ERROR";
}
if (params[0] == "VNA") {
vna->activate();
} else if(params[0] == "GEN") {
generator->activate();
} else if(params[0] == "SA") {
spectrumAnalyzer->activate();
} else {
return "INVALID MDOE";
}
return "";
}, [=]() -> QString {
auto active = Mode::getActiveMode();
if(active == vna) {
return "VNA";
} else if(active == generator) {
return "GEN";
} else if(active == spectrumAnalyzer) {
return "SA";
} else {
return "ERROR";
}
}));
ui->setupUi(this);
ui->statusbar->addWidget(&lConnectionStatus);
auto div1 = new QFrame;
@ -196,10 +142,6 @@ AppWindow::AppWindow(QWidget *parent)
generator = new Generator(this);
spectrumAnalyzer = new SpectrumAnalyzer(this);
scpi.add(vna);
scpi.add(generator);
scpi.add(spectrumAnalyzer);
// UI connections
connect(ui->actionUpdate_Device_List, &QAction::triggered, this, &AppWindow::UpdateDeviceList);
connect(ui->actionDisconnect, &QAction::triggered, this, &AppWindow::DisconnectDevice);
@ -242,7 +184,7 @@ AppWindow::AppWindow(QWidget *parent)
connect(ui->actionReceiver_Calibration, &QAction::triggered, this, &AppWindow::ReceiverCalibrationDialog);
connect(ui->actionPreferences, &QAction::triggered, [=](){
// save previous SCPI settings in case they change
auto p = Preferences::getInstance();
auto &p = Preferences::getInstance();
auto SCPIenabled = p.General.SCPI.enabled;
auto SCPIport = p.General.SCPI.port;
p.edit();
@ -272,6 +214,8 @@ AppWindow::AppWindow(QWidget *parent)
restoreGeometry(settings.value("geometry").toByteArray());
}
SetupSCPI();
// Set default mode
vna->activate();
@ -416,6 +360,174 @@ void AppWindow::CreateToolbars()
tb_reference->setObjectName("Reference Toolbar");
}
void AppWindow::SetupSCPI()
{
scpi.add(new SCPICommand("*IDN", nullptr, [=](QStringList){
return "LibreVNA-GUI";
}));
auto scpi_dev = new SCPINode("DEVice");
scpi.add(scpi_dev);
scpi_dev->add(new SCPICommand("DISConnect", [=](QStringList params) -> QString {
Q_UNUSED(params)
DisconnectDevice();
return "";
}, nullptr));
scpi_dev->add(new SCPICommand("CONNect", [=](QStringList params) -> QString {
QString serial;
if(params.size() > 0) {
serial = params[0];
}
if(!ConnectToDevice(serial)) {
return "Device not found";
} else {
return "";
}
}, [=](QStringList) -> QString {
if(device) {
return device->serial();
} else {
return "Not connected";
}
}));
scpi_dev->add(new SCPICommand("LIST", nullptr, [=](QStringList) -> QString {
QString ret;
for(auto d : Device::GetDevices()) {
ret += d + ",";
}
// remove last comma
ret.chop(1);
return ret;
}));
auto scpi_ref = new SCPINode("REFerence");
scpi_dev->add(scpi_ref);
scpi_ref->add(new SCPICommand("OUT", [=](QStringList params) -> QString {
if(params.size() != 1) {
return "ERROR";
} else if(params[0] == "0" || params[0] == "OFF") {
toolbars.reference.outFreq->setCurrentIndex(0);
} else if(params[0] == "10") {
toolbars.reference.outFreq->setCurrentIndex(1);
} else if(params[0] == "100") {
toolbars.reference.outFreq->setCurrentIndex(2);
} else {
return "ERROR";
}
return "";
}, [=](QStringList) -> QString {
switch(toolbars.reference.outFreq->currentIndex()) {
case 0: return "OFF";
case 1: return "10";
case 2: return "100";
default: return "ERROR";
}
}));
scpi_ref->add(new SCPICommand("IN", [=](QStringList params) -> QString {
if(params.size() != 1) {
return "ERROR";
} else if(params[0] == "INT") {
toolbars.reference.type->setCurrentIndex(0);
} else if(params[0] == "EXT") {
toolbars.reference.type->setCurrentIndex(1);
} else if(params[0] == "AUTO") {
toolbars.reference.type->setCurrentIndex(2);
} else {
return "ERROR";
}
return "";
}, [=](QStringList) -> QString {
switch(Device::Info().extRefInUse) {
case 0: return "INT";
case 1: return "EXT";
default: return "ERROR";
}
}));
scpi.add(new SCPICommand("MODE", [=](QStringList params) -> QString {
if (params.size() != 1) {
return "ERROR";
}
if (params[0] == "VNA") {
vna->activate();
} else if(params[0] == "GEN") {
generator->activate();
} else if(params[0] == "SA") {
spectrumAnalyzer->activate();
} else {
return "INVALID MDOE";
}
return "";
}, [=](QStringList) -> QString {
auto active = Mode::getActiveMode();
if(active == vna) {
return "VNA";
} else if(active == generator) {
return "GEN";
} else if(active == spectrumAnalyzer) {
return "SA";
} else {
return "ERROR";
}
}));
auto scpi_status = new SCPINode("STAtus");
scpi_dev->add(scpi_status);
scpi_status->add(new SCPICommand("UNLOcked", nullptr, [=](QStringList){
bool locked = Device::Info().source_locked && Device::Info().LO1_locked;
return locked ? "0" : "1";
}));
scpi_status->add(new SCPICommand("ADCOVERload", nullptr, [=](QStringList){
return Device::Info().ADC_overload ? "1" : "0";
}));
scpi_status->add(new SCPICommand("UNLEVel", nullptr, [=](QStringList){
return Device::Info().unlevel ? "1" : "0";
}));
auto scpi_info = new SCPINode("INFo");
scpi_dev->add(scpi_info);
scpi_info->add(new SCPICommand("FWREVision", nullptr, [=](QStringList){
return QString::number(Device::Info().FW_major)+"."+QString::number(Device::Info().FW_minor)+"."+QString::number(Device::Info().FW_patch);
}));
scpi_info->add(new SCPICommand("HWREVision", nullptr, [=](QStringList){
return QString(Device::Info().HW_Revision);
}));
scpi_info->add(new SCPICommand("TEMPeratures", nullptr, [=](QStringList){
return QString::number(Device::Info().temp_source)+"/"+QString::number(Device::Info().temp_LO1)+"/"+QString::number(Device::Info().temp_MCU);
}));
auto scpi_limits = new SCPINode("LIMits");
scpi_info->add(scpi_limits);
scpi_limits->add(new SCPICommand("MINFrequency", nullptr, [=](QStringList){
return QString::number(Device::Info().limits_minFreq);
}));
scpi_limits->add(new SCPICommand("MAXFrequency", nullptr, [=](QStringList){
return QString::number(Device::Info().limits_maxFreq);
}));
scpi_limits->add(new SCPICommand("MINIFBW", nullptr, [=](QStringList){
return QString::number(Device::Info().limits_minIFBW);
}));
scpi_limits->add(new SCPICommand("MAXIFBW", nullptr, [=](QStringList){
return QString::number(Device::Info().limits_maxIFBW);
}));
scpi_limits->add(new SCPICommand("MAXPoints", nullptr, [=](QStringList){
return QString::number(Device::Info().limits_maxPoints);
}));
scpi_limits->add(new SCPICommand("MINPOWer", nullptr, [=](QStringList){
return QString::number(Device::Info().limits_cdbm_min / 100.0);
}));
scpi_limits->add(new SCPICommand("MAXPOWer", nullptr, [=](QStringList){
return QString::number(Device::Info().limits_cdbm_max / 100.0);
}));
scpi_limits->add(new SCPICommand("MINRBW", nullptr, [=](QStringList){
return QString::number(Device::Info().limits_minRBW);
}));
scpi_limits->add(new SCPICommand("MAXRBW", nullptr, [=](QStringList){
return QString::number(Device::Info().limits_maxRBW);
}));
scpi_limits->add(new SCPICommand("MAXHARMonicfrequency", nullptr, [=](QStringList){
return QString::number(Device::Info().limits_maxFreqHarmonic);
}));
scpi.add(vna);
scpi.add(generator);
scpi.add(spectrumAnalyzer);
}
void AppWindow::StartTCPServer(int port)
{
server = new TCPServer(port);
@ -426,6 +538,7 @@ void AppWindow::StartTCPServer(int port)
void AppWindow::StopTCPServer()
{
delete server;
server = nullptr;
}
int AppWindow::UpdateDeviceList()

View File

@ -58,6 +58,7 @@ private slots:
private:
void DeviceConnectionLost();
void CreateToolbars();
void SetupSCPI();
void StartTCPServer(int port);
void StopTCPServer();

View File

@ -20,7 +20,20 @@ void sig_handler(int s) {
}
int main(int argc, char *argv[]) {
app = new QApplication(argc, argv);
// Hack: set platform to offscreen if no-gui option specified, this prevents any dialogs from showing up
char *argv_ext[argc+2];
for(int i=0;i<argc;i++) {
argv_ext[i] = argv[i];
}
for (int i = 1; i < argc; ++i) {
if (!qstrcmp(argv[i], "--no-gui")) {
argv_ext[argc] = const_cast<char*>("-platform");
argv_ext[argc+1] = const_cast<char*>("offscreen");
argc+=2;
break;
}
}
app = new QApplication(argc, argv_ext);
window = new AppWindow;
signal(SIGINT, sig_handler);
app->exec();

View File

@ -5,7 +5,7 @@ SCPI::SCPI() :
SCPINode("")
{
lastNode = this;
add(new SCPICommand("*LST", nullptr, [=](){
add(new SCPICommand("*LST", nullptr, [=](QStringList){
QString list;
createCommandList("", list);
return list.trimmed();
@ -130,7 +130,7 @@ QString SCPINode::parse(QString cmd, SCPINode* &lastNode)
// save current node in case of non-root for the next command
lastNode = this;
if(isQuery) {
return c->query();
return c->query(params);
} else {
return c->execute(params);
}
@ -150,11 +150,11 @@ QString SCPICommand::execute(QStringList params)
}
}
QString SCPICommand::query()
QString SCPICommand::query(QStringList params)
{
if(fn_query == nullptr) {
return "ERROR";
} else {
return fn_query();
return fn_query(params);
}
}

View File

@ -8,20 +8,20 @@
class SCPICommand {
public:
SCPICommand(QString name, std::function<QString(QStringList)> cmd, std::function<QString()> query) :
SCPICommand(QString name, std::function<QString(QStringList)> cmd, std::function<QString(QStringList)> query) :
_name(name),
fn_cmd(cmd),
fn_query(query){}
QString execute(QStringList params);
QString query();
QString query(QStringList params);
QString name() {return _name;}
bool queryable() { return fn_query != nullptr;};
bool executable() { return fn_cmd != nullptr;};
private:
const QString _name;
std::function<QString(QStringList)> fn_cmd;
std::function<QString()> fn_query;
std::function<QString(QStringList)> fn_query;
};
class SCPINode {

View File

@ -34,6 +34,10 @@ bool AmplitudeCal::Load() {
LOG_WARN("Invalid version in flash, expected %u, got %u", version, cal.version);
SetDefault();
return false;
} else if(cal.Source.usedPoints == 0 || cal.Receiver.usedPoints == 0){
LOG_WARN("Empty amplitude calibration, resetting to default");
SetDefault();
return false;
} else {
LOG_INFO("Loaded from flash");
return true;
@ -128,7 +132,7 @@ static void addPoint(CorrectionTable& table, const Protocol::AmplitudeCorrection
table.freq[p.pointNum] = p.freq;
table.port1Correction[p.pointNum] = p.port1;
table.port2Correction[p.pointNum] = p.port2;
if(p.pointNum == p.totalPoints - 1) {
if(p.pointNum == p.totalPoints - 1 || p.pointNum == AmplitudeCal::maxPoints - 1) {
// this was the last point, update used points and save
table.usedPoints = p.totalPoints;
LOG_INFO("Last point received, saving to flash");

View File

@ -142,6 +142,7 @@ void App_Start() {
Communication::SendWithoutPayload(Protocol::PacketType::Ack);
break;
case Protocol::PacketType::RequestDeviceInfo:
Communication::SendWithoutPayload(Protocol::PacketType::Ack);
Protocol::PacketInfo p;
p.type = Protocol::PacketType::DeviceInfo;
HW::fillDeviceInfo(&p.info);
@ -189,16 +190,20 @@ void App_Start() {
break;
#endif
case Protocol::PacketType::RequestSourceCal:
Communication::SendWithoutPayload(Protocol::PacketType::Ack);
AmplitudeCal::SendSource();
break;
case Protocol::PacketType::RequestReceiverCal:
Communication::SendWithoutPayload(Protocol::PacketType::Ack);
AmplitudeCal::SendReceiver();
break;
case Protocol::PacketType::SourceCalPoint:
AmplitudeCal::AddSourcePoint(recv_packet.amplitudePoint);
Communication::SendWithoutPayload(Protocol::PacketType::Ack);
break;
case Protocol::PacketType::ReceiverCalPoint:
AmplitudeCal::AddReceiverPoint(recv_packet.amplitudePoint);
Communication::SendWithoutPayload(Protocol::PacketType::Ack);
break;
default:
// this packet type is not supported