WIP: device driver abstraction
This commit is contained in:
parent
db6d823e0f
commit
cde564299c
@ -277,7 +277,7 @@ void LibreCALDialog::startCalibration()
|
|||||||
}
|
}
|
||||||
ui->lCalibrationStatus->setText("Creating calibration measurements...");
|
ui->lCalibrationStatus->setText("Creating calibration measurements...");
|
||||||
cal->reset();
|
cal->reset();
|
||||||
auto vnaPorts = VirtualDevice::getInfo(VirtualDevice::getConnected()).ports;
|
auto vnaPorts = DeviceDriver::getInfo(DeviceDriver::getActiveDriver()).Limits.VNA.ports;
|
||||||
set<CalibrationMeasurement::Base*> openMeasurements;
|
set<CalibrationMeasurement::Base*> openMeasurements;
|
||||||
set<CalibrationMeasurement::Base*> shortMeasurements;
|
set<CalibrationMeasurement::Base*> shortMeasurements;
|
||||||
set<CalibrationMeasurement::Base*> loadMeasurements;
|
set<CalibrationMeasurement::Base*> loadMeasurements;
|
||||||
@ -432,7 +432,7 @@ void LibreCALDialog::createPortAssignmentUI()
|
|||||||
while(layout->rowCount() > 1) {
|
while(layout->rowCount() > 1) {
|
||||||
layout->removeRow(1);
|
layout->removeRow(1);
|
||||||
}
|
}
|
||||||
auto vnaPorts = VirtualDevice::getInfo(VirtualDevice::getConnected()).ports;
|
auto vnaPorts = DeviceDriver::getInfo(DeviceDriver::getActiveDriver()).Limits.VNA.ports;
|
||||||
portAssignment.resize(vnaPorts, 0);
|
portAssignment.resize(vnaPorts, 0);
|
||||||
auto calPorts = 0;
|
auto calPorts = 0;
|
||||||
if(device) {
|
if(device) {
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include "devicedriver.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -20,126 +21,126 @@ static constexpr USBID IDs[] = {
|
|||||||
{0x0483, 0x4121},
|
{0x0483, 0x4121},
|
||||||
};
|
};
|
||||||
|
|
||||||
USBInBuffer::USBInBuffer(libusb_device_handle *handle, unsigned char endpoint, int buffer_size) :
|
//USBInBuffer::USBInBuffer(libusb_device_handle *handle, unsigned char endpoint, int buffer_size) :
|
||||||
buffer_size(buffer_size),
|
// buffer_size(buffer_size),
|
||||||
received_size(0),
|
// received_size(0),
|
||||||
inCallback(false),
|
// inCallback(false),
|
||||||
cancelling(false)
|
// cancelling(false)
|
||||||
{
|
//{
|
||||||
buffer = new unsigned char[buffer_size];
|
// buffer = new unsigned char[buffer_size];
|
||||||
memset(buffer, 0, buffer_size);
|
// memset(buffer, 0, buffer_size);
|
||||||
transfer = libusb_alloc_transfer(0);
|
// transfer = libusb_alloc_transfer(0);
|
||||||
libusb_fill_bulk_transfer(transfer, handle, endpoint, buffer, buffer_size, CallbackTrampoline, this, 0);
|
// libusb_fill_bulk_transfer(transfer, handle, endpoint, buffer, buffer_size, CallbackTrampoline, this, 0);
|
||||||
libusb_submit_transfer(transfer);
|
// libusb_submit_transfer(transfer);
|
||||||
}
|
//}
|
||||||
|
|
||||||
USBInBuffer::~USBInBuffer()
|
//USBInBuffer::~USBInBuffer()
|
||||||
{
|
//{
|
||||||
if(transfer) {
|
// if(transfer) {
|
||||||
cancelling = true;
|
// cancelling = true;
|
||||||
libusb_cancel_transfer(transfer);
|
// libusb_cancel_transfer(transfer);
|
||||||
// wait for cancellation to complete
|
// // wait for cancellation to complete
|
||||||
mutex mtx;
|
// mutex mtx;
|
||||||
unique_lock<mutex> lck(mtx);
|
// unique_lock<mutex> lck(mtx);
|
||||||
using namespace std::chrono_literals;
|
// using namespace std::chrono_literals;
|
||||||
if(cv.wait_for(lck, 100ms) == cv_status::timeout) {
|
// if(cv.wait_for(lck, 100ms) == cv_status::timeout) {
|
||||||
qWarning() << "Timed out waiting for mutex acquisition during disconnect";
|
// 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;
|
|
||||||
}
|
|
||||||
// qDebug() << libusb_error_name(transfer->status);
|
|
||||||
switch(transfer->status) {
|
|
||||||
case LIBUSB_TRANSFER_COMPLETED:
|
|
||||||
received_size += transfer->actual_length;
|
|
||||||
// Change/insert/delete random data to check the data handling for robustness
|
|
||||||
// srand((unsigned)time(0));
|
|
||||||
// for(unsigned int i=0;i<received_size;i++) {
|
|
||||||
// auto r = rand() % 100;
|
|
||||||
// if(r == 0) {
|
|
||||||
// // modify this byte
|
|
||||||
// buffer[i] = rand() % 256;
|
|
||||||
// } else if(r == 1) {
|
|
||||||
// // insert random byte
|
|
||||||
// memmove(&buffer[i+1], &buffer[i], received_size - i);
|
|
||||||
// buffer[i] = rand() % 256;
|
|
||||||
// received_size++;
|
|
||||||
// } else if(r == 2) {
|
|
||||||
// // remove byte
|
|
||||||
// memmove(&buffer[i], &buffer[i+1], received_size - i - 1);
|
|
||||||
// received_size--;
|
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// qDebug() << transfer->actual_length <<"total:" << received_size;
|
// delete[] buffer;
|
||||||
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)
|
//void USBInBuffer::removeBytes(int handled_bytes)
|
||||||
{
|
//{
|
||||||
auto usb = (USBInBuffer*) transfer->user_data;
|
// if(!inCallback) {
|
||||||
usb->Callback(transfer);
|
// 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;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
uint8_t *USBInBuffer::getBuffer() const
|
//int USBInBuffer::getReceived() const
|
||||||
{
|
//{
|
||||||
return buffer;
|
// 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;
|
||||||
|
// }
|
||||||
|
//// qDebug() << libusb_error_name(transfer->status);
|
||||||
|
// switch(transfer->status) {
|
||||||
|
// case LIBUSB_TRANSFER_COMPLETED:
|
||||||
|
// received_size += transfer->actual_length;
|
||||||
|
// // Change/insert/delete random data to check the data handling for robustness
|
||||||
|
//// srand((unsigned)time(0));
|
||||||
|
//// for(unsigned int i=0;i<received_size;i++) {
|
||||||
|
//// auto r = rand() % 100;
|
||||||
|
//// if(r == 0) {
|
||||||
|
//// // modify this byte
|
||||||
|
//// buffer[i] = rand() % 256;
|
||||||
|
//// } else if(r == 1) {
|
||||||
|
//// // insert random byte
|
||||||
|
//// memmove(&buffer[i+1], &buffer[i], received_size - i);
|
||||||
|
//// buffer[i] = rand() % 256;
|
||||||
|
//// received_size++;
|
||||||
|
//// } else if(r == 2) {
|
||||||
|
//// // remove byte
|
||||||
|
//// memmove(&buffer[i], &buffer[i+1], received_size - i - 1);
|
||||||
|
//// received_size--;
|
||||||
|
//// }
|
||||||
|
//// }
|
||||||
|
//// qDebug() << transfer->actual_length <<"total:" << received_size;
|
||||||
|
// 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;
|
||||||
|
//}
|
||||||
|
|
||||||
static constexpr Protocol::DeviceInfo defaultInfo = {
|
static constexpr Protocol::DeviceInfo defaultInfo = {
|
||||||
.ProtocolVersion = Protocol::Version,
|
.ProtocolVersion = Protocol::Version,
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "../../VNA_embedded/Application/Communication/Protocol.hpp"
|
#include "../../VNA_embedded/Application/Communication/Protocol.hpp"
|
||||||
|
|
||||||
|
#include "librevnausbdriver.h"
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <libusb-1.0/libusb.h>
|
#include <libusb-1.0/libusb.h>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
@ -18,31 +20,31 @@ Q_DECLARE_METATYPE(Protocol::ManualStatusV1)
|
|||||||
Q_DECLARE_METATYPE(Protocol::SpectrumAnalyzerResult)
|
Q_DECLARE_METATYPE(Protocol::SpectrumAnalyzerResult)
|
||||||
Q_DECLARE_METATYPE(Protocol::AmplitudeCorrectionPoint)
|
Q_DECLARE_METATYPE(Protocol::AmplitudeCorrectionPoint)
|
||||||
|
|
||||||
class USBInBuffer : public QObject {
|
//class USBInBuffer : public QObject {
|
||||||
Q_OBJECT
|
// Q_OBJECT
|
||||||
public:
|
//public:
|
||||||
USBInBuffer(libusb_device_handle *handle, unsigned char endpoint, int buffer_size);
|
// USBInBuffer(libusb_device_handle *handle, unsigned char endpoint, int buffer_size);
|
||||||
~USBInBuffer();
|
// ~USBInBuffer();
|
||||||
|
|
||||||
void removeBytes(int handled_bytes);
|
// void removeBytes(int handled_bytes);
|
||||||
int getReceived() const;
|
// int getReceived() const;
|
||||||
uint8_t *getBuffer() const;
|
// uint8_t *getBuffer() const;
|
||||||
|
|
||||||
signals:
|
//signals:
|
||||||
void DataReceived();
|
// void DataReceived();
|
||||||
void TransferError();
|
// void TransferError();
|
||||||
|
|
||||||
private:
|
//private:
|
||||||
void Callback(libusb_transfer *transfer);
|
// void Callback(libusb_transfer *transfer);
|
||||||
static void LIBUSB_CALL CallbackTrampoline(libusb_transfer *transfer);
|
// static void LIBUSB_CALL CallbackTrampoline(libusb_transfer *transfer);
|
||||||
libusb_transfer *transfer;
|
// libusb_transfer *transfer;
|
||||||
unsigned char *buffer;
|
// unsigned char *buffer;
|
||||||
int buffer_size;
|
// int buffer_size;
|
||||||
int received_size;
|
// int received_size;
|
||||||
bool inCallback;
|
// bool inCallback;
|
||||||
bool cancelling;
|
// bool cancelling;
|
||||||
std::condition_variable cv;
|
// std::condition_variable cv;
|
||||||
};
|
//};
|
||||||
|
|
||||||
|
|
||||||
class Device : public QObject
|
class Device : public QObject
|
||||||
|
@ -20,3 +20,85 @@ void DeviceDriver::disconnectDevice()
|
|||||||
disconnect();
|
disconnect();
|
||||||
activeDriver = nullptr;
|
activeDriver = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int DeviceDriver::SApoints() {
|
||||||
|
if(activeDriver) {
|
||||||
|
return activeDriver->getSApoints();
|
||||||
|
} else {
|
||||||
|
// return default value instead
|
||||||
|
return 1001;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Sparam DeviceDriver::VNAMeasurement::toSparam(int port1, int port2) const
|
||||||
|
{
|
||||||
|
Sparam S;
|
||||||
|
S.m11 = measurements.at("S"+QString::number(port1)+QString::number(port1));
|
||||||
|
S.m12 = measurements.at("S"+QString::number(port1)+QString::number(port2));
|
||||||
|
S.m21 = measurements.at("S"+QString::number(port2)+QString::number(port1));
|
||||||
|
S.m22 = measurements.at("S"+QString::number(port2)+QString::number(port2));
|
||||||
|
return S;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceDriver::VNAMeasurement::fromSparam(Sparam S, int port1, int port2)
|
||||||
|
{
|
||||||
|
QString s11 = "S"+QString::number(port1)+QString::number(port1);
|
||||||
|
QString s12 = "S"+QString::number(port1)+QString::number(port2);
|
||||||
|
QString s21 = "S"+QString::number(port2)+QString::number(port1);
|
||||||
|
QString s22 = "S"+QString::number(port2)+QString::number(port2);
|
||||||
|
if(measurements.count(s11)) {
|
||||||
|
measurements[s11] = S.m11;
|
||||||
|
}
|
||||||
|
if(measurements.count(s12)) {
|
||||||
|
measurements[s12] = S.m12;
|
||||||
|
}
|
||||||
|
if(measurements.count(s21)) {
|
||||||
|
measurements[s21] = S.m21;
|
||||||
|
}
|
||||||
|
if(measurements.count(s22)) {
|
||||||
|
measurements[s22] = S.m22;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceDriver::VNAMeasurement DeviceDriver::VNAMeasurement::interpolateTo(const DeviceDriver::VNAMeasurement &to, double a)
|
||||||
|
{
|
||||||
|
VNAMeasurement ret;
|
||||||
|
ret.frequency = frequency * (1.0 - a) + to.frequency * a;
|
||||||
|
ret.dBm = dBm * (1.0 - a) + to.dBm * a;
|
||||||
|
ret.Z0 = Z0 * (1.0 - a) + to.Z0 * a;
|
||||||
|
for(auto m : measurements) {
|
||||||
|
if(to.measurements.count(m.first) == 0) {
|
||||||
|
throw std::runtime_error("Nothing to interpolate to, expected measurement +\""+m.first.toStdString()+"\"");
|
||||||
|
}
|
||||||
|
ret.measurements[m.first] = measurements[m.first] * (1.0 - a) + to.measurements.at(m.first) * a;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceDriver::Info::Info()
|
||||||
|
{
|
||||||
|
firmware_version = "missing";
|
||||||
|
hardware_version = "missing";
|
||||||
|
Limits.VNA.ports = 2;
|
||||||
|
Limits.VNA.minFreq = 0;
|
||||||
|
Limits.VNA.maxFreq = 6000000000;
|
||||||
|
Limits.VNA.mindBm = -100;
|
||||||
|
Limits.VNA.maxdBm = 30;
|
||||||
|
Limits.VNA.minIFBW = 1;
|
||||||
|
Limits.VNA.maxIFBW = 1000000;
|
||||||
|
Limits.VNA.maxPoints = 65535;
|
||||||
|
|
||||||
|
Limits.Generator.ports = 2;
|
||||||
|
Limits.Generator.minFreq = 0;
|
||||||
|
Limits.Generator.maxFreq = 6000000000;
|
||||||
|
Limits.Generator.mindBm = -100;
|
||||||
|
Limits.Generator.maxdBm = 30;
|
||||||
|
|
||||||
|
Limits.SA.ports = 2;
|
||||||
|
Limits.SA.minFreq = 0;
|
||||||
|
Limits.SA.maxFreq = 6000000000;
|
||||||
|
Limits.SA.mindBm = -100;
|
||||||
|
Limits.SA.maxdBm = 30;
|
||||||
|
Limits.SA.minRBW = 1;
|
||||||
|
Limits.SA.maxRBW = 1000000;
|
||||||
|
}
|
||||||
|
@ -78,7 +78,7 @@ public:
|
|||||||
|
|
||||||
class Info {
|
class Info {
|
||||||
public:
|
public:
|
||||||
// TODO create constructor with default values
|
Info();
|
||||||
QString firmware_version;
|
QString firmware_version;
|
||||||
QString hardware_version;
|
QString hardware_version;
|
||||||
std::set<Feature> supportedFeatures;
|
std::set<Feature> supportedFeatures;
|
||||||
@ -161,6 +161,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual std::set<Flag> getFlags() = 0;
|
virtual std::set<Flag> getFlags() = 0;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
/**
|
||||||
|
* @brief Emit this signal whenever a flag changes
|
||||||
|
*/
|
||||||
|
void FlagsUpdated();
|
||||||
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks whether a specific flag is asserted
|
* @brief Checks whether a specific flag is asserted
|
||||||
* @param f Flag to check
|
* @param f Flag to check
|
||||||
@ -428,6 +435,14 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Registers metatypes within the Qt Framework.
|
||||||
|
*
|
||||||
|
* If the device driver uses a queued signal/slot connection with custom data types, these types must be registered before emitting the signal.
|
||||||
|
* Register them within this function with qRegisterMetaType<Type>("Name");
|
||||||
|
*/
|
||||||
|
virtual void registerTypes() {}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
/**
|
/**
|
||||||
* @brief Emit this signal when the device connection has been lost unexpectedly
|
* @brief Emit this signal when the device connection has been lost unexpectedly
|
||||||
@ -445,6 +460,7 @@ public:
|
|||||||
bool connectDevice(QString serial);
|
bool connectDevice(QString serial);
|
||||||
void disconnectDevice();
|
void disconnectDevice();
|
||||||
static DeviceDriver* getActiveDriver() {return activeDriver;}
|
static DeviceDriver* getActiveDriver() {return activeDriver;}
|
||||||
|
static unsigned int SApoints();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static DeviceDriver *activeDriver;
|
static DeviceDriver *activeDriver;
|
||||||
|
@ -2,6 +2,96 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
class Reference
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum class TypeIn {
|
||||||
|
Internal,
|
||||||
|
External,
|
||||||
|
Auto,
|
||||||
|
None
|
||||||
|
};
|
||||||
|
enum class OutFreq {
|
||||||
|
MHZ10,
|
||||||
|
MHZ100,
|
||||||
|
Off,
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
static QString OutFreqToLabel(Reference::OutFreq t)
|
||||||
|
{
|
||||||
|
switch(t) {
|
||||||
|
case OutFreq::MHZ10: return "10 MHz";
|
||||||
|
case OutFreq::MHZ100: return "100 MHz";
|
||||||
|
case OutFreq::Off: return "Off";
|
||||||
|
default: return "Invalid";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString OutFreqToKey(Reference::OutFreq f)
|
||||||
|
{
|
||||||
|
switch(f) {
|
||||||
|
case OutFreq::MHZ10: return "10 MHz";
|
||||||
|
case OutFreq::MHZ100: return "100 MHz";
|
||||||
|
case OutFreq::Off: return "Off";
|
||||||
|
default: return "Invalid";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Reference::OutFreq KeyToOutFreq(QString key)
|
||||||
|
{
|
||||||
|
for (auto r: Reference::getOutFrequencies()) {
|
||||||
|
if(OutFreqToKey(r) == key|| OutFreqToLabel(r) == key) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// not found
|
||||||
|
return Reference::OutFreq::None;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static QString TypeToLabel(TypeIn t)
|
||||||
|
{
|
||||||
|
switch(t) {
|
||||||
|
case TypeIn::Internal: return "Internal";
|
||||||
|
case TypeIn::External: return "External";
|
||||||
|
case TypeIn::Auto: return "Auto";
|
||||||
|
default: return "Invalid";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const QString TypeToKey(TypeIn t)
|
||||||
|
{
|
||||||
|
switch(t) {
|
||||||
|
case TypeIn::Internal: return "Int";
|
||||||
|
case TypeIn::External: return "Ext";
|
||||||
|
case TypeIn::Auto: return "Auto";
|
||||||
|
default: return "Invalid";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static TypeIn KeyToType(QString key)
|
||||||
|
{
|
||||||
|
for (auto r: Reference::getReferencesIn()) {
|
||||||
|
if(TypeToKey(r) == key || TypeToLabel(r) == key) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// not found
|
||||||
|
return TypeIn::None;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<Reference::TypeIn> getReferencesIn()
|
||||||
|
{
|
||||||
|
return {TypeIn::Internal, TypeIn::External, TypeIn::Auto};
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<Reference::OutFreq> getOutFrequencies()
|
||||||
|
{
|
||||||
|
return {OutFreq::Off, OutFreq::MHZ10, OutFreq::MHZ100};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
LibreVNADriver::LibreVNADriver()
|
LibreVNADriver::LibreVNADriver()
|
||||||
{
|
{
|
||||||
connected = false;
|
connected = false;
|
||||||
@ -142,6 +232,7 @@ bool LibreVNADriver::setSA(const DeviceDriver::SASettings &s, std::function<void
|
|||||||
zerospan = s.freqStart == s.freqStop;
|
zerospan = s.freqStart == s.freqStop;
|
||||||
|
|
||||||
Protocol::PacketInfo p = {};
|
Protocol::PacketInfo p = {};
|
||||||
|
p.type = Protocol::PacketType::SpectrumAnalyzerSettings;
|
||||||
p.spectrumSettings.f_start = s.freqStart;
|
p.spectrumSettings.f_start = s.freqStart;
|
||||||
p.spectrumSettings.f_stop = s.freqStop;
|
p.spectrumSettings.f_stop = s.freqStop;
|
||||||
|
|
||||||
@ -207,6 +298,62 @@ bool LibreVNADriver::setIdle(std::function<void (bool)> cb)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QStringList LibreVNADriver::availableExtRefInSettings()
|
||||||
|
{
|
||||||
|
QStringList ret;
|
||||||
|
for(auto r : Reference::getReferencesIn()) {
|
||||||
|
ret.push_back(Reference::TypeToLabel(r));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList LibreVNADriver::availableExtRefOutSettings()
|
||||||
|
{
|
||||||
|
QStringList ret;
|
||||||
|
for(auto r : Reference::getOutFrequencies()) {
|
||||||
|
ret.push_back(Reference::OutFreqToLabel(r));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LibreVNADriver::setExtRef(QString option_in, QString option_out)
|
||||||
|
{
|
||||||
|
auto refIn = Reference::KeyToType(option_in);
|
||||||
|
if(refIn == Reference::TypeIn::None) {
|
||||||
|
refIn = Reference::TypeIn::Internal;
|
||||||
|
}
|
||||||
|
auto refOut = Reference::KeyToOutFreq(option_out);
|
||||||
|
if(refOut == Reference::OutFreq::None) {
|
||||||
|
refOut = Reference::OutFreq::Off;
|
||||||
|
}
|
||||||
|
|
||||||
|
Protocol::PacketInfo p = {};
|
||||||
|
p.type = Protocol::PacketType::Reference;
|
||||||
|
switch(refIn) {
|
||||||
|
case Reference::TypeIn::Internal:
|
||||||
|
case Reference::TypeIn::None:
|
||||||
|
p.reference.UseExternalRef = 0;
|
||||||
|
p.reference.AutomaticSwitch = 0;
|
||||||
|
break;
|
||||||
|
case Reference::TypeIn::Auto:
|
||||||
|
p.reference.UseExternalRef = 0;
|
||||||
|
p.reference.AutomaticSwitch = 1;
|
||||||
|
break;
|
||||||
|
case Reference::TypeIn::External:
|
||||||
|
p.reference.UseExternalRef = 1;
|
||||||
|
p.reference.AutomaticSwitch = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch(refOut) {
|
||||||
|
case Reference::OutFreq::None:
|
||||||
|
case Reference::OutFreq::Off: p.reference.ExtRefOuputFreq = 0; break;
|
||||||
|
case Reference::OutFreq::MHZ10: p.reference.ExtRefOuputFreq = 10000000; break;
|
||||||
|
case Reference::OutFreq::MHZ100: p.reference.ExtRefOuputFreq = 100000000; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SendPacket(p);
|
||||||
|
}
|
||||||
|
|
||||||
void LibreVNADriver::handleReceivedPacket(const Protocol::PacketInfo &packet)
|
void LibreVNADriver::handleReceivedPacket(const Protocol::PacketInfo &packet)
|
||||||
{
|
{
|
||||||
emit passOnReceivedPacket(packet);
|
emit passOnReceivedPacket(packet);
|
||||||
@ -253,6 +400,7 @@ void LibreVNADriver::handleReceivedPacket(const Protocol::PacketInfo &packet)
|
|||||||
case Protocol::PacketType::DeviceStatusV1:
|
case Protocol::PacketType::DeviceStatusV1:
|
||||||
lastStatus = packet.statusV1;
|
lastStatus = packet.statusV1;
|
||||||
emit StatusUpdated();
|
emit StatusUpdated();
|
||||||
|
emit FlagsUpdated();
|
||||||
break;
|
break;
|
||||||
case Protocol::PacketType::VNADatapoint: {
|
case Protocol::PacketType::VNADatapoint: {
|
||||||
VNAMeasurement m;
|
VNAMeasurement m;
|
||||||
|
@ -249,6 +249,12 @@ void LibreVNAUSBDriver::disconnect()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LibreVNAUSBDriver::registerTypes()
|
||||||
|
{
|
||||||
|
qRegisterMetaType<Protocol::PacketInfo>("LibreVNAUSBPacket");
|
||||||
|
qRegisterMetaType<TransmissionResult>("LibreVNAUSBResult");
|
||||||
|
}
|
||||||
|
|
||||||
void LibreVNAUSBDriver::ReceivedData()
|
void LibreVNAUSBDriver::ReceivedData()
|
||||||
{
|
{
|
||||||
Protocol::PacketInfo packet;
|
Protocol::PacketInfo packet;
|
||||||
@ -429,3 +435,32 @@ void LibreVNAUSBDriver::SearchDevices(std::function<bool (libusb_device_handle *
|
|||||||
}
|
}
|
||||||
libusb_free_device_list(devList, 1);
|
libusb_free_device_list(devList, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LibreVNAUSBDriver::startNextTransmission()
|
||||||
|
{
|
||||||
|
if(transmissionQueue.isEmpty() || !connected) {
|
||||||
|
// nothing more to transmit
|
||||||
|
transmissionActive = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
transmissionActive = true;
|
||||||
|
auto t = transmissionQueue.head();
|
||||||
|
unsigned char buffer[1024];
|
||||||
|
unsigned int length = Protocol::EncodePacket(t.packet, buffer, sizeof(buffer));
|
||||||
|
if(!length) {
|
||||||
|
qCritical() << "Failed to encode packet";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int actual_length;
|
||||||
|
auto &log = DeviceUSBLog::getInstance();
|
||||||
|
log.addPacket(t.packet);
|
||||||
|
auto ret = libusb_bulk_transfer(m_handle, EP_Data_Out_Addr, buffer, length, &actual_length, 0);
|
||||||
|
if(ret < 0) {
|
||||||
|
qCritical() << "Error sending data: "
|
||||||
|
<< libusb_strerror((libusb_error) ret);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
transmissionTimer.start(t.timeout);
|
||||||
|
// qDebug() << "Transmission started, queue at " << transmissionQueue.size();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -10,6 +10,9 @@
|
|||||||
#include <QQueue>
|
#include <QQueue>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(Protocol::PacketInfo)
|
||||||
|
Q_DECLARE_METATYPE(LibreVNADriver::TransmissionResult)
|
||||||
|
|
||||||
class USBInBuffer : public QObject {
|
class USBInBuffer : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
@ -63,6 +66,14 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual void disconnect() override;
|
virtual void disconnect() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Registers metatypes within the Qt Framework.
|
||||||
|
*
|
||||||
|
* If the device driver uses a queued signal/slot connection with custom data types, these types must be registered before emitting the signal.
|
||||||
|
* Register them within this function with qRegisterMetaType<Type>("Name");
|
||||||
|
*/
|
||||||
|
virtual void registerTypes();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void ReceivedData();
|
void ReceivedData();
|
||||||
void ReceivedLog();
|
void ReceivedLog();
|
||||||
@ -101,11 +112,6 @@ private:
|
|||||||
bool transmissionActive;
|
bool transmissionActive;
|
||||||
|
|
||||||
std::thread *m_receiveThread;
|
std::thread *m_receiveThread;
|
||||||
Protocol::DeviceInfo info;
|
|
||||||
bool infoValid;
|
|
||||||
union {
|
|
||||||
Protocol::DeviceStatusV1 v1;
|
|
||||||
} status;
|
|
||||||
|
|
||||||
std::mutex accessMutex;
|
std::mutex accessMutex;
|
||||||
};
|
};
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,220 +1,220 @@
|
|||||||
#ifndef VIRTUALDEVICE_H
|
//#ifndef VIRTUALDEVICE_H
|
||||||
#define VIRTUALDEVICE_H
|
//#define VIRTUALDEVICE_H
|
||||||
|
|
||||||
#include "device.h"
|
//#include "device.h"
|
||||||
#include "Tools/parameters.h"
|
//#include "Tools/parameters.h"
|
||||||
#include "compounddevice.h"
|
//#include "compounddevice.h"
|
||||||
|
|
||||||
#include <set>
|
//#include <set>
|
||||||
#include <complex>
|
//#include <complex>
|
||||||
|
|
||||||
#include <QObject>
|
//#include <QObject>
|
||||||
|
|
||||||
class VirtualDevice : public QObject
|
//class VirtualDevice : public QObject
|
||||||
{
|
//{
|
||||||
Q_OBJECT
|
// Q_OBJECT
|
||||||
public:
|
//public:
|
||||||
VirtualDevice(QString serial = "");
|
// VirtualDevice(QString serial = "");
|
||||||
~VirtualDevice();
|
// ~VirtualDevice();
|
||||||
|
|
||||||
class Info {
|
// class Info {
|
||||||
public:
|
// public:
|
||||||
Info();
|
// Info();
|
||||||
Info(Device *dev);
|
// Info(Device *dev);
|
||||||
|
|
||||||
void subset(const Info &merge);
|
// void subset(const Info &merge);
|
||||||
|
|
||||||
uint16_t ProtocolVersion;
|
// uint16_t ProtocolVersion;
|
||||||
uint8_t FW_major;
|
// uint8_t FW_major;
|
||||||
uint8_t FW_minor;
|
// uint8_t FW_minor;
|
||||||
uint8_t FW_patch;
|
// uint8_t FW_patch;
|
||||||
uint8_t hardware_version;
|
// uint8_t hardware_version;
|
||||||
char HW_Revision;
|
// char HW_Revision;
|
||||||
unsigned int ports;
|
// unsigned int ports;
|
||||||
bool supportsVNAmode;
|
// bool supportsVNAmode;
|
||||||
bool supportsSAmode;
|
// bool supportsSAmode;
|
||||||
bool supportsSGmode;
|
// bool supportsSGmode;
|
||||||
bool supportsExtRef;
|
// bool supportsExtRef;
|
||||||
struct {
|
// struct {
|
||||||
double minFreq, maxFreq, maxFreqHarmonic;
|
// double minFreq, maxFreq, maxFreqHarmonic;
|
||||||
double minIFBW, maxIFBW;
|
// double minIFBW, maxIFBW;
|
||||||
unsigned int maxPoints;
|
// unsigned int maxPoints;
|
||||||
double mindBm;
|
// double mindBm;
|
||||||
double maxdBm;
|
// double maxdBm;
|
||||||
double minRBW, maxRBW;
|
// double minRBW, maxRBW;
|
||||||
} Limits;
|
// } Limits;
|
||||||
};
|
// };
|
||||||
|
|
||||||
class Status {
|
// class Status {
|
||||||
public:
|
// public:
|
||||||
Status();
|
// Status();
|
||||||
Status(Device *dev);
|
// Status(Device *dev);
|
||||||
|
|
||||||
void merge(const Status &merge);
|
// void merge(const Status &merge);
|
||||||
|
|
||||||
QString statusString;
|
// QString statusString;
|
||||||
bool overload;
|
// bool overload;
|
||||||
bool unlocked;
|
// bool unlocked;
|
||||||
bool unlevel;
|
// bool unlevel;
|
||||||
bool extRef;
|
// bool extRef;
|
||||||
};
|
// };
|
||||||
|
|
||||||
static void RegisterTypes();
|
// static void RegisterTypes();
|
||||||
|
|
||||||
void initialize(); // call this after creating the virtual device and all connections to signals have been made
|
// void initialize(); // call this after creating the virtual device and all connections to signals have been made
|
||||||
|
|
||||||
bool isCompoundDevice() const;
|
// bool isCompoundDevice() const;
|
||||||
Device *getDevice();
|
// Device *getDevice();
|
||||||
CompoundDevice *getCompoundDevice();
|
// CompoundDevice *getCompoundDevice();
|
||||||
std::vector<Device*> getDevices();
|
// std::vector<Device*> getDevices();
|
||||||
const Info& getInfo() const;
|
// const Info& getInfo() const;
|
||||||
static VirtualDevice::Info getInfo(VirtualDevice *vdev);
|
// static VirtualDevice::Info getInfo(VirtualDevice *vdev);
|
||||||
const Status &getStatus() const;
|
// const Status &getStatus() const;
|
||||||
static VirtualDevice::Status getStatus(VirtualDevice *vdev);
|
// static VirtualDevice::Status getStatus(VirtualDevice *vdev);
|
||||||
|
|
||||||
class VNASettings {
|
// class VNASettings {
|
||||||
public:
|
// public:
|
||||||
double freqStart, freqStop;
|
// double freqStart, freqStop;
|
||||||
double dBmStart, dBmStop;
|
// double dBmStart, dBmStop;
|
||||||
double IFBW;
|
// double IFBW;
|
||||||
int points;
|
// int points;
|
||||||
bool logSweep;
|
// bool logSweep;
|
||||||
std::vector<int> excitedPorts; // port count starts at one
|
// std::vector<int> excitedPorts; // port count starts at one
|
||||||
};
|
// };
|
||||||
class VNAMeasurement {
|
// class VNAMeasurement {
|
||||||
public:
|
// public:
|
||||||
unsigned int pointNum;
|
// unsigned int pointNum;
|
||||||
double Z0;
|
// double Z0;
|
||||||
union {
|
// union {
|
||||||
struct {
|
// struct {
|
||||||
// for non-zero span
|
// // for non-zero span
|
||||||
double frequency;
|
// double frequency;
|
||||||
double dBm;
|
// double dBm;
|
||||||
};
|
// };
|
||||||
struct {
|
// struct {
|
||||||
// for zero span
|
// // for zero span
|
||||||
double us; // time in us since first datapoint
|
// double us; // time in us since first datapoint
|
||||||
};
|
// };
|
||||||
};
|
// };
|
||||||
std::map<QString, std::complex<double>> measurements;
|
// std::map<QString, std::complex<double>> measurements;
|
||||||
|
|
||||||
Sparam toSparam(int port1, int port2) const;
|
// Sparam toSparam(int port1, int port2) const;
|
||||||
void fromSparam(Sparam S, int port1, int port2);
|
// void fromSparam(Sparam S, int port1, int port2);
|
||||||
VNAMeasurement interpolateTo(const VNAMeasurement &to, double a);
|
// VNAMeasurement interpolateTo(const VNAMeasurement &to, double a);
|
||||||
};
|
// };
|
||||||
|
|
||||||
QStringList availableVNAMeasurements();
|
// QStringList availableVNAMeasurements();
|
||||||
bool setVNA(const VNASettings &s, std::function<void(bool)> cb = nullptr);
|
// bool setVNA(const VNASettings &s, std::function<void(bool)> cb = nullptr);
|
||||||
QString serial();
|
// QString serial();
|
||||||
|
|
||||||
class SASettings {
|
// class SASettings {
|
||||||
public:
|
// public:
|
||||||
enum class Window {
|
// enum class Window {
|
||||||
None = 0,
|
// None = 0,
|
||||||
Kaiser = 1,
|
// Kaiser = 1,
|
||||||
Hann = 2,
|
// Hann = 2,
|
||||||
FlatTop = 3,
|
// FlatTop = 3,
|
||||||
Last
|
// Last
|
||||||
};
|
// };
|
||||||
enum class Detector {
|
// enum class Detector {
|
||||||
PPeak = 0,
|
// PPeak = 0,
|
||||||
NPeak = 1,
|
// NPeak = 1,
|
||||||
Sample = 2,
|
// Sample = 2,
|
||||||
Normal = 3,
|
// Normal = 3,
|
||||||
Average = 4,
|
// Average = 4,
|
||||||
Last
|
// Last
|
||||||
};
|
// };
|
||||||
|
|
||||||
double freqStart, freqStop;
|
// double freqStart, freqStop;
|
||||||
double RBW;
|
// double RBW;
|
||||||
int points;
|
// int points;
|
||||||
Window window;
|
// Window window;
|
||||||
Detector detector;
|
// Detector detector;
|
||||||
bool signalID;
|
// bool signalID;
|
||||||
bool trackingGenerator;
|
// bool trackingGenerator;
|
||||||
int trackingPort; // counting starts at zero
|
// int trackingPort; // counting starts at zero
|
||||||
double trackingOffset;
|
// double trackingOffset;
|
||||||
double trackingPower;
|
// double trackingPower;
|
||||||
};
|
// };
|
||||||
class SAMeasurement {
|
// class SAMeasurement {
|
||||||
public:
|
// public:
|
||||||
int pointNum;
|
// int pointNum;
|
||||||
union {
|
// union {
|
||||||
struct {
|
// struct {
|
||||||
// for non-zero span
|
// // for non-zero span
|
||||||
double frequency;
|
// double frequency;
|
||||||
};
|
// };
|
||||||
struct {
|
// struct {
|
||||||
// for zero span
|
// // for zero span
|
||||||
double us; // time in us since first datapoint
|
// double us; // time in us since first datapoint
|
||||||
};
|
// };
|
||||||
};
|
// };
|
||||||
std::map<QString, double> measurements;
|
// std::map<QString, double> measurements;
|
||||||
};
|
// };
|
||||||
|
|
||||||
QStringList availableSAMeasurements();
|
// QStringList availableSAMeasurements();
|
||||||
bool setSA(const SASettings &s, std::function<void(bool)> cb = nullptr);
|
// bool setSA(const SASettings &s, std::function<void(bool)> cb = nullptr);
|
||||||
|
|
||||||
class SGSettings {
|
// class SGSettings {
|
||||||
public:
|
// public:
|
||||||
double freq;
|
// double freq;
|
||||||
double dBm;
|
// double dBm;
|
||||||
int port; // starts at one, set to zero to disable all ports
|
// int port; // starts at one, set to zero to disable all ports
|
||||||
};
|
// };
|
||||||
|
|
||||||
QStringList availableSGPorts();
|
// QStringList availableSGPorts();
|
||||||
bool setSG(const SGSettings &s);
|
// bool setSG(const SGSettings &s);
|
||||||
|
|
||||||
bool setIdle(std::function<void(bool)> cb = nullptr);
|
// bool setIdle(std::function<void(bool)> cb = nullptr);
|
||||||
|
|
||||||
QStringList availableExtRefInSettings();
|
// QStringList availableExtRefInSettings();
|
||||||
QStringList availableExtRefOutSettings();
|
// QStringList availableExtRefOutSettings();
|
||||||
|
|
||||||
bool setExtRef(QString option_in, QString option_out);
|
// bool setExtRef(QString option_in, QString option_out);
|
||||||
|
|
||||||
static std::set<QString> GetAvailableVirtualDevices();
|
// static std::set<QString> GetAvailableVirtualDevices();
|
||||||
static VirtualDevice* getConnected();
|
// static VirtualDevice* getConnected();
|
||||||
|
|
||||||
static constexpr unsigned int maximumSupportedPorts = 8;
|
// static constexpr unsigned int maximumSupportedPorts = 8;
|
||||||
|
|
||||||
signals:
|
//signals:
|
||||||
void VNAmeasurementReceived(VNAMeasurement m);
|
// void VNAmeasurementReceived(VNAMeasurement m);
|
||||||
void SAmeasurementReceived(SAMeasurement m);
|
// void SAmeasurementReceived(SAMeasurement m);
|
||||||
void ConnectionLost();
|
// void ConnectionLost();
|
||||||
void InfoUpdated();
|
// void InfoUpdated();
|
||||||
void StatusUpdated(Status status);
|
// void StatusUpdated(Status status);
|
||||||
void LogLineReceived(QString line);
|
// void LogLineReceived(QString line);
|
||||||
void NeedsFirmwareUpdate(int usedProtocol, int requiredProtocol);
|
// void NeedsFirmwareUpdate(int usedProtocol, int requiredProtocol);
|
||||||
|
|
||||||
private slots:
|
//private slots:
|
||||||
void singleDatapointReceived(Device *dev, Protocol::VNADatapoint<32> *res);
|
// void singleDatapointReceived(Device *dev, Protocol::VNADatapoint<32> *res);
|
||||||
void compoundDatapointReceivecd(Device *dev, Protocol::VNADatapoint<32> *data);
|
// void compoundDatapointReceivecd(Device *dev, Protocol::VNADatapoint<32> *data);
|
||||||
void singleSpectrumResultReceived(Device *dev, Protocol::SpectrumAnalyzerResult res);
|
// void singleSpectrumResultReceived(Device *dev, Protocol::SpectrumAnalyzerResult res);
|
||||||
void compoundSpectrumResultReceived(Device *dev, Protocol::SpectrumAnalyzerResult res);
|
// void compoundSpectrumResultReceived(Device *dev, Protocol::SpectrumAnalyzerResult res);
|
||||||
void compoundInfoUpdated(Device *dev);
|
// void compoundInfoUpdated(Device *dev);
|
||||||
void compoundStatusUpdated(Device *dev);
|
// void compoundStatusUpdated(Device *dev);
|
||||||
private:
|
//private:
|
||||||
void checkIfAllTransmissionsComplete(std::function<void(bool)> cb = nullptr);
|
// void checkIfAllTransmissionsComplete(std::function<void(bool)> cb = nullptr);
|
||||||
|
|
||||||
Info info;
|
// Info info;
|
||||||
Status status;
|
// Status status;
|
||||||
std::vector<Device*> devices;
|
// std::vector<Device*> devices;
|
||||||
bool zerospan;
|
// bool zerospan;
|
||||||
|
|
||||||
std::map<Device*, Device::TransmissionResult> results;
|
// std::map<Device*, Device::TransmissionResult> results;
|
||||||
|
|
||||||
CompoundDevice *cdev;
|
// CompoundDevice *cdev;
|
||||||
|
|
||||||
std::map<int, std::map<Device*, Protocol::VNADatapoint<32>*>> compoundVNABuffer;
|
// std::map<int, std::map<Device*, Protocol::VNADatapoint<32>*>> compoundVNABuffer;
|
||||||
std::map<int, std::map<Device*, Protocol::SpectrumAnalyzerResult>> compoundSABuffer;
|
// std::map<int, std::map<Device*, Protocol::SpectrumAnalyzerResult>> compoundSABuffer;
|
||||||
std::map<Device*, Protocol::DeviceInfo> compoundInfoBuffer;
|
// std::map<Device*, Protocol::DeviceInfo> compoundInfoBuffer;
|
||||||
std::map<Device*, Protocol::DeviceStatusV1> compoundStatusBuffer;
|
// std::map<Device*, Protocol::DeviceStatusV1> compoundStatusBuffer;
|
||||||
|
|
||||||
std::map<int, int> portStageMapping; // maps from excitedPort (count starts at zero) to stage (count starts at zero)
|
// std::map<int, int> portStageMapping; // maps from excitedPort (count starts at zero) to stage (count starts at zero)
|
||||||
};
|
//};
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(VirtualDevice::Status)
|
//Q_DECLARE_METATYPE(VirtualDevice::Status)
|
||||||
Q_DECLARE_METATYPE(VirtualDevice::VNAMeasurement)
|
//Q_DECLARE_METATYPE(VirtualDevice::VNAMeasurement)
|
||||||
Q_DECLARE_METATYPE(VirtualDevice::SAMeasurement)
|
//Q_DECLARE_METATYPE(VirtualDevice::SAMeasurement)
|
||||||
|
|
||||||
#endif // VIRTUALDEVICE_H
|
//#endif // VIRTUALDEVICE_H
|
||||||
|
@ -499,18 +499,18 @@ void SpectrumAnalyzer::NewDatapoint(DeviceDriver::SAMeasurement m)
|
|||||||
for(auto m : m_avg.measurements) {
|
for(auto m : m_avg.measurements) {
|
||||||
normalize.portCorrection[m.first].push_back(m.second);
|
normalize.portCorrection[m.first].push_back(m.second);
|
||||||
}
|
}
|
||||||
if(m_avg.pointNum == DeviceDriver::getActiveDriver()->getSApoints() - 1) {
|
if(m_avg.pointNum == DeviceDriver::SApoints() - 1) {
|
||||||
// this was the last point
|
// this was the last point
|
||||||
normalize.measuring = false;
|
normalize.measuring = false;
|
||||||
normalize.f_start = settings.freqStart;
|
normalize.f_start = settings.freqStart;
|
||||||
normalize.f_stop = settings.freqStop;
|
normalize.f_stop = settings.freqStop;
|
||||||
normalize.points = DeviceDriver::getActiveDriver()->getSApoints();
|
normalize.points = DeviceDriver::SApoints();
|
||||||
EnableNormalization(true);
|
EnableNormalization(true);
|
||||||
qDebug() << "Normalization measurement complete";
|
qDebug() << "Normalization measurement complete";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int percentage = (((average.currentSweep() - 1) * 100) + (m_avg.pointNum + 1) * 100 / DeviceDriver::getActiveDriver()->getSApoints()) / averages;
|
int percentage = (((average.currentSweep() - 1) * 100) + (m_avg.pointNum + 1) * 100 / DeviceDriver::SApoints()) / averages;
|
||||||
normalize.dialog.setValue(percentage);
|
normalize.dialog.setValue(percentage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -524,7 +524,7 @@ void SpectrumAnalyzer::NewDatapoint(DeviceDriver::SAMeasurement m)
|
|||||||
|
|
||||||
traceModel.addSAData(m_avg, settings);
|
traceModel.addSAData(m_avg, settings);
|
||||||
emit dataChanged();
|
emit dataChanged();
|
||||||
if(m_avg.pointNum == DeviceDriver::getActiveDriver()->getSApoints() - 1) {
|
if(m_avg.pointNum == DeviceDriver::SApoints() - 1) {
|
||||||
UpdateAverageCount();
|
UpdateAverageCount();
|
||||||
markerModel->updateMarkers();
|
markerModel->updateMarkers();
|
||||||
}
|
}
|
||||||
@ -771,7 +771,8 @@ void SpectrumAnalyzer::EnableNormalization(bool enabled)
|
|||||||
if(enabled != normalize.active) {
|
if(enabled != normalize.active) {
|
||||||
if(enabled) {
|
if(enabled) {
|
||||||
// check if measurements already taken
|
// check if measurements already taken
|
||||||
if(normalize.f_start == settings.freqStart && normalize.f_stop == settings.freqStop && normalize.points == settings.points) {
|
if(normalize.f_start == settings.freqStart && normalize.f_stop == settings.freqStop
|
||||||
|
&& normalize.points == DeviceDriver::SApoints()) {
|
||||||
// same settings as with normalization measurement, can enable
|
// same settings as with normalization measurement, can enable
|
||||||
normalize.active = true;
|
normalize.active = true;
|
||||||
} else {
|
} else {
|
||||||
@ -856,7 +857,7 @@ void SpectrumAnalyzer::ConfigureDevice()
|
|||||||
|
|
||||||
if(normalize.active) {
|
if(normalize.active) {
|
||||||
// check if normalization is still valid
|
// check if normalization is still valid
|
||||||
if(normalize.f_start != settings.freqStart || normalize.f_stop != settings.freqStop || normalize.points != DeviceDriver::getActiveDriver()->getSApoints()) {
|
if(normalize.f_start != settings.freqStart || normalize.f_stop != settings.freqStop || normalize.points != DeviceDriver::SApoints()) {
|
||||||
// normalization was taken at different settings, disable
|
// normalization was taken at different settings, disable
|
||||||
EnableNormalization(false);
|
EnableNormalization(false);
|
||||||
InformationBox::ShowMessage("Information", "Normalization was disabled because the span has been changed");
|
InformationBox::ShowMessage("Information", "Normalization was disabled because the span has been changed");
|
||||||
@ -869,7 +870,7 @@ void SpectrumAnalyzer::ConfigureDevice()
|
|||||||
emit sweepStopped();
|
emit sweepStopped();
|
||||||
changingSettings = false;
|
changingSettings = false;
|
||||||
}
|
}
|
||||||
average.reset(DeviceDriver::getActiveDriver()->getSApoints());
|
average.reset(DeviceDriver::SApoints());
|
||||||
UpdateAverageCount();
|
UpdateAverageCount();
|
||||||
traceModel.clearLiveData();
|
traceModel.clearLiveData();
|
||||||
emit traceModel.SpanChanged(settings.freqStart, settings.freqStop);
|
emit traceModel.SpanChanged(settings.freqStart, settings.freqStop);
|
||||||
@ -890,7 +891,7 @@ void SpectrumAnalyzer::ConfigureDevice()
|
|||||||
|
|
||||||
void SpectrumAnalyzer::ResetLiveTraces()
|
void SpectrumAnalyzer::ResetLiveTraces()
|
||||||
{
|
{
|
||||||
average.reset(DeviceDriver::getActiveDriver()->getSApoints());
|
average.reset(DeviceDriver::SApoints());
|
||||||
traceModel.clearLiveData();
|
traceModel.clearLiveData();
|
||||||
UpdateAverageCount();
|
UpdateAverageCount();
|
||||||
}
|
}
|
||||||
|
@ -125,12 +125,11 @@ TraceEditDialog::TraceEditDialog(Trace &t, QWidget *parent) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
VNAtrace = Trace::isVNAParameter(t.liveParameter());
|
VNAtrace = Trace::isVNAParameter(t.liveParameter());
|
||||||
if(VirtualDevice::getConnected()) {
|
if(DeviceDriver::getActiveDriver()) {
|
||||||
qDebug() << VirtualDevice::getConnected();
|
|
||||||
if(VNAtrace) {
|
if(VNAtrace) {
|
||||||
ui->CLiveParam->addItems(VirtualDevice::getConnected()->availableVNAMeasurements());
|
ui->CLiveParam->addItems(DeviceDriver::getActiveDriver()->availableVNAMeasurements());
|
||||||
} else {
|
} else {
|
||||||
ui->CLiveParam->addItems(VirtualDevice::getConnected()->availableSAMeasurements());
|
ui->CLiveParam->addItems(DeviceDriver::getActiveDriver()->availableSAMeasurements());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1430,8 +1430,8 @@ void VNA::SetupSCPI()
|
|||||||
|
|
||||||
void VNA::ConstrainAndUpdateFrequencies()
|
void VNA::ConstrainAndUpdateFrequencies()
|
||||||
{
|
{
|
||||||
if(settings.Freq.stop > DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minFreq) {
|
if(settings.Freq.stop > DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxFreq) {
|
||||||
settings.Freq.stop = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.minFreq;
|
settings.Freq.stop = DeviceDriver::getInfo(window->getDevice()).Limits.VNA.maxFreq;
|
||||||
}
|
}
|
||||||
if(settings.Freq.start > settings.Freq.stop) {
|
if(settings.Freq.start > settings.Freq.stop) {
|
||||||
settings.Freq.start = settings.Freq.stop;
|
settings.Freq.start = settings.Freq.stop;
|
||||||
|
@ -60,6 +60,7 @@
|
|||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QCommandLineParser>
|
#include <QCommandLineParser>
|
||||||
#include <QScrollArea>
|
#include <QScrollArea>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -84,9 +85,6 @@ AppWindow::AppWindow(QWidget *parent)
|
|||||||
// qDebug().setVerbosity(0);
|
// qDebug().setVerbosity(0);
|
||||||
qDebug() << "Application start";
|
qDebug() << "Application start";
|
||||||
|
|
||||||
// Register device drivers
|
|
||||||
deviceDrivers.push_back(new LibreVNAUSBDriver());
|
|
||||||
|
|
||||||
this->setWindowIcon(QIcon(":/app/logo.png"));
|
this->setWindowIcon(QIcon(":/app/logo.png"));
|
||||||
|
|
||||||
parser.setApplicationDescription(qlibrevnaApp->applicationName());
|
parser.setApplicationDescription(qlibrevnaApp->applicationName());
|
||||||
@ -106,6 +104,15 @@ AppWindow::AppWindow(QWidget *parent)
|
|||||||
} else {
|
} else {
|
||||||
Preferences::getInstance().load();
|
Preferences::getInstance().load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Register device drivers
|
||||||
|
deviceDrivers.push_back(new LibreVNAUSBDriver());
|
||||||
|
|
||||||
|
for(auto driver : deviceDrivers) {
|
||||||
|
driver->registerTypes();
|
||||||
|
Preferences::getInstance().load(driver->driverSpecificSettings());
|
||||||
|
}
|
||||||
|
|
||||||
device = nullptr;
|
device = nullptr;
|
||||||
// vdevice = nullptr;
|
// vdevice = nullptr;
|
||||||
modeHandler = nullptr;
|
modeHandler = nullptr;
|
||||||
@ -184,9 +191,9 @@ AppWindow::AppWindow(QWidget *parent)
|
|||||||
}
|
}
|
||||||
// List available devices
|
// List available devices
|
||||||
UpdateDeviceList();
|
UpdateDeviceList();
|
||||||
if(pref.Startup.ConnectToFirstDevice) {
|
if(pref.Startup.ConnectToFirstDevice && deviceList.size() > 0) {
|
||||||
// at least one device available
|
// at least one device available
|
||||||
ConnectToDevice();
|
ConnectToDevice(deviceList[0].serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(parser.isSet("setup")) {
|
if(parser.isSet("setup")) {
|
||||||
@ -325,10 +332,13 @@ void AppWindow::closeEvent(QCloseEvent *event)
|
|||||||
delete modeHandler;
|
delete modeHandler;
|
||||||
modeHandler = nullptr;
|
modeHandler = nullptr;
|
||||||
pref.store();
|
pref.store();
|
||||||
|
for(auto driver : deviceDrivers) {
|
||||||
|
Preferences::getInstance().store(driver->driverSpecificSettings());
|
||||||
|
}
|
||||||
QMainWindow::closeEvent(event);
|
QMainWindow::closeEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AppWindow::ConnectToDevice(QString serial)
|
bool AppWindow::ConnectToDevice(QString serial, DeviceDriver *driver)
|
||||||
{
|
{
|
||||||
if(serial.isEmpty()) {
|
if(serial.isEmpty()) {
|
||||||
qDebug() << "Trying to connect to any device";
|
qDebug() << "Trying to connect to any device";
|
||||||
@ -341,16 +351,24 @@ bool AppWindow::ConnectToDevice(QString serial)
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
qDebug() << "Attempting to connect to device...";
|
qDebug() << "Attempting to connect to device...";
|
||||||
for(auto driver : deviceDrivers) {
|
for(auto d : deviceDrivers) {
|
||||||
if(driver->GetAvailableDevices().count(serial)) {
|
if(driver && driver != d) {
|
||||||
|
// not the specified driver
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(d->GetAvailableDevices().count(serial)) {
|
||||||
// this driver can connect to the device
|
// this driver can connect to the device
|
||||||
if(driver->connectDevice(serial)) {
|
if(d->connectDevice(serial)) {
|
||||||
device = driver;
|
device = d;
|
||||||
} else {
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!device) {
|
||||||
// failed to connect
|
// failed to connect
|
||||||
// TODO show error message
|
InformationBox::ShowError("Failed to connect", "Could not connect to "+serial);
|
||||||
}
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
UpdateStatusBar(AppWindow::DeviceStatusBar::Connected);
|
UpdateStatusBar(AppWindow::DeviceStatusBar::Connected);
|
||||||
connect(device, &DeviceDriver::InfoUpdated, this, &AppWindow::DeviceInfoUpdated);
|
connect(device, &DeviceDriver::InfoUpdated, this, &AppWindow::DeviceInfoUpdated);
|
||||||
@ -368,8 +386,11 @@ bool AppWindow::ConnectToDevice(QString serial)
|
|||||||
// }
|
// }
|
||||||
ui->actionPreset->setEnabled(true);
|
ui->actionPreset->setEnabled(true);
|
||||||
|
|
||||||
|
DeviceEntry e;
|
||||||
|
e.serial = device->getSerial();
|
||||||
|
e.driver = device;
|
||||||
for(auto d : deviceActionGroup->actions()) {
|
for(auto d : deviceActionGroup->actions()) {
|
||||||
if(d->text() == device->getSerial()) {
|
if(d->text() == e.toString()) {
|
||||||
d->blockSignals(true);
|
d->blockSignals(true);
|
||||||
d->setChecked(true);
|
d->setChecked(true);
|
||||||
d->blockSignals(false);
|
d->blockSignals(false);
|
||||||
@ -476,9 +497,11 @@ void AppWindow::SetupSCPI()
|
|||||||
}));
|
}));
|
||||||
scpi_dev->add(new SCPICommand("LIST", nullptr, [=](QStringList) -> QString {
|
scpi_dev->add(new SCPICommand("LIST", nullptr, [=](QStringList) -> QString {
|
||||||
QString ret;
|
QString ret;
|
||||||
for(auto d : VirtualDevice::GetAvailableVirtualDevices()) {
|
for(auto driver : deviceDrivers) {
|
||||||
|
for(auto d : driver->GetAvailableDevices()) {
|
||||||
ret += d + ",";
|
ret += d + ",";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// remove last comma
|
// remove last comma
|
||||||
ret.chop(1);
|
ret.chop(1);
|
||||||
return ret;
|
return ret;
|
||||||
@ -933,34 +956,43 @@ int AppWindow::UpdateDeviceList()
|
|||||||
{
|
{
|
||||||
deviceActionGroup->setExclusive(true);
|
deviceActionGroup->setExclusive(true);
|
||||||
ui->menuConnect_to->clear();
|
ui->menuConnect_to->clear();
|
||||||
std::set<QString> devices;
|
deviceList.clear();
|
||||||
for(auto driver : deviceDrivers) {
|
for(auto driver : deviceDrivers) {
|
||||||
devices.merge(driver->GetAvailableDevices());
|
for(auto serial : driver->GetAvailableDevices()) {
|
||||||
|
DeviceEntry e;
|
||||||
|
e.driver = driver;
|
||||||
|
e.serial = serial;
|
||||||
|
deviceList.push_back(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(device) {
|
if(device) {
|
||||||
devices.insert(device->getSerial());
|
DeviceEntry e;
|
||||||
|
e.driver = device;
|
||||||
|
e.serial = device->getSerial();
|
||||||
|
if(std::find(deviceList.begin(), deviceList.end(), e) == deviceList.end()) {
|
||||||
|
// connected device is not in list (this may happen if the driver does not detect a connected device as "available")
|
||||||
|
deviceList.push_back(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
int available = 0;
|
int available = 0;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
if(devices.size()) {
|
for(auto d : deviceList) {
|
||||||
for(auto d : devices) {
|
if(!parser.value("device").isEmpty() && parser.value("device") != d.serial) {
|
||||||
if(!parser.value("device").isEmpty() && parser.value("device") != d) {
|
|
||||||
// specified device does not match, ignore
|
// specified device does not match, ignore
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto connectAction = ui->menuConnect_to->addAction(d);
|
auto connectAction = ui->menuConnect_to->addAction(d.toString());
|
||||||
connectAction->setCheckable(true);
|
connectAction->setCheckable(true);
|
||||||
connectAction->setActionGroup(deviceActionGroup);
|
connectAction->setActionGroup(deviceActionGroup);
|
||||||
if(device && d == device->getSerial()) {
|
if(device && d.serial == device->getSerial()) {
|
||||||
connectAction->setChecked(true);
|
connectAction->setChecked(true);
|
||||||
}
|
}
|
||||||
connect(connectAction, &QAction::triggered, [this, d]() {
|
connect(connectAction, &QAction::triggered, [this, d]() {
|
||||||
ConnectToDevice(d);
|
ConnectToDevice(d.serial, d.driver);
|
||||||
});
|
});
|
||||||
found = true;
|
found = true;
|
||||||
available++;
|
available++;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
ui->menuConnect_to->setEnabled(found);
|
ui->menuConnect_to->setEnabled(found);
|
||||||
qDebug() << "Updated device list, found" << available;
|
qDebug() << "Updated device list, found" << available;
|
||||||
return available;
|
return available;
|
||||||
@ -1055,12 +1087,16 @@ void AppWindow::ShowUSBLog()
|
|||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
void AppWindow::DeviceStatusUpdated(VirtualDevice::Status status)
|
void AppWindow::DeviceStatusUpdated()
|
||||||
{
|
{
|
||||||
lDeviceInfo.setText(status.statusString);
|
lDeviceInfo.setText(device->getStatus());
|
||||||
lADCOverload.setVisible(status.overload);
|
}
|
||||||
lUnlevel.setVisible(status.unlevel);
|
|
||||||
lUnlock.setVisible(status.unlocked);
|
void AppWindow::DeviceFlagsUpdated()
|
||||||
|
{
|
||||||
|
lADCOverload.setVisible(device->asserted(DeviceDriver::Flag::Overload));
|
||||||
|
lUnlevel.setVisible(device->asserted(DeviceDriver::Flag::Unlevel));
|
||||||
|
lUnlock.setVisible(device->asserted(DeviceDriver::Flag::Unlocked));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppWindow::DeviceInfoUpdated()
|
void AppWindow::DeviceInfoUpdated()
|
||||||
@ -1320,3 +1356,31 @@ void AppWindow::UpdateStatusBar(DeviceStatusBar status)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString AppWindow::DeviceEntry::toString()
|
||||||
|
{
|
||||||
|
return serial + " (" + driver->getDriverName()+")";
|
||||||
|
}
|
||||||
|
|
||||||
|
AppWindow::DeviceEntry AppWindow::DeviceEntry::fromString(QString s, std::vector<DeviceDriver*> drivers)
|
||||||
|
{
|
||||||
|
DeviceEntry e;
|
||||||
|
QStringList parts = s.split(" ");
|
||||||
|
if(parts.size() < 2) {
|
||||||
|
// invalid string
|
||||||
|
e.serial = "";
|
||||||
|
e.driver = nullptr;
|
||||||
|
} else {
|
||||||
|
e.serial = parts[0];
|
||||||
|
e.driver = nullptr;
|
||||||
|
parts[1].chop(1);
|
||||||
|
auto driverName = parts[1].mid(1);
|
||||||
|
for(auto d : drivers) {
|
||||||
|
if(d->getDriverName() == driverName) {
|
||||||
|
e.driver = d;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
@ -58,7 +58,7 @@ public slots:
|
|||||||
protected:
|
protected:
|
||||||
void closeEvent(QCloseEvent *event) override;
|
void closeEvent(QCloseEvent *event) override;
|
||||||
private slots:
|
private slots:
|
||||||
bool ConnectToDevice(QString serial = QString());
|
bool ConnectToDevice(QString serial = QString(), DeviceDriver *driver = nullptr);
|
||||||
void DisconnectDevice();
|
void DisconnectDevice();
|
||||||
int UpdateDeviceList();
|
int UpdateDeviceList();
|
||||||
// void StartManualControl();
|
// void StartManualControl();
|
||||||
@ -67,8 +67,9 @@ private slots:
|
|||||||
// void UpdateAcquisitionFrequencies();
|
// void UpdateAcquisitionFrequencies();
|
||||||
void ShowUSBLog();
|
void ShowUSBLog();
|
||||||
// void StartFirmwareUpdateDialog();
|
// void StartFirmwareUpdateDialog();
|
||||||
void DeviceNeedsUpdate(int reported, int expected);
|
// void DeviceNeedsUpdate(int reported, int expected);
|
||||||
void DeviceStatusUpdated(VirtualDevice::Status status);
|
void DeviceStatusUpdated();
|
||||||
|
void DeviceFlagsUpdated();
|
||||||
void DeviceInfoUpdated();
|
void DeviceInfoUpdated();
|
||||||
// void SourceCalibrationDialog();
|
// void SourceCalibrationDialog();
|
||||||
// void ReceiverCalibrationDialog();
|
// void ReceiverCalibrationDialog();
|
||||||
@ -109,6 +110,20 @@ private:
|
|||||||
std::vector<DeviceDriver*> deviceDrivers;
|
std::vector<DeviceDriver*> deviceDrivers;
|
||||||
DeviceDriver *device;
|
DeviceDriver *device;
|
||||||
|
|
||||||
|
class DeviceEntry {
|
||||||
|
public:
|
||||||
|
QString toString();
|
||||||
|
static DeviceEntry fromString(QString s, std::vector<DeviceDriver*> drivers);
|
||||||
|
bool operator==(const DeviceEntry& rhs) {
|
||||||
|
return serial == rhs.serial && driver == rhs.driver;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString serial;
|
||||||
|
DeviceDriver *driver;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<DeviceEntry> deviceList;
|
||||||
|
|
||||||
DeviceLog deviceLog;
|
DeviceLog deviceLog;
|
||||||
QString deviceSerial;
|
QString deviceSerial;
|
||||||
QActionGroup *deviceActionGroup;
|
QActionGroup *deviceActionGroup;
|
||||||
|
@ -21,7 +21,6 @@ int main(int argc, char *argv[]) {
|
|||||||
qSetMessagePattern("%{time process}: [%{type}] %{message}");
|
qSetMessagePattern("%{time process}: [%{type}] %{message}");
|
||||||
|
|
||||||
Device::RegisterTypes();
|
Device::RegisterTypes();
|
||||||
VirtualDevice::RegisterTypes();
|
|
||||||
|
|
||||||
app = new QApplication(argc, argv);
|
app = new QApplication(argc, argv);
|
||||||
QCoreApplication::setOrganizationName("LibreVNA");
|
QCoreApplication::setOrganizationName("LibreVNA");
|
||||||
|
@ -163,14 +163,14 @@ PreferencesDialog::PreferencesDialog(Preferences *pref, QWidget *parent) :
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Compound device page
|
// Compound device page
|
||||||
connect(ui->compoundList, &QListWidget::currentRowChanged, [=](){
|
// connect(ui->compoundList, &QListWidget::currentRowChanged, [=](){
|
||||||
if(VirtualDevice::getConnected() && VirtualDevice::getConnected()->getCompoundDevice() == p->compoundDevices[ui->compoundList->currentRow()]) {
|
// if(VirtualDevice::getConnected() && VirtualDevice::getConnected()->getCompoundDevice() == p->compoundDevices[ui->compoundList->currentRow()]) {
|
||||||
// can't remove the device we are connected to
|
// // can't remove the device we are connected to
|
||||||
ui->compoundDelete->setEnabled(false);
|
// ui->compoundDelete->setEnabled(false);
|
||||||
} else {
|
// } else {
|
||||||
ui->compoundDelete->setEnabled(true);
|
// ui->compoundDelete->setEnabled(true);
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
connect(ui->compoundList, &QListWidget::doubleClicked, [=](){
|
connect(ui->compoundList, &QListWidget::doubleClicked, [=](){
|
||||||
auto index = ui->compoundList->currentRow();
|
auto index = ui->compoundList->currentRow();
|
||||||
if(index >= 0 && index < (int) p->compoundDevices.size()) {
|
if(index >= 0 && index < (int) p->compoundDevices.size()) {
|
||||||
@ -195,22 +195,22 @@ PreferencesDialog::PreferencesDialog(Preferences *pref, QWidget *parent) :
|
|||||||
});
|
});
|
||||||
d->show();
|
d->show();
|
||||||
});
|
});
|
||||||
connect(ui->compoundDelete, &QPushButton::clicked, [=](){
|
// connect(ui->compoundDelete, &QPushButton::clicked, [=](){
|
||||||
auto index = ui->compoundList->currentRow();
|
// auto index = ui->compoundList->currentRow();
|
||||||
if(index >= 0 && index < (int) p->compoundDevices.size()) {
|
// if(index >= 0 && index < (int) p->compoundDevices.size()) {
|
||||||
// delete the actual compound device
|
// // delete the actual compound device
|
||||||
if(VirtualDevice::getConnected() && VirtualDevice::getConnected()->getCompoundDevice() == p->compoundDevices[index]) {
|
// if(VirtualDevice::getConnected() && VirtualDevice::getConnected()->getCompoundDevice() == p->compoundDevices[index]) {
|
||||||
// can't remove the device we are currently connected to
|
// // can't remove the device we are currently connected to
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
delete p->compoundDevices[index];
|
// delete p->compoundDevices[index];
|
||||||
// delete the line in the GUI list
|
// // delete the line in the GUI list
|
||||||
delete ui->compoundList->takeItem(index);
|
// delete ui->compoundList->takeItem(index);
|
||||||
// remove compound device from list
|
// // remove compound device from list
|
||||||
p->compoundDevices.erase(p->compoundDevices.begin() + index);
|
// p->compoundDevices.erase(p->compoundDevices.begin() + index);
|
||||||
p->nonTrivialWriting();
|
// p->nonTrivialWriting();
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
|
|
||||||
// Debug page
|
// Debug page
|
||||||
ui->DebugMaxUSBlogSize->setUnit("B");
|
ui->DebugMaxUSBlogSize->setUnit("B");
|
||||||
@ -514,24 +514,32 @@ Preferences::~Preferences()
|
|||||||
|
|
||||||
void Preferences::load()
|
void Preferences::load()
|
||||||
{
|
{
|
||||||
QSettings settings;
|
|
||||||
// load settings, using default values if not present
|
// load settings, using default values if not present
|
||||||
qInfo() << "Loading preferences";
|
qInfo() << "Loading preferences";
|
||||||
|
load(descr);
|
||||||
|
nonTrivialParsing();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Preferences::load(std::vector<Savable::SettingDescription> descr)
|
||||||
|
{
|
||||||
|
QSettings settings;
|
||||||
for(auto d : descr) {
|
for(auto d : descr) {
|
||||||
try {
|
try {
|
||||||
d.var.setValue(settings.value(d.name, d.def));
|
d.var.setValue(settings.value(d.name, d.def));
|
||||||
// qDebug() << "Setting" << d.name << "is set to" << d.var.value();
|
|
||||||
} catch (const exception& e){
|
} catch (const exception& e){
|
||||||
d.var.setValue(d.def);
|
d.var.setValue(d.def);
|
||||||
// qDebug() << "Setting" << d.name << "reset to default:" << d.def;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nonTrivialParsing();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Preferences::store()
|
void Preferences::store()
|
||||||
{
|
{
|
||||||
nonTrivialWriting();
|
nonTrivialWriting();
|
||||||
|
store(descr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Preferences::store(std::vector<Savable::SettingDescription> descr)
|
||||||
|
{
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
// store settings
|
// store settings
|
||||||
for(auto d : descr) {
|
for(auto d : descr) {
|
||||||
|
@ -51,7 +51,9 @@ public:
|
|||||||
Preferences(const Preferences&) = delete;
|
Preferences(const Preferences&) = delete;
|
||||||
~Preferences();
|
~Preferences();
|
||||||
void load();
|
void load();
|
||||||
|
void load(std::vector<Savable::SettingDescription> descr);
|
||||||
void store();
|
void store();
|
||||||
|
void store(std::vector<Savable::SettingDescription> descr);
|
||||||
void edit();
|
void edit();
|
||||||
void setDefault();
|
void setDefault();
|
||||||
|
|
||||||
|
@ -32,10 +32,13 @@ SOURCES += \
|
|||||||
../LibreVNA-GUI/Device/compounddevice.cpp \
|
../LibreVNA-GUI/Device/compounddevice.cpp \
|
||||||
../LibreVNA-GUI/Device/compounddeviceeditdialog.cpp \
|
../LibreVNA-GUI/Device/compounddeviceeditdialog.cpp \
|
||||||
../LibreVNA-GUI/Device/device.cpp \
|
../LibreVNA-GUI/Device/device.cpp \
|
||||||
|
../LibreVNA-GUI/Device/devicedriver.cpp \
|
||||||
../LibreVNA-GUI/Device/devicelog.cpp \
|
../LibreVNA-GUI/Device/devicelog.cpp \
|
||||||
../LibreVNA-GUI/Device/deviceusblog.cpp \
|
../LibreVNA-GUI/Device/deviceusblog.cpp \
|
||||||
../LibreVNA-GUI/Device/deviceusblogview.cpp \
|
../LibreVNA-GUI/Device/deviceusblogview.cpp \
|
||||||
../LibreVNA-GUI/Device/firmwareupdatedialog.cpp \
|
../LibreVNA-GUI/Device/firmwareupdatedialog.cpp \
|
||||||
|
../LibreVNA-GUI/Device/librevnadriver.cpp \
|
||||||
|
../LibreVNA-GUI/Device/librevnausbdriver.cpp \
|
||||||
../LibreVNA-GUI/Device/manualcontroldialog.cpp \
|
../LibreVNA-GUI/Device/manualcontroldialog.cpp \
|
||||||
../LibreVNA-GUI/Device/virtualdevice.cpp \
|
../LibreVNA-GUI/Device/virtualdevice.cpp \
|
||||||
../LibreVNA-GUI/Generator/generator.cpp \
|
../LibreVNA-GUI/Generator/generator.cpp \
|
||||||
@ -199,10 +202,13 @@ HEADERS += \
|
|||||||
../LibreVNA-GUI/Device/compounddevice.h \
|
../LibreVNA-GUI/Device/compounddevice.h \
|
||||||
../LibreVNA-GUI/Device/compounddeviceeditdialog.h \
|
../LibreVNA-GUI/Device/compounddeviceeditdialog.h \
|
||||||
../LibreVNA-GUI/Device/device.h \
|
../LibreVNA-GUI/Device/device.h \
|
||||||
|
../LibreVNA-GUI/Device/devicedriver.h \
|
||||||
../LibreVNA-GUI/Device/devicelog.h \
|
../LibreVNA-GUI/Device/devicelog.h \
|
||||||
../LibreVNA-GUI/Device/deviceusblog.h \
|
../LibreVNA-GUI/Device/deviceusblog.h \
|
||||||
../LibreVNA-GUI/Device/deviceusblogview.h \
|
../LibreVNA-GUI/Device/deviceusblogview.h \
|
||||||
../LibreVNA-GUI/Device/firmwareupdatedialog.h \
|
../LibreVNA-GUI/Device/firmwareupdatedialog.h \
|
||||||
|
../LibreVNA-GUI/Device/librevnadriver.h \
|
||||||
|
../LibreVNA-GUI/Device/librevnausbdriver.h \
|
||||||
../LibreVNA-GUI/Device/manualcontroldialog.h \
|
../LibreVNA-GUI/Device/manualcontroldialog.h \
|
||||||
../LibreVNA-GUI/Device/virtualdevice.h \
|
../LibreVNA-GUI/Device/virtualdevice.h \
|
||||||
../LibreVNA-GUI/Generator/generator.h \
|
../LibreVNA-GUI/Generator/generator.h \
|
||||||
|
Loading…
Reference in New Issue
Block a user