WIP: device driver abstraction

This commit is contained in:
Jan Käberich 2023-01-16 00:25:29 +01:00
parent 59e30e93c5
commit db6d823e0f
42 changed files with 1631 additions and 576 deletions

View File

@ -151,7 +151,7 @@ Calibration::Calibration()
}
bool okay;
unsigned int number = params[1].toInt(&okay);
if(!okay || number < 1 || number > VirtualDevice::getInfo(VirtualDevice::getConnected()).ports) {
if(!okay || number < 1 || number > DeviceDriver::getInfo(DeviceDriver::getActiveDriver()).Limits.VNA.ports) {
// invalid port specified
return SCPI::getResultName(SCPI::Result::Error);
}
@ -168,8 +168,8 @@ Calibration::Calibration()
unsigned int port1 = params[1].toInt(&okay1);
bool okay2;
unsigned int port2 = params[2].toInt(&okay2);
if(!okay1 || !okay2 || port1 < 1 || port2 > VirtualDevice::getInfo(VirtualDevice::getConnected()).ports
|| port2 < 1 || port2 > VirtualDevice::getInfo(VirtualDevice::getConnected()).ports) {
if(!okay1 || !okay2 || port1 < 1 || port2 > DeviceDriver::getInfo(DeviceDriver::getActiveDriver()).Limits.VNA.ports
|| port2 < 1 || port2 > DeviceDriver::getInfo(DeviceDriver::getActiveDriver()).Limits.VNA.ports) {
// invalid port specified
return SCPI::getResultName(SCPI::Result::Error);
}
@ -318,7 +318,7 @@ Calibration::Type Calibration::TypeFromString(QString s)
return Type::None;
}
void Calibration::correctMeasurement(VirtualDevice::VNAMeasurement &d)
void Calibration::correctMeasurement(DeviceDriver::VNAMeasurement &d)
{
lock_guard<recursive_mutex> guard(access);
if(caltype.type == Type::None) {
@ -1424,7 +1424,7 @@ void Calibration::fromJSON(nlohmann::json j)
throw runtime_error("Measurement "+name.toStdString()+" does not contain any points");
}
for(auto j_p : j_m["points"]) {
VirtualDevice::VNAMeasurement p;
DeviceDriver::VNAMeasurement p;
p.frequency = j_p.value("frequency", 0.0);
p.Z0 = 50.0;
p.measurements["S11"] = complex<double>(j_p.value("S11_real", 0.0), j_p.value("S11_imag", 0.0));
@ -1557,10 +1557,7 @@ bool Calibration::fromFile(QString filename)
std::vector<Calibration::CalType> Calibration::getAvailableCalibrations()
{
unsigned int ports = 2;
if(VirtualDevice::getConnected()) {
ports = VirtualDevice::getConnected()->getInfo().ports;
}
unsigned int ports = DeviceDriver::getInfo(DeviceDriver::getActiveDriver()).Limits.VNA.ports;
vector<CalType> ret;
for(auto t : getTypes()) {
CalType cal;
@ -1727,14 +1724,15 @@ int Calibration::minimumPorts(Calibration::Type type)
return -1;
}
void Calibration::addMeasurements(std::set<CalibrationMeasurement::Base *> m, const VirtualDevice::VNAMeasurement &data)
void Calibration::addMeasurements(std::set<CalibrationMeasurement::Base *> m, const DeviceDriver::VNAMeasurement &data)
{
for(auto meas : m) {
meas->addPoint(data);
}
unsavedChanges = true;
if(VirtualDevice::getConnected()) {
validDevice = VirtualDevice::getConnected()->serial();
// TODO
if(DeviceDriver::getActiveDriver()) {
validDevice = DeviceDriver::getActiveDriver()->getSerial();
}
}

View File

@ -7,6 +7,8 @@
#include "Traces/trace.h"
#include "scpi.h"
#include <mutex>
class Calibration : public QObject, public Savable, public SCPINode
{
Q_OBJECT
@ -38,7 +40,7 @@ public:
static Type TypeFromString(QString s);
// Applies calculated calibration coefficients to measurement data
void correctMeasurement(VirtualDevice::VNAMeasurement &d);
void correctMeasurement(DeviceDriver::VNAMeasurement &d);
void correctTraces(std::map<QString, Trace*> traceSet);
// Starts the calibration edit dialog, allowing the user to make/delete measurements
@ -68,7 +70,7 @@ public:
static int minimumPorts(Type type);
// Adds a new measurement point (data) to all calibration measurements (m)
void addMeasurements(std::set<CalibrationMeasurement::Base*> m, const VirtualDevice::VNAMeasurement &data);
void addMeasurements(std::set<CalibrationMeasurement::Base*> m, const DeviceDriver::VNAMeasurement &data);
// Deletes all datapoints in the calibration measurements (m)
void clearMeasurements(std::set<CalibrationMeasurement::Base*> m);
CalType getCaltype() const;

View File

@ -246,7 +246,7 @@ void CalibrationMeasurement::OnePort::clearPoints()
timestamp = QDateTime();
}
void CalibrationMeasurement::OnePort::addPoint(const VirtualDevice::VNAMeasurement &m)
void CalibrationMeasurement::OnePort::addPoint(const DeviceDriver::VNAMeasurement &m)
{
QString measurementName = "S"+QString::number(port)+QString::number(port);
if(m.measurements.count(measurementName) > 0) {
@ -262,12 +262,12 @@ QWidget *CalibrationMeasurement::OnePort::createSettingsWidget()
{
auto label = new QLabel("Port:");
auto cbPort = new QComboBox();
auto dev = VirtualDevice::getConnected();
auto dev = DeviceDriver::getActiveDriver();
if(dev) {
if(port == 0) {
setPort(1);
}
for(unsigned int i=1;i<=dev->getInfo().ports;i++) {
for(unsigned int i=1;i<=dev->getInfo().Limits.VNA.ports;i++) {
cbPort->addItem(QString::number(i));
if(port == i) {
cbPort->setCurrentText(QString::number(i));
@ -390,7 +390,7 @@ void CalibrationMeasurement::TwoPort::clearPoints()
timestamp = QDateTime();
}
void CalibrationMeasurement::TwoPort::addPoint(const VirtualDevice::VNAMeasurement &m)
void CalibrationMeasurement::TwoPort::addPoint(const DeviceDriver::VNAMeasurement &m)
{
Point p;
p.frequency = m.frequency;
@ -407,7 +407,7 @@ QWidget *CalibrationMeasurement::TwoPort::createSettingsWidget()
auto cbPort2 = new QComboBox();
auto cbReverse = new QCheckBox("Reversed");
cbReverse->setToolTip("Enable this option if the calibration standard is defined with the port order swapped");
auto dev = VirtualDevice::getConnected();
auto dev = DeviceDriver::getActiveDriver();
if(dev) {
if(port1 == 0) {
setPort1(1);
@ -415,7 +415,7 @@ QWidget *CalibrationMeasurement::TwoPort::createSettingsWidget()
if(port2 == 0) {
setPort2(2);
}
for(unsigned int i=1;i<=dev->getInfo().ports;i++) {
for(unsigned int i=1;i<=dev->getInfo().Limits.VNA.ports;i++) {
cbPort1->addItem(QString::number(i));
cbPort2->addItem(QString::number(i));
if(port1 == i) {
@ -603,7 +603,7 @@ void CalibrationMeasurement::Isolation::clearPoints()
timestamp = QDateTime();
}
void CalibrationMeasurement::Isolation::addPoint(const VirtualDevice::VNAMeasurement &m)
void CalibrationMeasurement::Isolation::addPoint(const DeviceDriver::VNAMeasurement &m)
{
Point p;
p.frequency = m.frequency;

View File

@ -2,7 +2,7 @@
#define CALIBRATIONMEASUREMENT_H
#include "calstandard.h"
#include "Device/virtualdevice.h"
#include "Device/devicedriver.h"
#include <QDateTime>
#include <QObject>
@ -47,7 +47,7 @@ public:
virtual Type getType() = 0;
virtual void clearPoints() = 0;
virtual void addPoint(const VirtualDevice::VNAMeasurement &m) = 0;
virtual void addPoint(const DeviceDriver::VNAMeasurement &m) = 0;
virtual QWidget* createStandardWidget();
virtual QWidget* createSettingsWidget() = 0;
@ -83,7 +83,7 @@ public:
virtual bool readyForCalculation() override {return standard && points.size() > 0;}
virtual void clearPoints() override;
virtual void addPoint(const VirtualDevice::VNAMeasurement &m) override;
virtual void addPoint(const DeviceDriver::VNAMeasurement &m) override;
virtual QWidget* createSettingsWidget() override;
@ -197,7 +197,7 @@ public:
virtual bool readyForCalculation() override {return standard && points.size() > 0;}
virtual void clearPoints() override;
virtual void addPoint(const VirtualDevice::VNAMeasurement &m) override;
virtual void addPoint(const DeviceDriver::VNAMeasurement &m) override;
virtual QWidget* createSettingsWidget() override;
@ -268,7 +268,7 @@ public:
virtual bool readyForCalculation() override {return points.size() > 0;}
virtual void clearPoints() override;
virtual void addPoint(const VirtualDevice::VNAMeasurement &m) override;
virtual void addPoint(const DeviceDriver::VNAMeasurement &m) override;
virtual QWidget* createStandardWidget() override;
virtual QWidget* createSettingsWidget() override;

View File

@ -0,0 +1,22 @@
#include "devicedriver.h"
DeviceDriver *DeviceDriver::activeDriver = nullptr;
bool DeviceDriver::connectDevice(QString serial)
{
if(activeDriver && activeDriver != this) {
activeDriver->disconnect();
}
if(connectTo(serial)) {
activeDriver = this;
return true;
} else {
return false;
}
}
void DeviceDriver::disconnectDevice()
{
disconnect();
activeDriver = nullptr;
}

View File

@ -1,4 +1,4 @@
#ifndef DEVICEDRIVER_H
#ifndef DEVICEDRIVER_H
#define DEVICEDRIVER_H
/**
@ -24,8 +24,8 @@ class DeviceDriver : public QObject
{
Q_OBJECT
public:
DeviceDriver();
virtual ~DeviceDriver();
DeviceDriver() {}
virtual ~DeviceDriver() {}
/**
* @brief Returns the driver name. It must be unique across all implemented drivers and is used to identify the driver
@ -37,22 +37,26 @@ public:
* @return Serial numbers of detected devices
*/
virtual std::set<QString> GetAvailableDevices() = 0;
protected:
/**
* @brief Connects to a device, given by its serial number
*
* @param serial Serial number of device that should be connected to
* @return true if connection successful, otherwise false
*/
virtual bool connectTo(QString serial) = 0;
virtual bool connectTo(QString getSerial) = 0;
/**
* @brief Disconnects from device. Has no effect if no device was connected
*/
virtual void disconnect() = 0;
public:
/**
* @brief Returns the serial number of the connected device
* @return Serial number of connected device (empty string if no device is connected)
*/
virtual QString serial() = 0;
virtual QString getSerial() = 0;
enum class Feature {
// VNA features
@ -65,7 +69,6 @@ public:
Generator,
// Spectrum analyzer features
SA,
SASignalID,
SATrackingGenerator,
SATrackingOffset,
// External reference
@ -75,6 +78,7 @@ public:
class Info {
public:
// TODO create constructor with default values
QString firmware_version;
QString hardware_version;
std::set<Feature> supportedFeatures;
@ -106,6 +110,8 @@ public:
double minFreq, maxFreq;
// RBW limits in Hz
double minRBW, maxRBW;
// Output level limits of the tracking generator in dBm
double mindBm, maxdBm;
} SA;
} Limits;
};
@ -179,19 +185,16 @@ public:
/**
* @brief Returns the driver specific settings
*
* The settings are returned as a map.
* Key: user-readable setting name
* Value: SettingDescription, consisting of:
* The settings are returned as a vector of SettingDescriptions, consisting of:
* - var: Pointer to the setting variable (should be a private member of the derived class)
* - name: Arbitrary string used to persistently store this setting (never visible to the user)
* - def: Default value of the setting
*
* These settings will be persistent across reboots. For each device driver, a section within the preferences
* will be created where these settings can be changed.
* These settings will be persistent across reboots.
*
* @return Map of driver specific settings
*/
virtual std::map<QString, Savable::SettingDescription> driverSpecificSettings() {return std::map<QString, Savable::SettingDescription>();}
virtual std::vector<Savable::SettingDescription> driverSpecificSettings() {return std::vector<Savable::SettingDescription>();}
/**
* @brief Return driver specific actions.
@ -343,6 +346,12 @@ public:
* @return true if configuration successful, false otherwise
*/
virtual bool setSA(const SASettings &s, std::function<void(bool)> cb = nullptr) {Q_UNUSED(s) Q_UNUSED(cb) return false;}
/**
* @brief Returns the number of points in one spectrum analyzer sweep (as configured by the last setSA() call)
* @return Number of points in the sweep
*/
virtual unsigned int getSApoints() {return 0;}
signals:
/**
* @brief This signal must be emitted whenever a SA measurement is complete and should be passed on to the GUI
@ -411,9 +420,19 @@ public:
*/
static constexpr unsigned int maximumSupportedPorts = 8;
static Info getInfo(DeviceDriver* driver) {
if(driver) {
return driver->getInfo();
} else {
return Info();
}
}
signals:
/**
* @brief Emit this signal when the device connection has been lost unexpectedly
*
* The device driver should do nothing else, the disconnect() function will be called from the application after this signal has been emitted.
*/
void ConnectionLost();
/**
@ -421,6 +440,14 @@ signals:
* @param line
*/
void LogLineReceived(QString line);
public:
bool connectDevice(QString serial);
void disconnectDevice();
static DeviceDriver* getActiveDriver() {return activeDriver;}
private:
static DeviceDriver *activeDriver;
};
Q_DECLARE_METATYPE(DeviceDriver::VNAMeasurement)

View File

@ -1,6 +1,312 @@
#include "librevnadriver.h"
using namespace std;
LibreVNADriver::LibreVNADriver()
{
connected = false;
skipOwnPacketHandling = false;
SApoints = 0;
}
std::set<DeviceDriver::Flag> LibreVNADriver::getFlags()
{
std::set<DeviceDriver::Flag> ret;
if(lastStatus.extRefInUse) {
ret.insert(Flag::ExtRef);
}
if(!lastStatus.source_locked || !lastStatus.LO1_locked) {
ret.insert(Flag::Unlocked);
}
if(lastStatus.unlevel) {
ret.insert(Flag::Unlevel);
}
if(lastStatus.ADC_overload) {
ret.insert(Flag::Overload);
}
return ret;
}
QString LibreVNADriver::getStatus()
{
QString ret;
ret.append("HW Rev.");
ret.append(info.hardware_version);
ret.append(" FW "+info.firmware_version);
ret.append(" Temps: "+QString::number(lastStatus.temp_source)+"°C/"+QString::number(lastStatus.temp_LO1)+"°C/"+QString::number(lastStatus.temp_MCU)+"°C");
ret.append(" Reference:");
if(lastStatus.extRefInUse) {
ret.append("External");
} else {
ret.append("Internal");
if(lastStatus.extRefAvailable) {
ret.append(" (External available)");
}
}
return ret;
}
std::vector<Savable::SettingDescription> LibreVNADriver::driverSpecificSettings()
{
std::vector<Savable::SettingDescription> ret;
ret.push_back(Savable::SettingDescription(&captureRawReceiverValues, "captureRawReceiverValues", false));
ret.push_back(Savable::SettingDescription(&SASignalID, "signalID", true));
ret.push_back(Savable::SettingDescription(&VNASuppressInvalidPeaks, "suppressInvalidPeaks", true));
ret.push_back(Savable::SettingDescription(&VNAAdjustPowerLevel, "adjustPowerLevel", false));
ret.push_back(Savable::SettingDescription(&SAUseDFT, "useDFT", true));
ret.push_back(Savable::SettingDescription(&SARBWLimitForDFT, "RBWlimitDFT", 3000));
return ret;
}
std::vector<QAction *> LibreVNADriver::driverSpecificActions()
{
// TODO
return std::vector<QAction*>();
}
QStringList LibreVNADriver::availableVNAMeasurements()
{
QStringList ret;
for(unsigned int i=1;i<=info.Limits.VNA.ports;i++) {
for(unsigned int j=1;j<=info.Limits.VNA.ports;j++) {
ret.push_back("S"+QString::number(i)+QString::number(j));
}
}
if(captureRawReceiverValues) {
for(unsigned int i=1;i<=info.Limits.VNA.ports;i++) {
for(unsigned int j=0;j<info.Limits.VNA.ports;j++) {
ret.push_back("RawPort"+QString::number(i)+"Stage"+QString::number(j));
ret.push_back("RawPort"+QString::number(i)+"Stage"+QString::number(j)+"Ref");
}
}
}
return ret;
}
bool LibreVNADriver::setVNA(const DeviceDriver::VNASettings &s, std::function<void (bool)> cb)
{
if(!supports(Feature::VNA)) {
return false;
}
if(s.excitedPorts.size() == 0) {
return setIdle(cb);
}
// create port->stage mapping
portStageMapping.clear();
for(unsigned int i=0;i<s.excitedPorts.size();i++) {
portStageMapping[s.excitedPorts[i]] = i;
}
Protocol::PacketInfo p = {};
p.type = Protocol::PacketType::SweepSettings;
p.settings.f_start = s.freqStart;
p.settings.f_stop = s.freqStop;
p.settings.points = s.points;
p.settings.if_bandwidth = s.IFBW;
p.settings.cdbm_excitation_start = s.dBmStart * 100;
p.settings.cdbm_excitation_stop = s.dBmStop * 100;
p.settings.stages = s.excitedPorts.size() - 1;
p.settings.suppressPeaks = VNASuppressInvalidPeaks ? 1 : 0;
p.settings.fixedPowerSetting = VNAAdjustPowerLevel || s.dBmStart != s.dBmStop ? 0 : 1;
p.settings.logSweep = s.logSweep ? 1 : 0;
zerospan = (s.freqStart == s.freqStop) && (s.dBmStart == s.dBmStop);
p.settings.port1Stage = find(s.excitedPorts.begin(), s.excitedPorts.end(), 0) - s.excitedPorts.begin();
p.settings.port2Stage = find(s.excitedPorts.begin(), s.excitedPorts.end(), 1) - s.excitedPorts.begin();
p.settings.syncMode = 0;
p.settings.syncMaster = 0;
return SendPacket(p, [=](TransmissionResult r){
if(cb) {
cb(r == TransmissionResult::Ack);
}
});
}
QStringList LibreVNADriver::availableSAMeasurements()
{
QStringList ret;
for(unsigned int i=1;i<=info.Limits.SA.ports;i++) {
ret.push_back("PORT"+QString::number(i));
}
return ret;
}
bool LibreVNADriver::setSA(const DeviceDriver::SASettings &s, std::function<void (bool)> cb)
{
if(!supports(Feature::SA)) {
return false;
}
zerospan = s.freqStart == s.freqStop;
Protocol::PacketInfo p = {};
p.spectrumSettings.f_start = s.freqStart;
p.spectrumSettings.f_stop = s.freqStop;
constexpr unsigned int maxSApoints = 1001;
if(s.freqStop - s.freqStart >= maxSApoints || s.freqStop - s.freqStart <= 0) {
SApoints = maxSApoints;
} else {
SApoints = s.freqStop - s.freqStart + 1;
}
p.spectrumSettings.pointNum = SApoints;
p.spectrumSettings.RBW = s.RBW;
p.spectrumSettings.WindowType = (int) s.window;
p.spectrumSettings.SignalID = SASignalID ? 1 : 0;
p.spectrumSettings.Detector = (int) s.detector;
p.spectrumSettings.UseDFT = 0;
if(!s.trackingGenerator && SAUseDFT && s.RBW <= SARBWLimitForDFT) {
p.spectrumSettings.UseDFT = 1;
}
p.spectrumSettings.applyReceiverCorrection = 1;
p.spectrumSettings.trackingGeneratorOffset = s.trackingOffset;
p.spectrumSettings.trackingPower = s.trackingPower;
p.spectrumSettings.trackingGenerator = s.trackingGenerator ? 1 : 0;
p.spectrumSettings.trackingGeneratorPort = s.trackingPort;
p.spectrumSettings.syncMode = 0;
p.spectrumSettings.syncMaster = 0;
return SendPacket(p, [=](TransmissionResult r){
if(cb) {
cb(r == TransmissionResult::Ack);
}
});
}
QStringList LibreVNADriver::availableSGPorts()
{
QStringList ret;
for(unsigned int i=1;i<info.Limits.Generator.ports;i++) {
ret.push_back("PORT"+QString::number(i));
}
return ret;
}
bool LibreVNADriver::setSG(const DeviceDriver::SGSettings &s)
{
Protocol::PacketInfo p = {};
p.type = Protocol::PacketType::Generator;
p.generator.frequency = s.freq;
p.generator.cdbm_level = s.dBm * 100;
p.generator.activePort = s.port;
p.generator.applyAmplitudeCorrection = true;
return SendPacket(p);
}
bool LibreVNADriver::setIdle(std::function<void (bool)> cb)
{
Protocol::PacketInfo p;
p.type = Protocol::PacketType::SetIdle;
return SendPacket(p, [=](TransmissionResult res) {
if(cb) {
cb(res == TransmissionResult::Ack);
}
});
}
void LibreVNADriver::handleReceivedPacket(const Protocol::PacketInfo &packet)
{
emit passOnReceivedPacket(packet);
if(skipOwnPacketHandling) {
return;
}
switch(packet.type) {
case Protocol::PacketType::DeviceInfo:
// TODO check protocol version
info.firmware_version = QString::number(packet.info.FW_major)+"."+QString::number(packet.info.FW_minor)+"."+QString::number(packet.info.FW_patch);
info.hardware_version = QString::number(packet.info.hardware_version)+QString(packet.info.HW_Revision);
info.supportedFeatures = {
Feature::VNA, Feature::VNAFrequencySweep, Feature::VNALogSweep, Feature::VNAPowerSweep, Feature::VNAZeroSpan,
Feature::Generator,
Feature::SA, Feature::SATrackingGenerator, Feature::SATrackingOffset,
Feature::ExtRefIn, Feature::ExtRefOut,
};
info.Limits.VNA.ports = 2;
info.Limits.VNA.minFreq = packet.info.limits_minFreq;
info.Limits.VNA.maxFreq = packet.info.limits_maxFreq; // TODO check if harmonic mixing is enabled
info.Limits.VNA.maxPoints = packet.info.limits_maxPoints;
info.Limits.VNA.minIFBW = packet.info.limits_minIFBW;
info.Limits.VNA.maxIFBW = packet.info.limits_maxIFBW;
info.Limits.VNA.mindBm = (double) packet.info.limits_cdbm_min / 100;
info.Limits.VNA.maxdBm = (double) packet.info.limits_cdbm_max / 100;
info.Limits.Generator.ports = 2;
info.Limits.Generator.minFreq = packet.info.limits_minFreq;
info.Limits.Generator.maxFreq = packet.info.limits_maxFreq;
info.Limits.Generator.mindBm = (double) packet.info.limits_cdbm_min / 100;
info.Limits.Generator.maxdBm = (double) packet.info.limits_cdbm_max / 100;
info.Limits.SA.ports = 2;
info.Limits.SA.minFreq = packet.info.limits_minFreq;
info.Limits.SA.maxFreq = packet.info.limits_maxFreq;
info.Limits.SA.minRBW = packet.info.limits_minRBW;
info.Limits.SA.maxRBW = packet.info.limits_maxRBW;
info.Limits.SA.mindBm = (double) packet.info.limits_cdbm_min / 100;
info.Limits.SA.maxdBm = (double) packet.info.limits_cdbm_max / 100;
emit InfoUpdated();
break;
case Protocol::PacketType::DeviceStatusV1:
lastStatus = packet.statusV1;
emit StatusUpdated();
break;
case Protocol::PacketType::VNADatapoint: {
VNAMeasurement m;
Protocol::VNADatapoint<32> *res = packet.VNAdatapoint;
m.pointNum = res->pointNum;
m.Z0 = 50.0;
if(zerospan) {
m.us = res->us;
} else {
m.frequency = res->frequency;
m.dBm = (double) res->cdBm / 100;
}
for(auto map : portStageMapping) {
// map.first is the port (starts at zero)
// map.second is the stage at which this port had the stimulus (starts at zero)
complex<double> ref = res->getValue(map.second, map.first, true);
for(unsigned int i=0;i<info.Limits.VNA.ports;i++) {
complex<double> input = res->getValue(map.second, i, false);
if(!std::isnan(ref.real()) && !std::isnan(input.real())) {
// got both required measurements
QString name = "S"+QString::number(i+1)+QString::number(map.first+1);
m.measurements[name] = input / ref;
}
if(captureRawReceiverValues) {
QString name = "RawPort"+QString::number(i+1)+"Stage"+QString::number(map.first);
m.measurements[name] = input;
name = "RawPort"+QString::number(i+1)+"Stage"+QString::number(map.first)+"Ref";
m.measurements[name] = res->getValue(map.second, i, true);
}
}
}
delete res;
emit VNAmeasurementReceived(m);
}
break;
case Protocol::PacketType::SpectrumAnalyzerResult: {
SAMeasurement m;
m.pointNum = packet.spectrumResult.pointNum;
if(zerospan) {
m.us = packet.spectrumResult.us;
} else {
m.frequency = packet.spectrumResult.frequency;
}
m.measurements["PORT1"] = packet.spectrumResult.port1;
m.measurements["PORT2"] = packet.spectrumResult.port2;
emit SAmeasurementReceived(m);
}
break;
}
}
bool LibreVNADriver::sendWithoutPayload(Protocol::PacketType type, std::function<void(TransmissionResult)> cb)
{
Protocol::PacketInfo p;
p.type = type;
return SendPacket(p, cb);
}

View File

@ -5,6 +5,8 @@
#include "../../VNA_embedded/Application/Communication/Protocol.hpp"
#include <functional>
class LibreVNADriver : public DeviceDriver
{
Q_OBJECT
@ -19,11 +21,188 @@ public:
LibreVNADriver();
protected:
/**
* @brief Returns the serial number of the connected device
* @return Serial number of connected device (empty string if no device is connected)
*/
virtual QString getSerial() override {return serial;}
/**
* @brief Returns the device information. This function will be called when a device has been connected. Its return value must be valid
* directly after returning from DeviceDriver::connectTo()
*
* Emit the InfoUpdate() signal whenever the return value of this function changes.
*
* @return Device information
*/
virtual Info getInfo() override {return info;}
/**
* @brief Returns a set of all active flags
*
* There is also a convenience function to check a specific flag, see DeviceDriver::asserted()
*
* @return Set of active flags
*/
virtual std::set<Flag> getFlags() override;
/**
* @brief Returns the device status string. It will be displayed in the status bar of the application
*
* Emit the StatusUpdated() signal whenever the return value of this function changes
*
* @return Status string
*/
virtual QString getStatus() override;
/**
* @brief Returns the driver specific settings
*
* The settings are returned as a map.
* Key: user-readable setting name
* Value: SettingDescription, consisting of:
* - var: Pointer to the setting variable (should be a private member of the derived class)
* - name: Arbitrary string used to persistently store this setting (never visible to the user)
* - def: Default value of the setting
*
* These settings will be persistent across reboots. For each device driver, a section within the preferences
* will be created where these settings can be changed.
*
* @return Map of driver specific settings
*/
virtual std::vector<Savable::SettingDescription> driverSpecificSettings() override;
/**
* @brief Return driver specific actions.
*
* The returned actions will be appended to the device menu.
*
* @return List of actions
*/
virtual std::vector<QAction*> driverSpecificActions() override;
/**
* @brief Names of available measurements.
*
* The names must be identical to the names used in the returned VNAMeasurement.
* Typically the S parameters, e.g. this function may return {"S11","S12","S21","S22"} but any other names are also allowed.
*
* @return List of available VNA measurement parameters
*/
virtual QStringList availableVNAMeasurements() override;
/**
* @brief Configures the VNA and starts a sweep
* @param s VNA settings
* @param cb Callback, must be called after the VNA has been configured
* @return true if configuration successful, false otherwise
*/
virtual bool setVNA(const VNASettings &s, std::function<void(bool)> cb = nullptr) override;
/**
* @brief Names of available measurements.
*
* The names must be identical to the names used in the returned SAMeasurement.
* Typically the port names, e.g. this function may return {"PORT1","PORT2"} but any other names are also allowed.
*
* @return List of available SA measurement parameters
*/
virtual QStringList availableSAMeasurements() override;
/**
* @brief Configures the SA and starts a sweep
* @param s SA settings
* @param cb Callback, must be called after the SA has been configured
* @return true if configuration successful, false otherwise
*/
virtual bool setSA(const SASettings &s, std::function<void(bool)> cb = nullptr) override;
/**
* @brief Returns the number of points in one spectrum analyzer sweep (as configured by the last setSA() call)
* @return Number of points in the sweep
*/
virtual unsigned int getSApoints() {return SApoints;}
/**
* @brief Names of available generator ports.
*
* Typically the port names, e.g. this function may return {"PORT1","PORT2"} but any other names are also allowed.
*
* @return List of available SA measurement parameters
*/
virtual QStringList availableSGPorts() override;
/**
* @brief Configures the generator
* @param s Generator settings
* @return true if configuration successful, false otherwise
*/
virtual bool setSG(const SGSettings &s) override;
/**
* @brief Sets the device to idle
*
* Stops all sweeps and signal generation
*
* @param cb Callback, must be called after the device has stopped all operations
* @return true if configuration successful, false otherwise
*/
virtual bool setIdle(std::function<void(bool)> cb = nullptr) override;
/**
* @brief Returns the available options for the external reference input
* @return External reference input options
*/
virtual QStringList availableExtRefInSettings() override;
/**
* @brief Returns the available options for the external reference output
* @return External reference output options
*/
virtual QStringList availableExtRefOutSettings() override;
/**
* @brief Configures the external reference input/output
* @param option_in Reference input option (one of the options returned by availableExtRefInSettings())
* @param option_out Reference output option (one of the options returned by availableExtRefOutSettings())
* @return true if configuration successful, false otherwise
*/
virtual bool setExtRef(QString option_in, QString option_out) override;
public:
signals:
// Required for the compound device driver
void passOnReceivedPacket(const Protocol::PacketInfo& packet);
public:
virtual bool SendPacket(const Protocol::PacketInfo& packet, std::function<void(TransmissionResult)> cb = nullptr, unsigned int timeout = 500) = 0;
virtual void ReceivedData(const uint8_t data, unsigned int len) = 0;
protected:
signals:
void receivedAnswer(TransmissionResult result);
void receivedPacket(const Protocol::PacketInfo& packet);
protected slots:
void handleReceivedPacket(const Protocol::PacketInfo& packet);
protected:
bool sendWithoutPayload(Protocol::PacketType type, std::function<void(TransmissionResult)> cb = nullptr);
bool connected;
QString serial;
Info info;
Protocol::DeviceStatusV1 lastStatus;
bool skipOwnPacketHandling;
bool zerospan;
unsigned int SApoints;
std::map<int, int> portStageMapping; // maps from excitedPort (count starts at zero) to stage (count starts at zero)
// Driver specific settings
bool captureRawReceiverValues;
bool SASignalID;
bool SAUseDFT;
double SARBWLimitForDFT;
bool VNASuppressInvalidPeaks;
bool VNAAdjustPowerLevel;
};
#endif // LIBREVNADRIVER_H

View File

@ -0,0 +1,431 @@
#include "librevnausbdriver.h"
#include "CustomWidgets/informationbox.h"
#include "deviceusblog.h"
#include <QTimer>
using namespace std;
using USBID = struct {
int VID;
int PID;
};
static constexpr USBID IDs[] = {
{0x0483, 0x564e},
{0x0483, 0x4121},
};
USBInBuffer::USBInBuffer(libusb_device_handle *handle, unsigned char endpoint, int buffer_size) :
buffer_size(buffer_size),
received_size(0),
inCallback(false),
cancelling(false)
{
buffer = new unsigned char[buffer_size];
memset(buffer, 0, buffer_size);
transfer = libusb_alloc_transfer(0);
libusb_fill_bulk_transfer(transfer, handle, endpoint, buffer, buffer_size, CallbackTrampoline, this, 0);
libusb_submit_transfer(transfer);
}
USBInBuffer::~USBInBuffer()
{
if(transfer) {
cancelling = true;
libusb_cancel_transfer(transfer);
// wait for cancellation to complete
mutex mtx;
unique_lock<mutex> lck(mtx);
using namespace std::chrono_literals;
if(cv.wait_for(lck, 100ms) == cv_status::timeout) {
qWarning() << "Timed out waiting for mutex acquisition during disconnect";
}
}
delete[] buffer;
}
void USBInBuffer::removeBytes(int handled_bytes)
{
if(!inCallback) {
throw runtime_error("Removing of bytes is only allowed from within receive callback");
}
if(handled_bytes >= received_size) {
received_size = 0;
} else {
// not removing all bytes, have to move remaining data to the beginning of the buffer
memmove(buffer, &buffer[handled_bytes], received_size - handled_bytes);
received_size -= handled_bytes;
}
}
int USBInBuffer::getReceived() const
{
return received_size;
}
void USBInBuffer::Callback(libusb_transfer *transfer)
{
if(cancelling || (transfer->status == LIBUSB_TRANSFER_CANCELLED)) {
// destructor called, do not resubmit
libusb_free_transfer(transfer);
this->transfer = nullptr;
cv.notify_all();
return;
}
switch(transfer->status) {
case LIBUSB_TRANSFER_COMPLETED:
received_size += transfer->actual_length;
inCallback = true;
emit DataReceived();
inCallback = false;
break;
case LIBUSB_TRANSFER_NO_DEVICE:
qCritical() << "LIBUSB_TRANSFER_NO_DEVICE";
libusb_free_transfer(transfer);
return;
case LIBUSB_TRANSFER_ERROR:
case LIBUSB_TRANSFER_OVERFLOW:
case LIBUSB_TRANSFER_STALL:
qCritical() << "LIBUSB_ERROR" << transfer->status;
libusb_free_transfer(transfer);
this->transfer = nullptr;
emit TransferError();
return;
break;
case LIBUSB_TRANSFER_TIMED_OUT:
// nothing to do
break;
case LIBUSB_TRANSFER_CANCELLED:
// already handled before switch-case
break;
}
// Resubmit the transfer
transfer->buffer = &buffer[received_size];
transfer->length = buffer_size - received_size;
libusb_submit_transfer(transfer);
}
void USBInBuffer::CallbackTrampoline(libusb_transfer *transfer)
{
auto usb = (USBInBuffer*) transfer->user_data;
usb->Callback(transfer);
}
uint8_t *USBInBuffer::getBuffer() const
{
return buffer;
}
LibreVNAUSBDriver::LibreVNAUSBDriver()
: LibreVNADriver()
{
connected = false;
m_handle = nullptr;
m_context = nullptr;
dataBuffer = nullptr;
logBuffer = nullptr;
m_receiveThread = nullptr;
}
QString LibreVNAUSBDriver::getDriverName()
{
return "LibreVNA/USB";
}
std::set<QString> LibreVNAUSBDriver::GetAvailableDevices()
{
std::set<QString> serials;
libusb_context *ctx;
libusb_init(&ctx);
#if LIBUSB_API_VERSION >= 0x01000106
libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_INFO);
#endif
SearchDevices([&serials](libusb_device_handle *, QString serial) -> bool {
serials.insert(serial);
return true;
}, ctx, true);
libusb_exit(ctx);
return serials;
}
bool LibreVNAUSBDriver::connectTo(QString serial)
{
if(connected) {
disconnect();
}
// info = defaultInfo;
// status = {};
m_handle = nullptr;
// infoValid = false;
libusb_init(&m_context);
#if LIBUSB_API_VERSION >= 0x01000106
libusb_set_option(m_context, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_INFO);
#endif
SearchDevices([=](libusb_device_handle *handle, QString found_serial) -> bool {
if(serial.isEmpty() || serial == found_serial) {
// accept connection to this device
this->serial = found_serial;
m_handle = handle;
// abort device search
return false;
} else {
// not the requested device, continue search
return true;
}
}, m_context, false);
if(!m_handle) {
QString message = "No device found";
InformationBox::ShowError("Error opening device", message);
libusb_exit(m_context);
throw std::runtime_error(message.toStdString());
}
// Found the correct device, now connect
/* claim the interface */
int ret = libusb_claim_interface(m_handle, 0);
if (ret < 0) {
libusb_close(m_handle);
/* Failed to open */
QString message = "Failed to claim interface: \"";
message.append(libusb_strerror((libusb_error) ret));
message.append("\" Maybe you are already connected to this device?");
qWarning() << message;
InformationBox::ShowError("Error opening device", message);
libusb_exit(m_context);
throw std::runtime_error(message.toStdString());
}
qInfo() << "USB connection established" << flush;
connected = true;
m_receiveThread = new std::thread(&LibreVNAUSBDriver::USBHandleThread, this);
dataBuffer = new USBInBuffer(m_handle, EP_Data_In_Addr, 65536);
logBuffer = new USBInBuffer(m_handle, EP_Log_In_Addr, 65536);
connect(dataBuffer, &USBInBuffer::DataReceived, this, &LibreVNAUSBDriver::ReceivedData, Qt::DirectConnection);
connect(dataBuffer, &USBInBuffer::TransferError, this, &LibreVNAUSBDriver::ConnectionLost);
connect(logBuffer, &USBInBuffer::DataReceived, this, &LibreVNAUSBDriver::ReceivedLog, Qt::DirectConnection);
connect(&transmissionTimer, &QTimer::timeout, this, &LibreVNAUSBDriver::transmissionTimeout);
connect(this, &LibreVNAUSBDriver::receivedAnswer, this, &LibreVNAUSBDriver::transmissionFinished, Qt::QueuedConnection);
connect(this, &LibreVNAUSBDriver::receivedPacket, this, &LibreVNAUSBDriver::handleReceivedPacket, Qt::QueuedConnection);
transmissionTimer.setSingleShot(true);
transmissionActive = false;
sendWithoutPayload(Protocol::PacketType::RequestDeviceInfo);
sendWithoutPayload(Protocol::PacketType::RequestDeviceStatus);
return true;
}
void LibreVNAUSBDriver::disconnect()
{
if(connected) {
setIdle();
delete dataBuffer;
delete logBuffer;
connected = false;
serial = "";
for (int if_num = 0; if_num < 1; if_num++) {
int ret = libusb_release_interface(m_handle, if_num);
if (ret < 0) {
qCritical() << "Error releasing interface" << libusb_error_name(ret);
}
}
libusb_release_interface(m_handle, 0);
libusb_close(m_handle);
m_receiveThread->join();
libusb_exit(m_context);
delete m_receiveThread;
m_handle = nullptr;
m_context = nullptr;
m_receiveThread = nullptr;
dataBuffer = nullptr;
logBuffer = nullptr;
}
}
void LibreVNAUSBDriver::ReceivedData()
{
Protocol::PacketInfo packet;
uint16_t handled_len;
// qDebug() << "Received data";
do {
// qDebug() << "Decoding" << dataBuffer->getReceived() << "Bytes";
handled_len = Protocol::DecodeBuffer(dataBuffer->getBuffer(), dataBuffer->getReceived(), &packet);
// qDebug() << "Handled" << handled_len << "Bytes, type:" << (int) packet.type;
if(handled_len > 0) {
auto &log = DeviceUSBLog::getInstance();
if(packet.type != Protocol::PacketType::None) {
log.addPacket(packet, serial);
} else {
log.addInvalidBytes(dataBuffer->getBuffer(), handled_len, serial);
}
}
dataBuffer->removeBytes(handled_len);
switch(packet.type) {
case Protocol::PacketType::Ack:
emit receivedAnswer(TransmissionResult::Ack);
break;
case Protocol::PacketType::Nack:
emit receivedAnswer(TransmissionResult::Nack);
break;
default:
// pass on to LibreVNADriver class
emit receivedPacket(packet);
break;
}
} while (handled_len > 0);
}
void LibreVNAUSBDriver::ReceivedLog()
{
uint16_t handled_len;
do {
handled_len = 0;
auto firstLinebreak = (uint8_t*) memchr(logBuffer->getBuffer(), '\n', logBuffer->getReceived());
if(firstLinebreak) {
handled_len = firstLinebreak - logBuffer->getBuffer();
auto line = QString::fromLatin1((const char*) logBuffer->getBuffer(), handled_len - 1);
emit LogLineReceived(line);
logBuffer->removeBytes(handled_len + 1);
}
} while(handled_len > 0);
}
void LibreVNAUSBDriver::transmissionFinished(LibreVNADriver::TransmissionResult result)
{
lock_guard<mutex> lock(transmissionMutex);
// remove transmitted packet
// qDebug() << "Transmission finsished (" << result << "), queue at " << transmissionQueue.size() << " Outstanding ACKs:"<<outstandingAckCount;
if(transmissionQueue.empty()) {
qWarning() << "transmissionFinished with empty transmission queue, stray Ack? Result:" << result;
return;
}
auto t = transmissionQueue.dequeue();
if(result == TransmissionResult::Timeout) {
qWarning() << "transmissionFinished with timeout, packettype:" << (int) t.packet.type << "Device:" << serial;
}
if(result == TransmissionResult::Nack) {
qWarning() << "transmissionFinished with NACK";
}
if(t.callback) {
t.callback(result);
}
transmissionTimer.stop();
bool success = false;
while(!transmissionQueue.isEmpty() && !success) {
success = startNextTransmission();
if(!success) {
// failed to send this packet
auto t = transmissionQueue.dequeue();
if(t.callback) {
t.callback(TransmissionResult::InternalError);
}
}
}
if(transmissionQueue.isEmpty()) {
transmissionActive = false;
}
}
bool LibreVNAUSBDriver::SendPacket(const Protocol::PacketInfo &packet, std::function<void (LibreVNADriver::TransmissionResult)> cb, unsigned int timeout)
{
Transmission t;
t.packet = packet;
t.timeout = timeout;
t.callback = cb;
lock_guard<mutex> lock(transmissionMutex);
transmissionQueue.enqueue(t);
// qDebug() << "Enqueued packet, queue at " << transmissionQueue.size();
if(!transmissionActive) {
startNextTransmission();
}
return true;
}
void LibreVNAUSBDriver::USBHandleThread()
{
qDebug() << "Receive thread started";
while (connected) {
libusb_handle_events(m_context);
}
qDebug() << "Disconnected, receive thread exiting";
}
void LibreVNAUSBDriver::SearchDevices(std::function<bool (libusb_device_handle *, QString)> foundCallback, libusb_context *context, bool ignoreOpenError)
{
libusb_device **devList;
auto ndevices = libusb_get_device_list(context, &devList);
for (ssize_t idx = 0; idx < ndevices; idx++) {
int ret;
libusb_device *device = devList[idx];
libusb_device_descriptor desc = {};
ret = libusb_get_device_descriptor(device, &desc);
if (ret) {
/* some error occured */
qCritical() << "Failed to get device descriptor: "
<< libusb_strerror((libusb_error) ret);
continue;
}
bool correctID = false;
int numIDs = sizeof(IDs)/sizeof(IDs[0]);
for(int i=0;i<numIDs;i++) {
if(desc.idVendor == IDs[i].VID && desc.idProduct == IDs[i].PID) {
correctID = true;
break;
}
}
if(!correctID) {
continue;
}
/* Try to open the device */
libusb_device_handle *handle = nullptr;
ret = libusb_open(device, &handle);
if (ret) {
qDebug() << libusb_strerror((enum libusb_error) ret);
/* Failed to open */
if(!ignoreOpenError) {
QString message = "Found potential device but failed to open usb connection: \"";
message.append(libusb_strerror((libusb_error) ret));
message.append("\" On Linux this is most likely caused by a missing udev rule. "
"On Windows this most likely means that you are already connected to "
"this device (is another instance of the application already runnning?)");
qWarning() << message;
InformationBox::ShowError("Error opening device", message);
}
continue;
}
char c_product[256];
char c_serial[256];
libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber,
(unsigned char*) c_serial, sizeof(c_serial));
ret = libusb_get_string_descriptor_ascii(handle, desc.iProduct,
(unsigned char*) c_product, sizeof(c_product));
if (ret > 0) {
/* managed to read the product string */
QString product(c_product);
if (product == "VNA") {
// this is a match
if(!foundCallback(handle, QString(c_serial))) {
// abort search
break;
}
}
} else {
qWarning() << "Failed to get product descriptor: "
<< libusb_strerror((libusb_error) ret);
}
libusb_close(handle);
}
libusb_free_device_list(devList, 1);
}

View File

@ -0,0 +1,113 @@
#ifndef LIBREVNAUSBDRIVER_H
#define LIBREVNAUSBDRIVER_H
#include "librevnadriver.h"
#include <libusb-1.0/libusb.h>
#include <condition_variable>
#include <thread>
#include <QQueue>
#include <QTimer>
class USBInBuffer : public QObject {
Q_OBJECT
public:
USBInBuffer(libusb_device_handle *handle, unsigned char endpoint, int buffer_size);
~USBInBuffer();
void removeBytes(int handled_bytes);
int getReceived() const;
uint8_t *getBuffer() const;
signals:
void DataReceived();
void TransferError();
private:
void Callback(libusb_transfer *transfer);
static void LIBUSB_CALL CallbackTrampoline(libusb_transfer *transfer);
libusb_transfer *transfer;
unsigned char *buffer;
int buffer_size;
int received_size;
bool inCallback;
bool cancelling;
std::condition_variable cv;
};
class LibreVNAUSBDriver : public LibreVNADriver
{
Q_OBJECT
public:
LibreVNAUSBDriver();
/**
* @brief Returns the driver name. It must be unique across all implemented drivers and is used to identify the driver
* @return driver name
*/
virtual QString getDriverName() override;
/**
* @brief Lists all available devices by their serial numbers
* @return Serial numbers of detected devices
*/
virtual std::set<QString> GetAvailableDevices() override;
/**
* @brief Connects to a device, given by its serial number
* @param serial Serial number of device that should be connected to
* @return true if connection successful, otherwise false
*/
virtual bool connectTo(QString serial) override;
/**
* @brief Disconnects from device. Has no effect if no device was connected
*/
virtual void disconnect() override;
private slots:
void ReceivedData();
void ReceivedLog();
void transmissionTimeout() {
transmissionFinished(TransmissionResult::Timeout);
}
void transmissionFinished(TransmissionResult result);
private:
static constexpr int EP_Data_Out_Addr = 0x01;
static constexpr int EP_Data_In_Addr = 0x81;
static constexpr int EP_Log_In_Addr = 0x82;
virtual bool SendPacket(const Protocol::PacketInfo& packet, std::function<void(TransmissionResult)> cb = nullptr, unsigned int timeout = 500) override;
void USBHandleThread();
// foundCallback is called for every device that is found. If it returns true the search continues, otherwise it is aborted.
// When the search is aborted the last found device is still opened
static void SearchDevices(std::function<bool(libusb_device_handle *handle, QString getSerial)> foundCallback, libusb_context *context, bool ignoreOpenError);
libusb_device_handle *m_handle;
libusb_context *m_context;
USBInBuffer *dataBuffer;
USBInBuffer *logBuffer;
class Transmission {
public:
Protocol::PacketInfo packet;
unsigned int timeout;
std::function<void(TransmissionResult)> callback;
};
std::mutex transmissionMutex;
QQueue<Transmission> transmissionQueue;
bool startNextTransmission();
QTimer transmissionTimer;
bool transmissionActive;
std::thread *m_receiveThread;
Protocol::DeviceInfo info;
bool infoValid;
union {
Protocol::DeviceStatusV1 v1;
} status;
std::mutex accessMutex;
};
#endif // LIBREVNAUSBDRIVER_H

View File

@ -98,7 +98,7 @@ void Generator::setupSCPI()
}));
add(new SCPICommand("PORT", [=](QStringList params) -> QString {
unsigned long long newval;
if(!SCPI::paramToULongLong(params, 0, newval) || newval > VirtualDevice::getInfo(window->getDevice()).ports) {
if(!SCPI::paramToULongLong(params, 0, newval) || newval > DeviceDriver::getInfo(window->getDevice()).Limits.Generator.ports) {
return SCPI::getResultName(SCPI::Result::Error);
} else {
central->setPort(newval);

View File

@ -33,16 +33,16 @@ SignalgeneratorWidget::SignalgeneratorWidget(AppWindow *window, QWidget *parent)
ui->steps->setPrecision(0);
connect(ui->frequency, &SIUnitEdit::valueChanged, [=](double newval) {
if(newval < VirtualDevice::getInfo(window->getDevice()).Limits.minFreq) {
newval = VirtualDevice::getInfo(window->getDevice()).Limits.minFreq;
} else if (newval > VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq) {
newval = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq;
if(newval < DeviceDriver::getInfo(window->getDevice()).Limits.Generator.minFreq) {
newval = DeviceDriver::getInfo(window->getDevice()).Limits.Generator.minFreq;
} else if (newval > DeviceDriver::getInfo(window->getDevice()).Limits.Generator.maxFreq) {
newval = DeviceDriver::getInfo(window->getDevice()).Limits.Generator.maxFreq;
}
ui->frequency->setValueQuiet(newval);
if (newval < ui->span->value()/2)
ui->span->setValueQuiet(newval/2);
if (newval + ui->span->value()/2 > VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq)
ui->span->setValueQuiet((VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq - newval)*2);
if (newval + ui->span->value()/2 > DeviceDriver::getInfo(window->getDevice()).Limits.Generator.maxFreq)
ui->span->setValueQuiet((DeviceDriver::getInfo(window->getDevice()).Limits.Generator.maxFreq - newval)*2);
newval = ui->frequency->value() - ui->span->value()/2;
ui->current->setValueQuiet(newval);
emit SettingsChanged();
@ -51,8 +51,8 @@ SignalgeneratorWidget::SignalgeneratorWidget(AppWindow *window, QWidget *parent)
connect(ui->span, &SIUnitEdit::valueChanged, [=](double newval) {
if(newval < 0 ) {
newval = 0;
} else if (newval > VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq - VirtualDevice::getInfo(window->getDevice()).Limits.minFreq) {
newval = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq - VirtualDevice::getInfo(window->getDevice()).Limits.minFreq;
} else if (newval > DeviceDriver::getInfo(window->getDevice()).Limits.Generator.maxFreq - DeviceDriver::getInfo(window->getDevice()).Limits.Generator.minFreq) {
newval = DeviceDriver::getInfo(window->getDevice()).Limits.Generator.maxFreq - DeviceDriver::getInfo(window->getDevice()).Limits.Generator.minFreq;
}
ui->span->setValueQuiet(newval);
@ -61,8 +61,8 @@ SignalgeneratorWidget::SignalgeneratorWidget(AppWindow *window, QWidget *parent)
ui->frequency->setValueQuiet(ui->span->value()/2);
}
newF = ui->frequency->value() + ui->span->value()/2;
if (newF > VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq) {
ui->frequency->setValueQuiet(VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq - ui->span->value()/2);
if (newF > DeviceDriver::getInfo(window->getDevice()).Limits.Generator.maxFreq) {
ui->frequency->setValueQuiet(DeviceDriver::getInfo(window->getDevice()).Limits.Generator.maxFreq - ui->span->value()/2);
}
newval = ui->frequency->value() - ui->span->value()/2;
@ -73,8 +73,8 @@ SignalgeneratorWidget::SignalgeneratorWidget(AppWindow *window, QWidget *parent)
connect(ui->current, &SIUnitEdit::valueChanged, [=](double newval) {
if(newval < 0 ) {
newval = 0;
} else if (newval > VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq - VirtualDevice::getInfo(window->getDevice()).Limits.minFreq) {
newval = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq - VirtualDevice::getInfo(window->getDevice()).Limits.minFreq;
} else if (newval > DeviceDriver::getInfo(window->getDevice()).Limits.Generator.maxFreq - DeviceDriver::getInfo(window->getDevice()).Limits.Generator.minFreq) {
newval = DeviceDriver::getInfo(window->getDevice()).Limits.Generator.maxFreq - DeviceDriver::getInfo(window->getDevice()).Limits.Generator.minFreq;
}
ui->current->setValueQuiet(newval);
emit SettingsChanged();
@ -132,9 +132,9 @@ void SignalgeneratorWidget::timerEvent(QTimerEvent *event)
}
}
VirtualDevice::SGSettings SignalgeneratorWidget::getDeviceStatus()
DeviceDriver::SGSettings SignalgeneratorWidget::getDeviceStatus()
{
VirtualDevice::SGSettings s = {};
DeviceDriver::SGSettings s = {};
if (ui->EnabledSweep->isChecked())
s.freq = ui->current->value();
else
@ -189,7 +189,7 @@ void SignalgeneratorWidget::deviceInfoUpdated()
delete cb;
}
portCheckboxes.clear();
for(unsigned int i=1;i<=VirtualDevice::getInfo(window->getDevice()).ports;i++) {
for(unsigned int i=1;i<=DeviceDriver::getInfo(window->getDevice()).Limits.Generator.ports;i++) {
auto cb = new QCheckBox("Port "+QString::number(i));
ui->portBox->layout()->addWidget(cb);
portCheckboxes.push_back(cb);

View File

@ -18,7 +18,7 @@ public:
explicit SignalgeneratorWidget(AppWindow *window, QWidget *parent = nullptr);
~SignalgeneratorWidget();
VirtualDevice::SGSettings getDeviceStatus();
DeviceDriver::SGSettings getDeviceStatus();
virtual nlohmann::json toJSON() override;
virtual void fromJSON(nlohmann::json j) override;

View File

@ -32,6 +32,7 @@ HEADERS += \
Device/deviceusblogview.h \
Device/firmwareupdatedialog.h \
Device/librevnadriver.h \
Device/librevnausbdriver.h \
Device/manualcontroldialog.h \
Device/virtualdevice.h \
Generator/generator.h \
@ -176,11 +177,13 @@ SOURCES += \
Device/compounddevice.cpp \
Device/compounddeviceeditdialog.cpp \
Device/device.cpp \
Device/devicedriver.cpp \
Device/devicelog.cpp \
Device/deviceusblog.cpp \
Device/deviceusblogview.cpp \
Device/firmwareupdatedialog.cpp \
Device/librevnadriver.cpp \
Device/librevnausbdriver.cpp \
Device/manualcontroldialog.cpp \
Device/virtualdevice.cpp \
Generator/generator.cpp \

View File

@ -13,7 +13,6 @@
#include "Traces/Marker/markerwidget.h"
#include "Tools/impedancematchdialog.h"
#include "ui_main.h"
#include "Device/virtualdevice.h"
#include "preferences.h"
#include "Generator/signalgenwidget.h"
@ -191,7 +190,7 @@ SpectrumAnalyzer::SpectrumAnalyzer(AppWindow *window, QString name)
cbWindowType->addItem("Flat Top");
cbWindowType->setCurrentIndex(1);
connect(cbWindowType, qOverload<int>(&QComboBox::currentIndexChanged), [=](int index) {
SetWindow((VirtualDevice::SASettings::Window) index);
SetWindow((DeviceDriver::SASettings::Window) index);
});
tb_acq->addWidget(cbWindowType);
@ -204,7 +203,7 @@ SpectrumAnalyzer::SpectrumAnalyzer(AppWindow *window, QString name)
cbDetector->addItem("Average");
cbDetector->setCurrentIndex(0);
connect(cbDetector, qOverload<int>(&QComboBox::currentIndexChanged), [=](int index) {
SetDetector((VirtualDevice::SASettings::Detector) index);
SetDetector((DeviceDriver::SASettings::Detector) index);
});
tb_acq->addWidget(cbDetector);
@ -219,10 +218,6 @@ SpectrumAnalyzer::SpectrumAnalyzer(AppWindow *window, QString name)
connect(this, &SpectrumAnalyzer::averagingChanged, sbAverages, &QSpinBox::setValue);
tb_acq->addWidget(sbAverages);
cbSignalID = new QCheckBox("Signal ID");
connect(cbSignalID, &QCheckBox::toggled, this, &SpectrumAnalyzer::SetSignalID);
tb_acq->addWidget(cbSignalID);
window->addToolBar(tb_acq);
toolbars.insert(tb_acq);
@ -321,10 +316,8 @@ SpectrumAnalyzer::SpectrumAnalyzer(AppWindow *window, QString name)
ConstrainAndUpdateFrequencies();
SetRBW(pref.Startup.SA.RBW);
SetAveraging(pref.Startup.SA.averaging);
settings.points = 1001;
SetWindow((VirtualDevice::SASettings::Window) pref.Startup.SA.window);
SetDetector((VirtualDevice::SASettings::Detector) pref.Startup.SA.detector);
SetSignalID(pref.Startup.SA.signalID);
SetWindow((DeviceDriver::SASettings::Window) pref.Startup.SA.window);
SetDetector((DeviceDriver::SASettings::Detector) pref.Startup.SA.detector);
}
finalize(central);
@ -338,7 +331,7 @@ void SpectrumAnalyzer::deactivate()
void SpectrumAnalyzer::initializeDevice()
{
connect(window->getDevice(), &VirtualDevice::SAmeasurementReceived, this, &SpectrumAnalyzer::NewDatapoint, Qt::UniqueConnection);
connect(window->getDevice(), &DeviceDriver::SAmeasurementReceived, this, &SpectrumAnalyzer::NewDatapoint, Qt::UniqueConnection);
// Configure initial state of device
SettingsChanged();
@ -361,9 +354,8 @@ nlohmann::json SpectrumAnalyzer::toJSON()
sweep["single"] = singleSweep;
nlohmann::json acq;
acq["RBW"] = settings.RBW;
acq["window"] = WindowToString((VirtualDevice::SASettings::Window) settings.window).toStdString();
acq["detector"] = DetectorToString((VirtualDevice::SASettings::Detector) settings.detector).toStdString();
acq["signal ID"] = settings.signalID ? true : false;
acq["window"] = WindowToString((DeviceDriver::SASettings::Window) settings.window).toStdString();
acq["detector"] = DetectorToString((DeviceDriver::SASettings::Detector) settings.detector).toStdString();
sweep["acquisition"] = acq;
nlohmann::json tracking;
tracking["enabled"] = settings.trackingGenerator ? true : false;
@ -419,18 +411,17 @@ void SpectrumAnalyzer::fromJSON(nlohmann::json j)
auto acq = sweep["acquisition"];
SetRBW(acq.value("RBW", settings.RBW));
auto w = WindowFromString(QString::fromStdString(acq.value("window", "")));
if(w == VirtualDevice::SASettings::Window::Last) {
if(w == DeviceDriver::SASettings::Window::Last) {
// invalid, keep current value
w = (VirtualDevice::SASettings::Window) settings.window;
w = (DeviceDriver::SASettings::Window) settings.window;
}
SetWindow(w);
auto d = DetectorFromString(QString::fromStdString(acq.value("detector", "")));
if(d == VirtualDevice::SASettings::Detector::Last) {
if(d == DeviceDriver::SASettings::Detector::Last) {
// invalid, keep current value
d = (VirtualDevice::SASettings::Detector) settings.detector;
d = (DeviceDriver::SASettings::Detector) settings.detector;
}
SetDetector(d);
SetSignalID(acq.value("signal ID", settings.signalID ? true : false));
}
if(sweep.contains("trackingGenerator")) {
auto tracking = sweep["trackingGenerator"];
@ -473,8 +464,8 @@ void SpectrumAnalyzer::fromJSON(nlohmann::json j)
using namespace std;
void SpectrumAnalyzer::NewDatapoint(VirtualDevice::SAMeasurement m)
{
void SpectrumAnalyzer::NewDatapoint(DeviceDriver::SAMeasurement m)
{
if(isActive != true) {
return;
}
@ -488,11 +479,6 @@ void SpectrumAnalyzer::NewDatapoint(VirtualDevice::SAMeasurement m)
Stop();
}
if(m.pointNum >= settings.points) {
qWarning() << "Ignoring point with too large point number (" << m.pointNum << ")";
return;
}
auto m_avg = average.process(m);
if(settings.freqStart == settings.freqStop) {
@ -513,18 +499,18 @@ void SpectrumAnalyzer::NewDatapoint(VirtualDevice::SAMeasurement m)
for(auto m : m_avg.measurements) {
normalize.portCorrection[m.first].push_back(m.second);
}
if(m_avg.pointNum == settings.points - 1) {
if(m_avg.pointNum == DeviceDriver::getActiveDriver()->getSApoints() - 1) {
// this was the last point
normalize.measuring = false;
normalize.f_start = settings.freqStart;
normalize.f_stop = settings.freqStop;
normalize.points = settings.points;
normalize.points = DeviceDriver::getActiveDriver()->getSApoints();
EnableNormalization(true);
qDebug() << "Normalization measurement complete";
}
}
}
int percentage = (((average.currentSweep() - 1) * 100) + (m_avg.pointNum + 1) * 100 / settings.points) / averages;
int percentage = (((average.currentSweep() - 1) * 100) + (m_avg.pointNum + 1) * 100 / DeviceDriver::getActiveDriver()->getSApoints()) / averages;
normalize.dialog.setValue(percentage);
}
@ -538,7 +524,7 @@ void SpectrumAnalyzer::NewDatapoint(VirtualDevice::SAMeasurement m)
traceModel.addSAData(m_avg, settings);
emit dataChanged();
if(m_avg.pointNum == settings.points - 1) {
if(m_avg.pointNum == DeviceDriver::getActiveDriver()->getSApoints() - 1) {
UpdateAverageCount();
markerModel->updateMarkers();
}
@ -576,14 +562,14 @@ void SpectrumAnalyzer::SetStopFreq(double freq)
void SpectrumAnalyzer::SetCenterFreq(double freq)
{
auto old_span = settings.freqStop - settings.freqStart;
if (freq - old_span / 2 <= VirtualDevice::getInfo(window->getDevice()).Limits.minFreq) {
if (freq - old_span / 2 <= DeviceDriver::getInfo(window->getDevice()).Limits.SA.minFreq) {
// would shift start frequency below minimum
settings.freqStart = 0;
settings.freqStop = 2 * freq;
} else if(freq + old_span / 2 >= VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq) {
} else if(freq + old_span / 2 >= DeviceDriver::getInfo(window->getDevice()).Limits.SA.maxFreq) {
// would shift stop frequency above maximum
settings.freqStart = 2 * freq - VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq;
settings.freqStop = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq;
settings.freqStart = 2 * freq - DeviceDriver::getInfo(window->getDevice()).Limits.SA.maxFreq;
settings.freqStop = DeviceDriver::getInfo(window->getDevice()).Limits.SA.maxFreq;
} else {
settings.freqStart = freq - old_span / 2;
settings.freqStop = freq + old_span / 2;
@ -594,14 +580,14 @@ void SpectrumAnalyzer::SetCenterFreq(double freq)
void SpectrumAnalyzer::SetSpan(double span)
{
auto old_center = (settings.freqStart + settings.freqStop) / 2;
if(old_center < VirtualDevice::getInfo(window->getDevice()).Limits.minFreq + span / 2) {
if(old_center < DeviceDriver::getInfo(window->getDevice()).Limits.SA.minFreq + span / 2) {
// would shift start frequency below minimum
settings.freqStart = VirtualDevice::getInfo(window->getDevice()).Limits.minFreq;
settings.freqStop = VirtualDevice::getInfo(window->getDevice()).Limits.minFreq + span;
} else if(old_center > VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq - span / 2) {
settings.freqStart = DeviceDriver::getInfo(window->getDevice()).Limits.SA.minFreq;
settings.freqStop = DeviceDriver::getInfo(window->getDevice()).Limits.SA.minFreq + span;
} else if(old_center > DeviceDriver::getInfo(window->getDevice()).Limits.SA.maxFreq - span / 2) {
// would shift stop frequency above maximum
settings.freqStart = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq - span;
settings.freqStop = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq;
settings.freqStart = DeviceDriver::getInfo(window->getDevice()).Limits.SA.maxFreq - span;
settings.freqStop = DeviceDriver::getInfo(window->getDevice()).Limits.SA.maxFreq;
} else {
settings.freqStart = old_center - span / 2;
settings.freqStop = settings.freqStart + span;
@ -616,8 +602,8 @@ void SpectrumAnalyzer::SetFullSpan()
settings.freqStart = pref.Acquisition.fullSpanStart;
settings.freqStop = pref.Acquisition.fullSpanStop;
} else {
settings.freqStart = VirtualDevice::getInfo(window->getDevice()).Limits.minFreq;
settings.freqStop = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq;
settings.freqStart = DeviceDriver::getInfo(window->getDevice()).Limits.SA.minFreq;
settings.freqStop = DeviceDriver::getInfo(window->getDevice()).Limits.SA.maxFreq;
}
ConstrainAndUpdateFrequencies();
}
@ -664,24 +650,24 @@ void SpectrumAnalyzer::SetSingleSweep(bool single)
void SpectrumAnalyzer::SetRBW(double bandwidth)
{
if(bandwidth > VirtualDevice::getInfo(window->getDevice()).Limits.maxRBW) {
bandwidth = VirtualDevice::getInfo(window->getDevice()).Limits.maxRBW;
} else if(bandwidth < VirtualDevice::getInfo(window->getDevice()).Limits.minRBW) {
bandwidth = VirtualDevice::getInfo(window->getDevice()).Limits.minRBW;
if(bandwidth > DeviceDriver::getInfo(window->getDevice()).Limits.SA.maxRBW) {
bandwidth = DeviceDriver::getInfo(window->getDevice()).Limits.SA.maxRBW;
} else if(bandwidth < DeviceDriver::getInfo(window->getDevice()).Limits.SA.minRBW) {
bandwidth = DeviceDriver::getInfo(window->getDevice()).Limits.SA.minRBW;
}
settings.RBW = bandwidth;
emit RBWChanged(settings.RBW);
SettingsChanged();
}
void SpectrumAnalyzer::SetWindow(VirtualDevice::SASettings::Window w)
void SpectrumAnalyzer::SetWindow(DeviceDriver::SASettings::Window w)
{
settings.window = w;
cbWindowType->setCurrentIndex((int) w);
SettingsChanged();
}
void SpectrumAnalyzer::SetDetector(VirtualDevice::SASettings::Detector d)
void SpectrumAnalyzer::SetDetector(DeviceDriver::SASettings::Detector d)
{
settings.detector = d;
cbDetector->setCurrentIndex((int) d);
@ -696,13 +682,6 @@ void SpectrumAnalyzer::SetAveraging(unsigned int averages)
SettingsChanged();
}
void SpectrumAnalyzer::SetSignalID(bool enabled)
{
settings.signalID = enabled ? 1 : 0;
cbSignalID->setChecked(enabled);
SettingsChanged();
}
void SpectrumAnalyzer::SetTGEnabled(bool enabled)
{
if(enabled != settings.trackingGenerator) {
@ -735,10 +714,10 @@ void SpectrumAnalyzer::SetTGPort(int port)
void SpectrumAnalyzer::SetTGLevel(double level)
{
if(level > VirtualDevice::getInfo(window->getDevice()).Limits.maxdBm) {
level = VirtualDevice::getInfo(window->getDevice()).Limits.maxdBm;
} else if(level < VirtualDevice::getInfo(window->getDevice()).Limits.mindBm) {
level = VirtualDevice::getInfo(window->getDevice()).Limits.mindBm;
if(level > DeviceDriver::getInfo(window->getDevice()).Limits.SA.maxdBm) {
level = DeviceDriver::getInfo(window->getDevice()).Limits.SA.maxdBm;
} else if(level < DeviceDriver::getInfo(window->getDevice()).Limits.SA.mindBm) {
level = DeviceDriver::getInfo(window->getDevice()).Limits.SA.mindBm;
}
emit TGLevelChanged(level);
settings.trackingPower = level * 100;
@ -842,51 +821,47 @@ void SpectrumAnalyzer::ConfigureDevice()
{
if(running) {
changingSettings = true;
if(settings.freqStop - settings.freqStart >= 1000 || settings.freqStop - settings.freqStart <= 0) {
settings.points = 1001;
} else {
settings.points = settings.freqStop - settings.freqStart + 1;
}
if(settings.trackingGenerator && settings.freqStop >= 25000000) {
// Check point spacing.
// The highband PLL used as the tracking generator is not able to reach every frequency exactly. This
// could lead to sharp drops in the spectrum at certain frequencies. If the span is wide enough with
// respect to the point number, it is ensured that every displayed point has at least one sample with
// a reachable PLL frequency in it. Display a warning message if this is not the case with the current
// settings.
auto pointSpacing = (settings.freqStop - settings.freqStart) / (settings.points - 1);
// The frequency resolution of the PLL is frequency dependent (due to PLL divider).
// This code assumes some knowledge of the actual hardware and probably should be moved
// onto the device at some point
double minSpacing = 25000;
auto stop = settings.freqStop;
while(stop <= 3000000000) {
minSpacing /= 2;
stop *= 2;
}
if(pointSpacing < minSpacing) {
auto requiredMinSpan = minSpacing * (settings.points - 1);
auto message = QString() + "Due to PLL limitations, the tracking generator can not reach every frequency exactly. "
"With your current span, this could result in the signal not being detected at some bands. A minimum"
" span of " + Unit::ToString(requiredMinSpan, "Hz", " kMG") + " is recommended at this stop frequency.";
InformationBox::ShowMessage("Warning", message, "TrackingGeneratorSpanTooSmallWarning");
}
}
if(normalize.active) {
// check if normalization is still valid
if(normalize.f_start != settings.freqStart || normalize.f_stop != settings.freqStop || normalize.points != settings.points) {
// normalization was taken at different settings, disable
EnableNormalization(false);
InformationBox::ShowMessage("Information", "Normalization was disabled because the span has been changed");
}
}
// TODO move into libreVNA driver
// if(settings.trackingGenerator && settings.freqStop >= 25000000) {
// // Check point spacing.
// // The highband PLL used as the tracking generator is not able to reach every frequency exactly. This
// // could lead to sharp drops in the spectrum at certain frequencies. If the span is wide enough with
// // respect to the point number, it is ensured that every displayed point has at least one sample with
// // a reachable PLL frequency in it. Display a warning message if this is not the case with the current
// // settings.
// auto pointSpacing = (settings.freqStop - settings.freqStart) / (settings.points - 1);
// // The frequency resolution of the PLL is frequency dependent (due to PLL divider).
// // This code assumes some knowledge of the actual hardware and probably should be moved
// // onto the device at some point
// double minSpacing = 25000;
// auto stop = settings.freqStop;
// while(stop <= 3000000000) {
// minSpacing /= 2;
// stop *= 2;
// }
// if(pointSpacing < minSpacing) {
// auto requiredMinSpan = minSpacing * (settings.points - 1);
// auto message = QString() + "Due to PLL limitations, the tracking generator can not reach every frequency exactly. "
// "With your current span, this could result in the signal not being detected at some bands. A minimum"
// " span of " + Unit::ToString(requiredMinSpan, "Hz", " kMG") + " is recommended at this stop frequency.";
// InformationBox::ShowMessage("Warning", message, "TrackingGeneratorSpanTooSmallWarning");
// }
// }
if(window->getDevice() && isActive) {
window->getDevice()->setSA(settings, [=](bool){
// device received command
changingSettings = false;
if(normalize.active) {
// check if normalization is still valid
if(normalize.f_start != settings.freqStart || normalize.f_stop != settings.freqStop || normalize.points != DeviceDriver::getActiveDriver()->getSApoints()) {
// normalization was taken at different settings, disable
EnableNormalization(false);
InformationBox::ShowMessage("Information", "Normalization was disabled because the span has been changed");
}
}
});
emit sweepStarted();
} else {
@ -894,7 +869,7 @@ void SpectrumAnalyzer::ConfigureDevice()
emit sweepStopped();
changingSettings = false;
}
average.reset(settings.points);
average.reset(DeviceDriver::getActiveDriver()->getSApoints());
UpdateAverageCount();
traceModel.clearLiveData();
emit traceModel.SpanChanged(settings.freqStart, settings.freqStop);
@ -915,7 +890,7 @@ void SpectrumAnalyzer::ConfigureDevice()
void SpectrumAnalyzer::ResetLiveTraces()
{
average.reset(settings.points);
average.reset(DeviceDriver::getActiveDriver()->getSApoints());
traceModel.clearLiveData();
UpdateAverageCount();
}
@ -996,23 +971,23 @@ void SpectrumAnalyzer::SetupSCPI()
return SCPI::getResultName(SCPI::Result::Error);
}
if (params[0] == "NONE") {
SetWindow(VirtualDevice::SASettings::Window::None);
SetWindow(DeviceDriver::SASettings::Window::None);
} else if(params[0] == "KAISER") {
SetWindow(VirtualDevice::SASettings::Window::Kaiser);
SetWindow(DeviceDriver::SASettings::Window::Kaiser);
} else if(params[0] == "HANN") {
SetWindow(VirtualDevice::SASettings::Window::Hann);
SetWindow(DeviceDriver::SASettings::Window::Hann);
} else if(params[0] == "FLATTOP") {
SetWindow(VirtualDevice::SASettings::Window::FlatTop);
SetWindow(DeviceDriver::SASettings::Window::FlatTop);
} else {
return "INVALID WINDOW";
}
return SCPI::getResultName(SCPI::Result::Empty);
}, [=](QStringList) -> QString {
switch((VirtualDevice::SASettings::Window) settings.window) {
case VirtualDevice::SASettings::Window::None: return "NONE";
case VirtualDevice::SASettings::Window::Kaiser: return "KAISER";
case VirtualDevice::SASettings::Window::Hann: return "HANN";
case VirtualDevice::SASettings::Window::FlatTop: return "FLATTOP";
switch((DeviceDriver::SASettings::Window) settings.window) {
case DeviceDriver::SASettings::Window::None: return "NONE";
case DeviceDriver::SASettings::Window::Kaiser: return "KAISER";
case DeviceDriver::SASettings::Window::Hann: return "HANN";
case DeviceDriver::SASettings::Window::FlatTop: return "FLATTOP";
default: return SCPI::getResultName(SCPI::Result::Error);
}
}));
@ -1021,26 +996,26 @@ void SpectrumAnalyzer::SetupSCPI()
return SCPI::getResultName(SCPI::Result::Error);
}
if (params[0] == "+PEAK") {
SetDetector(VirtualDevice::SASettings::Detector::PPeak);
SetDetector(DeviceDriver::SASettings::Detector::PPeak);
} else if(params[0] == "-PEAK") {
SetDetector(VirtualDevice::SASettings::Detector::NPeak);
SetDetector(DeviceDriver::SASettings::Detector::NPeak);
} else if(params[0] == "NORMAL") {
SetDetector(VirtualDevice::SASettings::Detector::Normal);
SetDetector(DeviceDriver::SASettings::Detector::Normal);
} else if(params[0] == "SAMPLE") {
SetDetector(VirtualDevice::SASettings::Detector::Sample);
SetDetector(DeviceDriver::SASettings::Detector::Sample);
} else if(params[0] == "AVERAGE") {
SetDetector(VirtualDevice::SASettings::Detector::Average);
SetDetector(DeviceDriver::SASettings::Detector::Average);
} else {
return "INVALID MDOE";
}
return SCPI::getResultName(SCPI::Result::Empty);
}, [=](QStringList) -> QString {
switch((VirtualDevice::SASettings::Detector) settings.detector) {
case VirtualDevice::SASettings::Detector::PPeak: return "+PEAK";
case VirtualDevice::SASettings::Detector::NPeak: return "-PEAK";
case VirtualDevice::SASettings::Detector::Normal: return "NORMAL";
case VirtualDevice::SASettings::Detector::Sample: return "SAMPLE";
case VirtualDevice::SASettings::Detector::Average: return "AVERAGE";
switch((DeviceDriver::SASettings::Detector) settings.detector) {
case DeviceDriver::SASettings::Detector::PPeak: return "+PEAK";
case DeviceDriver::SASettings::Detector::NPeak: return "-PEAK";
case DeviceDriver::SASettings::Detector::Normal: return "NORMAL";
case DeviceDriver::SASettings::Detector::Sample: return "SAMPLE";
case DeviceDriver::SASettings::Detector::Average: return "AVERAGE";
default: return SCPI::getResultName(SCPI::Result::Error);
}
}));
@ -1064,21 +1039,6 @@ void SpectrumAnalyzer::SetupSCPI()
scpi_acq->add(new SCPICommand("LIMit", nullptr, [=](QStringList) -> QString {
return tiles->allLimitsPassing() ? "PASS" : "FAIL";
}));
scpi_acq->add(new SCPICommand("SIGid", [=](QStringList params) -> QString {
if (params.size() != 1) {
return SCPI::getResultName(SCPI::Result::Error);
}
if(params[0] == "1" || params[0] == "TRUE") {
SetSignalID(true);
} else if(params[0] == "0" || params[0] == "FALSE") {
SetSignalID(false);
} else {
return SCPI::getResultName(SCPI::Result::Error);
}
return SCPI::getResultName(SCPI::Result::Empty);
}, [=](QStringList) -> QString {
return settings.signalID ? SCPI::getResultName(SCPI::Result::True) : SCPI::getResultName(SCPI::Result::False);
}));
scpi_acq->add(new SCPICommand("SINGLE", [=](QStringList params) -> QString {
bool single;
if(!SCPI::paramToBool(params, 0, single)) {
@ -1124,7 +1084,7 @@ void SpectrumAnalyzer::SetupSCPI()
unsigned long long newval;
if(!SCPI::paramToULongLong(params, 0, newval)) {
return SCPI::getResultName(SCPI::Result::Error);
} else if(newval > 0 && newval <= VirtualDevice::getInfo(window->getDevice()).ports){
} else if(newval > 0 && newval <= DeviceDriver::getInfo(window->getDevice()).Limits.SA.ports){
SetTGPort(newval-1);
return SCPI::getResultName(SCPI::Result::Empty);
} else {
@ -1200,24 +1160,24 @@ void SpectrumAnalyzer::UpdateAverageCount()
void SpectrumAnalyzer::ConstrainAndUpdateFrequencies()
{
if(settings.freqStop > VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq) {
settings.freqStop = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq;
if(settings.freqStop > DeviceDriver::getInfo(window->getDevice()).Limits.SA.maxFreq) {
settings.freqStop = DeviceDriver::getInfo(window->getDevice()).Limits.SA.maxFreq;
}
if(settings.freqStart > settings.freqStop) {
settings.freqStart = settings.freqStop;
}
if(settings.freqStart < VirtualDevice::getInfo(window->getDevice()).Limits.minFreq) {
settings.freqStart = VirtualDevice::getInfo(window->getDevice()).Limits.minFreq;
if(settings.freqStart < DeviceDriver::getInfo(window->getDevice()).Limits.SA.minFreq) {
settings.freqStart = DeviceDriver::getInfo(window->getDevice()).Limits.SA.minFreq;
}
bool trackingOffset_limited = false;
if(settings.freqStop + settings.trackingOffset > VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq) {
if(settings.freqStop + settings.trackingOffset > DeviceDriver::getInfo(window->getDevice()).Limits.SA.maxFreq) {
trackingOffset_limited = true;
settings.trackingOffset = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq - settings.freqStop;
settings.trackingOffset = DeviceDriver::getInfo(window->getDevice()).Limits.SA.maxFreq - settings.freqStop;
}
if(settings.freqStart + settings.trackingOffset < VirtualDevice::getInfo(window->getDevice()).Limits.minFreq) {
if(settings.freqStart + settings.trackingOffset < DeviceDriver::getInfo(window->getDevice()).Limits.SA.minFreq) {
trackingOffset_limited = true;
settings.trackingOffset = VirtualDevice::getInfo(window->getDevice()).Limits.minFreq - settings.freqStart;
settings.trackingOffset = DeviceDriver::getInfo(window->getDevice()).Limits.SA.minFreq - settings.freqStart;
}
if(trackingOffset_limited) {
InformationBox::ShowMessage("Warning", "The selected tracking generator offset is not reachable for all frequencies with the current span. "
@ -1239,10 +1199,8 @@ void SpectrumAnalyzer::LoadSweepSettings()
settings.freqStop = s.value("SAStop", pref.Startup.SA.stop).toULongLong();
ConstrainAndUpdateFrequencies();
SetRBW(s.value("SARBW", pref.Startup.SA.RBW).toUInt());
settings.points = 1001;
SetWindow((VirtualDevice::SASettings::Window) s.value("SAWindow", pref.Startup.SA.window).toInt());
SetDetector((VirtualDevice::SASettings::Detector) s.value("SADetector", pref.Startup.SA.detector).toInt());
SetSignalID(s.value("SASignalID", pref.Startup.SA.signalID).toBool());
SetWindow((DeviceDriver::SASettings::Window) s.value("SAWindow", pref.Startup.SA.window).toInt());
SetDetector((DeviceDriver::SASettings::Detector) s.value("SADetector", pref.Startup.SA.detector).toInt());
SetAveraging(s.value("SAAveraging", pref.Startup.SA.averaging).toInt());
}
@ -1255,7 +1213,6 @@ void SpectrumAnalyzer::StoreSweepSettings()
s.setValue("SAWindow", (int) settings.window);
s.setValue("SADetector", (int) settings.detector);
s.setValue("SAAveraging", averages);
s.setValue("SASignalID", static_cast<bool>(settings.signalID));
}
void SpectrumAnalyzer::createDefaultTracesAndGraphs(int ports)
@ -1291,7 +1248,7 @@ void SpectrumAnalyzer::preset()
}
}
// Create default traces
createDefaultTracesAndGraphs(VirtualDevice::getInfo(window->getDevice()).ports);
createDefaultTracesAndGraphs(DeviceDriver::getInfo(window->getDevice()).Limits.SA.ports);
}
void SpectrumAnalyzer::deviceInfoUpdated()
@ -1300,53 +1257,53 @@ void SpectrumAnalyzer::deviceInfoUpdated()
ClearNormalization();
auto tgPort = cbTrackGenPort->currentIndex();
cbTrackGenPort->clear();
for(unsigned int i=0;i<VirtualDevice::getInfo(window->getDevice()).ports;i++) {
for(unsigned int i=0;i<DeviceDriver::getInfo(window->getDevice()).Limits.SA.ports;i++) {
cbTrackGenPort->addItem("Port "+QString::number(i+1));
}
SetTGPort(tgPort);
}
QString SpectrumAnalyzer::WindowToString(VirtualDevice::SASettings::Window w)
QString SpectrumAnalyzer::WindowToString(DeviceDriver::SASettings::Window w)
{
switch(w) {
case VirtualDevice::SASettings::Window::None: return "None";
case VirtualDevice::SASettings::Window::Kaiser: return "Kaiser";
case VirtualDevice::SASettings::Window::Hann: return "Hann";
case VirtualDevice::SASettings::Window::FlatTop: return "FlatTop";
case DeviceDriver::SASettings::Window::None: return "None";
case DeviceDriver::SASettings::Window::Kaiser: return "Kaiser";
case DeviceDriver::SASettings::Window::Hann: return "Hann";
case DeviceDriver::SASettings::Window::FlatTop: return "FlatTop";
default: return "Unknown";
}
}
VirtualDevice::SASettings::Window SpectrumAnalyzer::WindowFromString(QString s)
DeviceDriver::SASettings::Window SpectrumAnalyzer::WindowFromString(QString s)
{
for(int i=0;i<(int)VirtualDevice::SASettings::Window::Last;i++) {
if(WindowToString((VirtualDevice::SASettings::Window) i) == s) {
return (VirtualDevice::SASettings::Window) i;
for(int i=0;i<(int)DeviceDriver::SASettings::Window::Last;i++) {
if(WindowToString((DeviceDriver::SASettings::Window) i) == s) {
return (DeviceDriver::SASettings::Window) i;
}
}
// not found
return VirtualDevice::SASettings::Window::Last;
return DeviceDriver::SASettings::Window::Last;
}
QString SpectrumAnalyzer::DetectorToString(VirtualDevice::SASettings::Detector d)
QString SpectrumAnalyzer::DetectorToString(DeviceDriver::SASettings::Detector d)
{
switch(d) {
case VirtualDevice::SASettings::Detector::PPeak: return "+Peak";
case VirtualDevice::SASettings::Detector::NPeak: return "-Peak";
case VirtualDevice::SASettings::Detector::Sample: return "Sample";
case VirtualDevice::SASettings::Detector::Normal: return "Normal";
case VirtualDevice::SASettings::Detector::Average: return "Average";
case DeviceDriver::SASettings::Detector::PPeak: return "+Peak";
case DeviceDriver::SASettings::Detector::NPeak: return "-Peak";
case DeviceDriver::SASettings::Detector::Sample: return "Sample";
case DeviceDriver::SASettings::Detector::Normal: return "Normal";
case DeviceDriver::SASettings::Detector::Average: return "Average";
default: return "Unknown";
}
}
VirtualDevice::SASettings::Detector SpectrumAnalyzer::DetectorFromString(QString s)
DeviceDriver::SASettings::Detector SpectrumAnalyzer::DetectorFromString(QString s)
{
for(int i=0;i<(int)VirtualDevice::SASettings::Detector::Last;i++) {
if(DetectorToString((VirtualDevice::SASettings::Detector) i) == s) {
return (VirtualDevice::SASettings::Detector) i;
for(int i=0;i<(int)DeviceDriver::SASettings::Detector::Last;i++) {
if(DetectorToString((DeviceDriver::SASettings::Detector) i) == s) {
return (DeviceDriver::SASettings::Detector) i;
}
}
// not found
return VirtualDevice::SASettings::Detector::Last;
return DeviceDriver::SASettings::Detector::Last;
}

View File

@ -38,13 +38,13 @@ public:
virtual void deviceInfoUpdated() override;
private:
static QString WindowToString(VirtualDevice::SASettings::Window w);
static VirtualDevice::SASettings::Window WindowFromString(QString s);
static QString DetectorToString(VirtualDevice::SASettings::Detector d);
static VirtualDevice::SASettings::Detector DetectorFromString(QString s);
static QString WindowToString(DeviceDriver::SASettings::Window w);
static DeviceDriver::SASettings::Window WindowFromString(QString s);
static QString DetectorToString(DeviceDriver::SASettings::Detector d);
static DeviceDriver::SASettings::Detector DetectorFromString(QString s);
private slots:
void NewDatapoint(VirtualDevice::SAMeasurement m);
void NewDatapoint(DeviceDriver::SAMeasurement m);
// Sweep control
void SetStartFreq(double freq);
void SetStopFreq(double freq);
@ -57,10 +57,9 @@ private slots:
void SetSingleSweep(bool single);
// Acquisition control
void SetRBW(double bandwidth);
void SetWindow(VirtualDevice::SASettings::Window w);
void SetDetector(VirtualDevice::SASettings::Detector d);
void SetWindow(DeviceDriver::SASettings::Window w);
void SetDetector(DeviceDriver::SASettings::Detector d);
void SetAveraging(unsigned int averages);
void SetSignalID(bool enabled);
// TG control
void SetTGEnabled(bool enabled);
void SetTGPort(int port);
@ -87,7 +86,7 @@ private:
void createDefaultTracesAndGraphs(int ports);
VirtualDevice::SASettings settings;
DeviceDriver::SASettings settings;
bool changingSettings;
unsigned int averages;
bool singleSweep;

View File

@ -139,7 +139,7 @@ void Trace::addData(const Trace::Data& d, DataType domain, double reference_impe
emit outputSamplesChanged(index, index + 1);
}
void Trace::addData(const Trace::Data &d, const VirtualDevice::SASettings &s, int index)
void Trace::addData(const Trace::Data &d, const DeviceDriver::SASettings &s, int index)
{
settings.SA = s;
settings.valid = true;
@ -303,7 +303,7 @@ QString Trace::fillFromCSV(CSV &csv, unsigned int parameter)
return lastTraceName;
}
void Trace::fillFromDatapoints(std::map<QString, Trace *> traceSet, const std::vector<VirtualDevice::VNAMeasurement> &data, bool deembedded)
void Trace::fillFromDatapoints(std::map<QString, Trace *> traceSet, const std::vector<DeviceDriver::VNAMeasurement> &data, bool deembedded)
{
// remove all previous points
for(auto m : traceSet) {
@ -1001,9 +1001,9 @@ std::vector<Trace *> Trace::createFromCSV(CSV &csv)
return traces;
}
std::vector<VirtualDevice::VNAMeasurement> Trace::assembleDatapoints(std::map<QString, Trace *> traceSet)
std::vector<DeviceDriver::VNAMeasurement> Trace::assembleDatapoints(std::map<QString, Trace *> traceSet)
{
vector<VirtualDevice::VNAMeasurement> ret;
vector<DeviceDriver::VNAMeasurement> ret;
// Sanity check traces
unsigned int samples = traceSet.begin()->second->size();
@ -1041,7 +1041,7 @@ std::vector<VirtualDevice::VNAMeasurement> Trace::assembleDatapoints(std::map<QS
// Checks passed, assemble datapoints
for(unsigned int i=0;i<samples;i++) {
VirtualDevice::VNAMeasurement d;
DeviceDriver::VNAMeasurement d;
for(auto m : traceSet) {
QString measurement = m.first;
const Trace *t = m.second;

View File

@ -3,7 +3,7 @@
#include "touchstone.h"
#include "csv.h"
#include "Device/virtualdevice.h"
#include "Device/devicedriver.h"
#include "Math/tracemath.h"
#include "Tools/parameters.h"
@ -13,6 +13,7 @@
#include <QColor>
#include <set>
#include <QTime>
#include <QTimer>
class Marker;
class TraceModel;
@ -44,13 +45,13 @@ public:
void clear(bool force = false);
void addData(const Data& d, DataType domain, double reference_impedance = 50.0, int index = -1);
void addData(const Data& d, const VirtualDevice::SASettings &s, int index = -1);
void addData(const Data& d, const DeviceDriver::SASettings &s, int index = -1);
void addDeembeddingData(const Data& d, int index = -1);
void setName(QString name);
void setVelocityFactor(double v);
void fillFromTouchstone(Touchstone &t, unsigned int parameter);
QString fillFromCSV(CSV &csv, unsigned int parameter); // returns the suggested trace name (not yet set in member data)
static void fillFromDatapoints(std::map<QString, Trace*> traceSet, const std::vector<VirtualDevice::VNAMeasurement> &data, bool deembedded = false);
static void fillFromDatapoints(std::map<QString, Trace*> traceSet, const std::vector<DeviceDriver::VNAMeasurement> &data, bool deembedded = false);
void fromLivedata(LivedataType type, QString param);
void fromMath();
QString name() { return _name; }
@ -151,7 +152,7 @@ public:
// Assembles datapoints as received from the VNA from four S parameter traces. Requires that all traces are in the frequency domain,
// have the same number of samples and their samples must be at the same frequencies across all traces
static std::vector<VirtualDevice::VNAMeasurement> assembleDatapoints(std::map<QString, Trace *> traceSet);
static std::vector<DeviceDriver::VNAMeasurement> assembleDatapoints(std::map<QString, Trace *> traceSet);
static LivedataType TypeFromString(QString s);
static QString TypeToString(LivedataType t);
@ -275,7 +276,7 @@ private:
std::set<Marker*> markers;
struct {
union {
VirtualDevice::SASettings SA;
DeviceDriver::SASettings SA;
};
bool valid;
} settings;

View File

@ -475,16 +475,16 @@ double XAxis::sampleToCoordinate(Trace::Data data, Trace *t, unsigned int sample
void XAxis::set(Type type, bool log, bool autorange, double min, double max, double div)
{
if(max <= min) {
auto info = VirtualDevice::getInfo(VirtualDevice::getConnected());
auto info = DeviceDriver::getInfo(DeviceDriver::getActiveDriver());
// invalid selection, use default instead
switch(type) {
case Type::Frequency:
min = info.Limits.minFreq;
max = info.Limits.maxFreq;
min = info.Limits.VNA.minFreq;
max = info.Limits.VNA.maxFreq;
break;
case Type::Power:
min = info.Limits.mindBm;
max = info.Limits.maxdBm;
min = info.Limits.VNA.mindBm;
max = info.Limits.VNA.maxdBm;
break;
case Type::Time:
case Type::TimeZeroSpan:

View File

@ -280,7 +280,7 @@ void TraceModel::clearLiveData()
}
}
void TraceModel::addVNAData(const VirtualDevice::VNAMeasurement& d, TraceMath::DataType datatype, bool deembedded)
void TraceModel::addVNAData(const DeviceDriver::VNAMeasurement& d, TraceMath::DataType datatype, bool deembedded)
{
source = DataSource::VNA;
lastReceivedData = QDateTime::currentDateTimeUtc();
@ -319,7 +319,7 @@ void TraceModel::addVNAData(const VirtualDevice::VNAMeasurement& d, TraceMath::D
}
}
void TraceModel::addSAData(const VirtualDevice::SAMeasurement& d, const VirtualDevice::SASettings &settings)
void TraceModel::addSAData(const DeviceDriver::SAMeasurement& d, const DeviceDriver::SASettings &settings)
{
source = DataSource::SA;
lastReceivedData = QDateTime::currentDateTimeUtc();

View File

@ -1,7 +1,7 @@
#ifndef TRACEMODEL_H
#define TRACEMODEL_H
#include "Device/device.h"
#include "Device/devicedriver.h"
#include "savable.h"
#include "trace.h"
@ -71,8 +71,8 @@ signals:
public slots:
void clearLiveData();
void addVNAData(const VirtualDevice::VNAMeasurement& d, TraceMath::DataType datatype, bool deembedded);
void addSAData(const VirtualDevice::SAMeasurement &d, const VirtualDevice::SASettings &settings);
void addVNAData(const DeviceDriver::VNAMeasurement& d, TraceMath::DataType datatype, bool deembedded);
void addSAData(const DeviceDriver::SAMeasurement &d, const DeviceDriver::SASettings &settings);
private:
DataSource source;

View File

@ -126,7 +126,7 @@ Deembedding::Deembedding(TraceModel &tm)
}, nullptr));
}
void Deembedding::Deembed(VirtualDevice::VNAMeasurement &d)
void Deembedding::Deembed(DeviceDriver::VNAMeasurement &d)
{
// figure out the point in one sweep based on the incomig pointNums
static unsigned lastPointNum;

View File

@ -22,7 +22,7 @@ public:
Deembedding(TraceModel &tm);
~Deembedding(){}
void Deembed(VirtualDevice::VNAMeasurement &d);
void Deembed(DeviceDriver::VNAMeasurement &d);
void Deembed(std::map<QString, Trace*> traceSet);
void removeOption(unsigned int index);
@ -50,7 +50,7 @@ private:
TraceModel &tm;
bool measuring;
std::vector<VirtualDevice::VNAMeasurement> measurements;
std::vector<DeviceDriver::VNAMeasurement> measurements;
QDialog *measurementDialog;
Ui_DeembeddingMeasurementDialog *measurementUI;

View File

@ -2,7 +2,7 @@
#define DEEMBEDDINGOPTION_H
#include "savable.h"
#include "Device/device.h"
#include "Device/devicedriver.h"
#include "Traces/tracemodel.h"
#include "scpi.h"
@ -27,12 +27,12 @@ public:
static Type TypeFromString(QString string);
virtual std::set<unsigned int> getAffectedPorts() = 0;
virtual void transformDatapoint(VirtualDevice::VNAMeasurement &p) = 0;
virtual void transformDatapoint(DeviceDriver::VNAMeasurement &p) = 0;
virtual void edit(){}
virtual Type getType() = 0;
public slots:
virtual void measurementCompleted(std::vector<VirtualDevice::VNAMeasurement> m){Q_UNUSED(m)}
virtual void measurementCompleted(std::vector<DeviceDriver::VNAMeasurement> m){Q_UNUSED(m)}
signals:
// Deembedding option may selfdestruct if not applicable with current settings. It should emit this signal before deleting itself
void deleted(DeembeddingOption *option);

View File

@ -28,13 +28,13 @@ ImpedanceRenormalization::ImpedanceRenormalization()
std::set<unsigned int> ImpedanceRenormalization::getAffectedPorts()
{
set<unsigned int> ret;
for(unsigned int i=1;i<=VirtualDevice::getInfo(VirtualDevice::getConnected()).ports;i++) {
for(unsigned int i=1;i<=DeviceDriver::getInfo(DeviceDriver::getActiveDriver()).Limits.VNA.ports;i++) {
ret.insert(i);
}
return ret;
}
void ImpedanceRenormalization::transformDatapoint(VirtualDevice::VNAMeasurement &p)
void ImpedanceRenormalization::transformDatapoint(DeviceDriver::VNAMeasurement &p)
{
std::map<QString, std::complex<double>> transformed;
int ports = 0;

View File

@ -14,7 +14,7 @@ public:
ImpedanceRenormalization();
std::set<unsigned int> getAffectedPorts() override;
void transformDatapoint(VirtualDevice::VNAMeasurement &p) override;
void transformDatapoint(DeviceDriver::VNAMeasurement &p) override;
Type getType() override { return Type::ImpedanceRenormalization;}
nlohmann::json toJSON() override;
void fromJSON(nlohmann::json j) override;

View File

@ -78,7 +78,7 @@ std::set<unsigned int> MatchingNetwork::getAffectedPorts()
return {port};
}
void MatchingNetwork::transformDatapoint(VirtualDevice::VNAMeasurement &p)
void MatchingNetwork::transformDatapoint(DeviceDriver::VNAMeasurement &p)
{
if(matching.count(p.frequency) == 0) {
// this point is not calculated yet
@ -99,7 +99,7 @@ void MatchingNetwork::transformDatapoint(VirtualDevice::VNAMeasurement &p)
}
// at this point the map contains the matching network effect
auto m = matching[p.frequency];
VirtualDevice::VNAMeasurement uncorrected = p;
DeviceDriver::VNAMeasurement uncorrected = p;
auto portReflectionName = "S"+QString::number(port)+QString::number(port);
if(!uncorrected.measurements.count(portReflectionName)) {
@ -180,7 +180,7 @@ void MatchingNetwork::edit()
ui->lDefinedShunt->installEventFilter(this);
ui->port->setValue(port);
ui->port->setMaximum(VirtualDevice::maximumSupportedPorts);
ui->port->setMaximum(DeviceDriver::maximumSupportedPorts);
layout->setContentsMargins(0,0,0,0);
layout->setSpacing(0);

View File

@ -68,7 +68,7 @@ public:
// DeembeddingOption interface
public:
std::set<unsigned int> getAffectedPorts() override;
void transformDatapoint(VirtualDevice::VNAMeasurement &p) override;
void transformDatapoint(DeviceDriver::VNAMeasurement &p) override;
void edit() override;
Type getType() override {return Type::MatchingNetwork;}
nlohmann::json toJSON() override;

View File

@ -38,7 +38,7 @@ std::set<unsigned int> PortExtension::getAffectedPorts()
return {port};
}
void PortExtension::transformDatapoint(VirtualDevice::VNAMeasurement &d)
void PortExtension::transformDatapoint(DeviceDriver::VNAMeasurement &d)
{
auto phase = -2 * M_PI * ext.delay * d.frequency;
auto db_attennuation = ext.DCloss;
@ -88,7 +88,7 @@ void PortExtension::edit()
ui->Loss->setValue(ext.loss);
ui->Frequency->setValue(ext.frequency);
ui->port->setValue(port);
ui->port->setMaximum(VirtualDevice::maximumSupportedPorts);
ui->port->setMaximum(DeviceDriver::maximumSupportedPorts);
if(!kit) {
ui->calkit->setEnabled(false);
}
@ -138,7 +138,7 @@ void PortExtension::edit()
}
}
void PortExtension::measurementCompleted(std::vector<VirtualDevice::VNAMeasurement> m)
void PortExtension::measurementCompleted(std::vector<DeviceDriver::VNAMeasurement> m)
{
if(m.size() > 0) {
double last_phase = 0.0;

View File

@ -19,14 +19,14 @@ class PortExtension : public DeembeddingOption
public:
PortExtension();
std::set<unsigned int> getAffectedPorts() override;
void transformDatapoint(VirtualDevice::VNAMeasurement& d) override;
void transformDatapoint(DeviceDriver::VNAMeasurement& d) override;
void setCalkit(Calkit *kit);
Type getType() override {return Type::PortExtension;}
nlohmann::json toJSON() override;
void fromJSON(nlohmann::json j) override;
public slots:
void edit() override;
void measurementCompleted(std::vector<VirtualDevice::VNAMeasurement> m) override;
void measurementCompleted(std::vector<DeviceDriver::VNAMeasurement> m) override;
private:
void startMeasurement();

View File

@ -25,7 +25,7 @@ std::set<unsigned int> TwoThru::getAffectedPorts()
return {port1, port2};
}
void TwoThru::transformDatapoint(VirtualDevice::VNAMeasurement &p)
void TwoThru::transformDatapoint(DeviceDriver::VNAMeasurement &p)
{
// correct measurement
if(points.size() > 0) {
@ -109,7 +109,7 @@ void TwoThru::updateGUI()
}
}
void TwoThru::measurementCompleted(std::vector<VirtualDevice::VNAMeasurement> m)
void TwoThru::measurementCompleted(std::vector<DeviceDriver::VNAMeasurement> m)
{
if (measuring2xthru) {
measurements2xthru = m;
@ -136,9 +136,9 @@ void TwoThru::edit()
ui->lZ0->setVisible(false);
ui->port1->setValue(port1);
ui->port1->setMaximum(VirtualDevice::maximumSupportedPorts);
ui->port1->setMaximum(DeviceDriver::maximumSupportedPorts);
ui->port2->setValue(port2);
ui->port2->setMaximum(VirtualDevice::maximumSupportedPorts);
ui->port2->setMaximum(DeviceDriver::maximumSupportedPorts);
auto portChanged = [=](){
port1 = ui->port1->value();
@ -261,7 +261,7 @@ void TwoThru::fromJSON(nlohmann::json j)
}
}
std::vector<TwoThru::Point> TwoThru::calculateErrorBoxes(std::vector<VirtualDevice::VNAMeasurement> data_2xthru)
std::vector<TwoThru::Point> TwoThru::calculateErrorBoxes(std::vector<DeviceDriver::VNAMeasurement> data_2xthru)
{
// calculate error boxes, see https://www.freelists.org/post/si-list/IEEE-P370-Opensource-Deembedding-MATLAB-functions
// create vectors of S parameters
@ -442,7 +442,7 @@ std::vector<TwoThru::Point> TwoThru::calculateErrorBoxes(std::vector<VirtualDevi
return ret;
}
std::vector<TwoThru::Point> TwoThru::calculateErrorBoxes(std::vector<VirtualDevice::VNAMeasurement> data_2xthru, std::vector<VirtualDevice::VNAMeasurement> data_fix_dut_fix, double z0)
std::vector<TwoThru::Point> TwoThru::calculateErrorBoxes(std::vector<DeviceDriver::VNAMeasurement> data_2xthru, std::vector<DeviceDriver::VNAMeasurement> data_fix_dut_fix, double z0)
{
vector<Point> ret;
@ -715,9 +715,9 @@ std::vector<TwoThru::Point> TwoThru::calculateErrorBoxes(std::vector<VirtualDevi
return ret;
}
std::vector<VirtualDevice::VNAMeasurement> TwoThru::interpolateEvenFrequencySteps(std::vector<VirtualDevice::VNAMeasurement> input)
std::vector<DeviceDriver::VNAMeasurement> TwoThru::interpolateEvenFrequencySteps(std::vector<DeviceDriver::VNAMeasurement> input)
{
vector<VirtualDevice::VNAMeasurement> ret;
vector<DeviceDriver::VNAMeasurement> ret;
if(input.size() > 1) {
int size = input.size();
double freqStep = 0.0;
@ -739,8 +739,8 @@ std::vector<VirtualDevice::VNAMeasurement> TwoThru::interpolateEvenFrequencyStep
// needs to interpolate
double freq = freqStep;
while(freq <= input.back().frequency) {
VirtualDevice::VNAMeasurement interp;
auto it = lower_bound(input.begin(), input.end(), freq, [](const VirtualDevice::VNAMeasurement &lhs, const double f) -> bool {
DeviceDriver::VNAMeasurement interp;
auto it = lower_bound(input.begin(), input.end(), freq, [](const DeviceDriver::VNAMeasurement &lhs, const double f) -> bool {
return lhs.frequency < f;
});
if(it->frequency == freq) {

View File

@ -17,7 +17,7 @@ public:
TwoThru();
std::set<unsigned int> getAffectedPorts() override;
virtual void transformDatapoint(VirtualDevice::VNAMeasurement& p) override;
virtual void transformDatapoint(DeviceDriver::VNAMeasurement& p) override;
virtual void edit() override;
virtual Type getType() override {return DeembeddingOption::Type::TwoThru;}
nlohmann::json toJSON() override;
@ -26,19 +26,19 @@ public:
private slots:
void startMeasurement();
void updateGUI();
void measurementCompleted(std::vector<VirtualDevice::VNAMeasurement> m) override;
void measurementCompleted(std::vector<DeviceDriver::VNAMeasurement> m) override;
private:
using Point = struct {
double freq;
Tparam inverseP1, inverseP2;
};
static std::vector<VirtualDevice::VNAMeasurement> interpolateEvenFrequencySteps(std::vector<VirtualDevice::VNAMeasurement> input);
std::vector<Point> calculateErrorBoxes(std::vector<VirtualDevice::VNAMeasurement> data_2xthru);
std::vector<Point> calculateErrorBoxes(std::vector<VirtualDevice::VNAMeasurement> data_2xthru, std::vector<VirtualDevice::VNAMeasurement> data_fix_dut_fix, double z0);
static std::vector<DeviceDriver::VNAMeasurement> interpolateEvenFrequencySteps(std::vector<DeviceDriver::VNAMeasurement> input);
std::vector<Point> calculateErrorBoxes(std::vector<DeviceDriver::VNAMeasurement> data_2xthru);
std::vector<Point> calculateErrorBoxes(std::vector<DeviceDriver::VNAMeasurement> data_2xthru, std::vector<DeviceDriver::VNAMeasurement> data_fix_dut_fix, double z0);
std::vector<VirtualDevice::VNAMeasurement> measurements2xthru;
std::vector<VirtualDevice::VNAMeasurement> measurementsDUT;
std::vector<DeviceDriver::VNAMeasurement> measurements2xthru;
std::vector<DeviceDriver::VNAMeasurement> measurementsDUT;
double Z0;
unsigned int port1, port2;
std::vector<Point> points;

View File

@ -97,7 +97,7 @@ VNA::VNA(AppWindow *window, QString name)
connect(calLoad, &QAction::triggered, [=](){
LoadCalibration();
if(window->getDevice() && !cal.validForDevice(window->getDevice()->serial())) {
if(window->getDevice() && !cal.validForDevice(window->getDevice()->getSerial())) {
InformationBox::ShowMessage("Invalid calibration", "The selected calibration was created for a different device. You can still load it but the resulting "
"data likely isn't useful.");
}
@ -213,7 +213,7 @@ VNA::VNA(AppWindow *window, QString name)
connect(assignDefaultCal, &QAction::triggered, [=](){
if(window->getDevice()) {
auto key = "DefaultCalibration"+window->getDevice()->serial();
auto key = "DefaultCalibration"+window->getDevice()->getSerial();
QSettings settings;
auto filename = QFileDialog::getOpenFileName(nullptr, "Load calibration data", settings.value(key).toString(), "Calibration files (*.cal)", nullptr, QFileDialog::DontUseNativeDialog);
if(!filename.isEmpty()) {
@ -225,7 +225,7 @@ VNA::VNA(AppWindow *window, QString name)
});
connect(removeDefaultCal, &QAction::triggered, [=](){
QSettings settings;
settings.remove("DefaultCalibration"+window->getDevice()->serial());
settings.remove("DefaultCalibration"+window->getDevice()->getSerial());
removeDefaultCal->setEnabled(false);
});
@ -678,10 +678,10 @@ void VNA::deactivate()
void VNA::initializeDevice()
{
defaultCalMenu->setEnabled(true);
connect(window->getDevice(), &VirtualDevice::VNAmeasurementReceived, this, &VNA::NewDatapoint, Qt::UniqueConnection);
connect(window->getDevice(), &DeviceDriver::VNAmeasurementReceived, this, &VNA::NewDatapoint, Qt::UniqueConnection);
// Check if default calibration exists and attempt to load it
QSettings s;
auto key = "DefaultCalibration"+window->getDevice()->serial();
auto key = "DefaultCalibration"+window->getDevice()->getSerial();
if (s.contains(key)) {
auto filename = s.value(key).toString();
qDebug() << "Attempting to load default calibration file " << filename;
@ -702,7 +702,7 @@ void VNA::initializeDevice()
// Configure initial state of device
SettingsChanged();
emit deviceInitialized();
if(window->getDevice() && !cal.validForDevice(window->getDevice()->serial())) {
if(window->getDevice() && !cal.validForDevice(window->getDevice()->getSerial())) {
InformationBox::ShowMessage("Invalid calibration", "The current calibration was created for a different device. You can still use it but the resulting "
"data likely isn't useful.");
}
@ -806,7 +806,7 @@ void VNA::fromJSON(nlohmann::json j)
using namespace std;
void VNA::NewDatapoint(VirtualDevice::VNAMeasurement m)
void VNA::NewDatapoint(DeviceDriver::VNAMeasurement m)
{
if(isActive != true) {
// ignore
@ -979,14 +979,14 @@ void VNA::SetStopFreq(double freq)
void VNA::SetCenterFreq(double freq)
{
auto old_span = settings.Freq.stop - settings.Freq.start;
if (freq - old_span / 2 <= VirtualDevice::getInfo(window->getDevice()).Limits.minFreq) {
if (freq - old_span / 2 <= DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minFreq) {
// would shift start frequency below minimum
settings.Freq.start = 0;
settings.Freq.stop = 2 * freq;
} else if(freq + old_span / 2 >= VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq) {
} else if(freq + old_span / 2 >= DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxFreq) {
// would shift stop frequency above maximum
settings.Freq.start = 2 * freq - VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq;
settings.Freq.stop = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq;
settings.Freq.start = 2 * freq - DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxFreq;
settings.Freq.stop = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxFreq;
} else {
settings.Freq.start = freq - old_span / 2;
settings.Freq.stop = freq + old_span / 2;
@ -996,12 +996,12 @@ void VNA::SetCenterFreq(double freq)
void VNA::SetSpan(double span)
{
auto maxFreq = Preferences::getInstance().Acquisition.harmonicMixing ? VirtualDevice::getInfo(window->getDevice()).Limits.maxFreqHarmonic : VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq;
auto maxFreq = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxFreq;
auto old_center = (settings.Freq.start + settings.Freq.stop) / 2;
if(old_center < VirtualDevice::getInfo(window->getDevice()).Limits.minFreq + span / 2) {
if(old_center < DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minFreq + span / 2) {
// would shift start frequency below minimum
settings.Freq.start = VirtualDevice::getInfo(window->getDevice()).Limits.minFreq;
settings.Freq.stop = VirtualDevice::getInfo(window->getDevice()).Limits.minFreq + span;
settings.Freq.start = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minFreq;
settings.Freq.stop = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minFreq + span;
} else if(old_center > maxFreq - span / 2) {
// would shift stop frequency above maximum
settings.Freq.start = maxFreq - span;
@ -1025,8 +1025,8 @@ void VNA::SetFullSpan()
settings.Freq.start = pref.Acquisition.fullSpanStart;
settings.Freq.stop = pref.Acquisition.fullSpanStop;
} else {
settings.Freq.start = VirtualDevice::getInfo(window->getDevice()).Limits.minFreq;
settings.Freq.stop = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq;
settings.Freq.start = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minFreq;
settings.Freq.stop = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxFreq;
}
}
ConstrainAndUpdateFrequencies();
@ -1073,10 +1073,10 @@ void VNA::SetLogSweep(bool log)
void VNA::SetSourceLevel(double level)
{
if(level > VirtualDevice::getInfo(window->getDevice()).Limits.maxdBm) {
level = VirtualDevice::getInfo(window->getDevice()).Limits.maxdBm;
} else if(level < VirtualDevice::getInfo(window->getDevice()).Limits.mindBm) {
level = VirtualDevice::getInfo(window->getDevice()).Limits.mindBm;
if(level > DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxdBm) {
level = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxdBm;
} else if(level < DeviceDriver::getInfo(window->getDevice()).Limits.VNA.mindBm) {
level = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.mindBm;
}
emit sourceLevelChanged(level);
settings.Freq.excitation_power = level;
@ -1107,15 +1107,15 @@ void VNA::SetPowerSweepFrequency(double freq)
void VNA::SetPoints(unsigned int points)
{
unsigned int maxPoints = Preferences::getInstance().Acquisition.allowSegmentedSweep ? UINT16_MAX : VirtualDevice::getInfo(window->getDevice()).Limits.maxPoints;
unsigned int maxPoints = Preferences::getInstance().Acquisition.allowSegmentedSweep ? UINT16_MAX : DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxPoints;
if(points > maxPoints) {
points = maxPoints;
} else if (points < 2) {
points = 2;
}
if (points > VirtualDevice::getInfo(window->getDevice()).Limits.maxPoints) {
if (points > DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxPoints) {
// needs segmented sweep
settings.segments = ceil((double) points / VirtualDevice::getInfo(window->getDevice()).Limits.maxPoints);
settings.segments = ceil((double) points / DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxPoints);
settings.activeSegment = 0;
} else {
// can fit all points into one segment
@ -1129,10 +1129,10 @@ void VNA::SetPoints(unsigned int points)
void VNA::SetIFBandwidth(double bandwidth)
{
if(bandwidth > VirtualDevice::getInfo(window->getDevice()).Limits.maxIFBW) {
bandwidth = VirtualDevice::getInfo(window->getDevice()).Limits.maxIFBW;
} else if(bandwidth < VirtualDevice::getInfo(window->getDevice()).Limits.minIFBW) {
bandwidth = VirtualDevice::getInfo(window->getDevice()).Limits.minIFBW;
if(bandwidth > DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxIFBW) {
bandwidth = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxIFBW;
} else if(bandwidth < DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minIFBW) {
bandwidth = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minIFBW;
}
settings.bandwidth = bandwidth;
emit IFBandwidthChanged(settings.bandwidth);
@ -1150,7 +1150,7 @@ void VNA::SetAveraging(unsigned int averages)
void VNA::ExcitationRequired()
{
if(!Preferences::getInstance().Acquisition.alwaysExciteAllPorts) {
for(unsigned int i=1;i<VirtualDevice::getInfo(window->getDevice()).ports;i++) {
for(unsigned int i=1;i<DeviceDriver::getInfo(window->getDevice()).Limits.VNA.ports;i++) {
auto required = traceModel.PortExcitationRequired(i);
auto set = find(settings.excitedPorts.begin(), settings.excitedPorts.end(), i) != settings.excitedPorts.end();
if(required != set) {
@ -1430,21 +1430,14 @@ void VNA::SetupSCPI()
void VNA::ConstrainAndUpdateFrequencies()
{
auto& pref = Preferences::getInstance();
double maxFreq;
if(pref.Acquisition.harmonicMixing) {
maxFreq = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreqHarmonic;
} else {
maxFreq = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq;
}
if(settings.Freq.stop > maxFreq) {
settings.Freq.stop = maxFreq;
if(settings.Freq.stop > DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minFreq) {
settings.Freq.stop = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minFreq;
}
if(settings.Freq.start > settings.Freq.stop) {
settings.Freq.start = settings.Freq.stop;
}
if(settings.Freq.start < VirtualDevice::getInfo(window->getDevice()).Limits.minFreq) {
settings.Freq.start = VirtualDevice::getInfo(window->getDevice()).Limits.minFreq;
if(settings.Freq.start < DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minFreq) {
settings.Freq.start = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minFreq;
}
settings.zerospan = (settings.sweepType == SweepType::Frequency && settings.Freq.start == settings.Freq.stop)
|| (settings.sweepType == SweepType::Power && settings.Power.start == settings.Power.stop);
@ -1617,7 +1610,7 @@ void VNA::preset()
}
}
// Create default traces
createDefaultTracesAndGraphs(VirtualDevice::getInfo(window->getDevice()).ports);
createDefaultTracesAndGraphs(DeviceDriver::getInfo(window->getDevice()).Limits.VNA.ports);
}
QString VNA::SweepTypeToString(VNA::SweepType sw)
@ -1686,14 +1679,14 @@ void VNA::ConfigureDevice(bool resetTraces, std::function<void(bool)> cb)
}
changingSettings = true;
// assemble VNA protocol settings
VirtualDevice::VNASettings s = {};
DeviceDriver::VNASettings s = {};
s.IFBW = settings.bandwidth;
if(Preferences::getInstance().Acquisition.alwaysExciteAllPorts) {
for(unsigned int i=0;i<VirtualDevice::getInfo(window->getDevice()).ports;i++) {
for(unsigned int i=0;i<DeviceDriver::getInfo(window->getDevice()).Limits.VNA.ports;i++) {
s.excitedPorts.push_back(i);
}
} else {
for(unsigned int i=0;i<VirtualDevice::getInfo(window->getDevice()).ports;i++) {
for(unsigned int i=0;i<DeviceDriver::getInfo(window->getDevice()).Limits.VNA.ports;i++) {
if(traceModel.PortExcitationRequired(i))
s.excitedPorts.push_back(i);
}

View File

@ -81,7 +81,7 @@ public slots:
bool SaveCalibration(QString filename = "");
private slots:
void NewDatapoint(VirtualDevice::VNAMeasurement m);
void NewDatapoint(DeviceDriver::VNAMeasurement m);
void StartImpedanceMatching();
void StartMixedModeConversion();
// Sweep control

View File

@ -30,6 +30,7 @@
#include "mode.h"
#include "modehandler.h"
#include "modewindow.h"
#include "Device/librevnausbdriver.h"
#include <QDockWidget>
#include <QDesktopWidget>
@ -83,6 +84,9 @@ AppWindow::AppWindow(QWidget *parent)
// qDebug().setVerbosity(0);
qDebug() << "Application start";
// Register device drivers
deviceDrivers.push_back(new LibreVNAUSBDriver());
this->setWindowIcon(QIcon(":/app/logo.png"));
parser.setApplicationDescription(qlibrevnaApp->applicationName());
@ -102,7 +106,8 @@ AppWindow::AppWindow(QWidget *parent)
} else {
Preferences::getInstance().load();
}
vdevice = nullptr;
device = nullptr;
// vdevice = nullptr;
modeHandler = nullptr;
if(parser.isSet("port")) {
@ -233,12 +238,12 @@ void AppWindow::SetupMenu()
modeHandler->getActiveMode()->saveSreenshot();
});
connect(ui->actionManual_Control, &QAction::triggered, this, &AppWindow::StartManualControl);
// connect(ui->actionManual_Control, &QAction::triggered, this, &AppWindow::StartManualControl);
connect(ui->actionUSB_log, &QAction::triggered, this, &AppWindow::ShowUSBLog);
connect(ui->actionFirmware_Update, &QAction::triggered, this, &AppWindow::StartFirmwareUpdateDialog);
connect(ui->actionSource_Calibration, &QAction::triggered, this, &AppWindow::SourceCalibrationDialog);
connect(ui->actionReceiver_Calibration, &QAction::triggered, this, &AppWindow::ReceiverCalibrationDialog);
connect(ui->actionFrequency_Calibration, &QAction::triggered, this, &AppWindow::FrequencyCalibrationDialog);
// connect(ui->actionFirmware_Update, &QAction::triggered, this, &AppWindow::StartFirmwareUpdateDialog);
// connect(ui->actionSource_Calibration, &QAction::triggered, this, &AppWindow::SourceCalibrationDialog);
// connect(ui->actionReceiver_Calibration, &QAction::triggered, this, &AppWindow::ReceiverCalibrationDialog);
// connect(ui->actionFrequency_Calibration, &QAction::triggered, this, &AppWindow::FrequencyCalibrationDialog);
connect(ui->actionPreset, &QAction::triggered, [=](){
modeHandler->getActiveMode()->preset();
@ -278,14 +283,13 @@ void AppWindow::SetupMenu()
}
// acquisition frequencies may have changed, update
UpdateAcquisitionFrequencies();
// UpdateAcquisitionFrequencies();
auto active = modeHandler->getActiveMode();
if (active)
{
active->updateGraphColors();
if(vdevice) {
if(device) {
active->initializeDevice();
}
}
@ -311,7 +315,13 @@ void AppWindow::closeEvent(QCloseEvent *event)
if(modeHandler->getActiveMode()) {
modeHandler->deactivate(modeHandler->getActiveMode());
}
delete vdevice;
if(device) {
device->disconnectDevice();
device = nullptr;
}
for(auto driver : deviceDrivers) {
delete driver;
}
delete modeHandler;
modeHandler = nullptr;
pref.store();
@ -325,31 +335,41 @@ bool AppWindow::ConnectToDevice(QString serial)
} else {
qDebug() << "Trying to connect to" << serial;
}
if(vdevice) {
if(device) {
qDebug() << "Already connected to a device, disconnecting first...";
DisconnectDevice();
}
try {
qDebug() << "Attempting to connect to device...";
vdevice = new VirtualDevice(serial);
UpdateStatusBar(AppWindow::DeviceStatusBar::Connected);
connect(vdevice, &VirtualDevice::InfoUpdated, this, &AppWindow::DeviceInfoUpdated);
connect(vdevice, &VirtualDevice::LogLineReceived, &deviceLog, &DeviceLog::addLine);
connect(vdevice, &VirtualDevice::ConnectionLost, this, &AppWindow::DeviceConnectionLost);
connect(vdevice, &VirtualDevice::StatusUpdated, this, &AppWindow::DeviceStatusUpdated);
connect(vdevice, &VirtualDevice::NeedsFirmwareUpdate, this, &AppWindow::DeviceNeedsUpdate);
ui->actionDisconnect->setEnabled(true);
if(!vdevice->isCompoundDevice()) {
ui->actionManual_Control->setEnabled(true);
ui->actionFirmware_Update->setEnabled(true);
ui->actionSource_Calibration->setEnabled(true);
ui->actionReceiver_Calibration->setEnabled(true);
ui->actionFrequency_Calibration->setEnabled(true);
for(auto driver : deviceDrivers) {
if(driver->GetAvailableDevices().count(serial)) {
// this driver can connect to the device
if(driver->connectDevice(serial)) {
device = driver;
} else {
// failed to connect
// TODO show error message
}
}
}
UpdateStatusBar(AppWindow::DeviceStatusBar::Connected);
connect(device, &DeviceDriver::InfoUpdated, this, &AppWindow::DeviceInfoUpdated);
connect(device, &DeviceDriver::LogLineReceived, &deviceLog, &DeviceLog::addLine);
connect(device, &DeviceDriver::ConnectionLost, this, &AppWindow::DeviceConnectionLost);
connect(device, &DeviceDriver::StatusUpdated, this, &AppWindow::DeviceStatusUpdated);
// connect(vdevice, &VirtualDevice::NeedsFirmwareUpdate, this, &AppWindow::DeviceNeedsUpdate);
ui->actionDisconnect->setEnabled(true);
// if(!vdevice->isCompoundDevice()) {
// ui->actionManual_Control->setEnabled(true);
// ui->actionFirmware_Update->setEnabled(true);
// ui->actionSource_Calibration->setEnabled(true);
// ui->actionReceiver_Calibration->setEnabled(true);
// ui->actionFrequency_Calibration->setEnabled(true);
// }
ui->actionPreset->setEnabled(true);
for(auto d : deviceActionGroup->actions()) {
if(d->text() == vdevice->serial()) {
if(d->text() == device->getSerial()) {
d->blockSignals(true);
d->setChecked(true);
d->blockSignals(false);
@ -357,12 +377,12 @@ bool AppWindow::ConnectToDevice(QString serial)
}
}
for(auto m : modeHandler->getModes()) {
connect(vdevice, &VirtualDevice::InfoUpdated, m, &Mode::deviceInfoUpdated);
connect(device, &DeviceDriver::InfoUpdated, m, &Mode::deviceInfoUpdated);
}
vdevice->initialize();
// vdevice->initialize();
UpdateAcquisitionFrequencies();
// UpdateAcquisitionFrequencies();
if (modeHandler->getActiveMode()) {
modeHandler->getActiveMode()->initializeDevice();
}
@ -377,8 +397,10 @@ bool AppWindow::ConnectToDevice(QString serial)
void AppWindow::DisconnectDevice()
{
delete vdevice;
vdevice = nullptr;
if(device) {
device->disconnectDevice();
device = nullptr;
}
ui->actionDisconnect->setEnabled(false);
ui->actionManual_Control->setEnabled(false);
ui->actionFirmware_Update->setEnabled(false);
@ -446,8 +468,8 @@ void AppWindow::SetupSCPI()
return SCPI::getResultName(SCPI::Result::Empty);
}
}, [=](QStringList) -> QString {
if(vdevice) {
return vdevice->serial();
if(device) {
return device->getSerial();
} else {
return "Not connected";
}
@ -519,7 +541,11 @@ void AppWindow::SetupSCPI()
}
return SCPI::getResultName(SCPI::Result::Empty);
}, [=](QStringList) -> QString {
return VirtualDevice::getStatus(getDevice()).extRef ? "EXT" : "INT";
if(device) {
return device->asserted(DeviceDriver::Flag::ExtRef) ? "EXT" : "INT";
} else {
return SCPI::getResultName(SCPI::Result::Error);
}
}));
scpi_dev->add(new SCPICommand("MODE", [=](QStringList params) -> QString {
if (params.size() != 1) {
@ -557,84 +583,104 @@ void AppWindow::SetupSCPI()
auto scpi_status = new SCPINode("STAtus");
scpi_dev->add(scpi_status);
scpi_status->add(new SCPICommand("UNLOcked", nullptr, [=](QStringList){
return VirtualDevice::getStatus(getDevice()).unlocked ? "TRUE" : "FALSE";
if(device) {
return device->asserted(DeviceDriver::Flag::Unlocked) ? SCPI::getResultName(SCPI::Result::True) : SCPI::getResultName(SCPI::Result::False);
} else {
return SCPI::getResultName(SCPI::Result::Error);
}
}));
scpi_status->add(new SCPICommand("ADCOVERload", nullptr, [=](QStringList){
return VirtualDevice::getStatus(getDevice()).overload ? "TRUE" : "FALSE";
if(device) {
return device->asserted(DeviceDriver::Flag::Overload) ? SCPI::getResultName(SCPI::Result::True) : SCPI::getResultName(SCPI::Result::False);
} else {
return SCPI::getResultName(SCPI::Result::Error);
}
}));
scpi_status->add(new SCPICommand("UNLEVel", nullptr, [=](QStringList){
return VirtualDevice::getStatus(getDevice()).unlevel ? "TRUE" : "FALSE";
if(device) {
return device->asserted(DeviceDriver::Flag::Unlevel) ? SCPI::getResultName(SCPI::Result::True) : SCPI::getResultName(SCPI::Result::False);
} else {
return SCPI::getResultName(SCPI::Result::Error);
}
}));
auto scpi_info = new SCPINode("INFo");
scpi_dev->add(scpi_info);
scpi_info->add(new SCPICommand("FWREVision", nullptr, [=](QStringList){
return QString::number(VirtualDevice::getInfo(getDevice()).FW_major)+"."+QString::number(VirtualDevice::getInfo(getDevice()).FW_minor)+"."+QString::number(VirtualDevice::getInfo(getDevice()).FW_patch);
}));
scpi_info->add(new SCPICommand("HWREVision", nullptr, [=](QStringList){
return QString(VirtualDevice::getInfo(getDevice()).HW_Revision);
}));
scpi_info->add(new SCPICommand("TEMPeratures", nullptr, [=](QStringList){
if(!vdevice) {
return QString("0/0/0");
} else if(vdevice->isCompoundDevice()) {
// show highest temperature of all devices
int maxTempSource = 0;
int maxTempLO = 0;
int maxTempMCU = 0;
for(auto dev : vdevice->getDevices()) {
auto status = dev->StatusV1();
if(status.temp_source > maxTempSource) {
maxTempSource = status.temp_source;
}
if(status.temp_LO1 > maxTempLO) {
maxTempLO = status.temp_LO1;
}
if(status.temp_MCU > maxTempMCU) {
maxTempMCU = status.temp_MCU;
}
}
return QString::number(maxTempSource)+"/"+QString::number(maxTempLO)+"/"+QString::number(maxTempMCU);
if(device) {
return device->getInfo().firmware_version;
} else {
auto dev = vdevice->getDevice();
return QString::number(dev->StatusV1().temp_source)+"/"+QString::number(dev->StatusV1().temp_LO1)+"/"+QString::number(dev->StatusV1().temp_MCU);
return SCPI::getResultName(SCPI::Result::Error);
}
}));
scpi_info->add(new SCPICommand("HWREVision", nullptr, [=](QStringList){
if(device) {
return device->getInfo().hardware_version;
} else {
return SCPI::getResultName(SCPI::Result::Error);
}
}));
// scpi_info->add(new SCPICommand("TEMPeratures", nullptr, [=](QStringList){
// if(!vdevice) {
// return QString("0/0/0");
// } else if(vdevice->isCompoundDevice()) {
// // show highest temperature of all devices
// int maxTempSource = 0;
// int maxTempLO = 0;
// int maxTempMCU = 0;
// for(auto dev : vdevice->getDevices()) {
// auto status = dev->StatusV1();
// if(status.temp_source > maxTempSource) {
// maxTempSource = status.temp_source;
// }
// if(status.temp_LO1 > maxTempLO) {
// maxTempLO = status.temp_LO1;
// }
// if(status.temp_MCU > maxTempMCU) {
// maxTempMCU = status.temp_MCU;
// }
// }
// return QString::number(maxTempSource)+"/"+QString::number(maxTempLO)+"/"+QString::number(maxTempMCU);
// } else {
// auto dev = vdevice->getDevice();
// return QString::number(dev->StatusV1().temp_source)+"/"+QString::number(dev->StatusV1().temp_LO1)+"/"+QString::number(dev->StatusV1().temp_MCU);
// }
// }));
auto scpi_limits = new SCPINode("LIMits");
scpi_info->add(scpi_limits);
scpi_limits->add(new SCPICommand("MINFrequency", nullptr, [=](QStringList){
return QString::number(VirtualDevice::getInfo(getDevice()).Limits.minFreq);
return QString::number(DeviceDriver::getInfo(getDevice()).Limits.VNA.minFreq);
}));
scpi_limits->add(new SCPICommand("MAXFrequency", nullptr, [=](QStringList){
return QString::number(VirtualDevice::getInfo(getDevice()).Limits.maxFreq);
return QString::number(DeviceDriver::getInfo(getDevice()).Limits.SA.maxFreq);
}));
scpi_limits->add(new SCPICommand("MINIFBW", nullptr, [=](QStringList){
return QString::number(VirtualDevice::getInfo(getDevice()).Limits.minIFBW);
return QString::number(DeviceDriver::getInfo(getDevice()).Limits.VNA.minIFBW);
}));
scpi_limits->add(new SCPICommand("MAXIFBW", nullptr, [=](QStringList){
return QString::number(VirtualDevice::getInfo(getDevice()).Limits.maxIFBW);
return QString::number(DeviceDriver::getInfo(getDevice()).Limits.VNA.maxIFBW);
}));
scpi_limits->add(new SCPICommand("MAXPoints", nullptr, [=](QStringList){
return QString::number(VirtualDevice::getInfo(getDevice()).Limits.maxPoints);
return QString::number(DeviceDriver::getInfo(getDevice()).Limits.VNA.maxPoints);
}));
scpi_limits->add(new SCPICommand("MINPOWer", nullptr, [=](QStringList){
return QString::number(VirtualDevice::getInfo(getDevice()).Limits.mindBm);
return QString::number(DeviceDriver::getInfo(getDevice()).Limits.VNA.mindBm);
}));
scpi_limits->add(new SCPICommand("MAXPOWer", nullptr, [=](QStringList){
return QString::number(VirtualDevice::getInfo(getDevice()).Limits.maxdBm);
return QString::number(DeviceDriver::getInfo(getDevice()).Limits.VNA.maxdBm);
}));
scpi_limits->add(new SCPICommand("MINRBW", nullptr, [=](QStringList){
return QString::number(VirtualDevice::getInfo(getDevice()).Limits.minRBW);
return QString::number(DeviceDriver::getInfo(getDevice()).Limits.SA.minRBW);
}));
scpi_limits->add(new SCPICommand("MAXRBW", nullptr, [=](QStringList){
return QString::number(VirtualDevice::getInfo(getDevice()).Limits.maxRBW);
return QString::number(DeviceDriver::getInfo(getDevice()).Limits.SA.maxRBW);
}));
scpi_limits->add(new SCPICommand("MAXHARMonicfrequency", nullptr, [=](QStringList){
return QString::number(VirtualDevice::getInfo(getDevice()).Limits.maxFreqHarmonic);
return QString::number(DeviceDriver::getInfo(getDevice()).Limits.VNA.maxFreq);
}));
auto scpi_manual = new SCPINode("MANual");
scpi_manual->add(new SCPICommand("STArt",[=](QStringList) -> QString {
StartManualControl();
// StartManualControl();
return SCPI::getResultName(SCPI::Result::Empty);
}, nullptr));
scpi_manual->add(new SCPICommand("STOp",[=](QStringList) -> QString {
@ -887,9 +933,12 @@ int AppWindow::UpdateDeviceList()
{
deviceActionGroup->setExclusive(true);
ui->menuConnect_to->clear();
auto devices = VirtualDevice::GetAvailableVirtualDevices();
if(vdevice) {
devices.insert(vdevice->serial());
std::set<QString> devices;
for(auto driver : deviceDrivers) {
devices.merge(driver->GetAvailableDevices());
}
if(device) {
devices.insert(device->getSerial());
}
int available = 0;
bool found = false;
@ -902,7 +951,7 @@ int AppWindow::UpdateDeviceList()
auto connectAction = ui->menuConnect_to->addAction(d);
connectAction->setCheckable(true);
connectAction->setActionGroup(deviceActionGroup);
if(vdevice && d == vdevice->serial()) {
if(device && d == device->getSerial()) {
connectAction->setChecked(true);
}
connect(connectAction, &QAction::triggered, [this, d]() {
@ -917,59 +966,56 @@ int AppWindow::UpdateDeviceList()
return available;
}
void AppWindow::StartManualControl()
{
if(!vdevice || vdevice->isCompoundDevice()) {
return;
}
if(manual) {
// dialog already active, nothing to do
return;
}
manual = new ManualControlDialog(*vdevice->getDevice(), this);
connect(manual, &QDialog::finished, [=](){
manual = nullptr;
if(vdevice) {
modeHandler->getActiveMode()->initializeDevice();
}
});
if(AppWindow::showGUI()) {
manual->show();
}
}
//void AppWindow::StartManualControl()
//{
// if(!vdevice || vdevice->isCompoundDevice()) {
// return;
// }
// if(manual) {
// // dialog already active, nothing to do
// return;
// }
// manual = new ManualControlDialog(*vdevice->getDevice(), this);
// connect(manual, &QDialog::finished, [=](){
// manual = nullptr;
// if(vdevice) {
// modeHandler->getActiveMode()->initializeDevice();
// }
// });
// if(AppWindow::showGUI()) {
// manual->show();
// }
//}
void AppWindow::UpdateReferenceToolbar()
{
toolbars.reference.type->blockSignals(true);
toolbars.reference.outFreq->blockSignals(true);
if(!vdevice || !vdevice->getInfo().supportsExtRef) {
toolbars.reference.type->setEnabled(false);
toolbars.reference.outFreq->setEnabled(false);
} else {
toolbars.reference.type->setEnabled(true);
toolbars.reference.outFreq->setEnabled(true);
}
// save current setting
auto refInBuf = toolbars.reference.type->currentText();
auto refOutBuf = toolbars.reference.outFreq->currentText();
toolbars.reference.type->clear();
for(auto in : vdevice->availableExtRefInSettings()) {
toolbars.reference.type->addItem(in);
}
toolbars.reference.outFreq->clear();
for(auto out : vdevice->availableExtRefOutSettings()) {
toolbars.reference.outFreq->addItem(out);
}
// restore previous setting if still available
if(toolbars.reference.type->findText(refInBuf) >= 0) {
toolbars.reference.type->setCurrentText(refInBuf);
} else {
toolbars.reference.type->setCurrentIndex(0);
}
if(toolbars.reference.outFreq->findText(refOutBuf) >= 0) {
toolbars.reference.outFreq->setCurrentText(refOutBuf);
} else {
toolbars.reference.outFreq->setCurrentIndex(0);
toolbars.reference.type->setEnabled(device || device->supports(DeviceDriver::Feature::ExtRefIn));
toolbars.reference.outFreq->setEnabled(device || device->supports(DeviceDriver::Feature::ExtRefOut));
if(device) {
// save current setting
auto refInBuf = toolbars.reference.type->currentText();
auto refOutBuf = toolbars.reference.outFreq->currentText();
toolbars.reference.type->clear();
for(auto in : device->availableExtRefInSettings()) {
toolbars.reference.type->addItem(in);
}
toolbars.reference.outFreq->clear();
for(auto out : device->availableExtRefOutSettings()) {
toolbars.reference.outFreq->addItem(out);
}
// restore previous setting if still available
if(toolbars.reference.type->findText(refInBuf) >= 0) {
toolbars.reference.type->setCurrentText(refInBuf);
} else {
toolbars.reference.type->setCurrentIndex(0);
}
if(toolbars.reference.outFreq->findText(refOutBuf) >= 0) {
toolbars.reference.outFreq->setCurrentText(refOutBuf);
} else {
toolbars.reference.outFreq->setCurrentIndex(0);
}
}
toolbars.reference.type->blockSignals(false);
toolbars.reference.outFreq->blockSignals(false);
@ -978,27 +1024,11 @@ void AppWindow::UpdateReferenceToolbar()
void AppWindow::UpdateReference()
{
if(!vdevice) {
if(!device) {
// can't update without a device connected
return;
}
vdevice->setExtRef(toolbars.reference.type->currentText(), toolbars.reference.outFreq->currentText());
}
void AppWindow::UpdateAcquisitionFrequencies()
{
if(!vdevice) {
return;
}
Protocol::PacketInfo p;
p.type = Protocol::PacketType::AcquisitionFrequencySettings;
auto& pref = Preferences::getInstance();
p.acquisitionFrequencySettings.IF1 = pref.Acquisition.IF1;
p.acquisitionFrequencySettings.ADCprescaler = pref.Acquisition.ADCprescaler;
p.acquisitionFrequencySettings.DFTphaseInc = pref.Acquisition.DFTPhaseInc;
for(auto dev : vdevice->getDevices()) {
dev->SendPacket(p);
}
device->setExtRef(toolbars.reference.type->currentText(), toolbars.reference.outFreq->currentText());
}
void AppWindow::ShowUSBLog()
@ -1009,34 +1039,21 @@ void AppWindow::ShowUSBLog()
}
}
void AppWindow::StartFirmwareUpdateDialog()
{
if(!vdevice || vdevice->isCompoundDevice()) {
return;
}
auto fw_update = new FirmwareUpdateDialog(vdevice->getDevice());
connect(fw_update, &FirmwareUpdateDialog::DeviceRebooting, this, &AppWindow::DisconnectDevice);
connect(fw_update, &FirmwareUpdateDialog::DeviceRebooted, this, &AppWindow::ConnectToDevice);
if(AppWindow::showGUI()) {
fw_update->exec();
}
}
void AppWindow::DeviceNeedsUpdate(int reported, int expected)
{
auto ret = InformationBox::AskQuestion("Warning",
"The device reports a different protocol"
"version (" + QString::number(reported) + ") than expected (" + QString::number(expected) + ").\n"
"A firmware update is strongly recommended. Do you want to update now?", false);
if (ret) {
if (vdevice->isCompoundDevice()) {
InformationBox::ShowError("Unable to update the firmware", "The connected device is a compound device, direct firmware"
" update is not supported. Connect to each LibreVNA individually for the update.");
return;
}
StartFirmwareUpdateDialog();
}
}
//void AppWindow::DeviceNeedsUpdate(int reported, int expected)
//{
// auto ret = InformationBox::AskQuestion("Warning",
// "The device reports a different protocol"
// "version (" + QString::number(reported) + ") than expected (" + QString::number(expected) + ").\n"
// "A firmware update is strongly recommended. Do you want to update now?", false);
// if (ret) {
// if (vdevice->isCompoundDevice()) {
// InformationBox::ShowError("Unable to update the firmware", "The connected device is a compound device, direct firmware"
// " update is not supported. Connect to each LibreVNA individually for the update.");
// return;
// }
// StartFirmwareUpdateDialog();
// }
//}
void AppWindow::DeviceStatusUpdated(VirtualDevice::Status status)
{
@ -1054,38 +1071,38 @@ void AppWindow::DeviceInfoUpdated()
UpdateReferenceToolbar();
}
void AppWindow::SourceCalibrationDialog()
{
if(!vdevice || vdevice->isCompoundDevice()) {
return;
}
auto d = new SourceCalDialog(vdevice->getDevice(), modeHandler);
if(AppWindow::showGUI()) {
d->exec();
}
}
//void AppWindow::SourceCalibrationDialog()
//{
// if(!vdevice || vdevice->isCompoundDevice()) {
// return;
// }
// auto d = new SourceCalDialog(vdevice->getDevice(), modeHandler);
// if(AppWindow::showGUI()) {
// d->exec();
// }
//}
void AppWindow::ReceiverCalibrationDialog()
{
if(!vdevice || vdevice->isCompoundDevice()) {
return;
}
auto d = new ReceiverCalDialog(vdevice->getDevice(), modeHandler);
if(AppWindow::showGUI()) {
d->exec();
}
}
//void AppWindow::ReceiverCalibrationDialog()
//{
// if(!vdevice || vdevice->isCompoundDevice()) {
// return;
// }
// auto d = new ReceiverCalDialog(vdevice->getDevice(), modeHandler);
// if(AppWindow::showGUI()) {
// d->exec();
// }
//}
void AppWindow::FrequencyCalibrationDialog()
{
if(!vdevice || vdevice->isCompoundDevice()) {
return;
}
auto d = new FrequencyCalDialog(vdevice->getDevice(), modeHandler);
if(AppWindow::showGUI()) {
d->exec();
}
}
//void AppWindow::FrequencyCalibrationDialog()
//{
// if(!vdevice || vdevice->isCompoundDevice()) {
// return;
// }
// auto d = new FrequencyCalDialog(vdevice->getDevice(), modeHandler);
// if(AppWindow::showGUI()) {
// d->exec();
// }
//}
void AppWindow::SaveSetup(QString filename)
{
@ -1158,10 +1175,10 @@ void AppWindow::LoadSetup(nlohmann::json j)
// Disconnect device prior to deleting and creating new modes. This prevents excessice and unnnecessary configuration of the device
QString serial = QString();
if(vdevice->getConnected()) {
serial = vdevice->serial();
delete vdevice;
vdevice = nullptr;
if(device) {
serial = device->getSerial();
device->disconnectDevice();
device = nullptr;
}
modeHandler->closeModes();
@ -1214,9 +1231,9 @@ void AppWindow::LoadSetup(nlohmann::json j)
}
}
VirtualDevice *AppWindow::getDevice()
DeviceDriver *AppWindow::getDevice()
{
return vdevice;
return device;
}
QStackedWidget *AppWindow::getCentral() const
@ -1290,8 +1307,8 @@ void AppWindow::UpdateStatusBar(DeviceStatusBar status)
{
switch(status) {
case DeviceStatusBar::Connected:
lConnectionStatus.setText("Connected to " + vdevice->serial());
qInfo() << "Connected to" << vdevice->serial();
lConnectionStatus.setText("Connected to " + device->getSerial());
qInfo() << "Connected to" << device->getSerial();
break;
case DeviceStatusBar::Disconnected:
lConnectionStatus.setText("No device connected");

View File

@ -11,6 +11,7 @@
#include "scpi.h"
#include "tcpserver.h"
#include "Device/manualcontroldialog.h"
#include "Device/devicedriver.h"
#include <QWidget>
#include <QMainWindow>
@ -42,7 +43,7 @@ public:
Ui::MainWindow *getUi() const;
QStackedWidget *getCentral() const;
ModeHandler* getModeHandler() const;
VirtualDevice *getDevice();
DeviceDriver *getDevice();
const QString& getAppVersion() const;
const QString& getAppGitHash() const;
@ -60,18 +61,18 @@ private slots:
bool ConnectToDevice(QString serial = QString());
void DisconnectDevice();
int UpdateDeviceList();
void StartManualControl();
// void StartManualControl();
void UpdateReferenceToolbar();
void UpdateReference();
void UpdateAcquisitionFrequencies();
// void UpdateAcquisitionFrequencies();
void ShowUSBLog();
void StartFirmwareUpdateDialog();
// void StartFirmwareUpdateDialog();
void DeviceNeedsUpdate(int reported, int expected);
void DeviceStatusUpdated(VirtualDevice::Status status);
void DeviceInfoUpdated();
void SourceCalibrationDialog();
void ReceiverCalibrationDialog();
void FrequencyCalibrationDialog();
// void SourceCalibrationDialog();
// void ReceiverCalibrationDialog();
// void FrequencyCalibrationDialog();
nlohmann::json SaveSetup();
void SaveSetup(QString filename);
void LoadSetup(QString filename);
@ -103,7 +104,11 @@ private:
} toolbars;
ModeHandler *modeHandler;
VirtualDevice *vdevice;
// VirtualDevice *vdevice;
std::vector<DeviceDriver*> deviceDrivers;
DeviceDriver *device;
DeviceLog deviceLog;
QString deviceSerial;
QActionGroup *deviceActionGroup;

View File

@ -23,7 +23,7 @@ void Averaging::setAverages(unsigned int a)
reset(avg.size());
}
VirtualDevice::VNAMeasurement Averaging::process(VirtualDevice::VNAMeasurement d)
DeviceDriver::VNAMeasurement Averaging::process(DeviceDriver::VNAMeasurement d)
{
if(d.measurements.size() != numMeasurements) {
numMeasurements = d.measurements.size();
@ -42,7 +42,7 @@ VirtualDevice::VNAMeasurement Averaging::process(VirtualDevice::VNAMeasurement d
return d;
}
VirtualDevice::SAMeasurement Averaging::process(VirtualDevice::SAMeasurement d)
DeviceDriver::SAMeasurement Averaging::process(DeviceDriver::SAMeasurement d)
{
if(d.measurements.size() != numMeasurements) {
numMeasurements = d.measurements.size();

View File

@ -1,7 +1,7 @@
#ifndef AVERAGING_H
#define AVERAGING_H
#include "Device/virtualdevice.h"
#include "Device/devicedriver.h"
#include <array>
#include <deque>
@ -18,8 +18,8 @@ public:
Averaging();
void reset(unsigned int points);
void setAverages(unsigned int a);
VirtualDevice::VNAMeasurement process(VirtualDevice::VNAMeasurement d);
VirtualDevice::SAMeasurement process(VirtualDevice::SAMeasurement d);
DeviceDriver::VNAMeasurement process(DeviceDriver::VNAMeasurement d);
DeviceDriver::SAMeasurement process(DeviceDriver::SAMeasurement d);
// Returns the number of averaged sweeps. Value is incremented whenever the last point of the sweep is added.
// Returned values are in range 0 to averages
unsigned int getLevel();

View File

@ -93,7 +93,7 @@
</size>
</property>
<property name="currentIndex">
<number>3</number>
<number>6</number>
</property>
<widget class="QWidget" name="Startup">
<layout class="QHBoxLayout" name="horizontalLayout_4">
@ -107,8 +107,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>530</width>
<height>937</height>
<width>749</width>
<height>920</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_13">
@ -1795,8 +1795,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>168</width>
<height>127</height>
<width>763</width>
<height>561</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_12">
@ -1885,8 +1885,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>126</width>
<height>90</height>
<width>763</width>
<height>561</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_24">
@ -1956,8 +1956,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>263</width>
<height>241</height>
<width>763</width>
<height>561</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_19">

View File

@ -21,7 +21,9 @@ public:
bool openFromFileDialog(QString title, QString filetype);
bool saveToFileDialog(QString title, QString filetype, QString ending = "");
using SettingDescription = struct {
class SettingDescription {
public:
SettingDescription(QPointerVariant var, QString name, QVariant def) : var(var), name(name), def(def){}
QPointerVariant var;
QString name;
QVariant def;

View File

@ -13,7 +13,7 @@ PortExtensionTests::PortExtensionTests() : QObject(nullptr)
constexpr int steps = 501;
for(int i=0;i<steps;i++) {
double f = startFreq + (stopFreq - startFreq) * i / (steps - 1);
VirtualDevice::VNAMeasurement m;
DeviceDriver::VNAMeasurement m;
m.frequency = f;
m.dBm = -10;
m.pointNum = i;

View File

@ -15,7 +15,7 @@ private slots:
void autocalc();
void correct();
private:
std::vector<VirtualDevice::VNAMeasurement> dummyData;
std::vector<DeviceDriver::VNAMeasurement> dummyData;
};
#endif // PORTEXTENSIONTESTS_H