WIP: device driver abstraction
This commit is contained in:
parent
59e30e93c5
commit
db6d823e0f
@ -151,7 +151,7 @@ Calibration::Calibration()
|
|||||||
}
|
}
|
||||||
bool okay;
|
bool okay;
|
||||||
unsigned int number = params[1].toInt(&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
|
// invalid port specified
|
||||||
return SCPI::getResultName(SCPI::Result::Error);
|
return SCPI::getResultName(SCPI::Result::Error);
|
||||||
}
|
}
|
||||||
@ -168,8 +168,8 @@ Calibration::Calibration()
|
|||||||
unsigned int port1 = params[1].toInt(&okay1);
|
unsigned int port1 = params[1].toInt(&okay1);
|
||||||
bool okay2;
|
bool okay2;
|
||||||
unsigned int port2 = params[2].toInt(&okay2);
|
unsigned int port2 = params[2].toInt(&okay2);
|
||||||
if(!okay1 || !okay2 || port1 < 1 || port2 > VirtualDevice::getInfo(VirtualDevice::getConnected()).ports
|
if(!okay1 || !okay2 || port1 < 1 || port2 > DeviceDriver::getInfo(DeviceDriver::getActiveDriver()).Limits.VNA.ports
|
||||||
|| port2 < 1 || port2 > VirtualDevice::getInfo(VirtualDevice::getConnected()).ports) {
|
|| port2 < 1 || port2 > DeviceDriver::getInfo(DeviceDriver::getActiveDriver()).Limits.VNA.ports) {
|
||||||
// invalid port specified
|
// invalid port specified
|
||||||
return SCPI::getResultName(SCPI::Result::Error);
|
return SCPI::getResultName(SCPI::Result::Error);
|
||||||
}
|
}
|
||||||
@ -318,7 +318,7 @@ Calibration::Type Calibration::TypeFromString(QString s)
|
|||||||
return Type::None;
|
return Type::None;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Calibration::correctMeasurement(VirtualDevice::VNAMeasurement &d)
|
void Calibration::correctMeasurement(DeviceDriver::VNAMeasurement &d)
|
||||||
{
|
{
|
||||||
lock_guard<recursive_mutex> guard(access);
|
lock_guard<recursive_mutex> guard(access);
|
||||||
if(caltype.type == Type::None) {
|
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");
|
throw runtime_error("Measurement "+name.toStdString()+" does not contain any points");
|
||||||
}
|
}
|
||||||
for(auto j_p : j_m["points"]) {
|
for(auto j_p : j_m["points"]) {
|
||||||
VirtualDevice::VNAMeasurement p;
|
DeviceDriver::VNAMeasurement p;
|
||||||
p.frequency = j_p.value("frequency", 0.0);
|
p.frequency = j_p.value("frequency", 0.0);
|
||||||
p.Z0 = 50.0;
|
p.Z0 = 50.0;
|
||||||
p.measurements["S11"] = complex<double>(j_p.value("S11_real", 0.0), j_p.value("S11_imag", 0.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()
|
std::vector<Calibration::CalType> Calibration::getAvailableCalibrations()
|
||||||
{
|
{
|
||||||
unsigned int ports = 2;
|
unsigned int ports = DeviceDriver::getInfo(DeviceDriver::getActiveDriver()).Limits.VNA.ports;
|
||||||
if(VirtualDevice::getConnected()) {
|
|
||||||
ports = VirtualDevice::getConnected()->getInfo().ports;
|
|
||||||
}
|
|
||||||
vector<CalType> ret;
|
vector<CalType> ret;
|
||||||
for(auto t : getTypes()) {
|
for(auto t : getTypes()) {
|
||||||
CalType cal;
|
CalType cal;
|
||||||
@ -1727,14 +1724,15 @@ int Calibration::minimumPorts(Calibration::Type type)
|
|||||||
return -1;
|
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) {
|
for(auto meas : m) {
|
||||||
meas->addPoint(data);
|
meas->addPoint(data);
|
||||||
}
|
}
|
||||||
unsavedChanges = true;
|
unsavedChanges = true;
|
||||||
if(VirtualDevice::getConnected()) {
|
// TODO
|
||||||
validDevice = VirtualDevice::getConnected()->serial();
|
if(DeviceDriver::getActiveDriver()) {
|
||||||
|
validDevice = DeviceDriver::getActiveDriver()->getSerial();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#include "Traces/trace.h"
|
#include "Traces/trace.h"
|
||||||
#include "scpi.h"
|
#include "scpi.h"
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
class Calibration : public QObject, public Savable, public SCPINode
|
class Calibration : public QObject, public Savable, public SCPINode
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -38,7 +40,7 @@ public:
|
|||||||
static Type TypeFromString(QString s);
|
static Type TypeFromString(QString s);
|
||||||
|
|
||||||
// Applies calculated calibration coefficients to measurement data
|
// Applies calculated calibration coefficients to measurement data
|
||||||
void correctMeasurement(VirtualDevice::VNAMeasurement &d);
|
void correctMeasurement(DeviceDriver::VNAMeasurement &d);
|
||||||
void correctTraces(std::map<QString, Trace*> traceSet);
|
void correctTraces(std::map<QString, Trace*> traceSet);
|
||||||
|
|
||||||
// Starts the calibration edit dialog, allowing the user to make/delete measurements
|
// Starts the calibration edit dialog, allowing the user to make/delete measurements
|
||||||
@ -68,7 +70,7 @@ public:
|
|||||||
static int minimumPorts(Type type);
|
static int minimumPorts(Type type);
|
||||||
|
|
||||||
// Adds a new measurement point (data) to all calibration measurements (m)
|
// 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)
|
// Deletes all datapoints in the calibration measurements (m)
|
||||||
void clearMeasurements(std::set<CalibrationMeasurement::Base*> m);
|
void clearMeasurements(std::set<CalibrationMeasurement::Base*> m);
|
||||||
CalType getCaltype() const;
|
CalType getCaltype() const;
|
||||||
|
@ -246,7 +246,7 @@ void CalibrationMeasurement::OnePort::clearPoints()
|
|||||||
timestamp = QDateTime();
|
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);
|
QString measurementName = "S"+QString::number(port)+QString::number(port);
|
||||||
if(m.measurements.count(measurementName) > 0) {
|
if(m.measurements.count(measurementName) > 0) {
|
||||||
@ -262,12 +262,12 @@ QWidget *CalibrationMeasurement::OnePort::createSettingsWidget()
|
|||||||
{
|
{
|
||||||
auto label = new QLabel("Port:");
|
auto label = new QLabel("Port:");
|
||||||
auto cbPort = new QComboBox();
|
auto cbPort = new QComboBox();
|
||||||
auto dev = VirtualDevice::getConnected();
|
auto dev = DeviceDriver::getActiveDriver();
|
||||||
if(dev) {
|
if(dev) {
|
||||||
if(port == 0) {
|
if(port == 0) {
|
||||||
setPort(1);
|
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));
|
cbPort->addItem(QString::number(i));
|
||||||
if(port == i) {
|
if(port == i) {
|
||||||
cbPort->setCurrentText(QString::number(i));
|
cbPort->setCurrentText(QString::number(i));
|
||||||
@ -390,7 +390,7 @@ void CalibrationMeasurement::TwoPort::clearPoints()
|
|||||||
timestamp = QDateTime();
|
timestamp = QDateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CalibrationMeasurement::TwoPort::addPoint(const VirtualDevice::VNAMeasurement &m)
|
void CalibrationMeasurement::TwoPort::addPoint(const DeviceDriver::VNAMeasurement &m)
|
||||||
{
|
{
|
||||||
Point p;
|
Point p;
|
||||||
p.frequency = m.frequency;
|
p.frequency = m.frequency;
|
||||||
@ -407,7 +407,7 @@ QWidget *CalibrationMeasurement::TwoPort::createSettingsWidget()
|
|||||||
auto cbPort2 = new QComboBox();
|
auto cbPort2 = new QComboBox();
|
||||||
auto cbReverse = new QCheckBox("Reversed");
|
auto cbReverse = new QCheckBox("Reversed");
|
||||||
cbReverse->setToolTip("Enable this option if the calibration standard is defined with the port order swapped");
|
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(dev) {
|
||||||
if(port1 == 0) {
|
if(port1 == 0) {
|
||||||
setPort1(1);
|
setPort1(1);
|
||||||
@ -415,7 +415,7 @@ QWidget *CalibrationMeasurement::TwoPort::createSettingsWidget()
|
|||||||
if(port2 == 0) {
|
if(port2 == 0) {
|
||||||
setPort2(2);
|
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));
|
cbPort1->addItem(QString::number(i));
|
||||||
cbPort2->addItem(QString::number(i));
|
cbPort2->addItem(QString::number(i));
|
||||||
if(port1 == i) {
|
if(port1 == i) {
|
||||||
@ -603,7 +603,7 @@ void CalibrationMeasurement::Isolation::clearPoints()
|
|||||||
timestamp = QDateTime();
|
timestamp = QDateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CalibrationMeasurement::Isolation::addPoint(const VirtualDevice::VNAMeasurement &m)
|
void CalibrationMeasurement::Isolation::addPoint(const DeviceDriver::VNAMeasurement &m)
|
||||||
{
|
{
|
||||||
Point p;
|
Point p;
|
||||||
p.frequency = m.frequency;
|
p.frequency = m.frequency;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define CALIBRATIONMEASUREMENT_H
|
#define CALIBRATIONMEASUREMENT_H
|
||||||
|
|
||||||
#include "calstandard.h"
|
#include "calstandard.h"
|
||||||
#include "Device/virtualdevice.h"
|
#include "Device/devicedriver.h"
|
||||||
|
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
@ -47,7 +47,7 @@ public:
|
|||||||
virtual Type getType() = 0;
|
virtual Type getType() = 0;
|
||||||
|
|
||||||
virtual void clearPoints() = 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* createStandardWidget();
|
||||||
virtual QWidget* createSettingsWidget() = 0;
|
virtual QWidget* createSettingsWidget() = 0;
|
||||||
@ -83,7 +83,7 @@ public:
|
|||||||
virtual bool readyForCalculation() override {return standard && points.size() > 0;}
|
virtual bool readyForCalculation() override {return standard && points.size() > 0;}
|
||||||
|
|
||||||
virtual void clearPoints() override;
|
virtual void clearPoints() override;
|
||||||
virtual void addPoint(const VirtualDevice::VNAMeasurement &m) override;
|
virtual void addPoint(const DeviceDriver::VNAMeasurement &m) override;
|
||||||
|
|
||||||
virtual QWidget* createSettingsWidget() override;
|
virtual QWidget* createSettingsWidget() override;
|
||||||
|
|
||||||
@ -197,7 +197,7 @@ public:
|
|||||||
virtual bool readyForCalculation() override {return standard && points.size() > 0;}
|
virtual bool readyForCalculation() override {return standard && points.size() > 0;}
|
||||||
|
|
||||||
virtual void clearPoints() override;
|
virtual void clearPoints() override;
|
||||||
virtual void addPoint(const VirtualDevice::VNAMeasurement &m) override;
|
virtual void addPoint(const DeviceDriver::VNAMeasurement &m) override;
|
||||||
|
|
||||||
virtual QWidget* createSettingsWidget() override;
|
virtual QWidget* createSettingsWidget() override;
|
||||||
|
|
||||||
@ -268,7 +268,7 @@ public:
|
|||||||
virtual bool readyForCalculation() override {return points.size() > 0;}
|
virtual bool readyForCalculation() override {return points.size() > 0;}
|
||||||
|
|
||||||
virtual void clearPoints() override;
|
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* createStandardWidget() override;
|
||||||
virtual QWidget* createSettingsWidget() override;
|
virtual QWidget* createSettingsWidget() override;
|
||||||
|
22
Software/PC_Application/LibreVNA-GUI/Device/devicedriver.cpp
Normal file
22
Software/PC_Application/LibreVNA-GUI/Device/devicedriver.cpp
Normal 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;
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
#ifndef DEVICEDRIVER_H
|
#ifndef DEVICEDRIVER_H
|
||||||
#define DEVICEDRIVER_H
|
#define DEVICEDRIVER_H
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -24,8 +24,8 @@ class DeviceDriver : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
DeviceDriver();
|
DeviceDriver() {}
|
||||||
virtual ~DeviceDriver();
|
virtual ~DeviceDriver() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the driver name. It must be unique across all implemented drivers and is used to identify the driver
|
* @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
|
* @return Serial numbers of detected devices
|
||||||
*/
|
*/
|
||||||
virtual std::set<QString> GetAvailableDevices() = 0;
|
virtual std::set<QString> GetAvailableDevices() = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
/**
|
/**
|
||||||
* @brief Connects to a device, given by its serial number
|
* @brief Connects to a device, given by its serial number
|
||||||
|
*
|
||||||
* @param serial Serial number of device that should be connected to
|
* @param serial Serial number of device that should be connected to
|
||||||
* @return true if connection successful, otherwise false
|
* @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
|
* @brief Disconnects from device. Has no effect if no device was connected
|
||||||
*/
|
*/
|
||||||
virtual void disconnect() = 0;
|
virtual void disconnect() = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Returns the serial number of the connected device
|
* @brief Returns the serial number of the connected device
|
||||||
* @return Serial number of connected device (empty string if no device is connected)
|
* @return Serial number of connected device (empty string if no device is connected)
|
||||||
*/
|
*/
|
||||||
virtual QString serial() = 0;
|
virtual QString getSerial() = 0;
|
||||||
|
|
||||||
enum class Feature {
|
enum class Feature {
|
||||||
// VNA features
|
// VNA features
|
||||||
@ -65,7 +69,6 @@ public:
|
|||||||
Generator,
|
Generator,
|
||||||
// Spectrum analyzer features
|
// Spectrum analyzer features
|
||||||
SA,
|
SA,
|
||||||
SASignalID,
|
|
||||||
SATrackingGenerator,
|
SATrackingGenerator,
|
||||||
SATrackingOffset,
|
SATrackingOffset,
|
||||||
// External reference
|
// External reference
|
||||||
@ -75,6 +78,7 @@ public:
|
|||||||
|
|
||||||
class Info {
|
class Info {
|
||||||
public:
|
public:
|
||||||
|
// TODO create constructor with default values
|
||||||
QString firmware_version;
|
QString firmware_version;
|
||||||
QString hardware_version;
|
QString hardware_version;
|
||||||
std::set<Feature> supportedFeatures;
|
std::set<Feature> supportedFeatures;
|
||||||
@ -106,6 +110,8 @@ public:
|
|||||||
double minFreq, maxFreq;
|
double minFreq, maxFreq;
|
||||||
// RBW limits in Hz
|
// RBW limits in Hz
|
||||||
double minRBW, maxRBW;
|
double minRBW, maxRBW;
|
||||||
|
// Output level limits of the tracking generator in dBm
|
||||||
|
double mindBm, maxdBm;
|
||||||
} SA;
|
} SA;
|
||||||
} Limits;
|
} Limits;
|
||||||
};
|
};
|
||||||
@ -179,19 +185,16 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @brief Returns the driver specific settings
|
* @brief Returns the driver specific settings
|
||||||
*
|
*
|
||||||
* The settings are returned as a map.
|
* The settings are returned as a vector of SettingDescriptions, consisting of:
|
||||||
* Key: user-readable setting name
|
|
||||||
* Value: SettingDescription, consisting of:
|
|
||||||
* - var: Pointer to the setting variable (should be a private member of the derived class)
|
* - 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)
|
* - name: Arbitrary string used to persistently store this setting (never visible to the user)
|
||||||
* - def: Default value of the setting
|
* - def: Default value of the setting
|
||||||
*
|
*
|
||||||
* These settings will be persistent across reboots. For each device driver, a section within the preferences
|
* These settings will be persistent across reboots.
|
||||||
* will be created where these settings can be changed.
|
|
||||||
*
|
*
|
||||||
* @return Map of driver specific settings
|
* @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.
|
* @brief Return driver specific actions.
|
||||||
@ -343,6 +346,12 @@ public:
|
|||||||
* @return true if configuration successful, false otherwise
|
* @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;}
|
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:
|
signals:
|
||||||
/**
|
/**
|
||||||
* @brief This signal must be emitted whenever a SA measurement is complete and should be passed on to the GUI
|
* @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 constexpr unsigned int maximumSupportedPorts = 8;
|
||||||
|
|
||||||
|
static Info getInfo(DeviceDriver* driver) {
|
||||||
|
if(driver) {
|
||||||
|
return driver->getInfo();
|
||||||
|
} else {
|
||||||
|
return Info();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
/**
|
/**
|
||||||
* @brief Emit this signal when the device connection has been lost unexpectedly
|
* @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();
|
void ConnectionLost();
|
||||||
/**
|
/**
|
||||||
@ -421,6 +440,14 @@ signals:
|
|||||||
* @param line
|
* @param line
|
||||||
*/
|
*/
|
||||||
void LogLineReceived(QString 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)
|
Q_DECLARE_METATYPE(DeviceDriver::VNAMeasurement)
|
||||||
|
@ -1,6 +1,312 @@
|
|||||||
#include "librevnadriver.h"
|
#include "librevnadriver.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
LibreVNADriver::LibreVNADriver()
|
LibreVNADriver::LibreVNADriver()
|
||||||
{
|
{
|
||||||
connected = false;
|
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);
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
#include "../../VNA_embedded/Application/Communication/Protocol.hpp"
|
#include "../../VNA_embedded/Application/Communication/Protocol.hpp"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
class LibreVNADriver : public DeviceDriver
|
class LibreVNADriver : public DeviceDriver
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -19,11 +21,188 @@ public:
|
|||||||
|
|
||||||
LibreVNADriver();
|
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 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;
|
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
|
#endif // LIBREVNADRIVER_H
|
||||||
|
@ -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);
|
||||||
|
}
|
113
Software/PC_Application/LibreVNA-GUI/Device/librevnausbdriver.h
Normal file
113
Software/PC_Application/LibreVNA-GUI/Device/librevnausbdriver.h
Normal 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
|
@ -98,7 +98,7 @@ void Generator::setupSCPI()
|
|||||||
}));
|
}));
|
||||||
add(new SCPICommand("PORT", [=](QStringList params) -> QString {
|
add(new SCPICommand("PORT", [=](QStringList params) -> QString {
|
||||||
unsigned long long newval;
|
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);
|
return SCPI::getResultName(SCPI::Result::Error);
|
||||||
} else {
|
} else {
|
||||||
central->setPort(newval);
|
central->setPort(newval);
|
||||||
|
@ -33,16 +33,16 @@ SignalgeneratorWidget::SignalgeneratorWidget(AppWindow *window, QWidget *parent)
|
|||||||
ui->steps->setPrecision(0);
|
ui->steps->setPrecision(0);
|
||||||
|
|
||||||
connect(ui->frequency, &SIUnitEdit::valueChanged, [=](double newval) {
|
connect(ui->frequency, &SIUnitEdit::valueChanged, [=](double newval) {
|
||||||
if(newval < VirtualDevice::getInfo(window->getDevice()).Limits.minFreq) {
|
if(newval < DeviceDriver::getInfo(window->getDevice()).Limits.Generator.minFreq) {
|
||||||
newval = VirtualDevice::getInfo(window->getDevice()).Limits.minFreq;
|
newval = DeviceDriver::getInfo(window->getDevice()).Limits.Generator.minFreq;
|
||||||
} else if (newval > VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq) {
|
} else if (newval > DeviceDriver::getInfo(window->getDevice()).Limits.Generator.maxFreq) {
|
||||||
newval = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq;
|
newval = DeviceDriver::getInfo(window->getDevice()).Limits.Generator.maxFreq;
|
||||||
}
|
}
|
||||||
ui->frequency->setValueQuiet(newval);
|
ui->frequency->setValueQuiet(newval);
|
||||||
if (newval < ui->span->value()/2)
|
if (newval < ui->span->value()/2)
|
||||||
ui->span->setValueQuiet(newval/2);
|
ui->span->setValueQuiet(newval/2);
|
||||||
if (newval + ui->span->value()/2 > VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq)
|
if (newval + ui->span->value()/2 > DeviceDriver::getInfo(window->getDevice()).Limits.Generator.maxFreq)
|
||||||
ui->span->setValueQuiet((VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq - newval)*2);
|
ui->span->setValueQuiet((DeviceDriver::getInfo(window->getDevice()).Limits.Generator.maxFreq - newval)*2);
|
||||||
newval = ui->frequency->value() - ui->span->value()/2;
|
newval = ui->frequency->value() - ui->span->value()/2;
|
||||||
ui->current->setValueQuiet(newval);
|
ui->current->setValueQuiet(newval);
|
||||||
emit SettingsChanged();
|
emit SettingsChanged();
|
||||||
@ -51,8 +51,8 @@ SignalgeneratorWidget::SignalgeneratorWidget(AppWindow *window, QWidget *parent)
|
|||||||
connect(ui->span, &SIUnitEdit::valueChanged, [=](double newval) {
|
connect(ui->span, &SIUnitEdit::valueChanged, [=](double newval) {
|
||||||
if(newval < 0 ) {
|
if(newval < 0 ) {
|
||||||
newval = 0;
|
newval = 0;
|
||||||
} else if (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 = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq - VirtualDevice::getInfo(window->getDevice()).Limits.minFreq;
|
newval = DeviceDriver::getInfo(window->getDevice()).Limits.Generator.maxFreq - DeviceDriver::getInfo(window->getDevice()).Limits.Generator.minFreq;
|
||||||
}
|
}
|
||||||
ui->span->setValueQuiet(newval);
|
ui->span->setValueQuiet(newval);
|
||||||
|
|
||||||
@ -61,8 +61,8 @@ SignalgeneratorWidget::SignalgeneratorWidget(AppWindow *window, QWidget *parent)
|
|||||||
ui->frequency->setValueQuiet(ui->span->value()/2);
|
ui->frequency->setValueQuiet(ui->span->value()/2);
|
||||||
}
|
}
|
||||||
newF = ui->frequency->value() + ui->span->value()/2;
|
newF = ui->frequency->value() + ui->span->value()/2;
|
||||||
if (newF > VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq) {
|
if (newF > DeviceDriver::getInfo(window->getDevice()).Limits.Generator.maxFreq) {
|
||||||
ui->frequency->setValueQuiet(VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq - ui->span->value()/2);
|
ui->frequency->setValueQuiet(DeviceDriver::getInfo(window->getDevice()).Limits.Generator.maxFreq - ui->span->value()/2);
|
||||||
}
|
}
|
||||||
|
|
||||||
newval = ui->frequency->value() - 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) {
|
connect(ui->current, &SIUnitEdit::valueChanged, [=](double newval) {
|
||||||
if(newval < 0 ) {
|
if(newval < 0 ) {
|
||||||
newval = 0;
|
newval = 0;
|
||||||
} else if (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 = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq - VirtualDevice::getInfo(window->getDevice()).Limits.minFreq;
|
newval = DeviceDriver::getInfo(window->getDevice()).Limits.Generator.maxFreq - DeviceDriver::getInfo(window->getDevice()).Limits.Generator.minFreq;
|
||||||
}
|
}
|
||||||
ui->current->setValueQuiet(newval);
|
ui->current->setValueQuiet(newval);
|
||||||
emit SettingsChanged();
|
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())
|
if (ui->EnabledSweep->isChecked())
|
||||||
s.freq = ui->current->value();
|
s.freq = ui->current->value();
|
||||||
else
|
else
|
||||||
@ -189,7 +189,7 @@ void SignalgeneratorWidget::deviceInfoUpdated()
|
|||||||
delete cb;
|
delete cb;
|
||||||
}
|
}
|
||||||
portCheckboxes.clear();
|
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));
|
auto cb = new QCheckBox("Port "+QString::number(i));
|
||||||
ui->portBox->layout()->addWidget(cb);
|
ui->portBox->layout()->addWidget(cb);
|
||||||
portCheckboxes.push_back(cb);
|
portCheckboxes.push_back(cb);
|
||||||
|
@ -18,7 +18,7 @@ public:
|
|||||||
explicit SignalgeneratorWidget(AppWindow *window, QWidget *parent = nullptr);
|
explicit SignalgeneratorWidget(AppWindow *window, QWidget *parent = nullptr);
|
||||||
~SignalgeneratorWidget();
|
~SignalgeneratorWidget();
|
||||||
|
|
||||||
VirtualDevice::SGSettings getDeviceStatus();
|
DeviceDriver::SGSettings getDeviceStatus();
|
||||||
virtual nlohmann::json toJSON() override;
|
virtual nlohmann::json toJSON() override;
|
||||||
virtual void fromJSON(nlohmann::json j) override;
|
virtual void fromJSON(nlohmann::json j) override;
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ HEADERS += \
|
|||||||
Device/deviceusblogview.h \
|
Device/deviceusblogview.h \
|
||||||
Device/firmwareupdatedialog.h \
|
Device/firmwareupdatedialog.h \
|
||||||
Device/librevnadriver.h \
|
Device/librevnadriver.h \
|
||||||
|
Device/librevnausbdriver.h \
|
||||||
Device/manualcontroldialog.h \
|
Device/manualcontroldialog.h \
|
||||||
Device/virtualdevice.h \
|
Device/virtualdevice.h \
|
||||||
Generator/generator.h \
|
Generator/generator.h \
|
||||||
@ -176,11 +177,13 @@ SOURCES += \
|
|||||||
Device/compounddevice.cpp \
|
Device/compounddevice.cpp \
|
||||||
Device/compounddeviceeditdialog.cpp \
|
Device/compounddeviceeditdialog.cpp \
|
||||||
Device/device.cpp \
|
Device/device.cpp \
|
||||||
|
Device/devicedriver.cpp \
|
||||||
Device/devicelog.cpp \
|
Device/devicelog.cpp \
|
||||||
Device/deviceusblog.cpp \
|
Device/deviceusblog.cpp \
|
||||||
Device/deviceusblogview.cpp \
|
Device/deviceusblogview.cpp \
|
||||||
Device/firmwareupdatedialog.cpp \
|
Device/firmwareupdatedialog.cpp \
|
||||||
Device/librevnadriver.cpp \
|
Device/librevnadriver.cpp \
|
||||||
|
Device/librevnausbdriver.cpp \
|
||||||
Device/manualcontroldialog.cpp \
|
Device/manualcontroldialog.cpp \
|
||||||
Device/virtualdevice.cpp \
|
Device/virtualdevice.cpp \
|
||||||
Generator/generator.cpp \
|
Generator/generator.cpp \
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
#include "Traces/Marker/markerwidget.h"
|
#include "Traces/Marker/markerwidget.h"
|
||||||
#include "Tools/impedancematchdialog.h"
|
#include "Tools/impedancematchdialog.h"
|
||||||
#include "ui_main.h"
|
#include "ui_main.h"
|
||||||
#include "Device/virtualdevice.h"
|
|
||||||
#include "preferences.h"
|
#include "preferences.h"
|
||||||
#include "Generator/signalgenwidget.h"
|
#include "Generator/signalgenwidget.h"
|
||||||
|
|
||||||
@ -191,7 +190,7 @@ SpectrumAnalyzer::SpectrumAnalyzer(AppWindow *window, QString name)
|
|||||||
cbWindowType->addItem("Flat Top");
|
cbWindowType->addItem("Flat Top");
|
||||||
cbWindowType->setCurrentIndex(1);
|
cbWindowType->setCurrentIndex(1);
|
||||||
connect(cbWindowType, qOverload<int>(&QComboBox::currentIndexChanged), [=](int index) {
|
connect(cbWindowType, qOverload<int>(&QComboBox::currentIndexChanged), [=](int index) {
|
||||||
SetWindow((VirtualDevice::SASettings::Window) index);
|
SetWindow((DeviceDriver::SASettings::Window) index);
|
||||||
});
|
});
|
||||||
tb_acq->addWidget(cbWindowType);
|
tb_acq->addWidget(cbWindowType);
|
||||||
|
|
||||||
@ -204,7 +203,7 @@ SpectrumAnalyzer::SpectrumAnalyzer(AppWindow *window, QString name)
|
|||||||
cbDetector->addItem("Average");
|
cbDetector->addItem("Average");
|
||||||
cbDetector->setCurrentIndex(0);
|
cbDetector->setCurrentIndex(0);
|
||||||
connect(cbDetector, qOverload<int>(&QComboBox::currentIndexChanged), [=](int index) {
|
connect(cbDetector, qOverload<int>(&QComboBox::currentIndexChanged), [=](int index) {
|
||||||
SetDetector((VirtualDevice::SASettings::Detector) index);
|
SetDetector((DeviceDriver::SASettings::Detector) index);
|
||||||
});
|
});
|
||||||
tb_acq->addWidget(cbDetector);
|
tb_acq->addWidget(cbDetector);
|
||||||
|
|
||||||
@ -219,10 +218,6 @@ SpectrumAnalyzer::SpectrumAnalyzer(AppWindow *window, QString name)
|
|||||||
connect(this, &SpectrumAnalyzer::averagingChanged, sbAverages, &QSpinBox::setValue);
|
connect(this, &SpectrumAnalyzer::averagingChanged, sbAverages, &QSpinBox::setValue);
|
||||||
tb_acq->addWidget(sbAverages);
|
tb_acq->addWidget(sbAverages);
|
||||||
|
|
||||||
cbSignalID = new QCheckBox("Signal ID");
|
|
||||||
connect(cbSignalID, &QCheckBox::toggled, this, &SpectrumAnalyzer::SetSignalID);
|
|
||||||
tb_acq->addWidget(cbSignalID);
|
|
||||||
|
|
||||||
window->addToolBar(tb_acq);
|
window->addToolBar(tb_acq);
|
||||||
toolbars.insert(tb_acq);
|
toolbars.insert(tb_acq);
|
||||||
|
|
||||||
@ -321,10 +316,8 @@ SpectrumAnalyzer::SpectrumAnalyzer(AppWindow *window, QString name)
|
|||||||
ConstrainAndUpdateFrequencies();
|
ConstrainAndUpdateFrequencies();
|
||||||
SetRBW(pref.Startup.SA.RBW);
|
SetRBW(pref.Startup.SA.RBW);
|
||||||
SetAveraging(pref.Startup.SA.averaging);
|
SetAveraging(pref.Startup.SA.averaging);
|
||||||
settings.points = 1001;
|
SetWindow((DeviceDriver::SASettings::Window) pref.Startup.SA.window);
|
||||||
SetWindow((VirtualDevice::SASettings::Window) pref.Startup.SA.window);
|
SetDetector((DeviceDriver::SASettings::Detector) pref.Startup.SA.detector);
|
||||||
SetDetector((VirtualDevice::SASettings::Detector) pref.Startup.SA.detector);
|
|
||||||
SetSignalID(pref.Startup.SA.signalID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
finalize(central);
|
finalize(central);
|
||||||
@ -338,7 +331,7 @@ void SpectrumAnalyzer::deactivate()
|
|||||||
|
|
||||||
void SpectrumAnalyzer::initializeDevice()
|
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
|
// Configure initial state of device
|
||||||
SettingsChanged();
|
SettingsChanged();
|
||||||
@ -361,9 +354,8 @@ nlohmann::json SpectrumAnalyzer::toJSON()
|
|||||||
sweep["single"] = singleSweep;
|
sweep["single"] = singleSweep;
|
||||||
nlohmann::json acq;
|
nlohmann::json acq;
|
||||||
acq["RBW"] = settings.RBW;
|
acq["RBW"] = settings.RBW;
|
||||||
acq["window"] = WindowToString((VirtualDevice::SASettings::Window) settings.window).toStdString();
|
acq["window"] = WindowToString((DeviceDriver::SASettings::Window) settings.window).toStdString();
|
||||||
acq["detector"] = DetectorToString((VirtualDevice::SASettings::Detector) settings.detector).toStdString();
|
acq["detector"] = DetectorToString((DeviceDriver::SASettings::Detector) settings.detector).toStdString();
|
||||||
acq["signal ID"] = settings.signalID ? true : false;
|
|
||||||
sweep["acquisition"] = acq;
|
sweep["acquisition"] = acq;
|
||||||
nlohmann::json tracking;
|
nlohmann::json tracking;
|
||||||
tracking["enabled"] = settings.trackingGenerator ? true : false;
|
tracking["enabled"] = settings.trackingGenerator ? true : false;
|
||||||
@ -419,18 +411,17 @@ void SpectrumAnalyzer::fromJSON(nlohmann::json j)
|
|||||||
auto acq = sweep["acquisition"];
|
auto acq = sweep["acquisition"];
|
||||||
SetRBW(acq.value("RBW", settings.RBW));
|
SetRBW(acq.value("RBW", settings.RBW));
|
||||||
auto w = WindowFromString(QString::fromStdString(acq.value("window", "")));
|
auto w = WindowFromString(QString::fromStdString(acq.value("window", "")));
|
||||||
if(w == VirtualDevice::SASettings::Window::Last) {
|
if(w == DeviceDriver::SASettings::Window::Last) {
|
||||||
// invalid, keep current value
|
// invalid, keep current value
|
||||||
w = (VirtualDevice::SASettings::Window) settings.window;
|
w = (DeviceDriver::SASettings::Window) settings.window;
|
||||||
}
|
}
|
||||||
SetWindow(w);
|
SetWindow(w);
|
||||||
auto d = DetectorFromString(QString::fromStdString(acq.value("detector", "")));
|
auto d = DetectorFromString(QString::fromStdString(acq.value("detector", "")));
|
||||||
if(d == VirtualDevice::SASettings::Detector::Last) {
|
if(d == DeviceDriver::SASettings::Detector::Last) {
|
||||||
// invalid, keep current value
|
// invalid, keep current value
|
||||||
d = (VirtualDevice::SASettings::Detector) settings.detector;
|
d = (DeviceDriver::SASettings::Detector) settings.detector;
|
||||||
}
|
}
|
||||||
SetDetector(d);
|
SetDetector(d);
|
||||||
SetSignalID(acq.value("signal ID", settings.signalID ? true : false));
|
|
||||||
}
|
}
|
||||||
if(sweep.contains("trackingGenerator")) {
|
if(sweep.contains("trackingGenerator")) {
|
||||||
auto tracking = sweep["trackingGenerator"];
|
auto tracking = sweep["trackingGenerator"];
|
||||||
@ -473,8 +464,8 @@ void SpectrumAnalyzer::fromJSON(nlohmann::json j)
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
void SpectrumAnalyzer::NewDatapoint(VirtualDevice::SAMeasurement m)
|
void SpectrumAnalyzer::NewDatapoint(DeviceDriver::SAMeasurement m)
|
||||||
{
|
{
|
||||||
if(isActive != true) {
|
if(isActive != true) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -488,11 +479,6 @@ void SpectrumAnalyzer::NewDatapoint(VirtualDevice::SAMeasurement m)
|
|||||||
Stop();
|
Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m.pointNum >= settings.points) {
|
|
||||||
qWarning() << "Ignoring point with too large point number (" << m.pointNum << ")";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto m_avg = average.process(m);
|
auto m_avg = average.process(m);
|
||||||
|
|
||||||
if(settings.freqStart == settings.freqStop) {
|
if(settings.freqStart == settings.freqStop) {
|
||||||
@ -513,18 +499,18 @@ void SpectrumAnalyzer::NewDatapoint(VirtualDevice::SAMeasurement m)
|
|||||||
for(auto m : m_avg.measurements) {
|
for(auto m : m_avg.measurements) {
|
||||||
normalize.portCorrection[m.first].push_back(m.second);
|
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
|
// this was the last point
|
||||||
normalize.measuring = false;
|
normalize.measuring = false;
|
||||||
normalize.f_start = settings.freqStart;
|
normalize.f_start = settings.freqStart;
|
||||||
normalize.f_stop = settings.freqStop;
|
normalize.f_stop = settings.freqStop;
|
||||||
normalize.points = settings.points;
|
normalize.points = DeviceDriver::getActiveDriver()->getSApoints();
|
||||||
EnableNormalization(true);
|
EnableNormalization(true);
|
||||||
qDebug() << "Normalization measurement complete";
|
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);
|
normalize.dialog.setValue(percentage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -538,7 +524,7 @@ void SpectrumAnalyzer::NewDatapoint(VirtualDevice::SAMeasurement m)
|
|||||||
|
|
||||||
traceModel.addSAData(m_avg, settings);
|
traceModel.addSAData(m_avg, settings);
|
||||||
emit dataChanged();
|
emit dataChanged();
|
||||||
if(m_avg.pointNum == settings.points - 1) {
|
if(m_avg.pointNum == DeviceDriver::getActiveDriver()->getSApoints() - 1) {
|
||||||
UpdateAverageCount();
|
UpdateAverageCount();
|
||||||
markerModel->updateMarkers();
|
markerModel->updateMarkers();
|
||||||
}
|
}
|
||||||
@ -576,14 +562,14 @@ void SpectrumAnalyzer::SetStopFreq(double freq)
|
|||||||
void SpectrumAnalyzer::SetCenterFreq(double freq)
|
void SpectrumAnalyzer::SetCenterFreq(double freq)
|
||||||
{
|
{
|
||||||
auto old_span = settings.freqStop - settings.freqStart;
|
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
|
// would shift start frequency below minimum
|
||||||
settings.freqStart = 0;
|
settings.freqStart = 0;
|
||||||
settings.freqStop = 2 * freq;
|
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
|
// would shift stop frequency above maximum
|
||||||
settings.freqStart = 2 * freq - VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq;
|
settings.freqStart = 2 * freq - DeviceDriver::getInfo(window->getDevice()).Limits.SA.maxFreq;
|
||||||
settings.freqStop = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq;
|
settings.freqStop = DeviceDriver::getInfo(window->getDevice()).Limits.SA.maxFreq;
|
||||||
} else {
|
} else {
|
||||||
settings.freqStart = freq - old_span / 2;
|
settings.freqStart = freq - old_span / 2;
|
||||||
settings.freqStop = freq + old_span / 2;
|
settings.freqStop = freq + old_span / 2;
|
||||||
@ -594,14 +580,14 @@ void SpectrumAnalyzer::SetCenterFreq(double freq)
|
|||||||
void SpectrumAnalyzer::SetSpan(double span)
|
void SpectrumAnalyzer::SetSpan(double span)
|
||||||
{
|
{
|
||||||
auto old_center = (settings.freqStart + settings.freqStop) / 2;
|
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
|
// would shift start frequency below minimum
|
||||||
settings.freqStart = VirtualDevice::getInfo(window->getDevice()).Limits.minFreq;
|
settings.freqStart = DeviceDriver::getInfo(window->getDevice()).Limits.SA.minFreq;
|
||||||
settings.freqStop = VirtualDevice::getInfo(window->getDevice()).Limits.minFreq + span;
|
settings.freqStop = DeviceDriver::getInfo(window->getDevice()).Limits.SA.minFreq + span;
|
||||||
} else if(old_center > VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq - span / 2) {
|
} else if(old_center > DeviceDriver::getInfo(window->getDevice()).Limits.SA.maxFreq - span / 2) {
|
||||||
// would shift stop frequency above maximum
|
// would shift stop frequency above maximum
|
||||||
settings.freqStart = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq - span;
|
settings.freqStart = DeviceDriver::getInfo(window->getDevice()).Limits.SA.maxFreq - span;
|
||||||
settings.freqStop = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq;
|
settings.freqStop = DeviceDriver::getInfo(window->getDevice()).Limits.SA.maxFreq;
|
||||||
} else {
|
} else {
|
||||||
settings.freqStart = old_center - span / 2;
|
settings.freqStart = old_center - span / 2;
|
||||||
settings.freqStop = settings.freqStart + span;
|
settings.freqStop = settings.freqStart + span;
|
||||||
@ -616,8 +602,8 @@ void SpectrumAnalyzer::SetFullSpan()
|
|||||||
settings.freqStart = pref.Acquisition.fullSpanStart;
|
settings.freqStart = pref.Acquisition.fullSpanStart;
|
||||||
settings.freqStop = pref.Acquisition.fullSpanStop;
|
settings.freqStop = pref.Acquisition.fullSpanStop;
|
||||||
} else {
|
} else {
|
||||||
settings.freqStart = VirtualDevice::getInfo(window->getDevice()).Limits.minFreq;
|
settings.freqStart = DeviceDriver::getInfo(window->getDevice()).Limits.SA.minFreq;
|
||||||
settings.freqStop = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq;
|
settings.freqStop = DeviceDriver::getInfo(window->getDevice()).Limits.SA.maxFreq;
|
||||||
}
|
}
|
||||||
ConstrainAndUpdateFrequencies();
|
ConstrainAndUpdateFrequencies();
|
||||||
}
|
}
|
||||||
@ -664,24 +650,24 @@ void SpectrumAnalyzer::SetSingleSweep(bool single)
|
|||||||
|
|
||||||
void SpectrumAnalyzer::SetRBW(double bandwidth)
|
void SpectrumAnalyzer::SetRBW(double bandwidth)
|
||||||
{
|
{
|
||||||
if(bandwidth > VirtualDevice::getInfo(window->getDevice()).Limits.maxRBW) {
|
if(bandwidth > DeviceDriver::getInfo(window->getDevice()).Limits.SA.maxRBW) {
|
||||||
bandwidth = VirtualDevice::getInfo(window->getDevice()).Limits.maxRBW;
|
bandwidth = DeviceDriver::getInfo(window->getDevice()).Limits.SA.maxRBW;
|
||||||
} else if(bandwidth < VirtualDevice::getInfo(window->getDevice()).Limits.minRBW) {
|
} else if(bandwidth < DeviceDriver::getInfo(window->getDevice()).Limits.SA.minRBW) {
|
||||||
bandwidth = VirtualDevice::getInfo(window->getDevice()).Limits.minRBW;
|
bandwidth = DeviceDriver::getInfo(window->getDevice()).Limits.SA.minRBW;
|
||||||
}
|
}
|
||||||
settings.RBW = bandwidth;
|
settings.RBW = bandwidth;
|
||||||
emit RBWChanged(settings.RBW);
|
emit RBWChanged(settings.RBW);
|
||||||
SettingsChanged();
|
SettingsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpectrumAnalyzer::SetWindow(VirtualDevice::SASettings::Window w)
|
void SpectrumAnalyzer::SetWindow(DeviceDriver::SASettings::Window w)
|
||||||
{
|
{
|
||||||
settings.window = w;
|
settings.window = w;
|
||||||
cbWindowType->setCurrentIndex((int) w);
|
cbWindowType->setCurrentIndex((int) w);
|
||||||
SettingsChanged();
|
SettingsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpectrumAnalyzer::SetDetector(VirtualDevice::SASettings::Detector d)
|
void SpectrumAnalyzer::SetDetector(DeviceDriver::SASettings::Detector d)
|
||||||
{
|
{
|
||||||
settings.detector = d;
|
settings.detector = d;
|
||||||
cbDetector->setCurrentIndex((int) d);
|
cbDetector->setCurrentIndex((int) d);
|
||||||
@ -696,13 +682,6 @@ void SpectrumAnalyzer::SetAveraging(unsigned int averages)
|
|||||||
SettingsChanged();
|
SettingsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpectrumAnalyzer::SetSignalID(bool enabled)
|
|
||||||
{
|
|
||||||
settings.signalID = enabled ? 1 : 0;
|
|
||||||
cbSignalID->setChecked(enabled);
|
|
||||||
SettingsChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SpectrumAnalyzer::SetTGEnabled(bool enabled)
|
void SpectrumAnalyzer::SetTGEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
if(enabled != settings.trackingGenerator) {
|
if(enabled != settings.trackingGenerator) {
|
||||||
@ -735,10 +714,10 @@ void SpectrumAnalyzer::SetTGPort(int port)
|
|||||||
|
|
||||||
void SpectrumAnalyzer::SetTGLevel(double level)
|
void SpectrumAnalyzer::SetTGLevel(double level)
|
||||||
{
|
{
|
||||||
if(level > VirtualDevice::getInfo(window->getDevice()).Limits.maxdBm) {
|
if(level > DeviceDriver::getInfo(window->getDevice()).Limits.SA.maxdBm) {
|
||||||
level = VirtualDevice::getInfo(window->getDevice()).Limits.maxdBm;
|
level = DeviceDriver::getInfo(window->getDevice()).Limits.SA.maxdBm;
|
||||||
} else if(level < VirtualDevice::getInfo(window->getDevice()).Limits.mindBm) {
|
} else if(level < DeviceDriver::getInfo(window->getDevice()).Limits.SA.mindBm) {
|
||||||
level = VirtualDevice::getInfo(window->getDevice()).Limits.mindBm;
|
level = DeviceDriver::getInfo(window->getDevice()).Limits.SA.mindBm;
|
||||||
}
|
}
|
||||||
emit TGLevelChanged(level);
|
emit TGLevelChanged(level);
|
||||||
settings.trackingPower = level * 100;
|
settings.trackingPower = level * 100;
|
||||||
@ -842,51 +821,47 @@ void SpectrumAnalyzer::ConfigureDevice()
|
|||||||
{
|
{
|
||||||
if(running) {
|
if(running) {
|
||||||
changingSettings = true;
|
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) {
|
// TODO move into libreVNA driver
|
||||||
// Check point spacing.
|
// if(settings.trackingGenerator && settings.freqStop >= 25000000) {
|
||||||
// The highband PLL used as the tracking generator is not able to reach every frequency exactly. This
|
// // Check point spacing.
|
||||||
// could lead to sharp drops in the spectrum at certain frequencies. If the span is wide enough with
|
// // The highband PLL used as the tracking generator is not able to reach every frequency exactly. This
|
||||||
// respect to the point number, it is ensured that every displayed point has at least one sample with
|
// // could lead to sharp drops in the spectrum at certain frequencies. If the span is wide enough with
|
||||||
// a reachable PLL frequency in it. Display a warning message if this is not the case with the current
|
// // respect to the point number, it is ensured that every displayed point has at least one sample with
|
||||||
// settings.
|
// // a reachable PLL frequency in it. Display a warning message if this is not the case with the current
|
||||||
auto pointSpacing = (settings.freqStop - settings.freqStart) / (settings.points - 1);
|
// // settings.
|
||||||
// The frequency resolution of the PLL is frequency dependent (due to PLL divider).
|
// auto pointSpacing = (settings.freqStop - settings.freqStart) / (settings.points - 1);
|
||||||
// This code assumes some knowledge of the actual hardware and probably should be moved
|
// // The frequency resolution of the PLL is frequency dependent (due to PLL divider).
|
||||||
// onto the device at some point
|
// // This code assumes some knowledge of the actual hardware and probably should be moved
|
||||||
double minSpacing = 25000;
|
// // onto the device at some point
|
||||||
auto stop = settings.freqStop;
|
// double minSpacing = 25000;
|
||||||
while(stop <= 3000000000) {
|
// auto stop = settings.freqStop;
|
||||||
minSpacing /= 2;
|
// while(stop <= 3000000000) {
|
||||||
stop *= 2;
|
// minSpacing /= 2;
|
||||||
}
|
// stop *= 2;
|
||||||
if(pointSpacing < minSpacing) {
|
// }
|
||||||
auto requiredMinSpan = minSpacing * (settings.points - 1);
|
// if(pointSpacing < minSpacing) {
|
||||||
auto message = QString() + "Due to PLL limitations, the tracking generator can not reach every frequency exactly. "
|
// auto requiredMinSpan = minSpacing * (settings.points - 1);
|
||||||
"With your current span, this could result in the signal not being detected at some bands. A minimum"
|
// auto message = QString() + "Due to PLL limitations, the tracking generator can not reach every frequency exactly. "
|
||||||
" span of " + Unit::ToString(requiredMinSpan, "Hz", " kMG") + " is recommended at this stop frequency.";
|
// "With your current span, this could result in the signal not being detected at some bands. A minimum"
|
||||||
InformationBox::ShowMessage("Warning", message, "TrackingGeneratorSpanTooSmallWarning");
|
// " 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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(window->getDevice() && isActive) {
|
if(window->getDevice() && isActive) {
|
||||||
window->getDevice()->setSA(settings, [=](bool){
|
window->getDevice()->setSA(settings, [=](bool){
|
||||||
// device received command
|
// device received command
|
||||||
changingSettings = false;
|
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();
|
emit sweepStarted();
|
||||||
} else {
|
} else {
|
||||||
@ -894,7 +869,7 @@ void SpectrumAnalyzer::ConfigureDevice()
|
|||||||
emit sweepStopped();
|
emit sweepStopped();
|
||||||
changingSettings = false;
|
changingSettings = false;
|
||||||
}
|
}
|
||||||
average.reset(settings.points);
|
average.reset(DeviceDriver::getActiveDriver()->getSApoints());
|
||||||
UpdateAverageCount();
|
UpdateAverageCount();
|
||||||
traceModel.clearLiveData();
|
traceModel.clearLiveData();
|
||||||
emit traceModel.SpanChanged(settings.freqStart, settings.freqStop);
|
emit traceModel.SpanChanged(settings.freqStart, settings.freqStop);
|
||||||
@ -915,7 +890,7 @@ void SpectrumAnalyzer::ConfigureDevice()
|
|||||||
|
|
||||||
void SpectrumAnalyzer::ResetLiveTraces()
|
void SpectrumAnalyzer::ResetLiveTraces()
|
||||||
{
|
{
|
||||||
average.reset(settings.points);
|
average.reset(DeviceDriver::getActiveDriver()->getSApoints());
|
||||||
traceModel.clearLiveData();
|
traceModel.clearLiveData();
|
||||||
UpdateAverageCount();
|
UpdateAverageCount();
|
||||||
}
|
}
|
||||||
@ -996,23 +971,23 @@ void SpectrumAnalyzer::SetupSCPI()
|
|||||||
return SCPI::getResultName(SCPI::Result::Error);
|
return SCPI::getResultName(SCPI::Result::Error);
|
||||||
}
|
}
|
||||||
if (params[0] == "NONE") {
|
if (params[0] == "NONE") {
|
||||||
SetWindow(VirtualDevice::SASettings::Window::None);
|
SetWindow(DeviceDriver::SASettings::Window::None);
|
||||||
} else if(params[0] == "KAISER") {
|
} else if(params[0] == "KAISER") {
|
||||||
SetWindow(VirtualDevice::SASettings::Window::Kaiser);
|
SetWindow(DeviceDriver::SASettings::Window::Kaiser);
|
||||||
} else if(params[0] == "HANN") {
|
} else if(params[0] == "HANN") {
|
||||||
SetWindow(VirtualDevice::SASettings::Window::Hann);
|
SetWindow(DeviceDriver::SASettings::Window::Hann);
|
||||||
} else if(params[0] == "FLATTOP") {
|
} else if(params[0] == "FLATTOP") {
|
||||||
SetWindow(VirtualDevice::SASettings::Window::FlatTop);
|
SetWindow(DeviceDriver::SASettings::Window::FlatTop);
|
||||||
} else {
|
} else {
|
||||||
return "INVALID WINDOW";
|
return "INVALID WINDOW";
|
||||||
}
|
}
|
||||||
return SCPI::getResultName(SCPI::Result::Empty);
|
return SCPI::getResultName(SCPI::Result::Empty);
|
||||||
}, [=](QStringList) -> QString {
|
}, [=](QStringList) -> QString {
|
||||||
switch((VirtualDevice::SASettings::Window) settings.window) {
|
switch((DeviceDriver::SASettings::Window) settings.window) {
|
||||||
case VirtualDevice::SASettings::Window::None: return "NONE";
|
case DeviceDriver::SASettings::Window::None: return "NONE";
|
||||||
case VirtualDevice::SASettings::Window::Kaiser: return "KAISER";
|
case DeviceDriver::SASettings::Window::Kaiser: return "KAISER";
|
||||||
case VirtualDevice::SASettings::Window::Hann: return "HANN";
|
case DeviceDriver::SASettings::Window::Hann: return "HANN";
|
||||||
case VirtualDevice::SASettings::Window::FlatTop: return "FLATTOP";
|
case DeviceDriver::SASettings::Window::FlatTop: return "FLATTOP";
|
||||||
default: return SCPI::getResultName(SCPI::Result::Error);
|
default: return SCPI::getResultName(SCPI::Result::Error);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
@ -1021,26 +996,26 @@ void SpectrumAnalyzer::SetupSCPI()
|
|||||||
return SCPI::getResultName(SCPI::Result::Error);
|
return SCPI::getResultName(SCPI::Result::Error);
|
||||||
}
|
}
|
||||||
if (params[0] == "+PEAK") {
|
if (params[0] == "+PEAK") {
|
||||||
SetDetector(VirtualDevice::SASettings::Detector::PPeak);
|
SetDetector(DeviceDriver::SASettings::Detector::PPeak);
|
||||||
} else if(params[0] == "-PEAK") {
|
} else if(params[0] == "-PEAK") {
|
||||||
SetDetector(VirtualDevice::SASettings::Detector::NPeak);
|
SetDetector(DeviceDriver::SASettings::Detector::NPeak);
|
||||||
} else if(params[0] == "NORMAL") {
|
} else if(params[0] == "NORMAL") {
|
||||||
SetDetector(VirtualDevice::SASettings::Detector::Normal);
|
SetDetector(DeviceDriver::SASettings::Detector::Normal);
|
||||||
} else if(params[0] == "SAMPLE") {
|
} else if(params[0] == "SAMPLE") {
|
||||||
SetDetector(VirtualDevice::SASettings::Detector::Sample);
|
SetDetector(DeviceDriver::SASettings::Detector::Sample);
|
||||||
} else if(params[0] == "AVERAGE") {
|
} else if(params[0] == "AVERAGE") {
|
||||||
SetDetector(VirtualDevice::SASettings::Detector::Average);
|
SetDetector(DeviceDriver::SASettings::Detector::Average);
|
||||||
} else {
|
} else {
|
||||||
return "INVALID MDOE";
|
return "INVALID MDOE";
|
||||||
}
|
}
|
||||||
return SCPI::getResultName(SCPI::Result::Empty);
|
return SCPI::getResultName(SCPI::Result::Empty);
|
||||||
}, [=](QStringList) -> QString {
|
}, [=](QStringList) -> QString {
|
||||||
switch((VirtualDevice::SASettings::Detector) settings.detector) {
|
switch((DeviceDriver::SASettings::Detector) settings.detector) {
|
||||||
case VirtualDevice::SASettings::Detector::PPeak: return "+PEAK";
|
case DeviceDriver::SASettings::Detector::PPeak: return "+PEAK";
|
||||||
case VirtualDevice::SASettings::Detector::NPeak: return "-PEAK";
|
case DeviceDriver::SASettings::Detector::NPeak: return "-PEAK";
|
||||||
case VirtualDevice::SASettings::Detector::Normal: return "NORMAL";
|
case DeviceDriver::SASettings::Detector::Normal: return "NORMAL";
|
||||||
case VirtualDevice::SASettings::Detector::Sample: return "SAMPLE";
|
case DeviceDriver::SASettings::Detector::Sample: return "SAMPLE";
|
||||||
case VirtualDevice::SASettings::Detector::Average: return "AVERAGE";
|
case DeviceDriver::SASettings::Detector::Average: return "AVERAGE";
|
||||||
default: return SCPI::getResultName(SCPI::Result::Error);
|
default: return SCPI::getResultName(SCPI::Result::Error);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
@ -1064,21 +1039,6 @@ void SpectrumAnalyzer::SetupSCPI()
|
|||||||
scpi_acq->add(new SCPICommand("LIMit", nullptr, [=](QStringList) -> QString {
|
scpi_acq->add(new SCPICommand("LIMit", nullptr, [=](QStringList) -> QString {
|
||||||
return tiles->allLimitsPassing() ? "PASS" : "FAIL";
|
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 {
|
scpi_acq->add(new SCPICommand("SINGLE", [=](QStringList params) -> QString {
|
||||||
bool single;
|
bool single;
|
||||||
if(!SCPI::paramToBool(params, 0, single)) {
|
if(!SCPI::paramToBool(params, 0, single)) {
|
||||||
@ -1124,7 +1084,7 @@ void SpectrumAnalyzer::SetupSCPI()
|
|||||||
unsigned long long newval;
|
unsigned long long newval;
|
||||||
if(!SCPI::paramToULongLong(params, 0, newval)) {
|
if(!SCPI::paramToULongLong(params, 0, newval)) {
|
||||||
return SCPI::getResultName(SCPI::Result::Error);
|
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);
|
SetTGPort(newval-1);
|
||||||
return SCPI::getResultName(SCPI::Result::Empty);
|
return SCPI::getResultName(SCPI::Result::Empty);
|
||||||
} else {
|
} else {
|
||||||
@ -1200,24 +1160,24 @@ void SpectrumAnalyzer::UpdateAverageCount()
|
|||||||
|
|
||||||
void SpectrumAnalyzer::ConstrainAndUpdateFrequencies()
|
void SpectrumAnalyzer::ConstrainAndUpdateFrequencies()
|
||||||
{
|
{
|
||||||
if(settings.freqStop > VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq) {
|
if(settings.freqStop > DeviceDriver::getInfo(window->getDevice()).Limits.SA.maxFreq) {
|
||||||
settings.freqStop = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq;
|
settings.freqStop = DeviceDriver::getInfo(window->getDevice()).Limits.SA.maxFreq;
|
||||||
}
|
}
|
||||||
if(settings.freqStart > settings.freqStop) {
|
if(settings.freqStart > settings.freqStop) {
|
||||||
settings.freqStart = settings.freqStop;
|
settings.freqStart = settings.freqStop;
|
||||||
}
|
}
|
||||||
if(settings.freqStart < VirtualDevice::getInfo(window->getDevice()).Limits.minFreq) {
|
if(settings.freqStart < DeviceDriver::getInfo(window->getDevice()).Limits.SA.minFreq) {
|
||||||
settings.freqStart = VirtualDevice::getInfo(window->getDevice()).Limits.minFreq;
|
settings.freqStart = DeviceDriver::getInfo(window->getDevice()).Limits.SA.minFreq;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool trackingOffset_limited = false;
|
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;
|
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;
|
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) {
|
if(trackingOffset_limited) {
|
||||||
InformationBox::ShowMessage("Warning", "The selected tracking generator offset is not reachable for all frequencies with the current span. "
|
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();
|
settings.freqStop = s.value("SAStop", pref.Startup.SA.stop).toULongLong();
|
||||||
ConstrainAndUpdateFrequencies();
|
ConstrainAndUpdateFrequencies();
|
||||||
SetRBW(s.value("SARBW", pref.Startup.SA.RBW).toUInt());
|
SetRBW(s.value("SARBW", pref.Startup.SA.RBW).toUInt());
|
||||||
settings.points = 1001;
|
SetWindow((DeviceDriver::SASettings::Window) s.value("SAWindow", pref.Startup.SA.window).toInt());
|
||||||
SetWindow((VirtualDevice::SASettings::Window) s.value("SAWindow", pref.Startup.SA.window).toInt());
|
SetDetector((DeviceDriver::SASettings::Detector) s.value("SADetector", pref.Startup.SA.detector).toInt());
|
||||||
SetDetector((VirtualDevice::SASettings::Detector) s.value("SADetector", pref.Startup.SA.detector).toInt());
|
|
||||||
SetSignalID(s.value("SASignalID", pref.Startup.SA.signalID).toBool());
|
|
||||||
SetAveraging(s.value("SAAveraging", pref.Startup.SA.averaging).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("SAWindow", (int) settings.window);
|
||||||
s.setValue("SADetector", (int) settings.detector);
|
s.setValue("SADetector", (int) settings.detector);
|
||||||
s.setValue("SAAveraging", averages);
|
s.setValue("SAAveraging", averages);
|
||||||
s.setValue("SASignalID", static_cast<bool>(settings.signalID));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpectrumAnalyzer::createDefaultTracesAndGraphs(int ports)
|
void SpectrumAnalyzer::createDefaultTracesAndGraphs(int ports)
|
||||||
@ -1291,7 +1248,7 @@ void SpectrumAnalyzer::preset()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Create default traces
|
// Create default traces
|
||||||
createDefaultTracesAndGraphs(VirtualDevice::getInfo(window->getDevice()).ports);
|
createDefaultTracesAndGraphs(DeviceDriver::getInfo(window->getDevice()).Limits.SA.ports);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpectrumAnalyzer::deviceInfoUpdated()
|
void SpectrumAnalyzer::deviceInfoUpdated()
|
||||||
@ -1300,53 +1257,53 @@ void SpectrumAnalyzer::deviceInfoUpdated()
|
|||||||
ClearNormalization();
|
ClearNormalization();
|
||||||
auto tgPort = cbTrackGenPort->currentIndex();
|
auto tgPort = cbTrackGenPort->currentIndex();
|
||||||
cbTrackGenPort->clear();
|
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));
|
cbTrackGenPort->addItem("Port "+QString::number(i+1));
|
||||||
}
|
}
|
||||||
SetTGPort(tgPort);
|
SetTGPort(tgPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SpectrumAnalyzer::WindowToString(VirtualDevice::SASettings::Window w)
|
QString SpectrumAnalyzer::WindowToString(DeviceDriver::SASettings::Window w)
|
||||||
{
|
{
|
||||||
switch(w) {
|
switch(w) {
|
||||||
case VirtualDevice::SASettings::Window::None: return "None";
|
case DeviceDriver::SASettings::Window::None: return "None";
|
||||||
case VirtualDevice::SASettings::Window::Kaiser: return "Kaiser";
|
case DeviceDriver::SASettings::Window::Kaiser: return "Kaiser";
|
||||||
case VirtualDevice::SASettings::Window::Hann: return "Hann";
|
case DeviceDriver::SASettings::Window::Hann: return "Hann";
|
||||||
case VirtualDevice::SASettings::Window::FlatTop: return "FlatTop";
|
case DeviceDriver::SASettings::Window::FlatTop: return "FlatTop";
|
||||||
default: return "Unknown";
|
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++) {
|
for(int i=0;i<(int)DeviceDriver::SASettings::Window::Last;i++) {
|
||||||
if(WindowToString((VirtualDevice::SASettings::Window) i) == s) {
|
if(WindowToString((DeviceDriver::SASettings::Window) i) == s) {
|
||||||
return (VirtualDevice::SASettings::Window) i;
|
return (DeviceDriver::SASettings::Window) i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// not found
|
// 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) {
|
switch(d) {
|
||||||
case VirtualDevice::SASettings::Detector::PPeak: return "+Peak";
|
case DeviceDriver::SASettings::Detector::PPeak: return "+Peak";
|
||||||
case VirtualDevice::SASettings::Detector::NPeak: return "-Peak";
|
case DeviceDriver::SASettings::Detector::NPeak: return "-Peak";
|
||||||
case VirtualDevice::SASettings::Detector::Sample: return "Sample";
|
case DeviceDriver::SASettings::Detector::Sample: return "Sample";
|
||||||
case VirtualDevice::SASettings::Detector::Normal: return "Normal";
|
case DeviceDriver::SASettings::Detector::Normal: return "Normal";
|
||||||
case VirtualDevice::SASettings::Detector::Average: return "Average";
|
case DeviceDriver::SASettings::Detector::Average: return "Average";
|
||||||
default: return "Unknown";
|
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++) {
|
for(int i=0;i<(int)DeviceDriver::SASettings::Detector::Last;i++) {
|
||||||
if(DetectorToString((VirtualDevice::SASettings::Detector) i) == s) {
|
if(DetectorToString((DeviceDriver::SASettings::Detector) i) == s) {
|
||||||
return (VirtualDevice::SASettings::Detector) i;
|
return (DeviceDriver::SASettings::Detector) i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// not found
|
// not found
|
||||||
return VirtualDevice::SASettings::Detector::Last;
|
return DeviceDriver::SASettings::Detector::Last;
|
||||||
}
|
}
|
||||||
|
@ -38,13 +38,13 @@ public:
|
|||||||
virtual void deviceInfoUpdated() override;
|
virtual void deviceInfoUpdated() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static QString WindowToString(VirtualDevice::SASettings::Window w);
|
static QString WindowToString(DeviceDriver::SASettings::Window w);
|
||||||
static VirtualDevice::SASettings::Window WindowFromString(QString s);
|
static DeviceDriver::SASettings::Window WindowFromString(QString s);
|
||||||
static QString DetectorToString(VirtualDevice::SASettings::Detector d);
|
static QString DetectorToString(DeviceDriver::SASettings::Detector d);
|
||||||
static VirtualDevice::SASettings::Detector DetectorFromString(QString s);
|
static DeviceDriver::SASettings::Detector DetectorFromString(QString s);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void NewDatapoint(VirtualDevice::SAMeasurement m);
|
void NewDatapoint(DeviceDriver::SAMeasurement m);
|
||||||
// Sweep control
|
// Sweep control
|
||||||
void SetStartFreq(double freq);
|
void SetStartFreq(double freq);
|
||||||
void SetStopFreq(double freq);
|
void SetStopFreq(double freq);
|
||||||
@ -57,10 +57,9 @@ private slots:
|
|||||||
void SetSingleSweep(bool single);
|
void SetSingleSweep(bool single);
|
||||||
// Acquisition control
|
// Acquisition control
|
||||||
void SetRBW(double bandwidth);
|
void SetRBW(double bandwidth);
|
||||||
void SetWindow(VirtualDevice::SASettings::Window w);
|
void SetWindow(DeviceDriver::SASettings::Window w);
|
||||||
void SetDetector(VirtualDevice::SASettings::Detector d);
|
void SetDetector(DeviceDriver::SASettings::Detector d);
|
||||||
void SetAveraging(unsigned int averages);
|
void SetAveraging(unsigned int averages);
|
||||||
void SetSignalID(bool enabled);
|
|
||||||
// TG control
|
// TG control
|
||||||
void SetTGEnabled(bool enabled);
|
void SetTGEnabled(bool enabled);
|
||||||
void SetTGPort(int port);
|
void SetTGPort(int port);
|
||||||
@ -87,7 +86,7 @@ private:
|
|||||||
|
|
||||||
void createDefaultTracesAndGraphs(int ports);
|
void createDefaultTracesAndGraphs(int ports);
|
||||||
|
|
||||||
VirtualDevice::SASettings settings;
|
DeviceDriver::SASettings settings;
|
||||||
bool changingSettings;
|
bool changingSettings;
|
||||||
unsigned int averages;
|
unsigned int averages;
|
||||||
bool singleSweep;
|
bool singleSweep;
|
||||||
|
@ -139,7 +139,7 @@ void Trace::addData(const Trace::Data& d, DataType domain, double reference_impe
|
|||||||
emit outputSamplesChanged(index, index + 1);
|
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.SA = s;
|
||||||
settings.valid = true;
|
settings.valid = true;
|
||||||
@ -303,7 +303,7 @@ QString Trace::fillFromCSV(CSV &csv, unsigned int parameter)
|
|||||||
return lastTraceName;
|
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
|
// remove all previous points
|
||||||
for(auto m : traceSet) {
|
for(auto m : traceSet) {
|
||||||
@ -1001,9 +1001,9 @@ std::vector<Trace *> Trace::createFromCSV(CSV &csv)
|
|||||||
return traces;
|
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
|
// Sanity check traces
|
||||||
unsigned int samples = traceSet.begin()->second->size();
|
unsigned int samples = traceSet.begin()->second->size();
|
||||||
@ -1041,7 +1041,7 @@ std::vector<VirtualDevice::VNAMeasurement> Trace::assembleDatapoints(std::map<QS
|
|||||||
|
|
||||||
// Checks passed, assemble datapoints
|
// Checks passed, assemble datapoints
|
||||||
for(unsigned int i=0;i<samples;i++) {
|
for(unsigned int i=0;i<samples;i++) {
|
||||||
VirtualDevice::VNAMeasurement d;
|
DeviceDriver::VNAMeasurement d;
|
||||||
for(auto m : traceSet) {
|
for(auto m : traceSet) {
|
||||||
QString measurement = m.first;
|
QString measurement = m.first;
|
||||||
const Trace *t = m.second;
|
const Trace *t = m.second;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "touchstone.h"
|
#include "touchstone.h"
|
||||||
#include "csv.h"
|
#include "csv.h"
|
||||||
#include "Device/virtualdevice.h"
|
#include "Device/devicedriver.h"
|
||||||
#include "Math/tracemath.h"
|
#include "Math/tracemath.h"
|
||||||
#include "Tools/parameters.h"
|
#include "Tools/parameters.h"
|
||||||
|
|
||||||
@ -13,6 +13,7 @@
|
|||||||
#include <QColor>
|
#include <QColor>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <QTime>
|
#include <QTime>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
class Marker;
|
class Marker;
|
||||||
class TraceModel;
|
class TraceModel;
|
||||||
@ -44,13 +45,13 @@ public:
|
|||||||
|
|
||||||
void clear(bool force = false);
|
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, 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 addDeembeddingData(const Data& d, int index = -1);
|
||||||
void setName(QString name);
|
void setName(QString name);
|
||||||
void setVelocityFactor(double v);
|
void setVelocityFactor(double v);
|
||||||
void fillFromTouchstone(Touchstone &t, unsigned int parameter);
|
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)
|
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 fromLivedata(LivedataType type, QString param);
|
||||||
void fromMath();
|
void fromMath();
|
||||||
QString name() { return _name; }
|
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,
|
// 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
|
// 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 LivedataType TypeFromString(QString s);
|
||||||
static QString TypeToString(LivedataType t);
|
static QString TypeToString(LivedataType t);
|
||||||
@ -275,7 +276,7 @@ private:
|
|||||||
std::set<Marker*> markers;
|
std::set<Marker*> markers;
|
||||||
struct {
|
struct {
|
||||||
union {
|
union {
|
||||||
VirtualDevice::SASettings SA;
|
DeviceDriver::SASettings SA;
|
||||||
};
|
};
|
||||||
bool valid;
|
bool valid;
|
||||||
} settings;
|
} settings;
|
||||||
|
@ -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)
|
void XAxis::set(Type type, bool log, bool autorange, double min, double max, double div)
|
||||||
{
|
{
|
||||||
if(max <= min) {
|
if(max <= min) {
|
||||||
auto info = VirtualDevice::getInfo(VirtualDevice::getConnected());
|
auto info = DeviceDriver::getInfo(DeviceDriver::getActiveDriver());
|
||||||
// invalid selection, use default instead
|
// invalid selection, use default instead
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case Type::Frequency:
|
case Type::Frequency:
|
||||||
min = info.Limits.minFreq;
|
min = info.Limits.VNA.minFreq;
|
||||||
max = info.Limits.maxFreq;
|
max = info.Limits.VNA.maxFreq;
|
||||||
break;
|
break;
|
||||||
case Type::Power:
|
case Type::Power:
|
||||||
min = info.Limits.mindBm;
|
min = info.Limits.VNA.mindBm;
|
||||||
max = info.Limits.maxdBm;
|
max = info.Limits.VNA.maxdBm;
|
||||||
break;
|
break;
|
||||||
case Type::Time:
|
case Type::Time:
|
||||||
case Type::TimeZeroSpan:
|
case Type::TimeZeroSpan:
|
||||||
|
@ -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;
|
source = DataSource::VNA;
|
||||||
lastReceivedData = QDateTime::currentDateTimeUtc();
|
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;
|
source = DataSource::SA;
|
||||||
lastReceivedData = QDateTime::currentDateTimeUtc();
|
lastReceivedData = QDateTime::currentDateTimeUtc();
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef TRACEMODEL_H
|
#ifndef TRACEMODEL_H
|
||||||
#define TRACEMODEL_H
|
#define TRACEMODEL_H
|
||||||
|
|
||||||
#include "Device/device.h"
|
#include "Device/devicedriver.h"
|
||||||
#include "savable.h"
|
#include "savable.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
|
||||||
@ -71,8 +71,8 @@ signals:
|
|||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void clearLiveData();
|
void clearLiveData();
|
||||||
void addVNAData(const VirtualDevice::VNAMeasurement& d, TraceMath::DataType datatype, bool deembedded);
|
void addVNAData(const DeviceDriver::VNAMeasurement& d, TraceMath::DataType datatype, bool deembedded);
|
||||||
void addSAData(const VirtualDevice::SAMeasurement &d, const VirtualDevice::SASettings &settings);
|
void addSAData(const DeviceDriver::SAMeasurement &d, const DeviceDriver::SASettings &settings);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DataSource source;
|
DataSource source;
|
||||||
|
@ -126,7 +126,7 @@ Deembedding::Deembedding(TraceModel &tm)
|
|||||||
}, nullptr));
|
}, 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
|
// figure out the point in one sweep based on the incomig pointNums
|
||||||
static unsigned lastPointNum;
|
static unsigned lastPointNum;
|
||||||
|
@ -22,7 +22,7 @@ public:
|
|||||||
Deembedding(TraceModel &tm);
|
Deembedding(TraceModel &tm);
|
||||||
~Deembedding(){}
|
~Deembedding(){}
|
||||||
|
|
||||||
void Deembed(VirtualDevice::VNAMeasurement &d);
|
void Deembed(DeviceDriver::VNAMeasurement &d);
|
||||||
void Deembed(std::map<QString, Trace*> traceSet);
|
void Deembed(std::map<QString, Trace*> traceSet);
|
||||||
|
|
||||||
void removeOption(unsigned int index);
|
void removeOption(unsigned int index);
|
||||||
@ -50,7 +50,7 @@ private:
|
|||||||
TraceModel &tm;
|
TraceModel &tm;
|
||||||
|
|
||||||
bool measuring;
|
bool measuring;
|
||||||
std::vector<VirtualDevice::VNAMeasurement> measurements;
|
std::vector<DeviceDriver::VNAMeasurement> measurements;
|
||||||
QDialog *measurementDialog;
|
QDialog *measurementDialog;
|
||||||
Ui_DeembeddingMeasurementDialog *measurementUI;
|
Ui_DeembeddingMeasurementDialog *measurementUI;
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define DEEMBEDDINGOPTION_H
|
#define DEEMBEDDINGOPTION_H
|
||||||
|
|
||||||
#include "savable.h"
|
#include "savable.h"
|
||||||
#include "Device/device.h"
|
#include "Device/devicedriver.h"
|
||||||
#include "Traces/tracemodel.h"
|
#include "Traces/tracemodel.h"
|
||||||
#include "scpi.h"
|
#include "scpi.h"
|
||||||
|
|
||||||
@ -27,12 +27,12 @@ public:
|
|||||||
static Type TypeFromString(QString string);
|
static Type TypeFromString(QString string);
|
||||||
|
|
||||||
virtual std::set<unsigned int> getAffectedPorts() = 0;
|
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 void edit(){}
|
||||||
virtual Type getType() = 0;
|
virtual Type getType() = 0;
|
||||||
|
|
||||||
public slots:
|
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:
|
signals:
|
||||||
// Deembedding option may selfdestruct if not applicable with current settings. It should emit this signal before deleting itself
|
// Deembedding option may selfdestruct if not applicable with current settings. It should emit this signal before deleting itself
|
||||||
void deleted(DeembeddingOption *option);
|
void deleted(DeembeddingOption *option);
|
||||||
|
@ -28,13 +28,13 @@ ImpedanceRenormalization::ImpedanceRenormalization()
|
|||||||
std::set<unsigned int> ImpedanceRenormalization::getAffectedPorts()
|
std::set<unsigned int> ImpedanceRenormalization::getAffectedPorts()
|
||||||
{
|
{
|
||||||
set<unsigned int> ret;
|
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);
|
ret.insert(i);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImpedanceRenormalization::transformDatapoint(VirtualDevice::VNAMeasurement &p)
|
void ImpedanceRenormalization::transformDatapoint(DeviceDriver::VNAMeasurement &p)
|
||||||
{
|
{
|
||||||
std::map<QString, std::complex<double>> transformed;
|
std::map<QString, std::complex<double>> transformed;
|
||||||
int ports = 0;
|
int ports = 0;
|
||||||
|
@ -14,7 +14,7 @@ public:
|
|||||||
ImpedanceRenormalization();
|
ImpedanceRenormalization();
|
||||||
|
|
||||||
std::set<unsigned int> getAffectedPorts() override;
|
std::set<unsigned int> getAffectedPorts() override;
|
||||||
void transformDatapoint(VirtualDevice::VNAMeasurement &p) override;
|
void transformDatapoint(DeviceDriver::VNAMeasurement &p) override;
|
||||||
Type getType() override { return Type::ImpedanceRenormalization;}
|
Type getType() override { return Type::ImpedanceRenormalization;}
|
||||||
nlohmann::json toJSON() override;
|
nlohmann::json toJSON() override;
|
||||||
void fromJSON(nlohmann::json j) override;
|
void fromJSON(nlohmann::json j) override;
|
||||||
|
@ -78,7 +78,7 @@ std::set<unsigned int> MatchingNetwork::getAffectedPorts()
|
|||||||
return {port};
|
return {port};
|
||||||
}
|
}
|
||||||
|
|
||||||
void MatchingNetwork::transformDatapoint(VirtualDevice::VNAMeasurement &p)
|
void MatchingNetwork::transformDatapoint(DeviceDriver::VNAMeasurement &p)
|
||||||
{
|
{
|
||||||
if(matching.count(p.frequency) == 0) {
|
if(matching.count(p.frequency) == 0) {
|
||||||
// this point is not calculated yet
|
// 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
|
// at this point the map contains the matching network effect
|
||||||
auto m = matching[p.frequency];
|
auto m = matching[p.frequency];
|
||||||
VirtualDevice::VNAMeasurement uncorrected = p;
|
DeviceDriver::VNAMeasurement uncorrected = p;
|
||||||
|
|
||||||
auto portReflectionName = "S"+QString::number(port)+QString::number(port);
|
auto portReflectionName = "S"+QString::number(port)+QString::number(port);
|
||||||
if(!uncorrected.measurements.count(portReflectionName)) {
|
if(!uncorrected.measurements.count(portReflectionName)) {
|
||||||
@ -180,7 +180,7 @@ void MatchingNetwork::edit()
|
|||||||
ui->lDefinedShunt->installEventFilter(this);
|
ui->lDefinedShunt->installEventFilter(this);
|
||||||
|
|
||||||
ui->port->setValue(port);
|
ui->port->setValue(port);
|
||||||
ui->port->setMaximum(VirtualDevice::maximumSupportedPorts);
|
ui->port->setMaximum(DeviceDriver::maximumSupportedPorts);
|
||||||
|
|
||||||
layout->setContentsMargins(0,0,0,0);
|
layout->setContentsMargins(0,0,0,0);
|
||||||
layout->setSpacing(0);
|
layout->setSpacing(0);
|
||||||
|
@ -68,7 +68,7 @@ public:
|
|||||||
// DeembeddingOption interface
|
// DeembeddingOption interface
|
||||||
public:
|
public:
|
||||||
std::set<unsigned int> getAffectedPorts() override;
|
std::set<unsigned int> getAffectedPorts() override;
|
||||||
void transformDatapoint(VirtualDevice::VNAMeasurement &p) override;
|
void transformDatapoint(DeviceDriver::VNAMeasurement &p) override;
|
||||||
void edit() override;
|
void edit() override;
|
||||||
Type getType() override {return Type::MatchingNetwork;}
|
Type getType() override {return Type::MatchingNetwork;}
|
||||||
nlohmann::json toJSON() override;
|
nlohmann::json toJSON() override;
|
||||||
|
@ -38,7 +38,7 @@ std::set<unsigned int> PortExtension::getAffectedPorts()
|
|||||||
return {port};
|
return {port};
|
||||||
}
|
}
|
||||||
|
|
||||||
void PortExtension::transformDatapoint(VirtualDevice::VNAMeasurement &d)
|
void PortExtension::transformDatapoint(DeviceDriver::VNAMeasurement &d)
|
||||||
{
|
{
|
||||||
auto phase = -2 * M_PI * ext.delay * d.frequency;
|
auto phase = -2 * M_PI * ext.delay * d.frequency;
|
||||||
auto db_attennuation = ext.DCloss;
|
auto db_attennuation = ext.DCloss;
|
||||||
@ -88,7 +88,7 @@ void PortExtension::edit()
|
|||||||
ui->Loss->setValue(ext.loss);
|
ui->Loss->setValue(ext.loss);
|
||||||
ui->Frequency->setValue(ext.frequency);
|
ui->Frequency->setValue(ext.frequency);
|
||||||
ui->port->setValue(port);
|
ui->port->setValue(port);
|
||||||
ui->port->setMaximum(VirtualDevice::maximumSupportedPorts);
|
ui->port->setMaximum(DeviceDriver::maximumSupportedPorts);
|
||||||
if(!kit) {
|
if(!kit) {
|
||||||
ui->calkit->setEnabled(false);
|
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) {
|
if(m.size() > 0) {
|
||||||
double last_phase = 0.0;
|
double last_phase = 0.0;
|
||||||
|
@ -19,14 +19,14 @@ class PortExtension : public DeembeddingOption
|
|||||||
public:
|
public:
|
||||||
PortExtension();
|
PortExtension();
|
||||||
std::set<unsigned int> getAffectedPorts() override;
|
std::set<unsigned int> getAffectedPorts() override;
|
||||||
void transformDatapoint(VirtualDevice::VNAMeasurement& d) override;
|
void transformDatapoint(DeviceDriver::VNAMeasurement& d) override;
|
||||||
void setCalkit(Calkit *kit);
|
void setCalkit(Calkit *kit);
|
||||||
Type getType() override {return Type::PortExtension;}
|
Type getType() override {return Type::PortExtension;}
|
||||||
nlohmann::json toJSON() override;
|
nlohmann::json toJSON() override;
|
||||||
void fromJSON(nlohmann::json j) override;
|
void fromJSON(nlohmann::json j) override;
|
||||||
public slots:
|
public slots:
|
||||||
void edit() override;
|
void edit() override;
|
||||||
void measurementCompleted(std::vector<VirtualDevice::VNAMeasurement> m) override;
|
void measurementCompleted(std::vector<DeviceDriver::VNAMeasurement> m) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void startMeasurement();
|
void startMeasurement();
|
||||||
|
@ -25,7 +25,7 @@ std::set<unsigned int> TwoThru::getAffectedPorts()
|
|||||||
return {port1, port2};
|
return {port1, port2};
|
||||||
}
|
}
|
||||||
|
|
||||||
void TwoThru::transformDatapoint(VirtualDevice::VNAMeasurement &p)
|
void TwoThru::transformDatapoint(DeviceDriver::VNAMeasurement &p)
|
||||||
{
|
{
|
||||||
// correct measurement
|
// correct measurement
|
||||||
if(points.size() > 0) {
|
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) {
|
if (measuring2xthru) {
|
||||||
measurements2xthru = m;
|
measurements2xthru = m;
|
||||||
@ -136,9 +136,9 @@ void TwoThru::edit()
|
|||||||
ui->lZ0->setVisible(false);
|
ui->lZ0->setVisible(false);
|
||||||
|
|
||||||
ui->port1->setValue(port1);
|
ui->port1->setValue(port1);
|
||||||
ui->port1->setMaximum(VirtualDevice::maximumSupportedPorts);
|
ui->port1->setMaximum(DeviceDriver::maximumSupportedPorts);
|
||||||
ui->port2->setValue(port2);
|
ui->port2->setValue(port2);
|
||||||
ui->port2->setMaximum(VirtualDevice::maximumSupportedPorts);
|
ui->port2->setMaximum(DeviceDriver::maximumSupportedPorts);
|
||||||
|
|
||||||
auto portChanged = [=](){
|
auto portChanged = [=](){
|
||||||
port1 = ui->port1->value();
|
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
|
// calculate error boxes, see https://www.freelists.org/post/si-list/IEEE-P370-Opensource-Deembedding-MATLAB-functions
|
||||||
// create vectors of S parameters
|
// create vectors of S parameters
|
||||||
@ -442,7 +442,7 @@ std::vector<TwoThru::Point> TwoThru::calculateErrorBoxes(std::vector<VirtualDevi
|
|||||||
return ret;
|
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;
|
vector<Point> ret;
|
||||||
|
|
||||||
@ -715,9 +715,9 @@ std::vector<TwoThru::Point> TwoThru::calculateErrorBoxes(std::vector<VirtualDevi
|
|||||||
return ret;
|
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) {
|
if(input.size() > 1) {
|
||||||
int size = input.size();
|
int size = input.size();
|
||||||
double freqStep = 0.0;
|
double freqStep = 0.0;
|
||||||
@ -739,8 +739,8 @@ std::vector<VirtualDevice::VNAMeasurement> TwoThru::interpolateEvenFrequencyStep
|
|||||||
// needs to interpolate
|
// needs to interpolate
|
||||||
double freq = freqStep;
|
double freq = freqStep;
|
||||||
while(freq <= input.back().frequency) {
|
while(freq <= input.back().frequency) {
|
||||||
VirtualDevice::VNAMeasurement interp;
|
DeviceDriver::VNAMeasurement interp;
|
||||||
auto it = lower_bound(input.begin(), input.end(), freq, [](const VirtualDevice::VNAMeasurement &lhs, const double f) -> bool {
|
auto it = lower_bound(input.begin(), input.end(), freq, [](const DeviceDriver::VNAMeasurement &lhs, const double f) -> bool {
|
||||||
return lhs.frequency < f;
|
return lhs.frequency < f;
|
||||||
});
|
});
|
||||||
if(it->frequency == freq) {
|
if(it->frequency == freq) {
|
||||||
|
@ -17,7 +17,7 @@ public:
|
|||||||
TwoThru();
|
TwoThru();
|
||||||
|
|
||||||
std::set<unsigned int> getAffectedPorts() override;
|
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 void edit() override;
|
||||||
virtual Type getType() override {return DeembeddingOption::Type::TwoThru;}
|
virtual Type getType() override {return DeembeddingOption::Type::TwoThru;}
|
||||||
nlohmann::json toJSON() override;
|
nlohmann::json toJSON() override;
|
||||||
@ -26,19 +26,19 @@ public:
|
|||||||
private slots:
|
private slots:
|
||||||
void startMeasurement();
|
void startMeasurement();
|
||||||
void updateGUI();
|
void updateGUI();
|
||||||
void measurementCompleted(std::vector<VirtualDevice::VNAMeasurement> m) override;
|
void measurementCompleted(std::vector<DeviceDriver::VNAMeasurement> m) override;
|
||||||
private:
|
private:
|
||||||
using Point = struct {
|
using Point = struct {
|
||||||
double freq;
|
double freq;
|
||||||
Tparam inverseP1, inverseP2;
|
Tparam inverseP1, inverseP2;
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::vector<VirtualDevice::VNAMeasurement> interpolateEvenFrequencySteps(std::vector<VirtualDevice::VNAMeasurement> input);
|
static std::vector<DeviceDriver::VNAMeasurement> interpolateEvenFrequencySteps(std::vector<DeviceDriver::VNAMeasurement> input);
|
||||||
std::vector<Point> calculateErrorBoxes(std::vector<VirtualDevice::VNAMeasurement> data_2xthru);
|
std::vector<Point> calculateErrorBoxes(std::vector<DeviceDriver::VNAMeasurement> data_2xthru);
|
||||||
std::vector<Point> calculateErrorBoxes(std::vector<VirtualDevice::VNAMeasurement> data_2xthru, std::vector<VirtualDevice::VNAMeasurement> data_fix_dut_fix, double z0);
|
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<DeviceDriver::VNAMeasurement> measurements2xthru;
|
||||||
std::vector<VirtualDevice::VNAMeasurement> measurementsDUT;
|
std::vector<DeviceDriver::VNAMeasurement> measurementsDUT;
|
||||||
double Z0;
|
double Z0;
|
||||||
unsigned int port1, port2;
|
unsigned int port1, port2;
|
||||||
std::vector<Point> points;
|
std::vector<Point> points;
|
||||||
|
@ -97,7 +97,7 @@ VNA::VNA(AppWindow *window, QString name)
|
|||||||
|
|
||||||
connect(calLoad, &QAction::triggered, [=](){
|
connect(calLoad, &QAction::triggered, [=](){
|
||||||
LoadCalibration();
|
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 "
|
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.");
|
"data likely isn't useful.");
|
||||||
}
|
}
|
||||||
@ -213,7 +213,7 @@ VNA::VNA(AppWindow *window, QString name)
|
|||||||
|
|
||||||
connect(assignDefaultCal, &QAction::triggered, [=](){
|
connect(assignDefaultCal, &QAction::triggered, [=](){
|
||||||
if(window->getDevice()) {
|
if(window->getDevice()) {
|
||||||
auto key = "DefaultCalibration"+window->getDevice()->serial();
|
auto key = "DefaultCalibration"+window->getDevice()->getSerial();
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
auto filename = QFileDialog::getOpenFileName(nullptr, "Load calibration data", settings.value(key).toString(), "Calibration files (*.cal)", nullptr, QFileDialog::DontUseNativeDialog);
|
auto filename = QFileDialog::getOpenFileName(nullptr, "Load calibration data", settings.value(key).toString(), "Calibration files (*.cal)", nullptr, QFileDialog::DontUseNativeDialog);
|
||||||
if(!filename.isEmpty()) {
|
if(!filename.isEmpty()) {
|
||||||
@ -225,7 +225,7 @@ VNA::VNA(AppWindow *window, QString name)
|
|||||||
});
|
});
|
||||||
connect(removeDefaultCal, &QAction::triggered, [=](){
|
connect(removeDefaultCal, &QAction::triggered, [=](){
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
settings.remove("DefaultCalibration"+window->getDevice()->serial());
|
settings.remove("DefaultCalibration"+window->getDevice()->getSerial());
|
||||||
removeDefaultCal->setEnabled(false);
|
removeDefaultCal->setEnabled(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -678,10 +678,10 @@ void VNA::deactivate()
|
|||||||
void VNA::initializeDevice()
|
void VNA::initializeDevice()
|
||||||
{
|
{
|
||||||
defaultCalMenu->setEnabled(true);
|
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
|
// Check if default calibration exists and attempt to load it
|
||||||
QSettings s;
|
QSettings s;
|
||||||
auto key = "DefaultCalibration"+window->getDevice()->serial();
|
auto key = "DefaultCalibration"+window->getDevice()->getSerial();
|
||||||
if (s.contains(key)) {
|
if (s.contains(key)) {
|
||||||
auto filename = s.value(key).toString();
|
auto filename = s.value(key).toString();
|
||||||
qDebug() << "Attempting to load default calibration file " << filename;
|
qDebug() << "Attempting to load default calibration file " << filename;
|
||||||
@ -702,7 +702,7 @@ void VNA::initializeDevice()
|
|||||||
// Configure initial state of device
|
// Configure initial state of device
|
||||||
SettingsChanged();
|
SettingsChanged();
|
||||||
emit deviceInitialized();
|
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 "
|
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.");
|
"data likely isn't useful.");
|
||||||
}
|
}
|
||||||
@ -806,7 +806,7 @@ void VNA::fromJSON(nlohmann::json j)
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
void VNA::NewDatapoint(VirtualDevice::VNAMeasurement m)
|
void VNA::NewDatapoint(DeviceDriver::VNAMeasurement m)
|
||||||
{
|
{
|
||||||
if(isActive != true) {
|
if(isActive != true) {
|
||||||
// ignore
|
// ignore
|
||||||
@ -979,14 +979,14 @@ void VNA::SetStopFreq(double freq)
|
|||||||
void VNA::SetCenterFreq(double freq)
|
void VNA::SetCenterFreq(double freq)
|
||||||
{
|
{
|
||||||
auto old_span = settings.Freq.stop - settings.Freq.start;
|
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
|
// would shift start frequency below minimum
|
||||||
settings.Freq.start = 0;
|
settings.Freq.start = 0;
|
||||||
settings.Freq.stop = 2 * freq;
|
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
|
// would shift stop frequency above maximum
|
||||||
settings.Freq.start = 2 * freq - VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq;
|
settings.Freq.start = 2 * freq - DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxFreq;
|
||||||
settings.Freq.stop = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq;
|
settings.Freq.stop = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxFreq;
|
||||||
} else {
|
} else {
|
||||||
settings.Freq.start = freq - old_span / 2;
|
settings.Freq.start = freq - old_span / 2;
|
||||||
settings.Freq.stop = 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)
|
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;
|
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
|
// would shift start frequency below minimum
|
||||||
settings.Freq.start = VirtualDevice::getInfo(window->getDevice()).Limits.minFreq;
|
settings.Freq.start = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minFreq;
|
||||||
settings.Freq.stop = VirtualDevice::getInfo(window->getDevice()).Limits.minFreq + span;
|
settings.Freq.stop = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minFreq + span;
|
||||||
} else if(old_center > maxFreq - span / 2) {
|
} else if(old_center > maxFreq - span / 2) {
|
||||||
// would shift stop frequency above maximum
|
// would shift stop frequency above maximum
|
||||||
settings.Freq.start = maxFreq - span;
|
settings.Freq.start = maxFreq - span;
|
||||||
@ -1025,8 +1025,8 @@ void VNA::SetFullSpan()
|
|||||||
settings.Freq.start = pref.Acquisition.fullSpanStart;
|
settings.Freq.start = pref.Acquisition.fullSpanStart;
|
||||||
settings.Freq.stop = pref.Acquisition.fullSpanStop;
|
settings.Freq.stop = pref.Acquisition.fullSpanStop;
|
||||||
} else {
|
} else {
|
||||||
settings.Freq.start = VirtualDevice::getInfo(window->getDevice()).Limits.minFreq;
|
settings.Freq.start = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minFreq;
|
||||||
settings.Freq.stop = VirtualDevice::getInfo(window->getDevice()).Limits.maxFreq;
|
settings.Freq.stop = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxFreq;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ConstrainAndUpdateFrequencies();
|
ConstrainAndUpdateFrequencies();
|
||||||
@ -1073,10 +1073,10 @@ void VNA::SetLogSweep(bool log)
|
|||||||
|
|
||||||
void VNA::SetSourceLevel(double level)
|
void VNA::SetSourceLevel(double level)
|
||||||
{
|
{
|
||||||
if(level > VirtualDevice::getInfo(window->getDevice()).Limits.maxdBm) {
|
if(level > DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxdBm) {
|
||||||
level = VirtualDevice::getInfo(window->getDevice()).Limits.maxdBm;
|
level = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxdBm;
|
||||||
} else if(level < VirtualDevice::getInfo(window->getDevice()).Limits.mindBm) {
|
} else if(level < DeviceDriver::getInfo(window->getDevice()).Limits.VNA.mindBm) {
|
||||||
level = VirtualDevice::getInfo(window->getDevice()).Limits.mindBm;
|
level = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.mindBm;
|
||||||
}
|
}
|
||||||
emit sourceLevelChanged(level);
|
emit sourceLevelChanged(level);
|
||||||
settings.Freq.excitation_power = level;
|
settings.Freq.excitation_power = level;
|
||||||
@ -1107,15 +1107,15 @@ void VNA::SetPowerSweepFrequency(double freq)
|
|||||||
|
|
||||||
void VNA::SetPoints(unsigned int points)
|
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) {
|
if(points > maxPoints) {
|
||||||
points = maxPoints;
|
points = maxPoints;
|
||||||
} else if (points < 2) {
|
} else if (points < 2) {
|
||||||
points = 2;
|
points = 2;
|
||||||
}
|
}
|
||||||
if (points > VirtualDevice::getInfo(window->getDevice()).Limits.maxPoints) {
|
if (points > DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxPoints) {
|
||||||
// needs segmented sweep
|
// 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;
|
settings.activeSegment = 0;
|
||||||
} else {
|
} else {
|
||||||
// can fit all points into one segment
|
// can fit all points into one segment
|
||||||
@ -1129,10 +1129,10 @@ void VNA::SetPoints(unsigned int points)
|
|||||||
|
|
||||||
void VNA::SetIFBandwidth(double bandwidth)
|
void VNA::SetIFBandwidth(double bandwidth)
|
||||||
{
|
{
|
||||||
if(bandwidth > VirtualDevice::getInfo(window->getDevice()).Limits.maxIFBW) {
|
if(bandwidth > DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxIFBW) {
|
||||||
bandwidth = VirtualDevice::getInfo(window->getDevice()).Limits.maxIFBW;
|
bandwidth = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxIFBW;
|
||||||
} else if(bandwidth < VirtualDevice::getInfo(window->getDevice()).Limits.minIFBW) {
|
} else if(bandwidth < DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minIFBW) {
|
||||||
bandwidth = VirtualDevice::getInfo(window->getDevice()).Limits.minIFBW;
|
bandwidth = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minIFBW;
|
||||||
}
|
}
|
||||||
settings.bandwidth = bandwidth;
|
settings.bandwidth = bandwidth;
|
||||||
emit IFBandwidthChanged(settings.bandwidth);
|
emit IFBandwidthChanged(settings.bandwidth);
|
||||||
@ -1150,7 +1150,7 @@ void VNA::SetAveraging(unsigned int averages)
|
|||||||
void VNA::ExcitationRequired()
|
void VNA::ExcitationRequired()
|
||||||
{
|
{
|
||||||
if(!Preferences::getInstance().Acquisition.alwaysExciteAllPorts) {
|
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 required = traceModel.PortExcitationRequired(i);
|
||||||
auto set = find(settings.excitedPorts.begin(), settings.excitedPorts.end(), i) != settings.excitedPorts.end();
|
auto set = find(settings.excitedPorts.begin(), settings.excitedPorts.end(), i) != settings.excitedPorts.end();
|
||||||
if(required != set) {
|
if(required != set) {
|
||||||
@ -1430,21 +1430,14 @@ void VNA::SetupSCPI()
|
|||||||
|
|
||||||
void VNA::ConstrainAndUpdateFrequencies()
|
void VNA::ConstrainAndUpdateFrequencies()
|
||||||
{
|
{
|
||||||
auto& pref = Preferences::getInstance();
|
if(settings.Freq.stop > DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minFreq) {
|
||||||
double maxFreq;
|
settings.Freq.stop = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minFreq;
|
||||||
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.start > settings.Freq.stop) {
|
if(settings.Freq.start > settings.Freq.stop) {
|
||||||
settings.Freq.start = settings.Freq.stop;
|
settings.Freq.start = settings.Freq.stop;
|
||||||
}
|
}
|
||||||
if(settings.Freq.start < VirtualDevice::getInfo(window->getDevice()).Limits.minFreq) {
|
if(settings.Freq.start < DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minFreq) {
|
||||||
settings.Freq.start = VirtualDevice::getInfo(window->getDevice()).Limits.minFreq;
|
settings.Freq.start = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minFreq;
|
||||||
}
|
}
|
||||||
settings.zerospan = (settings.sweepType == SweepType::Frequency && settings.Freq.start == settings.Freq.stop)
|
settings.zerospan = (settings.sweepType == SweepType::Frequency && settings.Freq.start == settings.Freq.stop)
|
||||||
|| (settings.sweepType == SweepType::Power && settings.Power.start == settings.Power.stop);
|
|| (settings.sweepType == SweepType::Power && settings.Power.start == settings.Power.stop);
|
||||||
@ -1617,7 +1610,7 @@ void VNA::preset()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Create default traces
|
// Create default traces
|
||||||
createDefaultTracesAndGraphs(VirtualDevice::getInfo(window->getDevice()).ports);
|
createDefaultTracesAndGraphs(DeviceDriver::getInfo(window->getDevice()).Limits.VNA.ports);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString VNA::SweepTypeToString(VNA::SweepType sw)
|
QString VNA::SweepTypeToString(VNA::SweepType sw)
|
||||||
@ -1686,14 +1679,14 @@ void VNA::ConfigureDevice(bool resetTraces, std::function<void(bool)> cb)
|
|||||||
}
|
}
|
||||||
changingSettings = true;
|
changingSettings = true;
|
||||||
// assemble VNA protocol settings
|
// assemble VNA protocol settings
|
||||||
VirtualDevice::VNASettings s = {};
|
DeviceDriver::VNASettings s = {};
|
||||||
s.IFBW = settings.bandwidth;
|
s.IFBW = settings.bandwidth;
|
||||||
if(Preferences::getInstance().Acquisition.alwaysExciteAllPorts) {
|
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);
|
s.excitedPorts.push_back(i);
|
||||||
}
|
}
|
||||||
} else {
|
} 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))
|
if(traceModel.PortExcitationRequired(i))
|
||||||
s.excitedPorts.push_back(i);
|
s.excitedPorts.push_back(i);
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ public slots:
|
|||||||
bool SaveCalibration(QString filename = "");
|
bool SaveCalibration(QString filename = "");
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void NewDatapoint(VirtualDevice::VNAMeasurement m);
|
void NewDatapoint(DeviceDriver::VNAMeasurement m);
|
||||||
void StartImpedanceMatching();
|
void StartImpedanceMatching();
|
||||||
void StartMixedModeConversion();
|
void StartMixedModeConversion();
|
||||||
// Sweep control
|
// Sweep control
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "mode.h"
|
#include "mode.h"
|
||||||
#include "modehandler.h"
|
#include "modehandler.h"
|
||||||
#include "modewindow.h"
|
#include "modewindow.h"
|
||||||
|
#include "Device/librevnausbdriver.h"
|
||||||
|
|
||||||
#include <QDockWidget>
|
#include <QDockWidget>
|
||||||
#include <QDesktopWidget>
|
#include <QDesktopWidget>
|
||||||
@ -83,6 +84,9 @@ AppWindow::AppWindow(QWidget *parent)
|
|||||||
// qDebug().setVerbosity(0);
|
// qDebug().setVerbosity(0);
|
||||||
qDebug() << "Application start";
|
qDebug() << "Application start";
|
||||||
|
|
||||||
|
// Register device drivers
|
||||||
|
deviceDrivers.push_back(new LibreVNAUSBDriver());
|
||||||
|
|
||||||
this->setWindowIcon(QIcon(":/app/logo.png"));
|
this->setWindowIcon(QIcon(":/app/logo.png"));
|
||||||
|
|
||||||
parser.setApplicationDescription(qlibrevnaApp->applicationName());
|
parser.setApplicationDescription(qlibrevnaApp->applicationName());
|
||||||
@ -102,7 +106,8 @@ AppWindow::AppWindow(QWidget *parent)
|
|||||||
} else {
|
} else {
|
||||||
Preferences::getInstance().load();
|
Preferences::getInstance().load();
|
||||||
}
|
}
|
||||||
vdevice = nullptr;
|
device = nullptr;
|
||||||
|
// vdevice = nullptr;
|
||||||
modeHandler = nullptr;
|
modeHandler = nullptr;
|
||||||
|
|
||||||
if(parser.isSet("port")) {
|
if(parser.isSet("port")) {
|
||||||
@ -233,12 +238,12 @@ void AppWindow::SetupMenu()
|
|||||||
modeHandler->getActiveMode()->saveSreenshot();
|
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->actionUSB_log, &QAction::triggered, this, &AppWindow::ShowUSBLog);
|
||||||
connect(ui->actionFirmware_Update, &QAction::triggered, this, &AppWindow::StartFirmwareUpdateDialog);
|
// connect(ui->actionFirmware_Update, &QAction::triggered, this, &AppWindow::StartFirmwareUpdateDialog);
|
||||||
connect(ui->actionSource_Calibration, &QAction::triggered, this, &AppWindow::SourceCalibrationDialog);
|
// connect(ui->actionSource_Calibration, &QAction::triggered, this, &AppWindow::SourceCalibrationDialog);
|
||||||
connect(ui->actionReceiver_Calibration, &QAction::triggered, this, &AppWindow::ReceiverCalibrationDialog);
|
// connect(ui->actionReceiver_Calibration, &QAction::triggered, this, &AppWindow::ReceiverCalibrationDialog);
|
||||||
connect(ui->actionFrequency_Calibration, &QAction::triggered, this, &AppWindow::FrequencyCalibrationDialog);
|
// connect(ui->actionFrequency_Calibration, &QAction::triggered, this, &AppWindow::FrequencyCalibrationDialog);
|
||||||
|
|
||||||
connect(ui->actionPreset, &QAction::triggered, [=](){
|
connect(ui->actionPreset, &QAction::triggered, [=](){
|
||||||
modeHandler->getActiveMode()->preset();
|
modeHandler->getActiveMode()->preset();
|
||||||
@ -278,14 +283,13 @@ void AppWindow::SetupMenu()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// acquisition frequencies may have changed, update
|
// acquisition frequencies may have changed, update
|
||||||
UpdateAcquisitionFrequencies();
|
// UpdateAcquisitionFrequencies();
|
||||||
|
|
||||||
auto active = modeHandler->getActiveMode();
|
auto active = modeHandler->getActiveMode();
|
||||||
if (active)
|
if (active)
|
||||||
{
|
{
|
||||||
active->updateGraphColors();
|
active->updateGraphColors();
|
||||||
|
if(device) {
|
||||||
if(vdevice) {
|
|
||||||
active->initializeDevice();
|
active->initializeDevice();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -311,7 +315,13 @@ void AppWindow::closeEvent(QCloseEvent *event)
|
|||||||
if(modeHandler->getActiveMode()) {
|
if(modeHandler->getActiveMode()) {
|
||||||
modeHandler->deactivate(modeHandler->getActiveMode());
|
modeHandler->deactivate(modeHandler->getActiveMode());
|
||||||
}
|
}
|
||||||
delete vdevice;
|
if(device) {
|
||||||
|
device->disconnectDevice();
|
||||||
|
device = nullptr;
|
||||||
|
}
|
||||||
|
for(auto driver : deviceDrivers) {
|
||||||
|
delete driver;
|
||||||
|
}
|
||||||
delete modeHandler;
|
delete modeHandler;
|
||||||
modeHandler = nullptr;
|
modeHandler = nullptr;
|
||||||
pref.store();
|
pref.store();
|
||||||
@ -325,31 +335,41 @@ bool AppWindow::ConnectToDevice(QString serial)
|
|||||||
} else {
|
} else {
|
||||||
qDebug() << "Trying to connect to" << serial;
|
qDebug() << "Trying to connect to" << serial;
|
||||||
}
|
}
|
||||||
if(vdevice) {
|
if(device) {
|
||||||
qDebug() << "Already connected to a device, disconnecting first...";
|
qDebug() << "Already connected to a device, disconnecting first...";
|
||||||
DisconnectDevice();
|
DisconnectDevice();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
qDebug() << "Attempting to connect to device...";
|
qDebug() << "Attempting to connect to device...";
|
||||||
vdevice = new VirtualDevice(serial);
|
for(auto driver : deviceDrivers) {
|
||||||
UpdateStatusBar(AppWindow::DeviceStatusBar::Connected);
|
if(driver->GetAvailableDevices().count(serial)) {
|
||||||
connect(vdevice, &VirtualDevice::InfoUpdated, this, &AppWindow::DeviceInfoUpdated);
|
// this driver can connect to the device
|
||||||
connect(vdevice, &VirtualDevice::LogLineReceived, &deviceLog, &DeviceLog::addLine);
|
if(driver->connectDevice(serial)) {
|
||||||
connect(vdevice, &VirtualDevice::ConnectionLost, this, &AppWindow::DeviceConnectionLost);
|
device = driver;
|
||||||
connect(vdevice, &VirtualDevice::StatusUpdated, this, &AppWindow::DeviceStatusUpdated);
|
} else {
|
||||||
connect(vdevice, &VirtualDevice::NeedsFirmwareUpdate, this, &AppWindow::DeviceNeedsUpdate);
|
// failed to connect
|
||||||
ui->actionDisconnect->setEnabled(true);
|
// TODO show error message
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
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);
|
ui->actionPreset->setEnabled(true);
|
||||||
|
|
||||||
for(auto d : deviceActionGroup->actions()) {
|
for(auto d : deviceActionGroup->actions()) {
|
||||||
if(d->text() == vdevice->serial()) {
|
if(d->text() == device->getSerial()) {
|
||||||
d->blockSignals(true);
|
d->blockSignals(true);
|
||||||
d->setChecked(true);
|
d->setChecked(true);
|
||||||
d->blockSignals(false);
|
d->blockSignals(false);
|
||||||
@ -357,12 +377,12 @@ bool AppWindow::ConnectToDevice(QString serial)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(auto m : modeHandler->getModes()) {
|
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()) {
|
if (modeHandler->getActiveMode()) {
|
||||||
modeHandler->getActiveMode()->initializeDevice();
|
modeHandler->getActiveMode()->initializeDevice();
|
||||||
}
|
}
|
||||||
@ -377,8 +397,10 @@ bool AppWindow::ConnectToDevice(QString serial)
|
|||||||
|
|
||||||
void AppWindow::DisconnectDevice()
|
void AppWindow::DisconnectDevice()
|
||||||
{
|
{
|
||||||
delete vdevice;
|
if(device) {
|
||||||
vdevice = nullptr;
|
device->disconnectDevice();
|
||||||
|
device = nullptr;
|
||||||
|
}
|
||||||
ui->actionDisconnect->setEnabled(false);
|
ui->actionDisconnect->setEnabled(false);
|
||||||
ui->actionManual_Control->setEnabled(false);
|
ui->actionManual_Control->setEnabled(false);
|
||||||
ui->actionFirmware_Update->setEnabled(false);
|
ui->actionFirmware_Update->setEnabled(false);
|
||||||
@ -446,8 +468,8 @@ void AppWindow::SetupSCPI()
|
|||||||
return SCPI::getResultName(SCPI::Result::Empty);
|
return SCPI::getResultName(SCPI::Result::Empty);
|
||||||
}
|
}
|
||||||
}, [=](QStringList) -> QString {
|
}, [=](QStringList) -> QString {
|
||||||
if(vdevice) {
|
if(device) {
|
||||||
return vdevice->serial();
|
return device->getSerial();
|
||||||
} else {
|
} else {
|
||||||
return "Not connected";
|
return "Not connected";
|
||||||
}
|
}
|
||||||
@ -519,7 +541,11 @@ void AppWindow::SetupSCPI()
|
|||||||
}
|
}
|
||||||
return SCPI::getResultName(SCPI::Result::Empty);
|
return SCPI::getResultName(SCPI::Result::Empty);
|
||||||
}, [=](QStringList) -> QString {
|
}, [=](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 {
|
scpi_dev->add(new SCPICommand("MODE", [=](QStringList params) -> QString {
|
||||||
if (params.size() != 1) {
|
if (params.size() != 1) {
|
||||||
@ -557,84 +583,104 @@ void AppWindow::SetupSCPI()
|
|||||||
auto scpi_status = new SCPINode("STAtus");
|
auto scpi_status = new SCPINode("STAtus");
|
||||||
scpi_dev->add(scpi_status);
|
scpi_dev->add(scpi_status);
|
||||||
scpi_status->add(new SCPICommand("UNLOcked", nullptr, [=](QStringList){
|
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){
|
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){
|
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");
|
auto scpi_info = new SCPINode("INFo");
|
||||||
scpi_dev->add(scpi_info);
|
scpi_dev->add(scpi_info);
|
||||||
scpi_info->add(new SCPICommand("FWREVision", nullptr, [=](QStringList){
|
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);
|
if(device) {
|
||||||
}));
|
return device->getInfo().firmware_version;
|
||||||
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);
|
|
||||||
} else {
|
} else {
|
||||||
auto dev = vdevice->getDevice();
|
return SCPI::getResultName(SCPI::Result::Error);
|
||||||
return QString::number(dev->StatusV1().temp_source)+"/"+QString::number(dev->StatusV1().temp_LO1)+"/"+QString::number(dev->StatusV1().temp_MCU);
|
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
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");
|
auto scpi_limits = new SCPINode("LIMits");
|
||||||
scpi_info->add(scpi_limits);
|
scpi_info->add(scpi_limits);
|
||||||
scpi_limits->add(new SCPICommand("MINFrequency", nullptr, [=](QStringList){
|
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){
|
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){
|
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){
|
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){
|
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){
|
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){
|
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){
|
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){
|
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){
|
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");
|
auto scpi_manual = new SCPINode("MANual");
|
||||||
scpi_manual->add(new SCPICommand("STArt",[=](QStringList) -> QString {
|
scpi_manual->add(new SCPICommand("STArt",[=](QStringList) -> QString {
|
||||||
StartManualControl();
|
// StartManualControl();
|
||||||
return SCPI::getResultName(SCPI::Result::Empty);
|
return SCPI::getResultName(SCPI::Result::Empty);
|
||||||
}, nullptr));
|
}, nullptr));
|
||||||
scpi_manual->add(new SCPICommand("STOp",[=](QStringList) -> QString {
|
scpi_manual->add(new SCPICommand("STOp",[=](QStringList) -> QString {
|
||||||
@ -887,9 +933,12 @@ int AppWindow::UpdateDeviceList()
|
|||||||
{
|
{
|
||||||
deviceActionGroup->setExclusive(true);
|
deviceActionGroup->setExclusive(true);
|
||||||
ui->menuConnect_to->clear();
|
ui->menuConnect_to->clear();
|
||||||
auto devices = VirtualDevice::GetAvailableVirtualDevices();
|
std::set<QString> devices;
|
||||||
if(vdevice) {
|
for(auto driver : deviceDrivers) {
|
||||||
devices.insert(vdevice->serial());
|
devices.merge(driver->GetAvailableDevices());
|
||||||
|
}
|
||||||
|
if(device) {
|
||||||
|
devices.insert(device->getSerial());
|
||||||
}
|
}
|
||||||
int available = 0;
|
int available = 0;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
@ -902,7 +951,7 @@ int AppWindow::UpdateDeviceList()
|
|||||||
auto connectAction = ui->menuConnect_to->addAction(d);
|
auto connectAction = ui->menuConnect_to->addAction(d);
|
||||||
connectAction->setCheckable(true);
|
connectAction->setCheckable(true);
|
||||||
connectAction->setActionGroup(deviceActionGroup);
|
connectAction->setActionGroup(deviceActionGroup);
|
||||||
if(vdevice && d == vdevice->serial()) {
|
if(device && d == device->getSerial()) {
|
||||||
connectAction->setChecked(true);
|
connectAction->setChecked(true);
|
||||||
}
|
}
|
||||||
connect(connectAction, &QAction::triggered, [this, d]() {
|
connect(connectAction, &QAction::triggered, [this, d]() {
|
||||||
@ -917,59 +966,56 @@ int AppWindow::UpdateDeviceList()
|
|||||||
return available;
|
return available;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppWindow::StartManualControl()
|
//void AppWindow::StartManualControl()
|
||||||
{
|
//{
|
||||||
if(!vdevice || vdevice->isCompoundDevice()) {
|
// if(!vdevice || vdevice->isCompoundDevice()) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
if(manual) {
|
// if(manual) {
|
||||||
// dialog already active, nothing to do
|
// // dialog already active, nothing to do
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
manual = new ManualControlDialog(*vdevice->getDevice(), this);
|
// manual = new ManualControlDialog(*vdevice->getDevice(), this);
|
||||||
connect(manual, &QDialog::finished, [=](){
|
// connect(manual, &QDialog::finished, [=](){
|
||||||
manual = nullptr;
|
// manual = nullptr;
|
||||||
if(vdevice) {
|
// if(vdevice) {
|
||||||
modeHandler->getActiveMode()->initializeDevice();
|
// modeHandler->getActiveMode()->initializeDevice();
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
if(AppWindow::showGUI()) {
|
// if(AppWindow::showGUI()) {
|
||||||
manual->show();
|
// manual->show();
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
void AppWindow::UpdateReferenceToolbar()
|
void AppWindow::UpdateReferenceToolbar()
|
||||||
{
|
{
|
||||||
toolbars.reference.type->blockSignals(true);
|
toolbars.reference.type->blockSignals(true);
|
||||||
toolbars.reference.outFreq->blockSignals(true);
|
toolbars.reference.outFreq->blockSignals(true);
|
||||||
if(!vdevice || !vdevice->getInfo().supportsExtRef) {
|
toolbars.reference.type->setEnabled(device || device->supports(DeviceDriver::Feature::ExtRefIn));
|
||||||
toolbars.reference.type->setEnabled(false);
|
toolbars.reference.outFreq->setEnabled(device || device->supports(DeviceDriver::Feature::ExtRefOut));
|
||||||
toolbars.reference.outFreq->setEnabled(false);
|
if(device) {
|
||||||
} else {
|
// save current setting
|
||||||
toolbars.reference.type->setEnabled(true);
|
auto refInBuf = toolbars.reference.type->currentText();
|
||||||
toolbars.reference.outFreq->setEnabled(true);
|
auto refOutBuf = toolbars.reference.outFreq->currentText();
|
||||||
}
|
toolbars.reference.type->clear();
|
||||||
// save current setting
|
for(auto in : device->availableExtRefInSettings()) {
|
||||||
auto refInBuf = toolbars.reference.type->currentText();
|
toolbars.reference.type->addItem(in);
|
||||||
auto refOutBuf = toolbars.reference.outFreq->currentText();
|
}
|
||||||
toolbars.reference.type->clear();
|
toolbars.reference.outFreq->clear();
|
||||||
for(auto in : vdevice->availableExtRefInSettings()) {
|
for(auto out : device->availableExtRefOutSettings()) {
|
||||||
toolbars.reference.type->addItem(in);
|
toolbars.reference.outFreq->addItem(out);
|
||||||
}
|
}
|
||||||
toolbars.reference.outFreq->clear();
|
// restore previous setting if still available
|
||||||
for(auto out : vdevice->availableExtRefOutSettings()) {
|
if(toolbars.reference.type->findText(refInBuf) >= 0) {
|
||||||
toolbars.reference.outFreq->addItem(out);
|
toolbars.reference.type->setCurrentText(refInBuf);
|
||||||
}
|
} else {
|
||||||
// restore previous setting if still available
|
toolbars.reference.type->setCurrentIndex(0);
|
||||||
if(toolbars.reference.type->findText(refInBuf) >= 0) {
|
}
|
||||||
toolbars.reference.type->setCurrentText(refInBuf);
|
if(toolbars.reference.outFreq->findText(refOutBuf) >= 0) {
|
||||||
} else {
|
toolbars.reference.outFreq->setCurrentText(refOutBuf);
|
||||||
toolbars.reference.type->setCurrentIndex(0);
|
} else {
|
||||||
}
|
toolbars.reference.outFreq->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.type->blockSignals(false);
|
||||||
toolbars.reference.outFreq->blockSignals(false);
|
toolbars.reference.outFreq->blockSignals(false);
|
||||||
@ -978,27 +1024,11 @@ void AppWindow::UpdateReferenceToolbar()
|
|||||||
|
|
||||||
void AppWindow::UpdateReference()
|
void AppWindow::UpdateReference()
|
||||||
{
|
{
|
||||||
if(!vdevice) {
|
if(!device) {
|
||||||
// can't update without a device connected
|
// can't update without a device connected
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
vdevice->setExtRef(toolbars.reference.type->currentText(), toolbars.reference.outFreq->currentText());
|
device->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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppWindow::ShowUSBLog()
|
void AppWindow::ShowUSBLog()
|
||||||
@ -1009,34 +1039,21 @@ void AppWindow::ShowUSBLog()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppWindow::StartFirmwareUpdateDialog()
|
//void AppWindow::DeviceNeedsUpdate(int reported, int expected)
|
||||||
{
|
//{
|
||||||
if(!vdevice || vdevice->isCompoundDevice()) {
|
// auto ret = InformationBox::AskQuestion("Warning",
|
||||||
return;
|
// "The device reports a different protocol"
|
||||||
}
|
// "version (" + QString::number(reported) + ") than expected (" + QString::number(expected) + ").\n"
|
||||||
auto fw_update = new FirmwareUpdateDialog(vdevice->getDevice());
|
// "A firmware update is strongly recommended. Do you want to update now?", false);
|
||||||
connect(fw_update, &FirmwareUpdateDialog::DeviceRebooting, this, &AppWindow::DisconnectDevice);
|
// if (ret) {
|
||||||
connect(fw_update, &FirmwareUpdateDialog::DeviceRebooted, this, &AppWindow::ConnectToDevice);
|
// if (vdevice->isCompoundDevice()) {
|
||||||
if(AppWindow::showGUI()) {
|
// InformationBox::ShowError("Unable to update the firmware", "The connected device is a compound device, direct firmware"
|
||||||
fw_update->exec();
|
// " 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)
|
void AppWindow::DeviceStatusUpdated(VirtualDevice::Status status)
|
||||||
{
|
{
|
||||||
@ -1054,38 +1071,38 @@ void AppWindow::DeviceInfoUpdated()
|
|||||||
UpdateReferenceToolbar();
|
UpdateReferenceToolbar();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppWindow::SourceCalibrationDialog()
|
//void AppWindow::SourceCalibrationDialog()
|
||||||
{
|
//{
|
||||||
if(!vdevice || vdevice->isCompoundDevice()) {
|
// if(!vdevice || vdevice->isCompoundDevice()) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
auto d = new SourceCalDialog(vdevice->getDevice(), modeHandler);
|
// auto d = new SourceCalDialog(vdevice->getDevice(), modeHandler);
|
||||||
if(AppWindow::showGUI()) {
|
// if(AppWindow::showGUI()) {
|
||||||
d->exec();
|
// d->exec();
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
void AppWindow::ReceiverCalibrationDialog()
|
//void AppWindow::ReceiverCalibrationDialog()
|
||||||
{
|
//{
|
||||||
if(!vdevice || vdevice->isCompoundDevice()) {
|
// if(!vdevice || vdevice->isCompoundDevice()) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
auto d = new ReceiverCalDialog(vdevice->getDevice(), modeHandler);
|
// auto d = new ReceiverCalDialog(vdevice->getDevice(), modeHandler);
|
||||||
if(AppWindow::showGUI()) {
|
// if(AppWindow::showGUI()) {
|
||||||
d->exec();
|
// d->exec();
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
void AppWindow::FrequencyCalibrationDialog()
|
//void AppWindow::FrequencyCalibrationDialog()
|
||||||
{
|
//{
|
||||||
if(!vdevice || vdevice->isCompoundDevice()) {
|
// if(!vdevice || vdevice->isCompoundDevice()) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
auto d = new FrequencyCalDialog(vdevice->getDevice(), modeHandler);
|
// auto d = new FrequencyCalDialog(vdevice->getDevice(), modeHandler);
|
||||||
if(AppWindow::showGUI()) {
|
// if(AppWindow::showGUI()) {
|
||||||
d->exec();
|
// d->exec();
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
void AppWindow::SaveSetup(QString filename)
|
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
|
// Disconnect device prior to deleting and creating new modes. This prevents excessice and unnnecessary configuration of the device
|
||||||
QString serial = QString();
|
QString serial = QString();
|
||||||
if(vdevice->getConnected()) {
|
if(device) {
|
||||||
serial = vdevice->serial();
|
serial = device->getSerial();
|
||||||
delete vdevice;
|
device->disconnectDevice();
|
||||||
vdevice = nullptr;
|
device = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
modeHandler->closeModes();
|
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
|
QStackedWidget *AppWindow::getCentral() const
|
||||||
@ -1290,8 +1307,8 @@ void AppWindow::UpdateStatusBar(DeviceStatusBar status)
|
|||||||
{
|
{
|
||||||
switch(status) {
|
switch(status) {
|
||||||
case DeviceStatusBar::Connected:
|
case DeviceStatusBar::Connected:
|
||||||
lConnectionStatus.setText("Connected to " + vdevice->serial());
|
lConnectionStatus.setText("Connected to " + device->getSerial());
|
||||||
qInfo() << "Connected to" << vdevice->serial();
|
qInfo() << "Connected to" << device->getSerial();
|
||||||
break;
|
break;
|
||||||
case DeviceStatusBar::Disconnected:
|
case DeviceStatusBar::Disconnected:
|
||||||
lConnectionStatus.setText("No device connected");
|
lConnectionStatus.setText("No device connected");
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "scpi.h"
|
#include "scpi.h"
|
||||||
#include "tcpserver.h"
|
#include "tcpserver.h"
|
||||||
#include "Device/manualcontroldialog.h"
|
#include "Device/manualcontroldialog.h"
|
||||||
|
#include "Device/devicedriver.h"
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
@ -42,7 +43,7 @@ public:
|
|||||||
Ui::MainWindow *getUi() const;
|
Ui::MainWindow *getUi() const;
|
||||||
QStackedWidget *getCentral() const;
|
QStackedWidget *getCentral() const;
|
||||||
ModeHandler* getModeHandler() const;
|
ModeHandler* getModeHandler() const;
|
||||||
VirtualDevice *getDevice();
|
DeviceDriver *getDevice();
|
||||||
|
|
||||||
const QString& getAppVersion() const;
|
const QString& getAppVersion() const;
|
||||||
const QString& getAppGitHash() const;
|
const QString& getAppGitHash() const;
|
||||||
@ -60,18 +61,18 @@ private slots:
|
|||||||
bool ConnectToDevice(QString serial = QString());
|
bool ConnectToDevice(QString serial = QString());
|
||||||
void DisconnectDevice();
|
void DisconnectDevice();
|
||||||
int UpdateDeviceList();
|
int UpdateDeviceList();
|
||||||
void StartManualControl();
|
// void StartManualControl();
|
||||||
void UpdateReferenceToolbar();
|
void UpdateReferenceToolbar();
|
||||||
void UpdateReference();
|
void UpdateReference();
|
||||||
void UpdateAcquisitionFrequencies();
|
// void UpdateAcquisitionFrequencies();
|
||||||
void ShowUSBLog();
|
void ShowUSBLog();
|
||||||
void StartFirmwareUpdateDialog();
|
// void StartFirmwareUpdateDialog();
|
||||||
void DeviceNeedsUpdate(int reported, int expected);
|
void DeviceNeedsUpdate(int reported, int expected);
|
||||||
void DeviceStatusUpdated(VirtualDevice::Status status);
|
void DeviceStatusUpdated(VirtualDevice::Status status);
|
||||||
void DeviceInfoUpdated();
|
void DeviceInfoUpdated();
|
||||||
void SourceCalibrationDialog();
|
// void SourceCalibrationDialog();
|
||||||
void ReceiverCalibrationDialog();
|
// void ReceiverCalibrationDialog();
|
||||||
void FrequencyCalibrationDialog();
|
// void FrequencyCalibrationDialog();
|
||||||
nlohmann::json SaveSetup();
|
nlohmann::json SaveSetup();
|
||||||
void SaveSetup(QString filename);
|
void SaveSetup(QString filename);
|
||||||
void LoadSetup(QString filename);
|
void LoadSetup(QString filename);
|
||||||
@ -103,7 +104,11 @@ private:
|
|||||||
} toolbars;
|
} toolbars;
|
||||||
|
|
||||||
ModeHandler *modeHandler;
|
ModeHandler *modeHandler;
|
||||||
VirtualDevice *vdevice;
|
|
||||||
|
// VirtualDevice *vdevice;
|
||||||
|
std::vector<DeviceDriver*> deviceDrivers;
|
||||||
|
DeviceDriver *device;
|
||||||
|
|
||||||
DeviceLog deviceLog;
|
DeviceLog deviceLog;
|
||||||
QString deviceSerial;
|
QString deviceSerial;
|
||||||
QActionGroup *deviceActionGroup;
|
QActionGroup *deviceActionGroup;
|
||||||
|
@ -23,7 +23,7 @@ void Averaging::setAverages(unsigned int a)
|
|||||||
reset(avg.size());
|
reset(avg.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtualDevice::VNAMeasurement Averaging::process(VirtualDevice::VNAMeasurement d)
|
DeviceDriver::VNAMeasurement Averaging::process(DeviceDriver::VNAMeasurement d)
|
||||||
{
|
{
|
||||||
if(d.measurements.size() != numMeasurements) {
|
if(d.measurements.size() != numMeasurements) {
|
||||||
numMeasurements = d.measurements.size();
|
numMeasurements = d.measurements.size();
|
||||||
@ -42,7 +42,7 @@ VirtualDevice::VNAMeasurement Averaging::process(VirtualDevice::VNAMeasurement d
|
|||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtualDevice::SAMeasurement Averaging::process(VirtualDevice::SAMeasurement d)
|
DeviceDriver::SAMeasurement Averaging::process(DeviceDriver::SAMeasurement d)
|
||||||
{
|
{
|
||||||
if(d.measurements.size() != numMeasurements) {
|
if(d.measurements.size() != numMeasurements) {
|
||||||
numMeasurements = d.measurements.size();
|
numMeasurements = d.measurements.size();
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef AVERAGING_H
|
#ifndef AVERAGING_H
|
||||||
#define AVERAGING_H
|
#define AVERAGING_H
|
||||||
|
|
||||||
#include "Device/virtualdevice.h"
|
#include "Device/devicedriver.h"
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
@ -18,8 +18,8 @@ public:
|
|||||||
Averaging();
|
Averaging();
|
||||||
void reset(unsigned int points);
|
void reset(unsigned int points);
|
||||||
void setAverages(unsigned int a);
|
void setAverages(unsigned int a);
|
||||||
VirtualDevice::VNAMeasurement process(VirtualDevice::VNAMeasurement d);
|
DeviceDriver::VNAMeasurement process(DeviceDriver::VNAMeasurement d);
|
||||||
VirtualDevice::SAMeasurement process(VirtualDevice::SAMeasurement 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.
|
// 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
|
// Returned values are in range 0 to averages
|
||||||
unsigned int getLevel();
|
unsigned int getLevel();
|
||||||
|
@ -93,7 +93,7 @@
|
|||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>3</number>
|
<number>6</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="Startup">
|
<widget class="QWidget" name="Startup">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
@ -107,8 +107,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>530</width>
|
<width>749</width>
|
||||||
<height>937</height>
|
<height>920</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_13">
|
<layout class="QVBoxLayout" name="verticalLayout_13">
|
||||||
@ -1795,8 +1795,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>168</width>
|
<width>763</width>
|
||||||
<height>127</height>
|
<height>561</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_12">
|
<layout class="QHBoxLayout" name="horizontalLayout_12">
|
||||||
@ -1885,8 +1885,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>126</width>
|
<width>763</width>
|
||||||
<height>90</height>
|
<height>561</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_24">
|
<layout class="QVBoxLayout" name="verticalLayout_24">
|
||||||
@ -1956,8 +1956,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>263</width>
|
<width>763</width>
|
||||||
<height>241</height>
|
<height>561</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_19">
|
<layout class="QHBoxLayout" name="horizontalLayout_19">
|
||||||
|
@ -21,7 +21,9 @@ public:
|
|||||||
bool openFromFileDialog(QString title, QString filetype);
|
bool openFromFileDialog(QString title, QString filetype);
|
||||||
bool saveToFileDialog(QString title, QString filetype, QString ending = "");
|
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;
|
QPointerVariant var;
|
||||||
QString name;
|
QString name;
|
||||||
QVariant def;
|
QVariant def;
|
||||||
|
@ -13,7 +13,7 @@ PortExtensionTests::PortExtensionTests() : QObject(nullptr)
|
|||||||
constexpr int steps = 501;
|
constexpr int steps = 501;
|
||||||
for(int i=0;i<steps;i++) {
|
for(int i=0;i<steps;i++) {
|
||||||
double f = startFreq + (stopFreq - startFreq) * i / (steps - 1);
|
double f = startFreq + (stopFreq - startFreq) * i / (steps - 1);
|
||||||
VirtualDevice::VNAMeasurement m;
|
DeviceDriver::VNAMeasurement m;
|
||||||
m.frequency = f;
|
m.frequency = f;
|
||||||
m.dBm = -10;
|
m.dBm = -10;
|
||||||
m.pointNum = i;
|
m.pointNum = i;
|
||||||
|
@ -15,7 +15,7 @@ private slots:
|
|||||||
void autocalc();
|
void autocalc();
|
||||||
void correct();
|
void correct();
|
||||||
private:
|
private:
|
||||||
std::vector<VirtualDevice::VNAMeasurement> dummyData;
|
std::vector<DeviceDriver::VNAMeasurement> dummyData;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PORTEXTENSIONTESTS_H
|
#endif // PORTEXTENSIONTESTS_H
|
||||||
|
Loading…
Reference in New Issue
Block a user