diff --git a/rigcommander.cpp b/rigcommander.cpp index 295373a..d5f270e 100644 --- a/rigcommander.cpp +++ b/rigcommander.cpp @@ -37,6 +37,8 @@ rigCommander::rigCommander(unsigned char rigCivAddr, QString rigSerialPort, quin civAddr = rigCivAddr; // address of the radio. Decimal is 148. setCIVAddr(civAddr); + usingNativeLAN = false; // TODO: set to true if we are connected over ethernet to the rig + spectSeqMax = 0; // this is now set after rig ID determined //compCivAddr = 0xE1; //payloadPrefix = QByteArray("\xFE\xFE\x94\xE0"); payloadPrefix = QByteArray("\xFE\xFE"); @@ -533,6 +535,10 @@ void rigCommander::parseCommand() // qDebug() << "Have rig ID: " << (unsigned int)payloadIn[2]; // printHex(payloadIn, false, true); model = determineRadioModel(payloadIn[2]); + determineRigCaps(); + qDebug() << "Have rig ID: decimal: " << (unsigned int)model; + + break; case '\x26': if((int)payloadIn[1] == 0) @@ -794,7 +800,6 @@ void rigCommander::parseDetailedRegisters1A05() void rigCommander::parseWFData() { float freqSpan = 0.0; - switch(payloadIn[1]) { case 0: @@ -846,8 +851,85 @@ void rigCommander::parseWFData() } } +void rigCommander::determineRigCaps() +{ + //TODO: Add if(usingNativeLAN) condition + //TODO: Determine available bands (low priority, rig will reject out of band requests anyway) + + switch(model){ + case model7300: + rigCaps.hasSpectrum = true; + rigCaps.spectSeqMax = 11; + rigCaps.spectAmpMax = 160; + rigCaps.spectLenMax = 475; + rigCaps.hasLan = false; + rigCaps.hasEthernet = false; + rigCaps.hasWiFi = false; + break; + case model9700: + rigCaps.hasSpectrum = true; + rigCaps.spectSeqMax = 11; + rigCaps.spectAmpMax = 160; + rigCaps.spectLenMax = 475; + rigCaps.hasLan = true; + rigCaps.hasEthernet = true; + rigCaps.hasWiFi = false; + break; + case model7610: + rigCaps.hasSpectrum = true; + rigCaps.spectSeqMax = 15; + rigCaps.spectAmpMax = 200; + rigCaps.spectLenMax = 689; + rigCaps.hasLan = true; + rigCaps.hasEthernet = true; + rigCaps.hasWiFi = false; + break; + case model7850: + rigCaps.hasSpectrum = true; + rigCaps.spectSeqMax = 15; + rigCaps.spectAmpMax = 136; + rigCaps.spectLenMax = 689; + rigCaps.hasLan = true; + rigCaps.hasEthernet = true; + rigCaps.hasWiFi = false; + break; + case model705: + rigCaps.hasSpectrum = true; + rigCaps.spectSeqMax = 11; + rigCaps.spectAmpMax = 160; + rigCaps.spectLenMax = 475; + rigCaps.hasLan = true; + rigCaps.hasEthernet = false; + rigCaps.hasWiFi = true; + break; + default: + rigCaps.hasSpectrum = false; + rigCaps.spectSeqMax = 0; + rigCaps.spectAmpMax = 0; + rigCaps.spectLenMax = 0; + rigCaps.hasLan = false; + rigCaps.hasEthernet = false; + rigCaps.hasWiFi = false; + break; + + } + haveRigCaps = true; + emit haveRigID(rigCaps); +} + void rigCommander::parseSpectrum() { + if(!haveRigCaps) + { + qDebug() << "Spectrum received in rigCommander, but rigID is incomplete."; + return; + } + if(rigCaps.spectSeqMax == 0) + { + // there is a chance this will happen with rigs that support spectrum. Once our RigID query returns, we will parse correctly. + qDebug() << "Warning: Spectrum sequence max was zero, yet spectrum was received."; + return; + } // Here is what to expect: // payloadIn[00] = '\x27'; // payloadIn[01] = '\x00'; @@ -906,16 +988,16 @@ void rigCommander::parseSpectrum() spectrumStartFreq -= spectrumEndFreq; spectrumEndFreq = spectrumStartFreq + 2*(spectrumEndFreq); } - } else if ((sequence > 1) && (sequence < 11)) + } else if ((sequence > 1) && (sequence < rigCaps.spectSeqMax)) { // spectrum from index 05 to index 54, length is 55 per segment. Length is 56 total. Pixel data is 50 pixels. // sequence numbers 2 through 10, 50 pixels each. Total after sequence 10 is 450 pixels. payloadIn.chop(1); spectrumLine.insert(spectrumLine.length(), payloadIn.right(payloadIn.length() - 5)); // write over the FD, last one doesn't, oh well. //qDebug() << "sequence: " << sequence << "spec index: " << (sequence-2)*55 << " payloadPosition: " << payloadIn.length() - 5 << " payload length: " << payloadIn.length(); - } else if (sequence == 11) + } else if (sequence == rigCaps.spectSeqMax) { - // last spectrum, a little bit different (last 25 pixels). Total at end is 475 pixels. + // last spectrum, a little bit different (last 25 pixels). Total at end is 475 pixels (7300). payloadIn.chop(1); spectrumLine.insert(spectrumLine.length(), payloadIn.right(payloadIn.length() - 5)); //qDebug() << "sequence: " << sequence << " spec index: " << (sequence-2)*55 << " payloadPosition: " << payloadIn.length() - 5 << " payload length: " << payloadIn.length(); diff --git a/rigcommander.h b/rigcommander.h index c5377ed..9d339d3 100644 --- a/rigcommander.h +++ b/rigcommander.h @@ -64,6 +64,7 @@ public slots: signals: void haveSpectrumData(QByteArray spectrum, double startFreq, double endFreq); // pass along data to UI + void haveRigID(rigCapabilities rigCaps); void haveFrequency(double frequencyMhz); void haveMode(QString mode); void haveDataMode(bool dataModeEnabled); @@ -106,6 +107,7 @@ private: void prepDataAndSend(QByteArray data); void debugMe(); void printHex(const QByteArray &pdata, bool printVert, bool printHoriz); + void determineRigCaps(); commHandler * comm; QByteArray payloadIn; QByteArray echoPerfix; @@ -121,7 +123,14 @@ private: double spectrumStartFreq; double spectrumEndFreq; + struct rigCapabilities rigCaps; + bool haveRigCaps; model_kind model; + quint8 spectSeqMax; + quint16 spectAmpMax; + quint16 spectLenMax; + + bool usingNativeLAN; // indicates using OEM LAN connection (705,7610,9700,7850) double frequencyMhz; unsigned char civAddr; // 0x94 is default = 148decimal diff --git a/rigidentities.cpp b/rigidentities.cpp index 3ba02a5..6981eff 100644 --- a/rigidentities.cpp +++ b/rigidentities.cpp @@ -1,5 +1,6 @@ #include "rigidentities.h" -// Copytight 2017-2020 Elliott H. Liggett + +// Copytight 2017-2021 Elliott H. Liggett model_kind determineRadioModel(unsigned char rigID) { @@ -32,6 +33,12 @@ model_kind determineRadioModel(unsigned char rigID) case model7850: rig = model7850; break; + case model9700: + rig = model9700; + break; + case model705: + rig = model705; + break; default: rig = modelUnknown; break; @@ -39,3 +46,8 @@ model_kind determineRadioModel(unsigned char rigID) return rig; } + + + + + diff --git a/rigidentities.h b/rigidentities.h index c67c7d1..ffe9043 100644 --- a/rigidentities.h +++ b/rigidentities.h @@ -1,6 +1,8 @@ #ifndef RIGIDENTITIES_H #define RIGIDENTITIES_H +#include + // Credit: // http://www.docksideradio.com/Icom%20Radio%20Hex%20Addresses.htm @@ -15,12 +17,27 @@ enum model_kind { model7700 = 0x74, model7800 = 0x6A, model7850 = 0x8E, + model9700 = 0xA2, + model705 = 0xA4, modelUnknown = 0xFF }; model_kind determineRadioModel(unsigned char rigID); +struct rigCapabilities { + //model_kind model; + + bool hasLan; // OEM ethernet or wifi connection + bool hasEthernet; + bool hasWiFi; + + bool hasSpectrum; + quint8 spectSeqMax; + quint16 spectAmpMax; + quint16 spectLenMax; + +}; #endif // RIGIDENTITIES_H diff --git a/wfmain.cpp b/wfmain.cpp index 5b15b89..c38ace5 100644 --- a/wfmain.cpp +++ b/wfmain.cpp @@ -20,6 +20,8 @@ wfmain::wfmain(QWidget *parent) : setWindowTitle(QString("wfview")); + haveRigCaps = false; + ui->bandStkLastUsedBtn->setVisible(false); ui->bandStkVoiceBtn->setVisible(false); ui->bandStkDataBtn->setVisible(false); @@ -180,17 +182,17 @@ wfmain::wfmain(QWidget *parent) : tracer->setBrush(Qt::green); tracer->setSize(30); - spectWidth = 475; // fixed for now - wfLength = 160; // fixed for now +// spectWidth = 475; // fixed for now +// wfLength = 160; // fixed for now, time-length of waterfall - // Initialize before use! +// // Initialize before use! - QByteArray empty((int)spectWidth, '\x01'); - spectrumPeaks = QByteArray( (int)spectWidth, '\x01' ); - for(quint16 i=0; istart(); + qRegisterMetaType(); connect(rig, SIGNAL(haveFrequency(double)), this, SLOT(receiveFreq(double))); connect(this, SIGNAL(getFrequency()), rig, SLOT(getFrequency())); @@ -266,8 +269,9 @@ wfmain::wfmain(QWidget *parent) : connect(this, SIGNAL(getATUStatus()), rig, SLOT(getATUStatus())); connect(this, SIGNAL(getRigID()), rig, SLOT(getRigID())); connect(rig, SIGNAL(haveATUStatus(unsigned char)), this, SLOT(receiveATUStatus(unsigned char))); + connect(rig, SIGNAL(haveRigID(rigCapabilities)), this, SLOT(receiveRigID(rigCapabilities))); - // Speech (emitted from IC-7300 speaker) + // Speech (emitted from rig speaker) connect(this, SIGNAL(sayAll()), rig, SLOT(sayAll())); connect(this, SIGNAL(sayFrequency()), rig, SLOT(sayFrequency())); connect(this, SIGNAL(sayMode()), rig, SLOT(sayMode())); @@ -295,16 +299,20 @@ wfmain::wfmain(QWidget *parent) : wf->addPlottable(colorMap); #endif + //TRY moving to prepareWf(): + colorScale = new QCPColorScale(wf); - colorMap->data()->setValueRange(QCPRange(0, wfLength-1)); - colorMap->data()->setKeyRange(QCPRange(0, spectWidth-1)); - colorMap->setDataRange(QCPRange(0, 160)); - colorMap->setGradient(QCPColorGradient::gpJet); // TODO: Add preference - colorMapData = new QCPColorMapData(spectWidth, wfLength, QCPRange(0, spectWidth-1), QCPRange(0, wfLength-1)); - colorMap->setData(colorMapData); - spectRowCurrent = 0; - wf->yAxis->setRangeReversed(true); - wf->xAxis->setVisible(false); +// colorMap->data()->setValueRange(QCPRange(0, wfLength-1)); +// colorMap->data()->setKeyRange(QCPRange(0, spectWidth-1)); +// colorMap->setDataRange(QCPRange(0, 160)); +// colorMap->setGradient(QCPColorGradient::gpJet); // TODO: Add preference +// colorMapData = new QCPColorMapData(spectWidth, wfLength, QCPRange(0, spectWidth-1), QCPRange(0, wfLength-1)); +// colorMap->setData(colorMapData); +// spectRowCurrent = 0; +// wf->yAxis->setRangeReversed(true); +// wf->xAxis->setVisible(false); + + // end TRY ui->tabWidget->setCurrentIndex(0); @@ -547,6 +555,43 @@ void wfmain::saveSettings() settings.sync(); // Automatic, not needed (supposedly) } +void wfmain::prepareWf() +{ + // All this code gets moved in from the constructor of wfmain. + + if(haveRigCaps) + { + // do things + spectWidth = rigCaps.spectLenMax; // was fixed at 475 + wfLength = 160; // fixed for now, time-length of waterfall + + // Initialize before use! + + QByteArray empty((int)spectWidth, '\x01'); + spectrumPeaks = QByteArray( (int)spectWidth, '\x01' ); + for(quint16 i=0; idata()->setValueRange(QCPRange(0, wfLength-1)); + colorMap->data()->setKeyRange(QCPRange(0, spectWidth-1)); + colorMap->setDataRange(QCPRange(0, rigCaps.spectAmpMax)); + colorMap->setGradient(QCPColorGradient::gpJet); // TODO: Add preference + colorMapData = new QCPColorMapData(spectWidth, wfLength, QCPRange(0, spectWidth-1), QCPRange(0, wfLength-1)); + colorMap->setData(colorMapData); + spectRowCurrent = 0; + wf->yAxis->setRangeReversed(true); + wf->xAxis->setVisible(false); + + } else { + qDebug() << "Cannot prepare WF view without rigCaps. Waiting on this."; + return; + } + +} + // Key shortcuts (hotkeys) @@ -742,7 +787,7 @@ void wfmain::getInitialRigState() // the polling interval is set at 100ms. Faster is possible but slower // computers will glitch occassionally. - cmdOutQue.append(cmdGetRigID); // This may be used in the future. + cmdOutQue.append(cmdGetRigID); cmdOutQue.append(cmdGetFreq); cmdOutQue.append(cmdGetMode); @@ -759,6 +804,11 @@ void wfmain::getInitialRigState() // get TX level // get Scope reference Level + cmdOutQue.append(cmdNone); + cmdOutQue.append(cmdGetRigID); + cmdOutQue.append(cmdNone); + cmdOutQue.append(cmdGetRigID); + cmdOutQue.append(cmdDispEnable); cmdOutQue.append(cmdSpecOn); @@ -962,9 +1012,35 @@ void wfmain::runDelayedCommand() } } + +void wfmain::receiveRigID(rigCapabilities rigCaps) +{ + // Note: We intentionally request rigID several times + // because without rigID, we can't do anything with the waterfall. + if(haveRigCaps) + { + return; + } else { + qDebug() << "Rig ID received into wfmain: spectLenMax: " << rigCaps.spectLenMax; + qDebug() << "Rig ID received into wfmain: spectAmpMax: " << rigCaps.spectAmpMax; + qDebug() << "Rig ID received into wfmain: spectSeqMax: " << rigCaps.spectSeqMax; + qDebug() << "Rig ID received into wfmain: hasSpectrum: " << rigCaps.hasSpectrum; + + this->rigCaps = rigCaps; + this->spectWidth = rigCaps.spectLenMax; // used once haveRigCaps is true. + haveRigCaps = true; + prepareWf(); + // Adding these here because clearly at this point we have valid + // rig comms. In the future, we should establish comms and then + // do all the initial grabs. For now, this hack of adding them here and there: + cmdOutQue.append(cmdGetFreq); + cmdOutQue.append(cmdGetMode); + } +} + void wfmain::receiveFreq(double freqMhz) { - //qDebug() << "Frequency: " << freqMhz; + //qDebug() << "HEY WE GOT A Frequency: " << freqMhz; ui->freqLabel->setText(QString("%1").arg(freqMhz, 0, 'f')); this->freqMhz = freqMhz; this->knobFreqMhz = freqMhz; @@ -979,6 +1055,12 @@ void wfmain::receivePTTstatus(bool pttOn) void wfmain::receiveSpectrumData(QByteArray spectrum, double startFreq, double endFreq) { + if(!haveRigCaps) + { + qDebug() << "Spectrum received, but RigID incomplete."; + return; + } + if((startFreq != oldLowerFreq) || (endFreq != oldUpperFreq)) { // If the frequency changed and we were drawing peaks, now is the time to clearn them @@ -996,9 +1078,14 @@ void wfmain::receiveSpectrumData(QByteArray spectrum, double startFreq, double e //qDebug() << "start: " << startFreq << " end: " << endFreq; quint16 specLen = spectrum.length(); //qDebug() << "Spectrum data received at UI! Length: " << specLen; - if(specLen != 475) + //if( (specLen != 475) || (specLen!=689) ) + + if( specLen != rigCaps.spectLenMax ) { - //qDebug () << "Unusual spectrum: length: " << specLen; + qDebug() << "-------------------------------------------"; + qDebug() << "------ Unusual spectrum received, length: " << specLen; + qDebug() << "------ Expected spectrum length: " << rigCaps.spectLenMax; + qDebug() << "------ This should happen once at most. "; return; // safe. Using these unusual length things is a problem. } @@ -1208,7 +1295,11 @@ void wfmain::receiveDataModeStatus(bool dataEnabled) void wfmain::on_clearPeakBtn_clicked() { - spectrumPeaks = QByteArray( (int)spectWidth, '\x01' ); + if(haveRigCaps) + { + spectrumPeaks = QByteArray( (int)spectWidth, '\x01' ); + } + return; } void wfmain::on_drawPeakChk_clicked(bool checked) diff --git a/wfmain.h b/wfmain.h index c93b975..7365788 100644 --- a/wfmain.h +++ b/wfmain.h @@ -8,11 +8,14 @@ #include #include #include +#include #include "commhandler.h" #include "rigcommander.h" #include "freqmemory.h" +#include "rigidentities.h" + #include #include @@ -111,7 +114,7 @@ private slots: void receiveAfGain(unsigned char level); void receiveSql(unsigned char level); void receiveATUStatus(unsigned char atustatus); - + void receiveRigID(rigCapabilities rigCaps); void handlePlotClick(QMouseEvent *); void handlePlotDoubleClick(QMouseEvent *); void handleWFClick(QMouseEvent *); @@ -240,6 +243,7 @@ private: //commHandler *comm; void setAppTheme(bool isDark); void setPlotTheme(QCustomPlot *plot, bool isDark); + void prepareWf(); void getInitialRigState(); QWidget * theParent; QStringList portList; @@ -366,10 +370,16 @@ private: int oldFreqDialVal; + rigCapabilities rigCaps; + bool haveRigCaps; + void bandStackBtnClick(); bool waitingForBandStackRtn; char bandStkBand; char bandStkRegCode; }; +Q_DECLARE_METATYPE(struct rigCapabilities) ; + + #endif // WFMAIN_H