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