From cf6f8374dea8dcd5cf7bfe63bdaf1fd180270794 Mon Sep 17 00:00:00 2001 From: f4exb Date: Fri, 17 Jan 2020 15:08:43 +0100 Subject: [PATCH] LimeRFE USB support: implemented power calibration in UI --- sdrbase/limerfe/limerfeusbcalib.h | 2 +- sdrgui/CMakeLists.txt | 1 + sdrgui/gui/doublevalidator.h | 59 ++++++++++ sdrgui/limerfegui/limerfeusbdialog.cpp | 157 ++++++++++++++++++++++++- sdrgui/limerfegui/limerfeusbdialog.h | 10 +- sdrgui/limerfegui/limerfeusbdialog.ui | 107 +++++++++++++++-- sdrgui/mainwindow.cpp | 2 +- 7 files changed, 325 insertions(+), 13 deletions(-) create mode 100644 sdrgui/gui/doublevalidator.h diff --git a/sdrbase/limerfe/limerfeusbcalib.h b/sdrbase/limerfe/limerfeusbcalib.h index dc1e41a78..09486e2ce 100644 --- a/sdrbase/limerfe/limerfeusbcalib.h +++ b/sdrbase/limerfe/limerfeusbcalib.h @@ -48,7 +48,7 @@ public: CellularBand38 }; - QMap m_calibrations; //!< Channel range to calibration value in centi-Bels + QMap m_calibrations; //!< Channel range to calibration value in floating point decibels private: void serializeCalibMap(QByteArray& data) const; diff --git a/sdrgui/CMakeLists.txt b/sdrgui/CMakeLists.txt index 67c73c393..ef7d3aa6b 100644 --- a/sdrgui/CMakeLists.txt +++ b/sdrgui/CMakeLists.txt @@ -96,6 +96,7 @@ set(sdrgui_HEADERS gui/cwkeyergui.h gui/devicestreamselectiondialog.h gui/deviceuserargsdialog.h + gui/doublevalidator.h gui/editcommanddialog.h gui/externalclockbutton.h gui/externalclockdialog.h diff --git a/sdrgui/gui/doublevalidator.h b/sdrgui/gui/doublevalidator.h new file mode 100644 index 000000000..675132f5e --- /dev/null +++ b/sdrgui/gui/doublevalidator.h @@ -0,0 +1,59 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2020 F4EXB // +// written by Edouard Griffiths // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef SDRGUI_GUI_DOUBLEVALIDATOR_H_ +#define SDRGUI_GUI_DOUBLEVALIDATOR_H_ + +#include + +class DoubleValidator : public QDoubleValidator +{ +public: + DoubleValidator(double bottom, double top, int decimals, QObject * parent) : + QDoubleValidator(bottom, top, decimals, parent) + { + } + + QValidator::State validate(QString &s, int &i) const + { + if (s.isEmpty() || s == "-") { + return QValidator::Intermediate; + } + + QChar decimalPoint = locale().decimalPoint(); + + if(s.indexOf(decimalPoint) != -1) { + int charsAfterPoint = s.length() - s.indexOf(decimalPoint) - 1; + + if (charsAfterPoint > decimals()) { + return QValidator::Invalid; + } + } + + bool ok; + double d = locale().toDouble(s, &ok); + + if (ok && d >= bottom() && d <= top()) { + return QValidator::Acceptable; + } else { + return QValidator::Invalid; + } + } +}; + +#endif // SDRGUI_GUI_DOUBLEVALIDATOR_H_ diff --git a/sdrgui/limerfegui/limerfeusbdialog.cpp b/sdrgui/limerfegui/limerfeusbdialog.cpp index cd6cbaa28..9cf036f45 100644 --- a/sdrgui/limerfegui/limerfeusbdialog.cpp +++ b/sdrgui/limerfegui/limerfeusbdialog.cpp @@ -20,16 +20,19 @@ #include "util/serialutil.h" #include "util/db.h" #include "dsp/dspengine.h" +#include "gui/doublevalidator.h" #include "limerfeusbdialog.h" #include "ui_limerfeusbdialog.h" -LimeRFEUSBDialog::LimeRFEUSBDialog(QWidget* parent) : +LimeRFEUSBDialog::LimeRFEUSBDialog(LimeRFEUSBCalib& limeRFEUSBCalib, QWidget* parent) : + m_limeRFEUSBCalib(limeRFEUSBCalib), QDialog(parent), ui(new Ui::LimeRFEUSBDialog), m_rxTxToggle(false) { ui->setupUi(this); + ui->powerCorrValue->setValidator(new DoubleValidator(-99.9, 99.9, 1, ui->powerCorrValue)); std::vector comPorts; SerialUtil::getComPorts(comPorts, "ttyUSB[0-9]+"); // regex is for Linux only @@ -109,8 +112,10 @@ void LimeRFEUSBDialog::displayPower() { ui->powerEnable->blockSignals(true); ui->powerSource->blockSignals(true); + ui->powerEnable->setChecked(m_settings.m_swrEnable); ui->powerSource->setCurrentIndex((int) m_settings.m_swrSource); + ui->powerEnable->blockSignals(false); ui->powerSource->blockSignals(false); } @@ -154,6 +159,8 @@ void LimeRFEUSBDialog::refreshPower() vswr = vswr < 0.0 ? 0.0 : vswr > 99.999 ? 99.999 : vswr; ui->swrText->setText(QString::number(vswr, 'f', 3)); } + + updateAbsPower(m_currentPowerCorrection); } void LimeRFEUSBDialog::setRxChannels() @@ -238,6 +245,8 @@ void LimeRFEUSBDialog::setTxChannels() { ui->txChannel->blockSignals(true); ui->txPort->blockSignals(true); + ui->powerCorrValue->blockSignals(true); + ui->txChannel->clear(); ui->txPort->clear(); @@ -305,10 +314,128 @@ void LimeRFEUSBDialog::setTxChannels() } ui->txChannelGroup->setCurrentIndex((int) m_settings.m_txChannels); + m_currentPowerCorrection = getPowerCorrection(); + ui->powerCorrValue->setText(QString::number(m_currentPowerCorrection, 'f', 1)); + updateAbsPower(m_currentPowerCorrection); + + ui->powerCorrValue->blockSignals(false); ui->txPort->blockSignals(false); ui->txChannel->blockSignals(false); } +int LimeRFEUSBDialog::getPowerCorectionIndex() +{ + LimeRFEUSBCalib::ChannelRange range; + + switch (m_settings.m_txChannels) + { + case LimeRFEController::ChannelsWideband: + { + switch (m_settings.m_txWidebandChannel) + { + case LimeRFEController::WidebandLow: + range = LimeRFEUSBCalib::WidebandLow; + break; + case LimeRFEController::WidebandHigh: + range = LimeRFEUSBCalib::WidebandHigh; + break; + default: + return -1; + break; + } + break; + } + case LimeRFEController::ChannelsHAM: + { + switch (m_settings.m_txHAMChannel) + { + case LimeRFEController::HAM_30M: + range = LimeRFEUSBCalib::HAM_30MHz; + break; + case LimeRFEController::HAM_50_70MHz: + range = LimeRFEUSBCalib::HAM_50_70MHz; + break; + case LimeRFEController::HAM_144_146MHz: + range = LimeRFEUSBCalib::HAM_144_146MHz; + break; + case LimeRFEController::HAM_220_225MHz: + range = LimeRFEUSBCalib::HAM_220_225MHz; + break; + case LimeRFEController::HAM_430_440MHz: + range = LimeRFEUSBCalib::HAM_430_440MHz; + break; + case LimeRFEController::HAM_902_928MHz: + range = LimeRFEUSBCalib::HAM_902_928MHz; + break; + case LimeRFEController::HAM_1240_1325MHz: + range = LimeRFEUSBCalib::HAM_1240_1325MHz; + break; + case LimeRFEController::HAM_2300_2450MHz: + range = LimeRFEUSBCalib::HAM_2300_2450MHz; + break; + case LimeRFEController::HAM_3300_3500MHz: + range = LimeRFEUSBCalib::HAM_3300_3500MHz; + break; + default: + return -1; + break; + } + break; + } + case LimeRFEController::ChannelsCellular: + { + switch (m_settings.m_txCellularChannel) + { + case LimeRFEController::CellularBand1: + range = LimeRFEUSBCalib::CellularBand1; + break; + case LimeRFEController::CellularBand2: + range = LimeRFEUSBCalib::CellularBand2; + break; + case LimeRFEController::CellularBand7: + range = LimeRFEUSBCalib::CellularBand7; + break; + case LimeRFEController::CellularBand38: + range = LimeRFEUSBCalib::CellularBand38; + break; + default: + return -1; + break; + } + break; + } + default: + return -1; + break; + } + + return (int) range; +} + +double LimeRFEUSBDialog::getPowerCorrection() +{ + int index = getPowerCorectionIndex(); + + QMap::const_iterator it = m_limeRFEUSBCalib.m_calibrations.find(index); + + if (it != m_limeRFEUSBCalib.m_calibrations.end()) { + return it.value(); + } else { + return 0.0; + } +} + +void LimeRFEUSBDialog::setPowerCorrection(double dbValue) +{ + int index = getPowerCorectionIndex(); + + if (index < 0) { + return; + } + + m_limeRFEUSBCalib.m_calibrations[index] = dbValue; +} + void LimeRFEUSBDialog::on_openDevice_clicked() { int rc = m_controller.openDevice(ui->device->currentText().toStdString()); @@ -447,6 +574,34 @@ void LimeRFEUSBDialog::on_powerAutoRefresh_toggled(bool checked) } } +void LimeRFEUSBDialog::on_powerCorrValue_textEdited(const QString &text) +{ + bool ok; + double powerCorrection = text.toDouble(&ok); + + if (ok) + { + setPowerCorrection(powerCorrection); + m_currentPowerCorrection = powerCorrection; + updateAbsPower(powerCorrection); + } +} + +void LimeRFEUSBDialog::updateAbsPower(double powerCorrDB) +{ + bool ok; + double power = ui->powerFwdText->text().toDouble(&ok); + + if (ok) + { + double powerCorrected = power + powerCorrDB; + ui->powerAbsDbText->setText(QString::number(powerCorrected, 'f', 1)); + double powerMilliwatts = CalcDb::powerFromdB(powerCorrected); + powerMilliwatts = powerMilliwatts > 8000.0 ? 8000.0 : powerMilliwatts; + ui->powerAbsWText->setText(QString::number(powerMilliwatts/1000.0, 'f', 3)); + } +} + void LimeRFEUSBDialog::on_modeRx_toggled(bool checked) { int rc; diff --git a/sdrgui/limerfegui/limerfeusbdialog.h b/sdrgui/limerfegui/limerfeusbdialog.h index 591d8ca1d..171e41d86 100644 --- a/sdrgui/limerfegui/limerfeusbdialog.h +++ b/sdrgui/limerfegui/limerfeusbdialog.h @@ -23,6 +23,7 @@ #include #include "limerfe/limerfecontroller.h" +#include "limerfe/limerfeusbcalib.h" #include "export.h" namespace Ui { @@ -33,7 +34,7 @@ class SDRGUI_API LimeRFEUSBDialog : public QDialog { Q_OBJECT public: - explicit LimeRFEUSBDialog(QWidget* parent = nullptr); + explicit LimeRFEUSBDialog(LimeRFEUSBCalib& limeRFEUSBCalib, QWidget* parent = nullptr); ~LimeRFEUSBDialog(); private: @@ -43,12 +44,18 @@ private: void refreshPower(); void setRxChannels(); void setTxChannels(); + int getPowerCorectionIndex(); + double getPowerCorrection(); + void setPowerCorrection(double dbValue); + void updateAbsPower(double powerCorrDB); Ui::LimeRFEUSBDialog* ui; LimeRFEController m_controller; LimeRFEController::LimeRFESettings m_settings; + LimeRFEUSBCalib& m_limeRFEUSBCalib; bool m_rxTxToggle; QTimer m_timer; + double m_currentPowerCorrection; private slots: void on_openDevice_clicked(); @@ -65,6 +72,7 @@ private slots: void on_powerSource_currentIndexChanged(int index); void on_powerRefresh_clicked(); void on_powerAutoRefresh_toggled(bool checked); + void on_powerCorrValue_textEdited(const QString &text); void on_modeRx_toggled(bool checked); void on_modeTx_toggled(bool checked); void on_rxTxToggle_clicked(); diff --git a/sdrgui/limerfegui/limerfeusbdialog.ui b/sdrgui/limerfegui/limerfeusbdialog.ui index 67c523084..a4bf9e4d5 100644 --- a/sdrgui/limerfegui/limerfeusbdialog.ui +++ b/sdrgui/limerfegui/limerfeusbdialog.ui @@ -551,7 +551,7 @@ - 120 + 180 250 31 17 @@ -564,7 +564,7 @@ - 170 + 230 250 31 17 @@ -577,7 +577,7 @@ - 170 + 230 270 35 17 @@ -596,7 +596,7 @@ - 120 + 180 270 35 17 @@ -615,7 +615,7 @@ - 260 + 320 270 25 17 @@ -631,7 +631,7 @@ - 220 + 280 250 31 17 @@ -644,7 +644,7 @@ - 220 + 280 270 35 17 @@ -699,7 +699,7 @@ - 300 + 360 250 45 17 @@ -748,7 +748,7 @@ - 290 + 350 270 50 17 @@ -787,6 +787,95 @@ + + + + 120 + 260 + 31 + 17 + + + + Corr + + + + + + 170 + 290 + 45 + 17 + + + + Corrected forward power in dB + + + -00.0 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 220 + 290 + 45 + 17 + + + + Corrected forward power in Watts + + + 0.000 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 280 + 290 + 15 + 17 + + + + W + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 110 + 280 + 55 + 27 + + + + Qt::ClickFocus + + + Power correction in dBm + + + -00.0 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + diff --git a/sdrgui/mainwindow.cpp b/sdrgui/mainwindow.cpp index e0f9c2917..2a03bc0d8 100644 --- a/sdrgui/mainwindow.cpp +++ b/sdrgui/mainwindow.cpp @@ -1613,7 +1613,7 @@ void MainWindow::on_action_LimeRFE_triggered() qDebug("MainWindow::on_action_LimeRFE_triggered"); #if defined(HAS_LIMERFE) qDebug("MainWindow::on_action_LimeRFE_triggered: activated"); - LimeRFEUSBDialog *limeRFEUSBDialog = new LimeRFEUSBDialog(this); + LimeRFEUSBDialog *limeRFEUSBDialog = new LimeRFEUSBDialog(m_settings.getLimeRFEUSBCalib(), this); limeRFEUSBDialog->setModal(false); limeRFEUSBDialog->show(); #endif