mirror of
https://github.com/jankae/LibreVNA.git
synced 2026-04-05 06:25:16 +00:00
Startup and communication bugfixes
- reduce amount of mode switched when starting and loading setups - improve logging for errors during HIL tests - fix small USB communication bugs
This commit is contained in:
parent
733d0ffbf4
commit
ca25969574
14 changed files with 148 additions and 44 deletions
|
|
@ -29,7 +29,7 @@ CompoundDriver::CompoundDriver()
|
|||
p.load(d->driverSpecificSettings());
|
||||
}
|
||||
|
||||
specificSettings.push_back(Savable::SettingDescription(&compoundJSONString, "compoundDriver.compoundDeviceJSON", ""));
|
||||
specificSettings.push_back(Savable::SettingDescription(&compoundJSONString, "compoundDriver.compoundDeviceJSON", "{}"));
|
||||
specificSettings.push_back(Savable::SettingDescription(&captureRawReceiverValues, "compoundDriver.captureRawReceiverValues", false));
|
||||
specificSettings.push_back(Savable::SettingDescription(&preservePhase, "compoundDriver.preservePhase", false));
|
||||
}
|
||||
|
|
@ -488,6 +488,10 @@ void CompoundDriver::parseCompoundJSON()
|
|||
{
|
||||
try {
|
||||
configuredDevices.clear();
|
||||
if(compoundJSONString.isEmpty()) {
|
||||
// empty string will fail JSON parsing. Abort now instead of running into the exception
|
||||
return;
|
||||
}
|
||||
nlohmann::json jc = nlohmann::json::parse(compoundJSONString.toStdString());
|
||||
for(auto j : jc) {
|
||||
auto cd = new CompoundDevice();
|
||||
|
|
|
|||
|
|
@ -251,6 +251,11 @@ LibreVNADriver::LibreVNADriver()
|
|||
}
|
||||
return SCPI::getResultName(SCPI::Result::Empty);
|
||||
}, nullptr));
|
||||
|
||||
specificSCPIcommands.push_back(new SCPICommand("DEVice:PACKETLOG", nullptr, [=](QStringList) -> QString {
|
||||
auto &log = DevicePacketLog::getInstance();
|
||||
return QString::fromStdString(log.toJSON().dump());
|
||||
}));
|
||||
}
|
||||
|
||||
std::set<DeviceDriver::Flag> LibreVNADriver::getFlags()
|
||||
|
|
@ -407,6 +412,7 @@ QStringList LibreVNADriver::availableVNAMeasurements()
|
|||
bool LibreVNADriver::setVNA(const DeviceDriver::VNASettings &s, std::function<void (bool)> cb)
|
||||
{
|
||||
if(!supports(Feature::VNA)) {
|
||||
qDebug() << "VNA does not support features \"VNA\" (has the DeviceInfo been received?)";
|
||||
return false;
|
||||
}
|
||||
if(s.excitedPorts.size() == 0) {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include "devicepacketlog.h"
|
||||
|
||||
#include <QTimer>
|
||||
#include <QThread>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
|
@ -166,9 +167,9 @@ void LibreVNAUSBDriver::ReceivedData()
|
|||
uint16_t handled_len;
|
||||
// qDebug() << "Received data";
|
||||
do {
|
||||
// qDebug() << "Decoding" << dataBuffer->getReceived() << "Bytes";
|
||||
// qDebug() << "Decoding" << dataBuffer->getReceived() << "Bytes";
|
||||
handled_len = Protocol::DecodeBuffer(dataBuffer->getBuffer(), dataBuffer->getReceived(), &packet);
|
||||
// qDebug() << "Handled" << handled_len << "Bytes, type:" << (int) packet.type;
|
||||
// qDebug() << "Handled" << handled_len << "Bytes, type:" << (int) packet.type;
|
||||
if(handled_len > 0) {
|
||||
auto &log = DevicePacketLog::getInstance();
|
||||
if(packet.type != Protocol::PacketType::None) {
|
||||
|
|
@ -185,6 +186,8 @@ void LibreVNAUSBDriver::ReceivedData()
|
|||
case Protocol::PacketType::Nack:
|
||||
emit receivedAnswer(TransmissionResult::Nack);
|
||||
break;
|
||||
case Protocol::PacketType::None:
|
||||
break;
|
||||
default:
|
||||
// pass on to LibreVNADriver class
|
||||
emit receivedPacket(packet);
|
||||
|
|
@ -220,12 +223,12 @@ void LibreVNAUSBDriver::transmissionFinished(LibreVNADriver::TransmissionResult
|
|||
{
|
||||
lock_guard<mutex> lock(transmissionMutex);
|
||||
// remove transmitted packet
|
||||
// qDebug() << "Transmission finsished (" << result << "), queue at " << transmissionQueue.size() << " Outstanding ACKs:"<<outstandingAckCount;
|
||||
if(transmissionQueue.empty()) {
|
||||
qWarning() << "transmissionFinished with empty transmission queue, stray Ack? Result:" << result;
|
||||
return;
|
||||
}
|
||||
auto t = transmissionQueue.dequeue();
|
||||
// qDebug() << "Transmission finsished (packet type" << (int) t.packet.type <<",result" << result << "), queue at " << transmissionQueue.size();
|
||||
if(result == TransmissionResult::Timeout) {
|
||||
qWarning() << "transmissionFinished with timeout, packettype:" << (int) t.packet.type << "Device:" << serial;
|
||||
}
|
||||
|
|
@ -374,6 +377,6 @@ bool LibreVNAUSBDriver::startNextTransmission()
|
|||
return false;
|
||||
}
|
||||
transmissionTimer.start(t.timeout);
|
||||
// qDebug() << "Transmission started, queue at " << transmissionQueue.size();
|
||||
qDebug() << "Transmission started (packet type" << (int) t.packet.type << "), queue at " << transmissionQueue.size();
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -340,10 +340,10 @@ SpectrumAnalyzer::SpectrumAnalyzer(AppWindow *window, QString name)
|
|||
|
||||
void SpectrumAnalyzer::deactivate()
|
||||
{
|
||||
setOperationPending(false);
|
||||
StoreSweepSettings();
|
||||
configurationTimer.stop();
|
||||
Mode::deactivate();
|
||||
setOperationPending(false);
|
||||
}
|
||||
|
||||
void SpectrumAnalyzer::initializeDevice()
|
||||
|
|
@ -588,7 +588,11 @@ void SpectrumAnalyzer::NewDatapoint(DeviceDriver::SAMeasurement m)
|
|||
|
||||
void SpectrumAnalyzer::SettingsChanged()
|
||||
{
|
||||
if(window->getDevice()) {
|
||||
if(!running) {
|
||||
// not running, no need for any communication
|
||||
return;
|
||||
}
|
||||
if(isActive && window->getDevice()) {
|
||||
setOperationPending(true);
|
||||
}
|
||||
configurationTimer.start(100);
|
||||
|
|
@ -695,10 +699,15 @@ void SpectrumAnalyzer::SetSingleSweep(bool single)
|
|||
{
|
||||
if(singleSweep != single) {
|
||||
singleSweep = single;
|
||||
if(single) {
|
||||
Run();
|
||||
}
|
||||
emit singleSweepChanged(single);
|
||||
}
|
||||
if(single) {
|
||||
Run();
|
||||
} else {
|
||||
// if already set to single, a second single command triggers a new sweep
|
||||
if(single && !running) {
|
||||
Run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -734,7 +743,9 @@ void SpectrumAnalyzer::SetAveraging(unsigned int averages)
|
|||
average.setAverages(averages);
|
||||
emit averagingChanged(averages);
|
||||
UpdateAverageCount();
|
||||
setOperationPending(!average.settled());
|
||||
if(isActive && window->getDevice()) {
|
||||
setOperationPending(!average.settled());
|
||||
}
|
||||
}
|
||||
|
||||
void SpectrumAnalyzer::SetTGEnabled(bool enabled)
|
||||
|
|
@ -871,6 +882,7 @@ void SpectrumAnalyzer::Stop()
|
|||
{
|
||||
running = false;
|
||||
ConfigureDevice();
|
||||
setOperationPending(false);
|
||||
}
|
||||
|
||||
void SpectrumAnalyzer::ConfigureDevice()
|
||||
|
|
@ -920,9 +932,6 @@ void SpectrumAnalyzer::ConfigureDevice()
|
|||
|
||||
void SpectrumAnalyzer::ResetLiveTraces()
|
||||
{
|
||||
if(window->getDevice()) {
|
||||
setOperationPending(true);
|
||||
}
|
||||
average.reset(DeviceDriver::SApoints());
|
||||
traceModel.clearLiveData();
|
||||
UpdateAverageCount();
|
||||
|
|
|
|||
|
|
@ -745,10 +745,10 @@ QString VNA::getCalToolTip()
|
|||
|
||||
void VNA::deactivate()
|
||||
{
|
||||
setOperationPending(false);
|
||||
StoreSweepSettings();
|
||||
configurationTimer.stop();
|
||||
Mode::deactivate();
|
||||
setOperationPending(false);
|
||||
}
|
||||
|
||||
static void SetComboBoxItemEnabled(QComboBox * comboBox, int index, bool enabled)
|
||||
|
|
@ -939,9 +939,8 @@ void VNA::NewDatapoint(DeviceDriver::VNAMeasurement m)
|
|||
}
|
||||
|
||||
// Calculate sweep time
|
||||
if(m.pointNum == 0) {
|
||||
if(m.pointNum == 0 && lastPoint > 0) {
|
||||
// new sweep started
|
||||
static auto lastStart = QDateTime::currentDateTimeUtc();
|
||||
auto now = QDateTime::currentDateTimeUtc();
|
||||
auto sweepTime = lastStart.msecsTo(now);
|
||||
lastStart = now;
|
||||
|
|
@ -1042,7 +1041,6 @@ void VNA::NewDatapoint(DeviceDriver::VNAMeasurement m)
|
|||
markerModel->updateMarkers();
|
||||
}
|
||||
|
||||
static unsigned int lastPoint = 0;
|
||||
if(m_avg.pointNum > 0 && m_avg.pointNum != lastPoint + 1) {
|
||||
qWarning() << "Got point" << m_avg.pointNum << "but last received point was" << lastPoint << "("<<(m_avg.pointNum-lastPoint-1)<<"missed points)";
|
||||
}
|
||||
|
|
@ -1065,7 +1063,11 @@ void VNA::UpdateAverageCount()
|
|||
|
||||
void VNA::SettingsChanged(bool resetTraces, int delay)
|
||||
{
|
||||
if(window->getDevice()) {
|
||||
if(!running) {
|
||||
// not running, no need for any communication
|
||||
return;
|
||||
}
|
||||
if(isActive && window->getDevice()) {
|
||||
setOperationPending(true);
|
||||
}
|
||||
configurationTimer.start(delay);
|
||||
|
|
@ -1317,7 +1319,9 @@ void VNA::SetAveraging(unsigned int averages)
|
|||
average.setAverages(averages);
|
||||
emit averagingChanged(averages);
|
||||
UpdateAverageCount();
|
||||
setOperationPending(!average.settled());
|
||||
if(isActive && window->getDevice()) {
|
||||
setOperationPending(!average.settled());
|
||||
}
|
||||
}
|
||||
|
||||
void VNA::ExcitationRequired()
|
||||
|
|
@ -1880,10 +1884,15 @@ void VNA::SetSingleSweep(bool single)
|
|||
{
|
||||
if(singleSweep != single) {
|
||||
singleSweep = single;
|
||||
if(single) {
|
||||
Run();
|
||||
}
|
||||
emit singleSweepChanged(single);
|
||||
}
|
||||
if(single) {
|
||||
Run();
|
||||
} else {
|
||||
// if already set to single, a second single command triggers a new sweep
|
||||
if(single && !running) {
|
||||
Run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1897,6 +1906,7 @@ void VNA::Stop()
|
|||
{
|
||||
running = false;
|
||||
ConfigureDevice(false);
|
||||
setOperationPending(false);
|
||||
}
|
||||
|
||||
void VNA::ConfigureDevice(bool resetTraces, std::function<void(bool)> cb)
|
||||
|
|
@ -1976,6 +1986,8 @@ void VNA::ConfigureDevice(bool resetTraces, std::function<void(bool)> cb)
|
|||
cb(res);
|
||||
}
|
||||
changingSettings = false;
|
||||
lastStart = QDateTime::currentDateTimeUtc();
|
||||
lastPoint = -1;
|
||||
});
|
||||
emit sweepStarted();
|
||||
} else {
|
||||
|
|
@ -2004,7 +2016,7 @@ void VNA::ResetLiveTraces()
|
|||
traceModel.clearLiveData();
|
||||
UpdateAverageCount();
|
||||
UpdateCalWidget();
|
||||
if(window->getDevice()) {
|
||||
if(isActive && window->getDevice()) {
|
||||
setOperationPending(true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -198,6 +198,10 @@ private:
|
|||
QList<QAction*> importActions;
|
||||
QList<QAction*> exportActions;
|
||||
|
||||
// Statistics for detecting missing points and sweep time
|
||||
QDateTime lastStart;
|
||||
int lastPoint;
|
||||
|
||||
signals:
|
||||
void deviceInitialized();
|
||||
void dataChanged();
|
||||
|
|
|
|||
|
|
@ -31,10 +31,6 @@ int ModeHandler::addMode(Mode *mode)
|
|||
modes.push_back(mode);
|
||||
currentModeIndex = int(modes.size()) - 1;
|
||||
connect(mode, &Mode::statusbarMessage, this, &ModeHandler::setStatusBarMessageChanged);
|
||||
|
||||
auto m = getMode(currentModeIndex);
|
||||
activate(m);
|
||||
|
||||
emit ModeCreated(currentModeIndex);
|
||||
return (currentModeIndex);
|
||||
}
|
||||
|
|
@ -166,7 +162,12 @@ void ModeHandler::closeMode(int index)
|
|||
void ModeHandler::closeModes()
|
||||
{
|
||||
while(modes.size() > 0) {
|
||||
closeMode(0);
|
||||
// skip active mode unless it is the last remaining mode
|
||||
if(activeMode == modes[0] && modes.size() > 1) {
|
||||
closeMode(1);
|
||||
} else {
|
||||
closeMode(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -70,7 +70,8 @@ void ModeWindow::SetupUi()
|
|||
InformationBox::ShowError("Name collision", "Unable to create tab, " \
|
||||
"no duplicate names allowed");
|
||||
} else {
|
||||
handler->createMode(text, type);
|
||||
auto index = handler->createMode(text, type);
|
||||
handler->setCurrentIndex(index);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -157,7 +158,6 @@ void ModeWindow::ModeCreated(int modeIndex)
|
|||
tabBar->insertTab(modeIndex, name);
|
||||
tabBar->blockSignals(false);
|
||||
tabBar->setMovable(true);
|
||||
tabBar->setCurrentIndex(modeIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -369,8 +369,13 @@ void SCPINode::setOperationPending(bool pending)
|
|||
while(root->parent) {
|
||||
root = root->parent;
|
||||
}
|
||||
auto scpi = static_cast<SCPI*>(root);
|
||||
scpi->someOperationCompleted();
|
||||
auto scpi = dynamic_cast<SCPI*>(root);
|
||||
if(!scpi) {
|
||||
// dynamic cast failed, this is not actually a root node. The SCPI node likely
|
||||
// has no valid parent configured
|
||||
} else {
|
||||
scpi->someOperationCompleted();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue