From ad73a3e9d28df3eeeb6d5176ffa13c044e9118ba Mon Sep 17 00:00:00 2001 From: Elliott Liggett Date: Tue, 8 Jun 2021 09:58:30 -0700 Subject: [PATCH 01/10] Adjustable waterfall length is now non-destructive. --- wfmain.cpp | 18 +++++++++++------- wfmain.h | 1 + 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/wfmain.cpp b/wfmain.cpp index a20bf11..df8ab9a 100644 --- a/wfmain.cpp +++ b/wfmain.cpp @@ -1494,6 +1494,8 @@ void wfmain::prepareWf(unsigned int wfLength) spectrumDrawLock = true; spectWidth = rigCaps.spectLenMax; + wfLengthMax = 1024; + this->wfLength = wfLength; // fixed for now, time-length of waterfall // Initialize before use! @@ -1501,17 +1503,21 @@ void wfmain::prepareWf(unsigned int wfLength) QByteArray empty((int)spectWidth, '\x01'); spectrumPeaks = QByteArray( (int)spectWidth, '\x01' ); - if((unsigned int)wfimage.size() < wfLength) + //wfimage.resize(wfLengthMax); + + if((unsigned int)wfimage.size() < wfLengthMax) { unsigned int i=0; unsigned int oldSize = wfimage.size(); - for(i=oldSize; i<(wfLength); i++) + for(i=oldSize; i<(wfLengthMax); i++) { wfimage.append(empty); } } else { - wfimage.remove(wfLength, wfimage.size()-wfLength); + // Keep wfimage, do not trim, no performance impact. + //wfimage.remove(wfLength, wfimage.size()-wfLength); } + wfimage.squeeze(); //colorMap->clearData(); colorMap->data()->clear(); @@ -2675,10 +2681,8 @@ void wfmain::receiveSpectrumData(QByteArray spectrum, double startFreq, double e if(specLen == spectWidth) { wfimage.prepend(spectrum); - if(wfimage.length() > wfLength) - { - wfimage.remove(wfLength); - } + wfimage.resize(wfLengthMax); + wfimage.squeeze(); // Waterfall: for(int row = 0; row < wfLength; row++) diff --git a/wfmain.h b/wfmain.h index a5a1db8..9439ba7 100644 --- a/wfmain.h +++ b/wfmain.h @@ -557,6 +557,7 @@ private: int smeterPos=0; QVector wfimage; + unsigned int wfLengthMax; bool onFullscreen; bool drawPeaks; From 9664238917c3bb64a2f4de43fa1bc141b42dce4b Mon Sep 17 00:00:00 2001 From: Elliott Liggett Date: Tue, 8 Jun 2021 14:42:19 -0700 Subject: [PATCH 02/10] Preliminary IC-718 support. Very basic. --- rigcommander.cpp | 19 +++++++++++++++++++ rigidentities.h | 1 + 2 files changed, 20 insertions(+) diff --git a/rigcommander.cpp b/rigcommander.cpp index c201393..2fd19c9 100644 --- a/rigcommander.cpp +++ b/rigcommander.cpp @@ -2947,6 +2947,25 @@ void rigCommander::determineRigCaps() rigCaps.modes = commonModes; rigCaps.modes.insert(rigCaps.modes.end(), createMode(modeWFM, 0x06, "WFM")); break; + case model718: + rigCaps.modelName = QString("IC-718"); + rigCaps.hasSpectrum = false; + rigCaps.inputs.clear(); + rigCaps.hasLan = false; + rigCaps.hasEthernet = false; + rigCaps.hasWiFi = false; + rigCaps.hasATU = false; + rigCaps.attenuators.push_back('\x20'); + rigCaps.preamps.push_back('\x01'); + rigCaps.bands = {band10m, band10m, band12m, + band15m, band17m, band20m, band30m, + band40m, band60m, band80m, band160m, bandGen}; + rigCaps.modes = { createMode(modeLSB, 0x00, "LSB"), createMode(modeUSB, 0x01, "USB"), + createMode(modeAM, 0x02, "AM"), + createMode(modeCW, 0x03, "CW"), createMode(modeCW_R, 0x07, "CW-R"), + createMode(modeRTTY, 0x04, "RTTY"), createMode(modeRTTY_R, 0x08, "RTTY-R") + }; + break; case model756pro: rigCaps.modelName = QString("IC-756 Pro"); rigCaps.hasSpectrum = false; diff --git a/rigidentities.h b/rigidentities.h index 9ad2630..5869136 100644 --- a/rigidentities.h +++ b/rigidentities.h @@ -28,6 +28,7 @@ enum model_kind { model9700 = 0xA2, model705 = 0xA4, model706 = 0x58, + model718 = 0x5E, model756pro = 0x5C, model756proii = 0x64, model756proiii = 0x6E, From 297478ffca9f2847968985d9636a332c404664bb Mon Sep 17 00:00:00 2001 From: Elliott Liggett Date: Mon, 14 Jun 2021 20:22:15 -0700 Subject: [PATCH 03/10] We now calculate polling rates immediately upon receiveCommReady for serial connections. For network connections, we assume sane values and modify once we receive the baud rate from the server. --- rigidentities.cpp | 3 +++ wfmain.cpp | 19 +++++++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/rigidentities.cpp b/rigidentities.cpp index 15f62ac..c2322fd 100644 --- a/rigidentities.cpp +++ b/rigidentities.cpp @@ -52,6 +52,9 @@ model_kind determineRadioModel(unsigned char rigID) case model705: rig = model705; break; + case model718: + rig = model718; + break; case model756proiii: rig = model756proiii; break; diff --git a/wfmain.cpp b/wfmain.cpp index 1a3ccb1..f8fec6e 100644 --- a/wfmain.cpp +++ b/wfmain.cpp @@ -160,6 +160,7 @@ void wfmain::openRig() if (prefs.enableLAN) { ui->lanEnableBtn->setChecked(true); + usingLAN = true; // We need to setup the tx/rx audio: emit sendCommSetup(prefs.radioCIVAddr, udpPrefs, rxSetup, txSetup, prefs.virtualSerialPort); } else { @@ -176,10 +177,7 @@ void wfmain::openRig() serialPortRig = serialPortCL; } } - - // Here, the radioCIVAddr is being set from a default preference, which is for the 7300. - // However, we will not use it initially. OTOH, if it is set explicitedly to a value in the prefs, - // then we skip auto detection. + usingLAN = false; emit sendCommSetup(prefs.radioCIVAddr, serialPortRig, prefs.serialPortBaud,prefs.virtualSerialPort); } @@ -455,7 +453,13 @@ void wfmain::findSerialPort() void wfmain::receiveCommReady() { qInfo(logSystem()) << "Received CommReady!! "; - // taken from above: + if(!usingLAN) + { + // usingLAN gets set when we emit the sendCommSetup signal. + // If we're not using the LAN, then we're on serial, and + // we already know the baud rate and can calculate the timing parameters. + calculateTimingParameters(); + } if(prefs.radioCIVAddr == 0) { // tell rigCommander to broadcast a request for all rig IDs. @@ -484,7 +488,6 @@ void wfmain::receiveFoundRigID(rigCapabilities rigCaps) if(rig->usingLAN()) { usingLAN = true; - //delayedCommand->setInterval(delayedCmdIntervalLAN_ms); } else { usingLAN = false; } @@ -724,7 +727,7 @@ void wfmain::getSettingsFilePath(QString settingsFile) void wfmain::setInitialTiming() { - delayedCmdIntervalLAN_ms = 10; // interval for regular delayed commands, including initial rig/UI state queries + delayedCmdIntervalLAN_ms = 70; // interval for regular delayed commands, including initial rig/UI state queries delayedCmdIntervalSerial_ms = 100; // interval for regular delayed commands, including initial rig/UI state queries delayedCmdStartupInterval_ms = 250; // interval for rigID polling delayedCommand = new QTimer(this); @@ -4609,6 +4612,6 @@ void wfmain::on_wfLengthSlider_valueChanged(int value) void wfmain::on_debugBtn_clicked() { qInfo(logSystem()) << "Debug button pressed."; - prepareWf(160); + emit getTxPower(); } From 43d281cda71b9b608281f708c1340a106d7aa53d Mon Sep 17 00:00:00 2001 From: Elliott Liggett Date: Mon, 14 Jun 2021 20:36:13 -0700 Subject: [PATCH 04/10] Added collision detection for serial commands. Collisions are aparently frequent for true 1-wire CI-V radios. --- commhandler.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/commhandler.cpp b/commhandler.cpp index 5f83e14..735d0a4 100644 --- a/commhandler.cpp +++ b/commhandler.cpp @@ -117,6 +117,12 @@ void commHandler::receiveDataIn() return; } } + if(inPortData.contains("\xFC")) + { + //qInfo(logSerial()) << "Transaction contains collision data. Dumping."; + port->commitTransaction(); + return; + } if(inPortData.startsWith("\xFE\xFE")) { From 815591f07d4d9055c61065416e8f187160be0318 Mon Sep 17 00:00:00 2001 From: Elliott Liggett Date: Mon, 14 Jun 2021 20:55:28 -0700 Subject: [PATCH 05/10] Changed collision detection code so that we can more easily see what message was missed. --- commhandler.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/commhandler.cpp b/commhandler.cpp index 735d0a4..7a48d87 100644 --- a/commhandler.cpp +++ b/commhandler.cpp @@ -117,15 +117,17 @@ void commHandler::receiveDataIn() return; } } - if(inPortData.contains("\xFC")) - { - //qInfo(logSerial()) << "Transaction contains collision data. Dumping."; - port->commitTransaction(); - return; - } + if(inPortData.startsWith("\xFE\xFE")) { + if(inPortData.contains("\xFC")) + { + //qInfo(logSerial()) << "Transaction contains collision data. Dumping."; + //printHex(inPortData, false, true); + port->commitTransaction(); + return; + } if(inPortData.endsWith("\xFD")) { // good! From 2392bdd932a1faf8681bdc0fdad69fb217eb373b Mon Sep 17 00:00:00 2001 From: Elliott Liggett Date: Tue, 15 Jun 2021 10:28:20 -0700 Subject: [PATCH 06/10] Additional data corruption checking. --- rigcommander.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/rigcommander.cpp b/rigcommander.cpp index 2fd19c9..18558b3 100644 --- a/rigcommander.cpp +++ b/rigcommander.cpp @@ -1090,6 +1090,12 @@ void rigCommander::parseData(QByteArray dataInput) // payload = getpayload(data); // or something // parse (payload); // recursive ok? payloadIn = data.right(data.length() - 4); + if(payloadIn.contains("\xFE")) + { + //qDebug(logRig()) << "Corrupted data contains FE within message body: "; + //printHex(payloadIn); + break; + } parseCommand(); break; case '\x00': @@ -1100,9 +1106,15 @@ void rigCommander::parseData(QByteArray dataInput) // This is an echo of our own broadcast request. // The data are "to 00" and "from E1" // Don't use it! - qDebug(logRig()) << "Caught it! Found the echo'd broadcast request from us!"; + qDebug(logRig()) << "Caught it! Found the echo'd broadcast request from us! Rig has not responded to broadcast query yet."; } else { - payloadIn = data.right(data.length() - 4); + payloadIn = data.right(data.length() - 4); // Removes FE FE E0 94 part + if(payloadIn.contains("\xFE")) + { + //qDebug(logRig()) << "Corrupted data contains FE within message body: "; + //printHex(payloadIn); + break; + } parseCommand(); } break; @@ -1320,9 +1332,9 @@ void rigCommander::parseLevels() break; default: - qInfo(logRig()) << "Unknown control level (0x14) received at register " << payloadIn[1] << " with level " << level; + qInfo(logRig()) << "Unknown control level (0x14) received at register " << QString("0x%1").arg((int)payloadIn[1],2,16) << " with level " << QString("0x%1").arg((int)level,2,16) << ", int=" << (int)level; + printHex(payloadIn); break; - } return; } From d3d59b2a94880c582c5532ac1cf4a143232bb37d Mon Sep 17 00:00:00 2001 From: Elliott Liggett Date: Tue, 15 Jun 2021 11:27:45 -0700 Subject: [PATCH 07/10] Dynamic show/hide spectrum for rigs without this feature. --- wfmain.cpp | 43 +++++++++++++++++++++++++++++++++++++++++-- wfmain.h | 1 + wfmain.ui | 14 +++++++------- 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/wfmain.cpp b/wfmain.cpp index f8fec6e..ccf89b5 100644 --- a/wfmain.cpp +++ b/wfmain.cpp @@ -1494,6 +1494,40 @@ void wfmain::saveSettings() } +void wfmain::showHideSpectrum(bool show) +{ + + if(show) + { + wf->show(); + plot->show(); + } else { + wf->hide(); + plot->hide(); + } + + // Controls: + ui->spectrumGroupBox->setVisible(show); + ui->spectrumModeCombo->setVisible(show); + ui->scopeBWCombo->setVisible(show); + ui->scopeEdgeCombo->setVisible(show); + ui->scopeEnableWFBtn->setVisible(show); + ui->scopeRefLevelSlider->setEnabled(show); + ui->wfLengthSlider->setEnabled(show); + ui->wfthemeCombo->setVisible(show); + ui->toFixedBtn->setVisible(show); + ui->clearPeakBtn->setVisible(show); + + // And the labels: + ui->specEdgeLabel->setVisible(show); + ui->specModeLabel->setVisible(show); + ui->specSpanLabel->setVisible(show); + ui->specThemeLabel->setVisible(show); + + ui->specControlsHorizLayout->setEnabled(show); + +} + void wfmain::prepareWf() { prepareWf(160); @@ -1505,6 +1539,11 @@ void wfmain::prepareWf(unsigned int wfLength) if(haveRigCaps) { + showHideSpectrum(rigCaps.hasSpectrum); + if(!rigCaps.hasSpectrum) + { + return; + } // TODO: Lock the function that draws on the spectrum while we are updating. spectrumDrawLock = true; @@ -4357,7 +4396,7 @@ void wfmain::calculateTimingParameters() msMinTiming = 35; delayedCommand->setInterval( msMinTiming * 2); // 20 byte message - periodicPollingTimer->setInterval( msMinTiming ); // slower for s-meter poll + periodicPollingTimer->setInterval( msMinTiming *5); // slower for s-meter poll qInfo(logSystem()) << "Delay command interval timing: " << msMinTiming * 2 << "ms"; qInfo(logSystem()) << "Periodic polling timer: " << msMinTiming << "ms"; @@ -4612,6 +4651,6 @@ void wfmain::on_wfLengthSlider_valueChanged(int value) void wfmain::on_debugBtn_clicked() { qInfo(logSystem()) << "Debug button pressed."; - emit getTxPower(); + emit getFrequency(); } diff --git a/wfmain.h b/wfmain.h index 9439ba7..0f4317e 100644 --- a/wfmain.h +++ b/wfmain.h @@ -462,6 +462,7 @@ private: void setPlotTheme(QCustomPlot *plot, bool isDark); void prepareWf(); void prepareWf(unsigned int wfLength); + void showHideSpectrum(bool show); void getInitialRigState(); void setBandButtons(); void showButton(QPushButton *btn); diff --git a/wfmain.ui b/wfmain.ui index d2a6ade..e9b4a27 100644 --- a/wfmain.ui +++ b/wfmain.ui @@ -26,7 +26,7 @@ - + Spectrum @@ -44,12 +44,12 @@ - + 0 - + Spectrum Mode: @@ -66,7 +66,7 @@ - + Span: @@ -86,7 +86,7 @@ - + Edge @@ -133,7 +133,7 @@ - + Theme: @@ -150,7 +150,7 @@ - + Qt::Horizontal From 542376124b542719f5a2e0a6a718d78596d9166a Mon Sep 17 00:00:00 2001 From: Elliott Liggett Date: Tue, 15 Jun 2021 13:38:16 -0700 Subject: [PATCH 08/10] Additional code to hide/show spectrum and correcting an issue with the rig name not populating for non-spectrum radios. --- wfmain.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/wfmain.cpp b/wfmain.cpp index ccf89b5..20595a3 100644 --- a/wfmain.cpp +++ b/wfmain.cpp @@ -1524,8 +1524,12 @@ void wfmain::showHideSpectrum(bool show) ui->specSpanLabel->setVisible(show); ui->specThemeLabel->setVisible(show); + // And the layout for space: ui->specControlsHorizLayout->setEnabled(show); - + ui->splitter->setVisible(show); + ui->plot->setVisible(show); + ui->waterfall->setVisible(show); + ui->spectrumGroupBox->setEnabled(show); } void wfmain::prepareWf() @@ -1592,7 +1596,6 @@ void wfmain::prepareWf(unsigned int wfLength) wf->yAxis->setRangeReversed(true); wf->xAxis->setVisible(false); - rigName->setText(rigCaps.modelName); spectrumDrawLock = false; } else { @@ -2477,6 +2480,7 @@ void wfmain::receiveRigID(rigCapabilities rigCaps) qDebug(logSystem()) << "Rig ID received into wfmain: hasSpectrum: " << rigCaps.hasSpectrum; this->rigCaps = rigCaps; + rigName->setText(rigCaps.modelName); this->spectWidth = rigCaps.spectLenMax; // used once haveRigCaps is true. haveRigCaps = true; // Added so that server receives rig capabilities. From 7a2e8560cfccf13d52f20f3af455da644d59c16e Mon Sep 17 00:00:00 2001 From: Elliott Liggett Date: Thu, 17 Jun 2021 23:14:28 -0700 Subject: [PATCH 09/10] Radios without spectrum do not show spectrum, and, the window properly resizes for those controls. Also, a new key command, control-shift-d has been added to run debug functions from any tab in the program. --- wfmain.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ wfmain.h | 3 +++ 2 files changed, 60 insertions(+) diff --git a/wfmain.cpp b/wfmain.cpp index 20595a3..db3fbee 100644 --- a/wfmain.cpp +++ b/wfmain.cpp @@ -696,6 +696,54 @@ void wfmain::setupMainUI() ui->tuneLockChk->setChecked(false); freqLock = false; + + connect(ui->tabWidget, SIGNAL(currentChanged(int)), this, SLOT(updateSizes(int))); +} + +void wfmain::updateSizes(int tabIndex) +{ + // This function does nothing unless you are using a rig without spectrum. + // This is a hack. It is not great, but it seems to work ok. + if(!rigCaps.hasSpectrum) + { + // Set "ignore" size policy for non-selected tabs: + for(int i=0;itabWidget->count();i++) + if((i!=tabIndex) && tabIndex != 0) + ui->tabWidget->widget(i)->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); // allows size to be any size that fits the tab bar + + if(tabIndex==0 && !rigCaps.hasSpectrum) + { + + ui->tabWidget->widget(0)->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + ui->tabWidget->widget(0)->setMaximumSize(ui->tabWidget->widget(0)->minimumSizeHint()); + ui->tabWidget->widget(0)->adjustSize(); // tab + this->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + this->setMaximumSize(QSize(929, 270)); + this->setMinimumSize(QSize(929, 270)); + + resize(minimumSize()); + adjustSize(); // main window + adjustSize(); + + } else if(tabIndex==0 && rigCaps.hasSpectrum) { + // At main tab (0) and we have spectrum: + ui->tabWidget->widget(0)->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + + resize(minimumSizeHint()); + adjustSize(); // Without this call, the window retains the size of the previous tab. + } else { + // At some other tab, with or without spectrum: + ui->tabWidget->widget(tabIndex)->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + this->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + this->setMinimumSize(QSize(994, 455)); // not large enough for settings tab + this->setMaximumSize(QSize(65535,65535)); + } + } else { + ui->tabWidget->widget(tabIndex)->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + ui->tabWidget->widget(tabIndex)->setMaximumSize(65535,65535); + //ui->tabWidget->widget(0)->setMinimumSize(); + } + } void wfmain::getSettingsFilePath(QString settingsFile) @@ -1039,6 +1087,10 @@ void wfmain::setupKeyShortcuts() keyM = new QShortcut(this); keyM->setKey(Qt::Key_M); connect(keyM, SIGNAL(activated()), this, SLOT(shortcutM())); + + keyDebug = new QShortcut(this); + keyDebug->setKey(Qt::CTRL + Qt::SHIFT + Qt::Key_D); + connect(keyDebug, SIGNAL(activated()), this, SLOT(on_debugBtn_clicked())); } void wfmain::setDefPrefs() @@ -1530,6 +1582,10 @@ void wfmain::showHideSpectrum(bool show) ui->plot->setVisible(show); ui->waterfall->setVisible(show); ui->spectrumGroupBox->setEnabled(show); + + // Window resize: + updateSizes(ui->tabWidget->currentIndex()); + } void wfmain::prepareWf() @@ -3833,6 +3889,7 @@ void wfmain::on_connectBtn_clicked() emit sendCloseComm(); ui->connectBtn->setText("Connect"); haveRigCaps = false; + rigName->setText("NONE"); } else { diff --git a/wfmain.h b/wfmain.h index 0f4317e..1071b89 100644 --- a/wfmain.h +++ b/wfmain.h @@ -144,6 +144,7 @@ signals: void sendRigCaps(rigCapabilities caps); private slots: + void updateSizes(int tabIndex); void shortcutF1(); void shortcutF2(); void shortcutF3(); @@ -510,6 +511,8 @@ private: QShortcut *keyF; QShortcut *keyM; + QShortcut *keyDebug; + rigCommander * rig=Q_NULLPTR; QThread* rigThread = Q_NULLPTR; From bd1b6fc1de8dc117e51c3007c7ab663e977b9ddf Mon Sep 17 00:00:00 2001 From: Elliott Liggett Date: Fri, 18 Jun 2021 00:58:02 -0700 Subject: [PATCH 10/10] Fixed accidental s-meter timing parameter change. --- wfmain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wfmain.cpp b/wfmain.cpp index db3fbee..d85b7a1 100644 --- a/wfmain.cpp +++ b/wfmain.cpp @@ -4457,7 +4457,7 @@ void wfmain::calculateTimingParameters() msMinTiming = 35; delayedCommand->setInterval( msMinTiming * 2); // 20 byte message - periodicPollingTimer->setInterval( msMinTiming *5); // slower for s-meter poll + periodicPollingTimer->setInterval( msMinTiming ); // quicker for s-meter poll qInfo(logSystem()) << "Delay command interval timing: " << msMinTiming * 2 << "ms"; qInfo(logSystem()) << "Periodic polling timer: " << msMinTiming << "ms";