improve GUI synchronization for compound device

This commit is contained in:
Jan Käberich 2025-05-04 13:01:00 +02:00
parent b3b3fa7718
commit 199bb7bbd7
9 changed files with 161 additions and 38 deletions

View file

@ -13,6 +13,8 @@
CompoundDriver::CompoundDriver()
{
connected = false;
isIdle = true;
triggerForwarding = false;
SApoints = 0;
drivers.push_back(new LibreVNAUSBDriver);
@ -296,6 +298,11 @@ bool CompoundDriver::setVNA(const DeviceDriver::VNASettings &s, std::function<vo
return setIdle(cb);
}
setIdle([this](bool){
enableTriggerForwarding();
qDebug() << "Start trigger forwarding";
});
// create port->stage mapping
portStageMapping.clear();
for(unsigned int i=0;i<s.excitedPorts.size();i++) {
@ -334,6 +341,11 @@ bool CompoundDriver::setVNA(const DeviceDriver::VNASettings &s, std::function<vo
}
});
}
lastNonIdleSettings.type = lastNonIdleSettings.Types::VNA;
lastNonIdleSettings.vna = s;
isIdle = false;
return success;
}
@ -353,6 +365,11 @@ bool CompoundDriver::setSA(const DeviceDriver::SASettings &s, std::function<void
}
zerospan = s.freqStart == s.freqStop;
setIdle([this](bool){
enableTriggerForwarding();
qDebug() << "Start trigger forwarding";
});
// Configure the devices
results.clear();
bool success = true;
@ -385,6 +402,11 @@ bool CompoundDriver::setSA(const DeviceDriver::SASettings &s, std::function<void
break;
}
}
lastNonIdleSettings.type = lastNonIdleSettings.Types::SA;
lastNonIdleSettings.sa = s;
isIdle = false;
return success;
}
@ -415,14 +437,22 @@ bool CompoundDriver::setSG(const DeviceDriver::SGSettings &s)
}
success &= devices[i]->setSG(devSettings);
}
lastNonIdleSettings.type = lastNonIdleSettings.Types::SG;
lastNonIdleSettings.sg = s;
isIdle = false;
return success;
}
bool CompoundDriver::setIdle(std::function<void (bool)> cb)
{
disableTriggerForwarding();
qDebug() << "Stop trigger forwarding";
auto success = true;
results.clear();
for(auto dev : devices) {
dev->sendWithoutPayload(Protocol::PacketType::ClearTrigger);
success &= dev->setIdle([=](bool success){
if(cb) {
results[dev] = success;
@ -430,6 +460,9 @@ bool CompoundDriver::setIdle(std::function<void (bool)> cb)
}
});
}
isIdle = true;
return success;
}
@ -464,9 +497,36 @@ QStringList CompoundDriver::availableExtRefOutSettings()
bool CompoundDriver::setExtRef(QString option_in, QString option_out)
{
auto success = true;
for(auto dev : devices) {
success &= dev->setExtRef(option_in, option_out);
qDebug() << "Ref change start";
if(isIdle) {
// can immediately switch reference settings
for(auto dev : devices) {
success &= dev->setExtRef(option_in, option_out);
}
} else {
// can not switch during a sweep
// set to idle first
setIdle();
// change reference
for(auto dev : devices) {
success &= dev->setExtRef(option_in, option_out);
}
// restore last non idle state
switch(lastNonIdleSettings.type) {
case lastNonIdleSettings.Types::VNA:
setVNA(lastNonIdleSettings.vna);
break;
case lastNonIdleSettings.Types::SA:
setSA(lastNonIdleSettings.sa);
break;
case lastNonIdleSettings.Types::SG:
setSG(lastNonIdleSettings.sg);
break;
}
}
qDebug() << "Ref change stop";
return success;
}
@ -485,6 +545,27 @@ std::set<QString> CompoundDriver::getIndividualDeviceSerials()
return ret;
}
void CompoundDriver::triggerReceived(LibreVNADriver *device, bool set)
{
triggerMutex.lock();
if(activeDevice.sync == LibreVNADriver::Synchronization::GUI && triggerForwarding) {
for(unsigned int i=0;i<devices.size();i++) {
if(devices[i] == device) {
// pass on to the next device
if(i < devices.size() - 1) {
qDebug() << "Passing on trigger" << set << "from" << device->getSerial() << "to" << devices[i+1]->getSerial();
devices[i+1]->sendWithoutPayload(set ? Protocol::PacketType::SetTrigger : Protocol::PacketType::ClearTrigger);
} else {
qDebug() << "Passing on trigger" << set << "from" << device->getSerial() << "to" << devices[0]->getSerial();
devices[0]->sendWithoutPayload(set ? Protocol::PacketType::SetTrigger : Protocol::PacketType::ClearTrigger);
}
break;
}
}
}
triggerMutex.unlock();
}
void CompoundDriver::parseCompoundJSON()
{
try {
@ -529,36 +610,6 @@ void CompoundDriver::incomingPacket(LibreVNADriver *device, const Protocol::Pack
case Protocol::PacketType::SpectrumAnalyzerResult:
spectrumResultReceived(device, p.spectrumResult);
break;
case Protocol::PacketType::SetTrigger:
if(activeDevice.sync == LibreVNADriver::Synchronization::GUI) {
for(unsigned int i=0;i<devices.size();i++) {
if(devices[i] == device) {
// pass on to the next device
if(i < devices.size() - 1) {
devices[i+1]->sendWithoutPayload(Protocol::PacketType::SetTrigger);
} else {
devices[0]->sendWithoutPayload(Protocol::PacketType::SetTrigger);
}
break;
}
}
}
break;
case Protocol::PacketType::ClearTrigger:
if(activeDevice.sync == LibreVNADriver::Synchronization::GUI) {
for(unsigned int i=0;i<devices.size();i++) {
if(devices[i] == device) {
// pass on to the next device
if(i < devices.size() - 1) {
devices[i+1]->sendWithoutPayload(Protocol::PacketType::ClearTrigger);
} else {
devices[0]->sendWithoutPayload(Protocol::PacketType::ClearTrigger);
}
break;
}
}
}
break;
default:
// nothing to do for other packet types
break;
@ -652,6 +703,26 @@ void CompoundDriver::spectrumResultReceived(LibreVNADriver *dev, Protocol::Spect
}
}
void CompoundDriver::enableTriggerForwarding()
{
triggerMutex.lock();
for(auto d : devices) {
connect(d, &LibreVNADriver::receivedTrigger, this, &CompoundDriver::triggerReceived, Qt::UniqueConnection);
}
triggerForwarding = true;
triggerMutex.unlock();
}
void CompoundDriver::disableTriggerForwarding()
{
triggerMutex.lock();
triggerForwarding = false;
for(auto d : devices) {
QObject::disconnect(d, &LibreVNADriver::receivedTrigger, this, &CompoundDriver::triggerReceived);
}
triggerMutex.unlock();
}
void CompoundDriver::datapointReceivecd(LibreVNADriver *dev, Protocol::VNADatapoint<32> *data)
{
if(!compoundVNABuffer.count(data->pointNum)) {

View file

@ -4,6 +4,8 @@
#include "../../devicedriver.h"
#include "compounddevice.h"
#include <QMutex>
class CompoundDriver : public DeviceDriver
{
public:
@ -169,6 +171,8 @@ public:
static std::set<QString> getIndividualDeviceSerials();
private slots:
void triggerReceived(LibreVNADriver *device, bool set);
private:
void parseCompoundJSON();
void createCompoundJSON();
@ -177,6 +181,8 @@ private:
void updatedStatus(LibreVNADriver *device, const Protocol::DeviceStatus &status);
void datapointReceivecd(LibreVNADriver *dev, Protocol::VNADatapoint<32> *data);
void spectrumResultReceived(LibreVNADriver *dev, Protocol::SpectrumAnalyzerResult res);
void enableTriggerForwarding();
void disableTriggerForwarding();
Info info;
std::map<LibreVNADriver*, Info> deviceInfos;
@ -196,8 +202,17 @@ private:
// Configuration of the device we are connected to
CompoundDevice activeDevice;
bool connected;
bool triggerForwarding;
QMutex triggerMutex;
std::vector<LibreVNADriver*> devices;
bool zerospan;
bool isIdle;
struct {
VNASettings vna;
SASettings sa;
SGSettings sg;
enum class Types{VNA, SA, SG} type;
} lastNonIdleSettings;
unsigned int VNApoints;
unsigned int SApoints;

View file

@ -191,6 +191,8 @@ signals:
void receivedAnswer(const LibreVNADriver::TransmissionResult &result);
void receivedPacket(const Protocol::PacketInfo& packet);
void receivedTrigger(LibreVNADriver *driver, bool set);
protected slots:
void handleReceivedPacket(const Protocol::PacketInfo& packet);
protected:

View file

@ -242,6 +242,12 @@ void LibreVNATCPDriver::ReceivedData()
case Protocol::PacketType::Nack:
emit receivedAnswer(TransmissionResult::Nack);
break;
case Protocol::PacketType::SetTrigger:
emit receivedTrigger(this, true);
break;
case Protocol::PacketType::ClearTrigger:
emit receivedTrigger(this, false);
break;
default:
// pass on to LibreVNADriver class
emit receivedPacket(packet);

View file

@ -179,6 +179,12 @@ void LibreVNAUSBDriver::ReceivedData()
}
}
dataBuffer->removeBytes(handled_len);
if(packet.type == Protocol::PacketType::SetTrigger) {
qDebug() << "Incoming set trigger from " << serial;
}
if(packet.type == Protocol::PacketType::ClearTrigger) {
qDebug() << "Incoming clear trigger from " << serial;
}
switch(packet.type) {
case Protocol::PacketType::Ack:
emit receivedAnswer(TransmissionResult::Ack);
@ -186,6 +192,12 @@ void LibreVNAUSBDriver::ReceivedData()
case Protocol::PacketType::Nack:
emit receivedAnswer(TransmissionResult::Nack);
break;
case Protocol::PacketType::SetTrigger:
emit receivedTrigger(this, true);
break;
case Protocol::PacketType::ClearTrigger:
emit receivedTrigger(this, false);
break;
case Protocol::PacketType::None:
break;
default: