diff --git a/CHANGELOG b/CHANGELOG index c915abf..91161d4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,107 @@ +commit fe36ff1ac73dee5b14df534b50454587c95fe4bd +Merge: 13f06e1 4950127 +Author: Roeland Jansen +Date: Thu Jan 26 07:33:00 2023 +0100 + + Merge branch 'pbt-fixes' + +commit 49501273d02e02df7b2b1ca58be7a576daa1a19f +Author: Phil Taylor +Date: Wed Jan 25 21:37:12 2023 +0000 + + Fix for shuttle resource files + +commit ea46d6c625e02c4869bd5fcd42c191f111a590f7 +Author: Phil Taylor +Date: Wed Jan 25 21:22:06 2023 +0000 + + Add math.h for cwsender + +commit 13f06e1dd7596a83f1686be7e632f62121574036 +Merge: 6df7099 ded6bd1 +Author: Roeland Jansen +Date: Wed Jan 25 22:17:23 2023 +0100 + + Merge branch 'pbt-fixes' + +commit ded6bd1adeba5790b1457fa1afcae651f322f045 +Author: Phil Taylor +Date: Wed Jan 25 18:01:24 2023 +0000 + + Add CW Speed spinbox to CW sender + +commit 4b40e20d9825e66c7b7cd77371d3f1e8801f06ae +Author: Phil Taylor +Date: Wed Jan 25 15:39:01 2023 +0000 + + Remove some debugging + +commit 6df7099cb3ac8d48fdbff501cc0c1a7e2b236341 +Merge: bc0f9f0 5483732 +Author: Roeland Jansen +Date: Wed Jan 25 13:17:03 2023 +0100 + + Merge branch 'pbt-fixes' + +commit 54837327663bbb1b0aff5bb8cde45e1ebc4d63ee +Merge: 8b8668a 7f97625 +Author: Phil Taylor +Date: Wed Jan 25 11:42:13 2023 +0000 + + Merge branch 'master' into pbt-fixes + +commit 8b8668a6deacb528cf9e0bf7311465966abc1614 +Author: Phil Taylor +Date: Wed Jan 25 11:41:50 2023 +0000 + + Finally PBT works in all modes/filter widths/cw pitch settings. + +commit bc0f9f01c7333285214d3b847517625de2a63899 +Merge: 85e38d9 be0aee6 +Author: Roeland Jansen +Date: Wed Jan 25 09:16:36 2023 +0100 + + Merge branch 'morecontrols' + +commit be0aee6183286a73604f5eba7c4b2d57b530d383 +Author: Elliott Liggett +Date: Wed Jan 25 00:15:20 2023 -0800 + + Split mode is working, can also live-sync frequency and mode. + +commit 85e38d940f2874bbcbdcbbb619203732b0f1c146 +Merge: 7f97625 a1d3f93 +Author: Roeland Jansen +Date: Wed Jan 25 07:47:41 2023 +0100 + + Merge branch 'pbt-fixes' + +commit 4fea16c356189b06caad2adb2e5399dbbcc01945 +Author: Elliott Liggett +Date: Tue Jan 24 16:35:46 2023 -0800 + + Refined split interface controls. Offset is KHz, automatic tracking mode + added. + +commit ae64677c4213c0e0f2789a4388f5f2120c1574ff +Merge: 0a7f6b0 7f97625 +Author: Elliott Liggett +Date: Tue Jan 24 15:17:17 2023 -0800 + + Merge branch 'master' into morecontrols + +commit a1d3f93dad7141a54a4ffd5585eaad0ee7774591 +Author: Phil Taylor +Date: Tue Jan 24 20:12:23 2023 +0000 + + PBT should now display correctly in ALL modes! + +commit 7f97625e38eec48affcb4abe174802636a7b07ad +Author: Roeland Jansen +Date: Tue Jan 24 19:49:43 2023 +0100 + + modified CHANGELOG + commit d53c9b028e1e962b80334bbeaac794d4572d9939 Author: Elliott Liggett Date: Tue Jan 24 10:37:26 2023 -0800 @@ -5,6 +109,12 @@ Date: Tue Jan 24 10:37:26 2023 -0800 Added a rapidPollCmdQueue for things we need to poll rapidly on not-s- meter-intervals. Moved command types to wfviewtypes.h. +commit 0a7f6b0b6547087841bd0f5da1f962250cdda49c +Author: Elliott Liggett +Date: Tue Jan 24 09:21:09 2023 -0800 + + Started work on the UI for a split control interface. + commit 2df82d4f922fcebd256816d41839977840d08e5b Author: Roeland Jansen Date: Tue Jan 24 17:22:34 2023 +0100 diff --git a/freqmemory.h b/freqmemory.h index 58f8c7e..e7ccf76 100644 --- a/freqmemory.h +++ b/freqmemory.h @@ -4,13 +4,6 @@ #include #include "wfviewtypes.h" -struct mode_info { - mode_kind mk; - unsigned char reg; - unsigned char filter; - QString name; -}; - struct preset_kind { // QString name; // QString comment; diff --git a/repeatersetup.cpp b/repeatersetup.cpp index 78c3d4a..58c148d 100644 --- a/repeatersetup.cpp +++ b/repeatersetup.cpp @@ -16,9 +16,11 @@ repeaterSetup::repeaterSetup(QWidget *parent) : #ifdef QT_DEBUG ui->debugBtn->setVisible(true); ui->rptReadRigBtn->setVisible(true); + ui->rptOffsetBtn->setVisible(true); #else ui->debugBtn->setVisible(false); ui->rptReadRigBtn->setVisible(false); + ui->rptOffsetBtn->setVisible(false); #endif } @@ -235,21 +237,39 @@ void repeaterSetup::populateDTCS() void repeaterSetup::receiveDuplexMode(duplexMode dm) { currentdm = dm; + ui->splitEnableChk->blockSignals(true); switch(dm) { - case dmSimplex: case dmSplitOff: + ui->splitEnableChk->setChecked(false); + ui->autoTrackLiveBtn->setChecked(false); + break; + case dmSplitOn: + ui->splitEnableChk->setChecked(true); + ui->rptSimplexBtn->setChecked(false); + ui->rptDupPlusBtn->setChecked(false); + ui->rptDupMinusBtn->setChecked(false); + break; + case dmSimplex: ui->rptSimplexBtn->setChecked(true); + ui->splitEnableChk->setChecked(false); + ui->autoTrackLiveBtn->setChecked(false); break; case dmDupPlus: ui->rptDupPlusBtn->setChecked(true); + ui->splitEnableChk->setChecked(false); + ui->autoTrackLiveBtn->setChecked(false); break; case dmDupMinus: ui->rptDupMinusBtn->setChecked(true); + ui->splitEnableChk->setChecked(false); + ui->autoTrackLiveBtn->setChecked(false); break; default: + qDebug() << "Did not understand duplex/split/repeater value of " << (unsigned char)dm; break; } + ui->splitEnableChk->blockSignals(false); } void repeaterSetup::handleRptAccessMode(rptAccessTxRx tmode) @@ -296,6 +316,52 @@ void repeaterSetup::handleDTCS(quint16 dcode, bool tinv, bool rinv) ui->rptDTCSInvertRx->setChecked(rinv); } +void repeaterSetup::handleUpdateCurrentMainFrequency(freqt mainfreq) +{ + if(amTransmitting) + return; + + if(ui->autoTrackLiveBtn->isChecked() && !ui->splitOffsetEdit->text().isEmpty()) + { + if(currentMainFrequency.Hz != mainfreq.Hz) + { + this->currentMainFrequency = mainfreq; + if(usedPlusSplit) + { + on_splitPlusButton_clicked(); + } else { + on_splitMinusBtn_clicked(); + } + } + } + this->currentMainFrequency = mainfreq; +} + +void repeaterSetup::handleUpdateCurrentMainMode(mode_info m) +{ + // Used to set the secondary VFO to the same mode + // (generally FM) + // NB: We don't accept values during transmit as they + // may represent the inactive VFO + if(!amTransmitting) + { + this->currentModeMain = m; + this->modeTransmitVFO = m; + this->modeTransmitVFO.VFO = inactiveVFO; + } +} + +void repeaterSetup::handleTransmitStatus(bool amTransmitting) +{ + this->amTransmitting = amTransmitting; +} + +void repeaterSetup::showEvent(QShowEvent *event) +{ + emit getSplitModeEnabled(); + (void)event; +} + void repeaterSetup::on_rptSimplexBtn_clicked() { // Simplex @@ -395,3 +461,136 @@ void repeaterSetup::on_debugBtn_clicked() //emit getDTCS(); emit getRptAccessMode(); } + +void repeaterSetup::on_splitOffsetSetBtn_clicked() +{ + freqt txFreq; + bool ok = true; + txFreq.Hz = ui->splitTransmitFreqEdit->text().toDouble(&ok) * 1E6; + emit setTransmitFrequency(txFreq); +} + +void repeaterSetup::on_splitEnableChk_clicked(bool enabled) +{ + if(enabled) + { + emit setDuplexMode(dmSplitOn); + } else { + emit setDuplexMode(dmSplitOff); + } + if(ui->autoTrackLiveBtn->isChecked()) + { + ui->autoTrackLiveBtn->setChecked(false); + } +} + +quint64 repeaterSetup::getFreqHzFromKHzString(QString khz) +{ + // This function takes a string containing a number in KHz, + // and creates an accurate quint64 in Hz. + quint64 fhz = 0; + bool ok = true; + if(khz.isEmpty()) + { + qWarning() << "KHz offset was empty!"; + return fhz; + } + if(khz.contains(".")) + { + // "600.245" becomes "600" + khz.chop(khz.indexOf(".")); + } + fhz = 1E3 * khz.toUInt(&ok); + if(!ok) + { + qWarning() << "Could not understand user KHz text"; + } + return fhz; +} + +quint64 repeaterSetup::getFreqHzFromMHzString(QString MHz) +{ + // This function takes a string containing a number in KHz, + // and creates an accurate quint64 in Hz. + quint64 fhz = 0; + bool ok = true; + if(MHz.isEmpty()) + { + qWarning() << "MHz string was empty!"; + return fhz; + } + if(MHz.contains(".")) + { + int decimalPtIndex = MHz.indexOf("."); + // "29.623" + // indexOf(".") = 2 + // length = 6 + // We want the right 4xx 3 characters. + QString KHz = MHz.right(MHz.length() - decimalPtIndex - 1); + MHz.chop(MHz.length() - decimalPtIndex); + + fhz = MHz.toUInt(&ok) * 1E6; if(!ok) goto handleError; + fhz += KHz.toUInt(&ok) * 1E3; if(!ok) goto handleError; + + } else { + // Frequency was already MHz (unlikely but what can we do?) + fhz = MHz.toUInt(&ok) * 1E6; if(!ok) goto handleError; + } + return fhz; + +handleError: + qWarning() << "Could not understand user MHz text " << MHz; + return 0; +} + +void repeaterSetup::on_splitPlusButton_clicked() +{ + quint64 hzOffset = getFreqHzFromKHzString(ui->splitOffsetEdit->text()); + quint64 txfreqhz; + freqt f; + QString txString; + if(hzOffset) + { + txfreqhz = currentMainFrequency.Hz + hzOffset; + f.Hz = txfreqhz; + f.VFO = inactiveVFO; + txString = QString::number(f.Hz / double(1E6), 'f', 6); + ui->splitTransmitFreqEdit->setText(txString); + usedPlusSplit = true; + emit setTransmitFrequency(f); + emit setTransmitMode(modeTransmitVFO); + } +} + + +void repeaterSetup::on_splitMinusBtn_clicked() +{ + quint64 hzOffset = getFreqHzFromKHzString(ui->splitOffsetEdit->text()); + quint64 txfreqhz; + freqt f; + QString txString; + if(hzOffset) + { + txfreqhz = currentMainFrequency.Hz - hzOffset; + f.Hz = txfreqhz; + f.VFO = inactiveVFO; + txString = QString::number(f.Hz / double(1E6), 'f', 6); + ui->splitTransmitFreqEdit->setText(txString); + usedPlusSplit = false; + emit setTransmitFrequency(f); + emit setTransmitMode(modeTransmitVFO); + } +} + +void repeaterSetup::on_splitTxFreqSetBtn_clicked() +{ + quint64 fHz = getFreqHzFromMHzString(ui->splitTransmitFreqEdit->text()); + freqt f; + if(fHz) + { + f.Hz = fHz; + f.VFO = inactiveVFO; + emit setTransmitFrequency(f); + emit setTransmitMode(modeTransmitVFO); + } +} diff --git a/repeatersetup.h b/repeatersetup.h index 2763a12..73c71c7 100644 --- a/repeatersetup.h +++ b/repeatersetup.h @@ -31,6 +31,13 @@ signals: void getDTCS(); void setRptAccessMode(rptAccessTxRx tmode); void getRptAccessMode(); + // Split: + void getSplitModeEnabled(); + void getTransmitFrequency(); + // Use the duplexMode to communicate split. + // void setSplitModeEnabled(bool splitEnabled); + void setTransmitFrequency(freqt transmitFreq); + void setTransmitMode(mode_info m); public slots: void receiveDuplexMode(duplexMode dm); @@ -38,8 +45,14 @@ public slots: void handleTone(quint16 tone); void handleTSQL(quint16 tsql); void handleDTCS(quint16 dcscode, bool tinv, bool rinv); + // void handleSplitMode(bool splitEnabled); + // void handleSplitFrequency(freqt transmitFreq); + void handleUpdateCurrentMainFrequency(freqt mainfreq); + void handleUpdateCurrentMainMode(mode_info m); + void handleTransmitStatus(bool amTransmitting); private slots: + void showEvent(QShowEvent *event); void on_rptSimplexBtn_clicked(); void on_rptDupPlusBtn_clicked(); void on_rptDupMinusBtn_clicked(); @@ -51,16 +64,29 @@ private slots: void on_toneNone_clicked(); void on_toneTone_clicked(); void on_toneTSQL_clicked(); - void on_toneDTCS_clicked(); + void on_toneDTCS_clicked(); + void on_splitOffsetSetBtn_clicked(); + void on_splitEnableChk_clicked(bool enabled); + void on_splitPlusButton_clicked(); + void on_splitMinusBtn_clicked(); + + void on_splitTxFreqSetBtn_clicked(); private: Ui::repeaterSetup *ui; - + freqt currentMainFrequency; void populateTones(); void populateDTCS(); + quint64 getFreqHzFromKHzString(QString khz); + quint64 getFreqHzFromMHzString(QString MHz); + rigCapabilities rig; bool haveRig = false; duplexMode currentdm; + mode_info currentModeMain; + mode_info modeTransmitVFO; + bool usedPlusSplit = false; + bool amTransmitting = false; }; #endif // REPEATERSETUP_H diff --git a/repeatersetup.ui b/repeatersetup.ui index ffb72f5..e49f2f2 100644 --- a/repeatersetup.ui +++ b/repeatersetup.ui @@ -6,7 +6,7 @@ 0 0 - 800 + 922 217 @@ -71,7 +71,7 @@ 0 - + Repeater Duplex @@ -119,6 +119,115 @@ + + + + Split Mode + + + + + + + + Split Enable + + + + + + + Auto Track Live + + + + + + + + + + + Offset (KHz): + + + + + + + + 120 + 0 + + + + + 120 + 16777215 + + + + + + + + Split+ + + + + + + + Split- + + + + + + + RPT + + + + + + + + + + + Tx Freq (MHz): + + + + + + + + 120 + 0 + + + + + 120 + 16777215 + + + + + + + + Set + + + + + + + + @@ -231,7 +340,7 @@ - + diff --git a/rigcommander.cpp b/rigcommander.cpp index 5d3a8ef..eedd21b 100644 --- a/rigcommander.cpp +++ b/rigcommander.cpp @@ -772,8 +772,17 @@ void rigCommander::setMode(mode_info m) m.filter = '\x01'; } - payload.setRawData("\x06", 1); + if(m.VFO==inactiveVFO) + { + payload.setRawData("\x26\x01", 2); + } else { + payload.setRawData("\x06", 1); + } + payload.append(m.reg); + if(m.VFO==inactiveVFO) + payload.append("\x00", 1); + payload.append(m.filter); prepDataAndSend(payload); @@ -846,6 +855,19 @@ void rigCommander::getDataMode() prepDataAndSend(payload); } +void rigCommander::getSplit() +{ + QByteArray payload("\x0F"); + prepDataAndSend(payload); +} + +void rigCommander::setSplit(bool splitEnabled) +{ + QByteArray payload("\x0F"); + payload.append((unsigned char)splitEnabled); + prepDataAndSend(payload); +} + void rigCommander::setDuplexMode(duplexMode dm) { QByteArray payload; diff --git a/rigcommander.h b/rigcommander.h index 7ca3ff2..5dba56a 100644 --- a/rigcommander.h +++ b/rigcommander.h @@ -76,6 +76,8 @@ public slots: void getMode(); void setDataMode(bool dataOn, unsigned char filter); void getDataMode(); + void getSplit(); + void setSplit(bool splitEnabled); void getBandStackReg(char band, char regCode); void getRitEnabled(); void getRitValue(); @@ -365,7 +367,7 @@ private: void setup(); QByteArray stripData(const QByteArray &data, unsigned char cutPosition); void parseData(QByteArray data); // new data come here - void parseCommand(); + void parseCommand(); // Entry point for complete commands unsigned char bcdHexToUChar(unsigned char in); unsigned char bcdHexToUChar(unsigned char hundreds, unsigned char tensunits); unsigned int bcdHexToUInt(unsigned char hundreds, unsigned char tensunits); diff --git a/wfmain.cpp b/wfmain.cpp index ae94410..1c681af 100644 --- a/wfmain.cpp +++ b/wfmain.cpp @@ -391,6 +391,11 @@ void wfmain::rigConnections() connect(rig, SIGNAL(haveTSQL(quint16)), rpt, SLOT(handleTSQL(quint16))); connect(rig, SIGNAL(haveDTCS(quint16,bool,bool)), rpt, SLOT(handleDTCS(quint16,bool,bool))); connect(rig, SIGNAL(haveRptAccessMode(rptAccessTxRx)), rpt, SLOT(handleRptAccessMode(rptAccessTxRx))); + connect(this->rpt, &repeaterSetup::setTransmitFrequency, + [=](const freqt &transmitFreq) { issueCmd(cmdSetFreq, transmitFreq);}); + + connect(this->rpt, &repeaterSetup::setTransmitMode, + [=](const mode_info &transmitMode) { issueCmd(cmdSetMode, transmitMode);}); connect(this, SIGNAL(getDuplexMode()), rig, SLOT(getDuplexMode())); connect(this, SIGNAL(getPassband()), rig, SLOT(getPassband())); @@ -3597,7 +3602,7 @@ void wfmain::doCmd(commandtype cmddata) { lastFreqCmdTime_ms = QDateTime::currentMSecsSinceEpoch(); freqt f = (*std::static_pointer_cast(data)); - emit setFrequency(0,f); + emit setFrequency(f.VFO,f); break; } case cmdSetMode: @@ -4621,6 +4626,7 @@ void wfmain::receiveFreq(freqt freqStruct) { ui->freqLabel->setText(QString("%1").arg(freqStruct.MHzDouble, 0, 'f')); freq = freqStruct; + rpt->handleUpdateCurrentMainFrequency(freqStruct); } else { qDebug(logSystem()) << "Rejecting stale frequency: " << freqStruct.Hz << " Hz, delta time ms = " << tnow_ms - lastFreqCmdTime_ms\ << ", tnow_ms " << tnow_ms << ", last: " << lastFreqCmdTime_ms; @@ -4641,6 +4647,7 @@ void wfmain::receivePTTstatus(bool pttOn) pttLed->setState(QLedLabel::State::StateOk); } amTransmitting = pttOn; + rpt->handleTransmitStatus(pttOn); changeTxBtn(); } @@ -5366,18 +5373,11 @@ void wfmain::receiveMode(unsigned char mode, unsigned char filter) currentModeInfo.reg = mode; rpt->handleUpdateCurrentMainMode(currentModeInfo); -<<<<<<< Updated upstream - currentModeIndex = mode; - currentModeInfo.mk = (mode_kind)mode; - currentMode = (mode_kind)mode; - currentModeInfo.filter = filter; -======= if (!found) { qWarning(logSystem()) << __func__ << "Received mode " << mode << " but could not match to any index within the modeSelectCombo. "; return; } ->>>>>>> Stashed changes if (maxPassbandHz != 0) { diff --git a/wfviewtypes.h b/wfviewtypes.h index cdece4f..131989d 100644 --- a/wfviewtypes.h +++ b/wfviewtypes.h @@ -60,6 +60,19 @@ enum mode_kind { modeDCR }; +enum selVFO_t { + activeVFO = 0, + inactiveVFO = 1 +}; + +struct mode_info { + mode_kind mk; + unsigned char reg; + unsigned char filter; + selVFO_t VFO = activeVFO; + QString name; +}; + enum breakIn_t { brkinOff = 0x00, brkinSemi = 0x01, @@ -69,6 +82,7 @@ enum breakIn_t { struct freqt { quint64 Hz; double MHzDouble; + selVFO_t VFO = activeVFO; }; struct datekind {