diff --git a/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/Compound/compounddriver.cpp b/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/Compound/compounddriver.cpp index 8311035..bd5239e 100644 --- a/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/Compound/compounddriver.cpp +++ b/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/Compound/compounddriver.cpp @@ -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::functionstage mapping portStageMapping.clear(); for(unsigned int i=0;isetSG(devSettings); } + + lastNonIdleSettings.type = lastNonIdleSettings.Types::SG; + lastNonIdleSettings.sg = s; + isIdle = false; + return success; } bool CompoundDriver::setIdle(std::function 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 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 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;igetSerial() << "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;isendWithoutPayload(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;isendWithoutPayload(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)) { diff --git a/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/Compound/compounddriver.h b/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/Compound/compounddriver.h index f21498f..2520d0f 100644 --- a/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/Compound/compounddriver.h +++ b/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/Compound/compounddriver.h @@ -4,6 +4,8 @@ #include "../../devicedriver.h" #include "compounddevice.h" +#include + class CompoundDriver : public DeviceDriver { public: @@ -169,6 +171,8 @@ public: static std::set 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 deviceInfos; @@ -196,8 +202,17 @@ private: // Configuration of the device we are connected to CompoundDevice activeDevice; bool connected; + bool triggerForwarding; + QMutex triggerMutex; std::vector 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; diff --git a/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/librevnadriver.h b/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/librevnadriver.h index 36340c9..03f5476 100644 --- a/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/librevnadriver.h +++ b/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/librevnadriver.h @@ -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: diff --git a/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/librevnatcpdriver.cpp b/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/librevnatcpdriver.cpp index a7e88a5..cde3ae6 100644 --- a/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/librevnatcpdriver.cpp +++ b/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/librevnatcpdriver.cpp @@ -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); diff --git a/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/librevnausbdriver.cpp b/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/librevnausbdriver.cpp index a0e4e66..c9d03df 100644 --- a/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/librevnausbdriver.cpp +++ b/Software/PC_Application/LibreVNA-GUI/Device/LibreVNA/librevnausbdriver.cpp @@ -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: diff --git a/Software/PC_Application/LibreVNA-GUI/appwindow.cpp b/Software/PC_Application/LibreVNA-GUI/appwindow.cpp index 1e4399d..57e6afa 100644 --- a/Software/PC_Application/LibreVNA-GUI/appwindow.cpp +++ b/Software/PC_Application/LibreVNA-GUI/appwindow.cpp @@ -507,10 +507,13 @@ void AppWindow::CreateToolbars() tb_reference->addWidget(new QLabel("Ref out:")); toolbars.reference.outFreq = new QComboBox(); tb_reference->addWidget(toolbars.reference.outFreq); - connect(toolbars.reference.type, qOverload(&QComboBox::currentIndexChanged), this, &AppWindow::UpdateReference); - connect(toolbars.reference.outFreq, qOverload(&QComboBox::currentIndexChanged), this, &AppWindow::UpdateReference); + connect(toolbars.reference.type, qOverload(&QComboBox::currentIndexChanged), this, &AppWindow::ReferenceChanged); + connect(toolbars.reference.outFreq, qOverload(&QComboBox::currentIndexChanged), this, &AppWindow::ReferenceChanged); addToolBar(tb_reference); tb_reference->setObjectName("Reference Toolbar"); + + referenceTimer.setSingleShot(true); + connect(&referenceTimer, &QTimer::timeout, this, &AppWindow::UpdateReference); } void AppWindow::SetupSCPI() @@ -952,7 +955,7 @@ void AppWindow::ResetReference() toolbars.reference.outFreq->setCurrentIndex(0); toolbars.reference.type->blockSignals(false); toolbars.reference.outFreq->blockSignals(false); - UpdateReference(); + ReferenceChanged(); } //void AppWindow::StartManualControl() @@ -1008,7 +1011,16 @@ void AppWindow::UpdateReferenceToolbar() } toolbars.reference.type->blockSignals(false); toolbars.reference.outFreq->blockSignals(false); - UpdateReference(); + ReferenceChanged(); +} + +void AppWindow::ReferenceChanged() +{ + if(!device) { + // can't update without a device connected + return; + } + referenceTimer.start(100); } void AppWindow::UpdateReference() diff --git a/Software/PC_Application/LibreVNA-GUI/appwindow.h b/Software/PC_Application/LibreVNA-GUI/appwindow.h index 4a0469b..2d36579 100644 --- a/Software/PC_Application/LibreVNA-GUI/appwindow.h +++ b/Software/PC_Application/LibreVNA-GUI/appwindow.h @@ -82,6 +82,7 @@ private slots: // void StartManualControl(); void ResetReference(); void UpdateReferenceToolbar(); + void ReferenceChanged(); void UpdateReference(); void DeviceStatusUpdated(); void DeviceFlagsUpdated(); @@ -144,6 +145,9 @@ private: QString deviceSerial; QActionGroup *deviceActionGroup; + // Reference change timer + QTimer referenceTimer; + // Status bar widgets QLabel lConnectionStatus; QLabel lDeviceInfo; diff --git a/Software/VNA_embedded/.settings/stm32cubeide.project.prefs b/Software/VNA_embedded/.settings/stm32cubeide.project.prefs index 65c8f86..049399e 100644 --- a/Software/VNA_embedded/.settings/stm32cubeide.project.prefs +++ b/Software/VNA_embedded/.settings/stm32cubeide.project.prefs @@ -1,5 +1,5 @@ -2F62501ED4689FB349E356AB974DBE57=EF826FD321FB312AEADE4DB74B81458C +2F62501ED4689FB349E356AB974DBE57=6F84FD31C089E822CF61FFCABCD0B7D1 66BE74F758C12D739921AEA421D593D3=2 -8DF89ED150041C4CBC7CB9A9CAA90856=EF826FD321FB312AEADE4DB74B81458C +8DF89ED150041C4CBC7CB9A9CAA90856=6F84FD31C089E822CF61FFCABCD0B7D1 DC22A860405A8BF2F2C095E5B6529F12=BF78DB58F29884459C61AFB6BB93F7B6 eclipse.preferences.version=1 diff --git a/Software/VNA_embedded/Application/VNA.cpp b/Software/VNA_embedded/Application/VNA.cpp index c270852..01a05cc 100644 --- a/Software/VNA_embedded/Application/VNA.cpp +++ b/Software/VNA_embedded/Application/VNA.cpp @@ -146,6 +146,7 @@ bool VNA::Setup(Protocol::SweepSettings s) { vTaskDelay(5); data.clear(); HW::SetMode(HW::Mode::VNA); + Trigger::SetInput(false); sourceRefIndex = 0; LO1RefIndex = 0;