diff --git a/repeatersetup.cpp b/repeatersetup.cpp index 42e9008..f934b8d 100644 --- a/repeatersetup.cpp +++ b/repeatersetup.cpp @@ -16,11 +16,9 @@ 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 } @@ -102,6 +100,14 @@ void repeaterSetup::setRig(rigCapabilities inRig) ui->setToneSubVFOBtn->setDisabled(true); ui->setSplitRptrToneChk->setDisabled(true); } + ui->rptAutoBtn->setEnabled(rig.hasRepeaterModes); + ui->rptDupMinusBtn->setEnabled(rig.hasRepeaterModes); + ui->rptDupPlusBtn->setEnabled(rig.hasRepeaterModes); + ui->rptSimplexBtn->setEnabled(rig.hasRepeaterModes); + ui->rptrOffsetEdit->setEnabled(rig.hasRepeaterModes); + ui->rptrOffsetSetBtn->setEnabled(rig.hasRepeaterModes); + ui->setToneSubVFOBtn->setEnabled(rig.hasSpecifyMainSubCmd); + ui->setRptrSubVFOBtn->setEnabled(rig.hasSpecifyMainSubCmd); } void repeaterSetup::populateTones() @@ -280,7 +286,7 @@ void repeaterSetup::receiveDuplexMode(duplexMode dm) switch(dm) { case dmSplitOff: - ui->splitEnableChk->setChecked(false); + //ui->splitEnableChk->setChecked(false); ui->autoTrackLiveBtn->setChecked(false); break; case dmSplitOn: @@ -291,17 +297,17 @@ void repeaterSetup::receiveDuplexMode(duplexMode dm) break; case dmSimplex: ui->rptSimplexBtn->setChecked(true); - ui->splitEnableChk->setChecked(false); + //ui->splitEnableChk->setChecked(false); ui->autoTrackLiveBtn->setChecked(false); break; case dmDupPlus: ui->rptDupPlusBtn->setChecked(true); - ui->splitEnableChk->setChecked(false); + //ui->splitEnableChk->setChecked(false); ui->autoTrackLiveBtn->setChecked(false); break; case dmDupMinus: ui->rptDupMinusBtn->setChecked(true); - ui->splitEnableChk->setChecked(false); + //ui->splitEnableChk->setChecked(false); ui->autoTrackLiveBtn->setChecked(false); break; default: @@ -395,6 +401,12 @@ void repeaterSetup::handleUpdateCurrentMainMode(mode_info m) } } +void repeaterSetup::handleRptOffsetFrequency(freqt f) +{ + QString offsetstr = QString::number(f.Hz / double(1E6), 'f', 4); + ui->rptrOffsetEdit->setText(offsetstr); +} + void repeaterSetup::handleTransmitStatus(bool amTransmitting) { this->amTransmitting = amTransmitting; @@ -402,15 +414,38 @@ void repeaterSetup::handleTransmitStatus(bool amTransmitting) void repeaterSetup::showEvent(QShowEvent *event) { + emit getDuplexMode(); emit getSplitModeEnabled(); + if(rig.hasRepeaterModes) + emit getRptDuplexOffset(); + (void)event; } +void repeaterSetup::on_splitEnableChk_clicked() +{ + emit setDuplexMode(dmSplitOn); + + if(ui->autoTrackLiveBtn->isChecked()) + { + ui->autoTrackLiveBtn->setChecked(false); + } +} + +void repeaterSetup::on_splitOffBtn_clicked() +{ + emit setDuplexMode(dmSplitOff); +} + void repeaterSetup::on_rptSimplexBtn_clicked() { // Simplex - emit setDuplexMode(dmDupAutoOff); - emit setDuplexMode(dmSimplex); + emit setDuplexMode(dmSplitOff); + if(rig.hasRepeaterModes) + { + emit setDuplexMode(dmDupAutoOff); + emit setDuplexMode(dmSimplex); + } } void repeaterSetup::on_rptDupPlusBtn_clicked() @@ -557,27 +592,13 @@ void repeaterSetup::on_debugBtn_clicked() 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); - } -} +//void repeaterSetup::on_splitOffsetSetBtn_clicked() +//{ +// freqt txFreq; +// bool ok = true; +// txFreq.Hz = ui->splitTransmitFreqEdit->text().toDouble(&ok) * 1E6; +// emit setTransmitFrequency(txFreq); +//} quint64 repeaterSetup::getFreqHzFromKHzString(QString khz) { @@ -623,10 +644,16 @@ quint64 repeaterSetup::getFreqHzFromMHzString(QString MHz) // We want the right 4xx 3 characters. QString KHz = MHz.right(MHz.length() - decimalPtIndex - 1); MHz.chop(MHz.length() - decimalPtIndex); - + if(KHz.length() != 6) + { + QString zeros = QString("000000"); + zeros.chop(KHz.length()); + KHz.append(zeros); + } + //qInfo() << "KHz string: " << KHz; fhz = MHz.toUInt(&ok) * 1E6; if(!ok) goto handleError; - fhz += KHz.toUInt(&ok) * 1E3; if(!ok) goto handleError; - + fhz += KHz.toUInt(&ok) * 1; if(!ok) goto handleError; + //qInfo() << "Fhz: " << fhz; } else { // Frequency was already MHz (unlikely but what can we do?) fhz = MHz.toUInt(&ok) * 1E6; if(!ok) goto handleError; @@ -736,10 +763,40 @@ void repeaterSetup::on_swapMSBtn_clicked() void repeaterSetup::on_setToneSubVFOBtn_clicked() { - + // Perhaps not needed + // Set the secondary VFO to the selected tone + // TODO: DTCS + rptrTone_t rt; + rt.tone = (quint16)ui->rptToneCombo->currentData().toUInt(); + rt.useSecondaryVFO = true; + emit setTone(rt); } void repeaterSetup::on_setRptrSubVFOBtn_clicked() { + // Perhaps not needed + // Set the secondary VFO to the selected repeater mode + rptrAccessData_t rd; + rd.useSecondaryVFO = true; + if(ui->toneTone->isChecked()) + rd.accessMode=ratrTN; + if(ui->toneNone->isChecked()) + rd.accessMode=ratrNN; + if(ui->toneTSQL->isChecked()) + rd.accessMode=ratrTT; + if(ui->toneDTCS->isChecked()) + rd.accessMode=ratrDD; + + emit setRptAccessMode(rd); +} + +void repeaterSetup::on_rptrOffsetSetBtn_clicked() +{ + freqt f; + f.Hz = getFreqHzFromMHzString(ui->rptrOffsetEdit->text()); + if(f.Hz != 0) + { + emit setRptDuplexOffset(f); + } } diff --git a/repeatersetup.h b/repeatersetup.h index 4c56863..76431a9 100644 --- a/repeatersetup.h +++ b/repeatersetup.h @@ -30,8 +30,9 @@ signals: void getTSQL(); void getDTCS(); void setRptAccessMode(rptrAccessData_t rd); - void getRptAccessMode(); + void setRptDuplexOffset(freqt f); + void getRptDuplexOffset(); // Split: void getSplitModeEnabled(); void getTransmitFrequency(); @@ -56,6 +57,7 @@ public slots: void handleUpdateCurrentMainFrequency(freqt mainfreq); void handleUpdateCurrentMainMode(mode_info m); void handleTransmitStatus(bool amTransmitting); + void handleRptOffsetFrequency(freqt f); private slots: void showEvent(QShowEvent *event); @@ -71,8 +73,6 @@ private slots: void on_toneTone_clicked(); void on_toneTSQL_clicked(); void on_toneDTCS_clicked(); - void on_splitOffsetSetBtn_clicked(); - void on_splitEnableChk_clicked(bool enabled); void on_splitPlusButton_clicked(); void on_splitMinusBtn_clicked(); @@ -98,6 +98,12 @@ private slots: void on_setRptrSubVFOBtn_clicked(); + void on_rptrOffsetSetBtn_clicked(); + + void on_splitOffBtn_clicked(); + + void on_splitEnableChk_clicked(); + private: Ui::repeaterSetup *ui; freqt currentMainFrequency; diff --git a/repeatersetup.ui b/repeatersetup.ui index d099f54..1222dd4 100644 --- a/repeatersetup.ui +++ b/repeatersetup.ui @@ -6,8 +6,8 @@ 0 0 - 1198 - 238 + 1230 + 267 @@ -116,6 +116,27 @@ + + + + + + Offset (MHz): + + + + + + + + + + Set + + + + + @@ -128,23 +149,36 @@ - + - Split Enable + Split On + + rptDuplexBtns + + + + + + + Split Off + + + rptDuplexBtns + - Auto Track Live + AutoTrack - Set Repeater Tone + Set Rpt Tone @@ -189,13 +223,6 @@ - - - - RPT - - - diff --git a/rigcommander.cpp b/rigcommander.cpp index 014b7a0..de0b8c8 100644 --- a/rigcommander.cpp +++ b/rigcommander.cpp @@ -1192,6 +1192,27 @@ void rigCommander::setRptAccessMode(rptrAccessData_t rd) prepDataAndSend(payload); } +void rigCommander::setRptDuplexOffset(freqt f) +{ + QByteArray payload; + payload.setRawData("\x0D", 1); + // get f, chop to 10 MHz + QByteArray freqPayload = makeFreqPayload(f); + payload.append(freqPayload.mid(1, 3)); + //qInfo(logRig()) << "Here is potential repeater offset setting, not sending to radio:"; + printHexNow(payload, logRig()); + QString g = getHex(payload); + //qInfo(logRig()).noquote().nospace() << g; + prepDataAndSend(payload); +} + +void rigCommander::getRptDuplexOffset() +{ + QByteArray payload; + payload.setRawData("\x0C", 1); + prepDataAndSend(payload); +} + void rigCommander::setIPP(bool enabled) { QByteArray payload; @@ -1526,6 +1547,10 @@ void rigCommander::parseCommand() //qInfo(logRig()) << "Have mode data"; this->parseMode(); break; + case '\x0C': + qDebug(logRig) << "Have 0x0C reply"; + emit haveRptOffsetFrequency(parseFrequencyRptOffset(payloadIn)); + break; case '\x0F': emit haveDuplexMode((duplexMode)(unsigned char)payloadIn[1]); state.set(DUPLEX, (duplexMode)(unsigned char)payloadIn[1], false); @@ -3467,6 +3492,7 @@ void rigCommander::determineRigCaps() rigCaps.hasDV = true; rigCaps.hasCTCSS = true; rigCaps.hasDTCS = true; + rigCaps.hasRepeaterModes = true; rigCaps.hasTBPF = true; rigCaps.attenuators.push_back('\x10'); rigCaps.preamps.push_back('\x01'); @@ -3494,6 +3520,7 @@ void rigCommander::determineRigCaps() rigCaps.hasDV = false; rigCaps.hasCTCSS = true; rigCaps.hasDTCS = true; + rigCaps.hasRepeaterModes = true; rigCaps.hasATU = false; rigCaps.attenuators.insert(rigCaps.attenuators.end(),{ '\x10' , '\x20', '\x30'}); rigCaps.preamps.push_back('\x01'); @@ -3623,6 +3650,7 @@ void rigCommander::determineRigCaps() rigCaps.hasATU = true; rigCaps.hasCTCSS = true; rigCaps.hasDTCS = true; + rigCaps.hasRepeaterModes = true; rigCaps.hasTBPF = true; rigCaps.attenuators.insert(rigCaps.attenuators.end(),{ '\x10' , '\x20'}); rigCaps.preamps.push_back('\x01'); @@ -3706,6 +3734,7 @@ void rigCommander::determineRigCaps() rigCaps.hasATU = true; rigCaps.hasCTCSS = true; rigCaps.hasDTCS = true; + rigCaps.hasRepeaterModes = true; rigCaps.hasTBPF = true; rigCaps.attenuators.push_back('\x12'); rigCaps.preamps.push_back('\x01'); @@ -3930,6 +3959,7 @@ void rigCommander::determineRigCaps() rigCaps.hasIFShift = true; rigCaps.hasCTCSS = true; rigCaps.hasDTCS = true; + rigCaps.hasRepeaterModes = true; rigCaps.hasAntennaSel = true; rigCaps.preamps.push_back('\x01'); rigCaps.preamps.push_back('\x02'); @@ -4050,6 +4080,7 @@ void rigCommander::determineRigCaps() rigCaps.hasATU = true; rigCaps.hasDV = true; rigCaps.hasTBPF = true; + rigCaps.hasRepeaterModes = true; rigCaps.preamps.push_back('\x01'); rigCaps.preamps.push_back('\x02'); rigCaps.attenuators.insert(rigCaps.attenuators.end(),{ '\x20' }); @@ -4405,6 +4436,26 @@ void rigCommander::parseFrequency() emit haveFrequency(freq); } +freqt rigCommander::parseFrequencyRptOffset(QByteArray data) +{ + // DATA: 0c 00 60 00 fd + // INDEX: 00 01 02 03 04 + // 00.600.0 MHz (600.0 KHz) + + freqt f; + f.Hz = 0; + + f.Hz += (data[1] & 0x0f) * 1E6; // 1 MHz + f.Hz += ((data[1] & 0xf0) >> 4) * 1E6 * 10; // 10 MHz + f.Hz += (data[2] & 0x0f) * 10E3; // 10 KHz + f.Hz += ((data[2] & 0xf0) >> 4) * 100E3; // 100 KHz + + f.Hz += (data[3] & 0x0f) * 100; // 100 Hz + f.Hz += ((data[3] & 0xf0) >> 4) * 1000; // 1 KHz + + return f; +} + freqt rigCommander::parseFrequency(QByteArray data, unsigned char lastPosition) { // process payloadIn, which is stripped. diff --git a/rigcommander.h b/rigcommander.h index 1e93c41..f8bc04c 100644 --- a/rigcommander.h +++ b/rigcommander.h @@ -146,6 +146,8 @@ public slots: void setRptAccessMode(rptAccessTxRx ratr); void setRptAccessMode(rptrAccessData_t ratr); void getRptAccessMode(); + void setRptDuplexOffset(freqt f); + void getRptDuplexOffset(); // Get Levels: void getLevels(); // all supported levels @@ -309,6 +311,7 @@ signals: void haveTone(quint16 tone); void haveTSQL(quint16 tsql); void haveDTCS(quint16 dcscode, bool tinv, bool rinv); + void haveRptOffsetFrequency(freqt f); // Levels: void haveRfGain(unsigned char level); @@ -378,6 +381,8 @@ private: QByteArray bcdEncodeInt(unsigned int); void parseFrequency(); freqt parseFrequency(QByteArray data, unsigned char lastPosition); // supply index where Mhz is found + freqt parseFrequencyRptOffset(QByteArray data); + QByteArray makeFreqPayloadRptOffset(freqt freq); QByteArray makeFreqPayload(double frequency); QByteArray makeFreqPayload(freqt freq); QByteArray encodeTone(quint16 tone, bool tinv, bool rinv); diff --git a/rigidentities.h b/rigidentities.h index 87f051a..dbd6e3f 100644 --- a/rigidentities.h +++ b/rigidentities.h @@ -134,6 +134,7 @@ struct rigCapabilities { bool hasCTCSS; bool hasDTCS; + bool hasRepeaterModes = false; bool hasTransmit; bool hasPTTCommand; diff --git a/wfmain.cpp b/wfmain.cpp index 7ea2568..81236de 100644 --- a/wfmain.cpp +++ b/wfmain.cpp @@ -381,9 +381,12 @@ void wfmain::rigConnections() connect(rig, SIGNAL(havePassband(quint16)), this, SLOT(receivePassband(quint16))); connect(rig, SIGNAL(haveCwPitch(unsigned char)), this, SLOT(receiveCwPitch(unsigned char))); + // Repeater, duplex, and split: connect(rpt, SIGNAL(getDuplexMode()), rig, SLOT(getDuplexMode())); connect(rpt, SIGNAL(setDuplexMode(duplexMode)), rig, SLOT(setDuplexMode(duplexMode))); connect(rig, SIGNAL(haveDuplexMode(duplexMode)), rpt, SLOT(receiveDuplexMode(duplexMode))); + connect(this, SIGNAL(getRptDuplexOffset()), rig, SLOT(getRptDuplexOffset())); + connect(rig, SIGNAL(haveRptOffsetFrequency(freqt)), rpt, SLOT(handleRptOffsetFrequency(freqt))); connect(rpt, SIGNAL(getTone()), rig, SLOT(getTone())); connect(rpt, SIGNAL(getTSQL()), rig, SLOT(getTSQL())); connect(rpt, SIGNAL(getDTCS()), rig, SLOT(getDTCS())); @@ -420,8 +423,14 @@ void wfmain::rigConnections() [=]() { issueDelayedCommand(cmdVFOEqualMS);}); connect(this->rpt, &repeaterSetup::swapVFOs, [=]() { issueDelayedCommand(cmdVFOSwap);}); + connect(this->rpt, &repeaterSetup::setRptDuplexOffset, + [=](const freqt &fOffset) { issueCmd(cmdSetRptDuplexOffset, fOffset);}); + connect(this->rpt, &repeaterSetup::getRptDuplexOffset, + [=]() { issueDelayedCommand(cmdGetRptDuplexOffset);}); + connect(this, SIGNAL(setRptDuplexOffset(freqt)), rig, SLOT(setRptDuplexOffset(freqt))); connect(this, SIGNAL(getDuplexMode()), rig, SLOT(getDuplexMode())); + connect(this, SIGNAL(getPassband()), rig, SLOT(getPassband())); connect(this, SIGNAL(setPassband(quint16)), rig, SLOT(setPassband(quint16))); connect(this, SIGNAL(getCwPitch()), rig, SLOT(getCwPitch())); @@ -3713,6 +3722,12 @@ void wfmain::doCmd(commandtype cmddata) emit setRepeaterAccessMode(rd); break; } + case cmdSetRptDuplexOffset: + { + freqt f = (*std::static_pointer_cast(data)); + emit setRptDuplexOffset(f); + break; + } case cmdSetPTT: { bool pttrequest = (*std::static_pointer_cast(data)); @@ -3877,6 +3892,9 @@ void wfmain::doCmd(cmds cmd) case cmdGetDuplexMode: emit getDuplexMode(); break; + case cmdGetRptDuplexOffset: + emit getRptDuplexOffset(); + break; case cmdGetPassband: emit getPassband(); break; @@ -4062,7 +4080,6 @@ void wfmain::sendRadioCommandLoop() } } else if ((!rapidPollCmdQueue.empty()) && rapidPollCmdQueueEnabled) { - qDebug(logSystem()) << "Running rapid poll command."; int nrCmds = (int)rapidPollCmdQueue.size(); cmds rCmd = rapidPollCmdQueue[(rapidCmdNum++)%nrCmds]; doCmd(rCmd); @@ -6894,7 +6911,15 @@ void wfmain::on_serialDeviceListCombo_textActivated(const QString &arg1) void wfmain::on_rptSetupBtn_clicked() { + if(rpt->isMinimized()) + { + rpt->raise(); + rpt->activateWindow(); + return; + } rpt->show(); + rpt->raise(); + rpt->activateWindow(); } void wfmain::on_attSelCombo_activated(int index) @@ -7666,7 +7691,8 @@ void wfmain::on_underlayAverageBuffer_toggled(bool checked) void wfmain::on_debugBtn_clicked() { qInfo(logSystem()) << "Debug button pressed."; - cw->show(); + qDebug(logSystem()) << "Query for repeater duplex offset 0x0C headed out"; + issueDelayedCommand(cmdGetRptDuplexOffset); } // ---------- color helper functions: ---------- // diff --git a/wfmain.h b/wfmain.h index 4bcfaa5..cc351db 100644 --- a/wfmain.h +++ b/wfmain.h @@ -118,6 +118,8 @@ signals: void setRepeaterAccessMode(rptrAccessData_t rd); void setTone(rptrTone_t t); void setTSQL(rptrTone_t t); + void setRptDuplexOffset(freqt f); + void getRptDuplexOffset(); // Level get: void getLevels(); // get all levels diff --git a/wfviewtypes.h b/wfviewtypes.h index c935067..ea4f282 100644 --- a/wfviewtypes.h +++ b/wfviewtypes.h @@ -153,7 +153,7 @@ enum cmds { cmdGetCurrentModLevel, cmdStartRegularPolling, cmdStopRegularPolling, cmdQueNormalSpeed, cmdGetVdMeter, cmdGetIdMeter, cmdGetSMeter, cmdGetCenterMeter, cmdGetPowerMeter, cmdGetSWRMeter, cmdGetALCMeter, cmdGetCompMeter, cmdGetTxRxMeter, - cmdGetTone, cmdGetTSQL, cmdGetDTCS, cmdGetRptAccessMode, cmdSetTone, cmdSetTSQL, cmdSetRptAccessMode, + cmdGetTone, cmdGetTSQL, cmdGetDTCS, cmdGetRptAccessMode, cmdSetTone, cmdSetTSQL, cmdSetRptAccessMode, cmdSetRptDuplexOffset, cmdGetRptDuplexOffset, cmdSelVFO, cmdVFOSwap, cmdVFOEqualAB, cmdVFOEqualMS, cmdGetPreamp, cmdGetAttenuator, cmdGetAntenna, cmdGetBandStackReg, cmdGetKeySpeed, cmdSetKeySpeed, cmdGetBreakMode, cmdSetBreakMode, cmdSendCW, cmdStopCW,